mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Merge branch 'master' into gethclient_tracing_api
This commit is contained in:
commit
8f837abf6b
91 changed files with 2021 additions and 710 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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/
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
194
cmd/evm/internal/t8ntool/tx_iterator.go
Normal file
194
cmd/evm/internal/t8ntool/tx_iterator.go
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Dump any state to aid debugging
|
||||||
|
if dump {
|
||||||
|
dump := state.RawDump(nil)
|
||||||
|
result.State = &dump
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Test failed, mark as so and dump any state to aid debugging
|
// Test failed, mark as so
|
||||||
result.Pass, result.Error = false, err.Error()
|
result.Pass, result.Error = false, err.Error()
|
||||||
if dump {
|
|
||||||
dump := state.RawDump(nil)
|
|
||||||
result.State = &dump
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
results = append(results, *result)
|
results = append(results, *result)
|
||||||
|
|
|
||||||
|
|
@ -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
77
cmd/evm/testdata/30/README.txt
vendored
Normal 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
23
cmd/evm/testdata/30/alloc.json
vendored
Normal 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
23
cmd/evm/testdata/30/env.json
vendored
Normal 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
64
cmd/evm/testdata/30/exp.json
vendored
Normal 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
1
cmd/evm/testdata/30/txs.rlp
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"0xf8dbb8d903f8d601800285012a05f200833d090080830186a000f85bf85994095e7baea6a6c7c4c2dfeb977efac326af552d87f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010ae1a001a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d880a0fc12b67159a3567f8bdbc49e0be369a2e20e09d57a51c41310543a4128409464a02de0cfe5495c4f58ff60645ceda0afd67a4c90a70bc89fe207269435b35e5b67"
|
||||||
1
cmd/evm/testdata/30/txs_more.rlp
vendored
Normal file
1
cmd/evm/testdata/30/txs_more.rlp
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"0xf901adb86702f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904b8d903f8d601800285012a05f200833d090080830186a000f85bf85994095e7baea6a6c7c4c2dfeb977efac326af552d87f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010ae1a001a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d880a0fc12b67159a3567f8bdbc49e0be369a2e20e09d57a51c41310543a4128409464a02de0cfe5495c4f58ff60645ceda0afd67a4c90a70bc89fe207269435b35e5b67b86702f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9"
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ a data corruption.`,
|
||||||
utils.CacheFlag,
|
utils.CacheFlag,
|
||||||
utils.CacheDatabaseFlag,
|
utils.CacheDatabaseFlag,
|
||||||
}, utils.NetworkFlags, utils.DatabaseFlags),
|
}, utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
Description: `This command performs a database compaction.
|
Description: `This command performs a database compaction.
|
||||||
WARNING: This operation may take a very long time to finish, and may cause database
|
WARNING: This operation may take a very long time to finish, and may cause database
|
||||||
corruption if it is aborted during execution'!`,
|
corruption if it is aborted during execution'!`,
|
||||||
}
|
}
|
||||||
|
|
@ -130,7 +130,7 @@ corruption if it is aborted during execution'!`,
|
||||||
Flags: flags.Merge([]cli.Flag{
|
Flags: flags.Merge([]cli.Flag{
|
||||||
utils.SyncModeFlag,
|
utils.SyncModeFlag,
|
||||||
}, utils.NetworkFlags, utils.DatabaseFlags),
|
}, utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
Description: `This command deletes the specified database key from the database.
|
Description: `This command deletes the specified database key from the database.
|
||||||
WARNING: This is a low-level operation which may cause database corruption!`,
|
WARNING: This is a low-level operation which may cause database corruption!`,
|
||||||
}
|
}
|
||||||
dbPutCmd = &cli.Command{
|
dbPutCmd = &cli.Command{
|
||||||
|
|
@ -141,7 +141,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
|
||||||
Flags: flags.Merge([]cli.Flag{
|
Flags: flags.Merge([]cli.Flag{
|
||||||
utils.SyncModeFlag,
|
utils.SyncModeFlag,
|
||||||
}, utils.NetworkFlags, utils.DatabaseFlags),
|
}, utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
Description: `This command sets a given database key to the given value.
|
Description: `This command sets a given database key to the given value.
|
||||||
WARNING: This is a low-level operation which may cause database corruption!`,
|
WARNING: This is a low-level operation which may cause database corruption!`,
|
||||||
}
|
}
|
||||||
dbGetSlotsCmd = &cli.Command{
|
dbGetSlotsCmd = &cli.Command{
|
||||||
|
|
|
||||||
185
cmd/geth/logging_test.go
Normal file
185
cmd/geth/logging_test.go
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
159
cmd/geth/logtestcmd_active.go
Normal file
159
cmd/geth/logtestcmd_active.go
Normal 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 "" }
|
||||||
23
cmd/geth/logtestcmd_inactive.go
Normal file
23
cmd/geth/logtestcmd_inactive.go
Normal 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
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,8 +84,8 @@ In other words, this command does the snapshot to trie conversion.
|
||||||
Action: checkDanglingStorage,
|
Action: checkDanglingStorage,
|
||||||
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
|
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
Description: `
|
Description: `
|
||||||
geth snapshot check-dangling-storage <state-root> traverses the snap storage
|
geth snapshot check-dangling-storage <state-root> traverses the snap storage
|
||||||
data, and verifies that all snapshot storage data has a corresponding account.
|
data, and verifies that all snapshot storage data has a corresponding account.
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -96,7 +96,7 @@ data, and verifies that all snapshot storage data has a corresponding account.
|
||||||
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
|
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
Description: `
|
Description: `
|
||||||
geth snapshot inspect-account <address | hash> checks all snapshot layers and prints out
|
geth snapshot inspect-account <address | hash> checks all snapshot layers and prints out
|
||||||
information about the specified address.
|
information about the specified address.
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -125,7 +125,7 @@ geth snapshot traverse-rawstate <state-root>
|
||||||
will traverse the whole state from the given root and will abort if any referenced
|
will traverse the whole state from the given root and will abort if any referenced
|
||||||
trie node or contract code is missing. This command can be used for state integrity
|
trie node or contract code is missing. This command can be used for state integrity
|
||||||
verification. The default checking target is the HEAD state. It's basically identical
|
verification. The default checking target is the HEAD state. It's basically identical
|
||||||
to traverse-state, but the check granularity is smaller.
|
to traverse-state, but the check granularity is smaller.
|
||||||
|
|
||||||
It's also usable without snapshot enabled.
|
It's also usable without snapshot enabled.
|
||||||
`,
|
`,
|
||||||
|
|
@ -143,7 +143,7 @@ It's also usable without snapshot enabled.
|
||||||
}, utils.NetworkFlags, utils.DatabaseFlags),
|
}, utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
Description: `
|
Description: `
|
||||||
This command is semantically equivalent to 'geth dump', but uses the snapshots
|
This command is semantically equivalent to 'geth dump', but uses the snapshots
|
||||||
as the backend data source, making this command a lot faster.
|
as the backend data source, making this command a lot faster.
|
||||||
|
|
||||||
The argument is interpreted as block number or hash. If none is provided, the latest
|
The argument is interpreted as block number or hash. If none is provided, the latest
|
||||||
block is used.
|
block is used.
|
||||||
|
|
|
||||||
49
cmd/geth/testdata/logging/logtest-json.txt
vendored
Normal file
49
cmd/geth/testdata/logging/logtest-json.txt
vendored
Normal 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"}
|
||||||
49
cmd/geth/testdata/logging/logtest-logfmt.txt
vendored
Normal file
49
cmd/geth/testdata/logging/logtest-logfmt.txt
vendored
Normal 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
|
||||||
50
cmd/geth/testdata/logging/logtest-terminal.txt
vendored
Normal file
50
cmd/geth/testdata/logging/logtest-terminal.txt
vendored
Normal 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
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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,24 +343,23 @@ 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)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write state changes to db
|
block, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, b.txs, b.uncles, b.receipts, b.withdrawals)
|
||||||
root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number))
|
if err != nil {
|
||||||
if err != nil {
|
panic(err)
|
||||||
panic(fmt.Sprintf("state write error: %v", err))
|
|
||||||
}
|
|
||||||
if err = triedb.Commit(root, false); err != nil {
|
|
||||||
panic(fmt.Sprintf("trie write error: %v", err))
|
|
||||||
}
|
|
||||||
return block, b.receipts
|
|
||||||
}
|
}
|
||||||
return nil, nil
|
|
||||||
|
// Write state changes to db
|
||||||
|
root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number))
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("state write error: %v", err))
|
||||||
|
}
|
||||||
|
if err = triedb.Commit(root, false); err != nil {
|
||||||
|
panic(fmt.Sprintf("trie write error: %v", err))
|
||||||
|
}
|
||||||
|
return block, b.receipts
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(),
|
GasLimit: parent.GasLimit(),
|
||||||
Time: time - 10,
|
Number: new(big.Int).Add(parent.Number(), common.Big1),
|
||||||
Difficulty: parent.Difficulty(),
|
Time: time,
|
||||||
UncleHash: parent.UncleHash(),
|
|
||||||
}),
|
|
||||||
GasLimit: parent.GasLimit(),
|
|
||||||
Number: new(big.Int).Add(parent.Number(), common.Big1),
|
|
||||||
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.
|
||||||
config *params.ChainConfig
|
type chainMaker struct {
|
||||||
|
bottom *types.Block
|
||||||
|
engine consensus.Engine
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
@ -52,9 +54,8 @@ func TestGeneratePOSChain(t *testing.T) {
|
||||||
Difficulty: common.Big1,
|
Difficulty: common.Big1,
|
||||||
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()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
config.TerminalTotalDifficultyPassed = true
|
config.TerminalTotalDifficultyPassed = true
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -334,13 +334,18 @@ 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
|
||||||
for i := range data {
|
}
|
||||||
rlpHeaders = append(rlpHeaders, data[len(data)-1-i])
|
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 {
|
||||||
|
rlpHeaders = append(rlpHeaders, data[len(data)-1-i])
|
||||||
}
|
}
|
||||||
return rlpHeaders
|
return rlpHeaders
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,15 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -123,35 +123,35 @@ func TestFilters(t *testing.T) {
|
||||||
pragma solidity >=0.7.0 <0.9.0;
|
pragma solidity >=0.7.0 <0.9.0;
|
||||||
|
|
||||||
contract Logger {
|
contract Logger {
|
||||||
function log0() external {
|
function log0() external {
|
||||||
assembly {
|
assembly {
|
||||||
log0(0, 0)
|
log0(0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log1(uint t1) external {
|
function log1(uint t1) external {
|
||||||
assembly {
|
assembly {
|
||||||
log1(0, 0, t1)
|
log1(0, 0, t1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log2(uint t1, uint t2) external {
|
function log2(uint t1, uint t2) external {
|
||||||
assembly {
|
assembly {
|
||||||
log2(0, 0, t1, t2)
|
log2(0, 0, t1, t2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log3(uint t1, uint t2, uint t3) external {
|
function log3(uint t1, uint t2, uint t3) external {
|
||||||
assembly {
|
assembly {
|
||||||
log3(0, 0, t1, t2, t3)
|
log3(0, 0, t1, t2, t3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log4(uint t1, uint t2, uint t3, uint t4) external {
|
function log4(uint t1, uint t2, uint t3, uint t4) external {
|
||||||
assembly {
|
assembly {
|
||||||
log4(0, 0, t1, t2, t3, t4)
|
log4(0, 0, t1, t2, t3, t4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
bytecode = common.FromHex("608060405234801561001057600080fd5b50600436106100575760003560e01c80630aa731851461005c5780632a4c08961461006657806378b9a1f314610082578063c670f8641461009e578063c683d6a3146100ba575b600080fd5b6100646100d6565b005b610080600480360381019061007b9190610143565b6100dc565b005b61009c60048036038101906100979190610196565b6100e8565b005b6100b860048036038101906100b391906101d6565b6100f2565b005b6100d460048036038101906100cf9190610203565b6100fa565b005b600080a0565b808284600080a3505050565b8082600080a25050565b80600080a150565b80828486600080a450505050565b600080fd5b6000819050919050565b6101208161010d565b811461012b57600080fd5b50565b60008135905061013d81610117565b92915050565b60008060006060848603121561015c5761015b610108565b5b600061016a8682870161012e565b935050602061017b8682870161012e565b925050604061018c8682870161012e565b9150509250925092565b600080604083850312156101ad576101ac610108565b5b60006101bb8582860161012e565b92505060206101cc8582860161012e565b9150509250929050565b6000602082840312156101ec576101eb610108565b5b60006101fa8482850161012e565b91505092915050565b6000806000806080858703121561021d5761021c610108565b5b600061022b8782880161012e565b945050602061023c8782880161012e565b935050604061024d8782880161012e565b925050606061025e8782880161012e565b9150509295919450925056fea264697066735822122073a4b156f487e59970dc1ef449cc0d51467268f676033a17188edafcee861f9864736f6c63430008110033")
|
bytecode = common.FromHex("608060405234801561001057600080fd5b50600436106100575760003560e01c80630aa731851461005c5780632a4c08961461006657806378b9a1f314610082578063c670f8641461009e578063c683d6a3146100ba575b600080fd5b6100646100d6565b005b610080600480360381019061007b9190610143565b6100dc565b005b61009c60048036038101906100979190610196565b6100e8565b005b6100b860048036038101906100b391906101d6565b6100f2565b005b6100d460048036038101906100cf9190610203565b6100fa565b005b600080a0565b808284600080a3505050565b8082600080a25050565b80600080a150565b80828486600080a450505050565b600080fd5b6000819050919050565b6101208161010d565b811461012b57600080fd5b50565b60008135905061013d81610117565b92915050565b60008060006060848603121561015c5761015b610108565b5b600061016a8682870161012e565b935050602061017b8682870161012e565b925050604061018c8682870161012e565b9150509250925092565b600080604083850312156101ad576101ac610108565b5b60006101bb8582860161012e565b92505060206101cc8582860161012e565b9150509250929050565b6000602082840312156101ec576101eb610108565b5b60006101fa8482850161012e565b91505092915050565b6000806000806080858703121561021d5761021c610108565b5b600061022b8782880161012e565b945050602061023c8782880161012e565b935050604061024d8782880161012e565b925050606061025e8782880161012e565b9150509295919450925056fea264697066735822122073a4b156f487e59970dc1ef449cc0d51467268f676033a17188edafcee861f9864736f6c63430008110033")
|
||||||
|
|
@ -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",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,10 @@ type callContext struct {
|
||||||
|
|
||||||
// callLog is the result of LOG opCode
|
// callLog is the result of LOG opCode
|
||||||
type callLog struct {
|
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
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,8 @@
|
||||||
"0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb",
|
"0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb",
|
||||||
"0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb"
|
"0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb"
|
||||||
],
|
],
|
||||||
"data": "0x0000000000000000000000000000000000000000000000000000000000989680"
|
"data": "0x0000000000000000000000000000000000000000000000000000000000989680",
|
||||||
|
"position": "0x0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"value": "0x0",
|
"value": "0x0",
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,8 @@
|
||||||
"topics": [
|
"topics": [
|
||||||
"0x92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004"
|
"0x92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004"
|
||||||
],
|
],
|
||||||
"data": "0x00000000000000000000000001115b41bd2731353dd3e6abf44818fdc035aaf10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c1894130000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008861393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030"
|
"data": "0x00000000000000000000000001115b41bd2731353dd3e6abf44818fdc035aaf10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c1894130000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008861393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030",
|
||||||
|
"position": "0x0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"value": "0x0",
|
"value": "0x0",
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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
2
go.mod
|
|
@ -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
4
go.sum
|
|
@ -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=
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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!]
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -218,10 +218,9 @@ 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)
|
|
||||||
)
|
)
|
||||||
if len(logFile) > 0 {
|
if len(logFile) > 0 {
|
||||||
if err := validateLogLocation(filepath.Dir(logFile)); err != nil {
|
if err := validateLogLocation(filepath.Dir(logFile)); err != nil {
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
35
internal/reexec/reexec.go
Normal 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
|
||||||
|
}
|
||||||
14
internal/reexec/self_linux.go
Normal file
14
internal/reexec/self_linux.go
Normal 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"
|
||||||
|
}
|
||||||
32
internal/reexec/self_others.go
Normal file
32
internal/reexec/self_others.go
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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/",
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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...)
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,11 +96,15 @@ 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{
|
||||||
obj = &tester{
|
StateHistory: historyLimit,
|
||||||
|
CleanCacheSize: 256 * 1024,
|
||||||
|
DirtyCacheSize: 256 * 1024,
|
||||||
|
})
|
||||||
|
obj = &tester{
|
||||||
db: db,
|
db: db,
|
||||||
preimages: make(map[common.Hash]common.Address),
|
preimages: make(map[common.Hash]common.Address),
|
||||||
accounts: make(map[common.Hash][]byte),
|
accounts: make(map[common.Hash][]byte),
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
if err != nil {
|
// 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
|
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 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Debug("Pruned state history", "items", pruned, "tailid", oldest)
|
||||||
|
}
|
||||||
return ndl, nil
|
return ndl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
start = time.Now()
|
||||||
n int
|
history = newHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states)
|
||||||
start = time.Now()
|
|
||||||
h = 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue