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
|
// VerifyHeader checks whether a header conforms to the consensus rules of a
|
||||||
// given engine. Verifying the seal may be done optionally here, or explicitly
|
// given engine. Verifying the seal may be done optionally here, or explicitly
|
||||||
// via the VerifySeal method.
|
// 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
|
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
|
||||||
// concurrently. The method returns a quit channel to abort the operations and
|
// 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
|
// a results channel to retrieve the async verifications (the order is that of
|
||||||
// the input slice).
|
// 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
|
// VerifyUncles verifies that the given block's uncles conform to the consensus
|
||||||
// rules of a given engine.
|
// rules of a given engine.
|
||||||
|
|
@ -76,7 +76,7 @@ type Engine interface {
|
||||||
|
|
||||||
// Prepare initializes the consensus fields of a block header according to the
|
// Prepare initializes the consensus fields of a block header according to the
|
||||||
// rules of a particular engine. The changes are executed inline.
|
// 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)
|
// Finalize runs any post-transaction state modifications (e.g. block rewards)
|
||||||
// and assembles the final block.
|
// 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
|
// VerifyHeader checks whether a header conforms to the consensus rules of the
|
||||||
// stock Ethereum ethash engine.
|
// 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 we're running a full engine faking, accept any input as valid
|
||||||
if ethash.config.PowMode == ModeFullFake {
|
if ethash.config.PowMode == ModeFullFake {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -81,13 +81,13 @@ func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, state *state.Sta
|
||||||
return consensus.ErrUnknownAncestor
|
return consensus.ErrUnknownAncestor
|
||||||
}
|
}
|
||||||
// Sanity checks passed, do a proper verification
|
// 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
|
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
|
||||||
// concurrently. The method returns a quit channel to abort the operations and
|
// concurrently. The method returns a quit channel to abort the operations and
|
||||||
// a results channel to retrieve the async verifications.
|
// 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 we're running a full engine faking, accept any input as valid
|
||||||
if ethash.config.PowMode == ModeFullFake || len(headers) == 0 {
|
if ethash.config.PowMode == ModeFullFake || len(headers) == 0 {
|
||||||
abort, results := make(chan struct{}), make(chan error, len(headers))
|
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++ {
|
for i := 0; i < workers; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
for index := range inputs {
|
for index := range inputs {
|
||||||
errors[index] = ethash.verifyHeaderWorker(chain, state, headers, seals, index)
|
errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index)
|
||||||
done <- index
|
done <- index
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
@ -149,7 +149,7 @@ func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, state *state.St
|
||||||
return abort, errorsOut
|
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
|
var parent *types.Header
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
|
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 {
|
if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil {
|
||||||
return nil // known block
|
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
|
// 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() {
|
if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() {
|
||||||
return errDanglingUncle
|
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
|
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
|
// verifyHeader checks whether a header conforms to the consensus rules of the
|
||||||
// stock Ethereum ethash engine.
|
// stock Ethereum ethash engine.
|
||||||
// See YP section 4.3.4. "Block Header Validity"
|
// 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
|
// Ensure that the header's extra-data section is of a reasonable size
|
||||||
if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
|
if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
|
||||||
return fmt.Errorf("extra-data too long: %d > %d", 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
|
// Prepare implements consensus.Engine, initializing the difficulty field of a
|
||||||
// header to conform to the ethash protocol. The changes are done inline.
|
// 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)
|
parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
return consensus.ErrUnknownAncestor
|
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.
|
// 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 {
|
func (c *Posv) VerifyHeader(chain consensus.ChainReader, header *types.Header, fullVerify bool) error {
|
||||||
return c.verifyHeaderWithCache(chain, state, header, nil, fullVerify)
|
return c.verifyHeaderWithCache(chain, header, nil, fullVerify)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
|
// 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
|
// 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).
|
// 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{})
|
abort := make(chan struct{})
|
||||||
results := make(chan error, len(headers))
|
results := make(chan error, len(headers))
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for i, header := range headers {
|
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 {
|
select {
|
||||||
case <-abort:
|
case <-abort:
|
||||||
|
|
@ -290,12 +290,12 @@ func (c *Posv) VerifyHeaders(chain consensus.ChainReader, state *state.StateDB,
|
||||||
return abort, results
|
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())
|
_, check := c.verifiedHeaders.Get(header.Hash())
|
||||||
if check {
|
if check {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := c.verifyHeader(chain, state, header, parents, fullVerify)
|
err := c.verifyHeader(chain, header, parents, fullVerify)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.verifiedHeaders.Add(header.Hash(), true)
|
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
|
// 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
|
// looking those up from the database. This is useful for concurrently verifying
|
||||||
// a batch of new headers.
|
// 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 {
|
if header.Number == nil {
|
||||||
return errUnknownBlock
|
return errUnknownBlock
|
||||||
}
|
}
|
||||||
|
|
@ -361,14 +361,14 @@ func (c *Posv) verifyHeader(chain consensus.ChainReader, state *state.StateDB, h
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// All basic checks passed, verify cascading fields
|
// 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,
|
// verifyCascadingFields verifies all the header fields that are not standalone,
|
||||||
// rather depend on a batch of previous headers. The caller may optionally pass
|
// 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
|
// 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.
|
// 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
|
// The genesis block is the always valid dead-end
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
if number == 0 {
|
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 we're at block zero, make a snapshot
|
||||||
if number == 0 {
|
if number == 0 {
|
||||||
genesis := chain.GetHeaderByNumber(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
|
return nil, err
|
||||||
}
|
}
|
||||||
signers := make([]common.Address, (len(genesis.Extra)-extraVanity-extraSeal)/common.AddressLength)
|
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
|
// Prepare implements consensus.Engine, preparing all the consensus fields of the
|
||||||
// header for running the transactions on top.
|
// 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)
|
// If the block isn't a checkpoint, cast a random vote (good enough for now)
|
||||||
header.Coinbase = common.Address{}
|
header.Coinbase = common.Address{}
|
||||||
header.Nonce = types.BlockNonce{}
|
header.Nonce = types.BlockNonce{}
|
||||||
|
|
|
||||||
|
|
@ -1075,11 +1075,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
|
||||||
seals[i] = true
|
seals[i] = true
|
||||||
bc.downloadingBlock.Add(block.Hash(), true)
|
bc.downloadingBlock.Add(block.Hash(), true)
|
||||||
}
|
}
|
||||||
st, err := bc.State()
|
abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
|
||||||
if err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
abort, results := bc.engine.VerifyHeaders(bc, st, headers, seals)
|
|
||||||
defer close(abort)
|
defer close(abort)
|
||||||
|
|
||||||
// Iterate over the blocks and insert when the verifier permits
|
// 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)
|
log.Debug("Stop prepare a block because inserting", "number", block.NumberU64(), "hash", block.Hash(), "validator", block.Header().Validator)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
state, err := bc.State()
|
err = bc.engine.VerifyHeader(bc, block.Header(), false)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = bc.engine.VerifyHeader(bc, state, block.Header(), false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
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)
|
defer close(abort)
|
||||||
|
|
||||||
// Iterate over the headers and ensure they all check out
|
// 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.
|
// per transaction, dependent on the requestd tracer.
|
||||||
func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, config *TraceConfig) ([]*txTraceResult, error) {
|
func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, config *TraceConfig) ([]*txTraceResult, error) {
|
||||||
// Create the parent state database
|
// Create the parent state database
|
||||||
state, err := api.eth.blockchain.State()
|
if err := api.eth.engine.VerifyHeader(api.eth.blockchain, block.Header(), true); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err = api.eth.engine.VerifyHeader(api.eth.blockchain, state, block.Header(), true); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
parent := api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
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)
|
manager.downloader = downloader.New(mode, chaindb, manager.eventMux, blockchain, nil, manager.removePeer)
|
||||||
|
|
||||||
validator := func(header *types.Header) error {
|
validator := func(header *types.Header) error {
|
||||||
state, err := blockchain.State()
|
return engine.VerifyHeader(blockchain, header, true)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return engine.VerifyHeader(blockchain, state, header, true)
|
|
||||||
}
|
}
|
||||||
heighter := func() uint64 {
|
heighter := func() uint64 {
|
||||||
return blockchain.CurrentBlock().NumberU64()
|
return blockchain.CurrentBlock().NumberU64()
|
||||||
|
|
|
||||||
|
|
@ -552,11 +552,8 @@ func (self *worker) commitNewWork() {
|
||||||
if atomic.LoadInt32(&self.mining) == 1 {
|
if atomic.LoadInt32(&self.mining) == 1 {
|
||||||
header.Coinbase = self.coinbase
|
header.Coinbase = self.coinbase
|
||||||
}
|
}
|
||||||
state := &state.StateDB{}
|
|
||||||
if self.current != nil {
|
if err := self.engine.Prepare(self.chain, header); err != nil {
|
||||||
state = self.current.state
|
|
||||||
}
|
|
||||||
if err := self.engine.Prepare(self.chain, state, header); err != nil {
|
|
||||||
log.Error("Failed to prepare header for new block", "err", err)
|
log.Error("Failed to prepare header for new block", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue