diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 5aac42b208..d1bff61b65 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -33,7 +33,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/consensus" - //"github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/posv" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" @@ -1245,17 +1245,17 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai if config.Posv != nil { engine = posv.New(config.Posv, chainDb) } else { - //engine = ethash.NewFaker() - //if !ctx.GlobalBool(FakePoWFlag.Name) { - // engine = ethash.New(ethash.Config{ - // CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir), - // CachesInMem: eth.DefaultConfig.Ethash.CachesInMem, - // CachesOnDisk: eth.DefaultConfig.Ethash.CachesOnDisk, - // DatasetDir: stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir), - // DatasetsInMem: eth.DefaultConfig.Ethash.DatasetsInMem, - // DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk, - // }) - //} + engine = ethash.NewFaker() + if !ctx.GlobalBool(FakePoWFlag.Name) { + engine = ethash.New(ethash.Config{ + CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir), + CachesInMem: eth.DefaultConfig.Ethash.CachesInMem, + CachesOnDisk: eth.DefaultConfig.Ethash.CachesOnDisk, + DatasetDir: stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir), + DatasetsInMem: eth.DefaultConfig.Ethash.DatasetsInMem, + DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk, + }) + } Fatalf("Only support posv consensus") } if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 99eec82211..53b4ce968e 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -66,7 +66,7 @@ func (ethash *Ethash) Author(header *types.Header) (common.Address, error) { // VerifyHeader checks whether a header conforms to the consensus rules of the // stock Ethereum ethash engine. -func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { +func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, state *state.StateDB, header *types.Header, seal bool) error { // If we're running a full engine faking, accept any input as valid if ethash.config.PowMode == ModeFullFake { return nil @@ -81,13 +81,13 @@ func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.He return consensus.ErrUnknownAncestor } // Sanity checks passed, do a proper verification - return ethash.verifyHeader(chain, header, parent, false, seal) + return ethash.verifyHeader(chain, state, header, parent, false, seal) } // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers // concurrently. The method returns a quit channel to abort the operations and // a results channel to retrieve the async verifications. -func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { +func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, state *state.StateDB, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { // If we're running a full engine faking, accept any input as valid if ethash.config.PowMode == ModeFullFake || len(headers) == 0 { abort, results := make(chan struct{}), make(chan error, len(headers)) @@ -113,7 +113,7 @@ func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*type for i := 0; i < workers; i++ { go func() { for index := range inputs { - errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index) + errors[index] = ethash.verifyHeaderWorker(chain, state, headers, seals, index) done <- index } }() @@ -149,7 +149,7 @@ func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*type return abort, errorsOut } -func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error { +func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, state *state.StateDB, headers []*types.Header, seals []bool, index int) error { var parent *types.Header if index == 0 { parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1) @@ -162,7 +162,7 @@ func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers [] if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil { return nil // known block } - return ethash.verifyHeader(chain, headers[index], parent, false, seals[index]) + return ethash.verifyHeader(chain, state, headers[index], parent, false, seals[index]) } // VerifyUncles verifies that the given block's uncles conform to the consensus @@ -210,7 +210,7 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() { return errDanglingUncle } - if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true); err != nil { + if err := ethash.verifyHeader(chain, nil, uncle, ancestors[uncle.ParentHash], true, true); err != nil { return err } } @@ -220,7 +220,7 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo // verifyHeader checks whether a header conforms to the consensus rules of the // stock Ethereum ethash engine. // See YP section 4.3.4. "Block Header Validity" -func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *types.Header, uncle bool, seal bool) error { +func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, state *state.StateDB, header, parent *types.Header, uncle bool, seal bool) error { // Ensure that the header's extra-data section is of a reasonable size if uint64(len(header.Extra)) > params.MaximumExtraDataSize { return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize) @@ -502,7 +502,7 @@ func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Head // Prepare implements consensus.Engine, initializing the difficulty field of a // header to conform to the ethash protocol. The changes are done inline. -func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) error { +func (ethash *Ethash) Prepare(chain consensus.ChainReader, state *state.StateDB, header *types.Header) error { parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) if parent == nil { return consensus.ErrUnknownAncestor diff --git a/contracts/validator/validator_test.go b/contracts/validator/validator_test.go index f3896db4b8..346066b162 100644 --- a/contracts/validator/validator_test.go +++ b/contracts/validator/validator_test.go @@ -144,7 +144,7 @@ func TestRewardBalance(t *testing.T) { foundationAddr := common.HexToAddress(common.FoudationAddr) totalReward := new(big.Int).SetInt64(15 * 1000) - rewards, err := contracts.GetRewardBalancesRate(foundationAddr, acc3Addr, totalReward, baseValidator) + rewards, err := contracts.GetRewardBalancesRate(foundationAddr, nil, acc3Addr, totalReward) if err != nil { t.Error("Fail to get reward balances rate.", err) } diff --git a/core/block_validator_test.go b/core/block_validator_test.go index e334b3c3cd..d085effdc8 100644 --- a/core/block_validator_test.go +++ b/core/block_validator_test.go @@ -48,13 +48,13 @@ func TestHeaderVerification(t *testing.T) { for i := 0; i < len(blocks); i++ { for j, valid := range []bool{true, false} { var results <-chan error - + state, _ := chain.State() if valid { engine := ethash.NewFaker() - _, results = engine.VerifyHeaders(chain, []*types.Header{headers[i]}, []bool{true}) + _, results = engine.VerifyHeaders(chain, state, []*types.Header{headers[i]}, []bool{true}) } else { engine := ethash.NewFakeFailer(headers[i].Number.Uint64()) - _, results = engine.VerifyHeaders(chain, []*types.Header{headers[i]}, []bool{true}) + _, results = engine.VerifyHeaders(chain, state, []*types.Header{headers[i]}, []bool{true}) } // Wait for the verification result select { @@ -104,14 +104,15 @@ func testHeaderConcurrentVerification(t *testing.T, threads int) { // also an invalid chain (enough if one arbitrary block is invalid). for i, valid := range []bool{true, false} { var results <-chan error - if valid { chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}) - _, results = chain.engine.VerifyHeaders(chain, headers, seals) + state, _ := chain.State() + _, results = chain.engine.VerifyHeaders(chain, state, headers, seals) chain.Stop() } else { chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeFailer(uint64(len(headers)-1)), vm.Config{}) - _, results = chain.engine.VerifyHeaders(chain, headers, seals) + state, _ := chain.State() + _, results = chain.engine.VerifyHeaders(chain, state, headers, seals) chain.Stop() } // Wait for all the verification results @@ -175,8 +176,8 @@ func testHeaderConcurrentAbortion(t *testing.T, threads int) { // Start the verifications and immediately abort chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeDelayer(time.Millisecond), vm.Config{}) defer chain.Stop() - - abort, results := chain.engine.VerifyHeaders(chain, headers, seals) + state, _ := chain.State() + abort, results := chain.engine.VerifyHeaders(chain, state, headers, seals) close(abort) // Deplete the results channel diff --git a/core/blockchain_test.go b/core/blockchain_test.go index b752b9ef8d..46203a4f37 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -103,7 +103,8 @@ func printChain(bc *BlockChain) { func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { for _, block := range chain { // Try and process the block - err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true) + st, _ := blockchain.State() + err := blockchain.engine.VerifyHeader(blockchain, st, block.Header(), true) if err == nil { err = blockchain.validator.ValidateBody(block) } @@ -141,7 +142,8 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error { for _, header := range chain { // Try and validate the header - if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil { + state, _ := blockchain.State() + if err := blockchain.engine.VerifyHeader(blockchain, state, header, false); err != nil { return err } // Manually insert the header into the database, but don't reorganise (allows subsequent testing) diff --git a/eth/backend.go b/eth/backend.go index ad58f0677c..dae51e9582 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -393,31 +393,30 @@ func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chai if chainConfig.Posv != nil { return posv.New(chainConfig.Posv, db) } - // Otherwise, return nil - return nil - //// Otherwise assume proof-of-work - //switch { - //case config.PowMode == ethash.ModeFake: - // log.Warn("Ethash used in fake mode") - // return ethash.NewFaker() - //case config.PowMode == ethash.ModeTest: - // log.Warn("Ethash used in test mode") - // return ethash.NewTester() - //case config.PowMode == ethash.ModeShared: - // log.Warn("Ethash used in shared mode") - // return ethash.NewShared() - //default: - // engine := ethash.New(ethash.Config{ - // CacheDir: ctx.ResolvePath(config.CacheDir), - // CachesInMem: config.CachesInMem, - // CachesOnDisk: config.CachesOnDisk, - // DatasetDir: config.DatasetDir, - // DatasetsInMem: config.DatasetsInMem, - // DatasetsOnDisk: config.DatasetsOnDisk, - // }) - // engine.SetThreads(-1) // Disable CPU mining - // return engine - //} + + // Otherwise assume proof-of-work + switch { + case config.PowMode == ethash.ModeFake: + log.Warn("Ethash used in fake mode") + return ethash.NewFaker() + case config.PowMode == ethash.ModeTest: + log.Warn("Ethash used in test mode") + return ethash.NewTester() + case config.PowMode == ethash.ModeShared: + log.Warn("Ethash used in shared mode") + return ethash.NewShared() + default: + engine := ethash.New(ethash.Config{ + CacheDir: ctx.ResolvePath(config.CacheDir), + CachesInMem: config.CachesInMem, + CachesOnDisk: config.CachesOnDisk, + DatasetDir: config.DatasetDir, + DatasetsInMem: config.DatasetsInMem, + DatasetsOnDisk: config.DatasetsOnDisk, + }) + engine.SetThreads(-1) // Disable CPU mining + return engine + } } // APIs returns the collection of RPC services the ethereum package offers. diff --git a/light/lightchain_test.go b/light/lightchain_test.go index 0af7551d41..20e9556b1b 100644 --- a/light/lightchain_test.go +++ b/light/lightchain_test.go @@ -117,7 +117,8 @@ func testFork(t *testing.T, LightChain *LightChain, i, n int, comparator func(td func testHeaderChainImport(chain []*types.Header, lightchain *LightChain) error { for _, header := range chain { // Try and validate the header - if err := lightchain.engine.VerifyHeader(lightchain.hc, header, true); err != nil { + state, _ := lightchain.State() + if err := lightchain.engine.VerifyHeader(lightchain.hc, state, header, true); err != nil { return err } // Manually insert the header into the database, but don't reorganize (allows subsequent testing)