From 337b7c64ee3ccd1f8a0c18440609751b2df0f559 Mon Sep 17 00:00:00 2001 From: Tuna Date: Sat, 12 Jan 2019 13:08:01 +0700 Subject: [PATCH] remove state at verifyHeader, prepare --- consensus/consensus.go | 6 +++--- consensus/ethash/consensus.go | 18 +++++++++--------- consensus/posv/posv.go | 22 +++++++++++----------- core/blockchain.go | 12 ++---------- core/headerchain.go | 2 +- eth/api_tracer.go | 6 +----- eth/handler.go | 6 +----- miner/worker.go | 7 ++----- 8 files changed, 30 insertions(+), 49 deletions(-) diff --git a/consensus/consensus.go b/consensus/consensus.go index 8d992b5dee..b02afa63c4 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, state *state.StateDB, header *types.Header, fullVerify bool) error + VerifyHeader(chain ChainReader, 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, state *state.StateDB, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) + VerifyHeaders(chain ChainReader, 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, state *state.StateDB, header *types.Header) error + Prepare(chain ChainReader, header *types.Header) error // Finalize runs any post-transaction state modifications (e.g. block rewards) // and assembles the final block. diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 53b4ce968e..99eec82211 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, state *state.StateDB, header *types.Header, seal bool) error { +func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, 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, state *state.Sta return consensus.ErrUnknownAncestor } // Sanity checks passed, do a proper verification - return ethash.verifyHeader(chain, state, header, parent, false, seal) + return ethash.verifyHeader(chain, 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, state *state.StateDB, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { +func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, 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, state *state.St for i := 0; i < workers; i++ { go func() { for index := range inputs { - errors[index] = ethash.verifyHeaderWorker(chain, state, headers, seals, index) + errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index) done <- index } }() @@ -149,7 +149,7 @@ func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, state *state.St return abort, errorsOut } -func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, state *state.StateDB, headers []*types.Header, seals []bool, index int) error { +func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, 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, state *sta if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil { return nil // known block } - return ethash.verifyHeader(chain, state, headers[index], parent, false, seals[index]) + return ethash.verifyHeader(chain, 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, nil, uncle, ancestors[uncle.ParentHash], true, true); err != nil { + if err := ethash.verifyHeader(chain, 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, state *state.StateDB, header, parent *types.Header, uncle bool, seal bool) error { +func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, 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, state *state.StateDB, header *types.Header) error { +func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) error { parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) if parent == nil { return consensus.ErrUnknownAncestor diff --git a/consensus/posv/posv.go b/consensus/posv/posv.go index a27e1b3dd8..153c026b26 100644 --- a/consensus/posv/posv.go +++ b/consensus/posv/posv.go @@ -265,20 +265,20 @@ func (c *Posv) Author(header *types.Header) (common.Address, error) { } // VerifyHeader checks whether a header conforms to the consensus rules. -func (c *Posv) VerifyHeader(chain consensus.ChainReader, state *state.StateDB, header *types.Header, fullVerify bool) error { - return c.verifyHeaderWithCache(chain, state, header, nil, fullVerify) +func (c *Posv) VerifyHeader(chain consensus.ChainReader, header *types.Header, fullVerify bool) error { + return c.verifyHeaderWithCache(chain, header, nil, fullVerify) } // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. 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). -func (c *Posv) VerifyHeaders(chain consensus.ChainReader, state *state.StateDB, headers []*types.Header, fullVerifies []bool) (chan<- struct{}, <-chan error) { +func (c *Posv) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, fullVerifies []bool) (chan<- struct{}, <-chan error) { abort := make(chan struct{}) results := make(chan error, len(headers)) go func() { for i, header := range headers { - err := c.verifyHeaderWithCache(chain, state, header, headers[:i], fullVerifies[i]) + err := c.verifyHeaderWithCache(chain, header, headers[:i], fullVerifies[i]) select { case <-abort: @@ -290,12 +290,12 @@ func (c *Posv) VerifyHeaders(chain consensus.ChainReader, state *state.StateDB, return abort, results } -func (c *Posv) verifyHeaderWithCache(chain consensus.ChainReader, state *state.StateDB, header *types.Header, parents []*types.Header, fullVerify bool) error { +func (c *Posv) verifyHeaderWithCache(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error { _, check := c.verifiedHeaders.Get(header.Hash()) if check { return nil } - err := c.verifyHeader(chain, state, header, parents, fullVerify) + err := c.verifyHeader(chain, header, parents, fullVerify) if err == nil { c.verifiedHeaders.Add(header.Hash(), true) } @@ -306,7 +306,7 @@ func (c *Posv) verifyHeaderWithCache(chain consensus.ChainReader, state *state.S // caller may optionally pass in a batch of parents (ascending order) to avoid // looking those up from the database. This is useful for concurrently verifying // a batch of new headers. -func (c *Posv) verifyHeader(chain consensus.ChainReader, state *state.StateDB, header *types.Header, parents []*types.Header, fullVerify bool) error { +func (c *Posv) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error { if header.Number == nil { return errUnknownBlock } @@ -361,14 +361,14 @@ func (c *Posv) verifyHeader(chain consensus.ChainReader, state *state.StateDB, h return err } // All basic checks passed, verify cascading fields - return c.verifyCascadingFields(chain, state, header, parents, fullVerify) + return c.verifyCascadingFields(chain, header, parents, fullVerify) } // verifyCascadingFields verifies all the header fields that are not standalone, // rather depend on a batch of previous headers. The caller may optionally pass // in a batch of parents (ascending order) to avoid looking those up from the // database. This is useful for concurrently verifying a batch of new headers. -func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, state *state.StateDB, header *types.Header, parents []*types.Header, fullVerify bool) error { +func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error { // The genesis block is the always valid dead-end number := header.Number.Uint64() if number == 0 { @@ -543,7 +543,7 @@ func (c *Posv) snapshot(chain consensus.ChainReader, number uint64, hash common. // If we're at block zero, make a snapshot if number == 0 { genesis := chain.GetHeaderByNumber(0) - if err := c.VerifyHeader(chain, nil, genesis, true); err != nil { + if err := c.VerifyHeader(chain, genesis, true); err != nil { return nil, err } signers := make([]common.Address, (len(genesis.Extra)-extraVanity-extraSeal)/common.AddressLength) @@ -733,7 +733,7 @@ func (c *Posv) GetValidator(creator common.Address, chain consensus.ChainReader, // Prepare implements consensus.Engine, preparing all the consensus fields of the // header for running the transactions on top. -func (c *Posv) Prepare(chain consensus.ChainReader, state *state.StateDB, header *types.Header) error { +func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error { // If the block isn't a checkpoint, cast a random vote (good enough for now) header.Coinbase = common.Address{} header.Nonce = types.BlockNonce{} diff --git a/core/blockchain.go b/core/blockchain.go index c2d1cc2c58..48e2661111 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1075,11 +1075,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty seals[i] = true bc.downloadingBlock.Add(block.Hash(), true) } - st, err := bc.State() - if err != nil { - return 0, nil, nil, err - } - abort, results := bc.engine.VerifyHeaders(bc, st, headers, seals) + abort, results := bc.engine.VerifyHeaders(bc, headers, seals) defer close(abort) // Iterate over the blocks and insert when the verifier permits @@ -1256,11 +1252,7 @@ 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 } - state, err := bc.State() - if err != nil { - return err - } - err = bc.engine.VerifyHeader(bc, state, block.Header(), false) + err = bc.engine.VerifyHeader(bc, block.Header(), false) if err != nil { return err } diff --git a/core/headerchain.go b/core/headerchain.go index f0ecd73868..9bedc796f0 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -228,7 +228,7 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, state *state.S } seals[len(seals)-1] = true // Last should always be verified to avoid junk - abort, results := hc.engine.VerifyHeaders(hc, state, chain, seals) + abort, results := hc.engine.VerifyHeaders(hc, chain, seals) defer close(abort) // Iterate over the headers and ensure they all check out diff --git a/eth/api_tracer.go b/eth/api_tracer.go index 5f992494b0..07c4457bc3 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -387,11 +387,7 @@ func (api *PrivateDebugAPI) TraceBlockFromFile(ctx context.Context, file string, // per transaction, dependent on the requestd tracer. func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, config *TraceConfig) ([]*txTraceResult, error) { // Create the parent state database - state, err := api.eth.blockchain.State() - if err != nil { - return nil, err - } - if err = api.eth.engine.VerifyHeader(api.eth.blockchain, state, block.Header(), true); err != nil { + if err := api.eth.engine.VerifyHeader(api.eth.blockchain, block.Header(), true); err != nil { return nil, err } parent := api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) diff --git a/eth/handler.go b/eth/handler.go index df2435b080..322a888ade 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -165,11 +165,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne manager.downloader = downloader.New(mode, chaindb, manager.eventMux, blockchain, nil, manager.removePeer) validator := func(header *types.Header) error { - state, err := blockchain.State() - if err != nil { - return err - } - return engine.VerifyHeader(blockchain, state, header, true) + return engine.VerifyHeader(blockchain, header, true) } heighter := func() uint64 { return blockchain.CurrentBlock().NumberU64() diff --git a/miner/worker.go b/miner/worker.go index 8b80306e4d..d71b39fe7b 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -552,11 +552,8 @@ func (self *worker) commitNewWork() { if atomic.LoadInt32(&self.mining) == 1 { header.Coinbase = self.coinbase } - state := &state.StateDB{} - if self.current != nil { - state = self.current.state - } - if err := self.engine.Prepare(self.chain, state, header); err != nil { + + if err := self.engine.Prepare(self.chain, header); err != nil { log.Error("Failed to prepare header for new block", "err", err) return }