mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
eth/catalyst: add initial OpenTelemetry tracing for newPayload (#33521)
This PR adds initial OpenTelemetry tracing to the Engine API, focusing on engine_newPayload*. ``` jsonrpc.engine/newPayloadV4 | |- engine.newPayload [block.number, block.hash, tx.count] | |- core.blockchain.InsertBlockWithoutSetHead | |- bc.processor.Process | | |- core.ApplyTransactionWithEVM [tx.hash, tx.index] | | |- core.ApplyTransactionWithEVM [tx.hash, tx.index] | | |- ... (one per transaction) | | |- core.postExecution | |- bc.validator.ValidateState ``` --------- Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
parent
550ca91b17
commit
c709c19b40
15 changed files with 162 additions and 82 deletions
|
|
@ -20,6 +20,8 @@ require (
|
|||
github.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect
|
||||
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab // indirect
|
||||
github.com/ferranbt/fastssz v0.1.4 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
|
|
@ -32,6 +34,10 @@ require (
|
|||
github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/otel v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||
golang.org/x/crypto v0.44.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@ github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeD
|
|||
github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg=
|
||||
github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=
|
||||
github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
|
|
@ -59,6 +64,10 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
|
|||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
|
||||
github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
|
||||
|
|
@ -108,6 +117,16 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA
|
|||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
|
||||
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
|
|
@ -52,7 +53,7 @@ func main() {
|
|||
}
|
||||
vmConfig := vm.Config{}
|
||||
|
||||
crossStateRoot, crossReceiptRoot, err := core.ExecuteStateless(chainConfig, vmConfig, payload.Block, payload.Witness)
|
||||
crossStateRoot, crossReceiptRoot, err := core.ExecuteStateless(context.Background(), chainConfig, vmConfig, payload.Block, payload.Witness)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "stateless self-validation failed: %v\n", err)
|
||||
os.Exit(10)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -210,7 +211,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
|
|||
t.Fatalf("post-block %d: unexpected result returned: %v", i, result)
|
||||
case <-time.After(25 * time.Millisecond):
|
||||
}
|
||||
chain.InsertBlockWithoutSetHead(postBlocks[i], false)
|
||||
chain.InsertBlockWithoutSetHead(context.Background(), postBlocks[i], false)
|
||||
}
|
||||
|
||||
// Verify the blocks with pre-merge blocks and post-merge blocks
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -47,6 +48,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/internal/syncx"
|
||||
"github.com/ethereum/go-ethereum/internal/telemetry"
|
||||
"github.com/ethereum/go-ethereum/internal/version"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
|
|
@ -1818,7 +1820,7 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
|
|||
}
|
||||
defer bc.chainmu.Unlock()
|
||||
|
||||
_, n, err := bc.insertChain(chain, true, false) // No witness collection for mass inserts (would get super large)
|
||||
_, n, err := bc.insertChain(context.Background(), chain, true, false) // No witness collection for mass inserts (would get super large)
|
||||
return n, err
|
||||
}
|
||||
|
||||
|
|
@ -1830,7 +1832,7 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
|
|||
// racey behaviour. If a sidechain import is in progress, and the historic state
|
||||
// is imported, but then new canon-head is added before the actual sidechain
|
||||
// completes, then the historic state could be pruned again
|
||||
func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness bool) (*stateless.Witness, int, error) {
|
||||
func (bc *BlockChain) insertChain(ctx context.Context, chain types.Blocks, setHead bool, makeWitness bool) (*stateless.Witness, int, error) {
|
||||
// If the chain is terminating, don't even bother starting up.
|
||||
if bc.insertStopped() {
|
||||
return nil, 0, nil
|
||||
|
|
@ -1912,11 +1914,11 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
|
|||
if setHead {
|
||||
// First block is pruned, insert as sidechain and reorg only if TD grows enough
|
||||
log.Debug("Pruned ancestor, inserting as sidechain", "number", block.Number(), "hash", block.Hash())
|
||||
return bc.insertSideChain(block, it, makeWitness)
|
||||
return bc.insertSideChain(ctx, block, it, makeWitness)
|
||||
} else {
|
||||
// We're post-merge and the parent is pruned, try to recover the parent state
|
||||
log.Debug("Pruned ancestor", "number", block.Number(), "hash", block.Hash())
|
||||
_, err := bc.recoverAncestors(block, makeWitness)
|
||||
_, err := bc.recoverAncestors(ctx, block, makeWitness)
|
||||
return nil, it.index, err
|
||||
}
|
||||
// Some other error(except ErrKnownBlock) occurred, abort.
|
||||
|
|
@ -1988,7 +1990,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
|
|||
}
|
||||
// The traced section of block import.
|
||||
start := time.Now()
|
||||
res, err := bc.ProcessBlock(parent.Root, block, setHead, makeWitness && len(chain) == 1)
|
||||
res, err := bc.ProcessBlock(ctx, parent.Root, block, setHead, makeWitness && len(chain) == 1)
|
||||
if err != nil {
|
||||
return nil, it.index, err
|
||||
}
|
||||
|
|
@ -2073,7 +2075,7 @@ func (bpr *blockProcessingResult) Stats() *ExecuteStats {
|
|||
|
||||
// ProcessBlock executes and validates the given block. If there was no error
|
||||
// it writes the block and associated state to database.
|
||||
func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, setHead bool, makeWitness bool) (result *blockProcessingResult, blockEndErr error) {
|
||||
func (bc *BlockChain) ProcessBlock(ctx context.Context, parentRoot common.Hash, block *types.Block, setHead bool, makeWitness bool) (result *blockProcessingResult, blockEndErr error) {
|
||||
var (
|
||||
err error
|
||||
startTime = time.Now()
|
||||
|
|
@ -2164,7 +2166,9 @@ func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, s
|
|||
|
||||
// Process block using the parent state as reference point
|
||||
pstart := time.Now()
|
||||
res, err := bc.processor.Process(block, statedb, bc.cfg.VmConfig)
|
||||
pctx, _, spanEnd := telemetry.StartSpan(ctx, "bc.processor.Process")
|
||||
res, err := bc.processor.Process(pctx, block, statedb, bc.cfg.VmConfig)
|
||||
spanEnd(&err)
|
||||
if err != nil {
|
||||
bc.reportBadBlock(block, res, err)
|
||||
return nil, err
|
||||
|
|
@ -2172,7 +2176,10 @@ func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, s
|
|||
ptime := time.Since(pstart)
|
||||
|
||||
vstart := time.Now()
|
||||
if err := bc.validator.ValidateState(block, statedb, res, false); err != nil {
|
||||
_, _, spanEnd = telemetry.StartSpan(ctx, "bc.validator.ValidateState")
|
||||
err = bc.validator.ValidateState(block, statedb, res, false)
|
||||
spanEnd(&err)
|
||||
if err != nil {
|
||||
bc.reportBadBlock(block, res, err)
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -2195,7 +2202,7 @@ func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, s
|
|||
task := types.NewBlockWithHeader(context).WithBody(*block.Body())
|
||||
|
||||
// Run the stateless self-cross-validation
|
||||
crossStateRoot, crossReceiptRoot, err := ExecuteStateless(bc.chainConfig, bc.cfg.VmConfig, task, witness)
|
||||
crossStateRoot, crossReceiptRoot, err := ExecuteStateless(ctx, bc.chainConfig, bc.cfg.VmConfig, task, witness)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("stateless self-validation failed: %v", err)
|
||||
}
|
||||
|
|
@ -2282,7 +2289,7 @@ func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, s
|
|||
// The method writes all (header-and-body-valid) blocks to disk, then tries to
|
||||
// switch over to the new chain if the TD exceeded the current chain.
|
||||
// insertSideChain is only used pre-merge.
|
||||
func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator, makeWitness bool) (*stateless.Witness, int, error) {
|
||||
func (bc *BlockChain) insertSideChain(ctx context.Context, block *types.Block, it *insertIterator, makeWitness bool) (*stateless.Witness, int, error) {
|
||||
var current = bc.CurrentBlock()
|
||||
|
||||
// The first sidechain block error is already verified to be ErrPrunedAncestor.
|
||||
|
|
@ -2363,7 +2370,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator, ma
|
|||
// memory here.
|
||||
if len(blocks) >= 2048 || memory > 64*1024*1024 {
|
||||
log.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64())
|
||||
if _, _, err := bc.insertChain(blocks, true, false); err != nil {
|
||||
if _, _, err := bc.insertChain(ctx, blocks, true, false); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
blocks, memory = blocks[:0], 0
|
||||
|
|
@ -2377,7 +2384,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator, ma
|
|||
}
|
||||
if len(blocks) > 0 {
|
||||
log.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64())
|
||||
return bc.insertChain(blocks, true, makeWitness)
|
||||
return bc.insertChain(ctx, blocks, true, makeWitness)
|
||||
}
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
|
@ -2386,7 +2393,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator, ma
|
|||
// all the ancestor blocks since that.
|
||||
// recoverAncestors is only used post-merge.
|
||||
// We return the hash of the latest block that we could correctly validate.
|
||||
func (bc *BlockChain) recoverAncestors(block *types.Block, makeWitness bool) (common.Hash, error) {
|
||||
func (bc *BlockChain) recoverAncestors(ctx context.Context, block *types.Block, makeWitness bool) (common.Hash, error) {
|
||||
// Gather all the sidechain hashes (full blocks may be memory heavy)
|
||||
var (
|
||||
hashes []common.Hash
|
||||
|
|
@ -2426,7 +2433,7 @@ func (bc *BlockChain) recoverAncestors(block *types.Block, makeWitness bool) (co
|
|||
} else {
|
||||
b = bc.GetBlock(hashes[i], numbers[i])
|
||||
}
|
||||
if _, _, err := bc.insertChain(types.Blocks{b}, false, makeWitness && i == 0); err != nil {
|
||||
if _, _, err := bc.insertChain(ctx, types.Blocks{b}, false, makeWitness && i == 0); err != nil {
|
||||
return b.ParentHash(), err
|
||||
}
|
||||
}
|
||||
|
|
@ -2653,14 +2660,16 @@ 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
|
||||
// updating. It relies on the additional SetCanonical call to finalize the entire
|
||||
// procedure.
|
||||
func (bc *BlockChain) InsertBlockWithoutSetHead(block *types.Block, makeWitness bool) (*stateless.Witness, error) {
|
||||
func (bc *BlockChain) InsertBlockWithoutSetHead(ctx context.Context, block *types.Block, makeWitness bool) (witness *stateless.Witness, err error) {
|
||||
_, _, spanEnd := telemetry.StartSpan(ctx, "core.blockchain.InsertBlockWithoutSetHead")
|
||||
defer spanEnd(&err)
|
||||
if !bc.chainmu.TryLock() {
|
||||
return nil, errChainStopped
|
||||
}
|
||||
defer bc.chainmu.Unlock()
|
||||
|
||||
witness, _, err := bc.insertChain(types.Blocks{block}, false, makeWitness)
|
||||
return witness, err
|
||||
witness, _, err = bc.insertChain(ctx, types.Blocks{block}, false, makeWitness)
|
||||
return
|
||||
}
|
||||
|
||||
// SetCanonical rewinds the chain to set the new head block as the specified
|
||||
|
|
@ -2674,7 +2683,7 @@ func (bc *BlockChain) SetCanonical(head *types.Block) (common.Hash, error) {
|
|||
|
||||
// Re-execute the reorged chain in case the head state is missing.
|
||||
if !bc.HasState(head.Root()) {
|
||||
if latestValidHash, err := bc.recoverAncestors(head, false); err != nil {
|
||||
if latestValidHash, err := bc.recoverAncestors(context.Background(), head, false); err != nil {
|
||||
return latestValidHash, err
|
||||
}
|
||||
log.Info("Recovered head state", "number", head.Number(), "hash", head.Hash())
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package core
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
gomath "math"
|
||||
|
|
@ -160,7 +161,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := blockchain.processor.Process(block, statedb, vm.Config{})
|
||||
res, err := blockchain.processor.Process(context.Background(), block, statedb, vm.Config{})
|
||||
if err != nil {
|
||||
blockchain.reportBadBlock(block, res, err)
|
||||
return err
|
||||
|
|
@ -3456,7 +3457,7 @@ func testSetCanonical(t *testing.T, scheme string) {
|
|||
gen.AddTx(tx)
|
||||
})
|
||||
for _, block := range side {
|
||||
_, err := chain.InsertBlockWithoutSetHead(block, false)
|
||||
_, err := chain.InsertBlockWithoutSetHead(context.Background(), block, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to insert into chain: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
|
|
@ -27,6 +28,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/internal/telemetry"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
|
|
@ -57,7 +59,7 @@ func (p *StateProcessor) chainConfig() *params.ChainConfig {
|
|||
// Process returns the receipts and logs accumulated during the process and
|
||||
// returns the amount of gas that was used in the process. If any of the
|
||||
// transactions failed to execute due to insufficient gas it will return an error.
|
||||
func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResult, error) {
|
||||
func (p *StateProcessor) Process(ctx context.Context, block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResult, error) {
|
||||
var (
|
||||
config = p.chainConfig()
|
||||
receipts types.Receipts
|
||||
|
|
@ -101,30 +103,21 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
return nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
||||
}
|
||||
statedb.SetTxContext(tx.Hash(), i)
|
||||
|
||||
_, _, spanEnd := telemetry.StartSpan(ctx, "core.ApplyTransactionWithEVM",
|
||||
telemetry.StringAttribute("tx.hash", tx.Hash().Hex()),
|
||||
telemetry.Int64Attribute("tx.index", int64(i)),
|
||||
)
|
||||
receipt, err := ApplyTransactionWithEVM(msg, gp, statedb, blockNumber, blockHash, context.Time, tx, usedGas, evm)
|
||||
spanEnd(&err)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
||||
}
|
||||
receipts = append(receipts, receipt)
|
||||
allLogs = append(allLogs, receipt.Logs...)
|
||||
}
|
||||
// Read requests if Prague is enabled.
|
||||
var requests [][]byte
|
||||
if config.IsPrague(block.Number(), block.Time()) {
|
||||
requests = [][]byte{}
|
||||
// EIP-6110
|
||||
if err := ParseDepositLogs(&requests, allLogs, config); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse deposit logs: %w", err)
|
||||
}
|
||||
// EIP-7002
|
||||
if err := ProcessWithdrawalQueue(&requests, evm); err != nil {
|
||||
return nil, fmt.Errorf("failed to process withdrawal queue: %w", err)
|
||||
}
|
||||
// EIP-7251
|
||||
if err := ProcessConsolidationQueue(&requests, evm); err != nil {
|
||||
return nil, fmt.Errorf("failed to process consolidation queue: %w", err)
|
||||
}
|
||||
requests, err := postExecution(ctx, config, block, allLogs, evm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
|
||||
|
|
@ -138,6 +131,31 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
}, nil
|
||||
}
|
||||
|
||||
// postExecution processes the post-execution system calls if Prague is enabled.
|
||||
func postExecution(ctx context.Context, config *params.ChainConfig, block *types.Block, allLogs []*types.Log, evm *vm.EVM) (requests [][]byte, err error) {
|
||||
_, _, spanEnd := telemetry.StartSpan(ctx, "core.postExecution")
|
||||
defer spanEnd(&err)
|
||||
|
||||
// Read requests if Prague is enabled.
|
||||
if config.IsPrague(block.Number(), block.Time()) {
|
||||
requests = [][]byte{}
|
||||
// EIP-6110
|
||||
if err := ParseDepositLogs(&requests, allLogs, config); err != nil {
|
||||
return requests, fmt.Errorf("failed to parse deposit logs: %w", err)
|
||||
}
|
||||
// EIP-7002
|
||||
if err := ProcessWithdrawalQueue(&requests, evm); err != nil {
|
||||
return requests, fmt.Errorf("failed to process withdrawal queue: %w", err)
|
||||
}
|
||||
// EIP-7251
|
||||
if err := ProcessConsolidationQueue(&requests, evm); err != nil {
|
||||
return requests, fmt.Errorf("failed to process consolidation queue: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return requests, nil
|
||||
}
|
||||
|
||||
// ApplyTransactionWithEVM attempts to apply a transaction to the given state database
|
||||
// and uses the input parameters for its environment similar to ApplyTransaction. However,
|
||||
// this method takes an already created EVM instance as input.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/lru"
|
||||
"github.com/ethereum/go-ethereum/consensus/beacon"
|
||||
|
|
@ -40,7 +42,7 @@ import (
|
|||
// - It cannot be placed outside of core, because it needs to construct a dud headerchain
|
||||
//
|
||||
// TODO(karalabe): Would be nice to resolve both issues above somehow and move it.
|
||||
func ExecuteStateless(config *params.ChainConfig, vmconfig vm.Config, block *types.Block, witness *stateless.Witness) (common.Hash, common.Hash, error) {
|
||||
func ExecuteStateless(ctx context.Context, config *params.ChainConfig, vmconfig vm.Config, block *types.Block, witness *stateless.Witness) (common.Hash, common.Hash, error) {
|
||||
// Sanity check if the supplied block accidentally contains a set root or
|
||||
// receipt hash. If so, be very loud, but still continue.
|
||||
if block.Root() != (common.Hash{}) {
|
||||
|
|
@ -66,7 +68,7 @@ func ExecuteStateless(config *params.ChainConfig, vmconfig vm.Config, block *typ
|
|||
validator := NewBlockValidator(config, nil) // No chain, we only validate the state, not the block
|
||||
|
||||
// Run the stateless blocks processing and self-validate certain fields
|
||||
res, err := processor.Process(block, db, vmconfig)
|
||||
res, err := processor.Process(ctx, block, db, vmconfig)
|
||||
if err != nil {
|
||||
return common.Hash{}, common.Hash{}, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
|
|
@ -48,7 +49,7 @@ type Processor interface {
|
|||
// Process processes the state changes according to the Ethereum rules by running
|
||||
// the transaction messages using the statedb and applying any rewards to both
|
||||
// the processor (coinbase) and any included uncles.
|
||||
Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResult, error)
|
||||
Process(ctx context.Context, block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResult, error)
|
||||
}
|
||||
|
||||
// ProcessResult contains the values computed by Process.
|
||||
|
|
|
|||
|
|
@ -503,7 +503,7 @@ func (api *DebugAPI) ExecutionWitness(bn rpc.BlockNumber) (*stateless.ExtWitness
|
|||
if parent == nil {
|
||||
return &stateless.ExtWitness{}, fmt.Errorf("block number %v found, but parent missing", bn)
|
||||
}
|
||||
result, err := bc.ProcessBlock(parent.Root, block, false, true)
|
||||
result, err := bc.ProcessBlock(context.Background(), parent.Root, block, false, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -520,7 +520,7 @@ func (api *DebugAPI) ExecutionWitnessByHash(hash common.Hash) (*stateless.ExtWit
|
|||
if parent == nil {
|
||||
return &stateless.ExtWitness{}, fmt.Errorf("block number %x found, but parent missing", hash)
|
||||
}
|
||||
result, err := bc.ProcessBlock(parent.Root, block, false, true)
|
||||
result, err := bc.ProcessBlock(context.Background(), parent.Root, block, false, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package catalyst
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
|
@ -35,6 +36,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/internal/telemetry"
|
||||
"github.com/ethereum/go-ethereum/internal/version"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/miner"
|
||||
|
|
@ -625,15 +627,15 @@ func (api *ConsensusAPI) getBlobs(hashes []common.Hash, v2 bool) ([]*engine.Blob
|
|||
var invalidStatus = engine.PayloadStatusV1{Status: engine.INVALID}
|
||||
|
||||
// NewPayloadV1 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
|
||||
func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.PayloadStatusV1, error) {
|
||||
func (api *ConsensusAPI) NewPayloadV1(ctx context.Context, params engine.ExecutableData) (engine.PayloadStatusV1, error) {
|
||||
if params.Withdrawals != nil {
|
||||
return invalidStatus, paramsErr("withdrawals not supported in V1")
|
||||
}
|
||||
return api.newPayload(params, nil, nil, nil, false)
|
||||
return api.newPayload(ctx, params, nil, nil, nil, false)
|
||||
}
|
||||
|
||||
// NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
|
||||
func (api *ConsensusAPI) NewPayloadV2(params engine.ExecutableData) (engine.PayloadStatusV1, error) {
|
||||
func (api *ConsensusAPI) NewPayloadV2(ctx context.Context, params engine.ExecutableData) (engine.PayloadStatusV1, error) {
|
||||
var (
|
||||
cancun = api.config().IsCancun(api.config().LondonBlock, params.Timestamp)
|
||||
shanghai = api.config().IsShanghai(api.config().LondonBlock, params.Timestamp)
|
||||
|
|
@ -650,11 +652,11 @@ func (api *ConsensusAPI) NewPayloadV2(params engine.ExecutableData) (engine.Payl
|
|||
case params.BlobGasUsed != nil:
|
||||
return invalidStatus, paramsErr("non-nil blobGasUsed pre-cancun")
|
||||
}
|
||||
return api.newPayload(params, nil, nil, nil, false)
|
||||
return api.newPayload(ctx, params, nil, nil, nil, false)
|
||||
}
|
||||
|
||||
// NewPayloadV3 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
|
||||
func (api *ConsensusAPI) NewPayloadV3(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) {
|
||||
func (api *ConsensusAPI) NewPayloadV3(ctx context.Context, params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) {
|
||||
switch {
|
||||
case params.Withdrawals == nil:
|
||||
return invalidStatus, paramsErr("nil withdrawals post-shanghai")
|
||||
|
|
@ -669,11 +671,11 @@ func (api *ConsensusAPI) NewPayloadV3(params engine.ExecutableData, versionedHas
|
|||
case !api.checkFork(params.Timestamp, forks.Cancun):
|
||||
return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads")
|
||||
}
|
||||
return api.newPayload(params, versionedHashes, beaconRoot, nil, false)
|
||||
return api.newPayload(ctx, params, versionedHashes, beaconRoot, nil, false)
|
||||
}
|
||||
|
||||
// NewPayloadV4 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
|
||||
func (api *ConsensusAPI) NewPayloadV4(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, executionRequests []hexutil.Bytes) (engine.PayloadStatusV1, error) {
|
||||
func (api *ConsensusAPI) NewPayloadV4(ctx context.Context, params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, executionRequests []hexutil.Bytes) (engine.PayloadStatusV1, error) {
|
||||
switch {
|
||||
case params.Withdrawals == nil:
|
||||
return invalidStatus, paramsErr("nil withdrawals post-shanghai")
|
||||
|
|
@ -694,10 +696,10 @@ func (api *ConsensusAPI) NewPayloadV4(params engine.ExecutableData, versionedHas
|
|||
if err := validateRequests(requests); err != nil {
|
||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err)
|
||||
}
|
||||
return api.newPayload(params, versionedHashes, beaconRoot, requests, false)
|
||||
return api.newPayload(ctx, params, versionedHashes, beaconRoot, requests, false)
|
||||
}
|
||||
|
||||
func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte, witness bool) (engine.PayloadStatusV1, error) {
|
||||
func (api *ConsensusAPI) newPayload(ctx context.Context, params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte, witness bool) (result engine.PayloadStatusV1, err error) {
|
||||
// The locking here is, strictly, not required. Without these locks, this can happen:
|
||||
//
|
||||
// 1. NewPayload( execdata-N ) is invoked from the CL. It goes all the way down to
|
||||
|
|
@ -711,6 +713,13 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
|
|||
// sequentially.
|
||||
// Hence, we use a lock here, to be sure that the previous call has finished before we
|
||||
// check whether we already have the block locally.
|
||||
var attrs = []telemetry.Attribute{
|
||||
telemetry.Int64Attribute("block.number", int64(params.Number)),
|
||||
telemetry.StringAttribute("block.hash", params.BlockHash.Hex()),
|
||||
telemetry.Int64Attribute("tx.count", int64(len(params.Transactions))),
|
||||
}
|
||||
ctx, _, spanEnd := telemetry.StartSpan(ctx, "engine.newPayload", attrs...)
|
||||
defer spanEnd(&err)
|
||||
api.newPayloadLock.Lock()
|
||||
defer api.newPayloadLock.Unlock()
|
||||
|
||||
|
|
@ -789,7 +798,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
|
|||
}
|
||||
log.Trace("Inserting block without sethead", "hash", block.Hash(), "number", block.Number())
|
||||
start := time.Now()
|
||||
proofs, err := api.eth.BlockChain().InsertBlockWithoutSetHead(block, witness)
|
||||
proofs, err := api.eth.BlockChain().InsertBlockWithoutSetHead(ctx, block, witness)
|
||||
processingTime := time.Since(start)
|
||||
if err != nil {
|
||||
log.Warn("NewPayload: inserting block failed", "error", err)
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ func TestEth2NewBlock(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("Failed to convert executable data to block %v", err)
|
||||
}
|
||||
newResp, err := api.NewPayloadV1(*execData)
|
||||
newResp, err := api.NewPayloadV1(context.Background(), *execData)
|
||||
switch {
|
||||
case err != nil:
|
||||
t.Fatalf("Failed to insert block: %v", err)
|
||||
|
|
@ -356,7 +356,7 @@ func TestEth2NewBlock(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("Failed to convert executable data to block %v", err)
|
||||
}
|
||||
newResp, err := api.NewPayloadV1(*execData)
|
||||
newResp, err := api.NewPayloadV1(context.Background(), *execData)
|
||||
if err != nil || newResp.Status != "VALID" {
|
||||
t.Fatalf("Failed to insert block: %v", err)
|
||||
}
|
||||
|
|
@ -502,7 +502,7 @@ func setupBlocks(t *testing.T, ethservice *eth.Ethereum, n int, parent *types.He
|
|||
}
|
||||
|
||||
envelope := getNewEnvelope(t, api, parent, w, h)
|
||||
execResp, err := api.newPayload(*envelope.ExecutionPayload, []common.Hash{}, h, envelope.Requests, false)
|
||||
execResp, err := api.newPayload(context.Background(), *envelope.ExecutionPayload, []common.Hash{}, h, envelope.Requests, false)
|
||||
if err != nil {
|
||||
t.Fatalf("can't execute payload: %v", err)
|
||||
}
|
||||
|
|
@ -648,7 +648,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
|
|||
t.Fatalf("payload should not be empty")
|
||||
}
|
||||
}
|
||||
execResp, err := api.NewPayloadV1(*payload.ExecutionPayload)
|
||||
execResp, err := api.NewPayloadV1(context.Background(), *payload.ExecutionPayload)
|
||||
if err != nil {
|
||||
t.Fatalf("can't execute payload: %v", err)
|
||||
}
|
||||
|
|
@ -708,7 +708,7 @@ func TestEmptyBlocks(t *testing.T) {
|
|||
// (1) check LatestValidHash by sending a normal payload (P1'')
|
||||
payload := getNewPayload(t, api, commonAncestor, nil, nil)
|
||||
|
||||
status, err := api.NewPayloadV1(*payload)
|
||||
status, err := api.NewPayloadV1(context.Background(), *payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -724,7 +724,7 @@ func TestEmptyBlocks(t *testing.T) {
|
|||
payload.GasUsed += 1
|
||||
payload = setBlockhash(payload)
|
||||
// Now latestValidHash should be the common ancestor
|
||||
status, err = api.NewPayloadV1(*payload)
|
||||
status, err = api.NewPayloadV1(context.Background(), *payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -742,7 +742,7 @@ func TestEmptyBlocks(t *testing.T) {
|
|||
payload.ParentHash = common.Hash{1}
|
||||
payload = setBlockhash(payload)
|
||||
// Now latestValidHash should be the common ancestor
|
||||
status, err = api.NewPayloadV1(*payload)
|
||||
status, err = api.NewPayloadV1(context.Background(), *payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -859,7 +859,7 @@ func TestTrickRemoteBlockCache(t *testing.T) {
|
|||
|
||||
// feed the payloads to node B
|
||||
for _, payload := range invalidChain {
|
||||
status, err := apiB.NewPayloadV1(*payload)
|
||||
status, err := apiB.NewPayloadV1(context.Background(), *payload)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -892,7 +892,7 @@ func TestInvalidBloom(t *testing.T) {
|
|||
// (1) check LatestValidHash by sending a normal payload (P1'')
|
||||
payload := getNewPayload(t, api, commonAncestor, nil, nil)
|
||||
payload.LogsBloom = append(payload.LogsBloom, byte(1))
|
||||
status, err := api.NewPayloadV1(*payload)
|
||||
status, err := api.NewPayloadV1(context.Background(), *payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -931,7 +931,7 @@ func TestSimultaneousNewBlock(t *testing.T) {
|
|||
for ii := 0; ii < 10; ii++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if newResp, err := api.NewPayloadV1(*execData); err != nil {
|
||||
if newResp, err := api.NewPayloadV1(context.Background(), *execData); err != nil {
|
||||
errMu.Lock()
|
||||
testErr = fmt.Errorf("failed to insert block: %w", err)
|
||||
errMu.Unlock()
|
||||
|
|
@ -1038,7 +1038,7 @@ func TestWithdrawals(t *testing.T) {
|
|||
}
|
||||
|
||||
// 10: verify locally built block
|
||||
if status, err := api.NewPayloadV2(*execData.ExecutionPayload); err != nil {
|
||||
if status, err := api.NewPayloadV2(context.Background(), *execData.ExecutionPayload); err != nil {
|
||||
t.Fatalf("error validating payload: %v", err)
|
||||
} else if status.Status != engine.VALID {
|
||||
t.Fatalf("invalid payload")
|
||||
|
|
@ -1082,7 +1082,7 @@ func TestWithdrawals(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("error getting payload, err=%v", err)
|
||||
}
|
||||
if status, err := api.NewPayloadV2(*execData.ExecutionPayload); err != nil {
|
||||
if status, err := api.NewPayloadV2(context.Background(), *execData.ExecutionPayload); err != nil {
|
||||
t.Fatalf("error validating payload: %v", err)
|
||||
} else if status.Status != engine.VALID {
|
||||
t.Fatalf("invalid payload")
|
||||
|
|
@ -1225,9 +1225,9 @@ func TestNilWithdrawals(t *testing.T) {
|
|||
}
|
||||
var status engine.PayloadStatusV1
|
||||
if !shanghai {
|
||||
status, err = api.NewPayloadV1(*execData.ExecutionPayload)
|
||||
status, err = api.NewPayloadV1(context.Background(), *execData.ExecutionPayload)
|
||||
} else {
|
||||
status, err = api.NewPayloadV2(*execData.ExecutionPayload)
|
||||
status, err = api.NewPayloadV2(context.Background(), *execData.ExecutionPayload)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("error validating payload: %v", err.(*engine.EngineAPIError).ErrorData())
|
||||
|
|
@ -1598,7 +1598,7 @@ func TestParentBeaconBlockRoot(t *testing.T) {
|
|||
}
|
||||
|
||||
// 11: verify locally built block
|
||||
if status, err := api.NewPayloadV3(*execData.ExecutionPayload, []common.Hash{}, &common.Hash{42}); err != nil {
|
||||
if status, err := api.NewPayloadV3(context.Background(), *execData.ExecutionPayload, []common.Hash{}, &common.Hash{42}); err != nil {
|
||||
t.Fatalf("error validating payload: %v", err)
|
||||
} else if status.Status != engine.VALID {
|
||||
t.Fatalf("invalid payload")
|
||||
|
|
@ -1705,7 +1705,7 @@ func TestWitnessCreationAndConsumption(t *testing.T) {
|
|||
envelope.ExecutionPayload.StateRoot = wantStateRoot
|
||||
envelope.ExecutionPayload.ReceiptsRoot = wantReceiptRoot
|
||||
|
||||
res2, err := api.NewPayloadWithWitnessV3(*envelope.ExecutionPayload, []common.Hash{}, &common.Hash{42})
|
||||
res2, err := api.NewPayloadWithWitnessV3(context.Background(), *envelope.ExecutionPayload, []common.Hash{}, &common.Hash{42})
|
||||
if err != nil {
|
||||
t.Fatalf("error executing stateless payload witness: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package catalyst
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
|
|
@ -32,11 +33,13 @@ import (
|
|||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/internal/telemetry"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/params/forks"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"go.opentelemetry.io/otel"
|
||||
)
|
||||
|
||||
const devEpochLength = 32
|
||||
|
|
@ -191,6 +194,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
|
|||
}
|
||||
|
||||
version := payloadVersion(c.eth.BlockChain().Config(), timestamp)
|
||||
tracer := otel.Tracer("")
|
||||
|
||||
var random [32]byte
|
||||
rand.Read(random[:])
|
||||
|
|
@ -255,8 +259,16 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
|
|||
requests = envelope.Requests
|
||||
}
|
||||
|
||||
// Create a server span for newPayload, simulating the consensus client
|
||||
// sending the execution payload for validation.
|
||||
npCtx, npSpanEnd := telemetry.StartServerSpan(context.Background(), tracer, telemetry.RPCInfo{
|
||||
System: "jsonrpc",
|
||||
Service: "engine",
|
||||
Method: "newPayloadV" + fmt.Sprintf("%d", version),
|
||||
})
|
||||
// Mark the payload as canon
|
||||
_, err = c.engineAPI.newPayload(*payload, blobHashes, beaconRoot, requests, false)
|
||||
_, err = c.engineAPI.newPayload(npCtx, *payload, blobHashes, beaconRoot, requests, false)
|
||||
npSpanEnd(&err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package catalyst
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
|
@ -86,16 +87,16 @@ func (api *ConsensusAPI) ForkchoiceUpdatedWithWitnessV3(update engine.Forkchoice
|
|||
|
||||
// NewPayloadWithWitnessV1 is analogous to NewPayloadV1, only it also generates
|
||||
// and returns a stateless witness after running the payload.
|
||||
func (api *ConsensusAPI) NewPayloadWithWitnessV1(params engine.ExecutableData) (engine.PayloadStatusV1, error) {
|
||||
func (api *ConsensusAPI) NewPayloadWithWitnessV1(ctx context.Context, params engine.ExecutableData) (engine.PayloadStatusV1, error) {
|
||||
if params.Withdrawals != nil {
|
||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("withdrawals not supported in V1"))
|
||||
}
|
||||
return api.newPayload(params, nil, nil, nil, true)
|
||||
return api.newPayload(ctx, params, nil, nil, nil, true)
|
||||
}
|
||||
|
||||
// NewPayloadWithWitnessV2 is analogous to NewPayloadV2, only it also generates
|
||||
// and returns a stateless witness after running the payload.
|
||||
func (api *ConsensusAPI) NewPayloadWithWitnessV2(params engine.ExecutableData) (engine.PayloadStatusV1, error) {
|
||||
func (api *ConsensusAPI) NewPayloadWithWitnessV2(ctx context.Context, params engine.ExecutableData) (engine.PayloadStatusV1, error) {
|
||||
var (
|
||||
cancun = api.config().IsCancun(api.config().LondonBlock, params.Timestamp)
|
||||
shanghai = api.config().IsShanghai(api.config().LondonBlock, params.Timestamp)
|
||||
|
|
@ -112,12 +113,12 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV2(params engine.ExecutableData) (
|
|||
case params.BlobGasUsed != nil:
|
||||
return invalidStatus, paramsErr("non-nil blobGasUsed pre-cancun")
|
||||
}
|
||||
return api.newPayload(params, nil, nil, nil, true)
|
||||
return api.newPayload(ctx, params, nil, nil, nil, true)
|
||||
}
|
||||
|
||||
// NewPayloadWithWitnessV3 is analogous to NewPayloadV3, only it also generates
|
||||
// and returns a stateless witness after running the payload.
|
||||
func (api *ConsensusAPI) NewPayloadWithWitnessV3(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) {
|
||||
func (api *ConsensusAPI) NewPayloadWithWitnessV3(ctx context.Context, params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) {
|
||||
switch {
|
||||
case params.Withdrawals == nil:
|
||||
return invalidStatus, paramsErr("nil withdrawals post-shanghai")
|
||||
|
|
@ -132,12 +133,12 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV3(params engine.ExecutableData, v
|
|||
case !api.checkFork(params.Timestamp, forks.Cancun):
|
||||
return invalidStatus, unsupportedForkErr("newPayloadV3 must only be called for cancun payloads")
|
||||
}
|
||||
return api.newPayload(params, versionedHashes, beaconRoot, nil, true)
|
||||
return api.newPayload(ctx, params, versionedHashes, beaconRoot, nil, true)
|
||||
}
|
||||
|
||||
// NewPayloadWithWitnessV4 is analogous to NewPayloadV4, only it also generates
|
||||
// and returns a stateless witness after running the payload.
|
||||
func (api *ConsensusAPI) NewPayloadWithWitnessV4(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, executionRequests []hexutil.Bytes) (engine.PayloadStatusV1, error) {
|
||||
func (api *ConsensusAPI) NewPayloadWithWitnessV4(ctx context.Context, params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, executionRequests []hexutil.Bytes) (engine.PayloadStatusV1, error) {
|
||||
switch {
|
||||
case params.Withdrawals == nil:
|
||||
return invalidStatus, paramsErr("nil withdrawals post-shanghai")
|
||||
|
|
@ -158,7 +159,7 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV4(params engine.ExecutableData, v
|
|||
if err := validateRequests(requests); err != nil {
|
||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err)
|
||||
}
|
||||
return api.newPayload(params, versionedHashes, beaconRoot, requests, true)
|
||||
return api.newPayload(ctx, params, versionedHashes, beaconRoot, requests, true)
|
||||
}
|
||||
|
||||
// ExecuteStatelessPayloadV1 is analogous to NewPayloadV1, only it operates in
|
||||
|
|
@ -283,7 +284,7 @@ func (api *ConsensusAPI) executeStatelessPayload(params engine.ExecutableData, v
|
|||
api.lastNewPayloadUpdate.Store(time.Now().Unix())
|
||||
|
||||
log.Trace("Executing block statelessly", "number", block.Number(), "hash", params.BlockHash)
|
||||
stateRoot, receiptRoot, err := core.ExecuteStateless(api.config(), vm.Config{}, block, witness)
|
||||
stateRoot, receiptRoot, err := core.ExecuteStateless(context.Background(), api.config(), vm.Config{}, block, witness)
|
||||
if err != nil {
|
||||
log.Warn("ExecuteStatelessPayload: execution failed", "err", err)
|
||||
errorMsg := err.Error()
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
|
|||
if current = eth.blockchain.GetBlockByNumber(next); current == nil {
|
||||
return nil, nil, fmt.Errorf("block #%d not found", next)
|
||||
}
|
||||
_, err := eth.blockchain.Processor().Process(current, statedb, vm.Config{})
|
||||
_, err := eth.blockchain.Processor().Process(ctx, current, statedb, vm.Config{})
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("processing block %d failed: %v", current.NumberU64(), err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue