Merge branch 'master' into gethclient_tracing_api

This commit is contained in:
Brandon Liu 2023-11-14 15:27:57 +08:00 committed by GitHub
commit 8f837abf6b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
91 changed files with 2021 additions and 710 deletions

View file

@ -96,6 +96,7 @@ jobs:
- stage: build - stage: build
if: type = push if: type = push
os: osx os: osx
osx_image: xcode14.2
go: 1.21.x go: 1.21.x
env: env:
- azure-osx - azure-osx
@ -104,6 +105,8 @@ jobs:
script: script:
- go run build/ci.go install -dlgo - go run build/ci.go install -dlgo
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
- go run build/ci.go install -dlgo -arch arm64
- go run build/ci.go archive -arch arm64 -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
# These builders run the tests # These builders run the tests
- stage: build - stage: build

View file

@ -5,22 +5,22 @@
# https://github.com/ethereum/execution-spec-tests/releases/download/v1.0.6/ # https://github.com/ethereum/execution-spec-tests/releases/download/v1.0.6/
485af7b66cf41eb3a8c1bd46632913b8eb95995df867cf665617bbc9b4beedd1 fixtures_develop.tar.gz 485af7b66cf41eb3a8c1bd46632913b8eb95995df867cf665617bbc9b4beedd1 fixtures_develop.tar.gz
# version:golang 1.21.3 # version:golang 1.21.4
# https://go.dev/dl/ # https://go.dev/dl/
186f2b6f8c8b704e696821b09ab2041a5c1ee13dcbc3156a13adcf75931ee488 go1.21.3.src.tar.gz 47b26a83d2b65a3c1c1bcace273b69bee49a7a7b5168a7604ded3d26a37bd787 go1.21.4.src.tar.gz
27014fc69e301d7588a169ca239b3cc609f0aa1abf38528bf0d20d3b259211eb go1.21.3.darwin-amd64.tar.gz cd3bdcc802b759b70e8418bc7afbc4a65ca73a3fe576060af9fc8a2a5e71c3b8 go1.21.4.darwin-amd64.tar.gz
65302a7a9f7a4834932b3a7a14cb8be51beddda757b567a2f9e0cbd0d7b5a6ab go1.21.3.darwin-arm64.tar.gz 8b7caf2ac60bdff457dba7d4ff2a01def889592b834453431ae3caecf884f6a5 go1.21.4.darwin-arm64.tar.gz
8e0cd2f66cf1bde9d07b4aee01e3d7c3cfdd14e20650488e1683da4b8492594a go1.21.3.freebsd-386.tar.gz f1e685d086eb36f4be5b8b953b52baf7752bc6235400d84bb7d87e500b65f03e go1.21.4.freebsd-386.tar.gz
6e74f65f586e93d1f3947894766f69e9b2ebda488592a09df61f36f06bfe58a8 go1.21.3.freebsd-amd64.tar.gz 59f9b32187efb98d344a3818a631d3815ebb5c7bbefc367bab6515caaca544e9 go1.21.4.freebsd-amd64.tar.gz
fb209fd070db500a84291c5a95251cceeb1723e8f6142de9baca5af70a927c0e go1.21.3.linux-386.tar.gz 64d3e5d295806e137c9e39d1e1f10b00a30fcd5c2f230d72b3298f579bb3c89a go1.21.4.linux-386.tar.gz
1241381b2843fae5a9707eec1f8fb2ef94d827990582c7c7c32f5bdfbfd420c8 go1.21.3.linux-amd64.tar.gz 73cac0215254d0c7d1241fa40837851f3b9a8a742d0b54714cbdfb3feaf8f0af go1.21.4.linux-amd64.tar.gz
fc90fa48ae97ba6368eecb914343590bbb61b388089510d0c56c2dde52987ef3 go1.21.3.linux-arm64.tar.gz ce1983a7289856c3a918e1fd26d41e072cc39f928adfb11ba1896440849b95da go1.21.4.linux-arm64.tar.gz
a1ddcaaf0821a12a800884c14cb4268ce1c1f5a0301e9060646f1e15e611c6c7 go1.21.3.linux-armv6l.tar.gz 6c62e89113750cc77c498194d13a03fadfda22bd2c7d44e8a826fd354db60252 go1.21.4.linux-armv6l.tar.gz
3b0e10a3704f164a6e85e0377728ec5fd21524fabe4c925610e34076586d5826 go1.21.3.linux-ppc64le.tar.gz 2c63b36d2adcfb22013102a2ee730f058ec2f93b9f27479793c80b2e3641783f go1.21.4.linux-ppc64le.tar.gz
4c78e2e6f4c684a3d5a9bdc97202729053f44eb7be188206f0627ef3e18716b6 go1.21.3.linux-s390x.tar.gz 7a75ba4afc7a96058ca65903d994cd862381825d7dca12b2183f087c757c26c0 go1.21.4.linux-s390x.tar.gz
e36737f4f2fadb4d2f919ec4ce517133a56e06064cca6e82fc883bb000c4d56c go1.21.3.windows-386.zip 870a0e462b94671dc2d6cac707e9e19f7524fdc3c90711e6cd4450c3713a8ce0 go1.21.4.windows-386.zip
27c8daf157493f288d42a6f38debc6a2cb391f6543139eba9152fceca0be2a10 go1.21.3.windows-amd64.zip 79e5428e068c912d9cfa6cd115c13549856ec689c1332eac17f5d6122e19d595 go1.21.4.windows-amd64.zip
bfb7a5c56f9ded07d8ae0e0b3702ac07b65e68fa8f33da24ed6df4ce01fe2c5c go1.21.3.windows-arm64.zip 58bc7c6f4d4c72da2df4d2650c8222fe03c9978070eb3c66be8bbaa2a4757ac1 go1.21.4.windows-arm64.zip
# version:golangci 1.51.1 # version:golangci 1.51.1
# https://github.com/golangci/golangci-lint/releases/ # https://github.com/golangci/golangci-lint/releases/

View file

@ -307,6 +307,9 @@ func doTest(cmdline []string) {
// Enable CKZG backend in CI. // Enable CKZG backend in CI.
gotest.Args = append(gotest.Args, "-tags=ckzg") gotest.Args = append(gotest.Args, "-tags=ckzg")
// Enable integration-tests
gotest.Args = append(gotest.Args, "-tags=integrationtests")
// Test a single package at a time. CI builders are slow // Test a single package at a time. CI builders are slow
// and some tests run into timeouts under load. // and some tests run into timeouts under load.
gotest.Args = append(gotest.Args, "-p", "1") gotest.Args = append(gotest.Args, "-p", "1")

View file

@ -65,10 +65,8 @@ var (
"vendor/", "tests/testdata/", "build/", "vendor/", "tests/testdata/", "build/",
// don't relicense vendored sources // don't relicense vendored sources
"cmd/internal/browser",
"common/bitutil/bitutil", "common/bitutil/bitutil",
"common/prque/", "common/prque/",
"consensus/ethash/xor.go",
"crypto/blake2b/", "crypto/blake2b/",
"crypto/bn256/", "crypto/bn256/",
"crypto/bls12381/", "crypto/bls12381/",
@ -78,6 +76,7 @@ var (
"log/", "log/",
"metrics/", "metrics/",
"signer/rules/deps", "signer/rules/deps",
"internal/reexec",
// skip special licenses // skip special licenses
"crypto/secp256k1", // Relicensed to BSD-3 via https://github.com/ethereum/go-ethereum/pull/17225 "crypto/secp256k1", // Relicensed to BSD-3 via https://github.com/ethereum/go-ethereum/pull/17225

View file

@ -21,8 +21,8 @@ import (
"os" "os"
"testing" "testing"
"github.com/docker/docker/pkg/reexec"
"github.com/ethereum/go-ethereum/internal/cmdtest" "github.com/ethereum/go-ethereum/internal/cmdtest"
"github.com/ethereum/go-ethereum/internal/reexec"
) )
const registeredName = "clef-test" const registeredName = "clef-test"

View file

@ -21,8 +21,8 @@ import (
"os" "os"
"testing" "testing"
"github.com/docker/docker/pkg/reexec"
"github.com/ethereum/go-ethereum/internal/cmdtest" "github.com/ethereum/go-ethereum/internal/cmdtest"
"github.com/ethereum/go-ethereum/internal/reexec"
) )
type testEthkey struct { type testEthkey struct {

View file

@ -21,6 +21,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"regexp"
"sort" "sort"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
@ -30,11 +31,18 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
var RunFlag = &cli.StringFlag{
Name: "run",
Value: ".*",
Usage: "Run only those tests matching the regular expression.",
}
var blockTestCommand = &cli.Command{ var blockTestCommand = &cli.Command{
Action: blockTestCmd, Action: blockTestCmd,
Name: "blocktest", Name: "blocktest",
Usage: "executes the given blockchain tests", Usage: "executes the given blockchain tests",
ArgsUsage: "<file>", ArgsUsage: "<file>",
Flags: []cli.Flag{RunFlag},
} }
func blockTestCmd(ctx *cli.Context) error { func blockTestCmd(ctx *cli.Context) error {
@ -61,13 +69,21 @@ func blockTestCmd(ctx *cli.Context) error {
if err = json.Unmarshal(src, &tests); err != nil { if err = json.Unmarshal(src, &tests); err != nil {
return err return err
} }
// run them in order re, err := regexp.Compile(ctx.String(RunFlag.Name))
if err != nil {
return fmt.Errorf("invalid regex -%s: %v", RunFlag.Name, err)
}
// Run them in order
var keys []string var keys []string
for key := range tests { for key := range tests {
keys = append(keys, key) keys = append(keys, key)
} }
sort.Strings(keys) sort.Strings(keys)
for _, name := range keys { for _, name := range keys {
if !re.MatchString(name) {
continue
}
test := tests[name] test := tests[name]
if err := test.Run(false, rawdb.HashScheme, tracer); err != nil { if err := test.Run(false, rawdb.HashScheme, tracer); err != nil {
return fmt.Errorf("test %v: %w", name, err) return fmt.Errorf("test %v: %w", name, err)

View file

@ -116,8 +116,8 @@ type rejectedTx struct {
// Apply applies a set of transactions to a pre-state // Apply applies a set of transactions to a pre-state
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
txs types.Transactions, miningReward int64, txIt txIterator, miningReward int64,
getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error)) (*state.StateDB, *ExecutionResult, error) { getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error)) (*state.StateDB, *ExecutionResult, []byte, error) {
// Capture errors for BLOCKHASH operation, if we haven't been supplied the // Capture errors for BLOCKHASH operation, if we haven't been supplied the
// required blockhashes // required blockhashes
var hashError error var hashError error
@ -190,25 +190,39 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb) core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb)
} }
var blobGasUsed uint64 var blobGasUsed uint64
for i, tx := range txs {
for i := 0; txIt.Next(); i++ {
tx, err := txIt.Tx()
if err != nil {
log.Warn("rejected tx", "index", i, "error", err)
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
continue
}
if tx.Type() == types.BlobTxType && vmContext.BlobBaseFee == nil { if tx.Type() == types.BlobTxType && vmContext.BlobBaseFee == nil {
errMsg := "blob tx used but field env.ExcessBlobGas missing" errMsg := "blob tx used but field env.ExcessBlobGas missing"
log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", errMsg) log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", errMsg)
rejectedTxs = append(rejectedTxs, &rejectedTx{i, errMsg}) rejectedTxs = append(rejectedTxs, &rejectedTx{i, errMsg})
continue continue
} }
if tx.Type() == types.BlobTxType {
blobGasUsed += uint64(params.BlobTxBlobGasPerBlob * len(tx.BlobHashes()))
}
msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee) msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee)
if err != nil { if err != nil {
log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err) log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err)
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
continue continue
} }
if tx.Type() == types.BlobTxType {
txBlobGas := uint64(params.BlobTxBlobGasPerBlob * len(tx.BlobHashes()))
if used, max := blobGasUsed+txBlobGas, uint64(params.MaxBlobGasPerBlock); used > max {
err := fmt.Errorf("blob gas (%d) would exceed maximum allowance %d", used, max)
log.Warn("rejected tx", "index", i, "err", err)
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
continue
}
blobGasUsed += txBlobGas
}
tracer, err := getTracerFn(txIndex, tx.Hash()) tracer, err := getTracerFn(txIndex, tx.Hash())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, err
} }
vmConfig.Tracer = tracer vmConfig.Tracer = tracer
statedb.SetTxContext(tx.Hash(), txIndex) statedb.SetTxContext(tx.Hash(), txIndex)
@ -231,7 +245,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
} }
includedTxs = append(includedTxs, tx) includedTxs = append(includedTxs, tx)
if hashError != nil { if hashError != nil {
return nil, nil, NewError(ErrorMissingBlockhash, hashError) return nil, nil, nil, NewError(ErrorMissingBlockhash, hashError)
} }
gasUsed += msgResult.UsedGas gasUsed += msgResult.UsedGas
@ -306,7 +320,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
// Commit block // Commit block
root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber)) root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber))
if err != nil { if err != nil {
return nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err)) return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err))
} }
execRs := &ExecutionResult{ execRs := &ExecutionResult{
StateRoot: root, StateRoot: root,
@ -332,9 +346,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
// for accessing latest states. // for accessing latest states.
statedb, err = state.New(root, statedb.Database(), nil) statedb, err = state.New(root, statedb.Database(), nil)
if err != nil { if err != nil {
return nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err)) return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err))
} }
return statedb, execRs, nil body, _ := rlp.EncodeToBytes(includedTxs)
return statedb, execRs, body, nil
} }
func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) *state.StateDB { func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) *state.StateDB {

View file

@ -17,14 +17,12 @@
package t8ntool package t8ntool
import ( import (
"crypto/ecdsa"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"os" "os"
"path" "path"
"strings"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
@ -33,11 +31,9 @@ import (
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"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/crypto"
"github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/eth/tracers/logger"
"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/rlp"
"github.com/ethereum/go-ethereum/tests" "github.com/ethereum/go-ethereum/tests"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
@ -147,7 +143,7 @@ func Transition(ctx *cli.Context) error {
// Check if anything needs to be read from stdin // Check if anything needs to be read from stdin
var ( var (
prestate Prestate prestate Prestate
txs types.Transactions // txs to apply txIt txIterator // txs to apply
allocStr = ctx.String(InputAllocFlag.Name) allocStr = ctx.String(InputAllocFlag.Name)
envStr = ctx.String(InputEnvFlag.Name) envStr = ctx.String(InputEnvFlag.Name)
@ -192,7 +188,7 @@ func Transition(ctx *cli.Context) error {
// Set the chain id // Set the chain id
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name)) chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
if txs, err = loadTransactions(txStr, inputData, prestate.Env, chainConfig); err != nil { if txIt, err = loadTransactions(txStr, inputData, prestate.Env, chainConfig); err != nil {
return err return err
} }
if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil { if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil {
@ -208,136 +204,16 @@ func Transition(ctx *cli.Context) error {
return err return err
} }
// Run the test and aggregate the result // Run the test and aggregate the result
s, result, err := prestate.Apply(vmConfig, chainConfig, txs, ctx.Int64(RewardFlag.Name), getTracer) s, result, body, err := prestate.Apply(vmConfig, chainConfig, txIt, ctx.Int64(RewardFlag.Name), getTracer)
if err != nil { if err != nil {
return err return err
} }
body, _ := rlp.EncodeToBytes(txs)
// Dump the excution result // Dump the excution result
collector := make(Alloc) collector := make(Alloc)
s.DumpToCollector(collector, nil) s.DumpToCollector(collector, nil)
return dispatchOutput(ctx, baseDir, result, collector, body) return dispatchOutput(ctx, baseDir, result, collector, body)
} }
// txWithKey is a helper-struct, to allow us to use the types.Transaction along with
// a `secretKey`-field, for input
type txWithKey struct {
key *ecdsa.PrivateKey
tx *types.Transaction
protected bool
}
func (t *txWithKey) UnmarshalJSON(input []byte) error {
// Read the metadata, if present
type txMetadata struct {
Key *common.Hash `json:"secretKey"`
Protected *bool `json:"protected"`
}
var data txMetadata
if err := json.Unmarshal(input, &data); err != nil {
return err
}
if data.Key != nil {
k := data.Key.Hex()[2:]
if ecdsaKey, err := crypto.HexToECDSA(k); err != nil {
return err
} else {
t.key = ecdsaKey
}
}
if data.Protected != nil {
t.protected = *data.Protected
} else {
t.protected = true
}
// Now, read the transaction itself
var tx types.Transaction
if err := json.Unmarshal(input, &tx); err != nil {
return err
}
t.tx = &tx
return nil
}
// signUnsignedTransactions converts the input txs to canonical transactions.
//
// The transactions can have two forms, either
// 1. unsigned or
// 2. signed
//
// For (1), r, s, v, need so be zero, and the `secretKey` needs to be set.
// If so, we sign it here and now, with the given `secretKey`
// If the condition above is not met, then it's considered a signed transaction.
//
// To manage this, we read the transactions twice, first trying to read the secretKeys,
// and secondly to read them with the standard tx json format
func signUnsignedTransactions(txs []*txWithKey, signer types.Signer) (types.Transactions, error) {
var signedTxs []*types.Transaction
for i, tx := range txs {
var (
v, r, s = tx.tx.RawSignatureValues()
signed *types.Transaction
err error
)
if tx.key == nil || v.BitLen()+r.BitLen()+s.BitLen() != 0 {
// Already signed
signedTxs = append(signedTxs, tx.tx)
continue
}
// This transaction needs to be signed
if tx.protected {
signed, err = types.SignTx(tx.tx, signer, tx.key)
} else {
signed, err = types.SignTx(tx.tx, types.FrontierSigner{}, tx.key)
}
if err != nil {
return nil, NewError(ErrorJson, fmt.Errorf("tx %d: failed to sign tx: %v", i, err))
}
signedTxs = append(signedTxs, signed)
}
return signedTxs, nil
}
func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *params.ChainConfig) (types.Transactions, error) {
var txsWithKeys []*txWithKey
var signed types.Transactions
if txStr != stdinSelector {
data, err := os.ReadFile(txStr)
if err != nil {
return nil, NewError(ErrorIO, fmt.Errorf("failed reading txs file: %v", err))
}
if strings.HasSuffix(txStr, ".rlp") { // A file containing an rlp list
var body hexutil.Bytes
if err := json.Unmarshal(data, &body); err != nil {
return nil, err
}
// Already signed transactions
if err := rlp.DecodeBytes(body, &signed); err != nil {
return nil, err
}
return signed, nil
}
if err := json.Unmarshal(data, &txsWithKeys); err != nil {
return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshaling txs-file: %v", err))
}
} else {
if len(inputData.TxRlp) > 0 {
// Decode the body of already signed transactions
body := common.FromHex(inputData.TxRlp)
// Already signed transactions
if err := rlp.DecodeBytes(body, &signed); err != nil {
return nil, err
}
return signed, nil
}
// JSON encoded transactions
txsWithKeys = inputData.Txs
}
// We may have to sign the transactions.
signer := types.LatestSignerForChainID(chainConfig.ChainID)
return signUnsignedTransactions(txsWithKeys, signer)
}
func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error { func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
if !chainConfig.IsLondon(big.NewInt(int64(env.Number))) { if !chainConfig.IsLondon(big.NewInt(int64(env.Number))) {
return nil return nil

View file

@ -0,0 +1,194 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package t8ntool
import (
"bytes"
"crypto/ecdsa"
"encoding/json"
"fmt"
"io"
"os"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
)
// txWithKey is a helper-struct, to allow us to use the types.Transaction along with
// a `secretKey`-field, for input
type txWithKey struct {
key *ecdsa.PrivateKey
tx *types.Transaction
protected bool
}
func (t *txWithKey) UnmarshalJSON(input []byte) error {
// Read the metadata, if present
type txMetadata struct {
Key *common.Hash `json:"secretKey"`
Protected *bool `json:"protected"`
}
var data txMetadata
if err := json.Unmarshal(input, &data); err != nil {
return err
}
if data.Key != nil {
k := data.Key.Hex()[2:]
if ecdsaKey, err := crypto.HexToECDSA(k); err != nil {
return err
} else {
t.key = ecdsaKey
}
}
if data.Protected != nil {
t.protected = *data.Protected
} else {
t.protected = true
}
// Now, read the transaction itself
var tx types.Transaction
if err := json.Unmarshal(input, &tx); err != nil {
return err
}
t.tx = &tx
return nil
}
// signUnsignedTransactions converts the input txs to canonical transactions.
//
// The transactions can have two forms, either
// 1. unsigned or
// 2. signed
//
// For (1), r, s, v, need so be zero, and the `secretKey` needs to be set.
// If so, we sign it here and now, with the given `secretKey`
// If the condition above is not met, then it's considered a signed transaction.
//
// To manage this, we read the transactions twice, first trying to read the secretKeys,
// and secondly to read them with the standard tx json format
func signUnsignedTransactions(txs []*txWithKey, signer types.Signer) (types.Transactions, error) {
var signedTxs []*types.Transaction
for i, tx := range txs {
var (
v, r, s = tx.tx.RawSignatureValues()
signed *types.Transaction
err error
)
if tx.key == nil || v.BitLen()+r.BitLen()+s.BitLen() != 0 {
// Already signed
signedTxs = append(signedTxs, tx.tx)
continue
}
// This transaction needs to be signed
if tx.protected {
signed, err = types.SignTx(tx.tx, signer, tx.key)
} else {
signed, err = types.SignTx(tx.tx, types.FrontierSigner{}, tx.key)
}
if err != nil {
return nil, NewError(ErrorJson, fmt.Errorf("tx %d: failed to sign tx: %v", i, err))
}
signedTxs = append(signedTxs, signed)
}
return signedTxs, nil
}
func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *params.ChainConfig) (txIterator, error) {
var txsWithKeys []*txWithKey
if txStr != stdinSelector {
data, err := os.ReadFile(txStr)
if err != nil {
return nil, NewError(ErrorIO, fmt.Errorf("failed reading txs file: %v", err))
}
if strings.HasSuffix(txStr, ".rlp") { // A file containing an rlp list
var body hexutil.Bytes
if err := json.Unmarshal(data, &body); err != nil {
return nil, err
}
return newRlpTxIterator(body), nil
}
if err := json.Unmarshal(data, &txsWithKeys); err != nil {
return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshaling txs-file: %v", err))
}
} else {
if len(inputData.TxRlp) > 0 {
// Decode the body of already signed transactions
return newRlpTxIterator(common.FromHex(inputData.TxRlp)), nil
}
// JSON encoded transactions
txsWithKeys = inputData.Txs
}
// We may have to sign the transactions.
signer := types.LatestSignerForChainID(chainConfig.ChainID)
txs, err := signUnsignedTransactions(txsWithKeys, signer)
return newSliceTxIterator(txs), err
}
type txIterator interface {
// Next returns true until EOF
Next() bool
// Tx returns the next transaction, OR an error.
Tx() (*types.Transaction, error)
}
type sliceTxIterator struct {
idx int
txs []*types.Transaction
}
func newSliceTxIterator(transactions types.Transactions) txIterator {
return &sliceTxIterator{0, transactions}
}
func (ait *sliceTxIterator) Next() bool {
return ait.idx < len(ait.txs)
}
func (ait *sliceTxIterator) Tx() (*types.Transaction, error) {
if ait.idx < len(ait.txs) {
ait.idx++
return ait.txs[ait.idx-1], nil
}
return nil, io.EOF
}
type rlpTxIterator struct {
in *rlp.Stream
}
func newRlpTxIterator(rlpData []byte) txIterator {
in := rlp.NewStream(bytes.NewBuffer(rlpData), 1024*1024)
in.List()
return &rlpTxIterator{in}
}
func (it *rlpTxIterator) Next() bool {
return it.in.MoreDataInList()
}
func (it *rlpTxIterator) Tx() (*types.Transaction, error) {
var a types.Transaction
if err := it.in.Decode(&a); err != nil {
return nil, err
}
return &a, nil
}

View file

@ -108,13 +108,14 @@ func runStateTest(fname string, cfg vm.Config, jsonOut, dump bool) error {
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root) fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
} }
} }
if err != nil { // Dump any state to aid debugging
// Test failed, mark as so and dump any state to aid debugging
result.Pass, result.Error = false, err.Error()
if dump { if dump {
dump := state.RawDump(nil) dump := state.RawDump(nil)
result.State = &dump result.State = &dump
} }
if err != nil {
// Test failed, mark as so
result.Pass, result.Error = false, err.Error()
} }
}) })
results = append(results, *result) results = append(results, *result)

View file

@ -24,9 +24,9 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/docker/docker/pkg/reexec"
"github.com/ethereum/go-ethereum/cmd/evm/internal/t8ntool" "github.com/ethereum/go-ethereum/cmd/evm/internal/t8ntool"
"github.com/ethereum/go-ethereum/internal/cmdtest" "github.com/ethereum/go-ethereum/internal/cmdtest"
"github.com/ethereum/go-ethereum/internal/reexec"
) )
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
@ -275,6 +275,14 @@ func TestT8n(t *testing.T) {
output: t8nOutput{alloc: true, result: true}, output: t8nOutput{alloc: true, result: true},
expOut: "exp.json", expOut: "exp.json",
}, },
{ // More cancun test, plus example of rlp-transaction that cannot be decoded properly
base: "./testdata/30",
input: t8nInput{
"alloc.json", "txs_more.rlp", "env.json", "Cancun", "",
},
output: t8nOutput{alloc: true, result: true},
expOut: "exp.json",
},
} { } {
args := []string{"t8n"} args := []string{"t8n"}
args = append(args, tc.output.get()...) args = append(args, tc.output.get()...)

77
cmd/evm/testdata/30/README.txt vendored Normal file
View file

@ -0,0 +1,77 @@
This example comes from https://github.com/ethereum/go-ethereum/issues/27730.
The input transactions contain three transactions, number `0` and `2` are taken from
`testdata/13`, whereas number `1` is taken from #27730.
The problematic second transaction cannot be RLP-decoded, and the expectation is
that that particular transaction should be rejected, but number `0` and `1` should
still be accepted.
```
$ go run . t8n --input.alloc=./testdata/30/alloc.json --input.txs=./testdata/30/txs_more.rlp --input.env=./testdata/30/env.json --output.result=stdout --output.alloc=stdout --state.fork=Cancun
WARN [10-22|15:38:03.283] rejected tx index=1 error="rlp: input string too short for common.Address, decoding into (types.Transaction)(types.BlobTx).To"
INFO [10-22|15:38:03.284] Trie dumping started root=348312..915c93
INFO [10-22|15:38:03.284] Trie dumping complete accounts=3 elapsed="160.831µs"
{
"alloc": {
"0x095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"code": "0x60004960005500",
"balance": "0xde0b6b3a7640000"
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "0xde0b6b3a7640000"
},
"0xd02d72e067e77158444ef2020ff2d325f929b363": {
"balance": "0xfffffffb8390",
"nonce": "0x3"
}
},
"result": {
"stateRoot": "0x3483124b6710486c9fb3e07975669c66924697c88cccdcc166af5e1218915c93",
"txRoot": "0x013509c8563d41c0ae4bf38f2d6d19fc6512a1d0d6be045079c8c9f68bf45f9d",
"receiptsRoot": "0x75308898d571eafb5cd8cde8278bf5b3d13c5f6ec074926de3bb895b519264e1",
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"receipts": [
{
"type": "0x2",
"root": "0x",
"status": "0x1",
"cumulativeGasUsed": "0x5208",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": null,
"transactionHash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476",
"contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5208",
"effectiveGasPrice": null,
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactionIndex": "0x0"
},
{
"type": "0x2",
"root": "0x",
"status": "0x1",
"cumulativeGasUsed": "0xa410",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": null,
"transactionHash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a",
"contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5208",
"effectiveGasPrice": null,
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactionIndex": "0x1"
}
],
"rejected": [
{
"index": 1,
"error": "rlp: input string too short for common.Address, decoding into (types.Transaction)(types.BlobTx).To"
}
],
"currentDifficulty": null,
"gasUsed": "0xa410",
"currentBaseFee": "0x7",
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
}
}
```

23
cmd/evm/testdata/30/alloc.json vendored Normal file
View file

@ -0,0 +1,23 @@
{
"0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0x0de0b6b3a7640000",
"code" : "0x60004960005500",
"nonce" : "0x00",
"storage" : {
}
},
"0xd02d72e067e77158444ef2020ff2d325f929b363" : {
"balance": "0x01000000000000",
"code": "0x",
"nonce": "0x01",
"storage": {
}
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x0de0b6b3a7640000",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
}
}

23
cmd/evm/testdata/30/env.json vendored Normal file
View file

@ -0,0 +1,23 @@
{
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentNumber" : "0x01",
"currentTimestamp" : "0x03e8",
"currentGasLimit" : "0x1000000000",
"previousHash" : "0xe4e2a30b340bec696242b67584264f878600dce98354ae0b6328740fd4ff18da",
"currentDataGasUsed" : "0x2000",
"parentTimestamp" : "0x00",
"parentDifficulty" : "0x00",
"parentUncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"parentBeaconBlockRoot" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"currentRandom" : "0x0000000000000000000000000000000000000000000000000000000000020000",
"withdrawals" : [
],
"parentBaseFee" : "0x08",
"parentGasUsed" : "0x00",
"parentGasLimit" : "0x1000000000",
"parentExcessBlobGas" : "0x1000",
"parentBlobGasUsed" : "0x2000",
"blockHashes" : {
"0" : "0xe4e2a30b340bec696242b67584264f878600dce98354ae0b6328740fd4ff18da"
}
}

64
cmd/evm/testdata/30/exp.json vendored Normal file
View file

@ -0,0 +1,64 @@
{
"alloc": {
"0x095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"code": "0x60004960005500",
"balance": "0xde0b6b3a7640000"
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "0xde0b6b3a7640000"
},
"0xd02d72e067e77158444ef2020ff2d325f929b363": {
"balance": "0xfffffffb8390",
"nonce": "0x3"
}
},
"result": {
"stateRoot": "0x3483124b6710486c9fb3e07975669c66924697c88cccdcc166af5e1218915c93",
"txRoot": "0x013509c8563d41c0ae4bf38f2d6d19fc6512a1d0d6be045079c8c9f68bf45f9d",
"receiptsRoot": "0x75308898d571eafb5cd8cde8278bf5b3d13c5f6ec074926de3bb895b519264e1",
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"receipts": [
{
"type": "0x2",
"root": "0x",
"status": "0x1",
"cumulativeGasUsed": "0x5208",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": null,
"transactionHash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476",
"contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5208",
"effectiveGasPrice": null,
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactionIndex": "0x0"
},
{
"type": "0x2",
"root": "0x",
"status": "0x1",
"cumulativeGasUsed": "0xa410",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": null,
"transactionHash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a",
"contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5208",
"effectiveGasPrice": null,
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactionIndex": "0x1"
}
],
"rejected": [
{
"index": 1,
"error": "rlp: input string too short for common.Address, decoding into (types.Transaction)(types.BlobTx).To"
}
],
"currentDifficulty": null,
"gasUsed": "0xa410",
"currentBaseFee": "0x7",
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"currentExcessBlobGas": "0x0",
"blobGasUsed": "0x0"
}
}

1
cmd/evm/testdata/30/txs.rlp vendored Normal file
View file

@ -0,0 +1 @@
"0xf8dbb8d903f8d601800285012a05f200833d090080830186a000f85bf85994095e7baea6a6c7c4c2dfeb977efac326af552d87f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010ae1a001a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d880a0fc12b67159a3567f8bdbc49e0be369a2e20e09d57a51c41310543a4128409464a02de0cfe5495c4f58ff60645ceda0afd67a4c90a70bc89fe207269435b35e5b67"

1
cmd/evm/testdata/30/txs_more.rlp vendored Normal file
View file

@ -0,0 +1 @@
"0xf901adb86702f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904b8d903f8d601800285012a05f200833d090080830186a000f85bf85994095e7baea6a6c7c4c2dfeb977efac326af552d87f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010ae1a001a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d880a0fc12b67159a3567f8bdbc49e0be369a2e20e09d57a51c41310543a4128409464a02de0cfe5495c4f58ff60645ceda0afd67a4c90a70bc89fe207269435b35e5b67b86702f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9"

View file

@ -50,6 +50,8 @@ var (
ArgsUsage: "<genesisPath>", ArgsUsage: "<genesisPath>",
Flags: flags.Merge([]cli.Flag{ Flags: flags.Merge([]cli.Flag{
utils.CachePreimagesFlag, utils.CachePreimagesFlag,
utils.OverrideCancun,
utils.OverrideVerkle,
}, utils.DatabaseFlags), }, utils.DatabaseFlags),
Description: ` Description: `
The init command initializes a new genesis block and definition for the network. The init command initializes a new genesis block and definition for the network.
@ -193,6 +195,15 @@ func initGenesis(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx) stack, _ := makeConfigNode(ctx)
defer stack.Close() defer stack.Close()
var overrides core.ChainOverrides
if ctx.IsSet(utils.OverrideCancun.Name) {
v := ctx.Uint64(utils.OverrideCancun.Name)
overrides.OverrideCancun = &v
}
if ctx.IsSet(utils.OverrideVerkle.Name) {
v := ctx.Uint64(utils.OverrideVerkle.Name)
overrides.OverrideVerkle = &v
}
for _, name := range []string{"chaindata", "lightchaindata"} { for _, name := range []string{"chaindata", "lightchaindata"} {
chaindb, err := stack.OpenDatabaseWithFreezer(name, 0, 0, ctx.String(utils.AncientFlag.Name), "", false) chaindb, err := stack.OpenDatabaseWithFreezer(name, 0, 0, ctx.String(utils.AncientFlag.Name), "", false)
if err != nil { if err != nil {
@ -203,7 +214,7 @@ func initGenesis(ctx *cli.Context) error {
triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false) triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false)
defer triedb.Close() defer triedb.Close()
_, hash, err := core.SetupGenesisBlock(chaindb, triedb, genesis) _, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides)
if err != nil { if err != nil {
utils.Fatalf("Failed to write genesis block: %v", err) utils.Fatalf("Failed to write genesis block: %v", err)
} }

185
cmd/geth/logging_test.go Normal file
View file

@ -0,0 +1,185 @@
//go:build integrationtests
// Copyright 2023 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"math/rand"
"os"
"os/exec"
"strings"
"testing"
"github.com/ethereum/go-ethereum/internal/reexec"
)
func runSelf(args ...string) ([]byte, error) {
cmd := &exec.Cmd{
Path: reexec.Self(),
Args: append([]string{"geth-test"}, args...),
}
return cmd.CombinedOutput()
}
func split(input io.Reader) []string {
var output []string
scanner := bufio.NewScanner(input)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
output = append(output, strings.TrimSpace(scanner.Text()))
}
return output
}
func censor(input string, start, end int) string {
if len(input) < end {
return input
}
return input[:start] + strings.Repeat("X", end-start) + input[end:]
}
func TestLogging(t *testing.T) {
testConsoleLogging(t, "terminal", 6, 24)
testConsoleLogging(t, "logfmt", 2, 26)
}
func testConsoleLogging(t *testing.T, format string, tStart, tEnd int) {
haveB, err := runSelf("--log.format", format, "logtest")
if err != nil {
t.Fatal(err)
}
readFile, err := os.Open(fmt.Sprintf("testdata/logging/logtest-%v.txt", format))
if err != nil {
t.Fatal(err)
}
wantLines := split(readFile)
haveLines := split(bytes.NewBuffer(haveB))
for i, want := range wantLines {
if i > len(haveLines)-1 {
t.Fatalf("format %v, line %d missing, want:%v", format, i, want)
}
have := haveLines[i]
for strings.Contains(have, "Unknown config environment variable") {
// This can happen on CI runs. Drop it.
haveLines = append(haveLines[:i], haveLines[i+1:]...)
have = haveLines[i]
}
// Black out the timestamp
have = censor(have, tStart, tEnd)
want = censor(want, tStart, tEnd)
if have != want {
t.Logf(nicediff([]byte(have), []byte(want)))
t.Fatalf("format %v, line %d\nhave %v\nwant %v", format, i, have, want)
}
}
if len(haveLines) != len(wantLines) {
t.Errorf("format %v, want %d lines, have %d", format, len(haveLines), len(wantLines))
}
}
func TestVmodule(t *testing.T) {
checkOutput := func(level int, want, wantNot string) {
t.Helper()
output, err := runSelf("--log.format", "terminal", "--verbosity=0", "--log.vmodule", fmt.Sprintf("logtestcmd_active.go=%d", level), "logtest")
if err != nil {
t.Fatal(err)
}
if len(want) > 0 && !strings.Contains(string(output), want) { // trace should be present at 5
t.Errorf("failed to find expected string ('%s') in output", want)
}
if len(wantNot) > 0 && strings.Contains(string(output), wantNot) { // trace should be present at 5
t.Errorf("string ('%s') should not be present in output", wantNot)
}
}
checkOutput(5, "log at level trace", "") // trace should be present at 5
checkOutput(4, "log at level debug", "log at level trace") // debug should be present at 4, but trace should be missing
checkOutput(3, "log at level info", "log at level debug") // info should be present at 3, but debug should be missing
checkOutput(2, "log at level warn", "log at level info") // warn should be present at 2, but info should be missing
checkOutput(1, "log at level error", "log at level warn") // error should be present at 1, but warn should be missing
}
func nicediff(have, want []byte) string {
var i = 0
for ; i < len(have) && i < len(want); i++ {
if want[i] != have[i] {
break
}
}
var end = i + 40
var start = i - 50
if start < 0 {
start = 0
}
var h, w string
if end < len(have) {
h = string(have[start:end])
} else {
h = string(have[start:])
}
if end < len(want) {
w = string(want[start:end])
} else {
w = string(want[start:])
}
return fmt.Sprintf("have vs want:\n%q\n%q\n", h, w)
}
func TestFileOut(t *testing.T) {
var (
have, want []byte
err error
path = fmt.Sprintf("%s/test_file_out-%d", os.TempDir(), rand.Int63())
)
t.Cleanup(func() { os.Remove(path) })
if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "logtest"); err != nil {
t.Fatal(err)
}
if have, err = os.ReadFile(path); err != nil {
t.Fatal(err)
}
if !bytes.Equal(have, want) {
// show an intelligent diff
t.Logf(nicediff(have, want))
t.Errorf("file content wrong")
}
}
func TestRotatingFileOut(t *testing.T) {
var (
have, want []byte
err error
path = fmt.Sprintf("%s/test_file_out-%d", os.TempDir(), rand.Int63())
)
t.Cleanup(func() { os.Remove(path) })
if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "--log.rotate", "logtest"); err != nil {
t.Fatal(err)
}
if have, err = os.ReadFile(path); err != nil {
t.Fatal(err)
}
if !bytes.Equal(have, want) {
// show an intelligent diff
t.Logf(nicediff(have, want))
t.Errorf("file content wrong")
}
}

View file

@ -0,0 +1,159 @@
//go:build integrationtests
// Copyright 2023 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"fmt"
"math"
"math/big"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/holiman/uint256"
"github.com/urfave/cli/v2"
)
var logTestCommand = &cli.Command{
Action: logTest,
Name: "logtest",
Usage: "Print some log messages",
ArgsUsage: " ",
Description: `
This command is only meant for testing.
`}
// logTest is an entry point which spits out some logs. This is used by testing
// to verify expected outputs
func logTest(ctx *cli.Context) error {
log.ResetGlobalState()
{ // big.Int
ba, _ := new(big.Int).SetString("111222333444555678999", 10) // "111,222,333,444,555,678,999"
bb, _ := new(big.Int).SetString("-111222333444555678999", 10) // "-111,222,333,444,555,678,999"
bc, _ := new(big.Int).SetString("11122233344455567899900", 10) // "11,122,233,344,455,567,899,900"
bd, _ := new(big.Int).SetString("-11122233344455567899900", 10) // "-11,122,233,344,455,567,899,900"
log.Info("big.Int", "111,222,333,444,555,678,999", ba)
log.Info("-big.Int", "-111,222,333,444,555,678,999", bb)
log.Info("big.Int", "11,122,233,344,455,567,899,900", bc)
log.Info("-big.Int", "-11,122,233,344,455,567,899,900", bd)
}
{ //uint256
ua, _ := uint256.FromDecimal("111222333444555678999")
ub, _ := uint256.FromDecimal("11122233344455567899900")
log.Info("uint256", "111,222,333,444,555,678,999", ua)
log.Info("uint256", "11,122,233,344,455,567,899,900", ub)
}
{ // int64
log.Info("int64", "1,000,000", int64(1000000))
log.Info("int64", "-1,000,000", int64(-1000000))
log.Info("int64", "9,223,372,036,854,775,807", int64(math.MaxInt64))
log.Info("int64", "-9,223,372,036,854,775,808", int64(math.MinInt64))
}
{ // uint64
log.Info("uint64", "1,000,000", uint64(1000000))
log.Info("uint64", "18,446,744,073,709,551,615", uint64(math.MaxUint64))
}
{ // Special characters
log.Info("Special chars in value", "key", "special \r\n\t chars")
log.Info("Special chars in key", "special \n\t chars", "value")
log.Info("nospace", "nospace", "nospace")
log.Info("with space", "with nospace", "with nospace")
log.Info("Bash escapes in value", "key", "\u001b[1G\u001b[K\u001b[1A")
log.Info("Bash escapes in key", "\u001b[1G\u001b[K\u001b[1A", "value")
log.Info("Bash escapes in message \u001b[1G\u001b[K\u001b[1A end", "key", "value")
colored := fmt.Sprintf("\u001B[%dmColored\u001B[0m[", 35)
log.Info(colored, colored, colored)
}
{ // Custom Stringer() - type
log.Info("Custom Stringer value", "2562047h47m16.854s", common.PrettyDuration(time.Duration(9223372036854775807)))
}
{ // Lazy eval
log.Info("Lazy evaluation of value", "key", log.Lazy{Fn: func() interface{} { return "lazy value" }})
}
{ // Multi-line message
log.Info("A message with wonky \U0001F4A9 characters")
log.Info("A multiline message \nINFO [10-18|14:11:31.106] with wonky characters \U0001F4A9")
log.Info("A multiline message \nLALA [ZZZZZZZZZZZZZZZZZZ] Actually part of message above")
}
{ // Miscellaneous json-quirks
// This will check if the json output uses strings or json-booleans to represent bool values
log.Info("boolean", "true", true, "false", false)
// Handling of duplicate keys.
// This is actually ill-handled by the current handler: the format.go
// uses a global 'fieldPadding' map and mixes up the two keys. If 'alpha'
// is shorter than beta, it sometimes causes erroneous padding -- and what's more
// it causes _different_ padding in multi-handler context, e.g. both file-
// and console output, making the two mismatch.
log.Info("repeated-key 1", "foo", "alpha", "foo", "beta")
log.Info("repeated-key 2", "xx", "short", "xx", "longer")
}
{ // loglevels
log.Debug("log at level debug")
log.Trace("log at level trace")
log.Info("log at level info")
log.Warn("log at level warn")
log.Error("log at level error")
}
{
// The current log formatter has a global map of paddings, storing the
// longest seen padding per key in a map. This results in a statefulness
// which has some odd side-effects. Demonstrated here:
log.Info("test", "bar", "short", "a", "aligned left")
log.Info("test", "bar", "a long message", "a", 1)
log.Info("test", "bar", "short", "a", "aligned right")
}
{
// This sequence of logs should be output with alignment, so each field becoems a column.
log.Info("The following logs should align so that the key-fields make 5 columns")
log.Info("Inserted known block", "number", 1_012, "hash", common.HexToHash("0x1234"), "txs", 200, "gas", 1_123_123, "other", "first")
log.Info("Inserted new block", "number", 1, "hash", common.HexToHash("0x1235"), "txs", 2, "gas", 1_123, "other", "second")
log.Info("Inserted known block", "number", 99, "hash", common.HexToHash("0x12322"), "txs", 10, "gas", 1, "other", "third")
log.Warn("Inserted known block", "number", 1_012, "hash", common.HexToHash("0x1234"), "txs", 200, "gas", 99, "other", "fourth")
}
{ // Various types of nil
type customStruct struct {
A string
B *uint64
}
log.Info("(*big.Int)(nil)", "<nil>", (*big.Int)(nil))
log.Info("(*uint256.Int)(nil)", "<nil>", (*uint256.Int)(nil))
log.Info("(fmt.Stringer)(nil)", "res", (fmt.Stringer)(nil))
log.Info("nil-concrete-stringer", "res", (*time.Time)(nil))
log.Info("error(nil) ", "res", error(nil))
log.Info("nil-concrete-error", "res", (*customError)(nil))
log.Info("nil-custom-struct", "res", (*customStruct)(nil))
log.Info("raw nil", "res", nil)
log.Info("(*uint64)(nil)", "res", (*uint64)(nil))
}
{ // Logging with 'reserved' keys
log.Info("Using keys 't', 'lvl', 'time', 'level' and 'msg'", "t", "t", "time", "time", "lvl", "lvl", "level", "level", "msg", "msg")
}
return nil
}
// customError is a type which implements error
type customError struct{}
func (c *customError) Error() string { return "" }

View file

@ -0,0 +1,23 @@
//go:build !integrationtests
// Copyright 2023 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import "github.com/urfave/cli/v2"
var logTestCommand *cli.Command

View file

@ -234,6 +234,9 @@ func init() {
// See verkle.go // See verkle.go
verkleCommand, verkleCommand,
} }
if logTestCommand != nil {
app.Commands = append(app.Commands, logTestCommand)
}
sort.Sort(cli.CommandsByName(app.Commands)) sort.Sort(cli.CommandsByName(app.Commands))
app.Flags = flags.Merge( app.Flags = flags.Merge(

View file

@ -23,8 +23,8 @@ import (
"testing" "testing"
"time" "time"
"github.com/docker/docker/pkg/reexec"
"github.com/ethereum/go-ethereum/internal/cmdtest" "github.com/ethereum/go-ethereum/internal/cmdtest"
"github.com/ethereum/go-ethereum/internal/reexec"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
) )

View file

@ -0,0 +1,49 @@
{"111,222,333,444,555,678,999":"111222333444555678999","lvl":"info","msg":"big.Int","t":"2023-11-09T08:33:19.464383209+01:00"}
{"-111,222,333,444,555,678,999":"-111222333444555678999","lvl":"info","msg":"-big.Int","t":"2023-11-09T08:33:19.46455928+01:00"}
{"11,122,233,344,455,567,899,900":"11122233344455567899900","lvl":"info","msg":"big.Int","t":"2023-11-09T08:33:19.464582073+01:00"}
{"-11,122,233,344,455,567,899,900":"-11122233344455567899900","lvl":"info","msg":"-big.Int","t":"2023-11-09T08:33:19.464594846+01:00"}
{"111,222,333,444,555,678,999":"0x607851afc94ca2517","lvl":"info","msg":"uint256","t":"2023-11-09T08:33:19.464607873+01:00"}
{"11,122,233,344,455,567,899,900":"0x25aeffe8aaa1ef67cfc","lvl":"info","msg":"uint256","t":"2023-11-09T08:33:19.464694639+01:00"}
{"1,000,000":1000000,"lvl":"info","msg":"int64","t":"2023-11-09T08:33:19.464708835+01:00"}
{"-1,000,000":-1000000,"lvl":"info","msg":"int64","t":"2023-11-09T08:33:19.464725054+01:00"}
{"9,223,372,036,854,775,807":9223372036854775807,"lvl":"info","msg":"int64","t":"2023-11-09T08:33:19.464735773+01:00"}
{"-9,223,372,036,854,775,808":-9223372036854775808,"lvl":"info","msg":"int64","t":"2023-11-09T08:33:19.464744532+01:00"}
{"1,000,000":1000000,"lvl":"info","msg":"uint64","t":"2023-11-09T08:33:19.464752807+01:00"}
{"18,446,744,073,709,551,615":18446744073709551615,"lvl":"info","msg":"uint64","t":"2023-11-09T08:33:19.464779296+01:00"}
{"key":"special \r\n\t chars","lvl":"info","msg":"Special chars in value","t":"2023-11-09T08:33:19.464794181+01:00"}
{"lvl":"info","msg":"Special chars in key","special \n\t chars":"value","t":"2023-11-09T08:33:19.464827197+01:00"}
{"lvl":"info","msg":"nospace","nospace":"nospace","t":"2023-11-09T08:33:19.464841118+01:00"}
{"lvl":"info","msg":"with space","t":"2023-11-09T08:33:19.464862818+01:00","with nospace":"with nospace"}
{"key":"\u001b[1G\u001b[K\u001b[1A","lvl":"info","msg":"Bash escapes in value","t":"2023-11-09T08:33:19.464876802+01:00"}
{"\u001b[1G\u001b[K\u001b[1A":"value","lvl":"info","msg":"Bash escapes in key","t":"2023-11-09T08:33:19.464885416+01:00"}
{"key":"value","lvl":"info","msg":"Bash escapes in message \u001b[1G\u001b[K\u001b[1A end","t":"2023-11-09T08:33:19.464906946+01:00"}
{"\u001b[35mColored\u001b[0m[":"\u001b[35mColored\u001b[0m[","lvl":"info","msg":"\u001b[35mColored\u001b[0m[","t":"2023-11-09T08:33:19.464921455+01:00"}
{"2562047h47m16.854s":"2562047h47m16.854s","lvl":"info","msg":"Custom Stringer value","t":"2023-11-09T08:33:19.464943893+01:00"}
{"key":"lazy value","lvl":"info","msg":"Lazy evaluation of value","t":"2023-11-09T08:33:19.465013552+01:00"}
{"lvl":"info","msg":"A message with wonky 💩 characters","t":"2023-11-09T08:33:19.465069437+01:00"}
{"lvl":"info","msg":"A multiline message \nINFO [10-18|14:11:31.106] with wonky characters 💩","t":"2023-11-09T08:33:19.465083053+01:00"}
{"lvl":"info","msg":"A multiline message \nLALA [ZZZZZZZZZZZZZZZZZZ] Actually part of message above","t":"2023-11-09T08:33:19.465104289+01:00"}
{"false":"false","lvl":"info","msg":"boolean","t":"2023-11-09T08:33:19.465117185+01:00","true":"true"}
{"foo":"beta","lvl":"info","msg":"repeated-key 1","t":"2023-11-09T08:33:19.465143425+01:00"}
{"lvl":"info","msg":"repeated-key 2","t":"2023-11-09T08:33:19.465156323+01:00","xx":"longer"}
{"lvl":"info","msg":"log at level info","t":"2023-11-09T08:33:19.465193158+01:00"}
{"lvl":"warn","msg":"log at level warn","t":"2023-11-09T08:33:19.465228964+01:00"}
{"lvl":"eror","msg":"log at level error","t":"2023-11-09T08:33:19.465240352+01:00"}
{"a":"aligned left","bar":"short","lvl":"info","msg":"test","t":"2023-11-09T08:33:19.465247226+01:00"}
{"a":1,"bar":"a long message","lvl":"info","msg":"test","t":"2023-11-09T08:33:19.465269028+01:00"}
{"a":"aligned right","bar":"short","lvl":"info","msg":"test","t":"2023-11-09T08:33:19.465313611+01:00"}
{"lvl":"info","msg":"The following logs should align so that the key-fields make 5 columns","t":"2023-11-09T08:33:19.465328188+01:00"}
{"gas":1123123,"hash":"0x0000000000000000000000000000000000000000000000000000000000001234","lvl":"info","msg":"Inserted known block","number":1012,"other":"first","t":"2023-11-09T08:33:19.465350507+01:00","txs":200}
{"gas":1123,"hash":"0x0000000000000000000000000000000000000000000000000000000000001235","lvl":"info","msg":"Inserted new block","number":1,"other":"second","t":"2023-11-09T08:33:19.465387952+01:00","txs":2}
{"gas":1,"hash":"0x0000000000000000000000000000000000000000000000000000000000012322","lvl":"info","msg":"Inserted known block","number":99,"other":"third","t":"2023-11-09T08:33:19.465406687+01:00","txs":10}
{"gas":99,"hash":"0x0000000000000000000000000000000000000000000000000000000000001234","lvl":"warn","msg":"Inserted known block","number":1012,"other":"fourth","t":"2023-11-09T08:33:19.465433025+01:00","txs":200}
{"\u003cnil\u003e":"\u003cnil\u003e","lvl":"info","msg":"(*big.Int)(nil)","t":"2023-11-09T08:33:19.465450283+01:00"}
{"\u003cnil\u003e":"nil","lvl":"info","msg":"(*uint256.Int)(nil)","t":"2023-11-09T08:33:19.465472953+01:00"}
{"lvl":"info","msg":"(fmt.Stringer)(nil)","res":"\u003cnil\u003e","t":"2023-11-09T08:33:19.465538633+01:00"}
{"lvl":"info","msg":"nil-concrete-stringer","res":"nil","t":"2023-11-09T08:33:19.465552355+01:00"}
{"lvl":"info","msg":"error(nil) ","res":"\u003cnil\u003e","t":"2023-11-09T08:33:19.465601029+01:00"}
{"lvl":"info","msg":"nil-concrete-error","res":"","t":"2023-11-09T08:33:19.46561622+01:00"}
{"lvl":"info","msg":"nil-custom-struct","res":"\u003cnil\u003e","t":"2023-11-09T08:33:19.465638888+01:00"}
{"lvl":"info","msg":"raw nil","res":"\u003cnil\u003e","t":"2023-11-09T08:33:19.465673664+01:00"}
{"lvl":"info","msg":"(*uint64)(nil)","res":"\u003cnil\u003e","t":"2023-11-09T08:33:19.465700264+01:00"}
{"level":"level","lvl":"lvl","msg":"msg","t":"t","time":"time"}

View file

@ -0,0 +1,49 @@
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=big.Int 111,222,333,444,555,678,999=111,222,333,444,555,678,999
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=-big.Int -111,222,333,444,555,678,999=-111,222,333,444,555,678,999
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=big.Int 11,122,233,344,455,567,899,900=11,122,233,344,455,567,899,900
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=-big.Int -11,122,233,344,455,567,899,900=-11,122,233,344,455,567,899,900
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=uint256 111,222,333,444,555,678,999=111,222,333,444,555,678,999
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=uint256 11,122,233,344,455,567,899,900=11,122,233,344,455,567,899,900
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=int64 1,000,000=1,000,000
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=int64 -1,000,000=-1,000,000
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=int64 9,223,372,036,854,775,807=9,223,372,036,854,775,807
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=int64 -9,223,372,036,854,775,808=-9,223,372,036,854,775,808
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=uint64 1,000,000=1,000,000
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=uint64 18,446,744,073,709,551,615=18,446,744,073,709,551,615
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Special chars in value" key="special \r\n\t chars"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Special chars in key" "special \n\t chars"=value
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=nospace nospace=nospace
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="with space" "with nospace"="with nospace"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Bash escapes in value" key="\x1b[1G\x1b[K\x1b[1A"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Bash escapes in key" "\x1b[1G\x1b[K\x1b[1A"=value
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Bash escapes in message \x1b[1G\x1b[K\x1b[1A end" key=value
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="\x1b[35mColored\x1b[0m[" "\x1b[35mColored\x1b[0m["="\x1b[35mColored\x1b[0m["
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Custom Stringer value" 2562047h47m16.854s=2562047h47m16.854s
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Lazy evaluation of value" key="lazy value"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="A message with wonky 💩 characters"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="A multiline message \nINFO [10-18|14:11:31.106] with wonky characters 💩"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="A multiline message \nLALA [ZZZZZZZZZZZZZZZZZZ] Actually part of message above"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=boolean true=true false=false
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="repeated-key 1" foo=alpha foo=beta
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="repeated-key 2" xx=short xx=longer
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="log at level info"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=warn msg="log at level warn"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=eror msg="log at level error"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=test bar=short a="aligned left"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=test bar="a long message" a=1
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=test bar=short a="aligned right"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="The following logs should align so that the key-fields make 5 columns"
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Inserted known block" number=1012 hash=0x0000000000000000000000000000000000000000000000000000000000001234 txs=200 gas=1,123,123 other=first
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Inserted new block" number=1 hash=0x0000000000000000000000000000000000000000000000000000000000001235 txs=2 gas=1123 other=second
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Inserted known block" number=99 hash=0x0000000000000000000000000000000000000000000000000000000000012322 txs=10 gas=1 other=third
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=warn msg="Inserted known block" number=1012 hash=0x0000000000000000000000000000000000000000000000000000000000001234 txs=200 gas=99 other=fourth
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=(*big.Int)(nil) <nil>=<nil>
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=(*uint256.Int)(nil) <nil>=<nil>
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=(fmt.Stringer)(nil) res=nil
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=nil-concrete-stringer res=nil
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="error(nil) " res=nil
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=nil-concrete-error res=
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=nil-custom-struct res=<nil>
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="raw nil" res=nil
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg=(*uint64)(nil) res=<nil>
t=xxxxxxxxxxxxxxxxxxxxxxxx lvl=info msg="Using keys 't', 'lvl', 'time', 'level' and 'msg'" t=t time=time lvl=lvl level=level msg=msg

View file

@ -0,0 +1,50 @@
INFO [XX-XX|XX:XX:XX.XXX] big.Int 111,222,333,444,555,678,999=111,222,333,444,555,678,999
INFO [XX-XX|XX:XX:XX.XXX] -big.Int -111,222,333,444,555,678,999=-111,222,333,444,555,678,999
INFO [XX-XX|XX:XX:XX.XXX] big.Int 11,122,233,344,455,567,899,900=11,122,233,344,455,567,899,900
INFO [XX-XX|XX:XX:XX.XXX] -big.Int -11,122,233,344,455,567,899,900=-11,122,233,344,455,567,899,900
INFO [XX-XX|XX:XX:XX.XXX] uint256 111,222,333,444,555,678,999=111,222,333,444,555,678,999
INFO [XX-XX|XX:XX:XX.XXX] uint256 11,122,233,344,455,567,899,900=11,122,233,344,455,567,899,900
INFO [XX-XX|XX:XX:XX.XXX] int64 1,000,000=1,000,000
INFO [XX-XX|XX:XX:XX.XXX] int64 -1,000,000=-1,000,000
INFO [XX-XX|XX:XX:XX.XXX] int64 9,223,372,036,854,775,807=9,223,372,036,854,775,807
INFO [XX-XX|XX:XX:XX.XXX] int64 -9,223,372,036,854,775,808=-9,223,372,036,854,775,808
INFO [XX-XX|XX:XX:XX.XXX] uint64 1,000,000=1,000,000
INFO [XX-XX|XX:XX:XX.XXX] uint64 18,446,744,073,709,551,615=18,446,744,073,709,551,615
INFO [XX-XX|XX:XX:XX.XXX] Special chars in value key="special \r\n\t chars"
INFO [XX-XX|XX:XX:XX.XXX] Special chars in key "special \n\t chars"=value
INFO [XX-XX|XX:XX:XX.XXX] nospace nospace=nospace
INFO [XX-XX|XX:XX:XX.XXX] with space "with nospace"="with nospace"
INFO [XX-XX|XX:XX:XX.XXX] Bash escapes in value key="\x1b[1G\x1b[K\x1b[1A"
INFO [XX-XX|XX:XX:XX.XXX] Bash escapes in key "\x1b[1G\x1b[K\x1b[1A"=value
INFO [XX-XX|XX:XX:XX.XXX] "Bash escapes in message \x1b[1G\x1b[K\x1b[1A end" key=value
INFO [XX-XX|XX:XX:XX.XXX] "\x1b[35mColored\x1b[0m[" "\x1b[35mColored\x1b[0m["="\x1b[35mColored\x1b[0m["
INFO [XX-XX|XX:XX:XX.XXX] Custom Stringer value 2562047h47m16.854s=2562047h47m16.854s
INFO [XX-XX|XX:XX:XX.XXX] Lazy evaluation of value key="lazy value"
INFO [XX-XX|XX:XX:XX.XXX] "A message with wonky 💩 characters"
INFO [XX-XX|XX:XX:XX.XXX] "A multiline message \nINFO [10-18|14:11:31.106] with wonky characters 💩"
INFO [XX-XX|XX:XX:XX.XXX] A multiline message
LALA [XXZXXZXXZXXZXXZXXX] Actually part of message above
INFO [XX-XX|XX:XX:XX.XXX] boolean true=true false=false
INFO [XX-XX|XX:XX:XX.XXX] repeated-key 1 foo=alpha foo=beta
INFO [XX-XX|XX:XX:XX.XXX] repeated-key 2 xx=short xx=longer
INFO [XX-XX|XX:XX:XX.XXX] log at level info
WARN [XX-XX|XX:XX:XX.XXX] log at level warn
ERROR[XX-XX|XX:XX:XX.XXX] log at level error
INFO [XX-XX|XX:XX:XX.XXX] test bar=short a="aligned left"
INFO [XX-XX|XX:XX:XX.XXX] test bar="a long message" a=1
INFO [XX-XX|XX:XX:XX.XXX] test bar=short a="aligned right"
INFO [XX-XX|XX:XX:XX.XXX] The following logs should align so that the key-fields make 5 columns
INFO [XX-XX|XX:XX:XX.XXX] Inserted known block number=1012 hash=000000..001234 txs=200 gas=1,123,123 other=first
INFO [XX-XX|XX:XX:XX.XXX] Inserted new block number=1 hash=000000..001235 txs=2 gas=1123 other=second
INFO [XX-XX|XX:XX:XX.XXX] Inserted known block number=99 hash=000000..012322 txs=10 gas=1 other=third
WARN [XX-XX|XX:XX:XX.XXX] Inserted known block number=1012 hash=000000..001234 txs=200 gas=99 other=fourth
INFO [XX-XX|XX:XX:XX.XXX] (*big.Int)(nil) <nil>=<nil>
INFO [XX-XX|XX:XX:XX.XXX] (*uint256.Int)(nil) <nil>=<nil>
INFO [XX-XX|XX:XX:XX.XXX] (fmt.Stringer)(nil) res=nil
INFO [XX-XX|XX:XX:XX.XXX] nil-concrete-stringer res=nil
INFO [XX-XX|XX:XX:XX.XXX] error(nil) res=nil
INFO [XX-XX|XX:XX:XX.XXX] nil-concrete-error res=
INFO [XX-XX|XX:XX:XX.XXX] nil-custom-struct res=<nil>
INFO [XX-XX|XX:XX:XX.XXX] raw nil res=nil
INFO [XX-XX|XX:XX:XX.XXX] (*uint64)(nil) res=<nil>
INFO [XX-XX|XX:XX:XX.XXX] Using keys 't', 'lvl', 'time', 'level' and 'msg' t=t time=time lvl=lvl level=level msg=msg

View file

@ -2045,12 +2045,11 @@ func SplitTagsFlag(tagsFlag string) map[string]string {
return tagsMap return tagsMap
} }
// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails. // MakeChainDatabase opens a database using the flags passed to the client and will hard crash if it fails.
func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.Database { func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.Database {
var ( var (
cache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheDatabaseFlag.Name) / 100 cache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheDatabaseFlag.Name) / 100
handles = MakeDatabaseHandles(ctx.Int(FDLimitFlag.Name)) handles = MakeDatabaseHandles(ctx.Int(FDLimitFlag.Name))
err error err error
chainDb ethdb.Database chainDb ethdb.Database
) )

View file

@ -84,7 +84,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
toaddr := common.Address{} toaddr := common.Address{}
data := make([]byte, nbytes) data := make([]byte, nbytes)
gas, _ := IntrinsicGas(data, nil, false, false, false, false) gas, _ := IntrinsicGas(data, nil, false, false, false, false)
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)), gen.header.Time) signer := gen.Signer()
gasPrice := big.NewInt(0) gasPrice := big.NewInt(0)
if gen.header.BaseFee != nil { if gen.header.BaseFee != nil {
gasPrice = gen.header.BaseFee gasPrice = gen.header.BaseFee
@ -128,7 +128,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
if gen.header.BaseFee != nil { if gen.header.BaseFee != nil {
gasPrice = gen.header.BaseFee gasPrice = gen.header.BaseFee
} }
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)), gen.header.Time) signer := gen.Signer()
for { for {
gas -= params.TxGas gas -= params.TxGas
if gas < params.TxGas { if gas < params.TxGas {

View file

@ -38,8 +38,8 @@ import (
// See GenerateChain for a detailed explanation. // See GenerateChain for a detailed explanation.
type BlockGen struct { type BlockGen struct {
i int i int
cm *chainMaker
parent *types.Block parent *types.Block
chain []*types.Block
header *types.Header header *types.Header
statedb *state.StateDB statedb *state.StateDB
@ -49,7 +49,6 @@ type BlockGen struct {
uncles []*types.Header uncles []*types.Header
withdrawals []*types.Withdrawal withdrawals []*types.Withdrawal
config *params.ChainConfig
engine consensus.Engine engine consensus.Engine
} }
@ -88,13 +87,18 @@ func (b *BlockGen) SetPoS() {
b.header.Difficulty = new(big.Int) b.header.Difficulty = new(big.Int)
} }
// Difficulty returns the currently calculated difficulty of the block.
func (b *BlockGen) Difficulty() *big.Int {
return new(big.Int).Set(b.header.Difficulty)
}
// SetParentBeaconRoot sets the parent beacon root field of the generated // SetParentBeaconRoot sets the parent beacon root field of the generated
// block. // block.
func (b *BlockGen) SetParentBeaconRoot(root common.Hash) { func (b *BlockGen) SetParentBeaconRoot(root common.Hash) {
b.header.ParentBeaconRoot = &root b.header.ParentBeaconRoot = &root
var ( var (
blockContext = NewEVMBlockContext(b.header, nil, &b.header.Coinbase) blockContext = NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase)
vmenv = vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.config, vm.Config{}) vmenv = vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.cm.config, vm.Config{})
) )
ProcessBeaconBlockRoot(root, vmenv, b.statedb) ProcessBeaconBlockRoot(root, vmenv, b.statedb)
} }
@ -111,7 +115,7 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
b.SetCoinbase(common.Address{}) b.SetCoinbase(common.Address{})
} }
b.statedb.SetTxContext(tx.Hash(), len(b.txs)) b.statedb.SetTxContext(tx.Hash(), len(b.txs))
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig) receipt, err := ApplyTransaction(b.cm.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -125,11 +129,11 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
// AddTx adds a transaction to the generated block. If no coinbase has // AddTx adds a transaction to the generated block. If no coinbase has
// been set, the block's coinbase is set to the zero address. // been set, the block's coinbase is set to the zero address.
// //
// AddTx panics if the transaction cannot be executed. In addition to // AddTx panics if the transaction cannot be executed. In addition to the protocol-imposed
// the protocol-imposed limitations (gas limit, etc.), there are some // limitations (gas limit, etc.), there are some further limitations on the content of
// further limitations on the content of transactions that can be // transactions that can be added. Notably, contract code relying on the BLOCKHASH
// added. Notably, contract code relying on the BLOCKHASH instruction // instruction will panic during execution if it attempts to access a block number outside
// will panic during execution. // of the range created by GenerateChain.
func (b *BlockGen) AddTx(tx *types.Transaction) { func (b *BlockGen) AddTx(tx *types.Transaction) {
b.addTx(nil, vm.Config{}, tx) b.addTx(nil, vm.Config{}, tx)
} }
@ -137,11 +141,10 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
// AddTxWithChain adds a transaction to the generated block. If no coinbase has // AddTxWithChain adds a transaction to the generated block. If no coinbase has
// been set, the block's coinbase is set to the zero address. // been set, the block's coinbase is set to the zero address.
// //
// AddTxWithChain panics if the transaction cannot be executed. In addition to // AddTxWithChain panics if the transaction cannot be executed. In addition to the
// the protocol-imposed limitations (gas limit, etc.), there are some // protocol-imposed limitations (gas limit, etc.), there are some further limitations on
// further limitations on the content of transactions that can be // the content of transactions that can be added. If contract code relies on the BLOCKHASH
// added. If contract code relies on the BLOCKHASH instruction, // instruction, the block in chain will be returned.
// the block in chain will be returned.
func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) { func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
b.addTx(bc, vm.Config{}, tx) b.addTx(bc, vm.Config{}, tx)
} }
@ -158,8 +161,7 @@ func (b *BlockGen) GetBalance(addr common.Address) *big.Int {
return b.statedb.GetBalance(addr) return b.statedb.GetBalance(addr)
} }
// AddUncheckedTx forcefully adds a transaction to the block without any // AddUncheckedTx forcefully adds a transaction to the block without any validation.
// validation.
// //
// AddUncheckedTx will cause consensus failures when used during real // AddUncheckedTx will cause consensus failures when used during real
// chain processing. This is best used in conjunction with raw block insertion. // chain processing. This is best used in conjunction with raw block insertion.
@ -182,6 +184,16 @@ func (b *BlockGen) BaseFee() *big.Int {
return new(big.Int).Set(b.header.BaseFee) return new(big.Int).Set(b.header.BaseFee)
} }
// Gas returns the amount of gas left in the current block.
func (b *BlockGen) Gas() uint64 {
return b.header.GasLimit - b.header.GasUsed
}
// Signer returns a valid signer instance for the current block.
func (b *BlockGen) Signer() types.Signer {
return types.MakeSigner(b.cm.config, b.header.Number, b.header.Time)
}
// AddUncheckedReceipt forcefully adds a receipts to the block without a // AddUncheckedReceipt forcefully adds a receipts to the block without a
// backing transaction. // backing transaction.
// //
@ -207,20 +219,19 @@ func (b *BlockGen) AddUncle(h *types.Header) {
var parent *types.Header var parent *types.Header
for i := b.i - 1; i >= 0; i-- { for i := b.i - 1; i >= 0; i-- {
if b.chain[i].Hash() == h.ParentHash { if b.cm.chain[i].Hash() == h.ParentHash {
parent = b.chain[i].Header() parent = b.cm.chain[i].Header()
break break
} }
} }
chainreader := &fakeChainReader{config: b.config} h.Difficulty = b.engine.CalcDifficulty(b.cm, b.header.Time, parent)
h.Difficulty = b.engine.CalcDifficulty(chainreader, b.header.Time, parent)
// The gas limit and price should be derived from the parent // The gas limit and price should be derived from the parent
h.GasLimit = parent.GasLimit h.GasLimit = parent.GasLimit
if b.config.IsLondon(h.Number) { if b.cm.config.IsLondon(h.Number) {
h.BaseFee = eip1559.CalcBaseFee(b.config, parent) h.BaseFee = eip1559.CalcBaseFee(b.cm.config, parent)
if !b.config.IsLondon(parent.Number) { if !b.cm.config.IsLondon(parent.Number) {
parentGasLimit := parent.GasLimit * b.config.ElasticityMultiplier() parentGasLimit := parent.GasLimit * b.cm.config.ElasticityMultiplier()
h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
} }
} }
@ -242,12 +253,12 @@ func (b *BlockGen) nextWithdrawalIndex() uint64 {
return b.withdrawals[len(b.withdrawals)-1].Index + 1 return b.withdrawals[len(b.withdrawals)-1].Index + 1
} }
for i := b.i - 1; i >= 0; i-- { for i := b.i - 1; i >= 0; i-- {
if wd := b.chain[i].Withdrawals(); len(wd) != 0 { if wd := b.cm.chain[i].Withdrawals(); len(wd) != 0 {
return wd[len(wd)-1].Index + 1 return wd[len(wd)-1].Index + 1
} }
if i == 0 { if i == 0 {
// Correctly set the index if no parent had withdrawals. // Correctly set the index if no parent had withdrawals.
if wd := b.parent.Withdrawals(); len(wd) != 0 { if wd := b.cm.bottom.Withdrawals(); len(wd) != 0 {
return wd[len(wd)-1].Index + 1 return wd[len(wd)-1].Index + 1
} }
} }
@ -263,9 +274,9 @@ func (b *BlockGen) PrevBlock(index int) *types.Block {
panic(fmt.Errorf("block index %d out of range (%d,%d)", index, -1, b.i)) panic(fmt.Errorf("block index %d out of range (%d,%d)", index, -1, b.i))
} }
if index == -1 { if index == -1 {
return b.parent return b.cm.bottom
} }
return b.chain[index] return b.cm.chain[index]
} }
// OffsetTime modifies the time instance of a block, implicitly changing its // OffsetTime modifies the time instance of a block, implicitly changing its
@ -273,11 +284,10 @@ func (b *BlockGen) PrevBlock(index int) *types.Block {
// tied to chain length directly. // tied to chain length directly.
func (b *BlockGen) OffsetTime(seconds int64) { func (b *BlockGen) OffsetTime(seconds int64) {
b.header.Time += uint64(seconds) b.header.Time += uint64(seconds)
if b.header.Time <= b.parent.Header().Time { if b.header.Time <= b.cm.bottom.Header().Time {
panic("block time out of range") panic("block time out of range")
} }
chainreader := &fakeChainReader{config: b.config} b.header.Difficulty = b.engine.CalcDifficulty(b.cm, b.header.Time, b.parent.Header())
b.header.Difficulty = b.engine.CalcDifficulty(chainreader, b.header.Time, b.parent.Header())
} }
// GenerateChain creates a chain of n blocks. The first block's // GenerateChain creates a chain of n blocks. The first block's
@ -296,11 +306,14 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
if config == nil { if config == nil {
config = params.TestChainConfig config = params.TestChainConfig
} }
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n) if engine == nil {
chainreader := &fakeChainReader{config: config} panic("nil consensus engine")
}
cm := newChainMaker(parent, config, engine)
genblock := func(i int, parent *types.Block, triedb *trie.Database, statedb *state.StateDB) (*types.Block, types.Receipts) { genblock := func(i int, parent *types.Block, triedb *trie.Database, statedb *state.StateDB) (*types.Block, types.Receipts) {
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine} b := &BlockGen{i: i, cm: cm, parent: parent, statedb: statedb, engine: engine}
b.header = makeHeader(chainreader, parent, statedb, b.engine) b.header = cm.makeHeader(parent, statedb, b.engine)
// Set the difficulty for clique block. The chain maker doesn't have access // Set the difficulty for clique block. The chain maker doesn't have access
// to a chain, so the difficulty will be left unset (nil). Set it here to the // to a chain, so the difficulty will be left unset (nil). Set it here to the
@ -330,8 +343,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
if gen != nil { if gen != nil {
gen(i, b) gen(i, b)
} }
if b.engine != nil {
block, err := b.engine.FinalizeAndAssemble(chainreader, b.header, statedb, b.txs, b.uncles, b.receipts, b.withdrawals) block, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, b.txs, b.uncles, b.receipts, b.withdrawals)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -346,8 +359,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
} }
return block, b.receipts return block, b.receipts
} }
return nil, nil
}
// Forcibly use hash-based state scheme for retaining all nodes in disk. // Forcibly use hash-based state scheme for retaining all nodes in disk.
triedb := trie.NewDatabase(db, trie.HashDefaults) triedb := trie.NewDatabase(db, trie.HashDefaults)
defer triedb.Close() defer triedb.Close()
@ -357,12 +369,36 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
if err != nil { if err != nil {
panic(err) panic(err)
} }
block, receipt := genblock(i, parent, triedb, statedb) block, receipts := genblock(i, parent, triedb, statedb)
blocks[i] = block
receipts[i] = receipt // Post-process the receipts.
// Here we assign the final block hash and other info into the receipt.
// In order for DeriveFields to work, the transaction and receipt lists need to be
// of equal length. If AddUncheckedTx or AddUncheckedReceipt are used, there will be
// extra ones, so we just trim the lists here.
receiptsCount := len(receipts)
txs := block.Transactions()
if len(receipts) > len(txs) {
receipts = receipts[:len(txs)]
} else if len(receipts) < len(txs) {
txs = txs[:len(receipts)]
}
var blobGasPrice *big.Int
if block.ExcessBlobGas() != nil {
blobGasPrice = eip4844.CalcBlobFee(*block.ExcessBlobGas())
}
if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), blobGasPrice, txs); err != nil {
panic(err)
}
// Re-expand to ensure all receipts are returned.
receipts = receipts[:receiptsCount]
// Advance the chain.
cm.add(block, receipts)
parent = block parent = block
} }
return blocks, receipts return cm.chain, cm.receipts
} }
// GenerateChainWithGenesis is a wrapper of GenerateChain which will initialize // GenerateChainWithGenesis is a wrapper of GenerateChain which will initialize
@ -380,35 +416,26 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int,
return db, blocks, receipts return db, blocks, receipts
} }
func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header {
var time uint64 time := parent.Time() + 10 // block time is fixed at 10 seconds
if parent.Time() == 0 {
time = 10
} else {
time = parent.Time() + 10 // block time is fixed at 10 seconds
}
header := &types.Header{ header := &types.Header{
Root: state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())), Root: state.IntermediateRoot(cm.config.IsEIP158(parent.Number())),
ParentHash: parent.Hash(), ParentHash: parent.Hash(),
Coinbase: parent.Coinbase(), Coinbase: parent.Coinbase(),
Difficulty: engine.CalcDifficulty(chain, time, &types.Header{ Difficulty: engine.CalcDifficulty(cm, time, parent.Header()),
Number: parent.Number(),
Time: time - 10,
Difficulty: parent.Difficulty(),
UncleHash: parent.UncleHash(),
}),
GasLimit: parent.GasLimit(), GasLimit: parent.GasLimit(),
Number: new(big.Int).Add(parent.Number(), common.Big1), Number: new(big.Int).Add(parent.Number(), common.Big1),
Time: time, Time: time,
} }
if chain.Config().IsLondon(header.Number) {
header.BaseFee = eip1559.CalcBaseFee(chain.Config(), parent.Header()) if cm.config.IsLondon(header.Number) {
if !chain.Config().IsLondon(parent.Number()) { header.BaseFee = eip1559.CalcBaseFee(cm.config, parent.Header())
parentGasLimit := parent.GasLimit() * chain.Config().ElasticityMultiplier() if !cm.config.IsLondon(parent.Number()) {
parentGasLimit := parent.GasLimit() * cm.config.ElasticityMultiplier()
header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
} }
} }
if chain.Config().IsCancun(header.Number, header.Time) { if cm.config.IsCancun(header.Number, header.Time) {
var ( var (
parentExcessBlobGas uint64 parentExcessBlobGas uint64
parentBlobGasUsed uint64 parentBlobGasUsed uint64
@ -461,18 +488,86 @@ func makeBlockChainWithGenesis(genesis *Genesis, n int, engine consensus.Engine,
return db, blocks return db, blocks
} }
type fakeChainReader struct { // chainMaker contains the state of chain generation.
type chainMaker struct {
bottom *types.Block
engine consensus.Engine
config *params.ChainConfig config *params.ChainConfig
chain []*types.Block
chainByHash map[common.Hash]*types.Block
receipts []types.Receipts
} }
// Config returns the chain configuration. func newChainMaker(bottom *types.Block, config *params.ChainConfig, engine consensus.Engine) *chainMaker {
func (cr *fakeChainReader) Config() *params.ChainConfig { return &chainMaker{
return cr.config bottom: bottom,
config: config,
engine: engine,
chainByHash: make(map[common.Hash]*types.Block),
}
} }
func (cr *fakeChainReader) CurrentHeader() *types.Header { return nil } func (cm *chainMaker) add(b *types.Block, r []*types.Receipt) {
func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *types.Header { return nil } cm.chain = append(cm.chain, b)
func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *types.Header { return nil } cm.chainByHash[b.Hash()] = b
func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *types.Header { return nil } cm.receipts = append(cm.receipts, r)
func (cr *fakeChainReader) GetBlock(hash common.Hash, number uint64) *types.Block { return nil } }
func (cr *fakeChainReader) GetTd(hash common.Hash, number uint64) *big.Int { return nil }
func (cm *chainMaker) blockByNumber(number uint64) *types.Block {
if number == cm.bottom.NumberU64() {
return cm.bottom
}
cur := cm.CurrentHeader().Number.Uint64()
lowest := cm.bottom.NumberU64() + 1
if number < lowest || number > cur {
return nil
}
return cm.chain[number-lowest]
}
// ChainReader/ChainContext implementation
// Config returns the chain configuration (for consensus.ChainReader).
func (cm *chainMaker) Config() *params.ChainConfig {
return cm.config
}
// Engine returns the consensus engine (for ChainContext).
func (cm *chainMaker) Engine() consensus.Engine {
return cm.engine
}
func (cm *chainMaker) CurrentHeader() *types.Header {
if len(cm.chain) == 0 {
return cm.bottom.Header()
}
return cm.chain[len(cm.chain)-1].Header()
}
func (cm *chainMaker) GetHeaderByNumber(number uint64) *types.Header {
b := cm.blockByNumber(number)
if b == nil {
return nil
}
return b.Header()
}
func (cm *chainMaker) GetHeaderByHash(hash common.Hash) *types.Header {
b := cm.chainByHash[hash]
if b == nil {
return nil
}
return b.Header()
}
func (cm *chainMaker) GetHeader(hash common.Hash, number uint64) *types.Header {
return cm.GetHeaderByNumber(number)
}
func (cm *chainMaker) GetBlock(hash common.Hash, number uint64) *types.Block {
return cm.blockByNumber(number)
}
func (cm *chainMaker) GetTd(hash common.Hash, number uint64) *big.Int {
return nil // not supported
}

View file

@ -19,8 +19,10 @@ package core
import ( import (
"fmt" "fmt"
"math/big" "math/big"
"reflect"
"testing" "testing"
"github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/beacon" "github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/ethash"
@ -53,7 +55,6 @@ func TestGeneratePOSChain(t *testing.T) {
GasLimit: 5_000_000, GasLimit: 5_000_000,
} }
gendb = rawdb.NewMemoryDatabase() gendb = rawdb.NewMemoryDatabase()
signer = types.LatestSigner(gspec.Config)
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
) )
@ -82,10 +83,20 @@ func TestGeneratePOSChain(t *testing.T) {
} }
genesis := gspec.MustCommit(gendb, trie.NewDatabase(gendb, trie.HashDefaults)) genesis := gspec.MustCommit(gendb, trie.NewDatabase(gendb, trie.HashDefaults))
chain, _ := GenerateChain(gspec.Config, genesis, beacon.NewFaker(), gendb, 4, func(i int, gen *BlockGen) { genchain, genreceipts := GenerateChain(gspec.Config, genesis, beacon.NewFaker(), gendb, 4, func(i int, gen *BlockGen) {
gen.SetParentBeaconRoot(common.Hash{byte(i + 1)}) gen.SetParentBeaconRoot(common.Hash{byte(i + 1)})
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(address), address, big.NewInt(1000), params.TxGas, new(big.Int).Add(gen.BaseFee(), common.Big1), nil), signer, key)
// Add value transfer tx.
tx := types.MustSignNewTx(key, gen.Signer(), &types.LegacyTx{
Nonce: gen.TxNonce(address),
To: &address,
Value: big.NewInt(1000),
Gas: params.TxGas,
GasPrice: new(big.Int).Add(gen.BaseFee(), common.Big1),
})
gen.AddTx(tx) gen.AddTx(tx)
// Add withdrawals.
if i == 1 { if i == 1 {
gen.AddWithdrawal(&types.Withdrawal{ gen.AddWithdrawal(&types.Withdrawal{
Validator: 42, Validator: 42,
@ -116,20 +127,39 @@ func TestGeneratePOSChain(t *testing.T) {
blockchain, _ := NewBlockChain(db, nil, gspec, nil, beacon.NewFaker(), vm.Config{}, nil, nil) blockchain, _ := NewBlockChain(db, nil, gspec, nil, beacon.NewFaker(), vm.Config{}, nil, nil)
defer blockchain.Stop() defer blockchain.Stop()
if i, err := blockchain.InsertChain(chain); err != nil { if i, err := blockchain.InsertChain(genchain); err != nil {
fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err) t.Fatalf("insert error (block %d): %v\n", genchain[i].NumberU64(), err)
return
} }
// enforce that withdrawal indexes are monotonically increasing from 0 // enforce that withdrawal indexes are monotonically increasing from 0
var ( var (
withdrawalIndex uint64 withdrawalIndex uint64
head = blockchain.CurrentBlock().Number.Uint64()
) )
for i := 0; i < int(head); i++ { for i := range genchain {
block := blockchain.GetBlockByNumber(uint64(i)) blocknum := genchain[i].NumberU64()
block := blockchain.GetBlockByNumber(blocknum)
if block == nil { if block == nil {
t.Fatalf("block %d not found", i) t.Fatalf("block %d not found", blocknum)
}
// Verify receipts.
genBlockReceipts := genreceipts[i]
for _, r := range genBlockReceipts {
if r.BlockNumber.Cmp(block.Number()) != 0 {
t.Errorf("receipt has wrong block number %d, want %d", r.BlockNumber, block.Number())
}
if r.BlockHash != block.Hash() {
t.Errorf("receipt has wrong block hash %v, want %v", r.BlockHash, block.Hash())
}
// patch up empty logs list to make DeepEqual below work
if r.Logs == nil {
r.Logs = []*types.Log{}
}
}
blockchainReceipts := blockchain.GetReceiptsByHash(block.Hash())
if !reflect.DeepEqual(genBlockReceipts, blockchainReceipts) {
t.Fatalf("receipts mismatch\ngenerated: %s\nblockchain: %s", spew.Sdump(genBlockReceipts), spew.Sdump(blockchainReceipts))
} }
// Verify withdrawals. // Verify withdrawals.
@ -144,7 +174,7 @@ func TestGeneratePOSChain(t *testing.T) {
} }
// Verify parent beacon root. // Verify parent beacon root.
want := common.Hash{byte(i)} want := common.Hash{byte(blocknum)}
if got := block.BeaconRoot(); *got != want { if got := block.BeaconRoot(); *got != want {
t.Fatalf("block %d, wrong parent beacon root: got %s, want %s", i, got, want) t.Fatalf("block %d, wrong parent beacon root: got %s, want %s", i, got, want)
} }

View file

@ -77,11 +77,15 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
// NewEVMTxContext creates a new transaction context for a single transaction. // NewEVMTxContext creates a new transaction context for a single transaction.
func NewEVMTxContext(msg *Message) vm.TxContext { func NewEVMTxContext(msg *Message) vm.TxContext {
return vm.TxContext{ ctx := vm.TxContext{
Origin: msg.From, Origin: msg.From,
GasPrice: new(big.Int).Set(msg.GasPrice), GasPrice: new(big.Int).Set(msg.GasPrice),
BlobHashes: msg.BlobHashes, BlobHashes: msg.BlobHashes,
} }
if msg.BlobGasFeeCap != nil {
ctx.BlobFeeCap = new(big.Int).Set(msg.BlobGasFeeCap)
}
return ctx
} }
// GetHashFn returns a GetHashFunc which retrieves header hashes by number // GetHashFn returns a GetHashFunc which retrieves header hashes by number

View file

@ -287,11 +287,11 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
} else { } else {
log.Info("Writing custom genesis block") log.Info("Writing custom genesis block")
} }
applyOverrides(genesis.Config)
block, err := genesis.Commit(db, triedb) block, err := genesis.Commit(db, triedb)
if err != nil { if err != nil {
return genesis.Config, common.Hash{}, err return genesis.Config, common.Hash{}, err
} }
applyOverrides(genesis.Config)
return genesis.Config, block.Hash(), nil return genesis.Config, block.Hash(), nil
} }
// The genesis block is present(perhaps in ancient database) while the // The genesis block is present(perhaps in ancient database) while the
@ -303,6 +303,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
if genesis == nil { if genesis == nil {
genesis = DefaultGenesisBlock() genesis = DefaultGenesisBlock()
} }
applyOverrides(genesis.Config)
// Ensure the stored genesis matches with the given one. // Ensure the stored genesis matches with the given one.
hash := genesis.ToBlock().Hash() hash := genesis.ToBlock().Hash()
if hash != stored { if hash != stored {
@ -312,11 +313,11 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
if err != nil { if err != nil {
return genesis.Config, hash, err return genesis.Config, hash, err
} }
applyOverrides(genesis.Config)
return genesis.Config, block.Hash(), nil return genesis.Config, block.Hash(), nil
} }
// Check whether the genesis block is already written. // Check whether the genesis block is already written.
if genesis != nil { if genesis != nil {
applyOverrides(genesis.Config)
hash := genesis.ToBlock().Hash() hash := genesis.ToBlock().Hash()
if hash != stored { if hash != stored {
return genesis.Config, hash, &GenesisMismatchError{stored, hash} return genesis.Config, hash, &GenesisMismatchError{stored, hash}

View file

@ -334,14 +334,19 @@ func ReadHeaderRange(db ethdb.Reader, number uint64, count uint64) []rlp.RawValu
return rlpHeaders return rlpHeaders
} }
// read remaining from ancients // read remaining from ancients
max := count * 700 data, err := db.AncientRange(ChainFreezerHeaderTable, i+1-count, count, 0)
data, err := db.AncientRange(ChainFreezerHeaderTable, i+1-count, count, max) if err != nil {
if err == nil && uint64(len(data)) == count { log.Error("Failed to read headers from freezer", "err", err)
// the data is on the order [h, h+1, .., n] -- reordering needed return rlpHeaders
}
if uint64(len(data)) != count {
log.Warn("Incomplete read of headers from freezer", "wanted", count, "read", len(data))
return rlpHeaders
}
// The data is on the order [h, h+1, .., n] -- reordering needed
for i := range data { for i := range data {
rlpHeaders = append(rlpHeaders, data[len(data)-1-i]) rlpHeaders = append(rlpHeaders, data[len(data)-1-i])
} }
}
return rlpHeaders return rlpHeaders
} }

View file

@ -18,6 +18,7 @@ package rawdb
import ( import (
"fmt" "fmt"
"path/filepath"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@ -126,6 +127,8 @@ func InspectFreezerTable(ancient string, freezerName string, tableName string, s
switch freezerName { switch freezerName {
case chainFreezerName: case chainFreezerName:
path, tables = resolveChainFreezerDir(ancient), chainFreezerNoSnappy path, tables = resolveChainFreezerDir(ancient), chainFreezerNoSnappy
case stateFreezerName:
path, tables = filepath.Join(ancient, freezerName), stateFreezerNoSnappy
default: default:
return fmt.Errorf("unknown freezer, supported ones: %v", freezers) return fmt.Errorf("unknown freezer, supported ones: %v", freezers)
} }

View file

@ -182,19 +182,27 @@ func (batch *freezerTableBatch) maybeCommit() error {
// commit writes the batched items to the backing freezerTable. // commit writes the batched items to the backing freezerTable.
func (batch *freezerTableBatch) commit() error { func (batch *freezerTableBatch) commit() error {
// Write data. // Write data. The head file is fsync'd after write to ensure the
// data is truly transferred to disk.
_, err := batch.t.head.Write(batch.dataBuffer) _, err := batch.t.head.Write(batch.dataBuffer)
if err != nil { if err != nil {
return err return err
} }
if err := batch.t.head.Sync(); err != nil {
return err
}
dataSize := int64(len(batch.dataBuffer)) dataSize := int64(len(batch.dataBuffer))
batch.dataBuffer = batch.dataBuffer[:0] batch.dataBuffer = batch.dataBuffer[:0]
// Write indices. // Write indices. The index file is fsync'd after write to ensure the
// data indexes are truly transferred to disk.
_, err = batch.t.index.Write(batch.indexBuffer) _, err = batch.t.index.Write(batch.indexBuffer)
if err != nil { if err != nil {
return err return err
} }
if err := batch.t.index.Sync(); err != nil {
return err
}
indexSize := int64(len(batch.indexBuffer)) indexSize := int64(len(batch.indexBuffer))
batch.indexBuffer = batch.indexBuffer[:0] batch.indexBuffer = batch.indexBuffer[:0]

View file

@ -119,9 +119,10 @@ func (f *ResettableFreezer) Ancient(kind string, number uint64) ([]byte, error)
// AncientRange retrieves multiple items in sequence, starting from the index 'start'. // AncientRange retrieves multiple items in sequence, starting from the index 'start'.
// It will return // It will return
// - at most 'max' items, // - at most 'count' items,
// - at least 1 item (even if exceeding the maxByteSize), but will otherwise // - if maxBytes is specified: at least 1 item (even if exceeding the maxByteSize),
// return as many items as fit into maxByteSize // but will otherwise return as many items as fit into maxByteSize.
// - if maxBytes is not specified, 'count' items will be returned if they are present.
func (f *ResettableFreezer) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) { func (f *ResettableFreezer) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) {
f.lock.RLock() f.lock.RLock()
defer f.lock.RUnlock() defer f.lock.RUnlock()

View file

@ -215,7 +215,9 @@ func (t *freezerTable) repair() error {
if t.readonly { if t.readonly {
return fmt.Errorf("index file(path: %s, name: %s) size is not a multiple of %d", t.path, t.name, indexEntrySize) return fmt.Errorf("index file(path: %s, name: %s) size is not a multiple of %d", t.path, t.name, indexEntrySize)
} }
truncateFreezerFile(t.index, stat.Size()-overflow) // New file can't trigger this path if err := truncateFreezerFile(t.index, stat.Size()-overflow); err != nil {
return err
} // New file can't trigger this path
} }
// Retrieve the file sizes and prepare for truncation // Retrieve the file sizes and prepare for truncation
if stat, err = t.index.Stat(); err != nil { if stat, err = t.index.Stat(); err != nil {
@ -260,8 +262,8 @@ func (t *freezerTable) repair() error {
// Print an error log if the index is corrupted due to an incorrect // Print an error log if the index is corrupted due to an incorrect
// last index item. While it is theoretically possible to have a zero offset // last index item. While it is theoretically possible to have a zero offset
// by storing all zero-size items, it is highly unlikely to occur in practice. // by storing all zero-size items, it is highly unlikely to occur in practice.
if lastIndex.offset == 0 && offsetsSize%indexEntrySize > 1 { if lastIndex.offset == 0 && offsetsSize/indexEntrySize > 1 {
log.Error("Corrupted index file detected", "lastOffset", lastIndex.offset, "items", offsetsSize%indexEntrySize-1) log.Error("Corrupted index file detected", "lastOffset", lastIndex.offset, "indexes", offsetsSize/indexEntrySize)
} }
if t.readonly { if t.readonly {
t.head, err = t.openFile(lastIndex.filenum, openFreezerFileForReadOnly) t.head, err = t.openFile(lastIndex.filenum, openFreezerFileForReadOnly)
@ -416,6 +418,9 @@ func (t *freezerTable) truncateHead(items uint64) error {
if err := truncateFreezerFile(t.index, int64(length+1)*indexEntrySize); err != nil { if err := truncateFreezerFile(t.index, int64(length+1)*indexEntrySize); err != nil {
return err return err
} }
if err := t.index.Sync(); err != nil {
return err
}
// Calculate the new expected size of the data file and truncate it // Calculate the new expected size of the data file and truncate it
var expected indexEntry var expected indexEntry
if length == 0 { if length == 0 {
@ -438,6 +443,7 @@ func (t *freezerTable) truncateHead(items uint64) error {
// Release any files _after the current head -- both the previous head // Release any files _after the current head -- both the previous head
// and any files which may have been opened for reading // and any files which may have been opened for reading
t.releaseFilesAfter(expected.filenum, true) t.releaseFilesAfter(expected.filenum, true)
// Set back the historic head // Set back the historic head
t.head = newHead t.head = newHead
t.headId = expected.filenum t.headId = expected.filenum
@ -445,6 +451,9 @@ func (t *freezerTable) truncateHead(items uint64) error {
if err := truncateFreezerFile(t.head, int64(expected.offset)); err != nil { if err := truncateFreezerFile(t.head, int64(expected.offset)); err != nil {
return err return err
} }
if err := t.head.Sync(); err != nil {
return err
}
// All data files truncated, set internal counters and return // All data files truncated, set internal counters and return
t.headBytes = int64(expected.offset) t.headBytes = int64(expected.offset)
t.items.Store(items) t.items.Store(items)
@ -589,10 +598,12 @@ func (t *freezerTable) Close() error {
// error on Windows. // error on Windows.
doClose(t.index, true, true) doClose(t.index, true, true)
doClose(t.meta, true, true) doClose(t.meta, true, true)
// The preopened non-head data-files are all opened in readonly. // The preopened non-head data-files are all opened in readonly.
// The head is opened in rw-mode, so we sync it here - but since it's also // The head is opened in rw-mode, so we sync it here - but since it's also
// part of t.files, it will be closed in the loop below. // part of t.files, it will be closed in the loop below.
doClose(t.head, true, false) // sync but do not close doClose(t.head, true, false) // sync but do not close
for _, f := range t.files { for _, f := range t.files {
doClose(f, false, true) // close but do not sync doClose(f, false, true) // close but do not sync
} }

View file

@ -73,11 +73,7 @@ func copyFrom(srcPath, destPath string, offset uint64, before func(f *os.File) e
return err return err
} }
f = nil f = nil
return os.Rename(fname, destPath)
if err := os.Rename(fname, destPath); err != nil {
return err
}
return nil
} }
// openFreezerFileForAppend opens a freezer table file and seeks to the end // openFreezerFileForAppend opens a freezer table file and seeks to the end

View file

@ -230,7 +230,9 @@ func (dl *diskLayer) proveRange(ctx *generatorContext, trieId *trie.ID, prefix [
if origin == nil && !diskMore { if origin == nil && !diskMore {
stackTr := trie.NewStackTrie(nil) stackTr := trie.NewStackTrie(nil)
for i, key := range keys { for i, key := range keys {
stackTr.Update(key, vals[i]) if err := stackTr.Update(key, vals[i]); err != nil {
return nil, err
}
} }
if gotRoot := stackTr.Hash(); gotRoot != root { if gotRoot := stackTr.Hash(); gotRoot != root {
return &proofResult{ return &proofResult{

View file

@ -165,7 +165,8 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
} }
// Create a new context to be used in the EVM environment // Create a new context to be used in the EVM environment
blockContext := NewEVMBlockContext(header, bc, author) blockContext := NewEVMBlockContext(header, bc, author)
vmenv := vm.NewEVM(blockContext, vm.TxContext{BlobHashes: tx.BlobHashes()}, statedb, config, cfg) txContext := NewEVMTxContext(msg)
vmenv := vm.NewEVM(blockContext, txContext, statedb, config, cfg)
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv) return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
} }

View file

@ -95,7 +95,7 @@ func TestStateProcessorErrors(t *testing.T) {
}), signer, key1) }), signer, key1)
return tx return tx
} }
var mkBlobTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap *big.Int, hashes []common.Hash) *types.Transaction { var mkBlobTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap, blobGasFeeCap *big.Int, hashes []common.Hash) *types.Transaction {
tx, err := types.SignTx(types.NewTx(&types.BlobTx{ tx, err := types.SignTx(types.NewTx(&types.BlobTx{
Nonce: nonce, Nonce: nonce,
GasTipCap: uint256.MustFromBig(gasTipCap), GasTipCap: uint256.MustFromBig(gasTipCap),
@ -103,6 +103,7 @@ func TestStateProcessorErrors(t *testing.T) {
Gas: gasLimit, Gas: gasLimit,
To: to, To: to,
BlobHashes: hashes, BlobHashes: hashes,
BlobFeeCap: uint256.MustFromBig(blobGasFeeCap),
Value: new(uint256.Int), Value: new(uint256.Int),
}), signer, key1) }), signer, key1)
if err != nil { if err != nil {
@ -196,7 +197,7 @@ func TestStateProcessorErrors(t *testing.T) {
txs: []*types.Transaction{ txs: []*types.Transaction{
mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(0), big.NewInt(0)), mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(0), big.NewInt(0)),
}, },
want: "could not apply tx 0 [0xc4ab868fef0c82ae0387b742aee87907f2d0fc528fc6ea0a021459fb0fc4a4a8]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 0 baseFee: 875000000", want: "could not apply tx 0 [0xc4ab868fef0c82ae0387b742aee87907f2d0fc528fc6ea0a021459fb0fc4a4a8]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 0, baseFee: 875000000",
}, },
{ // ErrTipVeryHigh { // ErrTipVeryHigh
txs: []*types.Transaction{ txs: []*types.Transaction{
@ -247,9 +248,9 @@ func TestStateProcessorErrors(t *testing.T) {
}, },
{ // ErrBlobFeeCapTooLow { // ErrBlobFeeCapTooLow
txs: []*types.Transaction{ txs: []*types.Transaction{
mkBlobTx(0, common.Address{}, params.TxGas, big.NewInt(1), big.NewInt(1), []common.Hash{(common.Hash{1})}), mkBlobTx(0, common.Address{}, params.TxGas, big.NewInt(1), big.NewInt(1), big.NewInt(0), []common.Hash{(common.Hash{1})}),
}, },
want: "could not apply tx 0 [0x6c11015985ce82db691d7b2d017acda296db88b811c3c60dc71449c76256c716]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 1 baseFee: 875000000", want: "could not apply tx 0 [0x6c11015985ce82db691d7b2d017acda296db88b811c3c60dc71449c76256c716]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 1, baseFee: 875000000",
}, },
} { } {
block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config) block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config)
@ -359,7 +360,8 @@ func TestStateProcessorErrors(t *testing.T) {
func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions, config *params.ChainConfig) *types.Block { func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions, config *params.ChainConfig) *types.Block {
difficulty := big.NewInt(0) difficulty := big.NewInt(0)
if !config.TerminalTotalDifficultyPassed { if !config.TerminalTotalDifficultyPassed {
difficulty = engine.CalcDifficulty(&fakeChainReader{config}, parent.Time()+10, &types.Header{ fakeChainReader := newChainMaker(nil, config, engine)
difficulty = engine.CalcDifficulty(fakeChainReader, parent.Time()+10, &types.Header{
Number: parent.Number(), Number: parent.Number(),
Time: parent.Time(), Time: parent.Time(),
Difficulty: parent.Difficulty(), Difficulty: parent.Difficulty(),

View file

@ -287,11 +287,11 @@ func (st *StateTransition) preCheck() error {
msg.From.Hex(), codeHash) msg.From.Hex(), codeHash)
} }
} }
// Make sure that transaction gasFeeCap is greater than the baseFee (post london) // Make sure that transaction gasFeeCap is greater than the baseFee (post london)
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) { if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call) // Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
if !st.evm.Config.NoBaseFee || msg.GasFeeCap.BitLen() > 0 || msg.GasTipCap.BitLen() > 0 { skipCheck := st.evm.Config.NoBaseFee && msg.GasFeeCap.BitLen() == 0 && msg.GasTipCap.BitLen() == 0
if !skipCheck {
if l := msg.GasFeeCap.BitLen(); l > 256 { if l := msg.GasFeeCap.BitLen(); l > 256 {
return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh, return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
msg.From.Hex(), l) msg.From.Hex(), l)
@ -307,7 +307,7 @@ func (st *StateTransition) preCheck() error {
// This will panic if baseFee is nil, but basefee presence is verified // This will panic if baseFee is nil, but basefee presence is verified
// as part of header validation. // as part of header validation.
if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 { if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow, return fmt.Errorf("%w: address %v, maxFeePerGas: %s, baseFee: %s", ErrFeeCapTooLow,
msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee) msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee)
} }
} }
@ -324,17 +324,21 @@ func (st *StateTransition) preCheck() error {
} }
} }
} }
// Check that the user is paying at least the current blob fee
if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) { if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) {
if st.blobGasUsed() > 0 { if st.blobGasUsed() > 0 {
// Check that the user is paying at least the current blob fee // Skip the checks if gas fields are zero and blobBaseFee was explicitly disabled (eth_call)
blobFee := st.evm.Context.BlobBaseFee skipCheck := st.evm.Config.NoBaseFee && msg.BlobGasFeeCap.BitLen() == 0
if st.msg.BlobGasFeeCap.Cmp(blobFee) < 0 { if !skipCheck {
return fmt.Errorf("%w: address %v have %v want %v", ErrBlobFeeCapTooLow, st.msg.From.Hex(), st.msg.BlobGasFeeCap, blobFee) // This will panic if blobBaseFee is nil, but blobBaseFee presence
// is verified as part of header validation.
if msg.BlobGasFeeCap.Cmp(st.evm.Context.BlobBaseFee) < 0 {
return fmt.Errorf("%w: address %v blobGasFeeCap: %v, blobBaseFee: %v", ErrBlobFeeCapTooLow,
msg.From.Hex(), msg.BlobGasFeeCap, st.evm.Context.BlobBaseFee)
}
} }
} }
} }
return st.buyGas() return st.buyGas()
} }

View file

@ -72,8 +72,8 @@ type BlockContext struct {
BlockNumber *big.Int // Provides information for NUMBER BlockNumber *big.Int // Provides information for NUMBER
Time uint64 // Provides information for TIME Time uint64 // Provides information for TIME
Difficulty *big.Int // Provides information for DIFFICULTY Difficulty *big.Int // Provides information for DIFFICULTY
BaseFee *big.Int // Provides information for BASEFEE BaseFee *big.Int // Provides information for BASEFEE (0 if vm runs with NoBaseFee flag and 0 gas price)
BlobBaseFee *big.Int // Provides information for BLOBBASEFEE BlobBaseFee *big.Int // Provides information for BLOBBASEFEE (0 if vm runs with NoBaseFee flag and 0 blob gas price)
Random *common.Hash // Provides information for PREVRANDAO Random *common.Hash // Provides information for PREVRANDAO
} }
@ -82,8 +82,9 @@ type BlockContext struct {
type TxContext struct { type TxContext struct {
// Message information // Message information
Origin common.Address // Provides information for ORIGIN Origin common.Address // Provides information for ORIGIN
GasPrice *big.Int // Provides information for GASPRICE GasPrice *big.Int // Provides information for GASPRICE (and is used to zero the basefee if NoBaseFee is set)
BlobHashes []common.Hash // Provides information for BLOBHASH BlobHashes []common.Hash // Provides information for BLOBHASH
BlobFeeCap *big.Int // Is used to zero the blobbasefee if NoBaseFee is set
} }
// EVM is the Ethereum Virtual Machine base object and provides // EVM is the Ethereum Virtual Machine base object and provides
@ -125,6 +126,17 @@ type EVM struct {
// NewEVM returns a new EVM. The returned EVM is not thread safe and should // NewEVM returns a new EVM. The returned EVM is not thread safe and should
// only ever be used *once*. // only ever be used *once*.
func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM { func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM {
// If basefee tracking is disabled (eth_call, eth_estimateGas, etc), and no
// gas prices were specified, lower the basefee to 0 to avoid breaking EVM
// invariants (basefee < feecap)
if config.NoBaseFee {
if txCtx.GasPrice.BitLen() == 0 {
blockCtx.BaseFee = new(big.Int)
}
if txCtx.BlobFeeCap != nil && txCtx.BlobFeeCap.BitLen() == 0 {
blockCtx.BlobBaseFee = new(big.Int)
}
}
evm := &EVM{ evm := &EVM{
Context: blockCtx, Context: blockCtx,
TxContext: txCtx, TxContext: txCtx,
@ -160,14 +172,6 @@ func (evm *EVM) Interpreter() *EVMInterpreter {
return evm.interpreter return evm.interpreter
} }
// SetBlockContext updates the block context of the EVM.
func (evm *EVM) SetBlockContext(blockCtx BlockContext) {
evm.Context = blockCtx
num := blockCtx.BlockNumber
timestamp := blockCtx.Time
evm.chainRules = evm.chainConfig.Rules(num, blockCtx.Random != nil, timestamp)
}
// Call executes the contract associated with the addr with the given input as // Call executes the contract associated with the addr with the given input as
// parameters. It also handles any necessary value transfer required and takes // parameters. It also handles any necessary value transfer required and takes
// the necessary steps to create accounts and reverses the state in case of an // the necessary steps to create accounts and reverses the state in case of an

View file

@ -224,8 +224,7 @@ const (
SELFDESTRUCT OpCode = 0xff SELFDESTRUCT OpCode = 0xff
) )
// Since the opcodes aren't all in order we can't use a regular slice. var opCodeToString = [256]string{
var opCodeToString = map[OpCode]string{
// 0x0 range - arithmetic ops. // 0x0 range - arithmetic ops.
STOP: "STOP", STOP: "STOP",
ADD: "ADD", ADD: "ADD",
@ -399,12 +398,10 @@ var opCodeToString = map[OpCode]string{
} }
func (op OpCode) String() string { func (op OpCode) String() string {
str := opCodeToString[op] if s := opCodeToString[op]; s != "" {
if len(str) == 0 { return s
return fmt.Sprintf("opcode %#x not defined", int(op))
} }
return fmt.Sprintf("opcode %#x not defined", int(op))
return str
} }
var stringToOp = map[string]OpCode{ var stringToOp = map[string]OpCode{

View file

@ -26,6 +26,7 @@ func NewEnv(cfg *Config) *vm.EVM {
Origin: cfg.Origin, Origin: cfg.Origin,
GasPrice: cfg.GasPrice, GasPrice: cfg.GasPrice,
BlobHashes: cfg.BlobHashes, BlobHashes: cfg.BlobHashes,
BlobFeeCap: cfg.BlobFeeCap,
} }
blockContext := vm.BlockContext{ blockContext := vm.BlockContext{
CanTransfer: core.CanTransfer, CanTransfer: core.CanTransfer,

View file

@ -46,6 +46,7 @@ type Config struct {
BaseFee *big.Int BaseFee *big.Int
BlobBaseFee *big.Int BlobBaseFee *big.Int
BlobHashes []common.Hash BlobHashes []common.Hash
BlobFeeCap *big.Int
Random *common.Hash Random *common.Hash
State *state.StateDB State *state.StateDB
@ -97,7 +98,7 @@ func setDefaults(cfg *Config) {
cfg.BaseFee = big.NewInt(params.InitialBaseFee) cfg.BaseFee = big.NewInt(params.InitialBaseFee)
} }
if cfg.BlobBaseFee == nil { if cfg.BlobBaseFee == nil {
cfg.BlobBaseFee = new(big.Int) cfg.BlobBaseFee = big.NewInt(params.BlobTxMinBlobGasprice)
} }
} }

View file

@ -152,6 +152,10 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
networkID := config.NetworkId
if networkID == 0 {
networkID = chainConfig.ChainID.Uint64()
}
eth := &Ethereum{ eth := &Ethereum{
config: config, config: config,
merger: consensus.NewMerger(chainDb), merger: consensus.NewMerger(chainDb),
@ -160,7 +164,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
accountManager: stack.AccountManager(), accountManager: stack.AccountManager(),
engine: engine, engine: engine,
closeBloomHandler: make(chan struct{}), closeBloomHandler: make(chan struct{}),
networkID: config.NetworkId, networkID: networkID,
gasPrice: config.Miner.GasPrice, gasPrice: config.Miner.GasPrice,
etherbase: config.Miner.Etherbase, etherbase: config.Miner.Etherbase,
bloomRequests: make(chan chan *bloombits.Retrieval), bloomRequests: make(chan chan *bloombits.Retrieval),
@ -173,7 +177,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
if bcVersion != nil { if bcVersion != nil {
dbVer = fmt.Sprintf("%d", *bcVersion) dbVer = fmt.Sprintf("%d", *bcVersion)
} }
log.Info("Initialising Ethereum protocol", "network", config.NetworkId, "dbversion", dbVer) log.Info("Initialising Ethereum protocol", "network", networkID, "dbversion", dbVer)
if !config.SkipBcVersionCheck { if !config.SkipBcVersionCheck {
if bcVersion != nil && *bcVersion > core.BlockChainVersion { if bcVersion != nil && *bcVersion > core.BlockChainVersion {
@ -236,7 +240,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
Chain: eth.blockchain, Chain: eth.blockchain,
TxPool: eth.txPool, TxPool: eth.txPool,
Merger: eth.merger, Merger: eth.merger,
Network: config.NetworkId, Network: networkID,
Sync: config.SyncMode, Sync: config.SyncMode,
BloomCache: uint64(cacheLimit), BloomCache: uint64(cacheLimit),
EventMux: eth.eventMux, EventMux: eth.eventMux,
@ -270,7 +274,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
} }
// Start the RPC service // Start the RPC service
eth.netRPCService = ethapi.NewNetAPI(eth.p2pServer, config.NetworkId) eth.netRPCService = ethapi.NewNetAPI(eth.p2pServer, networkID)
// Register the backend on the node // Register the backend on the node
stack.RegisterAPIs(eth.APIs()) stack.RegisterAPIs(eth.APIs())

View file

@ -59,7 +59,7 @@ var LightClientGPO = gasprice.Config{
// Defaults contains default settings for use on the Ethereum main net. // Defaults contains default settings for use on the Ethereum main net.
var Defaults = Config{ var Defaults = Config{
SyncMode: downloader.SnapSync, SyncMode: downloader.SnapSync,
NetworkId: 1, NetworkId: 0, // enable auto configuration of networkID == chainID
TxLookupLimit: 2350000, TxLookupLimit: 2350000,
TransactionHistory: 2350000, TransactionHistory: 2350000,
StateHistory: params.FullImmutabilityThreshold, StateHistory: params.FullImmutabilityThreshold,
@ -87,8 +87,9 @@ type Config struct {
// If nil, the Ethereum main net block is used. // If nil, the Ethereum main net block is used.
Genesis *core.Genesis `toml:",omitempty"` Genesis *core.Genesis `toml:",omitempty"`
// Protocol options // Network ID separates blockchains on the peer-to-peer networking level. When left
NetworkId uint64 // Network ID to use for selecting peers to connect to // zero, the chain ID is used as network ID.
NetworkId uint64
SyncMode downloader.SyncMode SyncMode downloader.SyncMode
// This can be set to list of enrtree:// URLs which will be queried for // This can be set to list of enrtree:// URLs which will be queried for

View file

@ -36,8 +36,13 @@ import (
var ( var (
errInvalidTopic = errors.New("invalid topic(s)") errInvalidTopic = errors.New("invalid topic(s)")
errFilterNotFound = errors.New("filter not found") errFilterNotFound = errors.New("filter not found")
errInvalidBlockRange = errors.New("invalid block range params")
errExceedMaxTopics = errors.New("exceed max topics")
) )
// The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0
const maxTopics = 4
// filter is a helper struct that holds meta information over the filter type // filter is a helper struct that holds meta information over the filter type
// and associated subscription in the event system. // and associated subscription in the event system.
type filter struct { type filter struct {
@ -333,6 +338,9 @@ func (api *FilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) {
// GetLogs returns logs matching the given argument that are stored within the state. // GetLogs returns logs matching the given argument that are stored within the state.
func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) { func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) {
if len(crit.Topics) > maxTopics {
return nil, errExceedMaxTopics
}
var filter *Filter var filter *Filter
if crit.BlockHash != nil { if crit.BlockHash != nil {
// Block filter requested, construct a single-shot filter // Block filter requested, construct a single-shot filter
@ -347,6 +355,9 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type
if crit.ToBlock != nil { if crit.ToBlock != nil {
end = crit.ToBlock.Int64() end = crit.ToBlock.Int64()
} }
if begin > 0 && end > 0 && begin > end {
return nil, errInvalidBlockRange
}
// Construct the range filter // Construct the range filter
filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics) filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics)
} }

View file

@ -20,7 +20,6 @@ package filters
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -300,6 +299,9 @@ func (es *EventSystem) subscribe(sub *subscription) *Subscription {
// given criteria to the given logs channel. Default value for the from and to // given criteria to the given logs channel. Default value for the from and to
// block is "latest". If the fromBlock > toBlock an error is returned. // block is "latest". If the fromBlock > toBlock an error is returned.
func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) (*Subscription, error) { func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) (*Subscription, error) {
if len(crit.Topics) > maxTopics {
return nil, errExceedMaxTopics
}
var from, to rpc.BlockNumber var from, to rpc.BlockNumber
if crit.FromBlock == nil { if crit.FromBlock == nil {
from = rpc.LatestBlockNumber from = rpc.LatestBlockNumber
@ -332,7 +334,7 @@ func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*typ
if from >= 0 && to == rpc.LatestBlockNumber { if from >= 0 && to == rpc.LatestBlockNumber {
return es.subscribeLogs(crit, logs), nil return es.subscribeLogs(crit, logs), nil
} }
return nil, errors.New("invalid from and to block combination: from > to") return nil, errInvalidBlockRange
} }
// subscribeMinedPendingLogs creates a subscription that returned mined and // subscribeMinedPendingLogs creates a subscription that returned mined and

View file

@ -386,6 +386,8 @@ func TestLogFilterCreation(t *testing.T) {
{FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, false}, {FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, false},
// from block "higher" than to block // from block "higher" than to block
{FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, false}, {FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, false},
// topics more then 4
{FilterCriteria{Topics: [][]common.Hash{{}, {}, {}, {}, {}}}, false},
} }
) )
@ -420,6 +422,7 @@ func TestInvalidLogFilterCreation(t *testing.T) {
0: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, 0: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
1: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, 1: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)},
2: {FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(100)}, 2: {FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(100)},
3: {Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
} }
for i, test := range testCases { for i, test := range testCases {
@ -429,7 +432,10 @@ func TestInvalidLogFilterCreation(t *testing.T) {
} }
} }
// TestLogFilterUninstall tests invalid getLogs requests
func TestInvalidGetLogsRequest(t *testing.T) { func TestInvalidGetLogsRequest(t *testing.T) {
t.Parallel()
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
_, sys = newTestFilterSystem(t, db, Config{}) _, sys = newTestFilterSystem(t, db, Config{})
@ -442,6 +448,7 @@ func TestInvalidGetLogsRequest(t *testing.T) {
0: {BlockHash: &blockHash, FromBlock: big.NewInt(100)}, 0: {BlockHash: &blockHash, FromBlock: big.NewInt(100)},
1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)}, 1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)},
2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, 2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
3: {BlockHash: &blockHash, Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
} }
for i, test := range testCases { for i, test := range testCases {
@ -451,6 +458,21 @@ func TestInvalidGetLogsRequest(t *testing.T) {
} }
} }
// TestInvalidGetRangeLogsRequest tests getLogs with invalid block range
func TestInvalidGetRangeLogsRequest(t *testing.T) {
t.Parallel()
var (
db = rawdb.NewMemoryDatabase()
_, sys = newTestFilterSystem(t, db, Config{})
api = NewFilterAPI(sys, false)
)
if _, err := api.GetLogs(context.Background(), FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(1)}); err != errInvalidBlockRange {
t.Errorf("Expected Logs for invalid range return error, but got: %v", err)
}
}
// TestLogFilter tests whether log filters match the correct logs that are posted to the event feed. // TestLogFilter tests whether log filters match the correct logs that are posted to the event feed.
func TestLogFilter(t *testing.T) { func TestLogFilter(t *testing.T) {
t.Parallel() t.Parallel()

View file

@ -287,53 +287,71 @@ func TestFilters(t *testing.T) {
{ {
f: sys.NewBlockFilter(chain[2].Hash(), []common.Address{contract}, nil), f: sys.NewBlockFilter(chain[2].Hash(), []common.Address{contract}, nil),
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}), f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}),
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}), f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}),
}, { },
{
f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}), f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}),
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}), f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}),
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}), f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}),
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xdba3e2ea9a7d690b722d70ee605fd67ba4c00d1d3aecd5cf187a7b92ad8eb3df","transactionIndex":"0x1","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x1","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xdba3e2ea9a7d690b722d70ee605fd67ba4c00d1d3aecd5cf187a7b92ad8eb3df","transactionIndex":"0x1","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x1","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}), f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}),
}, { },
{
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil), f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil),
}, { },
{
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}), f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}),
}, { },
{
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil),
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil),
}, { },
{
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
err: "safe header not found", err: "safe header not found",
}, { },
{
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
err: "safe header not found", err: "safe header not found",
}, { },
{
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
err: "safe header not found", err: "safe header not found",
}, { },
{
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil),
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xc7245899e5817f16fa99cf5ad2d9c1e4b98443a565a673ec9c764640443ef037","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xd5e8d4e4eb51a2a2a6ec20ef68a4c2801240743c8deb77a6a1d118ac3eefb725","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil),
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xc7245899e5817f16fa99cf5ad2d9c1e4b98443a565a673ec9c764640443ef037","logIndex":"0x0","removed":false}]`, want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xd5e8d4e4eb51a2a2a6ec20ef68a4c2801240743c8deb77a6a1d118ac3eefb725","logIndex":"0x0","removed":false}]`,
}, { },
{
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
err: "invalid block range", err: "invalid block range",
}, },

View file

@ -50,6 +50,7 @@ type callLog struct {
Address common.Address `json:"address"` Address common.Address `json:"address"`
Topics []common.Hash `json:"topics"` Topics []common.Hash `json:"topics"`
Data hexutil.Bytes `json:"data"` Data hexutil.Bytes `json:"data"`
Position hexutil.Uint `json:"position"`
} }
// callTrace is the result of a callTracer run. // callTrace is the result of a callTracer run.
@ -324,7 +325,7 @@ func TestInternals(t *testing.T) {
byte(vm.LOG0), byte(vm.LOG0),
}, },
tracer: mkTracer("callTracer", json.RawMessage(`{ "withLog": true }`)), tracer: mkTracer("callTracer", json.RawMessage(`{ "withLog": true }`)),
want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x5b9e","to":"0x00000000000000000000000000000000deadbeef","input":"0x","logs":[{"address":"0x00000000000000000000000000000000deadbeef","topics":[],"data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}],"value":"0x0","type":"CALL"}`, want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x5b9e","to":"0x00000000000000000000000000000000deadbeef","input":"0x","logs":[{"address":"0x00000000000000000000000000000000deadbeef","topics":[],"data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","position":"0x0"}],"value":"0x0","type":"CALL"}`,
}, },
{ {
// Leads to OOM on the prestate tracer // Leads to OOM on the prestate tracer

View file

@ -95,14 +95,16 @@
"topics": [ "topics": [
"0xe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda" "0xe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda"
], ],
"data": "0x0000000000000000000000004f5777744b500616697cb655dcb02ee6cd51deb5be96016bb57376da7a6d296e0a405ee1501778227dfa604df0a81cb1ae018598" "data": "0x0000000000000000000000004f5777744b500616697cb655dcb02ee6cd51deb5be96016bb57376da7a6d296e0a405ee1501778227dfa604df0a81cb1ae018598",
"position": "0x0"
}, },
{ {
"address": "0x200edd17f30485a8735878661960cd7a9a95733f", "address": "0x200edd17f30485a8735878661960cd7a9a95733f",
"topics": [ "topics": [
"0xacbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da" "0xacbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000000" "data": "0x0000000000000000000000000000000000000000000000000000000000000000",
"position": "0x0"
} }
], ],
"value": "0x8ac7230489e80000", "value": "0x8ac7230489e80000",

View file

@ -257,7 +257,8 @@
"0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add", "0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add",
"0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5" "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5"
], ],
"data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac" "data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -278,7 +279,8 @@
"0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
"0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd" "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd"
], ],
"data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac" "data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -307,7 +309,8 @@
"0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
"0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd" "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd"
], ],
"data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac" "data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -328,7 +331,8 @@
"0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd", "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd",
"0x000000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a06" "0x000000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a06"
], ],
"data": "0x0000000000000000000000000000000000000000000000000041f50e27d56848" "data": "0x0000000000000000000000000000000000000000000000000041f50e27d56848",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -391,7 +395,8 @@
"0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
"0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add" "0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add"
], ],
"data": "0x000000000000000000000000000000000000000000000000de0b6b3a76400000" "data": "0x000000000000000000000000000000000000000000000000de0b6b3a76400000",
"position": "0x0"
} }
], ],
"type": "DELEGATECALL", "type": "DELEGATECALL",

View file

@ -357,7 +357,8 @@
"0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", "0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89",
"0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd"
], ],
"data": "0x00000000000000000000000000000000000000000001819451f999d617dafa93" "data": "0x00000000000000000000000000000000000000000001819451f999d617dafa93",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -370,7 +371,8 @@
"topics": [ "topics": [
"0x69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2" "0x69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2"
], ],
"data": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93" "data": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93",
"position": "0x1"
} }
], ],
"value": "0x0", "value": "0x0",
@ -491,7 +493,8 @@
"0x000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4", "0x000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4",
"0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd"
], ],
"data": "0x00000000000000000000000000000000000000000001819451f999d617dafa76" "data": "0x00000000000000000000000000000000000000000001819451f999d617dafa76",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -504,7 +507,8 @@
"topics": [ "topics": [
"0x69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2" "0x69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2"
], ],
"data": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76" "data": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76",
"position": "0x1"
} }
], ],
"value": "0x0", "value": "0x0",
@ -692,7 +696,8 @@
"0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
"0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc"
], ],
"data": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd" "data": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -874,7 +879,8 @@
"0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc",
"0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd"
], ],
"data": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccc" "data": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccc",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -892,7 +898,8 @@
"0x9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc", "0x9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc",
"0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc"
], ],
"data": "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff" "data": "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff",
"position": "0x1"
} }
], ],
"value": "0x0", "value": "0x0",
@ -914,7 +921,8 @@
"0x9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc", "0x9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc",
"0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc"
], ],
"data": "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff" "data": "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff",
"position": "0x1"
} }
], ],
"value": "0x0", "value": "0x0",
@ -939,7 +947,8 @@
"0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc",
"0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000001" "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -952,14 +961,16 @@
"topics": [ "topics": [
"0x07cf7e805770612a8b2ee8e0bcbba8aa908df5f85fbc4f9e2ef384cf75315038" "0x07cf7e805770612a8b2ee8e0bcbba8aa908df5f85fbc4f9e2ef384cf75315038"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000000" "data": "0x0000000000000000000000000000000000000000000000000000000000000000",
"position": "0x6"
}, },
{ {
"address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", "address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
"topics": [ "topics": [
"0x7027eecbd2a688fc1fa281702b311ed7168571514adfd17014a55d828cb43382" "0x7027eecbd2a688fc1fa281702b311ed7168571514adfd17014a55d828cb43382"
], ],
"data": "0x000000000000000000000000000000000000000000000004563918244f400000" "data": "0x000000000000000000000000000000000000000000000004563918244f400000",
"position": "0x8"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1035,7 +1046,8 @@
"0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
"0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000063" "data": "0x0000000000000000000000000000000000000000000000000000000000000063",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1162,7 +1174,8 @@
"0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f",
"0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000064" "data": "0x0000000000000000000000000000000000000000000000000000000000000064",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1175,14 +1188,16 @@
"topics": [ "topics": [
"0x4b0bc4f25f8d0b92d2e12b686ba96cd75e4e69325e6cf7b1f3119d14eaf2cbdf" "0x4b0bc4f25f8d0b92d2e12b686ba96cd75e4e69325e6cf7b1f3119d14eaf2cbdf"
], ],
"data": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" "data": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526",
"position": "0x6"
}, },
{ {
"address": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", "address": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
"topics": [ "topics": [
"0xf340c079d598119636d42046c6a2d2faf7a68c04aecee516f0e0b8a9e79b8666" "0xf340c079d598119636d42046c6a2d2faf7a68c04aecee516f0e0b8a9e79b8666"
], ],
"data": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e9652600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e9652600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000",
"position": "0x9"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1231,7 +1246,8 @@
"0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
"0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000001" "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1324,7 +1340,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x0000000000000000000000000000000000000000000000000000000000000001" "0x0000000000000000000000000000000000000000000000000000000000000001"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1417,7 +1434,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x0000000000000000000000000000000000000000000000000000000000000002" "0x0000000000000000000000000000000000000000000000000000000000000002"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1510,7 +1528,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x0000000000000000000000000000000000000000000000000000000000000003" "0x0000000000000000000000000000000000000000000000000000000000000003"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1603,7 +1622,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x0000000000000000000000000000000000000000000000000000000000000004" "0x0000000000000000000000000000000000000000000000000000000000000004"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1696,7 +1716,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x0000000000000000000000000000000000000000000000000000000000000005" "0x0000000000000000000000000000000000000000000000000000000000000005"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1789,7 +1810,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x0000000000000000000000000000000000000000000000000000000000000006" "0x0000000000000000000000000000000000000000000000000000000000000006"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1882,7 +1904,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x0000000000000000000000000000000000000000000000000000000000000007" "0x0000000000000000000000000000000000000000000000000000000000000007"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -1975,7 +1998,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x0000000000000000000000000000000000000000000000000000000000000008" "0x0000000000000000000000000000000000000000000000000000000000000008"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -2068,7 +2092,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x0000000000000000000000000000000000000000000000000000000000000009" "0x0000000000000000000000000000000000000000000000000000000000000009"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -2161,7 +2186,8 @@
"0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
"0x000000000000000000000000000000000000000000000000000000000000000a" "0x000000000000000000000000000000000000000000000000000000000000000a"
], ],
"data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"position": "0x2"
} }
], ],
"value": "0x0", "value": "0x0",
@ -2213,7 +2239,8 @@
"0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
"0x0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf30" "0x0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf30"
], ],
"data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c" "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -2234,7 +2261,8 @@
"0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
"0x0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a2" "0x0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a2"
], ],
"data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c" "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -2255,7 +2283,8 @@
"0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
"0x000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b" "0x000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b"
], ],
"data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c" "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",
@ -2268,21 +2297,24 @@
"topics": [ "topics": [
"0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b" "0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b"
], ],
"data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c" "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
"position": "0x2"
}, },
{ {
"address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
"topics": [ "topics": [
"0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b" "0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b"
], ],
"data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c" "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
"position": "0x3"
}, },
{ {
"address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
"topics": [ "topics": [
"0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b" "0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b"
], ],
"data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c" "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
"position": "0x4"
} }
], ],
"value": "0x0", "value": "0x0",

View file

@ -178,350 +178,400 @@
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebebeb0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebebeb0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8888880000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8888880000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3b3b30000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3b3b30000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfc0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfc0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3e3e30000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3e3e30000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e3e3e0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e3e3e0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbdbdb0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbdbdb0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f4f40000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f4f40000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfb0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfb0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0b0b00000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0b0b00000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0a0a00000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0a0a00000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5b5b0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5b5b0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababa0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababa0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaea0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaea0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9a9a90000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9a9a90000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9b9b90000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9b9b90000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfb0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfb0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababa0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababa0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6363630000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6363630000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f9f90000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f9f90000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaea0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaea0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c9c9c0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c9c9c0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f80000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f80000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfc0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfc0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d4e530000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d4e530000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x000000000000000000000000000000000000000000000000000000000000034300000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x000000000000000000000000000000000000000000000000000000000000034300000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
}, },
{ {
"address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
"topics": [ "topics": [
"0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
], ],
"data": "0x00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f494b0000000000000000000000000000000000000000000000000011c37937e08000" "data": "0x00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f494b0000000000000000000000000000000000000000000000000011c37937e08000",
"position": "0x0"
} }
], ],
"value": "0x3782dace9d90000", "value": "0x3782dace9d90000",

View file

@ -266,7 +266,8 @@
"topics": [ "topics": [
"0xaf30e4d66b2f1f23e63ef4591058a897f67e6867233e33ca3508b982dcc4129b" "0xaf30e4d66b2f1f23e63ef4591058a897f67e6867233e33ca3508b982dcc4129b"
], ],
"data": "0x00000000000000000000000050739060a2c32dc076e507ae1a893aab28ecfe68d1b13c1538a940417bf0e73b2498634436753c854c7fb971224d971bd2ae3e8800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000249f011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000355524c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000436a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d0000000000000000000000000000000000000000" "data": "0x00000000000000000000000050739060a2c32dc076e507ae1a893aab28ecfe68d1b13c1538a940417bf0e73b2498634436753c854c7fb971224d971bd2ae3e8800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000249f011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000355524c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000436a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d0000000000000000000000000000000000000000",
"position": "0x4"
} }
], ],
"value": "0x179d63013c5654", "value": "0x179d63013c5654",
@ -277,7 +278,8 @@
{ {
"address": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", "address": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
"topics": [], "topics": [],
"data": "0x62616e6b726f6c6c5f6d69736d61746368" "data": "0x62616e6b726f6c6c5f6d69736d61746368",
"position": "0x2"
} }
], ],
"value": "0x429d069189e0000", "value": "0x429d069189e0000",

View file

@ -75,7 +75,8 @@
"0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", "0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb",
"0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb" "0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb"
], ],
"data": "0x0000000000000000000000000000000000000000000000000000000000989680" "data": "0x0000000000000000000000000000000000000000000000000000000000989680",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",

View file

@ -98,7 +98,8 @@
"topics": [ "topics": [
"0x92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004" "0x92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004"
], ],
"data": "0x00000000000000000000000001115b41bd2731353dd3e6abf44818fdc035aaf10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c1894130000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008861393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030" "data": "0x00000000000000000000000001115b41bd2731353dd3e6abf44818fdc035aaf10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c1894130000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008861393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030",
"position": "0x0"
} }
], ],
"value": "0x0", "value": "0x0",

View file

@ -40,6 +40,9 @@ type callLog struct {
Address common.Address `json:"address"` Address common.Address `json:"address"`
Topics []common.Hash `json:"topics"` Topics []common.Hash `json:"topics"`
Data hexutil.Bytes `json:"data"` Data hexutil.Bytes `json:"data"`
// Position of the log relative to subcalls within the same trace
// See https://github.com/ethereum/go-ethereum/pull/28389 for details
Position hexutil.Uint `json:"position"`
} }
type callFrame struct { type callFrame struct {
@ -188,7 +191,12 @@ func (t *callTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, sco
return return
} }
log := callLog{Address: scope.Contract.Address(), Topics: topics, Data: hexutil.Bytes(data)} log := callLog{
Address: scope.Contract.Address(),
Topics: topics,
Data: hexutil.Bytes(data),
Position: hexutil.Uint(len(t.callstack[len(t.callstack)-1].Calls)),
}
t.callstack[len(t.callstack)-1].Logs = append(t.callstack[len(t.callstack)-1].Logs, log) t.callstack[len(t.callstack)-1].Logs = append(t.callstack[len(t.callstack)-1].Logs, log)
} }
} }

