aboutsummaryrefslogtreecommitdiffstats
path: root/light
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2017-04-05 06:16:29 +0800
committerFelix Lange <fjl@users.noreply.github.com>2017-04-05 06:16:29 +0800
commit09777952ee476ff80d4b6e63b5041ff5ca0e441b (patch)
treee85320f88f548201e3476b3e7095e96fd071617b /light
parente50a5b77712d891ff409aa942a5cbc24e721b332 (diff)
downloaddexon-09777952ee476ff80d4b6e63b5041ff5ca0e441b.tar.gz
dexon-09777952ee476ff80d4b6e63b5041ff5ca0e441b.tar.zst
dexon-09777952ee476ff80d4b6e63b5041ff5ca0e441b.zip
core, consensus: pluggable consensus engines (#3817)
This commit adds pluggable consensus engines to go-ethereum. In short, it introduces a generic consensus interface, and refactors the entire codebase to use this interface.
Diffstat (limited to 'light')
-rw-r--r--light/lightchain.go32
-rw-r--r--light/lightchain_test.go34
-rw-r--r--light/odr_test.go11
-rw-r--r--light/txpool_test.go13
4 files changed, 27 insertions, 63 deletions
diff --git a/light/lightchain.go b/light/lightchain.go
index 98fb024f0..4073e39e5 100644
--- a/light/lightchain.go
+++ b/light/lightchain.go
@@ -24,13 +24,13 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/rlp"
"github.com/hashicorp/golang-lru"
)
@@ -64,14 +64,13 @@ type LightChain struct {
procInterrupt int32 // interrupt signaler for block processing
wg sync.WaitGroup
- pow pow.PoW
- validator core.HeaderValidator
+ engine consensus.Engine
}
// NewLightChain returns a fully initialised light chain using information
// available in the database. It initialises the default Ethereum header
// validator.
-func NewLightChain(odr OdrBackend, config *params.ChainConfig, pow pow.PoW, mux *event.TypeMux) (*LightChain, error) {
+func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine, mux *event.TypeMux) (*LightChain, error) {
bodyCache, _ := lru.New(bodyCacheLimit)
bodyRLPCache, _ := lru.New(bodyCacheLimit)
blockCache, _ := lru.New(blockCacheLimit)
@@ -84,21 +83,17 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, pow pow.PoW, mux
bodyCache: bodyCache,
bodyRLPCache: bodyRLPCache,
blockCache: blockCache,
- pow: pow,
+ engine: engine,
}
-
var err error
- bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.Validator, bc.getProcInterrupt)
- bc.SetValidator(core.NewHeaderValidator(config, bc.hc, pow))
+ bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine, bc.getProcInterrupt)
if err != nil {
return nil, err
}
-
bc.genesisBlock, _ = bc.GetBlockByNumber(NoOdr, 0)
if bc.genesisBlock == nil {
return nil, core.ErrNoGenesis
}
-
if bc.genesisBlock.Hash() == params.MainNetGenesisHash {
// add trusted CHT
WriteTrustedCht(bc.chainDb, TrustedCht{Number: 805, Root: common.HexToHash("85e4286fe0a730390245c49de8476977afdae0eb5530b277f62a52b12313d50f")})
@@ -145,9 +140,6 @@ func (self *LightChain) loadLastState() error {
headerTd := self.GetTd(header.Hash(), header.Number.Uint64())
log.Info("Loaded most recent local header", "number", header.Number, "hash", header.Hash(), "td", headerTd)
- // Try to be smart and issue a pow verification for the head to pre-generate caches
- go self.pow.Verify(types.NewBlockWithHeader(header))
-
return nil
}
@@ -188,20 +180,6 @@ func (self *LightChain) Status() (td *big.Int, currentBlock common.Hash, genesis
return self.GetTd(hash, header.Number.Uint64()), hash, self.genesisBlock.Hash()
}
-// SetValidator sets the validator which is used to validate incoming headers.
-func (self *LightChain) SetValidator(validator core.HeaderValidator) {
- self.procmu.Lock()
- defer self.procmu.Unlock()
- self.validator = validator
-}
-
-// Validator returns the current header validator.
-func (self *LightChain) Validator() core.HeaderValidator {
- self.procmu.RLock()
- defer self.procmu.RUnlock()
- return self.validator
-}
-
// State returns a new mutable state based on the current HEAD block.
func (self *LightChain) State() *LightState {
return NewLightState(StateTrieID(self.hc.CurrentHeader()), self.odr)
diff --git a/light/lightchain_test.go b/light/lightchain_test.go
index e9236f1fd..41010cf57 100644
--- a/light/lightchain_test.go
+++ b/light/lightchain_test.go
@@ -23,12 +23,12 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/pow"
)
// So we can deterministically seed different blockchains
@@ -49,18 +49,15 @@ func makeHeaderChain(parent *types.Header, n int, db ethdb.Database, seed int) [
return headers
}
-func testChainConfig() *params.ChainConfig {
- return &params.ChainConfig{HomesteadBlock: big.NewInt(0)}
-}
-
// newCanonical creates a chain database, and injects a deterministic canonical
// chain. Depending on the full flag, if creates either a full block chain or a
// header only chain.
func newCanonical(n int) (ethdb.Database, *LightChain, error) {
db, _ := ethdb.NewMemDatabase()
- gspec := core.Genesis{Config: testChainConfig()}
+ gspec := core.Genesis{Config: params.TestChainConfig}
genesis := gspec.MustCommit(db)
- blockchain, _ := NewLightChain(&dummyOdr{db: db}, gspec.Config, pow.FakePow{}, new(event.TypeMux))
+ blockchain, _ := NewLightChain(&dummyOdr{db: db}, gspec.Config, ethash.NewFaker(), new(event.TypeMux))
+
// Create and inject the requested chain
if n == 0 {
return db, blockchain, nil
@@ -76,14 +73,13 @@ func newTestLightChain() *LightChain {
db, _ := ethdb.NewMemDatabase()
gspec := &core.Genesis{
Difficulty: big.NewInt(1),
- Config: testChainConfig(),
+ Config: params.TestChainConfig,
}
gspec.MustCommit(db)
- lc, err := NewLightChain(&dummyOdr{db: db}, gspec.Config, pow.NewTestEthash(), new(event.TypeMux))
+ lc, err := NewLightChain(&dummyOdr{db: db}, gspec.Config, ethash.NewFullFaker(), new(event.TypeMux))
if err != nil {
panic(err)
}
- lc.SetValidator(bproc{})
return lc
}
@@ -130,17 +126,17 @@ func printChain(bc *LightChain) {
// testHeaderChainImport tries to process a chain of header, writing them into
// the database if successful.
-func testHeaderChainImport(chain []*types.Header, LightChain *LightChain) error {
+func testHeaderChainImport(chain []*types.Header, lightchain *LightChain) error {
for _, header := range chain {
// Try and validate the header
- if err := LightChain.Validator().ValidateHeader(header, LightChain.GetHeaderByHash(header.ParentHash), false); err != nil {
+ if err := lightchain.engine.VerifyHeader(lightchain.hc, header, true); err != nil {
return err
}
// Manually insert the header into the database, but don't reorganize (allows subsequent testing)
- LightChain.mu.Lock()
- core.WriteTd(LightChain.chainDb, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, LightChain.GetTdByHash(header.ParentHash)))
- core.WriteHeader(LightChain.chainDb, header)
- LightChain.mu.Unlock()
+ lightchain.mu.Lock()
+ core.WriteTd(lightchain.chainDb, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, lightchain.GetTdByHash(header.ParentHash)))
+ core.WriteHeader(lightchain.chainDb, header)
+ lightchain.mu.Unlock()
}
return nil
}
@@ -257,10 +253,6 @@ func TestBrokenHeaderChain(t *testing.T) {
}
}
-type bproc struct{}
-
-func (bproc) ValidateHeader(*types.Header, *types.Header, bool) error { return nil }
-
func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Header {
var chain []*types.Header
for i, difficulty := range d {
@@ -359,7 +351,7 @@ func TestReorgBadHeaderHashes(t *testing.T) {
defer func() { delete(core.BadHashes, headers[3].Hash()) }()
// Create a new LightChain and check that it rolled back the state.
- ncm, err := NewLightChain(&dummyOdr{db: bc.chainDb}, testChainConfig(), pow.FakePow{}, new(event.TypeMux))
+ ncm, err := NewLightChain(&dummyOdr{db: bc.chainDb}, params.TestChainConfig, ethash.NewFaker(), new(event.TypeMux))
if err != nil {
t.Fatalf("failed to create new chain manager: %v", err)
}
diff --git a/light/odr_test.go b/light/odr_test.go
index 37d999994..ca33db246 100644
--- a/light/odr_test.go
+++ b/light/odr_test.go
@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
+ "github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
@@ -34,7 +35,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
)
@@ -248,7 +248,6 @@ func testChainGen(i int, block *core.BlockGen) {
func testChainOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
var (
evmux = new(event.TypeMux)
- pow = new(pow.FakePow)
sdb, _ = ethdb.NewMemDatabase()
ldb, _ = ethdb.NewMemDatabase()
gspec = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
@@ -256,16 +255,14 @@ func testChainOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
)
gspec.MustCommit(ldb)
// Assemble the test environment
- blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux, vm.Config{})
- chainConfig := &params.ChainConfig{HomesteadBlock: new(big.Int)}
- gchain, _ := core.GenerateChain(chainConfig, genesis, sdb, 4, testChainGen)
+ blockchain, _ := core.NewBlockChain(sdb, params.TestChainConfig, ethash.NewFullFaker(), evmux, vm.Config{})
+ gchain, _ := core.GenerateChain(params.TestChainConfig, genesis, sdb, 4, testChainGen)
if _, err := blockchain.InsertChain(gchain); err != nil {
panic(err)
}
odr := &testOdr{sdb: sdb, ldb: ldb}
- lightchain, _ := NewLightChain(odr, testChainConfig(), pow, evmux)
- lightchain.SetValidator(bproc{})
+ lightchain, _ := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker(), evmux)
headers := make([]*types.Header, len(gchain))
for i, block := range gchain {
headers[i] = block.Header()
diff --git a/light/txpool_test.go b/light/txpool_test.go
index 2b5fa7116..f23832a41 100644
--- a/light/txpool_test.go
+++ b/light/txpool_test.go
@@ -24,13 +24,13 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/pow"
)
type testTxRelay struct {
@@ -83,7 +83,6 @@ func TestTxPool(t *testing.T) {
var (
evmux = new(event.TypeMux)
- pow = new(pow.FakePow)
sdb, _ = ethdb.NewMemDatabase()
ldb, _ = ethdb.NewMemDatabase()
gspec = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
@@ -91,9 +90,8 @@ func TestTxPool(t *testing.T) {
)
gspec.MustCommit(ldb)
// Assemble the test environment
- blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux, vm.Config{})
- chainConfig := &params.ChainConfig{HomesteadBlock: new(big.Int)}
- gchain, _ := core.GenerateChain(chainConfig, genesis, sdb, poolTestBlocks, txPoolTestChainGen)
+ blockchain, _ := core.NewBlockChain(sdb, params.TestChainConfig, ethash.NewFullFaker(), evmux, vm.Config{})
+ gchain, _ := core.GenerateChain(params.TestChainConfig, genesis, sdb, poolTestBlocks, txPoolTestChainGen)
if _, err := blockchain.InsertChain(gchain); err != nil {
panic(err)
}
@@ -104,10 +102,9 @@ func TestTxPool(t *testing.T) {
discard: make(chan int, 1),
mined: make(chan int, 1),
}
- lightchain, _ := NewLightChain(odr, testChainConfig(), pow, evmux)
- lightchain.SetValidator(bproc{})
+ lightchain, _ := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker(), evmux)
txPermanent = 50
- pool := NewTxPool(testChainConfig(), evmux, lightchain, relay)
+ pool := NewTxPool(params.TestChainConfig, evmux, lightchain, relay)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()