This commit is contained in:
0g-wh 2025-07-20 07:13:43 +00:00
parent cf3a1c3cd1
commit 861b26698e
6 changed files with 104 additions and 19 deletions

View file

@ -2537,12 +2537,39 @@ func (bc *BlockChain) InsertBlockWithoutSetHead(block *types.Block, makeWitness
} }
newHeader, err := bc.validator.ValidateState(block, statedb, res, false) newHeader, err := bc.validator.ValidateState(block, statedb, res, false)
log.Info("New Header", "stateroot", newHeader.Root)
if err != nil { if err != nil {
return nil, nil, err 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 // Write the block with state
err = bc.writeBlockWithState(block, res.Receipts, statedb) err = bc.writeBlockWithState(updatedBlock, res.Receipts, statedb)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -2550,7 +2577,7 @@ func (bc *BlockChain) InsertBlockWithoutSetHead(block *types.Block, makeWitness
// Generate witness if requested // Generate witness if requested
var witness *stateless.Witness var witness *stateless.Witness
if makeWitness && bc.chainConfig.IsByzantium(block.Number()) { if makeWitness && bc.chainConfig.IsByzantium(block.Number()) {
witness, err = stateless.NewWitness(block.Header(), bc) witness, err = stateless.NewWitness(updatedBlock.Header(), bc)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View file

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb"
@ -181,6 +182,7 @@ func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
// GetBlockByHash retrieves a block from the database by hash, caching it if found. // GetBlockByHash retrieves a block from the database by hash, caching it if found.
func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
number := bc.hc.GetBlockNumber(hash) number := bc.hc.GetBlockNumber(hash)
log.Info("GetBlockByHash", "hash", hash, "number", number)
if number == nil { if number == nil {
return nil return nil
} }

View file

@ -99,9 +99,12 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
// from the cache or database // from the cache or database
func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 { func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 {
if cached, ok := hc.numberCache.Get(hash); ok { if cached, ok := hc.numberCache.Get(hash); ok {
log.Info("GetBlockNumber", "hash", hash, "cached", cached)
return &cached return &cached
} }
log.Info("GetBlockNumber", "hash", hash, "cached", "not cached")
number := rawdb.ReadHeaderNumber(hc.chainDb, hash) number := rawdb.ReadHeaderNumber(hc.chainDb, hash)
log.Info("ReadHeaderNumber", "hash", hash, "number", number)
if number != nil { if number != nil {
hc.numberCache.Add(hash, *number) hc.numberCache.Add(hash, *number)
} }

View file

@ -154,6 +154,7 @@ func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 {
// WriteHeaderNumber stores the hash->number mapping. // WriteHeaderNumber stores the hash->number mapping.
func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
log.Info("WriteHeaderNumber", "hash", hash, "number", number)
key := headerNumberKey(hash) key := headerNumberKey(hash)
enc := encodeBlockNumber(number) enc := encodeBlockNumber(number)
if err := db.Put(key, enc); err != nil { if err := db.Put(key, enc); err != nil {

View file

@ -260,7 +260,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?
@ -674,7 +674,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"
@ -712,11 +712,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
@ -747,7 +747,7 @@ 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())
newHeader, 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)
@ -760,6 +760,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
return api.invalid(err, parent.Header()), nil return api.invalid(err, parent.Header()), nil
} }
hash := newHeader.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

View file

@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -100,6 +101,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() {
@ -141,10 +144,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),
@ -267,13 +269,36 @@ func (miner *Miner) commitTransaction(env *environment, tx *types.Transaction) e
if tx.Type() == types.BlobTxType { if tx.Type() == types.BlobTxType {
return miner.commitBlobTransaction(env, tx) return miner.commitBlobTransaction(env, tx)
} }
receipt, err := miner.applyTransaction(env, tx)
if err != nil { // Set gas used to transaction's gas limit
return err gasUsed := tx.Gas()
// Create a mock receipt for the transaction without execution
receipt := &types.Receipt{
Type: tx.Type(),
PostState: nil, // No state changes
Status: 1, // Success status
CumulativeGasUsed: env.header.GasUsed + gasUsed,
Logs: []*types.Log{},
TxHash: tx.Hash(),
ContractAddress: common.Address{},
GasUsed: gasUsed,
BlockHash: env.header.Hash(),
BlockNumber: env.header.Number,
TransactionIndex: uint(env.tcount),
} }
// Add transaction to block without execution
env.txs = append(env.txs, tx) env.txs = append(env.txs, tx)
env.receipts = append(env.receipts, receipt) env.receipts = append(env.receipts, receipt)
env.tcount++ env.tcount++
// Accumulate gas used for this transaction
env.header.GasUsed += gasUsed
// Consume transaction's gas limit from pool
env.gasPool.SubGas(gasUsed)
return nil return nil
} }
@ -290,16 +315,41 @@ func (miner *Miner) commitBlobTransaction(env *environment, tx *types.Transactio
if env.blobs+len(sc.Blobs) > maxBlobs { if env.blobs+len(sc.Blobs) > maxBlobs {
return errors.New("max data blobs reached") return errors.New("max data blobs reached")
} }
receipt, err := miner.applyTransaction(env, tx)
if err != nil { // Set gas used to transaction's gas limit
return err gasUsed := tx.Gas()
blobGasUsed := uint64(len(sc.Blobs)) * params.BlobTxBlobGasPerBlob
// Create a mock receipt for the blob transaction without execution
receipt := &types.Receipt{
Type: tx.Type(),
PostState: nil, // No state changes
Status: 1, // Success status
CumulativeGasUsed: env.header.GasUsed + gasUsed,
Logs: []*types.Log{},
TxHash: tx.Hash(),
ContractAddress: common.Address{},
GasUsed: gasUsed,
BlobGasUsed: blobGasUsed,
BlockHash: env.header.Hash(),
BlockNumber: env.header.Number,
TransactionIndex: uint(env.tcount),
} }
// Add transaction to block without execution
env.txs = append(env.txs, tx.WithoutBlobTxSidecar()) env.txs = append(env.txs, tx.WithoutBlobTxSidecar())
env.receipts = append(env.receipts, receipt) env.receipts = append(env.receipts, receipt)
env.sidecars = append(env.sidecars, sc) env.sidecars = append(env.sidecars, sc)
env.blobs += len(sc.Blobs) env.blobs += len(sc.Blobs)
*env.header.BlobGasUsed += receipt.BlobGasUsed *env.header.BlobGasUsed += receipt.BlobGasUsed
env.tcount++ env.tcount++
// Accumulate gas used for this transaction
env.header.GasUsed += gasUsed
// Consume transaction's gas limit from pool
env.gasPool.SubGas(gasUsed)
return nil return nil
} }
@ -444,8 +494,8 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran
} }
// fillTransactions retrieves the pending transactions from the txpool and fills them // fillTransactions retrieves the pending transactions from the txpool and fills them
// into the given sealing block. The transaction selection and ordering strategy can // into the given sealing block based on gas limit without executing them.
// be customized with the plugin in the future. // The transaction selection and ordering strategy can be customized with the plugin in the future.
func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment) error { func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment) error {
miner.confMu.RLock() miner.confMu.RLock()
tip := miner.config.GasPrice tip := miner.config.GasPrice
@ -482,6 +532,7 @@ func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment)
prioBlobTxs[account] = txs prioBlobTxs[account] = txs
} }
} }
// Fill the block with all available pending transactions. // Fill the block with all available pending transactions.
if len(prioPlainTxs) > 0 || len(prioBlobTxs) > 0 { if len(prioPlainTxs) > 0 || len(prioBlobTxs) > 0 {
plainTxs := newTransactionsByPriceAndNonce(env.signer, prioPlainTxs, env.header.BaseFee) plainTxs := newTransactionsByPriceAndNonce(env.signer, prioPlainTxs, env.header.BaseFee)