aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/bench_test.go5
-rw-r--r--core/block_validator.go2
-rw-r--r--core/block_validator_test.go7
-rw-r--r--core/blockchain.go3
-rw-r--r--core/blockchain_test.go34
-rw-r--r--core/chain_makers.go13
-rw-r--r--core/chain_makers_test.go3
-rw-r--r--core/chain_pow.go2
-rw-r--r--core/chain_pow_test.go28
-rw-r--r--core/dao_test.go13
10 files changed, 52 insertions, 58 deletions
diff --git a/core/bench_test.go b/core/bench_test.go
index 8a1600557..42d50a7b1 100644
--- a/core/bench_test.go
+++ b/core/bench_test.go
@@ -31,6 +31,7 @@ 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"
)
func BenchmarkInsertChain_empty_memdb(b *testing.B) {
@@ -171,7 +172,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
// Time the insertion of the new chain.
// State and blocks are stored in the same DB.
evmux := new(event.TypeMux)
- chainman, _ := NewBlockChain(db, &params.ChainConfig{HomesteadBlock: new(big.Int)}, FakePow{}, evmux, vm.Config{})
+ chainman, _ := NewBlockChain(db, &params.ChainConfig{HomesteadBlock: new(big.Int)}, pow.FakePow{}, evmux, vm.Config{})
defer chainman.Stop()
b.ReportAllocs()
b.ResetTimer()
@@ -281,7 +282,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
if err != nil {
b.Fatalf("error opening database at %v: %v", dir, err)
}
- chain, err := NewBlockChain(db, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
+ chain, err := NewBlockChain(db, testChainConfig(), pow.FakePow{}, new(event.TypeMux), vm.Config{})
if err != nil {
b.Fatalf("error creating chain: %v", err)
}
diff --git a/core/block_validator.go b/core/block_validator.go
index ed5cc3ab6..f93a9f40b 100644
--- a/core/block_validator.go
+++ b/core/block_validator.go
@@ -244,7 +244,7 @@ func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Heade
if checkPow {
// Verify the nonce of the header. Return an error if it's not valid
- if !pow.Verify(types.NewBlockWithHeader(header)) {
+ if err := pow.Verify(types.NewBlockWithHeader(header)); err != nil {
return &BlockNonceErr{header.Number, header.Hash(), header.Nonce.Uint64()}
}
}
diff --git a/core/block_validator_test.go b/core/block_validator_test.go
index 01931efd2..c13aa83db 100644
--- a/core/block_validator_test.go
+++ b/core/block_validator_test.go
@@ -28,6 +28,7 @@ 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"
)
func testChainConfig() *params.ChainConfig {
@@ -40,7 +41,7 @@ func proc() (Validator, *BlockChain) {
var mux event.TypeMux
WriteTestNetGenesisBlock(db)
- blockchain, err := NewBlockChain(db, testChainConfig(), thePow(), &mux, vm.Config{})
+ blockchain, err := NewBlockChain(db, testChainConfig(), pow.NewTestEthash(), &mux, vm.Config{})
if err != nil {
fmt.Println(err)
}
@@ -54,13 +55,13 @@ func TestNumber(t *testing.T) {
cfg := testChainConfig()
header := makeHeader(cfg, chain.Genesis(), statedb)
header.Number = big.NewInt(3)
- err := ValidateHeader(cfg, FakePow{}, header, chain.Genesis().Header(), false, false)
+ err := ValidateHeader(cfg, pow.FakePow{}, header, chain.Genesis().Header(), false, false)
if err != BlockNumberErr {
t.Errorf("expected block number error, got %q", err)
}
header = makeHeader(cfg, chain.Genesis(), statedb)
- err = ValidateHeader(cfg, FakePow{}, header, chain.Genesis().Header(), false, false)
+ err = ValidateHeader(cfg, pow.FakePow{}, header, chain.Genesis().Header(), false, false)
if err == BlockNumberErr {
t.Errorf("didn't expect block number error")
}
diff --git a/core/blockchain.go b/core/blockchain.go
index 0c752b3f9..765a4b318 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -223,6 +223,9 @@ func (self *BlockChain) loadLastState() error {
log.Info("Loaded most recent local full block", "number", self.currentBlock.Number(), "hash", self.currentBlock.Hash(), "td", blockTd)
log.Info("Loaded most recent local fast block", "number", self.currentFastBlock.Number(), "hash", self.currentFastBlock.Hash(), "td", fastTd)
+ // Try to be smart and issue a pow verification for the head to pre-generate caches
+ go self.pow.Verify(types.NewBlockWithHeader(currentHeader))
+
return nil
}
diff --git a/core/blockchain_test.go b/core/blockchain_test.go
index 99b155620..2f06f0735 100644
--- a/core/blockchain_test.go
+++ b/core/blockchain_test.go
@@ -27,7 +27,6 @@ import (
"testing"
"time"
- "github.com/ethereum/ethash"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
@@ -45,15 +44,10 @@ func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
}
-func thePow() pow.PoW {
- pow, _ := ethash.NewForTesting()
- return pow
-}
-
func theBlockChain(db ethdb.Database, t *testing.T) *BlockChain {
var eventMux event.TypeMux
WriteTestNetGenesisBlock(db)
- blockchain, err := NewBlockChain(db, testChainConfig(), thePow(), &eventMux, vm.Config{})
+ blockchain, err := NewBlockChain(db, testChainConfig(), pow.NewTestEthash(), &eventMux, vm.Config{})
if err != nil {
t.Error("failed creating blockchain:", err)
t.FailNow()
@@ -476,7 +470,7 @@ func chm(genesis *types.Block, db ethdb.Database) *BlockChain {
chainDb: db,
genesisBlock: genesis,
eventMux: &eventMux,
- pow: FakePow{},
+ pow: pow.FakePow{},
config: testChainConfig(),
}
valFn := func() HeaderValidator { return bc.Validator() }
@@ -615,7 +609,7 @@ func testReorgBadHashes(t *testing.T, full bool) {
defer func() { delete(BadHashes, headers[3].Hash()) }()
}
// Create a new chain manager and check it rolled back the state
- ncm, err := NewBlockChain(db, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
+ ncm, err := NewBlockChain(db, testChainConfig(), pow.FakePow{}, new(event.TypeMux), vm.Config{})
if err != nil {
t.Fatalf("failed to create new chain manager: %v", err)
}
@@ -736,7 +730,7 @@ func TestFastVsFullChains(t *testing.T) {
archiveDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
- archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
+ archive, _ := NewBlockChain(archiveDb, testChainConfig(), pow.FakePow{}, new(event.TypeMux), vm.Config{})
if n, err := archive.InsertChain(blocks); err != nil {
t.Fatalf("failed to process block %d: %v", n, err)
@@ -744,7 +738,7 @@ func TestFastVsFullChains(t *testing.T) {
// Fast import the chain as a non-archive node to test
fastDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
- fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
+ fast, _ := NewBlockChain(fastDb, testChainConfig(), pow.FakePow{}, new(event.TypeMux), vm.Config{})
headers := make([]*types.Header, len(blocks))
for i, block := range blocks {
@@ -820,7 +814,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
archiveDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
- archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
+ archive, _ := NewBlockChain(archiveDb, testChainConfig(), pow.FakePow{}, new(event.TypeMux), vm.Config{})
if n, err := archive.InsertChain(blocks); err != nil {
t.Fatalf("failed to process block %d: %v", n, err)
@@ -832,7 +826,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
// Import the chain as a non-archive node and ensure all pointers are updated
fastDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
- fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
+ fast, _ := NewBlockChain(fastDb, testChainConfig(), pow.FakePow{}, new(event.TypeMux), vm.Config{})
headers := make([]*types.Header, len(blocks))
for i, block := range blocks {
@@ -851,7 +845,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
// Import the chain as a light node and ensure all pointers are updated
lightDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(lightDb, GenesisAccount{address, funds})
- light, _ := NewBlockChain(lightDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
+ light, _ := NewBlockChain(lightDb, testChainConfig(), pow.FakePow{}, new(event.TypeMux), vm.Config{})
if n, err := light.InsertHeaderChain(headers, 1); err != nil {
t.Fatalf("failed to insert header %d: %v", n, err)
@@ -917,7 +911,7 @@ func TestChainTxReorgs(t *testing.T) {
})
// Import the chain. This runs all block validation rules.
evmux := &event.TypeMux{}
- blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux, vm.Config{})
+ blockchain, _ := NewBlockChain(db, testChainConfig(), pow.FakePow{}, evmux, vm.Config{})
if i, err := blockchain.InsertChain(chain); err != nil {
t.Fatalf("failed to insert original chain[%d]: %v", i, err)
}
@@ -991,7 +985,7 @@ func TestLogReorgs(t *testing.T) {
)
evmux := &event.TypeMux{}
- blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux, vm.Config{})
+ blockchain, _ := NewBlockChain(db, testChainConfig(), pow.FakePow{}, evmux, vm.Config{})
subs := evmux.Subscribe(RemovedLogsEvent{})
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 2, func(i int, gen *BlockGen) {
@@ -1028,7 +1022,7 @@ func TestReorgSideEvent(t *testing.T) {
)
evmux := &event.TypeMux{}
- blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux, vm.Config{})
+ blockchain, _ := NewBlockChain(db, testChainConfig(), pow.FakePow{}, evmux, vm.Config{})
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {})
if _, err := blockchain.InsertChain(chain); err != nil {
@@ -1104,7 +1098,7 @@ func TestCanonicalBlockRetrieval(t *testing.T) {
)
evmux := &event.TypeMux{}
- blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux, vm.Config{})
+ blockchain, _ := NewBlockChain(db, testChainConfig(), pow.FakePow{}, evmux, vm.Config{})
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *BlockGen) {})
@@ -1147,7 +1141,7 @@ func TestEIP155Transition(t *testing.T) {
mux event.TypeMux
)
- blockchain, _ := NewBlockChain(db, config, FakePow{}, &mux, vm.Config{})
+ blockchain, _ := NewBlockChain(db, config, pow.FakePow{}, &mux, vm.Config{})
blocks, _ := GenerateChain(config, genesis, db, 4, func(i int, block *BlockGen) {
var (
tx *types.Transaction
@@ -1251,7 +1245,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
}
mux event.TypeMux
- blockchain, _ = NewBlockChain(db, config, FakePow{}, &mux, vm.Config{})
+ blockchain, _ = NewBlockChain(db, config, pow.FakePow{}, &mux, vm.Config{})
)
blocks, _ := GenerateChain(config, genesis, db, 3, func(i int, block *BlockGen) {
var (
diff --git a/core/chain_makers.go b/core/chain_makers.go
index 8b3b015a8..f63496fdc 100644
--- a/core/chain_makers.go
+++ b/core/chain_makers.go
@@ -43,17 +43,6 @@ func MakeChainConfig() *params.ChainConfig {
}
}
-// FakePow is a non-validating proof of work implementation.
-// It returns true from Verify for any block.
-type FakePow struct{}
-
-func (f FakePow) Search(block pow.Block, stop <-chan struct{}, index int) (uint64, []byte) {
- return 0, nil
-}
-func (f FakePow) Verify(block pow.Block) bool { return true }
-func (f FakePow) GetHashrate() int64 { return 0 }
-func (f FakePow) Turbo(bool) {}
-
// So we can deterministically seed different blockchains
var (
canonicalSeed = 1
@@ -256,7 +245,7 @@ func newCanonical(n int, full bool) (ethdb.Database, *BlockChain, error) {
// Initialize a fresh chain with only a genesis block
genesis, _ := WriteTestNetGenesisBlock(db)
- blockchain, _ := NewBlockChain(db, MakeChainConfig(), FakePow{}, evmux, vm.Config{})
+ blockchain, _ := NewBlockChain(db, MakeChainConfig(), pow.FakePow{}, evmux, vm.Config{})
// Create and inject the requested chain
if n == 0 {
return db, blockchain, nil
diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go
index 5c563de46..82751553f 100644
--- a/core/chain_makers_test.go
+++ b/core/chain_makers_test.go
@@ -26,6 +26,7 @@ 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"
)
func ExampleGenerateChain() {
@@ -82,7 +83,7 @@ func ExampleGenerateChain() {
// Import the chain. This runs all block validation rules.
evmux := &event.TypeMux{}
- blockchain, _ := NewBlockChain(db, chainConfig, FakePow{}, evmux, vm.Config{})
+ blockchain, _ := NewBlockChain(db, chainConfig, pow.FakePow{}, evmux, vm.Config{})
if i, err := blockchain.InsertChain(chain); err != nil {
fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
return
diff --git a/core/chain_pow.go b/core/chain_pow.go
index c3b5788c1..e5ccd87e2 100644
--- a/core/chain_pow.go
+++ b/core/chain_pow.go
@@ -65,7 +65,7 @@ func verifyNonces(checker pow.PoW, items []pow.Block) (chan<- struct{}, <-chan n
for i := 0; i < workers; i++ {
go func() {
for index := range tasks {
- results <- nonceCheckResult{index: index, valid: checker.Verify(items[index])}
+ results <- nonceCheckResult{index: index, valid: checker.Verify(items[index]) == nil}
}
}()
}
diff --git a/core/chain_pow_test.go b/core/chain_pow_test.go
index 1400b166f..311ca128e 100644
--- a/core/chain_pow_test.go
+++ b/core/chain_pow_test.go
@@ -17,6 +17,7 @@
package core
import (
+ "errors"
"math/big"
"runtime"
"testing"
@@ -35,12 +36,16 @@ type failPow struct {
failing uint64
}
-func (pow failPow) Search(pow.Block, <-chan struct{}, int) (uint64, []byte) {
+func (pow failPow) Search(pow.Block, <-chan struct{}) (uint64, []byte) {
return 0, nil
}
-func (pow failPow) Verify(block pow.Block) bool { return block.NumberU64() != pow.failing }
-func (pow failPow) GetHashrate() int64 { return 0 }
-func (pow failPow) Turbo(bool) {}
+func (pow failPow) Verify(block pow.Block) error {
+ if block.NumberU64() == pow.failing {
+ return errors.New("failed")
+ }
+ return nil
+}
+func (pow failPow) Hashrate() float64 { return 0 }
// delayedPow is a non-validating proof of work implementation, that returns true
// from Verify for all blocks, but delays them the configured amount of time.
@@ -48,12 +53,11 @@ type delayedPow struct {
delay time.Duration
}
-func (pow delayedPow) Search(pow.Block, <-chan struct{}, int) (uint64, []byte) {
+func (pow delayedPow) Search(pow.Block, <-chan struct{}) (uint64, []byte) {
return 0, nil
}
-func (pow delayedPow) Verify(block pow.Block) bool { time.Sleep(pow.delay); return true }
-func (pow delayedPow) GetHashrate() int64 { return 0 }
-func (pow delayedPow) Turbo(bool) {}
+func (pow delayedPow) Verify(block pow.Block) error { time.Sleep(pow.delay); return nil }
+func (pow delayedPow) Hashrate() float64 { return 0 }
// Tests that simple POW verification works, for both good and bad blocks.
func TestPowVerification(t *testing.T) {
@@ -75,11 +79,11 @@ func TestPowVerification(t *testing.T) {
switch {
case full && valid:
- _, results = verifyNoncesFromBlocks(FakePow{}, []*types.Block{blocks[i]})
+ _, results = verifyNoncesFromBlocks(pow.FakePow{}, []*types.Block{blocks[i]})
case full && !valid:
_, results = verifyNoncesFromBlocks(failPow{blocks[i].NumberU64()}, []*types.Block{blocks[i]})
case !full && valid:
- _, results = verifyNoncesFromHeaders(FakePow{}, []*types.Header{headers[i]})
+ _, results = verifyNoncesFromHeaders(pow.FakePow{}, []*types.Header{headers[i]})
case !full && !valid:
_, results = verifyNoncesFromHeaders(failPow{headers[i].Number.Uint64()}, []*types.Header{headers[i]})
}
@@ -134,11 +138,11 @@ func testPowConcurrentVerification(t *testing.T, threads int) {
switch {
case full && valid:
- _, results = verifyNoncesFromBlocks(FakePow{}, blocks)
+ _, results = verifyNoncesFromBlocks(pow.FakePow{}, blocks)
case full && !valid:
_, results = verifyNoncesFromBlocks(failPow{uint64(len(blocks) - 1)}, blocks)
case !full && valid:
- _, results = verifyNoncesFromHeaders(FakePow{}, headers)
+ _, results = verifyNoncesFromHeaders(pow.FakePow{}, headers)
case !full && !valid:
_, results = verifyNoncesFromHeaders(failPow{uint64(len(headers) - 1)}, headers)
}
diff --git a/core/dao_test.go b/core/dao_test.go
index b8b4c71cf..45b3235c7 100644
--- a/core/dao_test.go
+++ b/core/dao_test.go
@@ -24,6 +24,7 @@ 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"
)
// Tests that DAO-fork enabled clients can properly filter out fork-commencing
@@ -40,12 +41,12 @@ func TestDAOForkRangeExtradata(t *testing.T) {
proDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(proDb)
proConf := &params.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: true}
- proBc, _ := NewBlockChain(proDb, proConf, new(FakePow), new(event.TypeMux), vm.Config{})
+ proBc, _ := NewBlockChain(proDb, proConf, new(pow.FakePow), new(event.TypeMux), vm.Config{})
conDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(conDb)
conConf := &params.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: false}
- conBc, _ := NewBlockChain(conDb, conConf, new(FakePow), new(event.TypeMux), vm.Config{})
+ conBc, _ := NewBlockChain(conDb, conConf, new(pow.FakePow), new(event.TypeMux), vm.Config{})
if _, err := proBc.InsertChain(prefix); err != nil {
t.Fatalf("pro-fork: failed to import chain prefix: %v", err)
@@ -58,7 +59,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Create a pro-fork block, and try to feed into the no-fork chain
db, _ = ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(db)
- bc, _ := NewBlockChain(db, conConf, new(FakePow), new(event.TypeMux), vm.Config{})
+ bc, _ := NewBlockChain(db, conConf, new(pow.FakePow), new(event.TypeMux), vm.Config{})
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1))
for j := 0; j < len(blocks)/2; j++ {
@@ -79,7 +80,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Create a no-fork block, and try to feed into the pro-fork chain
db, _ = ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(db)
- bc, _ = NewBlockChain(db, proConf, new(FakePow), new(event.TypeMux), vm.Config{})
+ bc, _ = NewBlockChain(db, proConf, new(pow.FakePow), new(event.TypeMux), vm.Config{})
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1))
for j := 0; j < len(blocks)/2; j++ {
@@ -101,7 +102,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Verify that contra-forkers accept pro-fork extra-datas after forking finishes
db, _ = ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(db)
- bc, _ := NewBlockChain(db, conConf, new(FakePow), new(event.TypeMux), vm.Config{})
+ bc, _ := NewBlockChain(db, conConf, new(pow.FakePow), new(event.TypeMux), vm.Config{})
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1))
for j := 0; j < len(blocks)/2; j++ {
@@ -117,7 +118,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Verify that pro-forkers accept contra-fork extra-datas after forking finishes
db, _ = ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(db)
- bc, _ = NewBlockChain(db, proConf, new(FakePow), new(event.TypeMux), vm.Config{})
+ bc, _ = NewBlockChain(db, proConf, new(pow.FakePow), new(event.TypeMux), vm.Config{})
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1))
for j := 0; j < len(blocks)/2; j++ {