mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 02:42:27 +00:00
remove state at verifyHeader, prepare
This commit is contained in:
parent
eadb17b2bd
commit
337b7c64ee
8 changed files with 30 additions and 49 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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{}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue