Skip to content

Commit

Permalink
Simplify usage of FixedHash field on Block type
Browse files Browse the repository at this point in the history
  • Loading branch information
m-Peter committed Nov 4, 2024
1 parent 7ba15bc commit f8d4670
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 26 deletions.
35 changes: 14 additions & 21 deletions models/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,14 @@ func GenesisBlock(chainID flow.ChainID) *Block {

func NewBlockFromBytes(data []byte) (*Block, error) {
var b *Block
err := rlp.DecodeBytes(data, &b)
if err != nil {
if err := rlp.DecodeBytes(data, &b); err != nil {
pastBlock, err := decodeBlockBreakingChanges(data)
if err != nil {
return nil, err
}
b = pastBlock
}

// this is added because RLP decoding will decode into an empty string
if b.FixedHash != nil && *b.FixedHash == "" {
b.FixedHash = nil
}
return b, nil
}

Expand All @@ -51,10 +46,8 @@ type Block struct {
// will have more fields than before, so we make sure the hash we calculated
// with the previous format is fixed by assigning it to this field and then
// on hash calculation we check if this field is set we just return it.
// We must make the FixedHash exported so RLP encoding preserve it, and
// we must use string not common.Hash since RLP decoding has an issue
// with decoding into nil pointer slice.
FixedHash *string
// We must make the FixedHash exported so RLP encoding preserves it.
FixedHash gethCommon.Hash
TransactionHashes []gethCommon.Hash
}

Expand All @@ -63,8 +56,8 @@ func (b *Block) ToBytes() ([]byte, error) {
}

func (b *Block) Hash() (gethCommon.Hash, error) {
if b.FixedHash != nil && *b.FixedHash != "" {
return gethCommon.HexToHash(*b.FixedHash), nil
if b.FixedHash != zeroGethHash {
return b.FixedHash, nil
}
return b.Block.Hash()
}
Expand All @@ -81,13 +74,12 @@ func decodeBlockEvent(event cadence.Event) (*Block, *events.BlockEventPayload, e
)
}

var fixedHash *string
fixedHash := gethCommon.Hash{}
// If the `PrevRandao` field is the zero hash, we know that
// this is a block with the legacy format, and we need to
// fix its hash, due to the hash calculation breaking change.
if payload.PrevRandao == zeroGethHash {
hash := payload.Hash.String()
fixedHash = &hash
fixedHash = payload.Hash
}

return &Block{
Expand Down Expand Up @@ -115,7 +107,10 @@ type blockV0 struct {
// the fields from the blockV0Fields type.
func (b *blockV0) Hash() (gethCommon.Hash, error) {
data, err := b.Block.ToBytes()
return gethCrypto.Keccak256Hash(data), err
if err != nil {
return gethCommon.Hash{}, err
}
return gethCrypto.Keccak256Hash(data), nil
}

// blockV0Fields needed for decoding & computing the hash of blocks
Expand All @@ -136,20 +131,18 @@ func (b *blockV0Fields) ToBytes() ([]byte, error) {
}

// decodeBlockBreakingChanges will try to decode the bytes into all
// previous versions of block type, if it succeeds it will return the
// previous versions of block type. If it succeeds it will return the
// migrated block, otherwise it will return the decoding error.
func decodeBlockBreakingChanges(encoded []byte) (*Block, error) {
b0 := &blockV0{}
err := rlp.DecodeBytes(encoded, b0)
if err != nil {
if err := rlp.DecodeBytes(encoded, b0); err != nil {
return nil, err
}

blockHash, err := b0.Hash()
if err != nil {
return nil, err
}
h := blockHash.String()

return &Block{
Block: &types.Block{
Expand All @@ -161,7 +154,7 @@ func decodeBlockBreakingChanges(encoded []byte) (*Block, error) {
TransactionHashRoot: b0.Block.TransactionHashRoot,
TotalGasUsed: b0.Block.TotalGasUsed,
},
FixedHash: &h,
FixedHash: blockHash,
TransactionHashes: b0.TransactionHashes,
}, nil
}
16 changes: 12 additions & 4 deletions models/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ func Test_DecodePastBlockFormat(t *testing.T) {
block, err := NewBlockFromBytes(blockBytes)
require.NoError(t, err)

blockHash, err := block.Hash()
require.NoError(t, err)

assert.Equal(
t,
gethCommon.HexToHash("0xcad79e3019da8014f623f351f01c88d1bcb4613352d4801548c6b07992fd1393"),
blockHash,
)
assert.Equal(
t,
gethCommon.HexToHash("0x05aa4a6edbcf6fa81178566596be1c7fff7b721615c8b3bbd14ff76d9c81ec9b"),
Expand Down Expand Up @@ -66,12 +74,12 @@ func Test_DecodePastBlockFormat(t *testing.T) {
}

func Test_FixedHashBlock(t *testing.T) {
fixed := gethCommon.HexToHash("0x2").String()
fixed := gethCommon.HexToHash("0x2")
block := Block{
Block: &types.Block{
Height: 1,
},
FixedHash: &fixed,
FixedHash: fixed,
TransactionHashes: []gethCommon.Hash{
gethCommon.HexToHash("0x3"),
gethCommon.HexToHash("0x4"),
Expand All @@ -80,7 +88,7 @@ func Test_FixedHashBlock(t *testing.T) {

h, err := block.Hash()
require.NoError(t, err)
assert.Equal(t, fixed, h.String())
assert.Equal(t, fixed, h)

data, err := block.ToBytes()
require.NoError(t, err)
Expand All @@ -91,7 +99,7 @@ func Test_FixedHashBlock(t *testing.T) {
// make sure fixed hash and transaction hashes persists after decoding
h, err = decoded.Hash()
require.NoError(t, err)
require.Equal(t, fixed, h.String())
require.Equal(t, fixed, h)
require.Equal(t, block.TransactionHashes, decoded.TransactionHashes)
}

Expand Down
2 changes: 1 addition & 1 deletion tests/web3js/eth_non_interactive_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ it('get block', async () => {
block.transactionsRoot,
'0x0000000000000000000000000000000000000000000000000000000000000000'
)
assert.equal(block.size, 3995n)
assert.equal(block.size, 4028n)
assert.equal(block.gasLimit, 120000000n)
assert.equal(block.miner, '0x0000000000000000000000030000000000000000')
assert.equal(
Expand Down

0 comments on commit f8d4670

Please sign in to comment.