Skip to content

Commit

Permalink
Fix marshalling of CustomGenesis (#730)
Browse files Browse the repository at this point in the history
* fixes HexOrDecimal256 marshalling to json

* fix Bytes32 marshalling

* using default value method

* bytes32 nil marshalls to 0x0 instead of nil

* nits

* license
  • Loading branch information
otherview authored May 6, 2024
1 parent e61c650 commit 724e76f
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 10 deletions.
9 changes: 7 additions & 2 deletions genesis/customnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
38 changes: 35 additions & 3 deletions genesis/customnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package genesis_test

import (
"encoding/json"
"math"
"math/big"
"testing"
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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) {
Expand Down
10 changes: 5 additions & 5 deletions thor/bytes32.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"strings"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
)

// Bytes32 array of 32 bytes.
Expand Down Expand Up @@ -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.
Expand Down
46 changes: 46 additions & 0 deletions thor/bytes32_test.go
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/lgpl-3.0.html>
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))
}

0 comments on commit 724e76f

Please sign in to comment.