all: swap out the C++ ethash to the pure Go one (mining todo)
This commit is contained in:
parent
3b00a77de5
commit
567d41d936
@ -33,6 +33,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ type SimulatedBackend struct {
|
|||||||
func NewSimulatedBackend(accounts ...core.GenesisAccount) *SimulatedBackend {
|
func NewSimulatedBackend(accounts ...core.GenesisAccount) *SimulatedBackend {
|
||||||
database, _ := ethdb.NewMemDatabase()
|
database, _ := ethdb.NewMemDatabase()
|
||||||
core.WriteGenesisBlockForTesting(database, accounts...)
|
core.WriteGenesisBlockForTesting(database, accounts...)
|
||||||
blockchain, _ := core.NewBlockChain(database, chainConfig, new(core.FakePow), new(event.TypeMux), vm.Config{})
|
blockchain, _ := core.NewBlockChain(database, chainConfig, new(pow.FakePow), new(event.TypeMux), vm.Config{})
|
||||||
backend := &SimulatedBackend{database: database, blockchain: blockchain}
|
backend := &SimulatedBackend{database: database, blockchain: blockchain}
|
||||||
backend.rollback()
|
backend.rollback()
|
||||||
return backend
|
return backend
|
||||||
|
@ -28,7 +28,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/ethash"
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@ -922,11 +921,11 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
|
|||||||
}
|
}
|
||||||
chainConfig := MakeChainConfigFromDb(ctx, chainDb)
|
chainConfig := MakeChainConfigFromDb(ctx, chainDb)
|
||||||
|
|
||||||
pow := pow.PoW(core.FakePow{})
|
seal := pow.PoW(pow.FakePow{})
|
||||||
if !ctx.GlobalBool(FakePoWFlag.Name) {
|
if !ctx.GlobalBool(FakePoWFlag.Name) {
|
||||||
pow = ethash.New()
|
seal = pow.NewFullEthash("", "")
|
||||||
}
|
}
|
||||||
chain, err = core.NewBlockChain(chainDb, chainConfig, pow, new(event.TypeMux), vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)})
|
chain, err = core.NewBlockChain(chainDb, chainConfig, seal, new(event.TypeMux), vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Could not start chainmanager: %v", err)
|
Fatalf("Could not start chainmanager: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkInsertChain_empty_memdb(b *testing.B) {
|
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.
|
// Time the insertion of the new chain.
|
||||||
// State and blocks are stored in the same DB.
|
// State and blocks are stored in the same DB.
|
||||||
evmux := new(event.TypeMux)
|
evmux := new(event.TypeMux)
|
||||||
chainman, _ := NewBlockChain(db, ¶ms.ChainConfig{HomesteadBlock: new(big.Int)}, FakePow{}, evmux, vm.Config{})
|
chainman, _ := NewBlockChain(db, ¶ms.ChainConfig{HomesteadBlock: new(big.Int)}, pow.FakePow{}, evmux, vm.Config{})
|
||||||
defer chainman.Stop()
|
defer chainman.Stop()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
@ -281,7 +282,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("error opening database at %v: %v", dir, err)
|
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 {
|
if err != nil {
|
||||||
b.Fatalf("error creating chain: %v", err)
|
b.Fatalf("error creating chain: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Heade
|
|||||||
|
|
||||||
if checkPow {
|
if checkPow {
|
||||||
// Verify the nonce of the header. Return an error if it's not valid
|
// 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()}
|
return &BlockNonceErr{header.Number, header.Hash(), header.Nonce.Uint64()}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testChainConfig() *params.ChainConfig {
|
func testChainConfig() *params.ChainConfig {
|
||||||
@ -40,7 +41,7 @@ func proc() (Validator, *BlockChain) {
|
|||||||
var mux event.TypeMux
|
var mux event.TypeMux
|
||||||
|
|
||||||
WriteTestNetGenesisBlock(db)
|
WriteTestNetGenesisBlock(db)
|
||||||
blockchain, err := NewBlockChain(db, testChainConfig(), thePow(), &mux, vm.Config{})
|
blockchain, err := NewBlockChain(db, testChainConfig(), pow.NewTestEthash(), &mux, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
@ -54,13 +55,13 @@ func TestNumber(t *testing.T) {
|
|||||||
cfg := testChainConfig()
|
cfg := testChainConfig()
|
||||||
header := makeHeader(cfg, chain.Genesis(), statedb)
|
header := makeHeader(cfg, chain.Genesis(), statedb)
|
||||||
header.Number = big.NewInt(3)
|
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 {
|
if err != BlockNumberErr {
|
||||||
t.Errorf("expected block number error, got %q", err)
|
t.Errorf("expected block number error, got %q", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
header = makeHeader(cfg, chain.Genesis(), statedb)
|
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 {
|
if err == BlockNumberErr {
|
||||||
t.Errorf("didn't expect block number error")
|
t.Errorf("didn't expect block number error")
|
||||||
}
|
}
|
||||||
|
@ -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 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)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/ethash"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
@ -45,15 +44,10 @@ func init() {
|
|||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
}
|
}
|
||||||
|
|
||||||
func thePow() pow.PoW {
|
|
||||||
pow, _ := ethash.NewForTesting()
|
|
||||||
return pow
|
|
||||||
}
|
|
||||||
|
|
||||||
func theBlockChain(db ethdb.Database, t *testing.T) *BlockChain {
|
func theBlockChain(db ethdb.Database, t *testing.T) *BlockChain {
|
||||||
var eventMux event.TypeMux
|
var eventMux event.TypeMux
|
||||||
WriteTestNetGenesisBlock(db)
|
WriteTestNetGenesisBlock(db)
|
||||||
blockchain, err := NewBlockChain(db, testChainConfig(), thePow(), &eventMux, vm.Config{})
|
blockchain, err := NewBlockChain(db, testChainConfig(), pow.NewTestEthash(), &eventMux, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("failed creating blockchain:", err)
|
t.Error("failed creating blockchain:", err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@ -476,7 +470,7 @@ func chm(genesis *types.Block, db ethdb.Database) *BlockChain {
|
|||||||
chainDb: db,
|
chainDb: db,
|
||||||
genesisBlock: genesis,
|
genesisBlock: genesis,
|
||||||
eventMux: &eventMux,
|
eventMux: &eventMux,
|
||||||
pow: FakePow{},
|
pow: pow.FakePow{},
|
||||||
config: testChainConfig(),
|
config: testChainConfig(),
|
||||||
}
|
}
|
||||||
valFn := func() HeaderValidator { return bc.Validator() }
|
valFn := func() HeaderValidator { return bc.Validator() }
|
||||||
@ -615,7 +609,7 @@ func testReorgBadHashes(t *testing.T, full bool) {
|
|||||||
defer func() { delete(BadHashes, headers[3].Hash()) }()
|
defer func() { delete(BadHashes, headers[3].Hash()) }()
|
||||||
}
|
}
|
||||||
// Create a new chain manager and check it rolled back the state
|
// 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 {
|
if err != nil {
|
||||||
t.Fatalf("failed to create new chain manager: %v", err)
|
t.Fatalf("failed to create new chain manager: %v", err)
|
||||||
}
|
}
|
||||||
@ -736,7 +730,7 @@ func TestFastVsFullChains(t *testing.T) {
|
|||||||
archiveDb, _ := ethdb.NewMemDatabase()
|
archiveDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
|
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 {
|
if n, err := archive.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("failed to process block %d: %v", n, err)
|
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
|
// Fast import the chain as a non-archive node to test
|
||||||
fastDb, _ := ethdb.NewMemDatabase()
|
fastDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
|
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))
|
headers := make([]*types.Header, len(blocks))
|
||||||
for i, block := range blocks {
|
for i, block := range blocks {
|
||||||
@ -820,7 +814,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
|||||||
archiveDb, _ := ethdb.NewMemDatabase()
|
archiveDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
|
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 {
|
if n, err := archive.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("failed to process block %d: %v", n, err)
|
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
|
// Import the chain as a non-archive node and ensure all pointers are updated
|
||||||
fastDb, _ := ethdb.NewMemDatabase()
|
fastDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
|
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))
|
headers := make([]*types.Header, len(blocks))
|
||||||
for i, block := range 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
|
// Import the chain as a light node and ensure all pointers are updated
|
||||||
lightDb, _ := ethdb.NewMemDatabase()
|
lightDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(lightDb, GenesisAccount{address, funds})
|
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 {
|
if n, err := light.InsertHeaderChain(headers, 1); err != nil {
|
||||||
t.Fatalf("failed to insert header %d: %v", n, err)
|
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.
|
// Import the chain. This runs all block validation rules.
|
||||||
evmux := &event.TypeMux{}
|
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 {
|
if i, err := blockchain.InsertChain(chain); err != nil {
|
||||||
t.Fatalf("failed to insert original chain[%d]: %v", i, err)
|
t.Fatalf("failed to insert original chain[%d]: %v", i, err)
|
||||||
}
|
}
|
||||||
@ -991,7 +985,7 @@ func TestLogReorgs(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
evmux := &event.TypeMux{}
|
evmux := &event.TypeMux{}
|
||||||
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux, vm.Config{})
|
blockchain, _ := NewBlockChain(db, testChainConfig(), pow.FakePow{}, evmux, vm.Config{})
|
||||||
|
|
||||||
subs := evmux.Subscribe(RemovedLogsEvent{})
|
subs := evmux.Subscribe(RemovedLogsEvent{})
|
||||||
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 2, func(i int, gen *BlockGen) {
|
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 2, func(i int, gen *BlockGen) {
|
||||||
@ -1028,7 +1022,7 @@ func TestReorgSideEvent(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
evmux := &event.TypeMux{}
|
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) {})
|
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {})
|
||||||
if _, err := blockchain.InsertChain(chain); err != nil {
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
@ -1104,7 +1098,7 @@ func TestCanonicalBlockRetrieval(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
evmux := &event.TypeMux{}
|
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) {})
|
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *BlockGen) {})
|
||||||
|
|
||||||
@ -1147,7 +1141,7 @@ func TestEIP155Transition(t *testing.T) {
|
|||||||
mux event.TypeMux
|
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) {
|
blocks, _ := GenerateChain(config, genesis, db, 4, func(i int, block *BlockGen) {
|
||||||
var (
|
var (
|
||||||
tx *types.Transaction
|
tx *types.Transaction
|
||||||
@ -1251,7 +1245,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
|
|||||||
}
|
}
|
||||||
mux event.TypeMux
|
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) {
|
blocks, _ := GenerateChain(config, genesis, db, 3, func(i int, block *BlockGen) {
|
||||||
var (
|
var (
|
||||||
|
@ -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
|
// So we can deterministically seed different blockchains
|
||||||
var (
|
var (
|
||||||
canonicalSeed = 1
|
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
|
// Initialize a fresh chain with only a genesis block
|
||||||
genesis, _ := WriteTestNetGenesisBlock(db)
|
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
|
// Create and inject the requested chain
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return db, blockchain, nil
|
return db, blockchain, nil
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleGenerateChain() {
|
func ExampleGenerateChain() {
|
||||||
@ -82,7 +83,7 @@ func ExampleGenerateChain() {
|
|||||||
|
|
||||||
// Import the chain. This runs all block validation rules.
|
// Import the chain. This runs all block validation rules.
|
||||||
evmux := &event.TypeMux{}
|
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 {
|
if i, err := blockchain.InsertChain(chain); err != nil {
|
||||||
fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
|
fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
|
||||||
return
|
return
|
||||||
|
@ -65,7 +65,7 @@ func verifyNonces(checker pow.PoW, items []pow.Block) (chan<- struct{}, <-chan n
|
|||||||
for i := 0; i < workers; i++ {
|
for i := 0; i < workers; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
for index := range tasks {
|
for index := range tasks {
|
||||||
results <- nonceCheckResult{index: index, valid: checker.Verify(items[index])}
|
results <- nonceCheckResult{index: index, valid: checker.Verify(items[index]) == nil}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
@ -35,12 +36,16 @@ type failPow struct {
|
|||||||
failing uint64
|
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
|
return 0, nil
|
||||||
}
|
}
|
||||||
func (pow failPow) Verify(block pow.Block) bool { return block.NumberU64() != pow.failing }
|
func (pow failPow) Verify(block pow.Block) error {
|
||||||
func (pow failPow) GetHashrate() int64 { return 0 }
|
if block.NumberU64() == pow.failing {
|
||||||
func (pow failPow) Turbo(bool) {}
|
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
|
// 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.
|
// from Verify for all blocks, but delays them the configured amount of time.
|
||||||
@ -48,12 +53,11 @@ type delayedPow struct {
|
|||||||
delay time.Duration
|
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
|
return 0, nil
|
||||||
}
|
}
|
||||||
func (pow delayedPow) Verify(block pow.Block) bool { time.Sleep(pow.delay); return true }
|
func (pow delayedPow) Verify(block pow.Block) error { time.Sleep(pow.delay); return nil }
|
||||||
func (pow delayedPow) GetHashrate() int64 { return 0 }
|
func (pow delayedPow) Hashrate() float64 { return 0 }
|
||||||
func (pow delayedPow) Turbo(bool) {}
|
|
||||||
|
|
||||||
// Tests that simple POW verification works, for both good and bad blocks.
|
// Tests that simple POW verification works, for both good and bad blocks.
|
||||||
func TestPowVerification(t *testing.T) {
|
func TestPowVerification(t *testing.T) {
|
||||||
@ -75,11 +79,11 @@ func TestPowVerification(t *testing.T) {
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case full && valid:
|
case full && valid:
|
||||||
_, results = verifyNoncesFromBlocks(FakePow{}, []*types.Block{blocks[i]})
|
_, results = verifyNoncesFromBlocks(pow.FakePow{}, []*types.Block{blocks[i]})
|
||||||
case full && !valid:
|
case full && !valid:
|
||||||
_, results = verifyNoncesFromBlocks(failPow{blocks[i].NumberU64()}, []*types.Block{blocks[i]})
|
_, results = verifyNoncesFromBlocks(failPow{blocks[i].NumberU64()}, []*types.Block{blocks[i]})
|
||||||
case !full && valid:
|
case !full && valid:
|
||||||
_, results = verifyNoncesFromHeaders(FakePow{}, []*types.Header{headers[i]})
|
_, results = verifyNoncesFromHeaders(pow.FakePow{}, []*types.Header{headers[i]})
|
||||||
case !full && !valid:
|
case !full && !valid:
|
||||||
_, results = verifyNoncesFromHeaders(failPow{headers[i].Number.Uint64()}, []*types.Header{headers[i]})
|
_, results = verifyNoncesFromHeaders(failPow{headers[i].Number.Uint64()}, []*types.Header{headers[i]})
|
||||||
}
|
}
|
||||||
@ -134,11 +138,11 @@ func testPowConcurrentVerification(t *testing.T, threads int) {
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case full && valid:
|
case full && valid:
|
||||||
_, results = verifyNoncesFromBlocks(FakePow{}, blocks)
|
_, results = verifyNoncesFromBlocks(pow.FakePow{}, blocks)
|
||||||
case full && !valid:
|
case full && !valid:
|
||||||
_, results = verifyNoncesFromBlocks(failPow{uint64(len(blocks) - 1)}, blocks)
|
_, results = verifyNoncesFromBlocks(failPow{uint64(len(blocks) - 1)}, blocks)
|
||||||
case !full && valid:
|
case !full && valid:
|
||||||
_, results = verifyNoncesFromHeaders(FakePow{}, headers)
|
_, results = verifyNoncesFromHeaders(pow.FakePow{}, headers)
|
||||||
case !full && !valid:
|
case !full && !valid:
|
||||||
_, results = verifyNoncesFromHeaders(failPow{uint64(len(headers) - 1)}, headers)
|
_, results = verifyNoncesFromHeaders(failPow{uint64(len(headers) - 1)}, headers)
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tests that DAO-fork enabled clients can properly filter out fork-commencing
|
// Tests that DAO-fork enabled clients can properly filter out fork-commencing
|
||||||
@ -40,12 +41,12 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
|||||||
proDb, _ := ethdb.NewMemDatabase()
|
proDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(proDb)
|
WriteGenesisBlockForTesting(proDb)
|
||||||
proConf := ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: true}
|
proConf := ¶ms.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()
|
conDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(conDb)
|
WriteGenesisBlockForTesting(conDb)
|
||||||
conConf := ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: false}
|
conConf := ¶ms.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 {
|
if _, err := proBc.InsertChain(prefix); err != nil {
|
||||||
t.Fatalf("pro-fork: failed to import chain prefix: %v", err)
|
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
|
// Create a pro-fork block, and try to feed into the no-fork chain
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(db)
|
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))
|
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1))
|
||||||
for j := 0; j < len(blocks)/2; j++ {
|
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
|
// Create a no-fork block, and try to feed into the pro-fork chain
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(db)
|
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))
|
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1))
|
||||||
for j := 0; j < len(blocks)/2; j++ {
|
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
|
// Verify that contra-forkers accept pro-fork extra-datas after forking finishes
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(db)
|
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))
|
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1))
|
||||||
for j := 0; j < len(blocks)/2; j++ {
|
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
|
// Verify that pro-forkers accept contra-fork extra-datas after forking finishes
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(db)
|
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))
|
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1))
|
||||||
for j := 0; j < len(blocks)/2; j++ {
|
for j := 0; j < len(blocks)/2; j++ {
|
||||||
|
@ -288,15 +288,15 @@ func CreatePoW(config *Config) (pow.PoW, error) {
|
|||||||
switch {
|
switch {
|
||||||
case config.PowFake:
|
case config.PowFake:
|
||||||
log.Warn("Ethash used in fake mode")
|
log.Warn("Ethash used in fake mode")
|
||||||
return pow.PoW(core.FakePow{}), nil
|
return pow.FakePow{}, nil
|
||||||
case config.PowTest:
|
case config.PowTest:
|
||||||
log.Warn("Ethash used in test mode")
|
log.Warn("Ethash used in test mode")
|
||||||
return ethash.NewForTesting()
|
return pow.NewTestEthash(), nil
|
||||||
case config.PowShared:
|
case config.PowShared:
|
||||||
log.Warn("Ethash used in shared mode")
|
log.Warn("Ethash used in shared mode")
|
||||||
return ethash.NewShared(), nil
|
return pow.NewSharedEthash(), nil
|
||||||
default:
|
default:
|
||||||
return ethash.New(), nil
|
return pow.NewFullEthash("", ""), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
)
|
)
|
||||||
|
|
||||||
var bigTxGas = new(big.Int).SetUint64(params.TxGas)
|
var bigTxGas = new(big.Int).SetUint64(params.TxGas)
|
||||||
@ -468,7 +469,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
|
|||||||
// Create a DAO aware protocol manager
|
// Create a DAO aware protocol manager
|
||||||
var (
|
var (
|
||||||
evmux = new(event.TypeMux)
|
evmux = new(event.TypeMux)
|
||||||
pow = new(core.FakePow)
|
pow = new(pow.FakePow)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
genesis = core.WriteGenesisBlockForTesting(db)
|
genesis = core.WriteGenesisBlockForTesting(db)
|
||||||
config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
|
config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -53,7 +54,7 @@ var (
|
|||||||
func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) (*ProtocolManager, error) {
|
func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) (*ProtocolManager, error) {
|
||||||
var (
|
var (
|
||||||
evmux = new(event.TypeMux)
|
evmux = new(event.TypeMux)
|
||||||
pow = new(core.FakePow)
|
pow = new(pow.FakePow)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
genesis = core.WriteGenesisBlockForTesting(db, testBank)
|
genesis = core.WriteGenesisBlockForTesting(db, testBank)
|
||||||
chainConfig = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker
|
chainConfig = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/ethash"
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@ -39,6 +38,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
@ -1378,11 +1378,7 @@ func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string,
|
|||||||
if block == nil {
|
if block == nil {
|
||||||
return "", fmt.Errorf("block #%d not found", number)
|
return "", fmt.Errorf("block #%d not found", number)
|
||||||
}
|
}
|
||||||
hash, err := ethash.GetSeedHash(number)
|
return fmt.Sprintf("0x%x", pow.EthashSeedHash(number)), nil
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("0x%x", hash), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrivateDebugAPI is the collection of Etheruem APIs exposed over the private
|
// PrivateDebugAPI is the collection of Etheruem APIs exposed over the private
|
||||||
|
@ -39,6 +39,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -134,7 +135,7 @@ func testRCL() RequestCostList {
|
|||||||
func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *core.BlockGen)) (*ProtocolManager, ethdb.Database, *LesOdr, error) {
|
func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *core.BlockGen)) (*ProtocolManager, ethdb.Database, *LesOdr, error) {
|
||||||
var (
|
var (
|
||||||
evmux = new(event.TypeMux)
|
evmux = new(event.TypeMux)
|
||||||
pow = new(core.FakePow)
|
pow = new(pow.FakePow)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
genesis = core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
genesis = core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
||||||
chainConfig = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker
|
chainConfig = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker
|
||||||
|
@ -169,6 +169,9 @@ func (self *LightChain) loadLastState() error {
|
|||||||
headerTd := self.GetTd(header.Hash(), header.Number.Uint64())
|
headerTd := self.GetTd(header.Hash(), header.Number.Uint64())
|
||||||
log.Info("Loaded most recent local header", "number", header.Number, "hash", header.Hash(), "td", headerTd)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/ethash"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
@ -67,7 +66,7 @@ func newCanonical(n int) (ethdb.Database, *LightChain, error) {
|
|||||||
// Initialize a fresh chain with only a genesis block
|
// Initialize a fresh chain with only a genesis block
|
||||||
genesis, _ := core.WriteTestNetGenesisBlock(db)
|
genesis, _ := core.WriteTestNetGenesisBlock(db)
|
||||||
|
|
||||||
blockchain, _ := NewLightChain(&dummyOdr{db: db}, testChainConfig(), core.FakePow{}, evmux)
|
blockchain, _ := NewLightChain(&dummyOdr{db: db}, testChainConfig(), pow.FakePow{}, evmux)
|
||||||
// Create and inject the requested chain
|
// Create and inject the requested chain
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return db, blockchain, nil
|
return db, blockchain, nil
|
||||||
@ -82,15 +81,10 @@ func init() {
|
|||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
}
|
}
|
||||||
|
|
||||||
func thePow() pow.PoW {
|
|
||||||
pow, _ := ethash.NewForTesting()
|
|
||||||
return pow
|
|
||||||
}
|
|
||||||
|
|
||||||
func theLightChain(db ethdb.Database, t *testing.T) *LightChain {
|
func theLightChain(db ethdb.Database, t *testing.T) *LightChain {
|
||||||
var eventMux event.TypeMux
|
var eventMux event.TypeMux
|
||||||
core.WriteTestNetGenesisBlock(db)
|
core.WriteTestNetGenesisBlock(db)
|
||||||
LightChain, err := NewLightChain(&dummyOdr{db: db}, testChainConfig(), thePow(), &eventMux)
|
LightChain, err := NewLightChain(&dummyOdr{db: db}, testChainConfig(), pow.NewTestEthash(), &eventMux)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("failed creating LightChain:", err)
|
t.Error("failed creating LightChain:", err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@ -311,7 +305,7 @@ func (odr *dummyOdr) Retrieve(ctx context.Context, req OdrRequest) error {
|
|||||||
func chm(genesis *types.Block, db ethdb.Database) *LightChain {
|
func chm(genesis *types.Block, db ethdb.Database) *LightChain {
|
||||||
odr := &dummyOdr{db: db}
|
odr := &dummyOdr{db: db}
|
||||||
var eventMux event.TypeMux
|
var eventMux event.TypeMux
|
||||||
bc := &LightChain{odr: odr, chainDb: db, genesisBlock: genesis, eventMux: &eventMux, pow: core.FakePow{}}
|
bc := &LightChain{odr: odr, chainDb: db, genesisBlock: genesis, eventMux: &eventMux, pow: pow.FakePow{}}
|
||||||
bc.hc, _ = core.NewHeaderChain(db, testChainConfig(), bc.Validator, bc.getProcInterrupt)
|
bc.hc, _ = core.NewHeaderChain(db, testChainConfig(), bc.Validator, bc.getProcInterrupt)
|
||||||
bc.bodyCache, _ = lru.New(100)
|
bc.bodyCache, _ = lru.New(100)
|
||||||
bc.bodyRLPCache, _ = lru.New(100)
|
bc.bodyRLPCache, _ = lru.New(100)
|
||||||
@ -394,7 +388,7 @@ func TestReorgBadHeaderHashes(t *testing.T) {
|
|||||||
core.BadHashes[headers[3].Hash()] = true
|
core.BadHashes[headers[3].Hash()] = true
|
||||||
defer func() { delete(core.BadHashes, headers[3].Hash()) }()
|
defer func() { delete(core.BadHashes, headers[3].Hash()) }()
|
||||||
// Create a new chain manager and check it rolled back the state
|
// Create a new chain manager and check it rolled back the state
|
||||||
ncm, err := NewLightChain(&dummyOdr{db: db}, testChainConfig(), core.FakePow{}, new(event.TypeMux))
|
ncm, err := NewLightChain(&dummyOdr{db: db}, testChainConfig(), pow.FakePow{}, new(event.TypeMux))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create new chain manager: %v", err)
|
t.Fatalf("failed to create new chain manager: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@ -247,7 +248,7 @@ func testChainGen(i int, block *core.BlockGen) {
|
|||||||
func testChainOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
|
func testChainOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
|
||||||
var (
|
var (
|
||||||
evmux = new(event.TypeMux)
|
evmux = new(event.TypeMux)
|
||||||
pow = new(core.FakePow)
|
pow = new(pow.FakePow)
|
||||||
sdb, _ = ethdb.NewMemDatabase()
|
sdb, _ = ethdb.NewMemDatabase()
|
||||||
ldb, _ = ethdb.NewMemDatabase()
|
ldb, _ = ethdb.NewMemDatabase()
|
||||||
genesis = core.WriteGenesisBlockForTesting(sdb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
genesis = core.WriteGenesisBlockForTesting(sdb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ func TestTxPool(t *testing.T) {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
evmux = new(event.TypeMux)
|
evmux = new(event.TypeMux)
|
||||||
pow = new(core.FakePow)
|
pow = new(pow.FakePow)
|
||||||
sdb, _ = ethdb.NewMemDatabase()
|
sdb, _ = ethdb.NewMemDatabase()
|
||||||
ldb, _ = ethdb.NewMemDatabase()
|
ldb, _ = ethdb.NewMemDatabase()
|
||||||
genesis = core.WriteGenesisBlockForTesting(sdb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
genesis = core.WriteGenesisBlockForTesting(sdb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
||||||
|
@ -23,7 +23,6 @@ const (
|
|||||||
// locationTrims are trimmed for display to avoid unwieldy log lines.
|
// locationTrims are trimmed for display to avoid unwieldy log lines.
|
||||||
var locationTrims = []string{
|
var locationTrims = []string{
|
||||||
"github.com/ethereum/go-ethereum/",
|
"github.com/ethereum/go-ethereum/",
|
||||||
"github.com/ethereum/ethash/",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintOrigins sets or unsets log location (file:line) printing for terminal
|
// PrintOrigins sets or unsets log location (file:line) printing for terminal
|
||||||
|
@ -111,7 +111,7 @@ func (self *CpuAgent) mine(work *Work, stop <-chan struct{}) {
|
|||||||
log.Debug(fmt.Sprintf("(re)started agent[%d]. mining...\n", self.index))
|
log.Debug(fmt.Sprintf("(re)started agent[%d]. mining...\n", self.index))
|
||||||
|
|
||||||
// Mine
|
// Mine
|
||||||
nonce, mixDigest := self.pow.Search(work.Block, stop, self.index)
|
nonce, mixDigest := self.pow.Search(work.Block, stop)
|
||||||
if nonce != 0 {
|
if nonce != 0 {
|
||||||
block := work.Block.WithMiningResult(types.EncodeNonce(nonce), common.BytesToHash(mixDigest))
|
block := work.Block.WithMiningResult(types.EncodeNonce(nonce), common.BytesToHash(mixDigest))
|
||||||
self.returnCh <- &Result{work, block}
|
self.returnCh <- &Result{work, block}
|
||||||
@ -121,5 +121,5 @@ func (self *CpuAgent) mine(work *Work, stop <-chan struct{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *CpuAgent) GetHashRate() int64 {
|
func (self *CpuAgent) GetHashRate() int64 {
|
||||||
return self.pow.GetHashrate()
|
return int64(self.pow.Hashrate())
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ func (self *Miner) Mining() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) HashRate() (tot int64) {
|
func (self *Miner) HashRate() (tot int64) {
|
||||||
tot += self.pow.GetHashrate()
|
tot += int64(self.pow.Hashrate())
|
||||||
// do we care this might race? is it worth we're rewriting some
|
// do we care this might race? is it worth we're rewriting some
|
||||||
// aspects of the worker/locking up agents so we can get an accurate
|
// aspects of the worker/locking up agents so we can get an accurate
|
||||||
// hashrate?
|
// hashrate?
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/ethash"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
@ -115,7 +114,7 @@ func (a *RemoteAgent) GetWork() ([3]string, error) {
|
|||||||
block := a.currentWork.Block
|
block := a.currentWork.Block
|
||||||
|
|
||||||
res[0] = block.HashNoNonce().Hex()
|
res[0] = block.HashNoNonce().Hex()
|
||||||
seedHash, _ := ethash.GetSeedHash(block.NumberU64())
|
seedHash := pow.EthashSeedHash(block.NumberU64())
|
||||||
res[1] = common.BytesToHash(seedHash).Hex()
|
res[1] = common.BytesToHash(seedHash).Hex()
|
||||||
// Calculate the "target" to be returned to the external miner
|
// Calculate the "target" to be returned to the external miner
|
||||||
n := big.NewInt(1)
|
n := big.NewInt(1)
|
||||||
@ -145,8 +144,8 @@ func (a *RemoteAgent) SubmitWork(nonce types.BlockNonce, mixDigest, hash common.
|
|||||||
}
|
}
|
||||||
// Make sure the PoW solutions is indeed valid
|
// Make sure the PoW solutions is indeed valid
|
||||||
block := work.Block.WithMiningResult(nonce, mixDigest)
|
block := work.Block.WithMiningResult(nonce, mixDigest)
|
||||||
if !a.pow.Verify(block) {
|
if err := a.pow.Verify(block); err != nil {
|
||||||
log.Warn(fmt.Sprintf("Invalid PoW submitted for %x", hash))
|
log.Warn(fmt.Sprintf("Invalid PoW submitted for %x: %v", hash, err))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Solutions seems to be valid, return to the miner and notify acceptance
|
// Solutions seems to be valid, return to the miner and notify acceptance
|
||||||
|
37
pow/block.go
37
pow/block.go
@ -1,37 +0,0 @@
|
|||||||
// Copyright 2014 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package pow
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Block interface {
|
|
||||||
Difficulty() *big.Int
|
|
||||||
HashNoNonce() common.Hash
|
|
||||||
Nonce() uint64
|
|
||||||
MixDigest() common.Hash
|
|
||||||
NumberU64() uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChainManager interface {
|
|
||||||
GetBlockByNumber(uint64) *types.Block
|
|
||||||
CurrentBlock() *types.Block
|
|
||||||
}
|
|
1154
pow/ethash.go
1154
pow/ethash.go
File diff suppressed because it is too large
Load Diff
1071
pow/ethash_algo.go
Normal file
1071
pow/ethash_algo.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -675,14 +675,14 @@ func TestHashimoto(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Becnhmarks the cache generation performance.
|
// Benchmarks the cache generation performance.
|
||||||
func BenchmarkCacheGeneration(b *testing.B) {
|
func BenchmarkCacheGeneration(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
generateCache(cacheSize(1), make([]byte, 32))
|
generateCache(cacheSize(1), make([]byte, 32))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Becnhmarks the dataset (small) generation performance.
|
// Benchmarks the dataset (small) generation performance.
|
||||||
func BenchmarkSmallDatasetGeneration(b *testing.B) {
|
func BenchmarkSmallDatasetGeneration(b *testing.B) {
|
||||||
rawCache := generateCache(65536, make([]byte, 32))
|
rawCache := generateCache(65536, make([]byte, 32))
|
||||||
cache := prepare(uint64(len(rawCache)), bytes.NewReader(rawCache))
|
cache := prepare(uint64(len(rawCache)), bytes.NewReader(rawCache))
|
||||||
@ -693,7 +693,7 @@ func BenchmarkSmallDatasetGeneration(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Becnhmarks the light verification performace.
|
// Benchmarks the light verification performance.
|
||||||
func BenchmarkHashimotoLight(b *testing.B) {
|
func BenchmarkHashimotoLight(b *testing.B) {
|
||||||
var (
|
var (
|
||||||
rawCache = generateCache(cacheSize(1), make([]byte, 32))
|
rawCache = generateCache(cacheSize(1), make([]byte, 32))
|
||||||
@ -706,7 +706,7 @@ func BenchmarkHashimotoLight(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Becnhmarks the full (small) verification performace.
|
// Benchmarks the full (small) verification performance.
|
||||||
func BenchmarkHashimotoFullSmall(b *testing.B) {
|
func BenchmarkHashimotoFullSmall(b *testing.B) {
|
||||||
var (
|
var (
|
||||||
rawCache = generateCache(65536, make([]byte, 32))
|
rawCache = generateCache(65536, make([]byte, 32))
|
44
pow/pow.go
44
pow/pow.go
@ -16,9 +16,43 @@
|
|||||||
|
|
||||||
package pow
|
package pow
|
||||||
|
|
||||||
type PoW interface {
|
import (
|
||||||
Search(block Block, stop <-chan struct{}, index int) (uint64, []byte)
|
"math/big"
|
||||||
Verify(block Block) bool
|
|
||||||
GetHashrate() int64
|
"github.com/ethereum/go-ethereum/common"
|
||||||
Turbo(bool)
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Block interface {
|
||||||
|
Difficulty() *big.Int
|
||||||
|
HashNoNonce() common.Hash
|
||||||
|
Nonce() uint64
|
||||||
|
MixDigest() common.Hash
|
||||||
|
NumberU64() uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ChainManager interface {
|
||||||
|
GetBlockByNumber(uint64) *types.Block
|
||||||
|
CurrentBlock() *types.Block
|
||||||
|
}
|
||||||
|
|
||||||
|
type PoW interface {
|
||||||
|
Verify(block Block) error
|
||||||
|
Search(block Block, stop <-chan struct{}) (uint64, []byte)
|
||||||
|
Hashrate() float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// FakePow is a non-validating proof of work implementation.
|
||||||
|
// It returns true from Verify for any block.
|
||||||
|
type FakePow struct{}
|
||||||
|
|
||||||
|
// Verify implements PoW, returning a success for an input.
|
||||||
|
func (pow FakePow) Verify(block Block) error { return nil }
|
||||||
|
|
||||||
|
// Search implements PoW, returning the nonce 0 for any call.
|
||||||
|
func (pow FakePow) Search(block Block, stop <-chan struct{}) (uint64, []byte) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hashrate implements PoW, returning 0.
|
||||||
|
func (pow FakePow) Hashrate() float64 { return 0 }
|
||||||
|
@ -26,7 +26,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/ethash"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
@ -36,6 +35,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ func runBlockTest(homesteadBlock, daoForkBlock, gasPriceFork *big.Int, test *Blo
|
|||||||
core.WriteHeadBlockHash(db, test.Genesis.Hash())
|
core.WriteHeadBlockHash(db, test.Genesis.Hash())
|
||||||
evmux := new(event.TypeMux)
|
evmux := new(event.TypeMux)
|
||||||
config := ¶ms.ChainConfig{HomesteadBlock: homesteadBlock, DAOForkBlock: daoForkBlock, DAOForkSupport: true, EIP150Block: gasPriceFork}
|
config := ¶ms.ChainConfig{HomesteadBlock: homesteadBlock, DAOForkBlock: daoForkBlock, DAOForkSupport: true, EIP150Block: gasPriceFork}
|
||||||
chain, err := core.NewBlockChain(db, config, ethash.NewShared(), evmux, vm.Config{})
|
chain, err := core.NewBlockChain(db, config, pow.NewSharedEthash(), evmux, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user