diff --git a/consensus/engine/consensus_engine.go b/consensus/engine/consensus_engine.go index 3e7cc3b34..0879a5f54 100644 --- a/consensus/engine/consensus_engine.go +++ b/consensus/engine/consensus_engine.go @@ -79,7 +79,7 @@ type Engine interface { // via the VerifySeal method. VerifyHeader(chain ChainReader, header *block.Header, seal bool) error - // Similiar to VerifyHeader, which is only for verifying the block headers of one's own chain, this verification + // VerifyHeaderSignature similar to VerifyHeader, which is only for verifying the block headers of one's own chain, this verification // is used for verifying "incoming" block header against commit signature and bitmap sent from the other chain cross-shard via libp2p. // i.e. this header verification api is more flexible since the caller specifies which commit signature and bitmap to use // for verifying the block header, which is necessary for cross-shard block header verification. Example of such is cross-shard transaction. diff --git a/core/blockchain.go b/core/blockchain.go index a28df6bab..fda483165 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -126,6 +126,8 @@ type BlockChain interface { GetHeaderByNumber(number uint64) *block.Header // Config retrieves the blockchain's chain configuration. Config() *params.ChainConfig + // Engine retrieves the blockchain's consensus engine. + Engine() engine.Engine // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent. SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription // SubscribeTraceEvent registers a subscription of ChainEvent. diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index 5ed122420..515c4099f 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -49,8 +49,6 @@ import ( "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/crypto/bls" - "github.com/harmony-one/harmony/internal/chain" - chain2 "github.com/harmony-one/harmony/internal/chain" harmonyconfig "github.com/harmony-one/harmony/internal/configs/harmony" "github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/tikv" @@ -192,6 +190,7 @@ type BlockChainImpl struct { // procInterrupt must be atomically called procInterrupt int32 // interrupt signaler for block processing + engine consensus_engine.Engine processor Processor // block processor interface validator Validator // block and state validator interface vmConfig vm.Config @@ -205,9 +204,9 @@ type BlockChainImpl struct { // NewBlockChainWithOptions same as NewBlockChain but can accept additional behaviour options. func NewBlockChainWithOptions( db ethdb.Database, stateCache state.Database, beaconChain BlockChain, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, - vmConfig vm.Config, options Options, + engine consensus_engine.Engine, vmConfig vm.Config, options Options, ) (*BlockChainImpl, error) { - return newBlockChainWithOptions(db, stateCache, beaconChain, cacheConfig, chainConfig, vmConfig, options) + return newBlockChainWithOptions(db, stateCache, beaconChain, cacheConfig, chainConfig, engine, vmConfig, options) } // NewBlockChain returns a fully initialised block chain using information @@ -215,15 +214,15 @@ func NewBlockChainWithOptions( // Processor. func NewBlockChain( db ethdb.Database, stateCache state.Database, beaconChain BlockChain, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, - vmConfig vm.Config, + engine consensus_engine.Engine, vmConfig vm.Config, ) (*BlockChainImpl, error) { - return newBlockChainWithOptions(db, stateCache, beaconChain, cacheConfig, chainConfig, vmConfig, Options{}) + return newBlockChainWithOptions(db, stateCache, beaconChain, cacheConfig, chainConfig, engine, vmConfig, Options{}) } func newBlockChainWithOptions( db ethdb.Database, stateCache state.Database, beaconChain BlockChain, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, - vmConfig vm.Config, options Options) (*BlockChainImpl, error) { + engine consensus_engine.Engine, vmConfig vm.Config, options Options) (*BlockChainImpl, error) { bodyCache, _ := lru.New(bodyCacheLimit) bodyRLPCache, _ := lru.New(bodyCacheLimit) @@ -267,6 +266,7 @@ func newBlockChainWithOptions( blockAccumulatorCache: blockAccumulatorCache, leaderPubKeyFromCoinbase: leaderPubKeyFromCoinbase, blockchainPruner: newBlockchainPruner(db), + engine: engine, vmConfig: vmConfig, badBlocks: badBlocks, pendingSlashes: slash.Records{}, @@ -353,7 +353,7 @@ func VerifyCrossLink(blockchain BlockChain, cl types.CrossLink) error { if blockchain.ShardID() != shard.BeaconChainShardID { return errors.New("[VerifyCrossLink] Shard chains should not verify cross links") } - engine := chain.Engine() + engine := blockchain.Engine() if err := engine.VerifyCrossLink(blockchain, cl); err != nil { return errors.Wrap(err, "[VerifyCrossLink]") @@ -424,7 +424,7 @@ func (bc *BlockChainImpl) ValidateNewBlock(block *types.Block, beaconChain Block Msg("[ValidateNewBlock] Cannot validate header for the new block") return err } - if err := chain.Engine().VerifyVRF( + if err := bc.Engine().VerifyVRF( bc, block.Header(), ); err != nil { utils.Logger().Error(). @@ -436,7 +436,7 @@ func (bc *BlockChainImpl) ValidateNewBlock(block *types.Block, beaconChain Block "[ValidateNewBlock] Cannot verify vrf for the new block", ) } - err := chain.Engine().VerifyShardState(bc, beaconChain, block.Header()) + err := bc.Engine().VerifyShardState(bc, beaconChain, block.Header()) if err != nil { utils.Logger().Error(). Str("blockHash", block.Hash().Hex()). @@ -1577,7 +1577,7 @@ func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (i seals[i] = true } // Note that VerifyHeaders verifies headers in the chain in parallel - abort, results := chain2.Engine().VerifyHeaders(bc, headers, seals) + abort, results := bc.Engine().VerifyHeaders(bc, headers, seals) verifyHeadersResults = results defer close(abort) } @@ -2045,6 +2045,8 @@ func (bc *BlockChainImpl) GetHeaderByNumber(number uint64) *block.Header { func (bc *BlockChainImpl) Config() *params.ChainConfig { return bc.chainConfig } +func (bc *BlockChainImpl) Engine() consensus_engine.Engine { return bc.engine } + func (bc *BlockChainImpl) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription { return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch)) } diff --git a/core/blockchain_stub.go b/core/blockchain_stub.go index f1c27f574..f9e9111ea 100644 --- a/core/blockchain_stub.go +++ b/core/blockchain_stub.go @@ -141,6 +141,10 @@ func (a Stub) Config() *params.ChainConfig { return nil } +func (a Stub) Engine() engine.Engine { + return nil +} + func (a Stub) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription { return nil } diff --git a/core/epochchain.go b/core/epochchain.go index 507142f39..ede5ec5a7 100644 --- a/core/epochchain.go +++ b/core/epochchain.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/harmony-one/harmony/block" + "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/vm" @@ -128,7 +129,7 @@ func (bc *EpochChain) InsertChain(blocks types.Blocks, _ bool) (int, error) { } // Signature validation. - err = chain.Engine().VerifyHeaderSignature(bc, block.Header(), sig, bitmap) + err = bc.Engine().VerifyHeaderSignature(bc, block.Header(), sig, bitmap) if err != nil { return i, errors.Wrap(err, "failed signature validation") } @@ -238,6 +239,10 @@ func (bc *EpochChain) Config() *params.ChainConfig { return bc.chainConfig } +func (bc *EpochChain) Engine() engine.Engine { + return chain.Engine() +} + func (bc *EpochChain) ReadShardState(epoch *big.Int) (*shard.State, error) { cacheKey := string(epoch.Bytes()) if cached, ok := bc.shardStateCache.Get(cacheKey); ok { diff --git a/core/epochchain_test.go b/core/epochchain_test.go index 7a0d75423..91c85bfdb 100644 --- a/core/epochchain_test.go +++ b/core/epochchain_test.go @@ -12,7 +12,7 @@ import ( func TestGenesisBlock(t *testing.T) { db := rawdb.NewMemoryDatabase() - err := (&core.GenesisInitializer{NetworkType: nodeconfig.Mainnet}).InitChainDB(db, 0) + err := (&core.GenesisInitializer{}).InitChainDB(db, nodeconfig.Mainnet, 0) require.NoError(t, err) chain, err := core.NewEpochChain(db, nil, vm.Config{}) diff --git a/core/evm_test.go b/core/evm_test.go index ed6821ff5..3201ee116 100644 --- a/core/evm_test.go +++ b/core/evm_test.go @@ -21,6 +21,7 @@ import ( "github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/crypto/hash" + "github.com/harmony-one/harmony/internal/chain" "github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/numeric" staking "github.com/harmony-one/harmony/staking/types" @@ -44,7 +45,7 @@ func getTestEnvironment(testBankKey ecdsa.PrivateKey) (*BlockChainImpl, *state.D genesis := gspec.MustCommit(database) // fake blockchain - chain, _ := NewBlockChain(database, state.NewDatabase(database), nil, nil, gspec.Config, vm.Config{}) + chain, _ := NewBlockChain(database, state.NewDatabase(database), nil, nil, gspec.Config, chain.Engine(), vm.Config{}) db, _ := chain.StateAt(genesis.Root()) // make a fake block header (use epoch 1 so that locked tokens can be tested) diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index c3c3430d5..d6b181e18 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/harmony-one/harmony/crypto/bls" + "github.com/harmony-one/harmony/internal/chain" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -158,7 +159,7 @@ func createBlockChain() *BlockChainImpl { database := rawdb.NewMemoryDatabase() genesis := gspec.MustCommit(database) _ = genesis - blockchain, _ := NewBlockChain(database, state.NewDatabase(database), nil, nil, gspec.Config, vm.Config{}) + blockchain, _ := NewBlockChain(database, state.NewDatabase(database), nil, nil, gspec.Config, chain.Engine(), vm.Config{}) return blockchain } diff --git a/hmy/downloader/adapter.go b/hmy/downloader/adapter.go index 3d8f6ac97..c8758b506 100644 --- a/hmy/downloader/adapter.go +++ b/hmy/downloader/adapter.go @@ -25,6 +25,7 @@ type syncProtocol interface { type blockChain interface { engine.ChainReader + Engine() engine.Engine InsertChain(chain types.Blocks, verifyHeaders bool) (int, error) WriteCommitSig(blockNum uint64, lastCommits []byte) error diff --git a/hmy/downloader/downloader.go b/hmy/downloader/downloader.go index b7d597c6b..01ec242ab 100644 --- a/hmy/downloader/downloader.go +++ b/hmy/downloader/downloader.go @@ -308,10 +308,10 @@ func verifyAndInsertBlock(bc blockChain, block *types.Block, nextBlocks ...*type } } - if err := chain.Engine().VerifyHeaderSignature(bc, block.Header(), sigBytes, bitmap); err != nil { + if err := bc.Engine().VerifyHeaderSignature(bc, block.Header(), sigBytes, bitmap); err != nil { return &sigVerifyErr{err} } - if err := chain.Engine().VerifyHeader(bc, block.Header(), true); err != nil { + if err := bc.Engine().VerifyHeader(bc, block.Header(), true); err != nil { return errors.Wrap(err, "[VerifyHeader]") } if _, err := bc.InsertChain(types.Blocks{block}, false); err != nil { diff --git a/internal/chain/engine.go b/internal/chain/engine.go index 4337c2932..e01653646 100644 --- a/internal/chain/engine.go +++ b/internal/chain/engine.go @@ -45,10 +45,10 @@ type engineImpl struct { verifiedSigCache *lru.Cache // verifiedSigKey -> struct{}{} } -var internal = NewEngine() +var internal engine.Engine = NewEngine() // NewEngine creates Engine with some cache -func NewEngine() *engineImpl { +func NewEngine() engine.Engine { sigCache, _ := lru.New(verifiedSigCache) epochCtxCache, _ := lru.New(epochCtxCache) return &engineImpl{ @@ -57,7 +57,7 @@ func NewEngine() *engineImpl { } } -func Engine() *engineImpl { +func Engine() engine.Engine { return internal } diff --git a/internal/shardchain/shardchains.go b/internal/shardchain/shardchains.go index 957ba9150..771bfeb81 100644 --- a/internal/shardchain/shardchains.go +++ b/internal/shardchain/shardchains.go @@ -6,6 +6,7 @@ import ( "time" "github.com/harmony-one/harmony/core/state" + "github.com/harmony-one/harmony/internal/chain" harmonyconfig "github.com/harmony-one/harmony/internal/configs/harmony" nodeconfig "github.com/harmony-one/harmony/internal/configs/node" "github.com/harmony-one/harmony/internal/shardchain/tikv_manage" @@ -133,7 +134,7 @@ func (sc *CollectionImpl) ShardChain(shardID uint32, options ...core.Options) (c } if shardID == shard.BeaconChainShardID { bc, err = core.NewBlockChainWithOptions( - db, stateCache, bc, cacheConfig, &chainConfig, vm.Config{}, opts, + db, stateCache, bc, cacheConfig, &chainConfig, chain.Engine(), vm.Config{}, opts, ) } else { beacon, ok := sc.pool[shard.BeaconChainShardID] @@ -142,7 +143,7 @@ func (sc *CollectionImpl) ShardChain(shardID uint32, options ...core.Options) (c } bc, err = core.NewBlockChainWithOptions( - db, stateCache, beacon, cacheConfig, &chainConfig, vm.Config{}, opts, + db, stateCache, beacon, cacheConfig, &chainConfig, chain.Engine(), vm.Config{}, opts, ) } } diff --git a/node/node_handler_test.go b/node/node_handler_test.go index b0d276d71..92ef23677 100644 --- a/node/node_handler_test.go +++ b/node/node_handler_test.go @@ -33,9 +33,8 @@ func TestAddNewBlock(t *testing.T) { if err != nil { t.Fatalf("newhost failure: %v", err) } - chainconfig := nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType().ChainConfig() collection := shardchain.NewCollection( - nil, testDBFactory, &core.GenesisInitializer{NetworkType: nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType()}, &chainconfig, + nil, testDBFactory, &core.GenesisInitializer{}, nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType(), ) decider := quorum.NewDecider( quorum.SuperMajorityVote, shard.BeaconChainShardID, @@ -89,9 +88,8 @@ func TestVerifyNewBlock(t *testing.T) { if err != nil { t.Fatalf("newhost failure: %v", err) } - chainconfig := nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType().ChainConfig() collection := shardchain.NewCollection( - nil, testDBFactory, &core.GenesisInitializer{NetworkType: nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType()}, &chainconfig, + nil, testDBFactory, &core.GenesisInitializer{}, nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType(), ) decider := quorum.NewDecider( quorum.SuperMajorityVote, shard.BeaconChainShardID, @@ -144,9 +142,8 @@ func TestVerifyVRF(t *testing.T) { if err != nil { t.Fatalf("newhost failure: %v", err) } - chainconfig := nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType().ChainConfig() collection := shardchain.NewCollection( - nil, testDBFactory, &core.GenesisInitializer{NetworkType: nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType()}, &chainconfig, + nil, testDBFactory, &core.GenesisInitializer{}, nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType(), ) blockchain, err := collection.ShardChain(shard.BeaconChainShardID) if err != nil { diff --git a/node/node_newblock_test.go b/node/node_newblock_test.go index 5483e32c3..4843d3f91 100644 --- a/node/node_newblock_test.go +++ b/node/node_newblock_test.go @@ -34,9 +34,8 @@ func TestFinalizeNewBlockAsync(t *testing.T) { t.Fatalf("newhost failure: %v", err) } var testDBFactory = &shardchain.MemDBFactory{} - chainconfig := nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType().ChainConfig() collection := shardchain.NewCollection( - nil, testDBFactory, &core.GenesisInitializer{NetworkType: nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType()}, &chainconfig, + nil, testDBFactory, &core.GenesisInitializer{}, nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType(), ) blockchain, err := collection.ShardChain(shard.BeaconChainShardID) require.NoError(t, err) diff --git a/node/node_test.go b/node/node_test.go index 86bd2b10b..5f9d8ca51 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -36,9 +36,8 @@ func TestNewNode(t *testing.T) { decider := quorum.NewDecider( quorum.SuperMajorityVote, shard.BeaconChainShardID, ) - chainconfig := nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType().ChainConfig() collection := shardchain.NewCollection( - nil, testDBFactory, &core.GenesisInitializer{NetworkType: nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType()}, &chainconfig, + nil, testDBFactory, &core.GenesisInitializer{}, nodeconfig.GetShardConfig(shard.BeaconChainShardID).GetNetworkType(), ) blockchain, err := collection.ShardChain(shard.BeaconChainShardID) if err != nil { diff --git a/node/worker/worker_test.go b/node/worker/worker_test.go index 7bd25c8db..3565be954 100644 --- a/node/worker/worker_test.go +++ b/node/worker/worker_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/harmony-one/harmony/core/state" + "github.com/harmony-one/harmony/internal/chain" "github.com/ethereum/go-ethereum/core/rawdb" @@ -43,7 +44,7 @@ func TestNewWorker(t *testing.T) { genesis := gspec.MustCommit(database) _ = genesis - chain, err := core.NewBlockChain(database, state.NewDatabase(database), &core.BlockChainImpl{}, nil, gspec.Config, vm.Config{}) + chain, err := core.NewBlockChain(database, state.NewDatabase(database), &core.BlockChainImpl{}, nil, gspec.Config, chain.Engine(), vm.Config{}) if err != nil { t.Error(err) @@ -69,7 +70,7 @@ func TestCommitTransactions(t *testing.T) { ) gspec.MustCommit(database) - chain, _ := core.NewBlockChain(database, state.NewDatabase(database), nil, nil, gspec.Config, vm.Config{}) + chain, _ := core.NewBlockChain(database, state.NewDatabase(database), nil, nil, gspec.Config, chain.Engine(), vm.Config{}) // Create a new worker worker := New(params.TestChainConfig, chain, nil) diff --git a/test/chain/main.go b/test/chain/main.go index 6da925569..6358e9180 100644 --- a/test/chain/main.go +++ b/test/chain/main.go @@ -206,7 +206,7 @@ func playFaucetContract(chain core.BlockChain) { func main() { genesis := gspec.MustCommit(database) - chain, _ := core.NewBlockChain(database, harmonyState.NewDatabase(database), nil, nil, gspec.Config, vm.Config{}) + chain, _ := core.NewBlockChain(database, harmonyState.NewDatabase(database), nil, nil, gspec.Config, chain.Engine(), vm.Config{}) txpool := core.NewTxPool(core.DefaultTxPoolConfig, chainConfig, chain, types.NewTransactionErrorSink()) backend := &testWorkerBackend{ diff --git a/test/chain/reward/main.go b/test/chain/reward/main.go index 828c6fc7f..9afdeac39 100644 --- a/test/chain/reward/main.go +++ b/test/chain/reward/main.go @@ -7,6 +7,7 @@ import ( "time" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/harmony-one/harmony/internal/chain" msg_pb "github.com/harmony-one/harmony/api/proto/message" "github.com/harmony-one/harmony/crypto/bls" @@ -107,7 +108,8 @@ func main() { database := rawdb.NewMemoryDatabase() genesis := gspec.MustCommit(database) _ = genesis - bc, _ := core.NewBlockChain(database, state.NewDatabase(database), nil, nil, gspec.Config, vm.Config{}) + engine := chain.NewEngine() + bc, _ := core.NewBlockChain(database, state.NewDatabase(database), nil, nil, gspec.Config, engine, vm.Config{}) statedb, _ := state.New(common2.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase())) msg := createValidator() statedb.AddBalance(msg.ValidatorAddress, new(big.Int).Mul(big.NewInt(5e18), big.NewInt(2000)))