mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 13:46:43 +00:00
build block with gas limit
This commit is contained in:
parent
b0069fddd1
commit
6e0e7aa70f
7 changed files with 119 additions and 44 deletions
|
|
@ -119,13 +119,14 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
|
||||||
|
|
||||||
// ValidateState validates the various changes that happen after a state transition,
|
// ValidateState validates the various changes that happen after a state transition,
|
||||||
// such as amount of used gas, the receipt roots and the state root itself.
|
// such as amount of used gas, the receipt roots and the state root itself.
|
||||||
func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateDB, res *ProcessResult, stateless bool) error {
|
// Returns a new header with the actual state root instead of comparing with the original header.
|
||||||
|
func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateDB, res *ProcessResult, stateless bool) (*types.Header, error) {
|
||||||
if res == nil {
|
if res == nil {
|
||||||
return errors.New("nil ProcessResult value")
|
return nil, errors.New("nil ProcessResult value")
|
||||||
}
|
}
|
||||||
header := block.Header()
|
header := block.Header()
|
||||||
if block.GasUsed() != res.GasUsed {
|
if block.GasUsed() != res.GasUsed {
|
||||||
return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), res.GasUsed)
|
return nil, fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), res.GasUsed)
|
||||||
}
|
}
|
||||||
// Validate the received block's bloom with the one derived from the generated receipts.
|
// Validate the received block's bloom with the one derived from the generated receipts.
|
||||||
// For valid blocks this should always validate to true.
|
// For valid blocks this should always validate to true.
|
||||||
|
|
@ -135,33 +136,35 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
|
||||||
// everything.
|
// everything.
|
||||||
rbloom := types.MergeBloom(res.Receipts)
|
rbloom := types.MergeBloom(res.Receipts)
|
||||||
if rbloom != header.Bloom {
|
if rbloom != header.Bloom {
|
||||||
return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom)
|
return nil, fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom)
|
||||||
}
|
}
|
||||||
// In stateless mode, return early because the receipt and state root are not
|
// In stateless mode, return early because the receipt and state root are not
|
||||||
// provided through the witness, rather the cross validator needs to return it.
|
// provided through the witness, rather the cross validator needs to return it.
|
||||||
if stateless {
|
if stateless {
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
// The receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, Rn]]))
|
// The receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, Rn]]))
|
||||||
receiptSha := types.DeriveSha(res.Receipts, trie.NewStackTrie(nil))
|
receiptSha := types.DeriveSha(res.Receipts, trie.NewStackTrie(nil))
|
||||||
if receiptSha != header.ReceiptHash {
|
if receiptSha != header.ReceiptHash {
|
||||||
return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha)
|
return nil, fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha)
|
||||||
}
|
}
|
||||||
// Validate the parsed requests match the expected header value.
|
// Validate the parsed requests match the expected header value.
|
||||||
if header.RequestsHash != nil {
|
if header.RequestsHash != nil {
|
||||||
reqhash := types.CalcRequestsHash(res.Requests)
|
reqhash := types.CalcRequestsHash(res.Requests)
|
||||||
if reqhash != *header.RequestsHash {
|
if reqhash != *header.RequestsHash {
|
||||||
return fmt.Errorf("invalid requests hash (remote: %x local: %x)", *header.RequestsHash, reqhash)
|
return nil, fmt.Errorf("invalid requests hash (remote: %x local: %x)", *header.RequestsHash, reqhash)
|
||||||
}
|
}
|
||||||
} else if res.Requests != nil {
|
} else if res.Requests != nil {
|
||||||
return errors.New("block has requests before prague fork")
|
return nil, errors.New("block has requests before prague fork")
|
||||||
}
|
}
|
||||||
// Validate the state root against the received state root and throw
|
// Get the actual state root from the statedb
|
||||||
// an error if they don't match.
|
actualRoot := statedb.IntermediateRoot(v.config.IsEIP158(header.Number))
|
||||||
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
|
|
||||||
return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error())
|
// Create a new header with the actual state root
|
||||||
}
|
newHeader := *header
|
||||||
return nil
|
newHeader.Root = actualRoot
|
||||||
|
|
||||||
|
return &newHeader, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalcGasLimit computes the gas limit of the next block after parent. It aims
|
// CalcGasLimit computes the gas limit of the next block after parent. It aims
|
||||||
|
|
|
||||||
|
|
@ -1966,12 +1966,16 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s
|
||||||
ptime := time.Since(pstart)
|
ptime := time.Since(pstart)
|
||||||
|
|
||||||
vstart := time.Now()
|
vstart := time.Now()
|
||||||
if err := bc.validator.ValidateState(block, statedb, res, false); err != nil {
|
newHeader, err := bc.validator.ValidateState(block, statedb, res, false)
|
||||||
|
if err != nil {
|
||||||
bc.reportBlock(block, res, err)
|
bc.reportBlock(block, res, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vtime := time.Since(vstart)
|
vtime := time.Since(vstart)
|
||||||
|
|
||||||
|
// Create a new block with the updated header
|
||||||
|
newBlock := types.NewBlockWithHeader(newHeader).WithBody(*block.Body())
|
||||||
|
|
||||||
// If witnesses was generated and stateless self-validation requested, do
|
// If witnesses was generated and stateless self-validation requested, do
|
||||||
// that now. Self validation should *never* run in production, it's more of
|
// that now. Self validation should *never* run in production, it's more of
|
||||||
// a tight integration to enable running *all* consensus tests through the
|
// a tight integration to enable running *all* consensus tests through the
|
||||||
|
|
@ -1979,25 +1983,25 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s
|
||||||
// various invalid chain states/behaviors being contained in those tests.
|
// various invalid chain states/behaviors being contained in those tests.
|
||||||
xvstart := time.Now()
|
xvstart := time.Now()
|
||||||
if witness := statedb.Witness(); witness != nil && bc.vmConfig.StatelessSelfValidation {
|
if witness := statedb.Witness(); witness != nil && bc.vmConfig.StatelessSelfValidation {
|
||||||
log.Warn("Running stateless self-validation", "block", block.Number(), "hash", block.Hash())
|
log.Warn("Running stateless self-validation", "block", newBlock.Number(), "hash", newBlock.Hash())
|
||||||
|
|
||||||
// Remove critical computed fields from the block to force true recalculation
|
// Remove critical computed fields from the block to force true recalculation
|
||||||
context := block.Header()
|
context := newBlock.Header()
|
||||||
context.Root = common.Hash{}
|
context.Root = common.Hash{}
|
||||||
context.ReceiptHash = common.Hash{}
|
context.ReceiptHash = common.Hash{}
|
||||||
|
|
||||||
task := types.NewBlockWithHeader(context).WithBody(*block.Body())
|
task := types.NewBlockWithHeader(context).WithBody(*newBlock.Body())
|
||||||
|
|
||||||
// Run the stateless self-cross-validation
|
// Run the stateless self-cross-validation
|
||||||
crossStateRoot, crossReceiptRoot, err := ExecuteStateless(bc.chainConfig, bc.vmConfig, task, witness)
|
crossStateRoot, crossReceiptRoot, err := ExecuteStateless(bc.chainConfig, bc.vmConfig, task, witness)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("stateless self-validation failed: %v", err)
|
return nil, fmt.Errorf("stateless self-validation failed: %v", err)
|
||||||
}
|
}
|
||||||
if crossStateRoot != block.Root() {
|
if crossStateRoot != newBlock.Root() {
|
||||||
return nil, fmt.Errorf("stateless self-validation root mismatch (cross: %x local: %x)", crossStateRoot, block.Root())
|
return nil, fmt.Errorf("stateless self-validation root mismatch (cross: %x local: %x)", crossStateRoot, newBlock.Root())
|
||||||
}
|
}
|
||||||
if crossReceiptRoot != block.ReceiptHash() {
|
if crossReceiptRoot != newBlock.ReceiptHash() {
|
||||||
return nil, fmt.Errorf("stateless self-validation receipt root mismatch (cross: %x local: %x)", crossReceiptRoot, block.ReceiptHash())
|
return nil, fmt.Errorf("stateless self-validation receipt root mismatch (cross: %x local: %x)", crossReceiptRoot, newBlock.ReceiptHash())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xvtime := time.Since(xvstart)
|
xvtime := time.Since(xvstart)
|
||||||
|
|
@ -2028,9 +2032,9 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s
|
||||||
)
|
)
|
||||||
if !setHead {
|
if !setHead {
|
||||||
// Don't set the head, only insert the block
|
// Don't set the head, only insert the block
|
||||||
err = bc.writeBlockWithState(block, res.Receipts, statedb)
|
err = bc.writeBlockWithState(newBlock, res.Receipts, statedb)
|
||||||
} else {
|
} else {
|
||||||
status, err = bc.writeBlockAndSetHead(block, res.Receipts, res.Logs, statedb, false)
|
status, err = bc.writeBlockAndSetHead(newBlock, res.Receipts, res.Logs, statedb, false)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -2418,14 +2422,77 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Header) error
|
||||||
// The key difference between the InsertChain is it won't do the canonical chain
|
// The key difference between the InsertChain is it won't do the canonical chain
|
||||||
// updating. It relies on the additional SetCanonical call to finalize the entire
|
// updating. It relies on the additional SetCanonical call to finalize the entire
|
||||||
// procedure.
|
// procedure.
|
||||||
func (bc *BlockChain) InsertBlockWithoutSetHead(block *types.Block, makeWitness bool) (*stateless.Witness, error) {
|
// Returns the new header with actual state root and witness.
|
||||||
|
func (bc *BlockChain) InsertBlockWithoutSetHead(block *types.Block, makeWitness bool) (*types.Header, *stateless.Witness, error) {
|
||||||
if !bc.chainmu.TryLock() {
|
if !bc.chainmu.TryLock() {
|
||||||
return nil, errChainStopped
|
return nil, nil, errChainStopped
|
||||||
}
|
}
|
||||||
defer bc.chainmu.Unlock()
|
defer bc.chainmu.Unlock()
|
||||||
|
|
||||||
witness, _, err := bc.insertChain(types.Blocks{block}, false, makeWitness)
|
// Process the block to get the new header with actual state root
|
||||||
return witness, err
|
parent := bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
|
||||||
|
if parent == nil {
|
||||||
|
return nil, nil, consensus.ErrUnknownAncestor
|
||||||
|
}
|
||||||
|
|
||||||
|
statedb, err := state.New(parent.Root, bc.statedb)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := bc.processor.Process(block, statedb, bc.vmConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newHeader, err := bc.validator.ValidateState(block, statedb, res, false)
|
||||||
|
log.Info("New Header", "stateroot", newHeader.Root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new block with the updated header that contains the correct state root
|
||||||
|
log.Info("Block", "hash", block.Hash(), "number", block.Number())
|
||||||
|
updatedBlock := block.WithSeal(newHeader)
|
||||||
|
// Print the hash of the updated block for debugging purposes
|
||||||
|
log.Info("Updated Block Hash", "hash", updatedBlock.Hash())
|
||||||
|
|
||||||
|
// If the block hash has changed, we need to update the hash-to-number mapping
|
||||||
|
if updatedBlock.Hash() != block.Hash() {
|
||||||
|
log.Info("Block hash changed, updating hash-to-number mapping",
|
||||||
|
"old_hash", block.Hash(), "new_hash", updatedBlock.Hash(), "number", updatedBlock.Number())
|
||||||
|
|
||||||
|
// Write the updated hash-to-number mapping and remove the old one
|
||||||
|
batch := bc.db.NewBatch()
|
||||||
|
rawdb.WriteHeaderNumber(batch, updatedBlock.Hash(), updatedBlock.NumberU64())
|
||||||
|
rawdb.DeleteHeaderNumber(batch, block.Hash())
|
||||||
|
|
||||||
|
// Also clean up old receipts and body data if they exist
|
||||||
|
rawdb.DeleteReceipts(batch, block.Hash(), block.NumberU64())
|
||||||
|
rawdb.DeleteBody(batch, block.Hash(), block.NumberU64())
|
||||||
|
rawdb.DeleteHeader(batch, block.Hash(), block.NumberU64())
|
||||||
|
|
||||||
|
if err := batch.Write(); err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to update hash-to-number mapping: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the block with state
|
||||||
|
err = bc.writeBlockWithState(updatedBlock, res.Receipts, statedb)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate witness if requested
|
||||||
|
var witness *stateless.Witness
|
||||||
|
if makeWitness && bc.chainConfig.IsByzantium(block.Number()) {
|
||||||
|
witness, err = stateless.NewWitness(updatedBlock.Header(), bc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newHeader, witness, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCanonical rewinds the chain to set the new head block as the specified
|
// SetCanonical rewinds the chain to set the new head block as the specified
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
|
||||||
blockchain.reportBlock(block, res, err)
|
blockchain.reportBlock(block, res, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = blockchain.validator.ValidateState(block, statedb, res, false)
|
_, err = blockchain.validator.ValidateState(block, statedb, res, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
blockchain.reportBlock(block, res, err)
|
blockchain.reportBlock(block, res, err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -3425,7 +3425,7 @@ func testSetCanonical(t *testing.T, scheme string) {
|
||||||
gen.AddTx(tx)
|
gen.AddTx(tx)
|
||||||
})
|
})
|
||||||
for _, block := range side {
|
for _, block := range side {
|
||||||
_, err := chain.InsertBlockWithoutSetHead(block, false)
|
_, _, err := chain.InsertBlockWithoutSetHead(block, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to insert into chain: %v", err)
|
t.Fatalf("Failed to insert into chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,11 +70,12 @@ func ExecuteStateless(config *params.ChainConfig, vmconfig vm.Config, block *typ
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, common.Hash{}, err
|
return common.Hash{}, common.Hash{}, err
|
||||||
}
|
}
|
||||||
if err = validator.ValidateState(block, db, res, true); err != nil {
|
newHeader, err := validator.ValidateState(block, db, res, true)
|
||||||
|
if err != nil {
|
||||||
return common.Hash{}, common.Hash{}, err
|
return common.Hash{}, common.Hash{}, err
|
||||||
}
|
}
|
||||||
// Almost everything validated, but receipt and state root needs to be returned
|
// Almost everything validated, but receipt and state root needs to be returned
|
||||||
receiptRoot := types.DeriveSha(res.Receipts, trie.NewStackTrie(nil))
|
receiptRoot := types.DeriveSha(res.Receipts, trie.NewStackTrie(nil))
|
||||||
stateRoot := db.IntermediateRoot(config.IsEIP158(block.Number()))
|
stateRoot := newHeader.Root
|
||||||
return stateRoot, receiptRoot, nil
|
return stateRoot, receiptRoot, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ type Validator interface {
|
||||||
ValidateBody(block *types.Block) error
|
ValidateBody(block *types.Block) error
|
||||||
|
|
||||||
// ValidateState validates the given statedb and optionally the process result.
|
// ValidateState validates the given statedb and optionally the process result.
|
||||||
ValidateState(block *types.Block, state *state.StateDB, res *ProcessResult, stateless bool) error
|
// Returns a new header with the actual state root instead of comparing with the original header.
|
||||||
|
ValidateState(block *types.Block, state *state.StateDB, res *ProcessResult, stateless bool) (*types.Header, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefetcher is an interface for pre-caching transaction signatures and state.
|
// Prefetcher is an interface for pre-caching transaction signatures and state.
|
||||||
|
|
|
||||||
|
|
@ -312,7 +312,7 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl
|
||||||
api.forkchoiceLock.Lock()
|
api.forkchoiceLock.Lock()
|
||||||
defer api.forkchoiceLock.Unlock()
|
defer api.forkchoiceLock.Unlock()
|
||||||
|
|
||||||
log.Trace("Engine API request received", "method", "ForkchoiceUpdated", "head", update.HeadBlockHash, "finalized", update.FinalizedBlockHash, "safe", update.SafeBlockHash)
|
log.Info("Engine API request received", "method", "ForkchoiceUpdated", "head", update.HeadBlockHash, "finalized", update.FinalizedBlockHash, "safe", update.SafeBlockHash)
|
||||||
if update.HeadBlockHash == (common.Hash{}) {
|
if update.HeadBlockHash == (common.Hash{}) {
|
||||||
log.Warn("Forkchoice requested update to zero hash")
|
log.Warn("Forkchoice requested update to zero hash")
|
||||||
return engine.STATUS_INVALID, nil // TODO(karalabe): Why does someone send us this?
|
return engine.STATUS_INVALID, nil // TODO(karalabe): Why does someone send us this?
|
||||||
|
|
@ -836,7 +836,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
|
||||||
api.newPayloadLock.Lock()
|
api.newPayloadLock.Lock()
|
||||||
defer api.newPayloadLock.Unlock()
|
defer api.newPayloadLock.Unlock()
|
||||||
|
|
||||||
log.Trace("Engine API request received", "method", "NewPayload", "number", params.Number, "hash", params.BlockHash)
|
log.Info("Engine API request received", "method", "NewPayload", "number", params.Number, "hash", params.BlockHash)
|
||||||
block, err := engine.ExecutableDataToBlock(params, versionedHashes, beaconRoot, requests)
|
block, err := engine.ExecutableDataToBlock(params, versionedHashes, beaconRoot, requests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bgu := "nil"
|
bgu := "nil"
|
||||||
|
|
@ -876,11 +876,11 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
|
||||||
|
|
||||||
// If we already have the block locally, ignore the entire execution and just
|
// If we already have the block locally, ignore the entire execution and just
|
||||||
// return a fake success.
|
// return a fake success.
|
||||||
if block := api.eth.BlockChain().GetBlockByHash(params.BlockHash); block != nil {
|
/*if block := api.eth.BlockChain().GetBlockByHash(params.BlockHash); block != nil {
|
||||||
log.Warn("Ignoring already known beacon payload", "number", params.Number, "hash", params.BlockHash, "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
|
log.Warn("Ignoring already known beacon payload", "number", params.Number, "hash", params.BlockHash, "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
|
||||||
hash := block.Hash()
|
hash := block.Hash()
|
||||||
return engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &hash}, nil
|
return engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &hash}, nil
|
||||||
}
|
}*/
|
||||||
// If this block was rejected previously, keep rejecting it
|
// If this block was rejected previously, keep rejecting it
|
||||||
if res := api.checkInvalidAncestor(block.Hash(), block.Hash()); res != nil {
|
if res := api.checkInvalidAncestor(block.Hash(), block.Hash()); res != nil {
|
||||||
return *res, nil
|
return *res, nil
|
||||||
|
|
@ -911,8 +911,8 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
|
||||||
log.Warn("State not available, ignoring new payload")
|
log.Warn("State not available, ignoring new payload")
|
||||||
return engine.PayloadStatusV1{Status: engine.ACCEPTED}, nil
|
return engine.PayloadStatusV1{Status: engine.ACCEPTED}, nil
|
||||||
}
|
}
|
||||||
log.Trace("Inserting block without sethead", "hash", block.Hash(), "number", block.Number())
|
log.Info("Inserting block without sethead", "hash", block.Hash(), "number", block.Number())
|
||||||
proofs, err := api.eth.BlockChain().InsertBlockWithoutSetHead(block, witness)
|
newHeader, proofs, err := api.eth.BlockChain().InsertBlockWithoutSetHead(block, witness)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("NewPayload: inserting block failed", "error", err)
|
log.Warn("NewPayload: inserting block failed", "error", err)
|
||||||
|
|
||||||
|
|
@ -923,7 +923,8 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
|
||||||
|
|
||||||
return api.invalid(err, parent.Header()), nil
|
return api.invalid(err, parent.Header()), nil
|
||||||
}
|
}
|
||||||
hash := block.Hash()
|
hash := newHeader.Hash()
|
||||||
|
log.Info("NewHeader", "hash", hash, "root", newHeader.Root)
|
||||||
|
|
||||||
// If witness collection was requested, inject that into the result too
|
// If witness collection was requested, inject that into the result too
|
||||||
var ow *hexutil.Bytes
|
var ow *hexutil.Bytes
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
ethparams "github.com/ethereum/go-ethereum/params"
|
ethparams "github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -101,6 +102,8 @@ func (miner *Miner) generateWork(params *generateParams, witness bool) *newPaylo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &newPayloadResult{err: err}
|
return &newPayloadResult{err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use gas limit for block creation instead of executing transactions
|
||||||
if !params.noTxs {
|
if !params.noTxs {
|
||||||
interrupt := new(atomic.Int32)
|
interrupt := new(atomic.Int32)
|
||||||
timer := time.AfterFunc(miner.config.Recommit, func() {
|
timer := time.AfterFunc(miner.config.Recommit, func() {
|
||||||
|
|
@ -164,10 +167,9 @@ func (miner *Miner) generateWork(params *generateParams, witness bool) *newPaylo
|
||||||
work.header.RequestsHash = &reqHash
|
work.header.RequestsHash = &reqHash
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := miner.engine.FinalizeAndAssemble(miner.chain, work.header, work.state, &body, work.receipts)
|
// Directly construct the block without calling FinalizeAndAssemble
|
||||||
if err != nil {
|
// This returns a block with the current header, body, and receipts
|
||||||
return &newPayloadResult{err: err}
|
block := types.NewBlock(work.header, &body, work.receipts, trie.NewStackTrie(nil))
|
||||||
}
|
|
||||||
return &newPayloadResult{
|
return &newPayloadResult{
|
||||||
block: block,
|
block: block,
|
||||||
fees: totalFees(block, work.receipts),
|
fees: totalFees(block, work.receipts),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue