From 724e76f48b73591498998298bd709c401b0dabe0 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 6 May 2024 16:34:45 +0100 Subject: [PATCH] Fix marshalling of CustomGenesis (#730) * fixes HexOrDecimal256 marshalling to json * fix Bytes32 marshalling * using default value method * bytes32 nil marshalls to 0x0 instead of nil * nits * license --- genesis/customnet.go | 9 ++++++-- genesis/customnet_test.go | 38 +++++++++++++++++++++++++++++--- thor/bytes32.go | 10 ++++----- thor/bytes32_test.go | 46 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 thor/bytes32_test.go diff --git a/genesis/customnet.go b/genesis/customnet.go index e85b080a7..a0a35c2c4 100644 --- a/genesis/customnet.go +++ b/genesis/customnet.go @@ -254,6 +254,11 @@ func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error { } // MarshalJSON implements the json.Marshaler interface. -func (i *HexOrDecimal256) MarshalJSON() ([]byte, error) { - return (*math.HexOrDecimal256)(i).MarshalText() +func (i HexOrDecimal256) MarshalJSON() ([]byte, error) { + decimal256 := math.HexOrDecimal256(i) + text, err := decimal256.MarshalText() + if err != nil { + return nil, err + } + return []byte("\"" + string(text) + "\""), nil } diff --git a/genesis/customnet_test.go b/genesis/customnet_test.go index 127058f35..2ea41fca2 100644 --- a/genesis/customnet_test.go +++ b/genesis/customnet_test.go @@ -6,6 +6,7 @@ package genesis_test import ( + "encoding/json" "math" "math/big" "testing" @@ -41,6 +42,9 @@ func CustomNetWithParams(t *testing.T, executor genesis.Executor, baseGasPrice g accounts[0].Balance = &genesis.HexOrDecimal256{} accounts[0].Energy = &genesis.HexOrDecimal256{} accounts[0].Code = "0x608060405234801561001057600080fd5b50606460008190555061017f806100286000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220a1012465f7be855f040e95566de3bbd50542ba31a7730d7fea2ef9de563a9ac164736f6c63430008110033" + accounts[0].Storage = map[string]thor.Bytes32{ + "0x0000000000000000000000000000000000000000000000000000000000000001": thor.MustParseBytes32("0x0000000000000000000000000000000000000000000000000000000000000002"), + } mbp := uint64(10000) customGenesis := genesis.CustomGenesis{ @@ -125,21 +129,49 @@ func TestNewCustomNetInvalidProposerEndorsement(t *testing.T) { assert.Nil(t, genesisBlock, "NewCustomNet should return a nil Genesis object") } +func TestNewCustomGenesisMarshalUnmarshal(t *testing.T) { + rewardRatio := genesis.HexOrDecimal256(*big.NewInt(-100)) + customGenesis := CustomNetWithParams(t, genesis.Executor{}, genesis.HexOrDecimal256{}, rewardRatio, genesis.HexOrDecimal256{}) + + marshalVal, err := json.Marshal(customGenesis) + assert.NoError(t, err, "Marshaling should not produce an error") + + expectedMarshal := `{"launchTime":1526400000,"gaslimit":0,"extraData":"","accounts":[{"address":"0x0000000000000000000000000000000000000000","balance":"0x0","energy":"0x0","code":"0x608060405234801561001057600080fd5b50606460008190555061017f806100286000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632f5f3b3c14610046578063a32a3ee414610064578063acfee28314610082575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61006c6100a4565b60405161007991906100d0565b60405180910390f35b61009c6004803603810190610097919061011c565b6100ad565b005b60005481565b60008054905090565b8060008190555050565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220a1012465f7be855f040e95566de3bbd50542ba31a7730d7fea2ef9de563a9ac164736f6c63430008110033","storage":{"0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000002"}},{"address":"0x0000000000000000000000000000000000000000","balance":null,"energy":null,"code":"","storage":null}],"authority":[{"masterAddress":"0xf077b491b355e64048ce21e3a6fc4751eeea77fa","endorsorAddress":"0xf077b491b355e64048ce21e3a6fc4751eeea77fa","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"},{"masterAddress":"0x435933c8064b4ae76be665428e0307ef2ccfbd68","endorsorAddress":"0x435933c8064b4ae76be665428e0307ef2ccfbd68","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"},{"masterAddress":"0x0f872421dc479f3c11edd89512731814d0598db5","endorsorAddress":"0x0f872421dc479f3c11edd89512731814d0598db5","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"},{"masterAddress":"0xf370940abdbd2583bc80bfc19d19bc216c88ccf0","endorsorAddress":"0xf370940abdbd2583bc80bfc19d19bc216c88ccf0","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"},{"masterAddress":"0x99602e4bbc0503b8ff4432bb1857f916c3653b85","endorsorAddress":"0x99602e4bbc0503b8ff4432bb1857f916c3653b85","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"},{"masterAddress":"0x61e7d0c2b25706be3485980f39a3a994a8207acf","endorsorAddress":"0x61e7d0c2b25706be3485980f39a3a994a8207acf","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"},{"masterAddress":"0x361277d1b27504f36a3b33d3a52d1f8270331b8c","endorsorAddress":"0x361277d1b27504f36a3b33d3a52d1f8270331b8c","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"},{"masterAddress":"0xd7f75a0a1287ab2916848909c8531a0ea9412800","endorsorAddress":"0xd7f75a0a1287ab2916848909c8531a0ea9412800","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"},{"masterAddress":"0xabef6032b9176c186f6bf984f548bda53349f70a","endorsorAddress":"0xabef6032b9176c186f6bf984f548bda53349f70a","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"},{"masterAddress":"0x865306084235bf804c8bba8a8d56890940ca8f0b","endorsorAddress":"0x865306084235bf804c8bba8a8d56890940ca8f0b","identity":"0x00000000000000000000000000000000000000000000000000006d6173746572"}],"params":{"rewardRatio":"-0x64","baseGasPrice":"0x0","proposerEndorsement":"0x0","executorAddress":null,"maxBlockProposers":10000},"executor":{"approvers":null},"forkConfig":{"VIP191":4294967295,"ETH_CONST":4294967295,"BLOCKLIST":4294967295,"ETH_IST":4294967295,"VIP214":4294967295,"FINALITY":0}}` + assert.Equal(t, expectedMarshal, string(marshalVal)) +} + func TestHexOrDecimal256MarshalUnmarshal(t *testing.T) { // Example hex string representing the value 100 originalHex := `"0x64"` // Note the enclosing double quotes for valid JSON string // Unmarshal JSON into HexOrDecimal256 var unmarshaledValue genesis.HexOrDecimal256 + + // using direct function err := unmarshaledValue.UnmarshalJSON([]byte(originalHex)) assert.NoError(t, err, "Unmarshaling should not produce an error") + // using json overloading ( satisfies the json.Unmarshal interface ) + err = json.Unmarshal([]byte(originalHex), &unmarshaledValue) + assert.NoError(t, err, "Unmarshaling should not produce an error") + // Marshal the value back to JSON - marshaledJSON, err := unmarshaledValue.MarshalJSON() + // using direct function + directMarshallJson, err := unmarshaledValue.MarshalJSON() assert.NoError(t, err, "Marshaling should not produce an error") + assert.Equal(t, originalHex, string(directMarshallJson)) - // Compare the original hex string with the marshaled JSON string - assert.Equal(t, "0x64", string(marshaledJSON), "Original hex and marshaled JSON should be equivalent") + // using json overloading ( satisfies the json.Unmarshal interface ) + // using value + marshalVal, err := json.Marshal(unmarshaledValue) + assert.NoError(t, err, "Marshaling should not produce an error") + assert.Equal(t, originalHex, string(marshalVal)) + + // using json overloading ( satisfies the json.Unmarshal interface ) + // using pointer + marshalPtr, err := json.Marshal(&unmarshaledValue) + assert.NoError(t, err, "Marshaling should not produce an error") + assert.Equal(t, originalHex, string(marshalPtr)) } func TestHexOrDecimal256MarshalUnmarshalWithNilError(t *testing.T) { diff --git a/thor/bytes32.go b/thor/bytes32.go index 586b788d0..2d89d13bb 100644 --- a/thor/bytes32.go +++ b/thor/bytes32.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" ) // Bytes32 array of 32 bytes. @@ -44,11 +45,10 @@ func (b Bytes32) IsZero() bool { } // MarshalJSON implements json.Marshaler. -func (b *Bytes32) MarshalJSON() ([]byte, error) { - if b == nil { - return json.Marshal(nil) - } - return json.Marshal(b.String()) +func (b Bytes32) MarshalJSON() ([]byte, error) { + // Convert Bytes32 to a hexadecimal string. + // if []byte = [00000...] then we return 0x000000 instead of nil + return json.Marshal(hexutil.Encode(b[:])) } // UnmarshalJSON implements json.Unmarshaler. diff --git a/thor/bytes32_test.go b/thor/bytes32_test.go new file mode 100644 index 000000000..61ccb9f8a --- /dev/null +++ b/thor/bytes32_test.go @@ -0,0 +1,46 @@ +// Copyright (c) 2024 The VeChainThor developers + +// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying +// file LICENSE or +package thor + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMarshalUnmarshall(t *testing.T) { + // Example hex string representing the value 100 + originalHex := `"0x00000000000000000000000000000000000000000000000000006d6173746572"` // Note the enclosing double quotes for valid JSON string + + // Unmarshal JSON into HexOrDecimal256 + var unmarshaledValue Bytes32 + + // using direct function + err := unmarshaledValue.UnmarshalJSON([]byte(originalHex)) + assert.NoError(t, err) + + // using json overloading ( satisfies the json.Unmarshal interface ) + err = json.Unmarshal([]byte(originalHex), &unmarshaledValue) + assert.NoError(t, err) + + // Marshal the value back to JSON + // using direct function + directMarshallJson, err := unmarshaledValue.MarshalJSON() + assert.NoError(t, err, "Marshaling should not produce an error") + assert.Equal(t, originalHex, string(directMarshallJson)) + + // using json overloading ( satisfies the json.Unmarshal interface ) + // using value + marshalVal, err := json.Marshal(unmarshaledValue) + assert.NoError(t, err) + assert.Equal(t, originalHex, string(marshalVal)) + + // using json overloading ( satisfies the json.Unmarshal interface ) + // using pointer + marshalPtr, err := json.Marshal(&unmarshaledValue) + assert.NoError(t, err, "Marshaling should not produce an error") + assert.Equal(t, originalHex, string(marshalPtr)) +}