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