diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 1385ae1e46..26e592dfb6 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/XDPoS" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" @@ -1243,17 +1243,18 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai if config.XDPoS != nil { engine = XDPoS.New(config.XDPoS, 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 XDPoS consensus") } if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) diff --git a/consensus/consensus.go b/consensus/consensus.go index b02afa63c4..66fcbb092a 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -58,13 +58,13 @@ type Engine interface { // VerifyHeader checks whether a header conforms to the consensus rules of a // given engine. Verifying the seal may be done optionally here, or explicitly // via the VerifySeal method. - VerifyHeader(chain ChainReader, header *types.Header, fullVerify bool) error + VerifyHeader(chain ChainReader, state *state.StateDB, header *types.Header, fullVerify bool) error // 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 (the order is that of // the input slice). - VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) + VerifyHeaders(chain ChainReader, state *state.StateDB, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) // VerifyUncles verifies that the given block's uncles conform to the consensus // rules of a given engine. @@ -76,7 +76,7 @@ type Engine interface { // Prepare initializes the consensus fields of a block header according to the // rules of a particular engine. The changes are executed inline. - Prepare(chain ChainReader, header *types.Header) error + Prepare(chain ChainReader, state *state.StateDB, header *types.Header) error // Finalize runs any post-transaction state modifications (e.g. block rewards) // and assembles the final block. @@ -103,4 +103,4 @@ type PoW interface { // Hashrate returns the current mining hashrate of a PoW consensus engine. Hashrate() float64 -} +} \ No newline at end of file diff --git a/core/blockchain.go b/core/blockchain.go index bf9e6ee1fd..cd6f235c2e 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1069,7 +1069,11 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty seals[i] = true bc.downloadingBlock.Add(block.Hash(), true) } - abort, results := bc.engine.VerifyHeaders(bc, headers, seals) + st, err := bc.State() + if err != nil { + return 0, nil, nil, err + } + abort, results := bc.engine.VerifyHeaders(bc, st, headers, seals) defer close(abort) // Iterate over the blocks and insert when the verifier permits @@ -1246,7 +1250,11 @@ func (bc *BlockChain) PrepareBlock(block *types.Block) (err error) { log.Debug("Stop prepare a block because inserting", "number", block.NumberU64(), "hash", block.Hash(), "validator", block.Header().Validator) return nil } - err = bc.engine.VerifyHeader(bc, block.Header(), false) + state, err := bc.State() + if err != nil { + return err + } + err = bc.engine.VerifyHeader(bc, state, block.Header(), false) if err != nil { return err } @@ -1676,7 +1684,11 @@ Error: %v // because nonces can be verified sparsely, not needing to check each. func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { start := time.Now() - if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { + state, err := bc.State() + if err != nil { + return 0, err + } + if i, err := bc.hc.ValidateHeaderChain(chain, state, checkFreq); err != nil { return i, err } diff --git a/core/headerchain.go b/core/headerchain.go index 2d1b0a2a18..a5efb51831 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/hashicorp/golang-lru" + "github.com/ethereum/go-ethereum/core/state" ) const ( @@ -203,7 +204,7 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er // header writes should be protected by the parent chain mutex individually. type WhCallback func(*types.Header) error -func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) { +func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, state *state.StateDB, checkFreq int) (int, error) { // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(chain); i++ { if chain[i].Number.Uint64() != chain[i-1].Number.Uint64()+1 || chain[i].ParentHash != chain[i-1].Hash() { @@ -227,7 +228,7 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) } seals[len(seals)-1] = true // Last should always be verified to avoid junk - abort, results := hc.engine.VerifyHeaders(hc, chain, seals) + abort, results := hc.engine.VerifyHeaders(hc, state, chain, seals) defer close(abort) // Iterate over the headers and ensure they all check out @@ -454,4 +455,4 @@ func (hc *HeaderChain) Engine() consensus.Engine { return hc.engine } // a header chain does not have blocks available for retrieval. func (hc *HeaderChain) GetBlock(hash common.Hash, number uint64) *types.Block { return nil -} +} \ No newline at end of file diff --git a/light/lightchain.go b/light/lightchain.go index 2784615d35..b778f70eb7 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -344,8 +344,12 @@ func (self *LightChain) postChainEvents(events []interface{}) { // chain events when necessary. func (self *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { start := time.Now() - if i, err := self.hc.ValidateHeaderChain(chain, checkFreq); err != nil { - return i, err + state, err := self.State() + if err != nil { + return 0, err + } + if i, err := self.hc.ValidateHeaderChain(chain, state, checkFreq); err != nil { + return i, err } // Make sure only one thread manipulates the chain at once diff --git a/miner/worker.go b/miner/worker.go index 5609d24565..501d40cc2c 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -552,7 +552,7 @@ func (self *worker) commitNewWork() { if atomic.LoadInt32(&self.mining) == 1 { header.Coinbase = self.coinbase } - if err := self.engine.Prepare(self.chain, header); err != nil { + if err := self.engine.Prepare(self.chain, self.current.state, header); err != nil { log.Error("Failed to prepare header for new block", "err", err) return }