From c7ec1363d5cda9d3bed72a40c1d6ab19f7613ee0 Mon Sep 17 00:00:00 2001 From: Bui Quang Minh Date: Wed, 18 Oct 2023 18:24:24 +0700 Subject: [PATCH] chaincmd: correctly create consortium engine in import chain Currently, when import chain is used, we don't recognize the chain config to create the consortium engine. This commit creates the consortium engine when it is set in the chain config. --- cmd/utils/flags.go | 32 +++++++++++++++++++++++++++++++- eth/backend.go | 18 ++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d13682d0c3..2c15ecc025 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -38,9 +38,11 @@ import ( "github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/consensus/consortium" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" @@ -2218,9 +2220,17 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai if err != nil { Fatalf("%v", err) } - var engine consensus.Engine + var ( + engine consensus.Engine + setupAPIBackend func(chain *core.BlockChain, engine consensus.Engine) + ethApiBackend *eth.EthAPIBackend + ) if config.Clique != nil { engine = clique.New(config.Clique, chainDb) + } else if config.Consortium != nil { + ethApiBackend, setupAPIBackend = eth.MakeEthApiBackend(chainDb) + ethApi := ethapi.NewPublicBlockChainAPI(ethApiBackend) + engine = consortium.New(config, chainDb, ethApi) } else { engine = ethash.NewFaker() if !ctx.Bool(FakePoWFlag.Name) { @@ -2269,6 +2279,26 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai if err != nil { Fatalf("Can't create BlockChain: %v", err) } + setupAPIBackend(chain, engine) + if config.Consortium != nil { + c := engine.(*consortium.Consortium) + c.SetGetSCValidatorsFn(func() ([]common.Address, error) { + stateDb, err := chain.State() + if err != nil { + log.Crit("Cannot get state of blockchain", "err", err) + return nil, err + } + return state.GetSCValidators(stateDb), nil + }) + c.SetGetFenixValidators(func() ([]common.Address, error) { + stateDb, err := chain.State() + if err != nil { + log.Crit("Cannot get state of blockchain", "err", err) + return nil, err + } + return state.GetFenixValidators(stateDb, config.FenixValidatorContractAddress), nil + }) + } return chain, chainDb } diff --git a/eth/backend.go b/eth/backend.go index bf1c383640..b3cfc0596b 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -352,6 +352,24 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { return eth, nil } +// MakeEthApiBackend is used by MakeChain to create a minimal eth API backend for consortium +// engine. +// This code looks hacky as it returns a function to set the private blockchain field. This is +// due to the circular dependency as blockchain needs consortium engine which requires +// eth API backend. As the eth API backend is not used right after being created, we create a +// eth API backend without blockchain here and set that field later when blockchain is available. +func MakeEthApiBackend(chainDb ethdb.Database) (*EthAPIBackend, func(chain *core.BlockChain, engine consensus.Engine)) { + eth := &Ethereum{ + chainDb: chainDb, + config: ðconfig.Defaults, + } + apiBackend := &EthAPIBackend{eth: eth} + return apiBackend, func(chain *core.BlockChain, engine consensus.Engine) { + eth.blockchain = chain + eth.engine = engine + } +} + func makeExtraData(extra []byte) []byte { if len(extra) == 0 { // create default extradata