From 16294393a18b03342abf7b965939cc7578a678f6 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:39:53 +0200 Subject: [PATCH 1/2] use past block decoder --- models/block.go | 216 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 178 insertions(+), 38 deletions(-) diff --git a/models/block.go b/models/block.go index 497d6724..18db50aa 100644 --- a/models/block.go +++ b/models/block.go @@ -27,26 +27,15 @@ func NewBlockFromBytes(data []byte) (*Block, error) { err := rlp.DecodeBytes(data, &b) if err != nil { // todo temp remove this after previewnet is deprecated - var bV0360 *blockV0360 - if err := rlp.DecodeBytes(data, &bV0360); err != nil { - return nil, fmt.Errorf("failed to decode block [%x]: %w", data, err) + pastBlock := decodeBlockBreakingChanges(data) + if pastBlock == nil { + return nil, err } - b = &Block{ - Block: &types.Block{ - ParentBlockHash: bV0360.ParentBlockHash, - Height: bV0360.Height, - Timestamp: bV0360.Timestamp, - TotalSupply: bV0360.TotalSupply, - ReceiptRoot: bV0360.ReceiptRoot, - TransactionHashRoot: gethCommon.Hash{}, - TotalGasUsed: bV0360.TotalGasUsed, - }, - TransactionHashes: bV0360.TransactionHashes, - } - h, err := bV0360.Hash() + h, err := pastBlockHash(pastBlock) if err != nil { - return nil, fmt.Errorf("failed to calculate backward compatible hash for block: %w", err) + return nil, err } + b = pastBlock b.hash = &h } @@ -93,32 +82,183 @@ func decodeBlockEvent(event cadence.Event) (*Block, error) { }, nil } -// TODO temp remove after previewnet is deprecated -// this is an older format for the block, that contains transaction hashes -type blockV0360 struct { - // the hash of the parent block +// todo past decoding of blocks, moved from flow-go, remove after previewnet is deprecated + +type blockV0 struct { ParentBlockHash gethCommon.Hash - // Height returns the height of this block - Height uint64 - // Timestamp is a Unix timestamp in seconds at which the block was created - // Note that this value must be provided from the FVM Block - Timestamp uint64 - // holds the total amount of the native token deposited in the evm side. (in attoflow) - TotalSupply *big.Int - // ReceiptRoot returns the root hash of the receipts emitted in this block - // Note that this value won't be unique to each block, for example for the - // case of empty trie of receipts or a single receipt with no logs and failed state - // the same receipt root would be reported for block. - ReceiptRoot gethCommon.Hash - - // transaction hashes + Height uint64 + UUIDIndex uint64 + TotalSupply uint64 + StateRoot gethCommon.Hash + ReceiptRoot gethCommon.Hash +} + +// adds TransactionHashes + +type blockV1 struct { + ParentBlockHash gethCommon.Hash + Height uint64 + UUIDIndex uint64 + TotalSupply uint64 + StateRoot gethCommon.Hash + ReceiptRoot gethCommon.Hash + TransactionHashes []gethCommon.Hash +} + +// removes UUIDIndex + +type blockV2 struct { + ParentBlockHash gethCommon.Hash + Height uint64 + TotalSupply uint64 + StateRoot gethCommon.Hash + ReceiptRoot gethCommon.Hash + TransactionHashes []gethCommon.Hash +} + +// removes state root + +type blockV3 struct { + ParentBlockHash gethCommon.Hash + Height uint64 + TotalSupply uint64 + ReceiptRoot gethCommon.Hash + TransactionHashes []gethCommon.Hash +} + +// change total supply type + +type blockV4 struct { + ParentBlockHash gethCommon.Hash + Height uint64 + TotalSupply *big.Int + ReceiptRoot gethCommon.Hash + TransactionHashes []gethCommon.Hash +} + +// adds timestamp + +type blockV5 struct { + ParentBlockHash gethCommon.Hash + Height uint64 + Timestamp uint64 + TotalSupply *big.Int + ReceiptRoot gethCommon.Hash TransactionHashes []gethCommon.Hash +} - // stores gas used by all transactions included in the block. - TotalGasUsed uint64 +// adds total gas used + +type blockV6 struct { + ParentBlockHash gethCommon.Hash + Height uint64 + Timestamp uint64 + TotalSupply *big.Int + ReceiptRoot gethCommon.Hash + TransactionHashes []gethCommon.Hash + TotalGasUsed uint64 } -func (b *blockV0360) Hash() (gethCommon.Hash, error) { +func pastBlockHash(b any) (gethCommon.Hash, error) { data, err := rlp.EncodeToBytes(b) return gethCrypto.Keccak256Hash(data), err } + +// decodeBlockBreakingChanges will try to decode the bytes into all +// previous versions of block type, if it succeeds it will return the +// migrated block, otherwise it will return nil. +func decodeBlockBreakingChanges(encoded []byte) *Block { + b0 := &blockV0{} + if err := rlp.DecodeBytes(encoded, b0); err == nil { + return &Block{ + Block: &types.Block{ + ParentBlockHash: b0.ParentBlockHash, + Height: b0.Height, + ReceiptRoot: b0.ReceiptRoot, + TotalSupply: big.NewInt(int64(b0.TotalSupply)), + }, + } + } + + b1 := &blockV1{} + if err := rlp.DecodeBytes(encoded, b1); err == nil { + return &Block{ + Block: &types.Block{ + ParentBlockHash: b1.ParentBlockHash, + Height: b1.Height, + TotalSupply: big.NewInt(int64(b1.TotalSupply)), + ReceiptRoot: b1.ReceiptRoot, + }, + TransactionHashes: b1.TransactionHashes, + } + } + + b2 := &blockV2{} + if err := rlp.DecodeBytes(encoded, b2); err == nil { + return &Block{ + Block: &types.Block{ + ParentBlockHash: b2.ParentBlockHash, + Height: b2.Height, + TotalSupply: big.NewInt(int64(b2.TotalSupply)), + ReceiptRoot: b2.ReceiptRoot, + }, + TransactionHashes: b2.TransactionHashes, + } + } + + b3 := &blockV3{} + if err := rlp.DecodeBytes(encoded, b3); err == nil { + return &Block{ + Block: &types.Block{ + ParentBlockHash: b3.ParentBlockHash, + Height: b3.Height, + TotalSupply: big.NewInt(int64(b3.TotalSupply)), + ReceiptRoot: b3.ReceiptRoot, + }, + TransactionHashes: b3.TransactionHashes, + } + } + + b4 := &blockV4{} + if err := rlp.DecodeBytes(encoded, b4); err == nil { + return &Block{ + Block: &types.Block{ + ParentBlockHash: b4.ParentBlockHash, + Height: b4.Height, + TotalSupply: b4.TotalSupply, + ReceiptRoot: b4.ReceiptRoot, + }, + TransactionHashes: b4.TransactionHashes, + } + } + + b5 := &blockV5{} + if err := rlp.DecodeBytes(encoded, b5); err == nil { + return &Block{ + Block: &types.Block{ + ParentBlockHash: b5.ParentBlockHash, + Height: b5.Height, + Timestamp: b5.Timestamp, + TotalSupply: b5.TotalSupply, + ReceiptRoot: b5.ReceiptRoot, + }, + TransactionHashes: b5.TransactionHashes, + } + } + + b6 := &blockV6{} + if err := rlp.DecodeBytes(encoded, b6); err == nil { + return &Block{ + Block: &types.Block{ + ParentBlockHash: b5.ParentBlockHash, + Height: b5.Height, + Timestamp: b5.Timestamp, + TotalSupply: b5.TotalSupply, + ReceiptRoot: b5.ReceiptRoot, + }, + TransactionHashes: b6.TransactionHashes, + } + } + + return nil +} From c4c3b0862e3dbbb962c4be70170d768d6709c679 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:48:43 +0200 Subject: [PATCH 2/2] use b6 values --- models/block.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/models/block.go b/models/block.go index 18db50aa..2b2c5b6d 100644 --- a/models/block.go +++ b/models/block.go @@ -250,11 +250,12 @@ func decodeBlockBreakingChanges(encoded []byte) *Block { if err := rlp.DecodeBytes(encoded, b6); err == nil { return &Block{ Block: &types.Block{ - ParentBlockHash: b5.ParentBlockHash, - Height: b5.Height, - Timestamp: b5.Timestamp, - TotalSupply: b5.TotalSupply, - ReceiptRoot: b5.ReceiptRoot, + ParentBlockHash: b6.ParentBlockHash, + Height: b6.Height, + Timestamp: b6.Timestamp, + TotalSupply: b6.TotalSupply, + ReceiptRoot: b6.ReceiptRoot, + TotalGasUsed: b6.TotalGasUsed, }, TransactionHashes: b6.TransactionHashes, }