diff --git a/consensus/consortium/v2/api.go b/consensus/consortium/v2/api.go index a168eeb164..3ac0167e5f 100644 --- a/consensus/consortium/v2/api.go +++ b/consensus/consortium/v2/api.go @@ -52,8 +52,7 @@ func (api *consortiumV2Api) GetFinalityVoteAtHash(hash common.Hash) (*finalityVo return nil, consortiumCommon.ErrUnknownBlock } - isShillin := api.consortium.chainConfig.IsShillin(header.Number) - extraData, err := finality.DecodeExtra(header.Extra, isShillin) + extraData, err := finality.DecodeExtraV2(header.Extra, api.consortium.chainConfig, header.Number) if err != nil { return nil, err } diff --git a/consensus/consortium/v2/consortium.go b/consensus/consortium/v2/consortium.go index 0b91785870..1745260a39 100644 --- a/consensus/consortium/v2/consortium.go +++ b/consensus/consortium/v2/consortium.go @@ -359,7 +359,7 @@ func (c *Consortium) verifyCascadingFields(chain consensus.ChainHeaderReader, he // Check extra data isShillin := c.chainConfig.IsShillin(header.Number) - extraData, err := finality.DecodeExtra(header.Extra, isShillin) + extraData, err := finality.DecodeExtraV2(header.Extra, c.chainConfig, header.Number) if err != nil { return err } @@ -726,7 +726,6 @@ func (c *Consortium) Prepare(chain consensus.ChainHeaderReader, header *types.He // Set the correct difficulty header.Difficulty = CalcDifficulty(snap, coinbase) - isShillin := c.chainConfig.IsShillin(header.Number) var extraData finality.HeaderExtraData if number%c.config.EpochV2 == 0 || c.chainConfig.IsOnConsortiumV2(big.NewInt(int64(number))) { @@ -741,7 +740,10 @@ func (c *Consortium) Prepare(chain consensus.ChainHeaderReader, header *types.He // not assemble finality vote yet. Let's wait some time for the // finality votes to be broadcasted around the network. The // finality votes are assembled later in Seal function. - header.Extra = extraData.Encode(isShillin) + header.Extra, err = extraData.EncodeV2(c.chainConfig, header.Number) + if err != nil { + return err + } // Mix digest is reserved for now, set to empty header.MixDigest = common.Hash{} @@ -767,9 +769,10 @@ func (c *Consortium) processSystemTransactions(chain consensus.ChainHeaderReader _, _, _, contract := c.readSignerAndContract() // If the parent's block includes the finality votes, distribute reward for the voters - if c.chainConfig.IsShillin(new(big.Int).Sub(header.Number, common.Big1)) { + parentNumber := new(big.Int).Sub(header.Number, common.Big1) + if c.chainConfig.IsShillin(parentNumber) { parentHeader := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) - extraData, err := finality.DecodeExtra(parentHeader.Extra, true) + extraData, err := finality.DecodeExtraV2(parentHeader.Extra, c.chainConfig, parentNumber) if err != nil { return err } @@ -891,7 +894,7 @@ func (c *Consortium) Finalize(chain consensus.ChainHeaderReader, header *types.H if err != nil { return err } - extraData, err := finality.DecodeExtra(header.Extra, isShillin) + extraData, err := finality.DecodeExtraV2(header.Extra, c.chainConfig, header.Number) if err != nil { return err } @@ -1097,9 +1100,15 @@ func (c *Consortium) SealHash(header *types.Header) common.Hash { // FinalizeAndAssemble call. copyHeader := types.CopyHeader(header) - extraData, _ := finality.DecodeExtra(copyHeader.Extra, true) + extraData, err := finality.DecodeExtraV2(copyHeader.Extra, c.chainConfig, header.Number) + if err != nil { + log.Error("Failed to decode header extra data", "err", err) + } extraData.HasFinalityVote = 0 - copyHeader.Extra = extraData.Encode(true) + copyHeader.Extra, err = extraData.EncodeV2(c.chainConfig, header.Number) + if err != nil { + log.Error("Failed to encode header extra data", "err", err) + } return calculateSealHash(copyHeader, c.chainConfig.ChainID) } else { return calculateSealHash(header, c.chainConfig.ChainID) @@ -1263,7 +1272,7 @@ func (c *Consortium) assembleFinalityVote(header *types.Header, snap *Snapshot) bitSetCount := len(finalityVotedValidators.Indices()) if bitSetCount >= finalityThreshold { - extraData, err := finality.DecodeExtra(header.Extra, true) + extraData, err := finality.DecodeExtraV2(header.Extra, c.chainConfig, header.Number) if err != nil { // This should not happen log.Error("Failed to decode header extra data", "err", err) @@ -1272,7 +1281,11 @@ func (c *Consortium) assembleFinalityVote(header *types.Header, snap *Snapshot) extraData.HasFinalityVote = 1 extraData.FinalityVotedValidators = finalityVotedValidators extraData.AggregatedFinalityVotes = blst.AggregateSignatures(signatures) - header.Extra = extraData.Encode(true) + header.Extra, err = extraData.EncodeV2(c.chainConfig, header.Number) + if err != nil { + log.Error("Failed to encode header extra data", "err", err) + return + } } } } diff --git a/consensus/consortium/v2/consortium_test.go b/consensus/consortium/v2/consortium_test.go index 59c10c0c87..fe345a4918 100644 --- a/consensus/consortium/v2/consortium_test.go +++ b/consensus/consortium/v2/consortium_test.go @@ -3,8 +3,10 @@ package v2 import ( "bytes" "crypto/ecdsa" + "crypto/rand" "encoding/binary" "errors" + "io" "math/big" "testing" "time" @@ -530,6 +532,173 @@ func TestExtraDataDecode(t *testing.T) { } } +func mockExtraData(nVal int, bits uint32) *finality.HeaderExtraData { + var ( + finalityVotedValidators finality.FinalityVoteBitSet + aggregatedFinalityVotes blsCommon.Signature + checkpointValidators []finality.ValidatorWithBlsPub + seal = make([]byte, finality.ExtraSeal) + ret = &finality.HeaderExtraData{} + ) + + bits = bits % 7 // ensure bits can be represented by 3-bit integer + for i := 0; i < 3; i++ { + if bits&(1<