View file

@ -658,6 +658,12 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
if msg.GasPrice != nil { if msg.GasPrice != nil {
arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice) arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice)
} }
if msg.GasFeeCap != nil {
arg["maxFeePerGas"] = (*hexutil.Big)(msg.GasFeeCap)
}
if msg.GasTipCap != nil {
arg["maxPriorityFeePerGas"] = (*hexutil.Big)(msg.GasTipCap)
}
return arg return arg
} }

View file

@ -481,7 +481,7 @@ func testStatusFunctions(t *testing.T, client *rpc.Client) {
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if networkID.Cmp(big.NewInt(0)) != 0 { if networkID.Cmp(big.NewInt(1337)) != 0 {
t.Fatalf("unexpected networkID: %v", networkID) t.Fatalf("unexpected networkID: %v", networkID)
} }

View file

@ -48,6 +48,7 @@ var (
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
testAddr = crypto.PubkeyToAddress(testKey.PublicKey) testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
testContract = common.HexToAddress("0xbeef") testContract = common.HexToAddress("0xbeef")
testEmpty = common.HexToAddress("0xeeee")
testSlot = common.HexToHash("0xdeadbeef") testSlot = common.HexToHash("0xdeadbeef")
testValue = crypto.Keccak256Hash(testSlot[:]) testValue = crypto.Keccak256Hash(testSlot[:])
testBalance = big.NewInt(2e15) testBalance = big.NewInt(2e15)
@ -91,8 +92,11 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
func generateTestChain() (*core.Genesis, []*types.Block) { func generateTestChain() (*core.Genesis, []*types.Block) {
genesis := &core.Genesis{ genesis := &core.Genesis{
Config: params.AllEthashProtocolChanges, Config: params.AllEthashProtocolChanges,
Alloc: core.GenesisAlloc{testAddr: {Balance: testBalance, Storage: map[common.Hash]common.Hash{testSlot: testValue}}, Alloc: core.GenesisAlloc{
testContract: {Nonce: 1, Code: []byte{0x13, 0x37}}}, testAddr: {Balance: testBalance, Storage: map[common.Hash]common.Hash{testSlot: testValue}},
testContract: {Nonce: 1, Code: []byte{0x13, 0x37}},
testEmpty: {Balance: big.NewInt(1)},
},
ExtraData: []byte("test genesis"), ExtraData: []byte("test genesis"),
Timestamp: 9000, Timestamp: 9000,
} }
@ -135,6 +139,12 @@ func TestGethClient(t *testing.T) {
}, { }, {
"TestGetProof2", "TestGetProof2",
func(t *testing.T) { testGetProof(t, client, testContract) }, func(t *testing.T) { testGetProof(t, client, testContract) },
}, {
"TestGetProofEmpty",
func(t *testing.T) { testGetProof(t, client, testEmpty) },
}, {
"TestGetProofNonExistent",
func(t *testing.T) { testGetProofNonExistent(t, client) },
}, { }, {
"TestGetProofCanonicalizeKeys", "TestGetProofCanonicalizeKeys",
func(t *testing.T) { testGetProofCanonicalizeKeys(t, client) }, func(t *testing.T) { testGetProofCanonicalizeKeys(t, client) },
@ -317,6 +327,38 @@ func testGetProofCanonicalizeKeys(t *testing.T, client *rpc.Client) {
} }
} }
func testGetProofNonExistent(t *testing.T, client *rpc.Client) {
addr := common.HexToAddress("0x0001")
ec := New(client)
result, err := ec.GetProof(context.Background(), addr, nil, nil)
if err != nil {
t.Fatal(err)
}
if result.Address != addr {
t.Fatalf("unexpected address, have: %v want: %v", result.Address, addr)
}
// test nonce
if result.Nonce != 0 {
t.Fatalf("invalid nonce, want: %v got: %v", 0, result.Nonce)
}
// test balance
if result.Balance.Cmp(big.NewInt(0)) != 0 {
t.Fatalf("invalid balance, want: %v got: %v", 0, result.Balance)
}
// test storage
if have := len(result.StorageProof); have != 0 {
t.Fatalf("invalid storage proof, want 0 proof, got %v proof(s)", have)
}
// test codeHash
if have, want := result.CodeHash, (common.Hash{}); have != want {
t.Fatalf("codehash wrong, have %v want %v ", have, want)
}
// test codeHash
if have, want := result.StorageHash, (common.Hash{}); have != want {
t.Fatalf("storagehash wrong, have %v want %v ", have, want)
}
}
func testGCStats(t *testing.T, client *rpc.Client) { func testGCStats(t *testing.T, client *rpc.Client) {
ec := New(client) ec := New(client)
_, err := ec.GCStats(context.Background()) _, err := ec.GCStats(context.Background())

View file

@ -127,6 +127,9 @@ type panicLogger struct{}
func (l panicLogger) Infof(format string, args ...interface{}) { func (l panicLogger) Infof(format string, args ...interface{}) {
} }
func (l panicLogger) Errorf(format string, args ...interface{}) {
}
func (l panicLogger) Fatalf(format string, args ...interface{}) { func (l panicLogger) Fatalf(format string, args ...interface{}) {
panic(errors.Errorf("fatal: "+format, args...)) panic(errors.Errorf("fatal: "+format, args...))
} }
@ -160,8 +163,15 @@ func New(file string, cache int, handles int, namespace string, readonly bool, e
// including a frozen memory table and another live one. // including a frozen memory table and another live one.
memTableLimit := 2 memTableLimit := 2
memTableSize := cache * 1024 * 1024 / 2 / memTableLimit memTableSize := cache * 1024 * 1024 / 2 / memTableLimit
if memTableSize > maxMemTableSize {
memTableSize = maxMemTableSize // The memory table size is currently capped at maxMemTableSize-1 due to a
// known bug in the pebble where maxMemTableSize is not recognized as a
// valid size.
//
// TODO use the maxMemTableSize as the maximum table size once the issue
// in pebble is fixed.
if memTableSize >= maxMemTableSize {
memTableSize = maxMemTableSize - 1
} }
db := &Database{ db := &Database{
fn: file, fn: file,

2
go.mod
View file

@ -19,7 +19,6 @@ require (
github.com/crate-crypto/go-kzg-4844 v0.7.0 github.com/crate-crypto/go-kzg-4844 v0.7.0
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/deckarep/golang-set/v2 v2.1.0 github.com/deckarep/golang-set/v2 v2.1.0
github.com/docker/docker v24.0.5+incompatible
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127
github.com/ethereum/c-kzg-4844 v0.4.0 github.com/ethereum/c-kzg-4844 v0.4.0
github.com/fatih/color v1.13.0 github.com/fatih/color v1.13.0
@ -141,6 +140,5 @@ require (
golang.org/x/net v0.17.0 // indirect golang.org/x/net v0.17.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gotest.tools/v3 v3.5.1 // indirect
rsc.io/tmplfunc v0.0.3 // indirect rsc.io/tmplfunc v0.0.3 // indirect
) )

4
go.sum
View file

@ -169,8 +169,6 @@ github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwu
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=
github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo= github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo=
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
@ -963,8 +961,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View file

@ -615,13 +615,13 @@ func (t *Transaction) V(ctx context.Context) hexutil.Big {
return hexutil.Big(*v) return hexutil.Big(*v)
} }
func (t *Transaction) YParity(ctx context.Context) (*hexutil.Uint64, error) { func (t *Transaction) YParity(ctx context.Context) (*hexutil.Big, error) {
tx, _ := t.resolve(ctx) tx, _ := t.resolve(ctx)
if tx == nil || tx.Type() == types.LegacyTxType { if tx == nil || tx.Type() == types.LegacyTxType {
return nil, nil return nil, nil
} }
v, _, _ := tx.RawSignatureValues() v, _, _ := tx.RawSignatureValues()
ret := hexutil.Uint64(v.Int64()) ret := hexutil.Big(*v)
return &ret, nil return &ret, nil
} }
@ -1325,6 +1325,9 @@ func (r *Resolver) Blocks(ctx context.Context, args struct {
From *Long From *Long
To *Long To *Long
}) ([]*Block, error) { }) ([]*Block, error) {
if args.From == nil {
return nil, errors.New("from block number must be specified")
}
from := rpc.BlockNumber(*args.From) from := rpc.BlockNumber(*args.From)
var to rpc.BlockNumber var to rpc.BlockNumber
@ -1417,6 +1420,9 @@ func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria
if args.Filter.ToBlock != nil { if args.Filter.ToBlock != nil {
end = int64(*args.Filter.ToBlock) end = int64(*args.Filter.ToBlock)
} }
if begin > 0 && end > 0 && begin > end {
return nil, errInvalidBlockRange
}
var addresses []common.Address var addresses []common.Address
if args.Filter.Addresses != nil { if args.Filter.Addresses != nil {
addresses = *args.Filter.Addresses addresses = *args.Filter.Addresses

View file

@ -148,6 +148,11 @@ func TestGraphQLBlockSerialization(t *testing.T) {
want: `{"data":{"block":{"number":"0xa","call":{"data":"0x","status":"0x1"}}}}`, want: `{"data":{"block":{"number":"0xa","call":{"data":"0x","status":"0x1"}}}}`,
code: 200, code: 200,
}, },
{
body: `{"query": "{blocks {number}}"}`,
want: `{"errors":[{"message":"from block number must be specified","path":["blocks"]}],"data":null}`,
code: 400,
},
} { } {
resp, err := http.Post(fmt.Sprintf("%s/graphql", stack.HTTPEndpoint()), "application/json", strings.NewReader(tt.body)) resp, err := http.Post(fmt.Sprintf("%s/graphql", stack.HTTPEndpoint()), "application/json", strings.NewReader(tt.body))
if err != nil { if err != nil {
@ -164,6 +169,9 @@ func TestGraphQLBlockSerialization(t *testing.T) {
if tt.code != resp.StatusCode { if tt.code != resp.StatusCode {
t.Errorf("testcase %d %s,\nwrong statuscode, have: %v, want: %v", i, tt.body, resp.StatusCode, tt.code) t.Errorf("testcase %d %s,\nwrong statuscode, have: %v, want: %v", i, tt.body, resp.StatusCode, tt.code)
} }
if ctype := resp.Header.Get("Content-Type"); ctype != "application/json" {
t.Errorf("testcase %d \nwrong Content-Type, have: %v, want: %v", i, ctype, "application/json")
}
} }
} }

View file

@ -157,7 +157,7 @@ const schema string = `
r: BigInt! r: BigInt!
s: BigInt! s: BigInt!
v: BigInt! v: BigInt!
yParity: Long yParity: BigInt
# Envelope transaction support # Envelope transaction support
type: Long type: Long
accessList: [AccessTuple!] accessList: [AccessTuple!]

View file

@ -73,12 +73,12 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
// Setting this disables gzip compression in package node. // Setting this disables gzip compression in package node.
w.Header().Set("transfer-encoding", "identity") w.Header().Set("Transfer-Encoding", "identity")
// Flush the response. Since we are writing close to the response timeout, // Flush the response. Since we are writing close to the response timeout,
// chunked transfer encoding must be disabled by setting content-length. // chunked transfer encoding must be disabled by setting content-length.
w.Header().Set("content-type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Header().Set("content-length", strconv.Itoa(len(responseJSON))) w.Header().Set("Content-Length", strconv.Itoa(len(responseJSON)))
w.Write(responseJSON) w.Write(responseJSON)
if flush, ok := w.(http.Flusher); ok { if flush, ok := w.(http.Flusher); ok {
flush.Flush() flush.Flush()
@ -97,10 +97,10 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
w.Header().Set("Content-Type", "application/json")
if len(response.Errors) > 0 { if len(response.Errors) > 0 {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
} }
w.Header().Set("Content-Type", "application/json")
w.Write(responseJSON) w.Write(responseJSON)
}) })
} }

View file

@ -32,7 +32,7 @@ import (
"text/template" "text/template"
"time" "time"
"github.com/docker/docker/pkg/reexec" "github.com/ethereum/go-ethereum/internal/reexec"
) )
func NewTestCmd(t *testing.T, data interface{}) *TestCmd { func NewTestCmd(t *testing.T, data interface{}) *TestCmd {

View file

@ -218,8 +218,7 @@ func Setup(ctx *cli.Context) error {
return fmt.Errorf("unknown log format: %v", ctx.String(logFormatFlag.Name)) return fmt.Errorf("unknown log format: %v", ctx.String(logFormatFlag.Name))
} }
var ( var (
stdHandler = log.StreamHandler(output, logfmt) ostream = log.StreamHandler(output, logfmt)
ostream = stdHandler
logFile = ctx.String(logFileFlag.Name) logFile = ctx.String(logFileFlag.Name)
rotation = ctx.Bool(logRotateFlag.Name) rotation = ctx.Bool(logRotateFlag.Name)
) )
@ -242,20 +241,21 @@ func Setup(ctx *cli.Context) error {
} else { } else {
context = append(context, "location", filepath.Join(os.TempDir(), "geth-lumberjack.log")) context = append(context, "location", filepath.Join(os.TempDir(), "geth-lumberjack.log"))
} }
ostream = log.MultiHandler(log.StreamHandler(&lumberjack.Logger{ lumberWriter := &lumberjack.Logger{
Filename: logFile, Filename: logFile,
MaxSize: ctx.Int(logMaxSizeMBsFlag.Name), MaxSize: ctx.Int(logMaxSizeMBsFlag.Name),
MaxBackups: ctx.Int(logMaxBackupsFlag.Name), MaxBackups: ctx.Int(logMaxBackupsFlag.Name),
MaxAge: ctx.Int(logMaxAgeFlag.Name), MaxAge: ctx.Int(logMaxAgeFlag.Name),
Compress: ctx.Bool(logCompressFlag.Name), Compress: ctx.Bool(logCompressFlag.Name),
}, logfmt), stdHandler)
} else if logFile != "" {
if logOutputStream, err := log.FileHandler(logFile, logfmt); err != nil {
return err
} else {
ostream = log.MultiHandler(logOutputStream, stdHandler)
context = append(context, "location", logFile)
} }
ostream = log.StreamHandler(io.MultiWriter(output, lumberWriter), logfmt)
} else if logFile != "" {
f, err := os.OpenFile(logFile, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return err
}
ostream = log.StreamHandler(io.MultiWriter(output, f), logfmt)
context = append(context, "location", logFile)
} }
glogger.SetHandler(ostream) glogger.SetHandler(ostream)

View file

@ -678,6 +678,47 @@ func TestEstimateGas(t *testing.T) {
}, },
expectErr: core.ErrInsufficientFunds, expectErr: core.ErrInsufficientFunds,
}, },
// Test for a bug where the gas price was set to zero but the basefee non-zero
//
// contract BasefeeChecker {
// constructor() {
// require(tx.gasprice >= block.basefee);
// if (tx.gasprice > 0) {
// require(block.basefee > 0);
// }
// }
//}
{
blockNumber: rpc.LatestBlockNumber,
call: TransactionArgs{
From: &accounts[0].addr,
Input: hex2Bytes("6080604052348015600f57600080fd5b50483a1015601c57600080fd5b60003a111560315760004811603057600080fd5b5b603f80603e6000396000f3fe6080604052600080fdfea264697066735822122060729c2cee02b10748fae5200f1c9da4661963354973d9154c13a8e9ce9dee1564736f6c63430008130033"),
GasPrice: (*hexutil.Big)(big.NewInt(1_000_000_000)), // Legacy as pricing
},
expectErr: nil,
want: 67617,
},
{
blockNumber: rpc.LatestBlockNumber,
call: TransactionArgs{
From: &accounts[0].addr,
Input: hex2Bytes("6080604052348015600f57600080fd5b50483a1015601c57600080fd5b60003a111560315760004811603057600080fd5b5b603f80603e6000396000f3fe6080604052600080fdfea264697066735822122060729c2cee02b10748fae5200f1c9da4661963354973d9154c13a8e9ce9dee1564736f6c63430008130033"),
MaxFeePerGas: (*hexutil.Big)(big.NewInt(1_000_000_000)), // 1559 gas pricing
},
expectErr: nil,
want: 67617,
},
{
blockNumber: rpc.LatestBlockNumber,
call: TransactionArgs{
From: &accounts[0].addr,
Input: hex2Bytes("6080604052348015600f57600080fd5b50483a1015601c57600080fd5b60003a111560315760004811603057600080fd5b5b603f80603e6000396000f3fe6080604052600080fdfea264697066735822122060729c2cee02b10748fae5200f1c9da4661963354973d9154c13a8e9ce9dee1564736f6c63430008130033"),
GasPrice: nil, // No legacy gas pricing
MaxFeePerGas: nil, // No 1559 gas pricing
},
expectErr: nil,
want: 67595,
},
} }
for i, tc := range testSuite { for i, tc := range testSuite {
result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides) result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides)

35
internal/reexec/reexec.go Normal file
View file

@ -0,0 +1,35 @@
// This file originates from Docker/Moby,
// https://github.com/moby/moby/blob/master/pkg/reexec/reexec.go
// Licensed under Apache License 2.0: https://github.com/moby/moby/blob/master/LICENSE
// Copyright 2013-2018 Docker, Inc.
//
// Package reexec facilitates the busybox style reexec of the docker binary that
// we require because of the forking limitations of using Go. Handlers can be
// registered with a name and the argv 0 of the exec of the binary will be used
// to find and execute custom init paths.
package reexec
import (
"fmt"
"os"
)
var registeredInitializers = make(map[string]func())
// Register adds an initialization func under the specified name
func Register(name string, initializer func()) {
if _, exists := registeredInitializers[name]; exists {
panic(fmt.Sprintf("reexec func already registered under name %q", name))
}
registeredInitializers[name] = initializer
}
// Init is called as the first part of the exec process and returns true if an
// initialization function was called.
func Init() bool {
if initializer, ok := registeredInitializers[os.Args[0]]; ok {
initializer()
return true
}
return false
}

View file

@ -0,0 +1,14 @@
// This file originates from Docker/Moby,
// https://github.com/moby/moby/blob/master/pkg/reexec/
// Licensed under Apache License 2.0: https://github.com/moby/moby/blob/master/LICENSE
// Copyright 2013-2018 Docker, Inc.
//go:build linux
package reexec
// Self returns the path to the current process's binary.
// Returns "/proc/self/exe".
func Self() string {
return "/proc/self/exe"
}

View file

@ -0,0 +1,32 @@
// This file originates from Docker/Moby,
// https://github.com/moby/moby/blob/master/pkg/reexec/
// Licensed under Apache License 2.0: https://github.com/moby/moby/blob/master/LICENSE
// Copyright 2013-2018 Docker, Inc.
//go:build !linux
package reexec
import (
"os"
"os/exec"
"path/filepath"
)
// Self returns the path to the current process's binary.
// Uses os.Args[0].
func Self() string {
name := os.Args[0]
if filepath.Base(name) == name {
if lp, err := exec.LookPath(name); err == nil {
return lp
}
}
// handle conversion of relative paths to absolute
if absName, err := filepath.Abs(name); err == nil {
return absName
}
// if we couldn't get absolute name, return original
// (NOTE: Go only errors on Abs() if os.Getwd fails)
return name
}

View file

@ -24,6 +24,14 @@ const (
termCtxMaxPadding = 40 termCtxMaxPadding = 40
) )
// ResetGlobalState resets the fieldPadding, which is useful for producing
// predictable output.
func ResetGlobalState() {
fieldPaddingLock.Lock()
fieldPadding = make(map[string]int)
fieldPaddingLock.Unlock()
}
// locationTrims are trimmed for display to avoid unwieldy log lines. // locationTrims are trimmed for display to avoid unwieldy log lines.
var locationTrims = []string{ var locationTrims = []string{
"github.com/ethereum/go-ethereum/", "github.com/ethereum/go-ethereum/",

View file

@ -1,105 +1,10 @@
package log package log
import ( import (
"fmt"
"math"
"math/big"
"math/rand" "math/rand"
"strings"
"testing" "testing"
"github.com/holiman/uint256"
) )
func TestPrettyInt64(t *testing.T) {
tests := []struct {
n int64
s string
}{
{0, "0"},
{10, "10"},
{-10, "-10"},
{100, "100"},
{-100, "-100"},
{1000, "1000"},
{-1000, "-1000"},
{10000, "10000"},
{-10000, "-10000"},
{99999, "99999"},
{-99999, "-99999"},
{100000, "100,000"},
{-100000, "-100,000"},
{1000000, "1,000,000"},
{-1000000, "-1,000,000"},
{math.MaxInt64, "9,223,372,036,854,775,807"},
{math.MinInt64, "-9,223,372,036,854,775,808"},
}
for i, tt := range tests {
if have := FormatLogfmtInt64(tt.n); have != tt.s {
t.Errorf("test %d: format mismatch: have %s, want %s", i, have, tt.s)
}
}
}
func TestPrettyUint64(t *testing.T) {
tests := []struct {
n uint64
s string
}{
{0, "0"},
{10, "10"},
{100, "100"},
{1000, "1000"},
{10000, "10000"},
{99999, "99999"},
{100000, "100,000"},
{1000000, "1,000,000"},
{math.MaxUint64, "18,446,744,073,709,551,615"},
}
for i, tt := range tests {
if have := FormatLogfmtUint64(tt.n); have != tt.s {
t.Errorf("test %d: format mismatch: have %s, want %s", i, have, tt.s)
}
}
}
func TestPrettyBigInt(t *testing.T) {
tests := []struct {
int string
s string
}{
{"111222333444555678999", "111,222,333,444,555,678,999"},
{"-111222333444555678999", "-111,222,333,444,555,678,999"},
{"11122233344455567899900", "11,122,233,344,455,567,899,900"},
{"-11122233344455567899900", "-11,122,233,344,455,567,899,900"},
}
for _, tt := range tests {
v, _ := new(big.Int).SetString(tt.int, 10)
if have := formatLogfmtBigInt(v); have != tt.s {
t.Errorf("invalid output %s, want %s", have, tt.s)
}
}
}
func TestPrettyUint256(t *testing.T) {
tests := []struct {
int string
s string
}{
{"111222333444555678999", "111,222,333,444,555,678,999"},
{"11122233344455567899900", "11,122,233,344,455,567,899,900"},
}
for _, tt := range tests {
v := new(uint256.Int)
v.SetFromDecimal(tt.int)
if have := formatLogfmtUint256(v); have != tt.s {
t.Errorf("invalid output %s, want %s", have, tt.s)
}
}
}
var sink string var sink string
func BenchmarkPrettyInt64Logfmt(b *testing.B) { func BenchmarkPrettyInt64Logfmt(b *testing.B) {
@ -115,47 +20,3 @@ func BenchmarkPrettyUint64Logfmt(b *testing.B) {
sink = FormatLogfmtUint64(rand.Uint64()) sink = FormatLogfmtUint64(rand.Uint64())
} }
} }
func TestSanitation(t *testing.T) {
msg := "\u001b[1G\u001b[K\u001b[1A"
msg2 := "\u001b \u0000"
msg3 := "NiceMessage"
msg4 := "Space Message"
msg5 := "Enter\nMessage"
for i, tt := range []struct {
msg string
want string
}{
{
msg: msg,
want: fmt.Sprintf("] %q %q=%q\n", msg, msg, msg),
},
{
msg: msg2,
want: fmt.Sprintf("] %q %q=%q\n", msg2, msg2, msg2),
},
{
msg: msg3,
want: fmt.Sprintf("] %s %s=%s\n", msg3, msg3, msg3),
},
{
msg: msg4,
want: fmt.Sprintf("] %s %q=%q\n", msg4, msg4, msg4),
},
{
msg: msg5,
want: fmt.Sprintf("] %s %q=%q\n", msg5, msg5, msg5),
},
} {
var (
logger = New()
out = new(strings.Builder)
)
logger.SetHandler(LvlFilterHandler(LvlInfo, StreamHandler(out, TerminalFormat(false))))
logger.Info(tt.msg, tt.msg, tt.msg)
if have := out.String()[24:]; tt.want != have {
t.Fatalf("test %d: want / have: \n%v\n%v", i, tt.want, have)
}
}
}

View file

@ -34,7 +34,7 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/docker/docker/pkg/reexec" "github.com/ethereum/go-ethereum/internal/reexec"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"

View file

@ -25,8 +25,8 @@ import (
"os" "os"
"strconv" "strconv"
"github.com/docker/docker/pkg/reexec"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/internal/reexec"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"

View file

@ -21,7 +21,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math" "math"
"strconv"
"strings" "strings"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -221,7 +220,7 @@ func (bnh *BlockNumberOrHash) Number() (BlockNumber, bool) {
func (bnh *BlockNumberOrHash) String() string { func (bnh *BlockNumberOrHash) String() string {
if bnh.BlockNumber != nil { if bnh.BlockNumber != nil {
return strconv.Itoa(int(*bnh.BlockNumber)) return bnh.BlockNumber.String()
} }
if bnh.BlockHash != nil { if bnh.BlockHash != nil {
return bnh.BlockHash.String() return bnh.BlockHash.String()

View file

@ -153,3 +153,24 @@ func TestBlockNumberOrHash_WithNumber_MarshalAndUnmarshal(t *testing.T) {
}) })
} }
} }
func TestBlockNumberOrHash_StringAndUnmarshal(t *testing.T) {
tests := []BlockNumberOrHash{
BlockNumberOrHashWithNumber(math.MaxInt64),
BlockNumberOrHashWithNumber(PendingBlockNumber),
BlockNumberOrHashWithNumber(LatestBlockNumber),
BlockNumberOrHashWithNumber(EarliestBlockNumber),
BlockNumberOrHashWithNumber(32),
BlockNumberOrHashWithHash(common.Hash{0xaa}, false),
}
for _, want := range tests {
marshalled, _ := json.Marshal(want.String())
var have BlockNumberOrHash
if err := json.Unmarshal(marshalled, &have); err != nil {
t.Fatalf("cannot unmarshal (%v): %v", string(marshalled), err)
}
if !reflect.DeepEqual(want, have) {
t.Fatalf("wrong result: have %v, want %v", have, want)
}
}
}

View file

@ -18,6 +18,7 @@ package trie
import ( import (
"bytes" "bytes"
"errors"
"sync" "sync"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -92,12 +93,14 @@ func NewStackTrie(options *StackTrieOptions) *StackTrie {
// Update inserts a (key, value) pair into the stack trie. // Update inserts a (key, value) pair into the stack trie.
func (t *StackTrie) Update(key, value []byte) error { func (t *StackTrie) Update(key, value []byte) error {
k := keybytesToHex(key)
if len(value) == 0 { if len(value) == 0 {
panic("deletion not supported") return errors.New("trying to insert empty (deletion)")
} }
k := keybytesToHex(key)
k = k[:len(k)-1] // chop the termination flag k = k[:len(k)-1] // chop the termination flag
if bytes.Compare(t.last, k) >= 0 {
return errors.New("non-ascending key order")
}
// track the first and last inserted entries. // track the first and last inserted entries.
if t.first == nil { if t.first == nil {
t.first = append([]byte{}, k...) t.first = append([]byte{}, k...)

View file

@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/trie/testutil" "github.com/ethereum/go-ethereum/trie/testutil"
"github.com/stretchr/testify/assert"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -463,3 +464,24 @@ func TestPartialStackTrie(t *testing.T) {
} }
} }
} }
func TestStackTrieErrors(t *testing.T) {
s := NewStackTrie(nil)
// Deletion
if err := s.Update(nil, nil); err == nil {
t.Fatal("expected error")
}
if err := s.Update(nil, []byte{}); err == nil {
t.Fatal("expected error")
}
if err := s.Update([]byte{0xa}, []byte{}); err == nil {
t.Fatal("expected error")
}
// Non-ascending keys (going backwards or repeating)
assert.Nil(t, s.Update([]byte{0xaa}, []byte{0xa}))
assert.NotNil(t, s.Update([]byte{0xaa}, []byte{0xa}), "repeat insert same key")
assert.NotNil(t, s.Update([]byte{0xaa}, []byte{0xb}), "repeat insert same key")
assert.Nil(t, s.Update([]byte{0xab}, []byte{0xa}))
assert.NotNil(t, s.Update([]byte{0x10}, []byte{0xb}), "out of order insert")
assert.NotNil(t, s.Update([]byte{0xaa}, []byte{0xb}), "repeat insert same key")
}

View file

@ -96,10 +96,14 @@ type tester struct {
snapStorages map[common.Hash]map[common.Hash]map[common.Hash][]byte snapStorages map[common.Hash]map[common.Hash]map[common.Hash][]byte
} }
func newTester(t *testing.T) *tester { func newTester(t *testing.T, historyLimit uint64) *tester {
var ( var (
disk, _ = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) disk, _ = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false)
db = New(disk, &Config{CleanCacheSize: 256 * 1024, DirtyCacheSize: 256 * 1024}) db = New(disk, &Config{
StateHistory: historyLimit,
CleanCacheSize: 256 * 1024,
DirtyCacheSize: 256 * 1024,
})
obj = &tester{ obj = &tester{
db: db, db: db,
preimages: make(map[common.Hash]common.Address), preimages: make(map[common.Hash]common.Address),
@ -376,7 +380,7 @@ func (t *tester) bottomIndex() int {
func TestDatabaseRollback(t *testing.T) { func TestDatabaseRollback(t *testing.T) {
// Verify state histories // Verify state histories
tester := newTester(t) tester := newTester(t, 0)
defer tester.release() defer tester.release()
if err := tester.verifyHistory(); err != nil { if err := tester.verifyHistory(); err != nil {
@ -402,7 +406,7 @@ func TestDatabaseRollback(t *testing.T) {
func TestDatabaseRecoverable(t *testing.T) { func TestDatabaseRecoverable(t *testing.T) {
var ( var (
tester = newTester(t) tester = newTester(t, 0)
index = tester.bottomIndex() index = tester.bottomIndex()
) )
defer tester.release() defer tester.release()
@ -440,7 +444,7 @@ func TestDatabaseRecoverable(t *testing.T) {
} }
func TestDisable(t *testing.T) { func TestDisable(t *testing.T) {
tester := newTester(t) tester := newTester(t, 0)
defer tester.release() defer tester.release()
_, stored := rawdb.ReadAccountTrieNode(tester.db.diskdb, nil) _, stored := rawdb.ReadAccountTrieNode(tester.db.diskdb, nil)
@ -476,7 +480,7 @@ func TestDisable(t *testing.T) {
} }
func TestCommit(t *testing.T) { func TestCommit(t *testing.T) {
tester := newTester(t) tester := newTester(t, 0)
defer tester.release() defer tester.release()
if err := tester.db.Commit(tester.lastHash(), false); err != nil { if err := tester.db.Commit(tester.lastHash(), false); err != nil {
@ -500,7 +504,7 @@ func TestCommit(t *testing.T) {
} }
func TestJournal(t *testing.T) { func TestJournal(t *testing.T) {
tester := newTester(t) tester := newTester(t, 0)
defer tester.release() defer tester.release()
if err := tester.db.Journal(tester.lastHash()); err != nil { if err := tester.db.Journal(tester.lastHash()); err != nil {
@ -524,7 +528,7 @@ func TestJournal(t *testing.T) {
} }
func TestCorruptedJournal(t *testing.T) { func TestCorruptedJournal(t *testing.T) {
tester := newTester(t) tester := newTester(t, 0)
defer tester.release() defer tester.release()
if err := tester.db.Journal(tester.lastHash()); err != nil { if err := tester.db.Journal(tester.lastHash()); err != nil {
@ -553,6 +557,35 @@ func TestCorruptedJournal(t *testing.T) {
} }
} }
// TestTailTruncateHistory function is designed to test a specific edge case where,
// when history objects are removed from the end, it should trigger a state flush
// if the ID of the new tail object is even higher than the persisted state ID.
//
// For example, let's say the ID of the persistent state is 10, and the current
// history objects range from ID(5) to ID(15). As we accumulate six more objects,
// the history will expand to cover ID(11) to ID(21). ID(11) then becomes the
// oldest history object, and its ID is even higher than the stored state.
//
// In this scenario, it is mandatory to update the persistent state before
// truncating the tail histories. This ensures that the ID of the persistent state
// always falls within the range of [oldest-history-id, latest-history-id].
func TestTailTruncateHistory(t *testing.T) {
tester := newTester(t, 10)
defer tester.release()
tester.db.Close()
tester.db = New(tester.db.diskdb, &Config{StateHistory: 10})
head, err := tester.db.freezer.Ancients()
if err != nil {
t.Fatalf("Failed to obtain freezer head")
}
stored := rawdb.ReadPersistentStateID(tester.db.diskdb)
if head != stored {
t.Fatalf("Failed to truncate excess history object above, stored: %d, head: %d", stored, head)
}
}
// copyAccounts returns a deep-copied account set of the provided one. // copyAccounts returns a deep-copied account set of the provided one.
func copyAccounts(set map[common.Hash][]byte) map[common.Hash][]byte { func copyAccounts(set map[common.Hash][]byte) map[common.Hash][]byte {
copied := make(map[common.Hash][]byte, len(set)) copied := make(map[common.Hash][]byte, len(set))

View file

@ -172,37 +172,65 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
dl.lock.Lock() dl.lock.Lock()
defer dl.lock.Unlock() defer dl.lock.Unlock()
// Construct and store the state history first. If crash happens // Construct and store the state history first. If crash happens after storing
// after storing the state history but without flushing the // the state history but without flushing the corresponding states(journal),
// corresponding states(journal), the stored state history will // the stored state history will be truncated from head in the next restart.
// be truncated in the next restart. var (
overflow bool
oldest uint64
)
if dl.db.freezer != nil { if dl.db.freezer != nil {
err := writeHistory(dl.db.diskdb, dl.db.freezer, bottom, dl.db.config.StateHistory) err := writeHistory(dl.db.freezer, bottom)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Determine if the persisted history object has exceeded the configured
// limitation, set the overflow as true if so.
tail, err := dl.db.freezer.Tail()
if err != nil {
return nil, err
}
limit := dl.db.config.StateHistory
if limit != 0 && bottom.stateID()-tail > limit {
overflow = true
oldest = bottom.stateID() - limit + 1 // track the id of history **after truncation**
}
} }
// Mark the diskLayer as stale before applying any mutations on top. // Mark the diskLayer as stale before applying any mutations on top.
dl.stale = true dl.stale = true
// Store the root->id lookup afterwards. All stored lookups are // Store the root->id lookup afterwards. All stored lookups are identified
// identified by the **unique** state root. It's impossible that // by the **unique** state root. It's impossible that in the same chain
// in the same chain blocks are not adjacent but have the same // blocks are not adjacent but have the same root.
// root.
if dl.id == 0 { if dl.id == 0 {
rawdb.WriteStateID(dl.db.diskdb, dl.root, 0) rawdb.WriteStateID(dl.db.diskdb, dl.root, 0)
} }
rawdb.WriteStateID(dl.db.diskdb, bottom.rootHash(), bottom.stateID()) rawdb.WriteStateID(dl.db.diskdb, bottom.rootHash(), bottom.stateID())
// Construct a new disk layer by merging the nodes from the provided // Construct a new disk layer by merging the nodes from the provided diff
// diff layer, and flush the content in disk layer if there are too // layer, and flush the content in disk layer if there are too many nodes
// many nodes cached. The clean cache is inherited from the original // cached. The clean cache is inherited from the original disk layer.
// disk layer for reusing.
ndl := newDiskLayer(bottom.root, bottom.stateID(), dl.db, dl.cleans, dl.buffer.commit(bottom.nodes)) ndl := newDiskLayer(bottom.root, bottom.stateID(), dl.db, dl.cleans, dl.buffer.commit(bottom.nodes))
err := ndl.buffer.flush(ndl.db.diskdb, ndl.cleans, ndl.id, force)
// In a unique scenario where the ID of the oldest history object (after tail
// truncation) surpasses the persisted state ID, we take the necessary action
// of forcibly committing the cached dirty nodes to ensure that the persisted
// state ID remains higher.
if !force && rawdb.ReadPersistentStateID(dl.db.diskdb) < oldest {
force = true
}
if err := ndl.buffer.flush(ndl.db.diskdb, ndl.cleans, ndl.id, force); err != nil {
return nil, err
}
// To remove outdated history objects from the end, we set the 'tail' parameter
// to 'oldest-1' due to the offset between the freezer index and the history ID.
if overflow {
pruned, err := truncateFromTail(ndl.db.diskdb, ndl.db.freezer, oldest-1)
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.Debug("Pruned state history", "items", pruned, "tailid", oldest)
}
return ndl, nil return ndl, nil
} }

View file

@ -512,38 +512,28 @@ func readHistory(freezer *rawdb.ResettableFreezer, id uint64) (*history, error)
return &dec, nil return &dec, nil
} }
// writeHistory writes the state history with provided state set. After // writeHistory persists the state history with the provided state set.
// storing the corresponding state history, it will also prune the stale func writeHistory(freezer *rawdb.ResettableFreezer, dl *diffLayer) error {
// histories from the disk with the given threshold.
func writeHistory(db ethdb.KeyValueStore, freezer *rawdb.ResettableFreezer, dl *diffLayer, limit uint64) error {
// Short circuit if state set is not available. // Short circuit if state set is not available.
if dl.states == nil { if dl.states == nil {
return errors.New("state change set is not available") return errors.New("state change set is not available")
} }
var ( var (
err error
n int
start = time.Now() start = time.Now()
h = newHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states) history = newHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states)
) )
accountData, storageData, accountIndex, storageIndex := h.encode() accountData, storageData, accountIndex, storageIndex := history.encode()
dataSize := common.StorageSize(len(accountData) + len(storageData)) dataSize := common.StorageSize(len(accountData) + len(storageData))
indexSize := common.StorageSize(len(accountIndex) + len(storageIndex)) indexSize := common.StorageSize(len(accountIndex) + len(storageIndex))
// Write history data into five freezer table respectively. // Write history data into five freezer table respectively.
rawdb.WriteStateHistory(freezer, dl.stateID(), h.meta.encode(), accountIndex, storageIndex, accountData, storageData) rawdb.WriteStateHistory(freezer, dl.stateID(), history.meta.encode(), accountIndex, storageIndex, accountData, storageData)
// Prune stale state histories based on the config.
if limit != 0 && dl.stateID() > limit {
n, err = truncateFromTail(db, freezer, dl.stateID()-limit)
if err != nil {
return err
}
}
historyDataBytesMeter.Mark(int64(dataSize)) historyDataBytesMeter.Mark(int64(dataSize))
historyIndexBytesMeter.Mark(int64(indexSize)) historyIndexBytesMeter.Mark(int64(indexSize))
historyBuildTimeMeter.UpdateSince(start) historyBuildTimeMeter.UpdateSince(start)
log.Debug("Stored state history", "id", dl.stateID(), "block", dl.block, "data", dataSize, "index", indexSize, "pruned", n, "elapsed", common.PrettyDuration(time.Since(start))) log.Debug("Stored state history", "id", dl.stateID(), "block", dl.block, "data", dataSize, "index", indexSize, "elapsed", common.PrettyDuration(time.Since(start)))
return nil return nil
} }