From 5c4517dfa437526379e2ef3f015bfdad07385e0d Mon Sep 17 00:00:00 2001 From: Pratik Patil Date: Fri, 18 Aug 2023 08:42:21 +0530 Subject: [PATCH 1/3] added TxDependency Metadata to ExtraData in Block Header in Bor for Block-STM --- consensus/bor/bor.go | 61 +++++++++++++++++++++------- consensus/bor/snapshot.go | 2 +- core/types/block.go | 54 +++++++++++++++++++++++- core/types/block_test.go | 55 +++++++++++++++++++++++++ erigon-lib/chain/chain_config.go | 13 ++++++ eth/stagedsync/stage_bor_heimdall.go | 5 ++- 6 files changed, 171 insertions(+), 19 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 507119845c3..674358c3f2b 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -68,9 +68,6 @@ var ( "0": 64, } // Default number of blocks after which to checkpoint and reset the pending votes - extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity - extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal - uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. // diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures @@ -154,11 +151,11 @@ func Ecrecover(header *types.Header, sigcache *lru.ARCCache[libcommon.Hash, libc return address, nil } // Retrieve the signature from the header extra-data - if len(header.Extra) < extraSeal { + if len(header.Extra) < types.ExtraSealLength { return libcommon.Address{}, errMissingSignature } - signature := header.Extra[len(header.Extra)-extraSeal:] + signature := header.Extra[len(header.Extra)-types.ExtraSealLength:] // Recover the public key and the Ethereum address pubkey, err := crypto.Ecrecover(SealHash(header, c).Bytes(), signature) @@ -542,7 +539,7 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head isSprintEnd := isSprintStart(number+1, c.config.CalculateSprint(number)) // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise - signersBytes := len(header.Extra) - extraVanity - extraSeal + signersBytes := len(header.GetValidatorBytes(c.config)) if !isSprintEnd && signersBytes != 0 { return errExtraValidators } @@ -584,11 +581,11 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head // ValidateHeaderExtraField validates that the extra-data contains both the vanity and signature. // header.Extra = header.Vanity + header.ProducerBytes (optional) + header.Seal func ValidateHeaderExtraField(extraBytes []byte) error { - if len(extraBytes) < extraVanity { + if len(extraBytes) < types.ExtraVanityLength { return errMissingVanity } - if len(extraBytes) < extraVanity+extraSeal { + if len(extraBytes) < types.ExtraVanityLength+types.ExtraSealLength { return errMissingSignature } @@ -917,11 +914,11 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s header.Difficulty = new(big.Int).SetUint64(snap.Difficulty(c.authorizedSigner.Load().signer)) // Ensure the extra data has all it's components - if len(header.Extra) < extraVanity { - header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...) + if len(header.Extra) < types.ExtraVanityLength { + header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, types.ExtraVanityLength-len(header.Extra))...) } - header.Extra = header.Extra[:extraVanity] + header.Extra = header.Extra[:types.ExtraVanityLength] // get validator set if number // Note: headers.Extra has producer set and not validator set. The bor @@ -941,13 +938,47 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s // sort validator by address sort.Sort(valset.ValidatorsByAddress(newValidators)) - for _, validator := range newValidators { - header.Extra = append(header.Extra, validator.HeaderBytes()...) + if c.config.IsParallelUniverse(header.Number.Uint64()) { + var tempValidatorBytes []byte + + for _, validator := range newValidators { + tempValidatorBytes = append(tempValidatorBytes, validator.HeaderBytes()...) + } + + blockExtraData := &types.BlockExtraData{ + ValidatorBytes: tempValidatorBytes, + TxDependency: nil, + } + + blockExtraDataBytes, err := rlp.EncodeToBytes(blockExtraData) + if err != nil { + log.Error("error while encoding block extra data: %v", err) + return fmt.Errorf("error while encoding block extra data: %v", err) + } + + header.Extra = append(header.Extra, blockExtraDataBytes...) + } else { + for _, validator := range newValidators { + header.Extra = append(header.Extra, validator.HeaderBytes()...) + } + } + } else if c.config.IsParallelUniverse(header.Number.Uint64()) { + blockExtraData := &types.BlockExtraData{ + ValidatorBytes: nil, + TxDependency: nil, + } + + blockExtraDataBytes, err := rlp.EncodeToBytes(blockExtraData) + if err != nil { + log.Error("error while encoding block extra data: %v", err) + return fmt.Errorf("error while encoding block extra data: %v", err) } + + header.Extra = append(header.Extra, blockExtraDataBytes...) } // add extra seal space - header.Extra = append(header.Extra, make([]byte, extraSeal)...) + header.Extra = append(header.Extra, make([]byte, types.ExtraSealLength)...) // Mix digest is reserved for now, set to empty header.MixDigest = libcommon.Hash{} @@ -1161,7 +1192,7 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result if err != nil { return err } - copy(header.Extra[len(header.Extra)-extraSeal:], sighash) + copy(header.Extra[len(header.Extra)-types.ExtraSealLength:], sighash) go func() { // Wait until sealing is terminated or delay timeout. diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index d28d76c7cfb..65a71b39658 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -181,7 +181,7 @@ func (s *Snapshot) Apply(parent *types.Header, headers []*types.Header, logger l if err := ValidateHeaderExtraField(header.Extra); err != nil { return snap, err } - validatorBytes := header.Extra[extraVanity : len(header.Extra)-extraSeal] + validatorBytes := header.GetValidatorBytes(s.config) // get validators from headers and use that for new validator set newVals, _ := valset.ParseValidators(validatorBytes) diff --git a/core/types/block.go b/core/types/block.go index af025683318..fb3662afddb 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -22,16 +22,19 @@ import ( "encoding/binary" "errors" "fmt" - "github.com/ledgerwatch/erigon-lib/common/hexutil" "io" "math/big" "reflect" "sync/atomic" + "github.com/ledgerwatch/erigon-lib/common/hexutil" + "github.com/gballet/go-verkle" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/hexutility" rlp2 "github.com/ledgerwatch/erigon-lib/rlp" + "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/rlp" @@ -40,8 +43,22 @@ import ( var ( EmptyRootHash = libcommon.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") EmptyUncleHash = rlpHash([]*Header(nil)) + + ExtraVanityLength = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity + ExtraSealLength = 65 // Fixed number of extra-data suffix bytes reserved for signer seal ) +// In bor, RLP encoding of BlockExtraData will be stored in the Extra field in the header +type BlockExtraData struct { + // Validator bytes of bor + ValidatorBytes []byte + + // length of TxDependency -> n (n = number of transactions in the block) + // length of TxDependency[i] -> k (k = a whole number) + // k elements in TxDependency[i] -> transaction indexes on which transaction i is dependent on + TxDependency [][]uint64 +} + // A BlockNonce is a 64-bit hash which proves (combined with the // mix-hash) that a sufficient amount of computation has been carried // out on a block. @@ -1390,6 +1407,41 @@ func (b *Block) ParentBeaconBlockRoot() *libcommon.Hash { return b.header.Parent func (b *Block) Header() *Header { return CopyHeader(b.header) } func (b *Block) HeaderNoCopy() *Header { return b.header } +// Returns the Block-STM Transaction Dependency from the block header +func (b *Block) GetTxDependency() [][]uint64 { + if len(b.header.Extra) < ExtraVanityLength+ExtraSealLength { + log.Error("length of extra less is than vanity and seal") + return nil + } + + var blockExtraData BlockExtraData + if err := rlp.DecodeBytes(b.header.Extra[ExtraVanityLength:len(b.header.Extra)-ExtraSealLength], &blockExtraData); err != nil { + log.Error("error while decoding block extra data", "err", err) + return nil + } + + return blockExtraData.TxDependency +} + +func (h *Header) GetValidatorBytes(config *chain.BorConfig) []byte { + if !config.IsParallelUniverse(h.Number.Uint64()) { + return h.Extra[ExtraVanityLength : len(h.Extra)-ExtraSealLength] + } + + if len(h.Extra) < ExtraVanityLength+ExtraSealLength { + log.Error("length of extra less is than vanity and seal") + return nil + } + + var blockExtraData BlockExtraData + if err := rlp.DecodeBytes(h.Extra[ExtraVanityLength:len(h.Extra)-ExtraSealLength], &blockExtraData); err != nil { + log.Error("error while decoding block extra data", "err", err) + return nil + } + + return blockExtraData.ValidatorBytes +} + // Body returns the non-header content of the block. func (b *Block) Body() *Body { bd := &Body{Transactions: b.transactions, Uncles: b.uncles, Withdrawals: b.withdrawals} diff --git a/core/types/block_test.go b/core/types/block_test.go index 3b62f66b18f..d7f79982ccb 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -28,6 +28,7 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/hexutility" types2 "github.com/ledgerwatch/erigon-lib/types" + "github.com/ledgerwatch/log/v3" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -39,6 +40,60 @@ import ( "github.com/ledgerwatch/erigon/rlp" ) +// This is a replica of `(h *Header) GetValidatorBytes` function +// This was needed because currently, `IsParallelUniverse` will always return false. +func GetValidatorBytesTest(h *Header) []byte { + if len(h.Extra) < ExtraVanityLength+ExtraSealLength { + log.Error("length of extra is less than vanity and seal") + return nil + } + + var blockExtraData BlockExtraData + if err := rlp.DecodeBytes(h.Extra[ExtraVanityLength:len(h.Extra)-ExtraSealLength], &blockExtraData); err != nil { + log.Error("error while decoding block extra data", "err", err) + return nil + } + + return blockExtraData.ValidatorBytes +} + +func TestTxDependencyBlockDecoding(t *testing.T) { + t.Parallel() + + blockEnc := common.FromHex("f90270f9026ba00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8825208845506eb07b8710000000000000000000000000000000000000000000000000000000000000000cf8776616c20736574c6c20201c201800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498880000000000000000c0c0") + + var block Block + + if err := rlp.DecodeBytes(blockEnc, &block); err != nil { + t.Fatal("decode error: ", err) + } + check := func(f string, got, want interface{}) { + if !reflect.DeepEqual(got, want) { + t.Errorf("%s mismatch: got %v, want %v", f, got, want) + } + } + + check("Coinbase", block.Coinbase(), libcommon.HexToAddress("8888f1f195afa192cfee860698584c030f4c9db1")) + check("MixDigest", block.MixDigest(), libcommon.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498")) + check("Root", block.Root(), libcommon.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017")) + check("Time", block.Time(), uint64(1426516743)) + + validatorBytes := GetValidatorBytesTest(block.header) + txDependency := block.GetTxDependency() + + check("validatorBytes", validatorBytes, []byte("val set")) + check("txDependency", txDependency, [][]uint64{{2, 1}, {1, 0}}) + + ourBlockEnc, err := rlp.EncodeToBytes(&block) + + if err != nil { + t.Fatal("encode error: ", err) + } + if !bytes.Equal(ourBlockEnc, blockEnc) { + t.Errorf("encoded block mismatch:\ngot: %x\nwant: %x", ourBlockEnc, blockEnc) + } +} + // from bcValidBlockTest.json, "SimpleTx" func TestBlockEncoding(t *testing.T) { t.Parallel() diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 78d8da8e6cd..6e93c59ff90 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -470,6 +470,8 @@ type BorConfig struct { AgraBlock *big.Int `json:"agraBlock"` // Agra switch block (nil = no fork, 0 = already in agra) StateSyncConfirmationDelay map[string]uint64 `json:"stateSyncConfirmationDelay"` // StateSync Confirmation Delay, in seconds, to calculate `to` + ParallelUniverseBlock *big.Int `json:"parallelUniverseBlock"` // TODO: update all occurrence, change name and finalize number (hardfork for block-stm related changes) + sprints sprints } @@ -561,6 +563,17 @@ func (c *BorConfig) IsIndore(number uint64) bool { return isForked(c.IndoreBlock, number) } +// TODO: modify this function once the block number is finalized +func (c *BorConfig) IsParallelUniverse(number uint64) bool { + if c.ParallelUniverseBlock != nil { + if c.ParallelUniverseBlock.Cmp(big.NewInt(0)) == 0 { + return false + } + } + + return isForked(c.ParallelUniverseBlock, number) +} + func (c *BorConfig) CalculateStateSyncDelay(number uint64) uint64 { return borKeyValueConfigHelper(c.StateSyncConfirmationDelay, number) } diff --git a/eth/stagedsync/stage_bor_heimdall.go b/eth/stagedsync/stage_bor_heimdall.go index 46b7507d3e3..982df52e25e 100644 --- a/eth/stagedsync/stage_bor_heimdall.go +++ b/eth/stagedsync/stage_bor_heimdall.go @@ -294,7 +294,7 @@ func BorHeimdallForward( if !mine && header != nil { sprintLength := cfg.chainConfig.Bor.CalculateSprint(blockNum) if blockNum > zerothSpanEnd && ((blockNum+1)%sprintLength == 0) { - if err = checkHeaderExtraData(u, ctx, chain, blockNum, header); err != nil { + if err = checkHeaderExtraData(u, ctx, chain, blockNum, header, cfg.chainConfig.Bor); err != nil { return err } } @@ -322,6 +322,7 @@ func checkHeaderExtraData( chain consensus.ChainHeaderReader, blockNum uint64, header *types.Header, + config *chain.BorConfig, ) error { var spanID uint64 if blockNum+1 > zerothSpanEnd { @@ -339,7 +340,7 @@ func checkHeaderExtraData( sort.Sort(valset.ValidatorsByAddress(producerSet)) - headerVals, err := valset.ParseValidators(header.Extra[extraVanity : len(header.Extra)-extraSeal]) + headerVals, err := valset.ParseValidators(header.GetValidatorBytes(config)) if err != nil { return err } From 4eae55987b15c553075e849afafe7ba7c69601d9 Mon Sep 17 00:00:00 2001 From: Pratik Patil Date: Wed, 18 Oct 2023 14:27:18 +0530 Subject: [PATCH 2/3] addressed comments, moved the functions to consensus/bor --- consensus/bor/bor.go | 57 ++++++++++++++++++++++++++++++++++++--- consensus/bor/snapshot.go | 2 +- core/types/block.go | 48 --------------------------------- core/types/block_test.go | 32 +++++++++++++++++++--- 4 files changed, 84 insertions(+), 55 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 674358c3f2b..fe913ed779e 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -539,7 +539,7 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head isSprintEnd := isSprintStart(number+1, c.config.CalculateSprint(number)) // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise - signersBytes := len(header.GetValidatorBytes(c.config)) + signersBytes := len(GetValidatorBytes(header, c.config)) if !isSprintEnd && signersBytes != 0 { return errExtraValidators } @@ -945,7 +945,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s tempValidatorBytes = append(tempValidatorBytes, validator.HeaderBytes()...) } - blockExtraData := &types.BlockExtraData{ + blockExtraData := &BlockExtraData{ ValidatorBytes: tempValidatorBytes, TxDependency: nil, } @@ -963,7 +963,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s } } } else if c.config.IsParallelUniverse(header.Number.Uint64()) { - blockExtraData := &types.BlockExtraData{ + blockExtraData := &BlockExtraData{ ValidatorBytes: nil, TxDependency: nil, } @@ -1607,3 +1607,54 @@ func getUpdatedValidatorSet(oldValidatorSet *valset.ValidatorSet, newVals []*val func isSprintStart(number, sprint uint64) bool { return number%sprint == 0 } + +// In bor, RLP encoding of BlockExtraData will be stored in the Extra field in the header +type BlockExtraData struct { + // Validator bytes of bor + ValidatorBytes []byte + + // length of TxDependency -> n (n = number of transactions in the block) + // length of TxDependency[i] -> k (k = a whole number) + // k elements in TxDependency[i] -> transaction indexes on which transaction i is dependent on + TxDependency [][]uint64 +} + +// Returns the Block-STM Transaction Dependency from the block header +func GetTxDependency(b *types.Block) [][]uint64 { + tempExtra := b.Extra() + + if len(tempExtra) < types.ExtraVanityLength+types.ExtraSealLength { + log.Error("length of extra less is than vanity and seal") + return nil + } + + var blockExtraData BlockExtraData + + if err := rlp.DecodeBytes(tempExtra[types.ExtraVanityLength:len(tempExtra)-types.ExtraSealLength], &blockExtraData); err != nil { + log.Error("error while decoding block extra data", "err", err) + return nil + } + + return blockExtraData.TxDependency +} + +func GetValidatorBytes(h *types.Header, config *chain.BorConfig) []byte { + tempExtra := h.Extra + + if !config.IsParallelUniverse(h.Number.Uint64()) { + return tempExtra[types.ExtraVanityLength : len(tempExtra)-types.ExtraSealLength] + } + + if len(tempExtra) < types.ExtraVanityLength+types.ExtraSealLength { + log.Error("length of extra less is than vanity and seal") + return nil + } + + var blockExtraData BlockExtraData + if err := rlp.DecodeBytes(tempExtra[types.ExtraVanityLength:len(tempExtra)-types.ExtraSealLength], &blockExtraData); err != nil { + log.Error("error while decoding block extra data", "err", err) + return nil + } + + return blockExtraData.ValidatorBytes +} diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 65a71b39658..836acf36343 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -181,7 +181,7 @@ func (s *Snapshot) Apply(parent *types.Header, headers []*types.Header, logger l if err := ValidateHeaderExtraField(header.Extra); err != nil { return snap, err } - validatorBytes := header.GetValidatorBytes(s.config) + validatorBytes := GetValidatorBytes(header, s.config) // get validators from headers and use that for new validator set newVals, _ := valset.ParseValidators(validatorBytes) diff --git a/core/types/block.go b/core/types/block.go index fb3662afddb..1a434098bbf 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -30,11 +30,9 @@ import ( "github.com/ledgerwatch/erigon-lib/common/hexutil" "github.com/gballet/go-verkle" - "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/hexutility" rlp2 "github.com/ledgerwatch/erigon-lib/rlp" - "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/rlp" @@ -48,17 +46,6 @@ var ( ExtraSealLength = 65 // Fixed number of extra-data suffix bytes reserved for signer seal ) -// In bor, RLP encoding of BlockExtraData will be stored in the Extra field in the header -type BlockExtraData struct { - // Validator bytes of bor - ValidatorBytes []byte - - // length of TxDependency -> n (n = number of transactions in the block) - // length of TxDependency[i] -> k (k = a whole number) - // k elements in TxDependency[i] -> transaction indexes on which transaction i is dependent on - TxDependency [][]uint64 -} - // A BlockNonce is a 64-bit hash which proves (combined with the // mix-hash) that a sufficient amount of computation has been carried // out on a block. @@ -1407,41 +1394,6 @@ func (b *Block) ParentBeaconBlockRoot() *libcommon.Hash { return b.header.Parent func (b *Block) Header() *Header { return CopyHeader(b.header) } func (b *Block) HeaderNoCopy() *Header { return b.header } -// Returns the Block-STM Transaction Dependency from the block header -func (b *Block) GetTxDependency() [][]uint64 { - if len(b.header.Extra) < ExtraVanityLength+ExtraSealLength { - log.Error("length of extra less is than vanity and seal") - return nil - } - - var blockExtraData BlockExtraData - if err := rlp.DecodeBytes(b.header.Extra[ExtraVanityLength:len(b.header.Extra)-ExtraSealLength], &blockExtraData); err != nil { - log.Error("error while decoding block extra data", "err", err) - return nil - } - - return blockExtraData.TxDependency -} - -func (h *Header) GetValidatorBytes(config *chain.BorConfig) []byte { - if !config.IsParallelUniverse(h.Number.Uint64()) { - return h.Extra[ExtraVanityLength : len(h.Extra)-ExtraSealLength] - } - - if len(h.Extra) < ExtraVanityLength+ExtraSealLength { - log.Error("length of extra less is than vanity and seal") - return nil - } - - var blockExtraData BlockExtraData - if err := rlp.DecodeBytes(h.Extra[ExtraVanityLength:len(h.Extra)-ExtraSealLength], &blockExtraData); err != nil { - log.Error("error while decoding block extra data", "err", err) - return nil - } - - return blockExtraData.ValidatorBytes -} - // Body returns the non-header content of the block. func (b *Block) Body() *Body { bd := &Body{Transactions: b.transactions, Uncles: b.uncles, Withdrawals: b.withdrawals} diff --git a/core/types/block_test.go b/core/types/block_test.go index d7f79982ccb..4e2a8303d3f 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -40,7 +40,8 @@ import ( "github.com/ledgerwatch/erigon/rlp" ) -// This is a replica of `(h *Header) GetValidatorBytes` function +// the following 2 functions are replica for the test +// This is a replica of `bor.GetValidatorBytes` function // This was needed because currently, `IsParallelUniverse` will always return false. func GetValidatorBytesTest(h *Header) []byte { if len(h.Extra) < ExtraVanityLength+ExtraSealLength { @@ -48,7 +49,7 @@ func GetValidatorBytesTest(h *Header) []byte { return nil } - var blockExtraData BlockExtraData + var blockExtraData BlockExtraDataTest if err := rlp.DecodeBytes(h.Extra[ExtraVanityLength:len(h.Extra)-ExtraSealLength], &blockExtraData); err != nil { log.Error("error while decoding block extra data", "err", err) return nil @@ -57,6 +58,31 @@ func GetValidatorBytesTest(h *Header) []byte { return blockExtraData.ValidatorBytes } +func GetTxDependencyTest(b *Block) [][]uint64 { + if len(b.header.Extra) < ExtraVanityLength+ExtraSealLength { + log.Error("length of extra less is than vanity and seal") + return nil + } + + var blockExtraData BlockExtraDataTest + if err := rlp.DecodeBytes(b.header.Extra[ExtraVanityLength:len(b.header.Extra)-ExtraSealLength], &blockExtraData); err != nil { + log.Error("error while decoding block extra data", "err", err) + return nil + } + + return blockExtraData.TxDependency +} + +type BlockExtraDataTest struct { + // Validator bytes of bor + ValidatorBytes []byte + + // length of TxDependency -> n (n = number of transactions in the block) + // length of TxDependency[i] -> k (k = a whole number) + // k elements in TxDependency[i] -> transaction indexes on which transaction i is dependent on + TxDependency [][]uint64 +} + func TestTxDependencyBlockDecoding(t *testing.T) { t.Parallel() @@ -79,7 +105,7 @@ func TestTxDependencyBlockDecoding(t *testing.T) { check("Time", block.Time(), uint64(1426516743)) validatorBytes := GetValidatorBytesTest(block.header) - txDependency := block.GetTxDependency() + txDependency := GetTxDependencyTest(&block) check("validatorBytes", validatorBytes, []byte("val set")) check("txDependency", txDependency, [][]uint64{{2, 1}, {1, 0}}) From ff3c80d0ad85564bdd90ec173772eb7288fc63a5 Mon Sep 17 00:00:00 2001 From: Pratik Patil Date: Fri, 24 Nov 2023 15:35:17 +0530 Subject: [PATCH 3/3] bug fix --- eth/stagedsync/stage_bor_heimdall.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/stagedsync/stage_bor_heimdall.go b/eth/stagedsync/stage_bor_heimdall.go index 982df52e25e..d990fc952de 100644 --- a/eth/stagedsync/stage_bor_heimdall.go +++ b/eth/stagedsync/stage_bor_heimdall.go @@ -340,7 +340,7 @@ func checkHeaderExtraData( sort.Sort(valset.ValidatorsByAddress(producerSet)) - headerVals, err := valset.ParseValidators(header.GetValidatorBytes(config)) + headerVals, err := valset.ParseValidators(bor.GetValidatorBytes(header, config)) if err != nil { return err }