Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chaincmd: correctly create consortium engine in import chain #371

Merged
merged 3 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
fixupEth 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, fixupEth = eth.MakeEthApiBackend(chainDb)
ethApi := ethapi.NewPublicBlockChainAPI(ethApiBackend)
engine = consortium.New(config, chainDb, ethApi, true)
} else {
engine = ethash.NewFaker()
if !ctx.Bool(FakePoWFlag.Name) {
Expand Down Expand Up @@ -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)
}
fixupEth(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
}

Expand Down
6 changes: 3 additions & 3 deletions consensus/consortium/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ 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, genesisHash common.Hash) *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)
consortiumV2 := v2.New(chainConfig, db, ee, genesisHash, consortiumV1)
consortiumV1 := v1.New(chainConfig, db, ee, skipV1Check)
consortiumV2 := v2.New(chainConfig, db, ee, consortiumV1)

return &Consortium{
chainConfig: chainConfig,
Expand Down
43 changes: 24 additions & 19 deletions consensus/consortium/v1/consortium.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions consensus/consortium/v2/consortium.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ type Consortium struct {
chainConfig *params.ChainConfig
config *params.ConsortiumConfig // Consensus engine configuration parameters
forkedBlock uint64
genesisHash common.Hash
db ethdb.Database // Database to store and retrieve snapshot checkpoints

recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
Expand All @@ -120,7 +119,6 @@ func New(
chainConfig *params.ChainConfig,
db ethdb.Database,
ethAPI *ethapi.PublicBlockChainAPI,
genesisHash common.Hash,
v1 consortiumCommon.ConsortiumAdapter,
) *Consortium {
consortiumConfig := chainConfig.Consortium
Expand All @@ -136,7 +134,6 @@ func New(
consortium := Consortium{
chainConfig: chainConfig,
config: consortiumConfig,
genesisHash: genesisHash,
db: db,
ethAPI: ethAPI,
recents: recents,
Expand Down
20 changes: 19 additions & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
log.Info("Unprotected transactions allowed")
}
ethAPI := ethapi.NewPublicBlockChainAPI(eth.APIBackend)
eth.engine = ethconfig.CreateConsensusEngine(stack, chainConfig, &ethashConfig, config.Miner.Notify, config.Miner.Noverify, chainDb, ethAPI, genesisHash)
eth.engine = ethconfig.CreateConsensusEngine(stack, chainConfig, &ethashConfig, config.Miner.Notify, config.Miner.Noverify, chainDb, ethAPI)

bcVersion := rawdb.ReadDatabaseVersion(chainDb)
var dbVer = "<nil>"
Expand Down Expand Up @@ -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, engine 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: &ethconfig.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
Expand Down
12 changes: 10 additions & 2 deletions eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,21 @@ type Config struct {
}

// CreateConsensusEngine creates a consensus engine for the given chain configuration.
func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database, ee *ethapi.PublicBlockChainAPI, genesisHash common.Hash) consensus.Engine {
func CreateConsensusEngine(
stack *node.Node,
chainConfig *params.ChainConfig,
config *ethash.Config,
notify []string,
noverify bool,
db ethdb.Database,
ee *ethapi.PublicBlockChainAPI,
) consensus.Engine {
// If proof-of-authority is requested, set it up
if chainConfig.Clique != nil {
return clique.New(chainConfig.Clique, db)
}
if chainConfig.Consortium != nil {
return consortium.New(chainConfig, db, ee, genesisHash)
return consortium.New(chainConfig, db, ee, false)
}
// Otherwise assume proof-of-work
switch config.PowMode {
Expand Down
2 changes: 1 addition & 1 deletion les/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) {
eventMux: stack.EventMux(),
reqDist: newRequestDistributor(peers, &mclock.System{}),
accountManager: stack.AccountManager(),
engine: ethconfig.CreateConsensusEngine(stack, chainConfig, &config.Ethash, nil, false, chainDb, nil, genesisHash),
engine: ethconfig.CreateConsensusEngine(stack, chainConfig, &config.Ethash, nil, false, chainDb, nil),
bloomRequests: make(chan chan *bloombits.Retrieval),
bloomIndexer: core.NewBloomIndexer(chainDb, params.BloomBitsBlocksClient, params.HelperTrieConfirmations),
p2pServer: stack.Server(),
Expand Down
Loading