diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 01d08ec5d4c..703d691141e 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -541,7 +541,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 } @@ -662,7 +662,7 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t sort.Sort(valset.ValidatorsByAddress(producerSet)) - headerVals, err := valset.ParseValidators(header.GetValidatorBytes(c.config)) + headerVals, err := valset.ParseValidators(GetValidatorBytes(header, c.config)) if err != nil { return err @@ -686,7 +686,7 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t // verify the validator list in the last sprint block if isSprintStart(number, sprintLength) { // Retrieve the snapshot needed to verify this header and cache it - parentValidatorBytes := parent.GetValidatorBytes(c.config) + parentValidatorBytes := GetValidatorBytes(parent, c.config) validatorsBytes := make([]byte, len(snap.ValidatorSet.Validators)*validatorHeaderBytesLength) currentValidators := snap.ValidatorSet.Copy().Validators @@ -1006,7 +1006,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, } @@ -1024,7 +1024,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, } @@ -1720,3 +1720,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 b306f900a8f..b38e10005c4 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -171,7 +171,7 @@ func (s *Snapshot) apply(headers []*types.Header, logger log.Logger) (*Snapshot, if err := ValidateHeaderExtraField(header.Extra); err != nil { return nil, 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 110ec371db2..5f805271b72 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -28,11 +28,9 @@ import ( "sync/atomic" "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/common/hexutil" @@ -47,17 +45,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. @@ -1406,41 +1393,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 cb81ca06d83..afd1d801cb2 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}})