From edb1059b7b0c74c7e17ab356e26a1cace6c52b82 Mon Sep 17 00:00:00 2001 From: Bui Quang Minh Date: Thu, 16 May 2024 11:40:43 +0700 Subject: [PATCH] consortium-v1: add an option to disable checkpoint header check In version 1, the checkpoint header check happens early in the header verification step. This makes statedb read sometimes happens in incorrect statedb. While full sync, this leads to peer drop but still be able to continue syncing with other peers. However, while running import chain command or fast sync, this could lead to error. Add a option to disable checkpoint header check in these cases. --- cmd/utils/flags.go | 2 +- consensus/consortium/main.go | 4 +-- consensus/consortium/v1/consortium.go | 43 +++++++++++++++------------ eth/ethconfig/config.go | 2 +- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 65e284e746..a7c3b246fe 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2230,7 +2230,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai } else if config.Consortium != nil { ethApiBackend, fixupEth = eth.MakeEthApiBackend(chainDb) ethApi := ethapi.NewPublicBlockChainAPI(ethApiBackend) - engine = consortium.New(config, chainDb, ethApi) + engine = consortium.New(config, chainDb, ethApi, true) } else { engine = ethash.NewFaker() if !ctx.Bool(FakePoWFlag.Name) { diff --git a/consensus/consortium/main.go b/consensus/consortium/main.go index b2863c6f44..519e4a601a 100644 --- a/consensus/consortium/main.go +++ b/consensus/consortium/main.go @@ -27,9 +27,9 @@ type Consortium struct { } // New creates a Consortium proxy that decides what Consortium version will be called -func New(chainConfig *params.ChainConfig, db ethdb.Database, ee *ethapi.PublicBlockChainAPI) *Consortium { +func New(chainConfig *params.ChainConfig, db ethdb.Database, ee *ethapi.PublicBlockChainAPI, skipV1Check bool) *Consortium { // Set any missing consensus parameters to their defaults - consortiumV1 := v1.New(chainConfig, db, ee) + consortiumV1 := v1.New(chainConfig, db, ee, skipV1Check) consortiumV2 := v2.New(chainConfig, db, ee, consortiumV1) return &Consortium{ diff --git a/consensus/consortium/v1/consortium.go b/consensus/consortium/v1/consortium.go index 1adc03054b..e6b0b39c2c 100644 --- a/consensus/consortium/v1/consortium.go +++ b/consensus/consortium/v1/consortium.go @@ -117,11 +117,13 @@ type Consortium struct { getSCValidators func() ([]common.Address, error) // Get the list of validator from contract getFenixValidators func() ([]common.Address, error) // Get the validator list from Ronin Validator contract of Fenix hardfork + + skipCheckpointHeaderCheck bool } // New creates a Consortium proof-of-authority consensus engine with the initial // signers set to the ones provided by the user. -func New(chainConfig *params.ChainConfig, db ethdb.Database, ethAPI *ethapi.PublicBlockChainAPI) *Consortium { +func New(chainConfig *params.ChainConfig, db ethdb.Database, ethAPI *ethapi.PublicBlockChainAPI, skipCheckpointHeaderCheck bool) *Consortium { // Set any missing consensus parameters to their defaults consortiumConfig := *chainConfig.Consortium if consortiumConfig.Epoch == 0 { @@ -132,14 +134,15 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database, ethAPI *ethapi.Publ signatures, _ := lru.NewARC(inmemorySignatures) consortium := Consortium{ - chainConfig: chainConfig, - config: &consortiumConfig, - db: db, - recents: recents, - signatures: signatures, - ethAPI: ethAPI, - proposals: make(map[common.Address]bool), - signer: types.NewEIP155Signer(chainConfig.ChainID), + chainConfig: chainConfig, + config: &consortiumConfig, + db: db, + recents: recents, + signatures: signatures, + ethAPI: ethAPI, + proposals: make(map[common.Address]bool), + signer: types.NewEIP155Signer(chainConfig.ChainID), + skipCheckpointHeaderCheck: skipCheckpointHeaderCheck, } err := consortium.initContract(common.Address{}, nil) @@ -277,17 +280,19 @@ func (c *Consortium) verifyCascadingFields(chain consensus.ChainHeaderReader, he return c.verifySeal(chain, header, parents) } - signers, err := c.getValidatorsFromContract(chain, number-1) - if err != nil { - return err - } + if !c.skipCheckpointHeaderCheck { + signers, err := c.getValidatorsFromContract(chain, number-1) + if err != nil { + return err + } - extraSuffix := len(header.Extra) - consortiumCommon.ExtraSeal - checkpointHeaders := consortiumCommon.ExtractAddressFromBytes(header.Extra[extraVanity:extraSuffix]) - validSigners := consortiumCommon.CompareSignersLists(checkpointHeaders, signers) - if !validSigners { - log.Error("signers lists are different in checkpoint header and snapshot", "number", number, "signersHeader", checkpointHeaders, "signers", signers) - return consortiumCommon.ErrInvalidCheckpointSigners + extraSuffix := len(header.Extra) - consortiumCommon.ExtraSeal + checkpointHeaders := consortiumCommon.ExtractAddressFromBytes(header.Extra[extraVanity:extraSuffix]) + validSigners := consortiumCommon.CompareSignersLists(checkpointHeaders, signers) + if !validSigners { + log.Error("signers lists are different in checkpoint header and snapshot", "number", number, "signersHeader", checkpointHeaders, "signers", signers) + return consortiumCommon.ErrInvalidCheckpointSigners + } } // All basic checks passed, verify the seal and return diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 870d99bb52..5681bea965 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -239,7 +239,7 @@ func CreateConsensusEngine( return clique.New(chainConfig.Clique, db) } if chainConfig.Consortium != nil { - return consortium.New(chainConfig, db, ee) + return consortium.New(chainConfig, db, ee, false) } // Otherwise assume proof-of-work switch config.PowMode {