diff --git a/.travis.yml b/.travis.yml
index 31c944641f..2ba3af9419 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,7 +25,7 @@ jobs:
before_install:
- export DOCKER_CLI_EXPERIMENTAL=enabled
script:
- - go run build/ci.go dockerx -platform "linux/amd64,linux/arm64" -upload ethereum/client-go
+ - go run build/ci.go dockerx -platform "linux/amd64,linux/arm64,linux/riscv64" -upload ethereum/client-go
# This builder does the Linux Azure uploads
- stage: build
diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go
index 81836b3717..2be6edd44f 100644
--- a/accounts/usbwallet/ledger.go
+++ b/accounts/usbwallet/ledger.go
@@ -338,8 +338,22 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction
return common.Address{}, nil, err
}
} else {
- if txrlp, err = rlp.EncodeToBytes([]interface{}{tx.Nonce(), tx.GasPrice(), tx.Gas(), tx.To(), tx.Value(), tx.Data(), chainID, big.NewInt(0), big.NewInt(0)}); err != nil {
- return common.Address{}, nil, err
+ if tx.Type() == types.DynamicFeeTxType {
+ if txrlp, err = rlp.EncodeToBytes([]interface{}{chainID, tx.Nonce(), tx.GasTipCap(), tx.GasFeeCap(), tx.Gas(), tx.To(), tx.Value(), tx.Data(), tx.AccessList()}); err != nil {
+ return common.Address{}, nil, err
+ }
+ // append type to transaction
+ txrlp = append([]byte{tx.Type()}, txrlp...)
+ } else if tx.Type() == types.AccessListTxType {
+ if txrlp, err = rlp.EncodeToBytes([]interface{}{chainID, tx.Nonce(), tx.GasPrice(), tx.Gas(), tx.To(), tx.Value(), tx.Data(), tx.AccessList()}); err != nil {
+ return common.Address{}, nil, err
+ }
+ // append type to transaction
+ txrlp = append([]byte{tx.Type()}, txrlp...)
+ } else if tx.Type() == types.LegacyTxType {
+ if txrlp, err = rlp.EncodeToBytes([]interface{}{tx.Nonce(), tx.GasPrice(), tx.Gas(), tx.To(), tx.Value(), tx.Data(), chainID, big.NewInt(0), big.NewInt(0)}); err != nil {
+ return common.Address{}, nil, err
+ }
}
}
payload := append(path, txrlp...)
@@ -353,7 +367,9 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction
// Chunk size selection to mitigate an underlying RLP deserialization issue on the ledger app.
// https://github.com/LedgerHQ/app-ethereum/issues/409
chunk := 255
- for ; len(payload)%chunk <= ledgerEip155Size; chunk-- {
+ if tx.Type() == types.LegacyTxType {
+ for ; len(payload)%chunk <= ledgerEip155Size; chunk-- {
+ }
}
for len(payload) > 0 {
@@ -381,8 +397,11 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction
if chainID == nil {
signer = new(types.HomesteadSigner)
} else {
- signer = types.NewEIP155Signer(chainID)
- signature[64] -= byte(chainID.Uint64()*2 + 35)
+ signer = types.LatestSignerForChainID(chainID)
+ // For non-legacy transactions, V is 0 or 1, no need to subtract here.
+ if tx.Type() == types.LegacyTxType {
+ signature[64] -= byte(chainID.Uint64()*2 + 35)
+ }
}
signed, err := tx.WithSignature(signer, signature)
if err != nil {
diff --git a/appveyor.yml b/appveyor.yml
index 92369537cd..1543211edc 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -24,7 +24,9 @@ for:
- image: Ubuntu
build_script:
- go run build/ci.go lint
- - go run build/ci.go generate -verify
+ - go run build/ci.go check_tidy
+ - go run build/ci.go check_generate
+ - go run build/ci.go check_baddeps
- go run build/ci.go install -dlgo
test_script:
- go run build/ci.go test -dlgo -short
diff --git a/beacon/blsync/client.go b/beacon/blsync/client.go
index 39a1c6ea76..3c93754d3d 100644
--- a/beacon/blsync/client.go
+++ b/beacon/blsync/client.go
@@ -17,25 +17,22 @@
package blsync
import (
- "strings"
-
"github.com/ethereum/go-ethereum/beacon/light"
"github.com/ethereum/go-ethereum/beacon/light/api"
"github.com/ethereum/go-ethereum/beacon/light/request"
"github.com/ethereum/go-ethereum/beacon/light/sync"
+ "github.com/ethereum/go-ethereum/beacon/params"
"github.com/ethereum/go-ethereum/beacon/types"
- "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/ethdb/memorydb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
- "github.com/urfave/cli/v2"
)
type Client struct {
urls []string
customHeader map[string]string
- chainConfig *lightClientConfig
+ config *params.ClientConfig
scheduler *request.Scheduler
blockSync *beaconBlockSync
engineRPC *rpc.Client
@@ -44,34 +41,18 @@ type Client struct {
engineClient *engineClient
}
-func NewClient(ctx *cli.Context) *Client {
- if !ctx.IsSet(utils.BeaconApiFlag.Name) {
- utils.Fatalf("Beacon node light client API URL not specified")
- }
- var (
- chainConfig = makeChainConfig(ctx)
- customHeader = make(map[string]string)
- )
- for _, s := range ctx.StringSlice(utils.BeaconApiHeaderFlag.Name) {
- kv := strings.Split(s, ":")
- if len(kv) != 2 {
- utils.Fatalf("Invalid custom API header entry: %s", s)
- }
- customHeader[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1])
- }
-
+func NewClient(config params.ClientConfig) *Client {
// create data structures
var (
db = memorydb.New()
- threshold = ctx.Int(utils.BeaconThresholdFlag.Name)
- committeeChain = light.NewCommitteeChain(db, chainConfig.ChainConfig, threshold, !ctx.Bool(utils.BeaconNoFilterFlag.Name))
- headTracker = light.NewHeadTracker(committeeChain, threshold)
+ committeeChain = light.NewCommitteeChain(db, &config.ChainConfig, config.Threshold, !config.NoFilter)
+ headTracker = light.NewHeadTracker(committeeChain, config.Threshold)
)
headSync := sync.NewHeadSync(headTracker, committeeChain)
// set up scheduler and sync modules
scheduler := request.NewScheduler()
- checkpointInit := sync.NewCheckpointInit(committeeChain, chainConfig.Checkpoint)
+ checkpointInit := sync.NewCheckpointInit(committeeChain, config.Checkpoint)
forwardSync := sync.NewForwardUpdateSync(committeeChain)
beaconBlockSync := newBeaconBlockSync(headTracker)
scheduler.RegisterTarget(headTracker)
@@ -83,9 +64,9 @@ func NewClient(ctx *cli.Context) *Client {
return &Client{
scheduler: scheduler,
- urls: ctx.StringSlice(utils.BeaconApiFlag.Name),
- customHeader: customHeader,
- chainConfig: &chainConfig,
+ urls: config.Apis,
+ customHeader: config.CustomHeader,
+ config: &config,
blockSync: beaconBlockSync,
}
}
@@ -97,7 +78,7 @@ func (c *Client) SetEngineRPC(engine *rpc.Client) {
func (c *Client) Start() error {
headCh := make(chan types.ChainHeadEvent, 16)
c.chainHeadSub = c.blockSync.SubscribeChainHead(headCh)
- c.engineClient = startEngineClient(c.chainConfig, c.engineRPC, headCh)
+ c.engineClient = startEngineClient(c.config, c.engineRPC, headCh)
c.scheduler.Start()
for _, url := range c.urls {
diff --git a/beacon/blsync/config.go b/beacon/blsync/config.go
deleted file mode 100644
index efc44b47d1..0000000000
--- a/beacon/blsync/config.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2022 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package blsync
-
-import (
- "github.com/ethereum/go-ethereum/beacon/types"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/urfave/cli/v2"
-)
-
-// lightClientConfig contains beacon light client configuration
-type lightClientConfig struct {
- *types.ChainConfig
- Checkpoint common.Hash
-}
-
-var (
- MainnetConfig = lightClientConfig{
- ChainConfig: (&types.ChainConfig{
- GenesisValidatorsRoot: common.HexToHash("0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"),
- GenesisTime: 1606824023,
- }).
- AddFork("GENESIS", 0, []byte{0, 0, 0, 0}).
- AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}).
- AddFork("BELLATRIX", 144896, []byte{2, 0, 0, 0}).
- AddFork("CAPELLA", 194048, []byte{3, 0, 0, 0}).
- AddFork("DENEB", 269568, []byte{4, 0, 0, 0}),
- Checkpoint: common.HexToHash("0x388be41594ec7d6a6894f18c73f3469f07e2c19a803de4755d335817ed8e2e5a"),
- }
-
- SepoliaConfig = lightClientConfig{
- ChainConfig: (&types.ChainConfig{
- GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"),
- GenesisTime: 1655733600,
- }).
- AddFork("GENESIS", 0, []byte{144, 0, 0, 105}).
- AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}).
- AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}).
- AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}).
- AddFork("DENEB", 132608, []byte{144, 0, 0, 115}),
- Checkpoint: common.HexToHash("0x1005a6d9175e96bfbce4d35b80f468e9bff0b674e1e861d16e09e10005a58e81"),
- }
-)
-
-func makeChainConfig(ctx *cli.Context) lightClientConfig {
- var config lightClientConfig
- customConfig := ctx.IsSet(utils.BeaconConfigFlag.Name)
- utils.CheckExclusive(ctx, utils.MainnetFlag, utils.SepoliaFlag, utils.BeaconConfigFlag)
- switch {
- case ctx.Bool(utils.MainnetFlag.Name):
- config = MainnetConfig
- case ctx.Bool(utils.SepoliaFlag.Name):
- config = SepoliaConfig
- default:
- if !customConfig {
- config = MainnetConfig
- }
- }
- // Genesis root and time should always be specified together with custom chain config
- if customConfig {
- if !ctx.IsSet(utils.BeaconGenesisRootFlag.Name) {
- utils.Fatalf("Custom beacon chain config is specified but genesis root is missing")
- }
- if !ctx.IsSet(utils.BeaconGenesisTimeFlag.Name) {
- utils.Fatalf("Custom beacon chain config is specified but genesis time is missing")
- }
- if !ctx.IsSet(utils.BeaconCheckpointFlag.Name) {
- utils.Fatalf("Custom beacon chain config is specified but checkpoint is missing")
- }
- config.ChainConfig = &types.ChainConfig{
- GenesisTime: ctx.Uint64(utils.BeaconGenesisTimeFlag.Name),
- }
- if c, err := hexutil.Decode(ctx.String(utils.BeaconGenesisRootFlag.Name)); err == nil && len(c) <= 32 {
- copy(config.GenesisValidatorsRoot[:len(c)], c)
- } else {
- utils.Fatalf("Invalid hex string", "beacon.genesis.gvroot", ctx.String(utils.BeaconGenesisRootFlag.Name), "error", err)
- }
- if err := config.ChainConfig.LoadForks(ctx.String(utils.BeaconConfigFlag.Name)); err != nil {
- utils.Fatalf("Could not load beacon chain config file", "file name", ctx.String(utils.BeaconConfigFlag.Name), "error", err)
- }
- } else {
- if ctx.IsSet(utils.BeaconGenesisRootFlag.Name) {
- utils.Fatalf("Genesis root is specified but custom beacon chain config is missing")
- }
- if ctx.IsSet(utils.BeaconGenesisTimeFlag.Name) {
- utils.Fatalf("Genesis time is specified but custom beacon chain config is missing")
- }
- }
- // Checkpoint is required with custom chain config and is optional with pre-defined config
- if ctx.IsSet(utils.BeaconCheckpointFlag.Name) {
- if c, err := hexutil.Decode(ctx.String(utils.BeaconCheckpointFlag.Name)); err == nil && len(c) <= 32 {
- copy(config.Checkpoint[:len(c)], c)
- } else {
- utils.Fatalf("Invalid hex string", "beacon.checkpoint", ctx.String(utils.BeaconCheckpointFlag.Name), "error", err)
- }
- }
- return config
-}
diff --git a/beacon/blsync/engineclient.go b/beacon/blsync/engineclient.go
index fb8f77f32b..c6569fdbde 100644
--- a/beacon/blsync/engineclient.go
+++ b/beacon/blsync/engineclient.go
@@ -23,6 +23,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/beacon/engine"
+ "github.com/ethereum/go-ethereum/beacon/params"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/common"
ctypes "github.com/ethereum/go-ethereum/core/types"
@@ -31,14 +32,14 @@ import (
)
type engineClient struct {
- config *lightClientConfig
+ config *params.ClientConfig
rpc *rpc.Client
rootCtx context.Context
cancelRoot context.CancelFunc
wg sync.WaitGroup
}
-func startEngineClient(config *lightClientConfig, rpc *rpc.Client, headCh <-chan types.ChainHeadEvent) *engineClient {
+func startEngineClient(config *params.ClientConfig, rpc *rpc.Client, headCh <-chan types.ChainHeadEvent) *engineClient {
ctx, cancel := context.WithCancel(context.Background())
ec := &engineClient{
config: config,
diff --git a/beacon/light/committee_chain.go b/beacon/light/committee_chain.go
index a8d032bb65..4fa87785c0 100644
--- a/beacon/light/committee_chain.go
+++ b/beacon/light/committee_chain.go
@@ -76,34 +76,32 @@ type CommitteeChain struct {
unixNano func() int64 // system clock (simulated clock in tests)
sigVerifier committeeSigVerifier // BLS sig verifier (dummy verifier in tests)
- config *types.ChainConfig
- signerThreshold int
+ config *params.ChainConfig
minimumUpdateScore types.UpdateScore
enforceTime bool // enforceTime specifies whether the age of a signed header should be checked
}
// NewCommitteeChain creates a new CommitteeChain.
-func NewCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool) *CommitteeChain {
+func NewCommitteeChain(db ethdb.KeyValueStore, config *params.ChainConfig, signerThreshold int, enforceTime bool) *CommitteeChain {
return newCommitteeChain(db, config, signerThreshold, enforceTime, blsVerifier{}, &mclock.System{}, func() int64 { return time.Now().UnixNano() })
}
// NewTestCommitteeChain creates a new CommitteeChain for testing.
-func NewTestCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool, clock *mclock.Simulated) *CommitteeChain {
+func NewTestCommitteeChain(db ethdb.KeyValueStore, config *params.ChainConfig, signerThreshold int, enforceTime bool, clock *mclock.Simulated) *CommitteeChain {
return newCommitteeChain(db, config, signerThreshold, enforceTime, dummyVerifier{}, clock, func() int64 { return int64(clock.Now()) })
}
// newCommitteeChain creates a new CommitteeChain with the option of replacing the
// clock source and signature verification for testing purposes.
-func newCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool, sigVerifier committeeSigVerifier, clock mclock.Clock, unixNano func() int64) *CommitteeChain {
+func newCommitteeChain(db ethdb.KeyValueStore, config *params.ChainConfig, signerThreshold int, enforceTime bool, sigVerifier committeeSigVerifier, clock mclock.Clock, unixNano func() int64) *CommitteeChain {
s := &CommitteeChain{
- committeeCache: lru.NewCache[uint64, syncCommittee](10),
- db: db,
- sigVerifier: sigVerifier,
- clock: clock,
- unixNano: unixNano,
- config: config,
- signerThreshold: signerThreshold,
- enforceTime: enforceTime,
+ committeeCache: lru.NewCache[uint64, syncCommittee](10),
+ db: db,
+ sigVerifier: sigVerifier,
+ clock: clock,
+ unixNano: unixNano,
+ config: config,
+ enforceTime: enforceTime,
minimumUpdateScore: types.UpdateScore{
SignerCount: uint32(signerThreshold),
SubPeriodIndex: params.SyncPeriodLength / 16,
@@ -507,7 +505,7 @@ func (s *CommitteeChain) verifySignedHeader(head types.SignedHeader) (bool, time
if committee == nil {
return false, age, nil
}
- if signingRoot, err := s.config.Forks.SigningRoot(head.Header); err == nil {
+ if signingRoot, err := s.config.Forks.SigningRoot(head.Header.Epoch(), head.Header.Hash()); err == nil {
return s.sigVerifier.verifySignature(committee, signingRoot, &head.Signature), age, nil
}
return false, age, nil
diff --git a/beacon/light/committee_chain_test.go b/beacon/light/committee_chain_test.go
index 57b6d7175c..17ba135905 100644
--- a/beacon/light/committee_chain_test.go
+++ b/beacon/light/committee_chain_test.go
@@ -31,15 +31,15 @@ var (
testGenesis = newTestGenesis()
testGenesis2 = newTestGenesis()
- tfBase = newTestForks(testGenesis, types.Forks{
- &types.Fork{Epoch: 0, Version: []byte{0}},
+ tfBase = newTestForks(testGenesis, params.Forks{
+ ¶ms.Fork{Epoch: 0, Version: []byte{0}},
})
- tfAlternative = newTestForks(testGenesis, types.Forks{
- &types.Fork{Epoch: 0, Version: []byte{0}},
- &types.Fork{Epoch: 0x700, Version: []byte{1}},
+ tfAlternative = newTestForks(testGenesis, params.Forks{
+ ¶ms.Fork{Epoch: 0, Version: []byte{0}},
+ ¶ms.Fork{Epoch: 0x700, Version: []byte{1}},
})
- tfAnotherGenesis = newTestForks(testGenesis2, types.Forks{
- &types.Fork{Epoch: 0, Version: []byte{0}},
+ tfAnotherGenesis = newTestForks(testGenesis2, params.Forks{
+ ¶ms.Fork{Epoch: 0, Version: []byte{0}},
})
tcBase = newTestCommitteeChain(nil, tfBase, true, 0, 10, 400, false)
@@ -226,13 +226,13 @@ type committeeChainTest struct {
t *testing.T
db *memorydb.Database
clock *mclock.Simulated
- config types.ChainConfig
+ config params.ChainConfig
signerThreshold int
enforceTime bool
chain *CommitteeChain
}
-func newCommitteeChainTest(t *testing.T, config types.ChainConfig, signerThreshold int, enforceTime bool) *committeeChainTest {
+func newCommitteeChainTest(t *testing.T, config params.ChainConfig, signerThreshold int, enforceTime bool) *committeeChainTest {
c := &committeeChainTest{
t: t,
db: memorydb.New(),
@@ -298,20 +298,20 @@ func (c *committeeChainTest) verifyRange(tc *testCommitteeChain, begin, end uint
c.verifySignedHeader(tc, float64(end)+1.5, false)
}
-func newTestGenesis() types.ChainConfig {
- var config types.ChainConfig
+func newTestGenesis() params.ChainConfig {
+ var config params.ChainConfig
rand.Read(config.GenesisValidatorsRoot[:])
return config
}
-func newTestForks(config types.ChainConfig, forks types.Forks) types.ChainConfig {
+func newTestForks(config params.ChainConfig, forks params.Forks) params.ChainConfig {
for _, fork := range forks {
config.AddFork(fork.Name, fork.Epoch, fork.Version)
}
return config
}
-func newTestCommitteeChain(parent *testCommitteeChain, config types.ChainConfig, newCommittees bool, begin, end int, signerCount int, finalizedHeader bool) *testCommitteeChain {
+func newTestCommitteeChain(parent *testCommitteeChain, config params.ChainConfig, newCommittees bool, begin, end int, signerCount int, finalizedHeader bool) *testCommitteeChain {
tc := &testCommitteeChain{
config: config,
}
@@ -337,7 +337,7 @@ type testPeriod struct {
type testCommitteeChain struct {
periods []testPeriod
- config types.ChainConfig
+ config params.ChainConfig
}
func (tc *testCommitteeChain) fillCommittees(begin, end int) {
diff --git a/beacon/light/test_helpers.go b/beacon/light/test_helpers.go
index f537d963a6..7bd19ca0ad 100644
--- a/beacon/light/test_helpers.go
+++ b/beacon/light/test_helpers.go
@@ -33,7 +33,7 @@ func GenerateTestCommittee() *types.SerializedSyncCommittee {
return s
}
-func GenerateTestUpdate(config *types.ChainConfig, period uint64, committee, nextCommittee *types.SerializedSyncCommittee, signerCount int, finalizedHeader bool) *types.LightClientUpdate {
+func GenerateTestUpdate(config *params.ChainConfig, period uint64, committee, nextCommittee *types.SerializedSyncCommittee, signerCount int, finalizedHeader bool) *types.LightClientUpdate {
update := new(types.LightClientUpdate)
update.NextSyncCommitteeRoot = nextCommittee.Root()
var attestedHeader types.Header
@@ -48,9 +48,9 @@ func GenerateTestUpdate(config *types.ChainConfig, period uint64, committee, nex
return update
}
-func GenerateTestSignedHeader(header types.Header, config *types.ChainConfig, committee *types.SerializedSyncCommittee, signatureSlot uint64, signerCount int) types.SignedHeader {
+func GenerateTestSignedHeader(header types.Header, config *params.ChainConfig, committee *types.SerializedSyncCommittee, signatureSlot uint64, signerCount int) types.SignedHeader {
bitmask := makeBitmask(signerCount)
- signingRoot, _ := config.Forks.SigningRoot(header)
+ signingRoot, _ := config.Forks.SigningRoot(header.Epoch(), header.Hash())
c, _ := dummyVerifier{}.deserializeSyncCommittee(committee)
return types.SignedHeader{
Header: header,
diff --git a/beacon/types/config.go b/beacon/params/config.go
similarity index 94%
rename from beacon/types/config.go
rename to beacon/params/config.go
index 7706e85f6c..be2a40f171 100644
--- a/beacon/types/config.go
+++ b/beacon/params/config.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see .
-package types
+package params
import (
"crypto/sha256"
@@ -39,81 +39,13 @@ const syncCommitteeDomain = 7
var knownForks = []string{"GENESIS", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB"}
-// Fork describes a single beacon chain fork and also stores the calculated
-// signature domain used after this fork.
-type Fork struct {
- // Name of the fork in the chain config (config.yaml) file
- Name string
-
- // Epoch when given fork version is activated
- Epoch uint64
-
- // Fork version, see https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types
- Version []byte
-
- // index in list of known forks or MaxInt if unknown
- knownIndex int
-
- // calculated by computeDomain, based on fork version and genesis validators root
- domain merkle.Value
-}
-
-// computeDomain returns the signature domain based on the given fork version
-// and genesis validator set root.
-func (f *Fork) computeDomain(genesisValidatorsRoot common.Hash) {
- var (
- hasher = sha256.New()
- forkVersion32 merkle.Value
- forkDataRoot merkle.Value
- )
- copy(forkVersion32[:], f.Version)
- hasher.Write(forkVersion32[:])
- hasher.Write(genesisValidatorsRoot[:])
- hasher.Sum(forkDataRoot[:0])
-
- f.domain[0] = syncCommitteeDomain
- copy(f.domain[4:], forkDataRoot[:28])
-}
-
-// Forks is the list of all beacon chain forks in the chain configuration.
-type Forks []*Fork
-
-// domain returns the signature domain for the given epoch (assumes that domains
-// have already been calculated).
-func (f Forks) domain(epoch uint64) (merkle.Value, error) {
- for i := len(f) - 1; i >= 0; i-- {
- if epoch >= f[i].Epoch {
- return f[i].domain, nil
- }
- }
- return merkle.Value{}, fmt.Errorf("unknown fork for epoch %d", epoch)
-}
-
-// SigningRoot calculates the signing root of the given header.
-func (f Forks) SigningRoot(header Header) (common.Hash, error) {
- domain, err := f.domain(header.Epoch())
- if err != nil {
- return common.Hash{}, err
- }
- var (
- signingRoot common.Hash
- headerHash = header.Hash()
- hasher = sha256.New()
- )
- hasher.Write(headerHash[:])
- hasher.Write(domain[:])
- hasher.Sum(signingRoot[:0])
-
- return signingRoot, nil
-}
-
-func (f Forks) Len() int { return len(f) }
-func (f Forks) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
-func (f Forks) Less(i, j int) bool {
- if f[i].Epoch != f[j].Epoch {
- return f[i].Epoch < f[j].Epoch
- }
- return f[i].knownIndex < f[j].knownIndex
+// ClientConfig contains beacon light client configuration.
+type ClientConfig struct {
+ ChainConfig
+ Apis []string
+ CustomHeader map[string]string
+ Threshold int
+ NoFilter bool
}
// ChainConfig contains the beacon chain configuration.
@@ -121,6 +53,7 @@ type ChainConfig struct {
GenesisTime uint64 // Unix timestamp of slot 0
GenesisValidatorsRoot common.Hash // Root hash of the genesis validator set, used for signature domain calculation
Forks Forks
+ Checkpoint common.Hash
}
// ForkAtEpoch returns the latest active fork at the given epoch.
@@ -202,3 +135,79 @@ func (c *ChainConfig) LoadForks(path string) error {
}
return nil
}
+
+// Fork describes a single beacon chain fork and also stores the calculated
+// signature domain used after this fork.
+type Fork struct {
+ // Name of the fork in the chain config (config.yaml) file
+ Name string
+
+ // Epoch when given fork version is activated
+ Epoch uint64
+
+ // Fork version, see https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types
+ Version []byte
+
+ // index in list of known forks or MaxInt if unknown
+ knownIndex int
+
+ // calculated by computeDomain, based on fork version and genesis validators root
+ domain merkle.Value
+}
+
+// computeDomain returns the signature domain based on the given fork version
+// and genesis validator set root.
+func (f *Fork) computeDomain(genesisValidatorsRoot common.Hash) {
+ var (
+ hasher = sha256.New()
+ forkVersion32 merkle.Value
+ forkDataRoot merkle.Value
+ )
+ copy(forkVersion32[:], f.Version)
+ hasher.Write(forkVersion32[:])
+ hasher.Write(genesisValidatorsRoot[:])
+ hasher.Sum(forkDataRoot[:0])
+
+ f.domain[0] = syncCommitteeDomain
+ copy(f.domain[4:], forkDataRoot[:28])
+}
+
+// Forks is the list of all beacon chain forks in the chain configuration.
+type Forks []*Fork
+
+// domain returns the signature domain for the given epoch (assumes that domains
+// have already been calculated).
+func (f Forks) domain(epoch uint64) (merkle.Value, error) {
+ for i := len(f) - 1; i >= 0; i-- {
+ if epoch >= f[i].Epoch {
+ return f[i].domain, nil
+ }
+ }
+ return merkle.Value{}, fmt.Errorf("unknown fork for epoch %d", epoch)
+}
+
+// SigningRoot calculates the signing root of the given header.
+func (f Forks) SigningRoot(epoch uint64, root common.Hash) (common.Hash, error) {
+ domain, err := f.domain(epoch)
+ if err != nil {
+ return common.Hash{}, err
+ }
+ var (
+ signingRoot common.Hash
+ hasher = sha256.New()
+ )
+ hasher.Write(root[:])
+ hasher.Write(domain[:])
+ hasher.Sum(signingRoot[:0])
+
+ return signingRoot, nil
+}
+
+func (f Forks) Len() int { return len(f) }
+func (f Forks) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
+func (f Forks) Less(i, j int) bool {
+ if f[i].Epoch != f[j].Epoch {
+ return f[i].Epoch < f[j].Epoch
+ }
+ return f[i].knownIndex < f[j].knownIndex
+}
diff --git a/beacon/params/networks.go b/beacon/params/networks.go
new file mode 100644
index 0000000000..5b00b27953
--- /dev/null
+++ b/beacon/params/networks.go
@@ -0,0 +1,56 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package params
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+)
+
+var (
+ MainnetLightConfig = (&ChainConfig{
+ GenesisValidatorsRoot: common.HexToHash("0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"),
+ GenesisTime: 1606824023,
+ Checkpoint: common.HexToHash("0x6509b691f4de4f7b083f2784938fd52f0e131675432b3fd85ea549af9aebd3d0"),
+ }).
+ AddFork("GENESIS", 0, []byte{0, 0, 0, 0}).
+ AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}).
+ AddFork("BELLATRIX", 144896, []byte{2, 0, 0, 0}).
+ AddFork("CAPELLA", 194048, []byte{3, 0, 0, 0}).
+ AddFork("DENEB", 269568, []byte{4, 0, 0, 0})
+
+ SepoliaLightConfig = (&ChainConfig{
+ GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"),
+ GenesisTime: 1655733600,
+ Checkpoint: common.HexToHash("0x456e85f5608afab3465a0580bff8572255f6d97af0c5f939e3f7536b5edb2d3f"),
+ }).
+ AddFork("GENESIS", 0, []byte{144, 0, 0, 105}).
+ AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}).
+ AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}).
+ AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}).
+ AddFork("DENEB", 132608, []byte{144, 0, 0, 115})
+
+ HoleskyLightConfig = (&ChainConfig{
+ GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"),
+ GenesisTime: 1695902400,
+ Checkpoint: common.HexToHash("0x6456a1317f54d4b4f2cb5bc9d153b5af0988fe767ef0609f0236cf29030bcff7"),
+ }).
+ AddFork("GENESIS", 0, []byte{1, 1, 112, 0}).
+ AddFork("ALTAIR", 0, []byte{2, 1, 112, 0}).
+ AddFork("BELLATRIX", 0, []byte{3, 1, 112, 0}).
+ AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}).
+ AddFork("DENEB", 29696, []byte{5, 1, 112, 0})
+)
diff --git a/build/ci.go b/build/ci.go
index 1765d750c2..754d88a86a 100644
--- a/build/ci.go
+++ b/build/ci.go
@@ -24,9 +24,14 @@ Usage: go run build/ci.go
Available commands are:
- install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables
- test [ -coverage ] [ packages... ] -- runs the tests
- lint -- runs certain pre-selected linters
+ lint -- runs certain pre-selected linters
+ check_tidy -- verifies that everything is 'go mod tidy'-ed
+ check_generate -- verifies that everything is 'go generate'-ed
+ check_baddeps -- verifies that certain dependencies are avoided
+
+ install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables
+ test [ -coverage ] [ packages... ] -- runs the tests
+
archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts
importkeys -- imports signing keys from env
debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package
@@ -39,17 +44,16 @@ package main
import (
"bytes"
- "crypto/sha256"
"encoding/base64"
"flag"
"fmt"
- "io"
"log"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
+ "slices"
"strings"
"time"
@@ -156,6 +160,12 @@ func main() {
doTest(os.Args[2:])
case "lint":
doLint(os.Args[2:])
+ case "check_tidy":
+ doCheckTidy()
+ case "check_generate":
+ doCheckGenerate()
+ case "check_baddeps":
+ doCheckBadDeps()
case "archive":
doArchive(os.Args[2:])
case "dockerx":
@@ -168,8 +178,6 @@ func main() {
doPurge(os.Args[2:])
case "sanitycheck":
doSanityCheck()
- case "generate":
- doGenerate()
default:
log.Fatal("unknown command ", os.Args[1])
}
@@ -219,8 +227,7 @@ func doInstall(cmdline []string) {
// Do the build!
for _, pkg := range packages {
- args := make([]string, len(gobuild.Args))
- copy(args, gobuild.Args)
+ args := slices.Clone(gobuild.Args)
args = append(args, "-o", executablePath(path.Base(pkg)))
args = append(args, pkg)
build.MustRun(&exec.Cmd{Path: gobuild.Path, Args: args, Env: gobuild.Env})
@@ -348,128 +355,93 @@ func downloadSpecTestFixtures(csdb *build.ChecksumDB, cachedir string) string {
return filepath.Join(cachedir, base)
}
-// hashAllSourceFiles iterates all files under the top-level project directory
-// computing the hash of each file (excluding files within the tests
-// subrepo)
-func hashAllSourceFiles() (map[string][32]byte, error) {
- res := make(map[string][32]byte)
- err := filepath.WalkDir(".", func(path string, d os.DirEntry, err error) error {
- if strings.HasPrefix(path, filepath.FromSlash("tests/testdata")) {
- return filepath.SkipDir
- }
- if !d.Type().IsRegular() {
- return nil
- }
- // open the file and hash it
- f, err := os.OpenFile(path, os.O_RDONLY, 0666)
- if err != nil {
- return err
- }
- hasher := sha256.New()
- if _, err := io.Copy(hasher, f); err != nil {
- return err
- }
- res[path] = [32]byte(hasher.Sum(nil))
- return nil
- })
+// doCheckTidy assets that the Go modules files are tidied already.
+func doCheckTidy() {
+ targets := []string{"go.mod", "go.sum"}
+
+ hashes, err := build.HashFiles(targets)
if err != nil {
- return nil, err
+ log.Fatalf("failed to hash go.mod/go.sum: %v", err)
}
- return res, nil
-}
+ build.MustRun(new(build.GoToolchain).Go("mod", "tidy"))
-// hashSourceFiles iterates the provided set of filepaths (relative to the top-level geth project directory)
-// computing the hash of each file.
-func hashSourceFiles(files []string) (map[string][32]byte, error) {
- res := make(map[string][32]byte)
- for _, filePath := range files {
- f, err := os.OpenFile(filePath, os.O_RDONLY, 0666)
- if err != nil {
- return nil, err
- }
- hasher := sha256.New()
- if _, err := io.Copy(hasher, f); err != nil {
- return nil, err
- }
- res[filePath] = [32]byte(hasher.Sum(nil))
- }
- return res, nil
-}
-
-// compareHashedFilesets compares two maps (key is relative file path to top-level geth directory, value is its hash)
-// and returns the list of file paths whose hashes differed.
-func compareHashedFilesets(preHashes map[string][32]byte, postHashes map[string][32]byte) []string {
- updates := []string{}
- for path, postHash := range postHashes {
- preHash, ok := preHashes[path]
- if !ok || preHash != postHash {
- updates = append(updates, path)
- }
- }
- return updates
-}
-
-func doGoModTidy() {
- targetFiles := []string{"go.mod", "go.sum"}
- preHashes, err := hashSourceFiles(targetFiles)
+ tidied, err := build.HashFiles(targets)
if err != nil {
- log.Fatal("failed to hash go.mod/go.sum", "err", err)
+ log.Fatalf("failed to rehash go.mod/go.sum: %v", err)
}
- tc := new(build.GoToolchain)
- c := tc.Go("mod", "tidy")
- build.MustRun(c)
- postHashes, err := hashSourceFiles(targetFiles)
- updates := compareHashedFilesets(preHashes, postHashes)
- for _, updatedFile := range updates {
- fmt.Fprintf(os.Stderr, "changed file %s\n", updatedFile)
- }
- if len(updates) != 0 {
- log.Fatal("go.sum and/or go.mod were updated by running 'go mod tidy'")
+ if updates := build.DiffHashes(hashes, tidied); len(updates) > 0 {
+ log.Fatalf("files changed on running 'go mod tidy': %v", updates)
}
+ fmt.Println("No untidy module files detected.")
}
-// doGenerate ensures that re-generating generated files does not cause
-// any mutations in the source file tree: i.e. all generated files were
-// updated and committed. Any stale generated files are updated.
-func doGenerate() {
+// doCheckGenerate ensures that re-generating generated files does not cause
+// any mutations in the source file tree.
+func doCheckGenerate() {
var (
- tc = new(build.GoToolchain)
cachedir = flag.String("cachedir", "./build/cache", "directory for caching binaries.")
- verify = flag.Bool("verify", false, "check whether any files are changed by go generate")
)
+ // Compute the origin hashes of all the files
+ var hashes map[string][32]byte
- protocPath := downloadProtoc(*cachedir)
- protocGenGoPath := downloadProtocGenGo(*cachedir)
-
- var preHashes map[string][32]byte
- if *verify {
- var err error
- preHashes, err = hashAllSourceFiles()
- if err != nil {
- log.Fatal("failed to compute map of source hashes", "err", err)
- }
+ var err error
+ hashes, err = build.HashFolder(".", []string{"tests/testdata", "build/cache"})
+ if err != nil {
+ log.Fatal("Error computing hashes", "err", err)
}
-
- c := tc.Go("generate", "./...")
+ // Run any go generate steps we might be missing
+ var (
+ protocPath = downloadProtoc(*cachedir)
+ protocGenGoPath = downloadProtocGenGo(*cachedir)
+ )
+ c := new(build.GoToolchain).Go("generate", "./...")
pathList := []string{filepath.Join(protocPath, "bin"), protocGenGoPath, os.Getenv("PATH")}
c.Env = append(c.Env, "PATH="+strings.Join(pathList, string(os.PathListSeparator)))
build.MustRun(c)
- if !*verify {
- return
- }
- // Check if files were changed.
- postHashes, err := hashAllSourceFiles()
+ // Check if generate file hashes have changed
+ generated, err := build.HashFolder(".", []string{"tests/testdata", "build/cache"})
if err != nil {
- log.Fatal("error computing source tree file hashes", "err", err)
+ log.Fatalf("Error re-computing hashes: %v", err)
}
- updates := compareHashedFilesets(preHashes, postHashes)
- for _, updatedFile := range updates {
- fmt.Fprintf(os.Stderr, "changed file %s\n", updatedFile)
+ updates := build.DiffHashes(hashes, generated)
+ for _, file := range updates {
+ log.Printf("File changed: %s", file)
}
if len(updates) != 0 {
log.Fatal("One or more generated files were updated by running 'go generate ./...'")
}
+ fmt.Println("No stale files detected.")
+}
+
+// doCheckBadDeps verifies whether certain unintended dependencies between some
+// packages leak into the codebase due to a refactor. This is not an exhaustive
+// list, rather something we build up over time at sensitive places.
+func doCheckBadDeps() {
+ baddeps := [][2]string{
+ // Rawdb tends to be a dumping ground for db utils, sometimes leaking the db itself
+ {"github.com/ethereum/go-ethereum/core/rawdb", "github.com/ethereum/go-ethereum/ethdb/leveldb"},
+ {"github.com/ethereum/go-ethereum/core/rawdb", "github.com/ethereum/go-ethereum/ethdb/pebbledb"},
+ }
+ tc := new(build.GoToolchain)
+
+ var failed bool
+ for _, rule := range baddeps {
+ out, err := tc.Go("list", "-deps", rule[0]).CombinedOutput()
+ if err != nil {
+ log.Fatalf("Failed to list '%s' dependencies: %v", rule[0], err)
+ }
+ for _, line := range strings.Split(string(out), "\n") {
+ if strings.TrimSpace(line) == rule[1] {
+ log.Printf("Found bad dependency '%s' -> '%s'", rule[0], rule[1])
+ failed = true
+ }
+ }
+ }
+ if failed {
+ log.Fatalf("Bad dependencies detected.")
+ }
+ fmt.Println("No bad dependencies detected.")
}
// doLint runs golangci-lint on requested packages.
@@ -486,8 +458,6 @@ func doLint(cmdline []string) {
linter := downloadLinter(*cachedir)
lflags := []string{"run", "--config", ".golangci.yml"}
build.MustRunCommandWithOutput(linter, append(lflags, packages...)...)
-
- doGoModTidy()
fmt.Println("You have achieved perfection.")
}
diff --git a/cmd/blsync/main.go b/cmd/blsync/main.go
index f9b8575edf..d74e1496cd 100644
--- a/cmd/blsync/main.go
+++ b/cmd/blsync/main.go
@@ -20,6 +20,7 @@ import (
"context"
"fmt"
"os"
+ "slices"
"github.com/ethereum/go-ethereum/beacon/blsync"
"github.com/ethereum/go-ethereum/cmd/utils"
@@ -33,7 +34,7 @@ import (
func main() {
app := flags.NewApp("beacon light syncer tool")
- app.Flags = flags.Merge([]cli.Flag{
+ app.Flags = slices.Concat([]cli.Flag{
utils.BeaconApiFlag,
utils.BeaconApiHeaderFlag,
utils.BeaconThresholdFlag,
@@ -45,6 +46,7 @@ func main() {
//TODO datadir for optional permanent database
utils.MainnetFlag,
utils.SepoliaFlag,
+ utils.HoleskyFlag,
utils.BlsyncApiFlag,
utils.BlsyncJWTSecretFlag,
},
@@ -68,7 +70,7 @@ func main() {
func sync(ctx *cli.Context) error {
// set up blsync
- client := blsync.NewClient(ctx)
+ client := blsync.NewClient(utils.MakeBeaconLightConfig(ctx))
client.SetEngineRPC(makeRPCClient(ctx))
client.Start()
diff --git a/cmd/devp2p/discv4cmd.go b/cmd/devp2p/discv4cmd.go
index 3b5400ca3a..8c48b3a557 100644
--- a/cmd/devp2p/discv4cmd.go
+++ b/cmd/devp2p/discv4cmd.go
@@ -21,6 +21,7 @@ import (
"fmt"
"net"
"net/http"
+ "slices"
"strconv"
"strings"
"time"
@@ -28,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/cmd/devp2p/internal/v4test"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/p2p/enode"
@@ -83,7 +83,7 @@ var (
Name: "listen",
Usage: "Runs a discovery node",
Action: discv4Listen,
- Flags: flags.Merge(discoveryNodeFlags, []cli.Flag{
+ Flags: slices.Concat(discoveryNodeFlags, []cli.Flag{
httpAddrFlag,
}),
}
@@ -91,7 +91,7 @@ var (
Name: "crawl",
Usage: "Updates a nodes.json file with random nodes found in the DHT",
Action: discv4Crawl,
- Flags: flags.Merge(discoveryNodeFlags, []cli.Flag{crawlTimeoutFlag, crawlParallelismFlag}),
+ Flags: slices.Concat(discoveryNodeFlags, []cli.Flag{crawlTimeoutFlag, crawlParallelismFlag}),
}
discv4TestCommand = &cli.Command{
Name: "test",
diff --git a/cmd/devp2p/discv5cmd.go b/cmd/devp2p/discv5cmd.go
index 0dac945269..2422ef6644 100644
--- a/cmd/devp2p/discv5cmd.go
+++ b/cmd/devp2p/discv5cmd.go
@@ -19,11 +19,11 @@ package main
import (
"errors"
"fmt"
+ "slices"
"time"
"github.com/ethereum/go-ethereum/cmd/devp2p/internal/v5test"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/urfave/cli/v2"
)
@@ -56,7 +56,7 @@ var (
Name: "crawl",
Usage: "Updates a nodes.json file with random nodes found in the DHT",
Action: discv5Crawl,
- Flags: flags.Merge(discoveryNodeFlags, []cli.Flag{
+ Flags: slices.Concat(discoveryNodeFlags, []cli.Flag{
crawlTimeoutFlag,
}),
}
diff --git a/cmd/evm/main.go b/cmd/evm/main.go
index 994684ab22..0d4471b8d5 100644
--- a/cmd/evm/main.go
+++ b/cmd/evm/main.go
@@ -21,6 +21,7 @@ import (
"fmt"
"math/big"
"os"
+ "slices"
"github.com/ethereum/go-ethereum/cmd/evm/internal/t8ntool"
"github.com/ethereum/go-ethereum/internal/debug"
@@ -254,7 +255,7 @@ var traceFlags = []cli.Flag{
var app = flags.NewApp("the evm command line interface")
func init() {
- app.Flags = flags.Merge(vmFlags, traceFlags, debug.Flags)
+ app.Flags = slices.Concat(vmFlags, traceFlags, debug.Flags)
app.Commands = []*cli.Command{
compileCommand,
disasmCommand,
diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go
index 235fed6630..8c382e6257 100644
--- a/cmd/evm/runner.go
+++ b/cmd/evm/runner.go
@@ -24,6 +24,7 @@ import (
"math/big"
"os"
goruntime "runtime"
+ "slices"
"testing"
"time"
@@ -50,7 +51,7 @@ var runCommand = &cli.Command{
Usage: "Run arbitrary evm binary",
ArgsUsage: "",
Description: `The run command runs arbitrary EVM code.`,
- Flags: flags.Merge(vmFlags, traceFlags),
+ Flags: slices.Concat(vmFlags, traceFlags),
}
// readGenesis will read the given JSON format genesis file and return
@@ -75,36 +76,53 @@ func readGenesis(genesisPath string) *core.Genesis {
}
type execStats struct {
- time time.Duration // The execution time.
- allocs int64 // The number of heap allocations during execution.
- bytesAllocated int64 // The cumulative number of bytes allocated during execution.
+ Time time.Duration `json:"time"` // The execution Time.
+ Allocs int64 `json:"allocs"` // The number of heap allocations during execution.
+ BytesAllocated int64 `json:"bytesAllocated"` // The cumulative number of bytes allocated during execution.
+ GasUsed uint64 `json:"gasUsed"` // the amount of gas used during execution
}
-func timedExec(bench bool, execFunc func() ([]byte, uint64, error)) (output []byte, gasLeft uint64, stats execStats, err error) {
+func timedExec(bench bool, execFunc func() ([]byte, uint64, error)) ([]byte, execStats, error) {
if bench {
+ // Do one warm-up run
+ output, gasUsed, err := execFunc()
result := testing.Benchmark(func(b *testing.B) {
for i := 0; i < b.N; i++ {
- output, gasLeft, err = execFunc()
+ haveOutput, haveGasUsed, haveErr := execFunc()
+ if !bytes.Equal(haveOutput, output) {
+ b.Fatalf("output differs, have\n%x\nwant%x\n", haveOutput, output)
+ }
+ if haveGasUsed != gasUsed {
+ b.Fatalf("gas differs, have %v want%v", haveGasUsed, gasUsed)
+ }
+ if haveErr != err {
+ b.Fatalf("err differs, have %v want%v", haveErr, err)
+ }
}
})
-
// Get the average execution time from the benchmarking result.
// There are other useful stats here that could be reported.
- stats.time = time.Duration(result.NsPerOp())
- stats.allocs = result.AllocsPerOp()
- stats.bytesAllocated = result.AllocedBytesPerOp()
- } else {
- var memStatsBefore, memStatsAfter goruntime.MemStats
- goruntime.ReadMemStats(&memStatsBefore)
- startTime := time.Now()
- output, gasLeft, err = execFunc()
- stats.time = time.Since(startTime)
- goruntime.ReadMemStats(&memStatsAfter)
- stats.allocs = int64(memStatsAfter.Mallocs - memStatsBefore.Mallocs)
- stats.bytesAllocated = int64(memStatsAfter.TotalAlloc - memStatsBefore.TotalAlloc)
+ stats := execStats{
+ Time: time.Duration(result.NsPerOp()),
+ Allocs: result.AllocsPerOp(),
+ BytesAllocated: result.AllocedBytesPerOp(),
+ GasUsed: gasUsed,
+ }
+ return output, stats, err
}
-
- return output, gasLeft, stats, err
+ var memStatsBefore, memStatsAfter goruntime.MemStats
+ goruntime.ReadMemStats(&memStatsBefore)
+ t0 := time.Now()
+ output, gasUsed, err := execFunc()
+ duration := time.Since(t0)
+ goruntime.ReadMemStats(&memStatsAfter)
+ stats := execStats{
+ Time: duration,
+ Allocs: int64(memStatsAfter.Mallocs - memStatsBefore.Mallocs),
+ BytesAllocated: int64(memStatsAfter.TotalAlloc - memStatsBefore.TotalAlloc),
+ GasUsed: gasUsed,
+ }
+ return output, stats, err
}
func runCmd(ctx *cli.Context) error {
@@ -264,12 +282,13 @@ func runCmd(ctx *cli.Context) error {
statedb.SetCode(receiver, code)
}
execFunc = func() ([]byte, uint64, error) {
- return runtime.Call(receiver, input, &runtimeConfig)
+ output, gasLeft, err := runtime.Call(receiver, input, &runtimeConfig)
+ return output, initialGas - gasLeft, err
}
}
bench := ctx.Bool(BenchFlag.Name)
- output, leftOverGas, stats, err := timedExec(bench, execFunc)
+ output, stats, err := timedExec(bench, execFunc)
if ctx.Bool(DumpFlag.Name) {
root, err := statedb.Commit(genesisConfig.Number, true)
@@ -299,7 +318,7 @@ func runCmd(ctx *cli.Context) error {
execution time: %v
allocations: %d
allocated bytes: %d
-`, initialGas-leftOverGas, stats.time, stats.allocs, stats.bytesAllocated)
+`, stats.GasUsed, stats.Time, stats.Allocs, stats.BytesAllocated)
}
if tracer == nil {
fmt.Printf("%#x\n", output)
diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go
index 4514367e8a..d0a0d3287c 100644
--- a/cmd/evm/staterunner.go
+++ b/cmd/evm/staterunner.go
@@ -27,26 +27,51 @@ import (
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
+ "github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/tests"
"github.com/urfave/cli/v2"
)
+var (
+ forkFlag = &cli.StringFlag{
+ Name: "statetest.fork",
+ Usage: "The hard-fork to run the test against",
+ Category: flags.VMCategory,
+ }
+ idxFlag = &cli.IntFlag{
+ Name: "statetest.index",
+ Usage: "The index of the subtest to run",
+ Category: flags.VMCategory,
+ Value: -1, // default to select all subtest indices
+ }
+ testNameFlag = &cli.StringFlag{
+ Name: "statetest.name",
+ Usage: "The name of the state test to run",
+ Category: flags.VMCategory,
+ }
+)
var stateTestCommand = &cli.Command{
Action: stateTestCmd,
Name: "statetest",
Usage: "Executes the given state tests. Filenames can be fed via standard input (batch mode) or as an argument (one-off execution).",
ArgsUsage: "",
+ Flags: []cli.Flag{
+ forkFlag,
+ idxFlag,
+ testNameFlag,
+ },
}
// StatetestResult contains the execution status after running a state test, any
// error that might have occurred and a dump of the final state if requested.
type StatetestResult struct {
- Name string `json:"name"`
- Pass bool `json:"pass"`
- Root *common.Hash `json:"stateRoot,omitempty"`
- Fork string `json:"fork"`
- Error string `json:"error,omitempty"`
- State *state.Dump `json:"state,omitempty"`
+ Name string `json:"name"`
+ Pass bool `json:"pass"`
+ Root *common.Hash `json:"stateRoot,omitempty"`
+ Fork string `json:"fork"`
+ Error string `json:"error,omitempty"`
+ State *state.Dump `json:"state,omitempty"`
+ BenchStats *execStats `json:"benchStats,omitempty"`
}
func stateTestCmd(ctx *cli.Context) error {
@@ -67,7 +92,7 @@ func stateTestCmd(ctx *cli.Context) error {
}
// Load the test content from the input file
if len(ctx.Args().First()) != 0 {
- return runStateTest(ctx.Args().First(), cfg, ctx.Bool(DumpFlag.Name))
+ return runStateTest(ctx, ctx.Args().First(), cfg, ctx.Bool(DumpFlag.Name), ctx.Bool(BenchFlag.Name))
}
// Read filenames from stdin and execute back-to-back
scanner := bufio.NewScanner(os.Stdin)
@@ -76,15 +101,48 @@ func stateTestCmd(ctx *cli.Context) error {
if len(fname) == 0 {
return nil
}
- if err := runStateTest(fname, cfg, ctx.Bool(DumpFlag.Name)); err != nil {
+ if err := runStateTest(ctx, fname, cfg, ctx.Bool(DumpFlag.Name), ctx.Bool(BenchFlag.Name)); err != nil {
return err
}
}
return nil
}
+type stateTestCase struct {
+ name string
+ test tests.StateTest
+ st tests.StateSubtest
+}
+
+// collectMatchedSubtests returns test cases which match against provided filtering CLI parameters
+func collectMatchedSubtests(ctx *cli.Context, testsByName map[string]tests.StateTest) []stateTestCase {
+ var res []stateTestCase
+ subtestName := ctx.String(testNameFlag.Name)
+ if subtestName != "" {
+ if subtest, ok := testsByName[subtestName]; ok {
+ testsByName := make(map[string]tests.StateTest)
+ testsByName[subtestName] = subtest
+ }
+ }
+ idx := ctx.Int(idxFlag.Name)
+ fork := ctx.String(forkFlag.Name)
+
+ for key, test := range testsByName {
+ for _, st := range test.Subtests() {
+ if idx != -1 && st.Index != idx {
+ continue
+ }
+ if fork != "" && st.Fork != fork {
+ continue
+ }
+ res = append(res, stateTestCase{name: key, st: st, test: test})
+ }
+ }
+ return res
+}
+
// runStateTest loads the state-test given by fname, and executes the test.
-func runStateTest(fname string, cfg vm.Config, dump bool) error {
+func runStateTest(ctx *cli.Context, fname string, cfg vm.Config, dump bool, bench bool) error {
src, err := os.ReadFile(fname)
if err != nil {
return err
@@ -94,31 +152,38 @@ func runStateTest(fname string, cfg vm.Config, dump bool) error {
return err
}
+ matchingTests := collectMatchedSubtests(ctx, testsByName)
+
// Iterate over all the tests, run them and aggregate the results
- results := make([]StatetestResult, 0, len(testsByName))
- for key, test := range testsByName {
- for _, st := range test.Subtests() {
- // Run the test and aggregate the result
- result := &StatetestResult{Name: key, Fork: st.Fork, Pass: true}
- test.Run(st, cfg, false, rawdb.HashScheme, func(err error, tstate *tests.StateTestState) {
- var root common.Hash
- if tstate.StateDB != nil {
- root = tstate.StateDB.IntermediateRoot(false)
- result.Root = &root
- fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
- if dump { // Dump any state to aid debugging
- cpy, _ := state.New(root, tstate.StateDB.Database())
- dump := cpy.RawDump(nil)
- result.State = &dump
- }
- }
- if err != nil {
- // Test failed, mark as so
- result.Pass, result.Error = false, err.Error()
+ var results []StatetestResult
+ for _, test := range matchingTests {
+ // Run the test and aggregate the result
+ result := &StatetestResult{Name: test.name, Fork: test.st.Fork, Pass: true}
+ test.test.Run(test.st, cfg, false, rawdb.HashScheme, func(err error, tstate *tests.StateTestState) {
+ var root common.Hash
+ if tstate.StateDB != nil {
+ root = tstate.StateDB.IntermediateRoot(false)
+ result.Root = &root
+ fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
+ if dump { // Dump any state to aid debugging
+ cpy, _ := state.New(root, tstate.StateDB.Database())
+ dump := cpy.RawDump(nil)
+ result.State = &dump
}
+ }
+ if err != nil {
+ // Test failed, mark as so
+ result.Pass, result.Error = false, err.Error()
+ }
+ })
+ if bench {
+ _, stats, _ := timedExec(true, func() ([]byte, uint64, error) {
+ _, _, gasUsed, _ := test.test.RunNoVerify(test.st, cfg, false, rawdb.HashScheme)
+ return nil, gasUsed, nil
})
- results = append(results, *result)
+ result.BenchStats = &stats
}
+ results = append(results, *result)
}
out, _ := json.MarshalIndent(results, "", " ")
fmt.Println(string(out))
diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
index d85e4a83c8..f6dc1cf4bf 100644
--- a/cmd/geth/chaincmd.go
+++ b/cmd/geth/chaincmd.go
@@ -22,6 +22,7 @@ import (
"fmt"
"os"
"runtime"
+ "slices"
"strconv"
"sync/atomic"
"time"
@@ -36,7 +37,6 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/internal/era"
- "github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
@@ -49,7 +49,7 @@ var (
Name: "init",
Usage: "Bootstrap and initialize a new genesis block",
ArgsUsage: "",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.CachePreimagesFlag,
utils.OverrideCancun,
utils.OverrideVerkle,
@@ -76,7 +76,7 @@ if one is set. Otherwise it prints the genesis from the datadir.`,
Name: "import",
Usage: "Import a blockchain file",
ArgsUsage: " ( ... ) ",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.CacheFlag,
utils.SyncModeFlag,
utils.GCModeFlag,
@@ -115,7 +115,7 @@ processing will proceed even if an individual RLP-file import failure occurs.`,
Name: "export",
Usage: "Export blockchain into file",
ArgsUsage: " [ ]",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.CacheFlag,
utils.SyncModeFlag,
}, utils.DatabaseFlags),
@@ -131,7 +131,7 @@ be gzipped.`,
Name: "import-history",
Usage: "Import an Era archive",
ArgsUsage: "",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.TxLookupLimitFlag,
},
utils.DatabaseFlags,
@@ -147,7 +147,7 @@ from Era archives.
Name: "export-history",
Usage: "Export blockchain history to Era archives",
ArgsUsage: " ",
- Flags: flags.Merge(utils.DatabaseFlags),
+ Flags: slices.Concat(utils.DatabaseFlags),
Description: `
The export-history command will export blocks and their corresponding receipts
into Era archives. Eras are typically packaged in steps of 8192 blocks.
@@ -158,7 +158,7 @@ into Era archives. Eras are typically packaged in steps of 8192 blocks.
Name: "import-preimages",
Usage: "Import the preimage database from an RLP stream",
ArgsUsage: "",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.CacheFlag,
utils.SyncModeFlag,
}, utils.DatabaseFlags),
@@ -173,7 +173,7 @@ It's deprecated, please use "geth db import" instead.
Name: "dump",
Usage: "Dump a specific block from storage",
ArgsUsage: "[? | ]",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.CacheFlag,
utils.IterativeOutputFlag,
utils.ExcludeCodeFlag,
diff --git a/cmd/geth/config.go b/cmd/geth/config.go
index 8282c80c41..17ed9fb606 100644
--- a/cmd/geth/config.go
+++ b/cmd/geth/config.go
@@ -23,6 +23,7 @@ import (
"os"
"reflect"
"runtime"
+ "slices"
"strings"
"unicode"
@@ -53,7 +54,7 @@ var (
Name: "dumpconfig",
Usage: "Export configuration values in a TOML format",
ArgsUsage: "",
- Flags: flags.Merge(nodeFlags, rpcFlags),
+ Flags: slices.Concat(nodeFlags, rpcFlags),
Description: `Export configuration values in TOML format (to stdout by default).`,
}
@@ -132,7 +133,7 @@ func defaultNodeConfig() node.Config {
cfg.Version = version.WithCommit(git.Commit, git.Date)
cfg.HTTPModules = append(cfg.HTTPModules, "eth")
cfg.WSModules = append(cfg.WSModules, "eth")
- cfg.IPCPath = "geth.ipc"
+ cfg.IPCPath = clientIdentifier + ".ipc"
return cfg
}
@@ -239,7 +240,7 @@ func makeFullNode(ctx *cli.Context) *node.Node {
// Start blsync mode.
srv := rpc.NewServer()
srv.RegisterName("engine", catalyst.NewConsensusAPI(eth))
- blsyncer := blsync.NewClient(ctx)
+ blsyncer := blsync.NewClient(utils.MakeBeaconLightConfig(ctx))
blsyncer.SetEngineRPC(rpc.DialInProc(srv))
stack.RegisterLifecycle(blsyncer)
} else {
diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go
index 2a59f0052f..bf38c86349 100644
--- a/cmd/geth/consolecmd.go
+++ b/cmd/geth/consolecmd.go
@@ -18,11 +18,11 @@ package main
import (
"fmt"
+ "slices"
"strings"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/console"
- "github.com/ethereum/go-ethereum/internal/flags"
"github.com/urfave/cli/v2"
)
@@ -33,7 +33,7 @@ var (
Action: localConsole,
Name: "console",
Usage: "Start an interactive JavaScript environment",
- Flags: flags.Merge(nodeFlags, rpcFlags, consoleFlags),
+ Flags: slices.Concat(nodeFlags, rpcFlags, consoleFlags),
Description: `
The Geth console is an interactive shell for the JavaScript runtime environment
which exposes a node admin interface as well as the Ðapp JavaScript API.
@@ -45,7 +45,7 @@ See https://geth.ethereum.org/docs/interacting-with-geth/javascript-console.`,
Name: "attach",
Usage: "Start an interactive JavaScript environment (connect to node)",
ArgsUsage: "[endpoint]",
- Flags: flags.Merge([]cli.Flag{utils.DataDirFlag, utils.HttpHeaderFlag}, consoleFlags),
+ Flags: slices.Concat([]cli.Flag{utils.DataDirFlag, utils.HttpHeaderFlag}, consoleFlags),
Description: `
The Geth console is an interactive shell for the JavaScript runtime environment
which exposes a node admin interface as well as the Ðapp JavaScript API.
@@ -58,7 +58,7 @@ This command allows to open a console on a running geth node.`,
Name: "js",
Usage: "(DEPRECATED) Execute the specified JavaScript files",
ArgsUsage: " [jsfile...]",
- Flags: flags.Merge(nodeFlags, consoleFlags),
+ Flags: slices.Concat(nodeFlags, consoleFlags),
Description: `
The JavaScript VM exposes a node admin interface as well as the Ðapp
JavaScript API. See https://geth.ethereum.org/docs/interacting-with-geth/javascript-console`,
diff --git a/cmd/geth/dbcmd.go b/cmd/geth/dbcmd.go
index 052ae0eab2..7622246050 100644
--- a/cmd/geth/dbcmd.go
+++ b/cmd/geth/dbcmd.go
@@ -22,6 +22,7 @@ import (
"os"
"os/signal"
"path/filepath"
+ "slices"
"strconv"
"strings"
"syscall"
@@ -36,7 +37,6 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
@@ -60,7 +60,7 @@ var (
Name: "removedb",
Usage: "Remove blockchain and state databases",
ArgsUsage: "",
- Flags: flags.Merge(utils.DatabaseFlags,
+ Flags: slices.Concat(utils.DatabaseFlags,
[]cli.Flag{removeStateDataFlag, removeChainDataFlag}),
Description: `
Remove blockchain and state databases`,
@@ -89,7 +89,7 @@ Remove blockchain and state databases`,
Action: inspect,
Name: "inspect",
ArgsUsage: " ",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Usage: "Inspect the storage size for each type of data in the database",
@@ -99,7 +99,7 @@ Remove blockchain and state databases`,
Action: checkStateContent,
Name: "check-state-content",
ArgsUsage: "",
- Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
+ Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Usage: "Verify that state data is cryptographically correct",
Description: `This command iterates the entire database for 32-byte keys, looking for rlp-encoded trie nodes.
For each trie node encountered, it checks that the key corresponds to the keccak256(value). If this is not true, this indicates
@@ -109,7 +109,7 @@ a data corruption.`,
Action: dbStats,
Name: "stats",
Usage: "Print leveldb statistics",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
}
@@ -117,7 +117,7 @@ a data corruption.`,
Action: dbCompact,
Name: "compact",
Usage: "Compact leveldb database. WARNING: May take a very long time",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
utils.CacheFlag,
utils.CacheDatabaseFlag,
@@ -131,7 +131,7 @@ corruption if it is aborted during execution'!`,
Name: "get",
Usage: "Show the value of a database key",
ArgsUsage: "",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: "This command looks up the specified database key from the database.",
@@ -141,7 +141,7 @@ corruption if it is aborted during execution'!`,
Name: "delete",
Usage: "Delete a database key (WARNING: may corrupt your database)",
ArgsUsage: "",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: `This command deletes the specified database key from the database.
@@ -152,7 +152,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "put",
Usage: "Set the value of a database key (WARNING: may corrupt your database)",
ArgsUsage: " ",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: `This command sets a given database key to the given value.
@@ -163,7 +163,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "dumptrie",
Usage: "Show the storage key/values of a given storage trie",
ArgsUsage: " ",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: "This command looks up the specified database key from the database.",
@@ -173,7 +173,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "freezer-index",
Usage: "Dump out the index of a specific freezer table",
ArgsUsage: " ",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: "This command displays information about the freezer index.",
@@ -183,7 +183,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "import",
Usage: "Imports leveldb-data from an exported RLP dump.",
ArgsUsage: " has .gz suffix, gzip compression will be used.",
ArgsUsage: " ",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: "Exports the specified chain data to an RLP encoded stream, optionally gzip-compressed.",
@@ -202,7 +202,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Action: showMetaData,
Name: "metadata",
Usage: "Shows metadata about the chain status.",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: "Shows metadata about the chain status.",
@@ -212,7 +212,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "inspect-history",
Usage: "Inspect the state history within block range",
ArgsUsage: " [OPTIONAL ]",
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag,
&cli.Uint64Flag{
Name: "start",
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index 2675a61675..10d4052737 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -20,6 +20,7 @@ package main
import (
"fmt"
"os"
+ "slices"
"sort"
"strconv"
"strings"
@@ -53,7 +54,7 @@ const (
var (
// flags that configure the node
- nodeFlags = flags.Merge([]cli.Flag{
+ nodeFlags = slices.Concat([]cli.Flag{
utils.IdentityFlag,
utils.UnlockedAccountFlag,
utils.PasswordFileFlag,
@@ -66,7 +67,7 @@ var (
utils.SmartCardDaemonPathFlag,
utils.OverrideCancun,
utils.OverrideVerkle,
- utils.EnablePersonal,
+ utils.EnablePersonal, // deprecated
utils.TxPoolLocalsFlag,
utils.TxPoolNoLocalsFlag,
utils.TxPoolJournalFlag,
@@ -251,7 +252,7 @@ func init() {
}
sort.Sort(cli.CommandsByName(app.Commands))
- app.Flags = flags.Merge(
+ app.Flags = slices.Concat(
nodeFlags,
rpcFlags,
consoleFlags,
diff --git a/cmd/geth/snapshot.go b/cmd/geth/snapshot.go
index 14c6826e1d..f0be52a0df 100644
--- a/cmd/geth/snapshot.go
+++ b/cmd/geth/snapshot.go
@@ -22,6 +22,7 @@ import (
"errors"
"fmt"
"os"
+ "slices"
"time"
"github.com/ethereum/go-ethereum/cmd/utils"
@@ -32,7 +33,6 @@ import (
"github.com/ethereum/go-ethereum/core/state/snapshot"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
@@ -50,7 +50,7 @@ var (
Usage: "Prune stale ethereum state data based on the snapshot",
ArgsUsage: "",
Action: pruneState,
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.BloomFilterSizeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: `
@@ -70,7 +70,7 @@ WARNING: it's only supported in hash mode(--state.scheme=hash)".
Usage: "Recalculate state hash based on the snapshot for verification",
ArgsUsage: "",
Action: verifyState,
- Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
+ Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: `
geth snapshot verify-state
will traverse the whole accounts and storages set based on the specified
@@ -83,7 +83,7 @@ In other words, this command does the snapshot to trie conversion.
Usage: "Check that there is no 'dangling' snap storage",
ArgsUsage: "",
Action: checkDanglingStorage,
- Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
+ Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: `
geth snapshot check-dangling-storage traverses the snap storage
data, and verifies that all snapshot storage data has a corresponding account.
@@ -94,7 +94,7 @@ data, and verifies that all snapshot storage data has a corresponding account.
Usage: "Check all snapshot layers for the specific account",
ArgsUsage: "",
Action: checkAccount,
- Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
+ Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: `
geth snapshot inspect-account checks all snapshot layers and prints out
information about the specified address.
@@ -105,7 +105,7 @@ information about the specified address.
Usage: "Traverse the state with given root hash and perform quick verification",
ArgsUsage: "",
Action: traverseState,
- Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
+ Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: `
geth snapshot traverse-state
will traverse the whole state from the given state root and will abort if any
@@ -120,7 +120,7 @@ It's also usable without snapshot enabled.
Usage: "Traverse the state with given root hash and perform detailed verification",
ArgsUsage: "",
Action: traverseRawState,
- Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
+ Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: `
geth snapshot traverse-rawstate
will traverse the whole state from the given root and will abort if any referenced
@@ -136,7 +136,7 @@ It's also usable without snapshot enabled.
Usage: "Dump a specific block from storage (same as 'geth dump' but using snapshots)",
ArgsUsage: "[? | ]",
Action: dumpState,
- Flags: flags.Merge([]cli.Flag{
+ Flags: slices.Concat([]cli.Flag{
utils.ExcludeCodeFlag,
utils.ExcludeStorageFlag,
utils.StartKeyFlag,
diff --git a/cmd/geth/verkle.go b/cmd/geth/verkle.go
index 9eb37fb5a8..6490f832af 100644
--- a/cmd/geth/verkle.go
+++ b/cmd/geth/verkle.go
@@ -22,11 +22,11 @@ import (
"errors"
"fmt"
"os"
+ "slices"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-verkle"
"github.com/urfave/cli/v2"
@@ -45,7 +45,7 @@ var (
Usage: "verify the conversion of a MPT into a verkle tree",
ArgsUsage: "",
Action: verifyVerkle,
- Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
+ Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: `
geth verkle verify
This command takes a root commitment and attempts to rebuild the tree.
@@ -56,7 +56,7 @@ This command takes a root commitment and attempts to rebuild the tree.
Usage: "Dump a verkle tree to a DOT file",
ArgsUsage: " [ ...]",
Action: expandVerkle,
- Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
+ Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: `
geth verkle dump [ ...]
This command will produce a dot file representing the tree, rooted at .
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index e98d5cc8e3..4eef66ebc6 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -40,6 +40,7 @@ import (
bparams "github.com/ethereum/go-ethereum/beacon/params"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/fdlimit"
+ "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/txpool/blobpool"
@@ -176,12 +177,6 @@ var (
Usage: "Custom node name",
Category: flags.NetworkingCategory,
}
- DocRootFlag = &flags.DirectoryFlag{
- Name: "docroot",
- Usage: "Document Root for HTTPClient file scheme",
- Value: flags.DirectoryString(flags.HomeDir()),
- Category: flags.APICategory,
- }
ExitWhenSyncedFlag = &cli.BoolFlag{
Name: "exitwhensynced",
Usage: "Exits after block synchronisation completes",
@@ -217,8 +212,7 @@ var (
Value: 0,
}
- defaultSyncMode = ethconfig.Defaults.SyncMode
- SnapshotFlag = &cli.BoolFlag{
+ SnapshotFlag = &cli.BoolFlag{
Name: "snapshot",
Usage: `Enables snapshot-database mode (default = enable)`,
Value: true,
@@ -250,10 +244,10 @@ var (
Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting",
Category: flags.EthCategory,
}
- SyncModeFlag = &flags.TextMarshalerFlag{
+ SyncModeFlag = &cli.StringFlag{
Name: "syncmode",
Usage: `Blockchain sync mode ("snap" or "full")`,
- Value: &defaultSyncMode,
+ Value: ethconfig.Defaults.SyncMode.String(),
Category: flags.StateCategory,
}
GCModeFlag = &cli.StringFlag{
@@ -326,7 +320,7 @@ var (
Usage: "Target EL engine API URL",
Category: flags.BeaconCategory,
}
- BlsyncJWTSecretFlag = &cli.StringFlag{
+ BlsyncJWTSecretFlag = &flags.DirectoryFlag{
Name: "blsync.jwtsecret",
Usage: "Path to a JWT secret to use for target engine API endpoint",
Category: flags.BeaconCategory,
@@ -741,11 +735,6 @@ var (
Value: node.DefaultConfig.BatchResponseMaxSize,
Category: flags.APICategory,
}
- EnablePersonal = &cli.BoolFlag{
- Name: "rpc.enabledeprecatedpersonal",
- Usage: "Enables the (deprecated) personal namespace",
- Category: flags.APICategory,
- }
// Network Settings
MaxPeersFlag = &cli.IntFlag{
@@ -1399,9 +1388,8 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
if ctx.IsSet(JWTSecretFlag.Name) {
cfg.JWTSecret = ctx.String(JWTSecretFlag.Name)
}
-
if ctx.IsSet(EnablePersonal.Name) {
- cfg.EnablePersonal = true
+ log.Warn(fmt.Sprintf("Option --%s is deprecated. The 'personal' RPC namespace has been removed.", EnablePersonal.Name))
}
if ctx.IsSet(ExternalSignerFlag.Name) {
@@ -1675,7 +1663,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
if ctx.IsSet(SyncTargetFlag.Name) {
cfg.SyncMode = downloader.FullSync // dev sync target forces full sync
} else if ctx.IsSet(SyncModeFlag.Name) {
- cfg.SyncMode = *flags.GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)
+ if err = cfg.SyncMode.UnmarshalText([]byte(ctx.String(SyncModeFlag.Name))); err != nil {
+ Fatalf("invalid --syncmode flag: %v", err)
+ }
}
if ctx.IsSet(NetworkIdFlag.Name) {
cfg.NetworkId = ctx.Uint64(NetworkIdFlag.Name)
@@ -1755,9 +1745,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.SnapshotCache = 0 // Disabled
}
}
- if ctx.IsSet(DocRootFlag.Name) {
- cfg.DocRoot = ctx.String(DocRootFlag.Name)
- }
if ctx.IsSet(VMEnableDebugFlag.Name) {
// TODO(fjl): force-enable this in --dev mode
cfg.EnablePreimageRecording = ctx.Bool(VMEnableDebugFlag.Name)
@@ -1903,6 +1890,81 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
}
}
+// MakeBeaconLightConfig constructs a beacon light client config based on the
+// related command line flags.
+func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig {
+ var config bparams.ClientConfig
+ customConfig := ctx.IsSet(BeaconConfigFlag.Name)
+ CheckExclusive(ctx, MainnetFlag, SepoliaFlag, HoleskyFlag, BeaconConfigFlag)
+ switch {
+ case ctx.Bool(MainnetFlag.Name):
+ config.ChainConfig = *bparams.MainnetLightConfig
+ case ctx.Bool(SepoliaFlag.Name):
+ config.ChainConfig = *bparams.SepoliaLightConfig
+ case ctx.Bool(HoleskyFlag.Name):
+ config.ChainConfig = *bparams.HoleskyLightConfig
+ default:
+ if !customConfig {
+ config.ChainConfig = *bparams.MainnetLightConfig
+ }
+ }
+ // Genesis root and time should always be specified together with custom chain config
+ if customConfig {
+ if !ctx.IsSet(BeaconGenesisRootFlag.Name) {
+ Fatalf("Custom beacon chain config is specified but genesis root is missing")
+ }
+ if !ctx.IsSet(BeaconGenesisTimeFlag.Name) {
+ Fatalf("Custom beacon chain config is specified but genesis time is missing")
+ }
+ if !ctx.IsSet(BeaconCheckpointFlag.Name) {
+ Fatalf("Custom beacon chain config is specified but checkpoint is missing")
+ }
+ config.ChainConfig = bparams.ChainConfig{
+ GenesisTime: ctx.Uint64(BeaconGenesisTimeFlag.Name),
+ }
+ if c, err := hexutil.Decode(ctx.String(BeaconGenesisRootFlag.Name)); err == nil && len(c) <= 32 {
+ copy(config.GenesisValidatorsRoot[:len(c)], c)
+ } else {
+ Fatalf("Invalid hex string", "beacon.genesis.gvroot", ctx.String(BeaconGenesisRootFlag.Name), "error", err)
+ }
+ configFile := ctx.String(BeaconConfigFlag.Name)
+ if err := config.ChainConfig.LoadForks(configFile); err != nil {
+ Fatalf("Could not load beacon chain config", "file", configFile, "error", err)
+ }
+ log.Info("Using custom beacon chain config", "file", configFile)
+ } else {
+ if ctx.IsSet(BeaconGenesisRootFlag.Name) {
+ Fatalf("Genesis root is specified but custom beacon chain config is missing")
+ }
+ if ctx.IsSet(BeaconGenesisTimeFlag.Name) {
+ Fatalf("Genesis time is specified but custom beacon chain config is missing")
+ }
+ }
+ // Checkpoint is required with custom chain config and is optional with pre-defined config
+ if ctx.IsSet(BeaconCheckpointFlag.Name) {
+ if c, err := hexutil.Decode(ctx.String(BeaconCheckpointFlag.Name)); err == nil && len(c) <= 32 {
+ copy(config.Checkpoint[:len(c)], c)
+ } else {
+ Fatalf("Invalid hex string", "beacon.checkpoint", ctx.String(BeaconCheckpointFlag.Name), "error", err)
+ }
+ }
+ config.Apis = ctx.StringSlice(BeaconApiFlag.Name)
+ if config.Apis == nil {
+ Fatalf("Beacon node light client API URL not specified")
+ }
+ config.CustomHeader = make(map[string]string)
+ for _, s := range ctx.StringSlice(BeaconApiHeaderFlag.Name) {
+ kv := strings.Split(s, ":")
+ if len(kv) != 2 {
+ Fatalf("Invalid custom API header entry: %s", s)
+ }
+ config.CustomHeader[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1])
+ }
+ config.Threshold = ctx.Int(BeaconThresholdFlag.Name)
+ config.NoFilter = ctx.Bool(BeaconNoFilterFlag.Name)
+ return config
+}
+
// SetDNSDiscoveryDefaults configures DNS discovery with the given URL if
// no URLs are set.
func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis common.Hash) {
diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go
index f145f605d6..6209516e05 100644
--- a/cmd/utils/flags_legacy.go
+++ b/cmd/utils/flags_legacy.go
@@ -153,6 +153,12 @@ var (
Usage: "Enable expensive metrics collection and reporting (deprecated)",
Category: flags.DeprecatedCategory,
}
+ // Deprecated Oct 2024
+ EnablePersonal = &cli.BoolFlag{
+ Name: "rpc.enabledeprecatedpersonal",
+ Usage: "This used to enable the 'personal' namespace.",
+ Category: flags.DeprecatedCategory,
+ }
)
// showDeprecated displays deprecated flags that will be soon removed from the codebase.
diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go
index 4ee19c7d4d..cdacf354a5 100644
--- a/consensus/beacon/consensus.go
+++ b/consensus/beacon/consensus.go
@@ -398,21 +398,25 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
if parent == nil {
return nil, fmt.Errorf("nil parent header for block %d", header.Number)
}
-
preTrie, err := state.Database().OpenTrie(parent.Root)
if err != nil {
return nil, fmt.Errorf("error opening pre-state tree root: %w", err)
}
-
vktPreTrie, okpre := preTrie.(*trie.VerkleTrie)
vktPostTrie, okpost := state.GetTrie().(*trie.VerkleTrie)
+
+ // The witness is only attached iff both parent and current block are
+ // using verkle tree.
if okpre && okpost {
if len(keys) > 0 {
- verkleProof, stateDiff, err := vktPreTrie.Proof(vktPostTrie, keys, vktPreTrie.FlatdbNodeResolver)
+ verkleProof, stateDiff, err := vktPreTrie.Proof(vktPostTrie, keys)
if err != nil {
return nil, fmt.Errorf("error generating verkle proof for block %d: %w", header.Number, err)
}
- block = block.WithWitness(&types.ExecutionWitness{StateDiff: stateDiff, VerkleProof: verkleProof})
+ block = block.WithWitness(&types.ExecutionWitness{
+ StateDiff: stateDiff,
+ VerkleProof: verkleProof,
+ })
}
}
}
diff --git a/console/bridge.go b/console/bridge.go
index 37578041ca..c1d7746c02 100644
--- a/console/bridge.go
+++ b/console/bridge.go
@@ -19,15 +19,12 @@ package console
import (
"encoding/json"
"errors"
- "fmt"
"io"
"reflect"
"strings"
"time"
"github.com/dop251/goja"
- "github.com/ethereum/go-ethereum/accounts/scwallet"
- "github.com/ethereum/go-ethereum/accounts/usbwallet"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/console/prompt"
"github.com/ethereum/go-ethereum/internal/jsre"
@@ -51,268 +48,6 @@ func newBridge(client *rpc.Client, prompter prompt.UserPrompter, printer io.Writ
}
}
-func getJeth(vm *goja.Runtime) *goja.Object {
- jeth := vm.Get("jeth")
- if jeth == nil {
- panic(vm.ToValue("jeth object does not exist"))
- }
- return jeth.ToObject(vm)
-}
-
-// NewAccount is a wrapper around the personal.newAccount RPC method that uses a
-// non-echoing password prompt to acquire the passphrase and executes the original
-// RPC method (saved in jeth.newAccount) with it to actually execute the RPC call.
-func (b *bridge) NewAccount(call jsre.Call) (goja.Value, error) {
- var (
- password string
- confirm string
- err error
- )
- switch {
- // No password was specified, prompt the user for it
- case len(call.Arguments) == 0:
- if password, err = b.prompter.PromptPassword("Passphrase: "); err != nil {
- return nil, err
- }
- if confirm, err = b.prompter.PromptPassword("Repeat passphrase: "); err != nil {
- return nil, err
- }
- if password != confirm {
- return nil, errors.New("passwords don't match")
- }
- // A single string password was specified, use that
- case len(call.Arguments) == 1 && call.Argument(0).ToString() != nil:
- password = call.Argument(0).ToString().String()
- default:
- return nil, errors.New("expected 0 or 1 string argument")
- }
- // Password acquired, execute the call and return
- newAccount, callable := goja.AssertFunction(getJeth(call.VM).Get("newAccount"))
- if !callable {
- return nil, errors.New("jeth.newAccount is not callable")
- }
- ret, err := newAccount(goja.Null(), call.VM.ToValue(password))
- if err != nil {
- return nil, err
- }
- return ret, nil
-}
-
-// OpenWallet is a wrapper around personal.openWallet which can interpret and
-// react to certain error messages, such as the Trezor PIN matrix request.
-func (b *bridge) OpenWallet(call jsre.Call) (goja.Value, error) {
- // Make sure we have a wallet specified to open
- if call.Argument(0).ToObject(call.VM).ClassName() != "String" {
- return nil, errors.New("first argument must be the wallet URL to open")
- }
- wallet := call.Argument(0)
-
- var passwd goja.Value
- if goja.IsUndefined(call.Argument(1)) || goja.IsNull(call.Argument(1)) {
- passwd = call.VM.ToValue("")
- } else {
- passwd = call.Argument(1)
- }
- // Open the wallet and return if successful in itself
- openWallet, callable := goja.AssertFunction(getJeth(call.VM).Get("openWallet"))
- if !callable {
- return nil, errors.New("jeth.openWallet is not callable")
- }
- val, err := openWallet(goja.Null(), wallet, passwd)
- if err == nil {
- return val, nil
- }
-
- // Wallet open failed, report error unless it's a PIN or PUK entry
- switch {
- case strings.HasSuffix(err.Error(), usbwallet.ErrTrezorPINNeeded.Error()):
- val, err = b.readPinAndReopenWallet(call)
- if err == nil {
- return val, nil
- }
- val, err = b.readPassphraseAndReopenWallet(call)
- if err != nil {
- return nil, err
- }
-
- case strings.HasSuffix(err.Error(), scwallet.ErrPairingPasswordNeeded.Error()):
- // PUK input requested, fetch from the user and call open again
- input, err := b.prompter.PromptPassword("Please enter the pairing password: ")
- if err != nil {
- return nil, err
- }
- passwd = call.VM.ToValue(input)
- if val, err = openWallet(goja.Null(), wallet, passwd); err != nil {
- if !strings.HasSuffix(err.Error(), scwallet.ErrPINNeeded.Error()) {
- return nil, err
- }
- // PIN input requested, fetch from the user and call open again
- input, err := b.prompter.PromptPassword("Please enter current PIN: ")
- if err != nil {
- return nil, err
- }
- if val, err = openWallet(goja.Null(), wallet, call.VM.ToValue(input)); err != nil {
- return nil, err
- }
- }
-
- case strings.HasSuffix(err.Error(), scwallet.ErrPINUnblockNeeded.Error()):
- // PIN unblock requested, fetch PUK and new PIN from the user
- var pukpin string
- input, err := b.prompter.PromptPassword("Please enter current PUK: ")
- if err != nil {
- return nil, err
- }
- pukpin = input
- input, err = b.prompter.PromptPassword("Please enter new PIN: ")
- if err != nil {
- return nil, err
- }
- pukpin += input
-
- if val, err = openWallet(goja.Null(), wallet, call.VM.ToValue(pukpin)); err != nil {
- return nil, err
- }
-
- case strings.HasSuffix(err.Error(), scwallet.ErrPINNeeded.Error()):
- // PIN input requested, fetch from the user and call open again
- input, err := b.prompter.PromptPassword("Please enter current PIN: ")
- if err != nil {
- return nil, err
- }
- if val, err = openWallet(goja.Null(), wallet, call.VM.ToValue(input)); err != nil {
- return nil, err
- }
-
- default:
- // Unknown error occurred, drop to the user
- return nil, err
- }
- return val, nil
-}
-
-func (b *bridge) readPassphraseAndReopenWallet(call jsre.Call) (goja.Value, error) {
- wallet := call.Argument(0)
- input, err := b.prompter.PromptPassword("Please enter your passphrase: ")
- if err != nil {
- return nil, err
- }
- openWallet, callable := goja.AssertFunction(getJeth(call.VM).Get("openWallet"))
- if !callable {
- return nil, errors.New("jeth.openWallet is not callable")
- }
- return openWallet(goja.Null(), wallet, call.VM.ToValue(input))
-}
-
-func (b *bridge) readPinAndReopenWallet(call jsre.Call) (goja.Value, error) {
- wallet := call.Argument(0)
- // Trezor PIN matrix input requested, display the matrix to the user and fetch the data
- fmt.Fprintf(b.printer, "Look at the device for number positions\n\n")
- fmt.Fprintf(b.printer, "7 | 8 | 9\n")
- fmt.Fprintf(b.printer, "--+---+--\n")
- fmt.Fprintf(b.printer, "4 | 5 | 6\n")
- fmt.Fprintf(b.printer, "--+---+--\n")
- fmt.Fprintf(b.printer, "1 | 2 | 3\n\n")
-
- input, err := b.prompter.PromptPassword("Please enter current PIN: ")
- if err != nil {
- return nil, err
- }
- openWallet, callable := goja.AssertFunction(getJeth(call.VM).Get("openWallet"))
- if !callable {
- return nil, errors.New("jeth.openWallet is not callable")
- }
- return openWallet(goja.Null(), wallet, call.VM.ToValue(input))
-}
-
-// UnlockAccount is a wrapper around the personal.unlockAccount RPC method that
-// uses a non-echoing password prompt to acquire the passphrase and executes the
-// original RPC method (saved in jeth.unlockAccount) with it to actually execute
-// the RPC call.
-func (b *bridge) UnlockAccount(call jsre.Call) (goja.Value, error) {
- if len(call.Arguments) < 1 {
- return nil, errors.New("usage: unlockAccount(account, [ password, duration ])")
- }
-
- account := call.Argument(0)
- // Make sure we have an account specified to unlock.
- if goja.IsUndefined(account) || goja.IsNull(account) || account.ExportType().Kind() != reflect.String {
- return nil, errors.New("first argument must be the account to unlock")
- }
-
- // If password is not given or is the null value, prompt the user for it.
- var passwd goja.Value
- if goja.IsUndefined(call.Argument(1)) || goja.IsNull(call.Argument(1)) {
- fmt.Fprintf(b.printer, "Unlock account %s\n", account)
- input, err := b.prompter.PromptPassword("Passphrase: ")
- if err != nil {
- return nil, err
- }
- passwd = call.VM.ToValue(input)
- } else {
- if call.Argument(1).ExportType().Kind() != reflect.String {
- return nil, errors.New("password must be a string")
- }
- passwd = call.Argument(1)
- }
-
- // Third argument is the duration how long the account should be unlocked.
- duration := goja.Null()
- if !goja.IsUndefined(call.Argument(2)) && !goja.IsNull(call.Argument(2)) {
- if !isNumber(call.Argument(2)) {
- return nil, errors.New("unlock duration must be a number")
- }
- duration = call.Argument(2)
- }
-
- // Send the request to the backend and return.
- unlockAccount, callable := goja.AssertFunction(getJeth(call.VM).Get("unlockAccount"))
- if !callable {
- return nil, errors.New("jeth.unlockAccount is not callable")
- }
- return unlockAccount(goja.Null(), account, passwd, duration)
-}
-
-// Sign is a wrapper around the personal.sign RPC method that uses a non-echoing password
-// prompt to acquire the passphrase and executes the original RPC method (saved in
-// jeth.sign) with it to actually execute the RPC call.
-func (b *bridge) Sign(call jsre.Call) (goja.Value, error) {
- if nArgs := len(call.Arguments); nArgs < 2 {
- return nil, errors.New("usage: sign(message, account, [ password ])")
- }
- var (
- message = call.Argument(0)
- account = call.Argument(1)
- passwd = call.Argument(2)
- )
-
- if goja.IsUndefined(message) || message.ExportType().Kind() != reflect.String {
- return nil, errors.New("first argument must be the message to sign")
- }
- if goja.IsUndefined(account) || account.ExportType().Kind() != reflect.String {
- return nil, errors.New("second argument must be the account to sign with")
- }
-
- // if the password is not given or null ask the user and ensure password is a string
- if goja.IsUndefined(passwd) || goja.IsNull(passwd) {
- fmt.Fprintf(b.printer, "Give password for account %s\n", account)
- input, err := b.prompter.PromptPassword("Password: ")
- if err != nil {
- return nil, err
- }
- passwd = call.VM.ToValue(input)
- } else if passwd.ExportType().Kind() != reflect.String {
- return nil, errors.New("third argument must be the password to unlock the account")
- }
-
- // Send the request to the backend and return
- sign, callable := goja.AssertFunction(getJeth(call.VM).Get("sign"))
- if !callable {
- return nil, errors.New("jeth.sign is not callable")
- }
- return sign(goja.Null(), message, account, passwd)
-}
-
// Sleep will block the console for the specified number of seconds.
func (b *bridge) Sleep(call jsre.Call) (goja.Value, error) {
if nArgs := len(call.Arguments); nArgs < 1 {
diff --git a/console/console.go b/console/console.go
index 5acb4cdccb..b5c77bd78f 100644
--- a/console/console.go
+++ b/console/console.go
@@ -142,7 +142,6 @@ func (c *Console) init(preload []string) error {
// Add bridge overrides for web3.js functionality.
c.jsre.Do(func(vm *goja.Runtime) {
c.initAdmin(vm, bridge)
- c.initPersonal(vm, bridge)
})
// Preload JavaScript files.
@@ -249,30 +248,6 @@ func (c *Console) initAdmin(vm *goja.Runtime, bridge *bridge) {
}
}
-// initPersonal redirects account-related API methods through the bridge.
-//
-// If the console is in interactive mode and the 'personal' API is available, override
-// the openWallet, unlockAccount, newAccount and sign methods since these require user
-// interaction. The original web3 callbacks are stored in 'jeth'. These will be called
-// by the bridge after the prompt and send the original web3 request to the backend.
-func (c *Console) initPersonal(vm *goja.Runtime, bridge *bridge) {
- personal := getObject(vm, "personal")
- if personal == nil || c.prompter == nil {
- return
- }
- log.Warn("Enabling deprecated personal namespace")
- jeth := vm.NewObject()
- vm.Set("jeth", jeth)
- jeth.Set("openWallet", personal.Get("openWallet"))
- jeth.Set("unlockAccount", personal.Get("unlockAccount"))
- jeth.Set("newAccount", personal.Get("newAccount"))
- jeth.Set("sign", personal.Get("sign"))
- personal.Set("openWallet", jsre.MakeCallback(vm, bridge.OpenWallet))
- personal.Set("unlockAccount", jsre.MakeCallback(vm, bridge.UnlockAccount))
- personal.Set("newAccount", jsre.MakeCallback(vm, bridge.NewAccount))
- personal.Set("sign", jsre.MakeCallback(vm, bridge.Sign))
-}
-
func (c *Console) clearHistory() {
c.history = nil
c.prompter.ClearHistory()
diff --git a/core/bench_test.go b/core/bench_test.go
index 639d36e9ae..6d518e8d3b 100644
--- a/core/bench_test.go
+++ b/core/bench_test.go
@@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/params"
)
@@ -80,9 +81,15 @@ var (
// value-transfer transaction with n bytes of extra data in each
// block.
func genValueTx(nbytes int) func(int, *BlockGen) {
+ // We can reuse the data for all transactions.
+ // During signing, the method tx.WithSignature(s, sig)
+ // performs:
+ // cpy := tx.inner.copy()
+ // cpy.setSignatureValues(signer.ChainID(), v, r, s)
+ // After this operation, the data can be reused by the caller.
+ data := make([]byte, nbytes)
return func(i int, gen *BlockGen) {
toaddr := common.Address{}
- data := make([]byte, nbytes)
gas, _ := IntrinsicGas(data, nil, false, false, false, false)
signer := gen.Signer()
gasPrice := big.NewInt(0)
@@ -173,18 +180,16 @@ func genUncles(i int, gen *BlockGen) {
func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
// Create the database in memory or in a temporary directory.
var db ethdb.Database
- var err error
if !disk {
db = rawdb.NewMemoryDatabase()
} else {
- dir := b.TempDir()
- db, err = rawdb.NewLevelDBDatabase(dir, 128, 128, "", false)
+ pdb, err := pebble.New(b.TempDir(), 128, 128, "", false)
if err != nil {
b.Fatalf("cannot create temporary database: %v", err)
}
+ db = rawdb.NewDatabase(pdb)
defer db.Close()
}
-
// Generate a chain of b.N blocks using the supplied block
// generator function.
gspec := &Genesis{
@@ -211,15 +216,27 @@ func BenchmarkChainRead_full_10k(b *testing.B) {
benchReadChain(b, true, 10000)
}
func BenchmarkChainRead_header_100k(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
benchReadChain(b, false, 100000)
}
func BenchmarkChainRead_full_100k(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
benchReadChain(b, true, 100000)
}
func BenchmarkChainRead_header_500k(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
benchReadChain(b, false, 500000)
}
func BenchmarkChainRead_full_500k(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
benchReadChain(b, true, 500000)
}
func BenchmarkChainWrite_header_10k(b *testing.B) {
@@ -235,9 +252,15 @@ func BenchmarkChainWrite_full_100k(b *testing.B) {
benchWriteChain(b, true, 100000)
}
func BenchmarkChainWrite_header_500k(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
benchWriteChain(b, false, 500000)
}
func BenchmarkChainWrite_full_500k(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
benchWriteChain(b, true, 500000)
}
@@ -281,11 +304,11 @@ func makeChainForBench(db ethdb.Database, genesis *Genesis, full bool, count uin
func benchWriteChain(b *testing.B, full bool, count uint64) {
genesis := &Genesis{Config: params.AllEthashProtocolChanges}
for i := 0; i < b.N; i++ {
- dir := b.TempDir()
- db, err := rawdb.NewLevelDBDatabase(dir, 128, 1024, "", false)
+ pdb, err := pebble.New(b.TempDir(), 1024, 128, "", false)
if err != nil {
- b.Fatalf("error opening database at %v: %v", dir, err)
+ b.Fatalf("error opening database: %v", err)
}
+ db := rawdb.NewDatabase(pdb)
makeChainForBench(db, genesis, full, count)
db.Close()
}
@@ -294,10 +317,12 @@ func benchWriteChain(b *testing.B, full bool, count uint64) {
func benchReadChain(b *testing.B, full bool, count uint64) {
dir := b.TempDir()
- db, err := rawdb.NewLevelDBDatabase(dir, 128, 1024, "", false)
+ pdb, err := pebble.New(dir, 1024, 128, "", false)
if err != nil {
- b.Fatalf("error opening database at %v: %v", dir, err)
+ b.Fatalf("error opening database: %v", err)
}
+ db := rawdb.NewDatabase(pdb)
+
genesis := &Genesis{Config: params.AllEthashProtocolChanges}
makeChainForBench(db, genesis, full, count)
db.Close()
@@ -308,15 +333,16 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
- db, err := rawdb.NewLevelDBDatabase(dir, 128, 1024, "", false)
+ pdb, err = pebble.New(dir, 1024, 128, "", false)
if err != nil {
- b.Fatalf("error opening database at %v: %v", dir, err)
+ b.Fatalf("error opening database: %v", err)
}
+ db = rawdb.NewDatabase(pdb)
+
chain, err := NewBlockChain(db, &cacheConfig, genesis, nil, ethash.NewFaker(), vm.Config{}, nil)
if err != nil {
b.Fatalf("error creating chain: %v", err)
}
-
for n := uint64(0); n < count; n++ {
header := chain.GetHeaderByNumber(n)
if full {
diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go
index 8a2dfe9f11..6c52d057ad 100644
--- a/core/blockchain_repair_test.go
+++ b/core/blockchain_repair_test.go
@@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/params"
)
@@ -1764,12 +1765,13 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
datadir := t.TempDir()
ancient := filepath.Join(datadir, "ancient")
- db, err := rawdb.Open(rawdb.OpenOptions{
- Directory: datadir,
- AncientsDirectory: ancient,
- })
+ pdb, err := pebble.New(datadir, 0, 0, "", false)
if err != nil {
- t.Fatalf("Failed to create persistent database: %v", err)
+ t.Fatalf("Failed to create persistent key-value database: %v", err)
+ }
+ db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
+ if err != nil {
+ t.Fatalf("Failed to create persistent freezer database: %v", err)
}
defer db.Close() // Might double close, should be fine
@@ -1848,12 +1850,13 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
chain.stopWithoutSaving()
// Start a new blockchain back up and see where the repair leads us
- db, err = rawdb.Open(rawdb.OpenOptions{
- Directory: datadir,
- AncientsDirectory: ancient,
- })
+ pdb, err = pebble.New(datadir, 0, 0, "", false)
if err != nil {
- t.Fatalf("Failed to reopen persistent database: %v", err)
+ t.Fatalf("Failed to reopen persistent key-value database: %v", err)
+ }
+ db, err = rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
+ if err != nil {
+ t.Fatalf("Failed to reopen persistent freezer database: %v", err)
}
defer db.Close()
@@ -1912,12 +1915,13 @@ func testIssue23496(t *testing.T, scheme string) {
datadir := t.TempDir()
ancient := filepath.Join(datadir, "ancient")
- db, err := rawdb.Open(rawdb.OpenOptions{
- Directory: datadir,
- AncientsDirectory: ancient,
- })
+ pdb, err := pebble.New(datadir, 0, 0, "", false)
if err != nil {
- t.Fatalf("Failed to create persistent database: %v", err)
+ t.Fatalf("Failed to create persistent key-value database: %v", err)
+ }
+ db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
+ if err != nil {
+ t.Fatalf("Failed to create persistent freezer database: %v", err)
}
defer db.Close() // Might double close, should be fine
@@ -1969,12 +1973,13 @@ func testIssue23496(t *testing.T, scheme string) {
chain.stopWithoutSaving()
// Start a new blockchain back up and see where the repair leads us
- db, err = rawdb.Open(rawdb.OpenOptions{
- Directory: datadir,
- AncientsDirectory: ancient,
- })
+ pdb, err = pebble.New(datadir, 0, 0, "", false)
if err != nil {
- t.Fatalf("Failed to reopen persistent database: %v", err)
+ t.Fatalf("Failed to reopen persistent key-value database: %v", err)
+ }
+ db, err = rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
+ if err != nil {
+ t.Fatalf("Failed to reopen persistent freezer database: %v", err)
}
defer db.Close()
diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go
index b72de33896..424854b2bf 100644
--- a/core/blockchain_sethead_test.go
+++ b/core/blockchain_sethead_test.go
@@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/triedb"
"github.com/ethereum/go-ethereum/triedb/hashdb"
@@ -1968,12 +1969,13 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
datadir := t.TempDir()
ancient := filepath.Join(datadir, "ancient")
- db, err := rawdb.Open(rawdb.OpenOptions{
- Directory: datadir,
- AncientsDirectory: ancient,
- })
+ pdb, err := pebble.New(datadir, 0, 0, "", false)
if err != nil {
- t.Fatalf("Failed to create persistent database: %v", err)
+ t.Fatalf("Failed to create persistent key-value database: %v", err)
+ }
+ db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
+ if err != nil {
+ t.Fatalf("Failed to create persistent freezer database: %v", err)
}
defer db.Close()
diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go
index 120977f222..1a6fe38af6 100644
--- a/core/blockchain_snapshot_test.go
+++ b/core/blockchain_snapshot_test.go
@@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/params"
)
@@ -65,12 +66,13 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo
datadir := t.TempDir()
ancient := filepath.Join(datadir, "ancient")
- db, err := rawdb.Open(rawdb.OpenOptions{
- Directory: datadir,
- AncientsDirectory: ancient,
- })
+ pdb, err := pebble.New(datadir, 0, 0, "", false)
if err != nil {
- t.Fatalf("Failed to create persistent database: %v", err)
+ t.Fatalf("Failed to create persistent key-value database: %v", err)
+ }
+ db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
+ if err != nil {
+ t.Fatalf("Failed to create persistent freezer database: %v", err)
}
// Initialize a fresh chain
var (
@@ -255,12 +257,13 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) {
chain.triedb.Close()
// Start a new blockchain back up and see where the repair leads us
- newdb, err := rawdb.Open(rawdb.OpenOptions{
- Directory: snaptest.datadir,
- AncientsDirectory: snaptest.ancient,
- })
+ pdb, err := pebble.New(snaptest.datadir, 0, 0, "", false)
if err != nil {
- t.Fatalf("Failed to reopen persistent database: %v", err)
+ t.Fatalf("Failed to create persistent key-value database: %v", err)
+ }
+ newdb, err := rawdb.NewDatabaseWithFreezer(pdb, snaptest.ancient, "", false)
+ if err != nil {
+ t.Fatalf("Failed to create persistent freezer database: %v", err)
}
defer newdb.Close()
diff --git a/core/blockchain_test.go b/core/blockchain_test.go
index 05629cd19f..dc391bb520 100644
--- a/core/blockchain_test.go
+++ b/core/blockchain_test.go
@@ -29,7 +29,6 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/ethash"
@@ -40,6 +39,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
"github.com/holiman/uint256"
@@ -2663,12 +2663,13 @@ func testSideImportPrunedBlocks(t *testing.T, scheme string) {
datadir := t.TempDir()
ancient := path.Join(datadir, "ancient")
- db, err := rawdb.Open(rawdb.OpenOptions{
- Directory: datadir,
- AncientsDirectory: ancient,
- })
+ pdb, err := pebble.New(datadir, 0, 0, "", false)
if err != nil {
- t.Fatalf("Failed to create persistent database: %v", err)
+ t.Fatalf("Failed to create persistent key-value database: %v", err)
+ }
+ db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
+ if err != nil {
+ t.Fatalf("Failed to create persistent freezer database: %v", err)
}
defer db.Close()
@@ -4231,36 +4232,3 @@ func TestPragueRequests(t *testing.T) {
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
}
}
-
-func BenchmarkReorg(b *testing.B) {
- chainLength := b.N
-
- dir := b.TempDir()
- db, err := rawdb.NewLevelDBDatabase(dir, 128, 128, "", false)
- if err != nil {
- b.Fatalf("cannot create temporary database: %v", err)
- }
- defer db.Close()
- gspec := &Genesis{
- Config: params.TestChainConfig,
- Alloc: types.GenesisAlloc{benchRootAddr: {Balance: math.BigPow(2, 254)}},
- }
- blockchain, _ := NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
- defer blockchain.Stop()
-
- // Insert an easy and a difficult chain afterwards
- easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), db, chainLength, genValueTx(50000))
- diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), db, chainLength, genValueTx(50000))
-
- if _, err := blockchain.InsertChain(easyBlocks); err != nil {
- b.Fatalf("failed to insert easy chain: %v", err)
- }
- b.ResetTimer()
- if _, err := blockchain.InsertChain(diffBlocks); err != nil {
- b.Fatalf("failed to insert difficult chain: %v", err)
- }
-}
-
-// Master: BenchmarkReorg-8 10000 899591 ns/op 820154 B/op 1440 allocs/op 1549443072 bytes of heap used
-// WithoutOldChain: BenchmarkReorg-8 10000 1147281 ns/op 943163 B/op 1564 allocs/op 1163870208 bytes of heap used
-// WithoutNewChain: BenchmarkReorg-8 10000 1018922 ns/op 943580 B/op 1564 allocs/op 1171890176 bytes of heap used
diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go
index 0b9dbe1335..0e986f66e0 100644
--- a/core/rawdb/accessors_chain_test.go
+++ b/core/rawdb/accessors_chain_test.go
@@ -649,11 +649,15 @@ func makeTestBlocks(nblock int, txsPerBlock int) []*types.Block {
// makeTestReceipts creates fake receipts for the ancient write benchmark.
func makeTestReceipts(n int, nPerBlock int) []types.Receipts {
receipts := make([]*types.Receipt, nPerBlock)
+ var logs []*types.Log
+ for i := 0; i < 5; i++ {
+ logs = append(logs, new(types.Log))
+ }
for i := 0; i < len(receipts); i++ {
receipts[i] = &types.Receipt{
Status: types.ReceiptStatusSuccessful,
CumulativeGasUsed: 0x888888888,
- Logs: make([]*types.Log, 5),
+ Logs: logs,
}
}
allReceipts := make([]types.Receipts, n)
diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go
index 78dba000fc..1bee455503 100644
--- a/core/rawdb/accessors_indexes_test.go
+++ b/core/rawdb/accessors_indexes_test.go
@@ -35,17 +35,17 @@ var newTestHasher = blocktest.NewHasher
func TestLookupStorage(t *testing.T) {
tests := []struct {
name string
- writeTxLookupEntriesByBlock func(ethdb.Writer, *types.Block)
+ writeTxLookupEntriesByBlock func(ethdb.KeyValueWriter, *types.Block)
}{
{
"DatabaseV6",
- func(db ethdb.Writer, block *types.Block) {
+ func(db ethdb.KeyValueWriter, block *types.Block) {
WriteTxLookupEntriesByBlock(db, block)
},
},
{
"DatabaseV4-V5",
- func(db ethdb.Writer, block *types.Block) {
+ func(db ethdb.KeyValueWriter, block *types.Block) {
for _, tx := range block.Transactions() {
db.Put(txLookupKey(tx.Hash()), block.Hash().Bytes())
}
@@ -53,7 +53,7 @@ func TestLookupStorage(t *testing.T) {
},
{
"DatabaseV3",
- func(db ethdb.Writer, block *types.Block) {
+ func(db ethdb.KeyValueWriter, block *types.Block) {
for index, tx := range block.Transactions() {
entry := LegacyTxLookupEntry{
BlockHash: block.Hash(),
diff --git a/core/rawdb/database.go b/core/rawdb/database.go
index e48e523f9e..53418d1646 100644
--- a/core/rawdb/database.go
+++ b/core/rawdb/database.go
@@ -27,9 +27,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/ethdb/leveldb"
"github.com/ethereum/go-ethereum/ethdb/memorydb"
- "github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/log"
"github.com/olekukonko/tablewriter"
)
@@ -299,37 +297,9 @@ func NewMemoryDatabase() ethdb.Database {
return NewDatabase(memorydb.New())
}
-// NewMemoryDatabaseWithCap creates an ephemeral in-memory key-value database
-// with an initial starting capacity, but without a freezer moving immutable
-// chain segments into cold storage.
-func NewMemoryDatabaseWithCap(size int) ethdb.Database {
- return NewDatabase(memorydb.NewWithCap(size))
-}
-
-// NewLevelDBDatabase creates a persistent key-value database without a freezer
-// moving immutable chain segments into cold storage.
-func NewLevelDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) {
- db, err := leveldb.New(file, cache, handles, namespace, readonly)
- if err != nil {
- return nil, err
- }
- log.Info("Using LevelDB as the backing database")
- return NewDatabase(db), nil
-}
-
-// NewPebbleDBDatabase creates a persistent key-value database without a freezer
-// moving immutable chain segments into cold storage.
-func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) {
- db, err := pebble.New(file, cache, handles, namespace, readonly)
- if err != nil {
- return nil, err
- }
- return NewDatabase(db), nil
-}
-
const (
- dbPebble = "pebble"
- dbLeveldb = "leveldb"
+ DBPebble = "pebble"
+ DBLeveldb = "leveldb"
)
// PreexistingDatabase checks the given data directory whether a database is already
@@ -343,72 +313,9 @@ func PreexistingDatabase(path string) string {
if err != nil {
panic(err) // only possible if the pattern is malformed
}
- return dbPebble
+ return DBPebble
}
- return dbLeveldb
-}
-
-// OpenOptions contains the options to apply when opening a database.
-// OBS: If AncientsDirectory is empty, it indicates that no freezer is to be used.
-type OpenOptions struct {
- Type string // "leveldb" | "pebble"
- Directory string // the datadir
- AncientsDirectory string // the ancients-dir
- Namespace string // the namespace for database relevant metrics
- Cache int // the capacity(in megabytes) of the data caching
- Handles int // number of files to be open simultaneously
- ReadOnly bool
-}
-
-// openKeyValueDatabase opens a disk-based key-value database, e.g. leveldb or pebble.
-//
-// type == null type != null
-// +----------------------------------------
-// db is non-existent | pebble default | specified type
-// db is existent | from db | specified type (if compatible)
-func openKeyValueDatabase(o OpenOptions) (ethdb.Database, error) {
- // Reject any unsupported database type
- if len(o.Type) != 0 && o.Type != dbLeveldb && o.Type != dbPebble {
- return nil, fmt.Errorf("unknown db.engine %v", o.Type)
- }
- // Retrieve any pre-existing database's type and use that or the requested one
- // as long as there's no conflict between the two types
- existingDb := PreexistingDatabase(o.Directory)
- if len(existingDb) != 0 && len(o.Type) != 0 && o.Type != existingDb {
- return nil, fmt.Errorf("db.engine choice was %v but found pre-existing %v database in specified data directory", o.Type, existingDb)
- }
- if o.Type == dbPebble || existingDb == dbPebble {
- log.Info("Using pebble as the backing database")
- return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
- }
- if o.Type == dbLeveldb || existingDb == dbLeveldb {
- log.Info("Using leveldb as the backing database")
- return NewLevelDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
- }
- // No pre-existing database, no user-requested one either. Default to Pebble.
- log.Info("Defaulting to pebble as the backing database")
- return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
-}
-
-// Open opens both a disk-based key-value database such as leveldb or pebble, but also
-// integrates it with a freezer database -- if the AncientDir option has been
-// set on the provided OpenOptions.
-// The passed o.AncientDir indicates the path of root ancient directory where
-// the chain freezer can be opened.
-func Open(o OpenOptions) (ethdb.Database, error) {
- kvdb, err := openKeyValueDatabase(o)
- if err != nil {
- return nil, err
- }
- if len(o.AncientsDirectory) == 0 {
- return kvdb, nil
- }
- frdb, err := NewDatabaseWithFreezer(kvdb, o.AncientsDirectory, o.Namespace, o.ReadOnly)
- if err != nil {
- kvdb.Close()
- return nil, err
- }
- return frdb, nil
+ return DBLeveldb
}
type counter uint64
diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go
index 1b8df958d1..d6370cee33 100644
--- a/core/rawdb/freezer.go
+++ b/core/rawdb/freezer.go
@@ -58,8 +58,9 @@ const freezerTableSize = 2 * 1000 * 1000 * 1000
// - The append-only nature ensures that disk writes are minimized.
// - The in-order data ensures that disk reads are always optimized.
type Freezer struct {
- frozen atomic.Uint64 // Number of items already frozen
- tail atomic.Uint64 // Number of the first stored item in the freezer
+ datadir string
+ frozen atomic.Uint64 // Number of items already frozen
+ tail atomic.Uint64 // Number of the first stored item in the freezer
// This lock synchronizes writers and the truncate operation, as well as
// the "atomic" (batched) read operations.
@@ -109,6 +110,7 @@ func NewFreezer(datadir string, namespace string, readonly bool, maxTableSize ui
}
// Open all the supported data tables
freezer := &Freezer{
+ datadir: datadir,
readonly: readonly,
tables: make(map[string]*freezerTable),
instanceLock: lock,
@@ -172,6 +174,11 @@ func (f *Freezer) Close() error {
return nil
}
+// AncientDatadir returns the path of the ancient store.
+func (f *Freezer) AncientDatadir() (string, error) {
+ return f.datadir, nil
+}
+
// HasAncient returns an indicator whether the specified ancient data exists
// in the freezer.
func (f *Freezer) HasAncient(kind string, number uint64) (bool, error) {
diff --git a/core/rawdb/freezer_memory.go b/core/rawdb/freezer_memory.go
index ee4f553919..2d3dbb07dd 100644
--- a/core/rawdb/freezer_memory.go
+++ b/core/rawdb/freezer_memory.go
@@ -419,3 +419,9 @@ func (f *MemoryFreezer) Reset() error {
f.items, f.tail = 0, 0
return nil
}
+
+// AncientDatadir returns the path of the ancient store.
+// Since the memory freezer is ephemeral, an empty string is returned.
+func (f *MemoryFreezer) AncientDatadir() (string, error) {
+ return "", nil
+}
diff --git a/core/rawdb/freezer_resettable.go b/core/rawdb/freezer_resettable.go
index b147995066..7c77a06efc 100644
--- a/core/rawdb/freezer_resettable.go
+++ b/core/rawdb/freezer_resettable.go
@@ -202,6 +202,14 @@ func (f *resettableFreezer) Sync() error {
return f.freezer.Sync()
}
+// AncientDatadir returns the path of the ancient store.
+func (f *resettableFreezer) AncientDatadir() (string, error) {
+ f.lock.RLock()
+ defer f.lock.RUnlock()
+
+ return f.freezer.AncientDatadir()
+}
+
// cleanup removes the directory located in the specified path
// has the name with deletion marker suffix.
func cleanup(path string) error {
diff --git a/core/rawdb/table.go b/core/rawdb/table.go
index bc1d354d10..1a9060b636 100644
--- a/core/rawdb/table.go
+++ b/core/rawdb/table.go
@@ -129,6 +129,12 @@ func (t *table) Delete(key []byte) error {
return t.db.Delete(append([]byte(t.prefix), key...))
}
+// DeleteRange deletes all of the keys (and values) in the range [start,end)
+// (inclusive on start, exclusive on end).
+func (t *table) DeleteRange(start, end []byte) error {
+ return t.db.DeleteRange(append([]byte(t.prefix), start...), append([]byte(t.prefix), end...))
+}
+
// NewIterator creates a binary-alphabetical iterator over a subset
// of database content with a particular key prefix, starting at a particular
// initial key (or after, if it does not exist).
diff --git a/core/state/access_events.go b/core/state/access_events.go
index 7f67df64eb..b745c383b1 100644
--- a/core/state/access_events.go
+++ b/core/state/access_events.go
@@ -117,7 +117,7 @@ func (ae *AccessEvents) ValueTransferGas(callerAddr, targetAddr common.Address)
return gas
}
-// ContractCreateCPreheck charges access costs before
+// ContractCreatePreCheckGas charges access costs before
// a contract creation is initiated. It is just reads, because the
// address collision is done before the transfer, and so no write
// are guaranteed to happen at this point.
diff --git a/core/state/database.go b/core/state/database.go
index de61dee036..0d8acec35a 100644
--- a/core/state/database.go
+++ b/core/state/database.go
@@ -186,9 +186,9 @@ func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) {
// is optional and may be partially useful if it's not fully
// generated.
if db.snap != nil {
- sr, err := newStateReader(stateRoot, db.snap)
- if err == nil {
- readers = append(readers, sr) // snap reader is optional
+ snap := db.snap.Snapshot(stateRoot)
+ if snap != nil {
+ readers = append(readers, newStateReader(snap)) // snap reader is optional
}
}
// Set up the trie reader, which is expected to always be available
diff --git a/core/state/reader.go b/core/state/reader.go
index 6bddefc2a7..85842adde8 100644
--- a/core/state/reader.go
+++ b/core/state/reader.go
@@ -21,13 +21,13 @@ import (
"maps"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state/snapshot"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/trie/utils"
"github.com/ethereum/go-ethereum/triedb"
+ "github.com/ethereum/go-ethereum/triedb/database"
)
// Reader defines the interface for accessing accounts and storage slots
@@ -52,23 +52,18 @@ type Reader interface {
Copy() Reader
}
-// stateReader is a wrapper over the state snapshot and implements the Reader
-// interface. It provides an efficient way to access flat state.
+// stateReader wraps a database state reader.
type stateReader struct {
- snap snapshot.Snapshot
- buff crypto.KeccakState
+ reader database.StateReader
+ buff crypto.KeccakState
}
-// newStateReader constructs a flat state reader with on the specified state root.
-func newStateReader(root common.Hash, snaps *snapshot.Tree) (*stateReader, error) {
- snap := snaps.Snapshot(root)
- if snap == nil {
- return nil, errors.New("snapshot is not available")
- }
+// newStateReader constructs a state reader with on the given state root.
+func newStateReader(reader database.StateReader) *stateReader {
return &stateReader{
- snap: snap,
- buff: crypto.NewKeccakState(),
- }, nil
+ reader: reader,
+ buff: crypto.NewKeccakState(),
+ }
}
// Account implements Reader, retrieving the account specified by the address.
@@ -78,18 +73,18 @@ func newStateReader(root common.Hash, snaps *snapshot.Tree) (*stateReader, error
//
// The returned account might be nil if it's not existent.
func (r *stateReader) Account(addr common.Address) (*types.StateAccount, error) {
- ret, err := r.snap.Account(crypto.HashData(r.buff, addr.Bytes()))
+ account, err := r.reader.Account(crypto.HashData(r.buff, addr.Bytes()))
if err != nil {
return nil, err
}
- if ret == nil {
+ if account == nil {
return nil, nil
}
acct := &types.StateAccount{
- Nonce: ret.Nonce,
- Balance: ret.Balance,
- CodeHash: ret.CodeHash,
- Root: common.BytesToHash(ret.Root),
+ Nonce: account.Nonce,
+ Balance: account.Balance,
+ CodeHash: account.CodeHash,
+ Root: common.BytesToHash(account.Root),
}
if len(acct.CodeHash) == 0 {
acct.CodeHash = types.EmptyCodeHash.Bytes()
@@ -110,7 +105,7 @@ func (r *stateReader) Account(addr common.Address) (*types.StateAccount, error)
func (r *stateReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) {
addrHash := crypto.HashData(r.buff, addr.Bytes())
slotHash := crypto.HashData(r.buff, key.Bytes())
- ret, err := r.snap.Storage(addrHash, slotHash)
+ ret, err := r.reader.Storage(addrHash, slotHash)
if err != nil {
return common.Hash{}, err
}
@@ -131,8 +126,8 @@ func (r *stateReader) Storage(addr common.Address, key common.Hash) (common.Hash
// Copy implements Reader, returning a deep-copied snap reader.
func (r *stateReader) Copy() Reader {
return &stateReader{
- snap: r.snap,
- buff: crypto.NewKeccakState(),
+ reader: r.reader,
+ buff: crypto.NewKeccakState(),
}
}
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 0183c14480..d855e5626d 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -341,6 +341,9 @@ func (s *StateDB) TxIndex() int {
func (s *StateDB) GetCode(addr common.Address) []byte {
stateObject := s.getStateObject(addr)
if stateObject != nil {
+ if s.witness != nil {
+ s.witness.AddCode(stateObject.Code())
+ }
return stateObject.Code()
}
return nil
@@ -349,6 +352,9 @@ func (s *StateDB) GetCode(addr common.Address) []byte {
func (s *StateDB) GetCodeSize(addr common.Address) int {
stateObject := s.getStateObject(addr)
if stateObject != nil {
+ if s.witness != nil {
+ s.witness.AddCode(stateObject.Code())
+ }
return stateObject.CodeSize()
}
return 0
@@ -1062,7 +1068,8 @@ func (s *StateDB) handleDestruction() (map[common.Hash]*accountDelete, []*trieno
deletes[addrHash] = op
// Short circuit if the origin storage was empty.
- if prev.Root == types.EmptyRootHash {
+
+ if prev.Root == types.EmptyRootHash || s.db.TrieDB().IsVerkle() {
continue
}
// Remove storage slots belonging to the account.
diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go
index e7ec0228f0..2314a02989 100644
--- a/core/state/statedb_hooked.go
+++ b/core/state/statedb_hooked.go
@@ -174,7 +174,7 @@ func (s *hookedStateDB) Snapshot() int {
}
func (s *hookedStateDB) AddPreimage(hash common.Hash, bytes []byte) {
- s.inner.Snapshot()
+ s.inner.AddPreimage(hash, bytes)
}
func (s *hookedStateDB) Witness() *stateless.Witness {
@@ -222,22 +222,46 @@ func (s *hookedStateDB) SetState(address common.Address, key common.Hash, value
}
func (s *hookedStateDB) SelfDestruct(address common.Address) uint256.Int {
- prev := s.inner.SelfDestruct(address)
- if !prev.IsZero() {
- if s.hooks.OnBalanceChange != nil {
- s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
- }
+ var prevCode []byte
+ var prevCodeHash common.Hash
+
+ if s.hooks.OnCodeChange != nil {
+ prevCode = s.inner.GetCode(address)
+ prevCodeHash = s.inner.GetCodeHash(address)
}
+
+ prev := s.inner.SelfDestruct(address)
+
+ if s.hooks.OnBalanceChange != nil && !prev.IsZero() {
+ s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
+ }
+
+ if s.hooks.OnCodeChange != nil && len(prevCode) > 0 {
+ s.hooks.OnCodeChange(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil)
+ }
+
return prev
}
func (s *hookedStateDB) SelfDestruct6780(address common.Address) (uint256.Int, bool) {
- prev, changed := s.inner.SelfDestruct6780(address)
- if !prev.IsZero() && changed {
- if s.hooks.OnBalanceChange != nil {
- s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
- }
+ var prevCode []byte
+ var prevCodeHash common.Hash
+
+ if s.hooks.OnCodeChange != nil {
+ prevCodeHash = s.inner.GetCodeHash(address)
+ prevCode = s.inner.GetCode(address)
}
+
+ prev, changed := s.inner.SelfDestruct6780(address)
+
+ if s.hooks.OnBalanceChange != nil && changed && !prev.IsZero() {
+ s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
+ }
+
+ if s.hooks.OnCodeChange != nil && changed && len(prevCode) > 0 {
+ s.hooks.OnCodeChange(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil)
+ }
+
return prev, changed
}
diff --git a/core/state_processor_test.go b/core/state_processor_test.go
index 2a16ef2cfb..f3d2304690 100644
--- a/core/state_processor_test.go
+++ b/core/state_processor_test.go
@@ -18,7 +18,6 @@ package core
import (
"crypto/ecdsa"
- "encoding/binary"
"math"
"math/big"
"testing"
@@ -30,14 +29,11 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
- "github.com/ethereum/go-ethereum/triedb"
- "github.com/ethereum/go-verkle"
"github.com/holiman/uint256"
"golang.org/x/crypto/sha3"
)
@@ -426,193 +422,3 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
}
return types.NewBlock(header, body, receipts, trie.NewStackTrie(nil))
}
-
-var (
- code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`)
- intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, true, true, true, true)
- // A contract creation that calls EXTCODECOPY in the constructor. Used to ensure that the witness
- // will not contain that copied data.
- // Source: https://gist.github.com/gballet/a23db1e1cb4ed105616b5920feb75985
- codeWithExtCodeCopy = common.FromHex(`0x60806040526040516100109061017b565b604051809103906000f08015801561002c573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561007857600080fd5b5060008067ffffffffffffffff8111156100955761009461024a565b5b6040519080825280601f01601f1916602001820160405280156100c75781602001600182028036833780820191505090505b50905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506020600083833c81610101906101e3565b60405161010d90610187565b61011791906101a3565b604051809103906000f080158015610133573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061029b565b60d58061046783390190565b6102068061053c83390190565b61019d816101d9565b82525050565b60006020820190506101b86000830184610194565b92915050565b6000819050602082019050919050565b600081519050919050565b6000819050919050565b60006101ee826101ce565b826101f8846101be565b905061020381610279565b925060208210156102435761023e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261028e565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600061028582516101d9565b80915050919050565b600082821b905092915050565b6101bd806102aa6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f566852414610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381ca91d36040518163ffffffff1660e01b815260040160206040518083038186803b1580156100b857600080fd5b505afa1580156100cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f0919061010a565b905090565b60008151905061010481610170565b92915050565b6000602082840312156101205761011f61016b565b5b600061012e848285016100f5565b91505092915050565b61014081610161565b82525050565b600060208201905061015b6000830184610137565b92915050565b6000819050919050565b600080fd5b61017981610161565b811461018457600080fd5b5056fea2646970667358221220a6a0e11af79f176f9c421b7b12f441356b25f6489b83d38cc828a701720b41f164736f6c63430008070033608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ab5ed15014602d575b600080fd5b60336047565b604051603e9190605d565b60405180910390f35b60006001905090565b6057816076565b82525050565b6000602082019050607060008301846050565b92915050565b600081905091905056fea26469706673582212203a14eb0d5cd07c277d3e24912f110ddda3e553245a99afc4eeefb2fbae5327aa64736f6c63430008070033608060405234801561001057600080fd5b5060405161020638038061020683398181016040528101906100329190610063565b60018160001c6100429190610090565b60008190555050610145565b60008151905061005d8161012e565b92915050565b60006020828403121561007957610078610129565b5b60006100878482850161004e565b91505092915050565b600061009b826100f0565b91506100a6836100f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156100db576100da6100fa565b5b828201905092915050565b6000819050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610137816100e6565b811461014257600080fd5b50565b60b3806101536000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806381ca91d314602d575b600080fd5b60336047565b604051603e9190605a565b60405180910390f35b60005481565b6054816073565b82525050565b6000602082019050606d6000830184604d565b92915050565b600081905091905056fea26469706673582212209bff7098a2f526de1ad499866f27d6d0d6f17b74a413036d6063ca6a0998ca4264736f6c63430008070033`)
- intrinsicCodeWithExtCodeCopyGas, _ = IntrinsicGas(codeWithExtCodeCopy, nil, true, true, true, true)
-)
-
-func TestProcessVerkle(t *testing.T) {
- var (
- config = ¶ms.ChainConfig{
- ChainID: big.NewInt(1),
- HomesteadBlock: big.NewInt(0),
- EIP150Block: big.NewInt(0),
- EIP155Block: big.NewInt(0),
- EIP158Block: big.NewInt(0),
- ByzantiumBlock: big.NewInt(0),
- ConstantinopleBlock: big.NewInt(0),
- PetersburgBlock: big.NewInt(0),
- IstanbulBlock: big.NewInt(0),
- MuirGlacierBlock: big.NewInt(0),
- BerlinBlock: big.NewInt(0),
- LondonBlock: big.NewInt(0),
- Ethash: new(params.EthashConfig),
- ShanghaiTime: u64(0),
- VerkleTime: u64(0),
- TerminalTotalDifficulty: common.Big0,
- }
- signer = types.LatestSigner(config)
- testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain
- coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7")
- gspec = &Genesis{
- Config: config,
- Alloc: GenesisAlloc{
- coinbase: GenesisAccount{
- Balance: big.NewInt(1000000000000000000), // 1 ether
- Nonce: 0,
- },
- },
- }
- )
- // Verkle trees use the snapshot, which must be enabled before the
- // data is saved into the tree+database.
- // genesis := gspec.MustCommit(bcdb, triedb)
- cacheConfig := DefaultCacheConfigWithScheme("path")
- cacheConfig.SnapshotLimit = 0
- blockchain, _ := NewBlockChain(bcdb, cacheConfig, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil)
- defer blockchain.Stop()
-
- txCost1 := params.TxGas
- txCost2 := params.TxGas
- contractCreationCost := intrinsicContractCreationGas +
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* creation with value */
- 739 /* execution costs */
- codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas +
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (tx) */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at pc=0x20) */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */
- params.WitnessChunkReadCost + /* SLOAD in constructor */
- params.WitnessChunkWriteCost + /* SSTORE in constructor */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at PC=0x121) */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */
- params.WitnessChunkReadCost + /* SLOAD in constructor */
- params.WitnessChunkWriteCost + /* SSTORE in constructor */
- params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash for tx creation */
- 15*(params.WitnessChunkReadCost+params.WitnessChunkWriteCost) + /* code chunks #0..#14 */
- 4844 /* execution costs */
- blockGasUsagesExpected := []uint64{
- txCost1*2 + txCost2,
- txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas,
- }
- _, chain, _, proofs, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) {
- gen.SetPoS()
-
- // TODO need to check that the tx cost provided is the exact amount used (no remaining left-over)
- tx, _ := types.SignTx(types.NewTransaction(uint64(i)*3, common.Address{byte(i), 2, 3}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey)
- gen.AddTx(tx)
- tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+1, common.Address{}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey)
- gen.AddTx(tx)
- tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+2, common.Address{}, big.NewInt(0), txCost2, big.NewInt(875000000), nil), signer, testKey)
- gen.AddTx(tx)
-
- // Add two contract creations in block #2
- if i == 1 {
- tx, _ = types.SignTx(types.NewContractCreation(6, big.NewInt(16), 3000000, big.NewInt(875000000), code), signer, testKey)
- gen.AddTx(tx)
-
- tx, _ = types.SignTx(types.NewContractCreation(7, big.NewInt(0), 3000000, big.NewInt(875000000), codeWithExtCodeCopy), signer, testKey)
- gen.AddTx(tx)
- }
- })
-
- // Check proof for both blocks
- err := verkle.Verify(proofs[0], gspec.ToBlock().Root().Bytes(), chain[0].Root().Bytes(), statediffs[0])
- if err != nil {
- t.Fatal(err)
- }
- err = verkle.Verify(proofs[1], chain[0].Root().Bytes(), chain[1].Root().Bytes(), statediffs[1])
- if err != nil {
- t.Fatal(err)
- }
-
- t.Log("verified verkle proof, inserting blocks into the chain")
-
- endnum, err := blockchain.InsertChain(chain)
- if err != nil {
- t.Fatalf("block %d imported with error: %v", endnum, err)
- }
-
- for i := 0; i < 2; i++ {
- b := blockchain.GetBlockByNumber(uint64(i) + 1)
- if b == nil {
- t.Fatalf("expected block %d to be present in chain", i+1)
- }
- if b.Hash() != chain[i].Hash() {
- t.Fatalf("block #%d not found at expected height", b.NumberU64())
- }
- if b.GasUsed() != blockGasUsagesExpected[i] {
- t.Fatalf("expected block #%d txs to use %d, got %d\n", b.NumberU64(), blockGasUsagesExpected[i], b.GasUsed())
- }
- }
-}
-
-func TestProcessParentBlockHash(t *testing.T) {
- var (
- chainConfig = params.MergedTestChainConfig
- hashA = common.Hash{0x01}
- hashB = common.Hash{0x02}
- header = &types.Header{ParentHash: hashA, Number: big.NewInt(2), Difficulty: big.NewInt(0)}
- parent = &types.Header{ParentHash: hashB, Number: big.NewInt(1), Difficulty: big.NewInt(0)}
- coinbase = common.Address{}
- )
- test := func(statedb *state.StateDB) {
- statedb.SetNonce(params.HistoryStorageAddress, 1)
- statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode)
- statedb.IntermediateRoot(true)
-
- vmContext := NewEVMBlockContext(header, nil, &coinbase)
- evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{})
- ProcessParentBlockHash(header.ParentHash, evm, statedb)
-
- vmContext = NewEVMBlockContext(parent, nil, &coinbase)
- evm = vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{})
- ProcessParentBlockHash(parent.ParentHash, evm, statedb)
-
- // make sure that the state is correct
- if have := getParentBlockHash(statedb, 1); have != hashA {
- t.Errorf("want parent hash %v, have %v", hashA, have)
- }
- if have := getParentBlockHash(statedb, 0); have != hashB {
- t.Errorf("want parent hash %v, have %v", hashB, have)
- }
- }
- t.Run("MPT", func(t *testing.T) {
- statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
- test(statedb)
- })
- t.Run("Verkle", func(t *testing.T) {
- db := rawdb.NewMemoryDatabase()
- cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme)
- cacheConfig.SnapshotLimit = 0
- triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true))
- statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil))
- test(statedb)
- })
-}
-
-func getParentBlockHash(statedb *state.StateDB, number uint64) common.Hash {
- ringIndex := number % params.HistoryServeWindow
- var key common.Hash
- binary.BigEndian.PutUint64(key[24:], ringIndex)
- return statedb.GetState(params.HistoryStorageAddress, key)
-}
diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go
index 76cb6801fa..0352ea9783 100644
--- a/core/txpool/blobpool/blobpool.go
+++ b/core/txpool/blobpool/blobpool.go
@@ -318,6 +318,10 @@ type BlobPool struct {
discoverFeed event.Feed // Event feed to send out new tx events on pool discovery (reorg excluded)
insertFeed event.Feed // Event feed to send out new tx events on pool inclusion (reorg included)
+ // txValidationFn defaults to txpool.ValidateTransaction, but can be
+ // overridden for testing purposes.
+ txValidationFn txpool.ValidationFunction
+
lock sync.RWMutex // Mutex protecting the pool during reorg handling
}
@@ -329,12 +333,13 @@ func New(config Config, chain BlockChain) *BlobPool {
// Create the transaction pool with its initial settings
return &BlobPool{
- config: config,
- signer: types.LatestSigner(chain.Config()),
- chain: chain,
- lookup: newLookup(),
- index: make(map[common.Address][]*blobTxMeta),
- spent: make(map[common.Address]*uint256.Int),
+ config: config,
+ signer: types.LatestSigner(chain.Config()),
+ chain: chain,
+ lookup: newLookup(),
+ index: make(map[common.Address][]*blobTxMeta),
+ spent: make(map[common.Address]*uint256.Int),
+ txValidationFn: txpool.ValidateTransaction,
}
}
@@ -1090,7 +1095,8 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error {
MaxSize: txMaxSize,
MinTip: p.gasTip.ToBig(),
}
- if err := txpool.ValidateTransaction(tx, p.head, p.signer, baseOpts); err != nil {
+
+ if err := p.txValidationFn(tx, p.head, p.signer, baseOpts); err != nil {
return err
}
// Ensure the transaction adheres to the stateful pool filters (nonce, balance)
diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go
index 721f7c6c2e..e4441bec5d 100644
--- a/core/txpool/blobpool/blobpool_test.go
+++ b/core/txpool/blobpool/blobpool_test.go
@@ -1449,11 +1449,29 @@ func TestAdd(t *testing.T) {
}
}
+// fakeBilly is a billy.Database implementation which just drops data on the floor.
+type fakeBilly struct {
+ billy.Database
+ count uint64
+}
+
+func (f *fakeBilly) Put(data []byte) (uint64, error) {
+ f.count++
+ return f.count, nil
+}
+
+var _ billy.Database = (*fakeBilly)(nil)
+
// Benchmarks the time it takes to assemble the lazy pending transaction list
// from the pool contents.
func BenchmarkPoolPending100Mb(b *testing.B) { benchmarkPoolPending(b, 100_000_000) }
func BenchmarkPoolPending1GB(b *testing.B) { benchmarkPoolPending(b, 1_000_000_000) }
-func BenchmarkPoolPending10GB(b *testing.B) { benchmarkPoolPending(b, 10_000_000_000) }
+func BenchmarkPoolPending10GB(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
+ benchmarkPoolPending(b, 10_000_000_000)
+}
func benchmarkPoolPending(b *testing.B, datacap uint64) {
// Calculate the maximum number of transaction that would fit into the pool
@@ -1477,6 +1495,15 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) {
if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil {
b.Fatalf("failed to create blob pool: %v", err)
}
+ // Make the pool not use disk (just drop everything). This test never reads
+ // back the data, it just iterates over the pool in-memory items
+ pool.store = &fakeBilly{pool.store, 0}
+ // Avoid validation - verifying all blob proofs take significant time
+ // when the capacity is large. The purpose of this bench is to measure assembling
+ // the lazies, not the kzg verifications.
+ pool.txValidationFn = func(tx *types.Transaction, head *types.Header, signer types.Signer, opts *txpool.ValidationOptions) error {
+ return nil // accept all
+ }
// Fill the pool up with one random transaction from each account with the
// same price and everything to maximize the worst case scenario
for i := 0; i < int(capacity); i++ {
diff --git a/core/txpool/blobpool/evictheap_test.go b/core/txpool/blobpool/evictheap_test.go
index 1cf577cb00..b03dd83d69 100644
--- a/core/txpool/blobpool/evictheap_test.go
+++ b/core/txpool/blobpool/evictheap_test.go
@@ -239,9 +239,25 @@ func BenchmarkPriceHeapOverflow10MB(b *testing.B) { benchmarkPriceHeapOverflow(
func BenchmarkPriceHeapOverflow100MB(b *testing.B) { benchmarkPriceHeapOverflow(b, 100*1024*1024) }
func BenchmarkPriceHeapOverflow1GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 1024*1024*1024) }
func BenchmarkPriceHeapOverflow10GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 10*1024*1024*1024) }
-func BenchmarkPriceHeapOverflow25GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 25*1024*1024*1024) }
-func BenchmarkPriceHeapOverflow50GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 50*1024*1024*1024) }
-func BenchmarkPriceHeapOverflow100GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 100*1024*1024*1024) }
+
+func BenchmarkPriceHeapOverflow25GB(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
+ benchmarkPriceHeapOverflow(b, 25*1024*1024*1024)
+}
+func BenchmarkPriceHeapOverflow50GB(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
+ benchmarkPriceHeapOverflow(b, 50*1024*1024*1024)
+}
+func BenchmarkPriceHeapOverflow100GB(b *testing.B) {
+ if testing.Short() {
+ b.Skip("Skipping in short-mode")
+ }
+ benchmarkPriceHeapOverflow(b, 100*1024*1024*1024)
+}
func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) {
// Calculate how many unique transactions we can fit into the provided disk
diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go
index 363fa29c02..54ae3be569 100644
--- a/core/txpool/txpool.go
+++ b/core/txpool/txpool.go
@@ -358,7 +358,7 @@ func (p *TxPool) Add(txs []*types.Transaction, local bool, sync bool) []error {
for i, split := range splits {
// If the transaction was rejected by all subpools, mark it unsupported
if split == -1 {
- errs[i] = core.ErrTxTypeNotSupported
+ errs[i] = fmt.Errorf("%w: received type %d", core.ErrTxTypeNotSupported, txs[i].Type())
continue
}
// Find which subpool handled it and pull in the corresponding error
diff --git a/core/txpool/validation.go b/core/txpool/validation.go
index 7fd5f8bc79..33b383d5cf 100644
--- a/core/txpool/validation.go
+++ b/core/txpool/validation.go
@@ -47,6 +47,11 @@ type ValidationOptions struct {
MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool
}
+// ValidationFunction is an method type which the pools use to perform the tx-validations which do not
+// require state access. Production code typically uses ValidateTransaction, whereas testing-code
+// might choose to instead use something else, e.g. to always fail or avoid heavy cpu usage.
+type ValidationFunction func(tx *types.Transaction, head *types.Header, signer types.Signer, opts *ValidationOptions) error
+
// ValidateTransaction is a helper method to check whether a transaction is valid
// according to the consensus rules, but does not check state-dependent validation
// (balance, nonce, etc).
@@ -99,7 +104,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
}
// Make sure the transaction is signed properly
if _, err := types.Sender(signer, tx); err != nil {
- return ErrInvalidSender
+ return fmt.Errorf("%w: %v", ErrInvalidSender, err)
}
// Ensure the transaction has more gas than the bare minimum needed to cover
// the transaction metadata
diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go
new file mode 100644
index 0000000000..5a4210cdab
--- /dev/null
+++ b/core/verkle_witness_test.go
@@ -0,0 +1,1087 @@
+// Copyright 2024 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package core
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/hex"
+ "math/big"
+ "slices"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus/beacon"
+ "github.com/ethereum/go-ethereum/consensus/ethash"
+ "github.com/ethereum/go-ethereum/core/rawdb"
+ "github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/params"
+ "github.com/ethereum/go-ethereum/trie/utils"
+ "github.com/ethereum/go-ethereum/triedb"
+ "github.com/ethereum/go-verkle"
+ "github.com/holiman/uint256"
+)
+
+var (
+ testVerkleChainConfig = ¶ms.ChainConfig{
+ ChainID: big.NewInt(1),
+ HomesteadBlock: big.NewInt(0),
+ EIP150Block: big.NewInt(0),
+ EIP155Block: big.NewInt(0),
+ EIP158Block: big.NewInt(0),
+ ByzantiumBlock: big.NewInt(0),
+ ConstantinopleBlock: big.NewInt(0),
+ PetersburgBlock: big.NewInt(0),
+ IstanbulBlock: big.NewInt(0),
+ MuirGlacierBlock: big.NewInt(0),
+ BerlinBlock: big.NewInt(0),
+ LondonBlock: big.NewInt(0),
+ Ethash: new(params.EthashConfig),
+ ShanghaiTime: u64(0),
+ VerkleTime: u64(0),
+ TerminalTotalDifficulty: common.Big0,
+ // TODO uncomment when proof generation is merged
+ // ProofInBlocks: true,
+ }
+ testKaustinenLikeChainConfig = ¶ms.ChainConfig{
+ ChainID: big.NewInt(69420),
+ HomesteadBlock: big.NewInt(0),
+ EIP150Block: big.NewInt(0),
+ EIP155Block: big.NewInt(0),
+ EIP158Block: big.NewInt(0),
+ ByzantiumBlock: big.NewInt(0),
+ ConstantinopleBlock: big.NewInt(0),
+ PetersburgBlock: big.NewInt(0),
+ IstanbulBlock: big.NewInt(0),
+ MuirGlacierBlock: big.NewInt(0),
+ BerlinBlock: big.NewInt(0),
+ LondonBlock: big.NewInt(0),
+ Ethash: new(params.EthashConfig),
+ ShanghaiTime: u64(0),
+ VerkleTime: u64(0),
+ TerminalTotalDifficulty: common.Big0,
+ }
+)
+
+func TestProcessVerkle(t *testing.T) {
+ var (
+ code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`)
+ intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, true, true, true, true)
+ // A contract creation that calls EXTCODECOPY in the constructor. Used to ensure that the witness
+ // will not contain that copied data.
+ // Source: https://gist.github.com/gballet/a23db1e1cb4ed105616b5920feb75985
+ codeWithExtCodeCopy = common.FromHex(`0x60806040526040516100109061017b565b604051809103906000f08015801561002c573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561007857600080fd5b5060008067ffffffffffffffff8111156100955761009461024a565b5b6040519080825280601f01601f1916602001820160405280156100c75781602001600182028036833780820191505090505b50905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506020600083833c81610101906101e3565b60405161010d90610187565b61011791906101a3565b604051809103906000f080158015610133573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061029b565b60d58061046783390190565b6102068061053c83390190565b61019d816101d9565b82525050565b60006020820190506101b86000830184610194565b92915050565b6000819050602082019050919050565b600081519050919050565b6000819050919050565b60006101ee826101ce565b826101f8846101be565b905061020381610279565b925060208210156102435761023e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261028e565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600061028582516101d9565b80915050919050565b600082821b905092915050565b6101bd806102aa6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f566852414610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381ca91d36040518163ffffffff1660e01b815260040160206040518083038186803b1580156100b857600080fd5b505afa1580156100cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f0919061010a565b905090565b60008151905061010481610170565b92915050565b6000602082840312156101205761011f61016b565b5b600061012e848285016100f5565b91505092915050565b61014081610161565b82525050565b600060208201905061015b6000830184610137565b92915050565b6000819050919050565b600080fd5b61017981610161565b811461018457600080fd5b5056fea2646970667358221220a6a0e11af79f176f9c421b7b12f441356b25f6489b83d38cc828a701720b41f164736f6c63430008070033608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ab5ed15014602d575b600080fd5b60336047565b604051603e9190605d565b60405180910390f35b60006001905090565b6057816076565b82525050565b6000602082019050607060008301846050565b92915050565b600081905091905056fea26469706673582212203a14eb0d5cd07c277d3e24912f110ddda3e553245a99afc4eeefb2fbae5327aa64736f6c63430008070033608060405234801561001057600080fd5b5060405161020638038061020683398181016040528101906100329190610063565b60018160001c6100429190610090565b60008190555050610145565b60008151905061005d8161012e565b92915050565b60006020828403121561007957610078610129565b5b60006100878482850161004e565b91505092915050565b600061009b826100f0565b91506100a6836100f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156100db576100da6100fa565b5b828201905092915050565b6000819050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610137816100e6565b811461014257600080fd5b50565b60b3806101536000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806381ca91d314602d575b600080fd5b60336047565b604051603e9190605a565b60405180910390f35b60005481565b6054816073565b82525050565b6000602082019050606d6000830184604d565b92915050565b600081905091905056fea26469706673582212209bff7098a2f526de1ad499866f27d6d0d6f17b74a413036d6063ca6a0998ca4264736f6c63430008070033`)
+ intrinsicCodeWithExtCodeCopyGas, _ = IntrinsicGas(codeWithExtCodeCopy, nil, true, true, true, true)
+ signer = types.LatestSigner(testVerkleChainConfig)
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain
+ coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7")
+ gspec = &Genesis{
+ Config: testVerkleChainConfig,
+ Alloc: GenesisAlloc{
+ coinbase: {
+ Balance: big.NewInt(1000000000000000000), // 1 ether
+ Nonce: 0,
+ },
+ params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0},
+ params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0},
+ params.WithdrawalQueueAddress: {Nonce: 1, Code: params.WithdrawalQueueCode, Balance: common.Big0},
+ params.ConsolidationQueueAddress: {Nonce: 1, Code: params.ConsolidationQueueCode, Balance: common.Big0},
+ },
+ }
+ )
+ // Verkle trees use the snapshot, which must be enabled before the
+ // data is saved into the tree+database.
+ // genesis := gspec.MustCommit(bcdb, triedb)
+ cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme)
+ cacheConfig.SnapshotLimit = 0
+ blockchain, _ := NewBlockChain(bcdb, cacheConfig, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil)
+ defer blockchain.Stop()
+
+ txCost1 := params.TxGas
+ txCost2 := params.TxGas
+ contractCreationCost := intrinsicContractCreationGas +
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* creation with value */
+ 739 /* execution costs */
+ codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas +
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (tx) */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at pc=0x20) */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */
+ params.WitnessChunkReadCost + /* SLOAD in constructor */
+ params.WitnessChunkWriteCost + /* SSTORE in constructor */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at PC=0x121) */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */
+ params.WitnessChunkReadCost + /* SLOAD in constructor */
+ params.WitnessChunkWriteCost + /* SSTORE in constructor */
+ params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash for tx creation */
+ 15*(params.WitnessChunkReadCost+params.WitnessChunkWriteCost) + /* code chunks #0..#14 */
+ 4844 /* execution costs */
+ blockGasUsagesExpected := []uint64{
+ txCost1*2 + txCost2,
+ txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas,
+ }
+ _, chain, _, proofs, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+
+ // TODO need to check that the tx cost provided is the exact amount used (no remaining left-over)
+ tx, _ := types.SignTx(types.NewTransaction(uint64(i)*3, common.Address{byte(i), 2, 3}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey)
+ gen.AddTx(tx)
+ tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+1, common.Address{}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey)
+ gen.AddTx(tx)
+ tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+2, common.Address{}, big.NewInt(0), txCost2, big.NewInt(875000000), nil), signer, testKey)
+ gen.AddTx(tx)
+
+ // Add two contract creations in block #2
+ if i == 1 {
+ tx, _ = types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 6,
+ Value: big.NewInt(16),
+ Gas: 3000000,
+ GasPrice: big.NewInt(875000000),
+ Data: code,
+ })
+ gen.AddTx(tx)
+
+ tx, _ = types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 7,
+ Value: big.NewInt(0),
+ Gas: 3000000,
+ GasPrice: big.NewInt(875000000),
+ Data: codeWithExtCodeCopy,
+ })
+ gen.AddTx(tx)
+ }
+ })
+
+ // Check proof for both blocks
+ err := verkle.Verify(proofs[0], gspec.ToBlock().Root().Bytes(), chain[0].Root().Bytes(), statediffs[0])
+ if err != nil {
+ t.Fatal(err)
+ }
+ err = verkle.Verify(proofs[1], chain[0].Root().Bytes(), chain[1].Root().Bytes(), statediffs[1])
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ t.Log("verified verkle proof, inserting blocks into the chain")
+
+ endnum, err := blockchain.InsertChain(chain)
+ if err != nil {
+ t.Fatalf("block %d imported with error: %v", endnum, err)
+ }
+
+ for i := 0; i < 2; i++ {
+ b := blockchain.GetBlockByNumber(uint64(i) + 1)
+ if b == nil {
+ t.Fatalf("expected block %d to be present in chain", i+1)
+ }
+ if b.Hash() != chain[i].Hash() {
+ t.Fatalf("block #%d not found at expected height", b.NumberU64())
+ }
+ if b.GasUsed() != blockGasUsagesExpected[i] {
+ t.Fatalf("expected block #%d txs to use %d, got %d\n", b.NumberU64(), blockGasUsagesExpected[i], b.GasUsed())
+ }
+ }
+}
+
+func TestProcessParentBlockHash(t *testing.T) {
+ // This test uses blocks where,
+ // block 1 parent hash is 0x0100....
+ // block 2 parent hash is 0x0200....
+ // etc
+ checkBlockHashes := func(statedb *state.StateDB) {
+ statedb.SetNonce(params.HistoryStorageAddress, 1)
+ statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode)
+ // Process n blocks, from 1 .. num
+ var num = 2
+ for i := 1; i <= num; i++ {
+ header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)}
+ vmContext := NewEVMBlockContext(header, nil, new(common.Address))
+ evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, params.MergedTestChainConfig, vm.Config{})
+ ProcessParentBlockHash(header.ParentHash, evm, statedb)
+ }
+ // Read block hashes for block 0 .. num-1
+ for i := 0; i < num; i++ {
+ have, want := getContractStoredBlockHash(statedb, uint64(i)), common.Hash{byte(i + 1)}
+ if have != want {
+ t.Errorf("block %d, have parent hash %v, want %v", i, have, want)
+ }
+ }
+ }
+ t.Run("MPT", func(t *testing.T) {
+ statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
+ checkBlockHashes(statedb)
+ })
+ t.Run("Verkle", func(t *testing.T) {
+ db := rawdb.NewMemoryDatabase()
+ cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme)
+ cacheConfig.SnapshotLimit = 0
+ triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true))
+ statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil))
+ checkBlockHashes(statedb)
+ })
+}
+
+// getContractStoredBlockHash is a utility method which reads the stored parent blockhash for block 'number'
+func getContractStoredBlockHash(statedb *state.StateDB, number uint64) common.Hash {
+ ringIndex := number % params.HistoryServeWindow
+ var key common.Hash
+ binary.BigEndian.PutUint64(key[24:], ringIndex)
+ return statedb.GetState(params.HistoryStorageAddress, key)
+}
+
+// TestProcessVerkleInvalidContractCreation checks for several modes of contract creation failures
+func TestProcessVerkleInvalidContractCreation(t *testing.T) {
+ var (
+ account1 = common.HexToAddress("0x687704DB07e902e9A8B3754031D168D46E3D586e")
+ account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d")
+ gspec = verkleTestGenesis(testKaustinenLikeChainConfig)
+ )
+ // slightly modify it to suit the live txs from the testnet
+ gspec.Alloc[account2] = types.Account{
+ Balance: big.NewInt(1000000000000000000), // 1 ether
+ Nonce: 1,
+ }
+
+ // Create two blocks that reproduce what is happening on kaustinen.
+ // - The first block contains two failing contract creation transactions, that
+ // write to storage before they revert.
+ //
+ // - The second block contains a single failing contract creation transaction,
+ // that fails right off the bat.
+ _, chain, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+
+ if i == 0 {
+ for _, rlpData := range []string{
+ // SSTORE at slot 41 and reverts
+ "f8d48084479c2c18830186a08080b8806000602955bda3f9600060ca55600060695523b360006039551983576000601255b0620c2fde2c592ac2600060bc55e0ac6000606455a63e22600060e655eb607e605c5360a2605d5360c7605e53601d605f5360eb606053606b606153608e60625360816063536079606453601e60655360fc60665360b7606753608b60685383021e7ca0cc20c65a97d2e526b8ec0f4266e8b01bdcde43b9aeb59d8bfb44e8eb8119c109a07a8e751813ae1b2ce734960dbc39a4f954917d7822a2c5d1dca18b06c584131f",
+ // SSTORE at slot 133 and reverts
+ "02f8db83010f2c01843b9aca0084479c2c18830186a08080b88060006085553fad6000600a55600060565555600060b55506600060cf557f1b8b38183e7bd1bdfaa7123c5a4976e54cce0e42049d841411978fd3595e25c66019527f0538943712953cf08900aae40222a40b2d5a4ac8075ad8cf0870e2be307edbb96039527f9f3174ff85024747041ae7a611acffb987c513c088d90ab288aec080a0cd6ac65ce2cb0a912371f6b5a551ba8caffc22ec55ad4d3cb53de41d05eb77b6a02e0dfe8513dfa6ec7bfd7eda6f5c0dac21b39b982436045e128cec46cfd3f960",
+ // this one is a simple transfer that succeeds, necessary to get the correct nonce in the other block.
+ "f8e80184479c2c18830186a094bbbbde4ca27f83fc18aa108170547ff57675936a80b8807ff71f7c15faadb969a76a5f54a81a0117e1e743cb7f24e378eda28442ea4c6eb6604a527fb5409e5718d44e23bfffac926e5ea726067f772772e7e19446acba0c853f62f5606a526020608a536088608b536039608c536004608d5360af608e537f7f7675d9f210e0a61564e6d11e7cd75f5bc9009ac9f6b94a0fc63035441a83021e7ba04a4a172d81ebb02847829b76a387ac09749c8b65668083699abe20c887fb9efca07c5b1a990702ec7b31a5e8e3935cd9a77649f8c25a84131229e24ab61aec6093",
+ } {
+ var tx = new(types.Transaction)
+ if err := tx.UnmarshalBinary(common.Hex2Bytes(rlpData)); err != nil {
+ t.Fatal(err)
+ }
+ gen.AddTx(tx)
+ }
+ } else {
+ var tx = new(types.Transaction)
+ // immediately reverts
+ if err := tx.UnmarshalBinary(common.Hex2Bytes("01f8d683010f2c028443ad7d0e830186a08080b880b00e7fa3c849dce891cce5fae8a4c46cbb313d6aec0c0ffe7863e05fb7b22d4807674c6055527ffbfcb0938f3e18f7937aa8fa95d880afebd5c4cec0d85186095832d03c85cf8a60755260ab60955360cf6096536066609753606e60985360fa609953609e609a53608e609b536024609c5360f6609d536072609e5360a4609fc080a08fc6f7101f292ff1fb0de8ac69c2d320fbb23bfe61cf327173786ea5daee6e37a044c42d91838ef06646294bf4f9835588aee66243b16a66a2da37641fae4c045f")); err != nil {
+ t.Fatal(err)
+ }
+ gen.AddTx(tx)
+ }
+ })
+
+ tx1ContractAddress := crypto.CreateAddress(account1, 0)
+ tx1ContractStem := utils.GetTreeKey(tx1ContractAddress[:], uint256.NewInt(0), 105)
+ tx1ContractStem = tx1ContractStem[:31]
+
+ tx2ContractAddress := crypto.CreateAddress(account2, 1)
+ tx2SlotKey := [32]byte{}
+ tx2SlotKey[31] = 133
+ tx2ContractStem := utils.StorageSlotKey(tx2ContractAddress[:], tx2SlotKey[:])
+ tx2ContractStem = tx2ContractStem[:31]
+
+ eip2935Stem := utils.GetTreeKey(params.HistoryStorageAddress[:], uint256.NewInt(0), 0)
+ eip2935Stem = eip2935Stem[:31]
+
+ // Check that the witness contains what we expect: a storage entry for each of the two contract
+ // creations that failed: one at 133 for the 2nd tx, and one at 105 for the first tx.
+ for _, stemStateDiff := range statediffs[0] {
+ // Check that the slot number 133, which is overflowing the account header,
+ // is present. Note that the offset of the 2nd group (first group after the
+ // header) is skipping the first 64 values, hence we still have an offset
+ // of 133, and not 133 - 64.
+ if bytes.Equal(stemStateDiff.Stem[:], tx2ContractStem[:]) {
+ for _, suffixDiff := range stemStateDiff.SuffixDiffs {
+ if suffixDiff.Suffix != 133 {
+ t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix)
+ }
+ if suffixDiff.CurrentValue != nil {
+ t.Fatalf("invalid prestate value found for %x in block #1: %v != nil\n", stemStateDiff.Stem, suffixDiff.CurrentValue)
+ }
+ if suffixDiff.NewValue != nil {
+ t.Fatalf("invalid poststate value found for %x in block #1: %v != nil\n", stemStateDiff.Stem, suffixDiff.NewValue)
+ }
+ }
+ } else if bytes.Equal(stemStateDiff.Stem[:], tx1ContractStem) {
+ // For this contract creation, check that only the accound header and storage slot 41
+ // are found in the witness.
+ for _, suffixDiff := range stemStateDiff.SuffixDiffs {
+ if suffixDiff.Suffix != 105 && suffixDiff.Suffix != 0 && suffixDiff.Suffix != 1 {
+ t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix)
+ }
+ }
+ } else if bytes.Equal(stemStateDiff.Stem[:], eip2935Stem) {
+ // Check the eip 2935 group of leaves.
+ // Check that only one leaf was accessed, and is present in the witness.
+ if len(stemStateDiff.SuffixDiffs) > 1 {
+ t.Fatalf("invalid suffix diff count found for BLOCKHASH contract: %d != 1", len(stemStateDiff.SuffixDiffs))
+ }
+ // Check that this leaf is the first storage slot
+ if stemStateDiff.SuffixDiffs[0].Suffix != 64 {
+ t.Fatalf("invalid suffix diff value found for BLOCKHASH contract: %d != 64", stemStateDiff.SuffixDiffs[0].Suffix)
+ }
+ // check that the prestate value is nil and that the poststate value isn't.
+ if stemStateDiff.SuffixDiffs[0].CurrentValue != nil {
+ t.Fatalf("non-nil current value in BLOCKHASH contract insert: %x", stemStateDiff.SuffixDiffs[0].CurrentValue)
+ }
+ if stemStateDiff.SuffixDiffs[0].NewValue == nil {
+ t.Fatalf("nil new value in BLOCKHASH contract insert")
+ }
+ if *stemStateDiff.SuffixDiffs[0].NewValue != chain[0].Hash() {
+ t.Fatalf("invalid BLOCKHASH value: %x != %x", *stemStateDiff.SuffixDiffs[0].NewValue, chain[0].Hash())
+ }
+ } else {
+ // For all other entries present in the witness, check that nothing beyond
+ // the account header was accessed.
+ for _, suffixDiff := range stemStateDiff.SuffixDiffs {
+ if suffixDiff.Suffix > 2 {
+ t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix)
+ }
+ }
+ }
+ }
+
+ // Check that no account has a value above 4 in the 2nd block as no storage nor
+ // code should make it to the witness.
+ for _, stemStateDiff := range statediffs[1] {
+ for _, suffixDiff := range stemStateDiff.SuffixDiffs {
+ if bytes.Equal(stemStateDiff.Stem[:], eip2935Stem) {
+ // BLOCKHASH contract stem
+ if len(stemStateDiff.SuffixDiffs) > 1 {
+ t.Fatalf("invalid suffix diff count found for BLOCKHASH contract at block #2: %d != 1", len(stemStateDiff.SuffixDiffs))
+ }
+ if stemStateDiff.SuffixDiffs[0].Suffix != 65 {
+ t.Fatalf("invalid suffix diff value found for BLOCKHASH contract at block #2: %d != 65", stemStateDiff.SuffixDiffs[0].Suffix)
+ }
+ if stemStateDiff.SuffixDiffs[0].NewValue == nil {
+ t.Fatalf("missing post state value for BLOCKHASH contract at block #2")
+ }
+ if *stemStateDiff.SuffixDiffs[0].NewValue != common.HexToHash("0788c2c0f23aa07eb8bf76fe6c1ca9064a4821c1fd0af803913da488a58dba54") {
+ t.Fatalf("invalid post state value for BLOCKHASH contract at block #2: 0788c2c0f23aa07eb8bf76fe6c1ca9064a4821c1fd0af803913da488a58dba54 != %x", (*stemStateDiff.SuffixDiffs[0].NewValue)[:])
+ }
+ } else if suffixDiff.Suffix > 4 {
+ t.Fatalf("invalid suffix diff found for %x in block #2: %d\n", stemStateDiff.Stem, suffixDiff.Suffix)
+ }
+ }
+ }
+}
+
+func verkleTestGenesis(config *params.ChainConfig) *Genesis {
+ var (
+ coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7")
+ account1 = common.HexToAddress("0x687704DB07e902e9A8B3754031D168D46E3D586e")
+ account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d")
+ )
+ return &Genesis{
+ Config: config,
+ Alloc: GenesisAlloc{
+ coinbase: GenesisAccount{
+ Balance: big.NewInt(1000000000000000000), // 1 ether
+ Nonce: 0,
+ },
+ account1: GenesisAccount{
+ Balance: big.NewInt(1000000000000000000), // 1 ether
+ Nonce: 0,
+ },
+ account2: GenesisAccount{
+ Balance: big.NewInt(1000000000000000000), // 1 ether
+ Nonce: 3,
+ },
+ params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0},
+ params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0},
+ params.WithdrawalQueueAddress: {Nonce: 1, Code: params.WithdrawalQueueCode, Balance: common.Big0},
+ params.ConsolidationQueueAddress: {Nonce: 1, Code: params.ConsolidationQueueCode, Balance: common.Big0},
+ },
+ }
+}
+
+// TestProcessVerkleContractWithEmptyCode checks that the witness contains all valid
+// entries, if the initcode returns an empty code.
+func TestProcessVerkleContractWithEmptyCode(t *testing.T) {
+ // The test txs were taken from a secondary testnet with chain id 69421
+ config := *testKaustinenLikeChainConfig
+ config.ChainID.SetUint64(69421)
+ gspec := verkleTestGenesis(&config)
+
+ _, chain, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+ var tx types.Transaction
+ // a transaction that does some PUSH1n but returns a 0-sized contract
+ txpayload := common.Hex2Bytes("02f8db83010f2d03843b9aca008444cf6a05830186a08080b8807fdfbbb59f2371a76485ce557fd0de00c298d3ede52a3eab56d35af674eb49ec5860335260826053536001605453604c60555360f3605653606060575360446058536096605953600c605a5360df605b5360f3605c5360fb605d53600c605e53609a605f53607f60605360fe606153603d60625360f4606353604b60645360cac001a0486b6dc55b8a311568b7239a2cae1d77e7446dba71df61eaafd53f73820a138fa010bd48a45e56133ac4c5645142c2ea48950d40eb35050e9510b6bad9e15c5865")
+ if err := tx.UnmarshalBinary(txpayload); err != nil {
+ t.Fatal(err)
+ }
+ gen.AddTx(&tx)
+ })
+
+ eip2935Stem := utils.GetTreeKey(params.HistoryStorageAddress[:], uint256.NewInt(0), 0)
+ eip2935Stem = eip2935Stem[:31]
+
+ for _, stemStateDiff := range statediffs[0] {
+ // Handle the case of the history contract: make sure only the correct
+ // slots are added to the witness.
+ if bytes.Equal(stemStateDiff.Stem[:], eip2935Stem) {
+ // BLOCKHASH contract stem
+ if len(stemStateDiff.SuffixDiffs) > 1 {
+ t.Fatalf("invalid suffix diff count found for BLOCKHASH contract: %d != 1", len(stemStateDiff.SuffixDiffs))
+ }
+ if stemStateDiff.SuffixDiffs[0].Suffix != 64 {
+ t.Fatalf("invalid suffix diff value found for BLOCKHASH contract: %d != 64", stemStateDiff.SuffixDiffs[0].Suffix)
+ }
+ // check that the "current value" is nil and that the new value isn't.
+ if stemStateDiff.SuffixDiffs[0].CurrentValue != nil {
+ t.Fatalf("non-nil current value in BLOCKHASH contract insert: %x", stemStateDiff.SuffixDiffs[0].CurrentValue)
+ }
+ if stemStateDiff.SuffixDiffs[0].NewValue == nil {
+ t.Fatalf("nil new value in BLOCKHASH contract insert")
+ }
+ if *stemStateDiff.SuffixDiffs[0].NewValue != chain[0].Hash() {
+ t.Fatalf("invalid BLOCKHASH value: %x != %x", *stemStateDiff.SuffixDiffs[0].NewValue, chain[0].Hash())
+ }
+ } else {
+ for _, suffixDiff := range stemStateDiff.SuffixDiffs {
+ if suffixDiff.Suffix > 2 {
+ // if d8898012c484fb48610ecb7963886339207dab004bce968b007b616ffa18e0 shows up, it means that the PUSHn
+ // in the transaction above added entries into the witness, when they should not have since they are
+ // part of a contract deployment.
+ t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix)
+ }
+ }
+ }
+ }
+}
+
+// TestProcessVerkleExtCodeHashOpcode verifies that calling EXTCODEHASH on another
+// deployed contract, creates all the right entries in the witness.
+func TestProcessVerkleExtCodeHashOpcode(t *testing.T) {
+ // The test txs were taken from a secondary testnet with chain id 69421
+ config := *testKaustinenLikeChainConfig
+ config.ChainID.SetUint64(69421)
+
+ var (
+ signer = types.LatestSigner(&config)
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ gspec = verkleTestGenesis(&config)
+ )
+ dummyContract := []byte{
+ byte(vm.PUSH1), 2,
+ byte(vm.PUSH1), 12,
+ byte(vm.PUSH1), 0x00,
+ byte(vm.CODECOPY),
+
+ byte(vm.PUSH1), 2,
+ byte(vm.PUSH1), 0x00,
+ byte(vm.RETURN),
+
+ byte(vm.PUSH1), 42,
+ }
+ deployer := crypto.PubkeyToAddress(testKey.PublicKey)
+ dummyContractAddr := crypto.CreateAddress(deployer, 0)
+
+ // contract that calls EXTCODEHASH on the dummy contract
+ extCodeHashContract := []byte{
+ byte(vm.PUSH1), 22,
+ byte(vm.PUSH1), 12,
+ byte(vm.PUSH1), 0x00,
+ byte(vm.CODECOPY),
+
+ byte(vm.PUSH1), 22,
+ byte(vm.PUSH1), 0x00,
+ byte(vm.RETURN),
+
+ byte(vm.PUSH20),
+ 0x3a, 0x22, 0x0f, 0x35, 0x12, 0x52, 0x08, 0x9d, 0x38, 0x5b, 0x29, 0xbe, 0xca, 0x14, 0xe2, 0x7f, 0x20, 0x4c, 0x29, 0x6a,
+ byte(vm.EXTCODEHASH),
+ }
+ extCodeHashContractAddr := crypto.CreateAddress(deployer, 1)
+
+ _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+
+ if i == 0 {
+ // Create dummy contract.
+ tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0,
+ Value: big.NewInt(0),
+ Gas: 100_000,
+ GasPrice: big.NewInt(875000000),
+ Data: dummyContract,
+ })
+ gen.AddTx(tx)
+
+ // Create contract with EXTCODEHASH opcode.
+ tx, _ = types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 1,
+ Value: big.NewInt(0),
+ Gas: 100_000,
+ GasPrice: big.NewInt(875000000),
+ Data: extCodeHashContract})
+ gen.AddTx(tx)
+ } else {
+ tx, _ := types.SignTx(types.NewTransaction(2, extCodeHashContractAddr, big.NewInt(0), 100_000, big.NewInt(875000000), nil), signer, testKey)
+ gen.AddTx(tx)
+ }
+ })
+
+ contractKeccakTreeKey := utils.CodeHashKey(dummyContractAddr[:])
+
+ var stateDiffIdx = -1
+ for i, stemStateDiff := range statediffs[1] {
+ if bytes.Equal(stemStateDiff.Stem[:], contractKeccakTreeKey[:31]) {
+ stateDiffIdx = i
+ break
+ }
+ }
+ if stateDiffIdx == -1 {
+ t.Fatalf("no state diff found for stem")
+ }
+
+ codeHashStateDiff := statediffs[1][stateDiffIdx].SuffixDiffs[0]
+ // Check location of code hash was accessed
+ if codeHashStateDiff.Suffix != utils.CodeHashLeafKey {
+ t.Fatalf("code hash invalid suffix")
+ }
+ // check the code hash wasn't present in the prestate, as
+ // the contract was deployed in this block.
+ if codeHashStateDiff.CurrentValue == nil {
+ t.Fatalf("codeHash.CurrentValue must not be empty")
+ }
+ // check the poststate value corresponds to the code hash
+ // of the deployed contract.
+ expCodeHash := crypto.Keccak256Hash(dummyContract[12:])
+ if *codeHashStateDiff.CurrentValue != expCodeHash {
+ t.Fatalf("codeHash.CurrentValue unexpected code hash")
+ }
+ if codeHashStateDiff.NewValue != nil {
+ t.Fatalf("codeHash.NewValue must be nil")
+ }
+}
+
+// TestProcessVerkleBalanceOpcode checks that calling balance
+// on another contract will add the correct entries to the witness.
+func TestProcessVerkleBalanceOpcode(t *testing.T) {
+ // The test txs were taken from a secondary testnet with chain id 69421
+ config := *testKaustinenLikeChainConfig
+ config.ChainID.SetUint64(69421)
+
+ var (
+ signer = types.LatestSigner(&config)
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d")
+ gspec = verkleTestGenesis(&config)
+ )
+ _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+ txData := slices.Concat(
+ []byte{byte(vm.PUSH20)},
+ common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d").Bytes(),
+ []byte{byte(vm.BALANCE)})
+
+ tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0,
+ Value: big.NewInt(0),
+ Gas: 100_000,
+ GasPrice: big.NewInt(875000000),
+ Data: txData})
+ gen.AddTx(tx)
+ })
+
+ account2BalanceTreeKey := utils.BasicDataKey(account2[:])
+
+ var stateDiffIdx = -1
+ for i, stemStateDiff := range statediffs[0] {
+ if bytes.Equal(stemStateDiff.Stem[:], account2BalanceTreeKey[:31]) {
+ stateDiffIdx = i
+ break
+ }
+ }
+ if stateDiffIdx == -1 {
+ t.Fatalf("no state diff found for stem")
+ }
+
+ var zero [32]byte
+ balanceStateDiff := statediffs[0][stateDiffIdx].SuffixDiffs[0]
+ if balanceStateDiff.Suffix != utils.BasicDataLeafKey {
+ t.Fatalf("invalid suffix diff")
+ }
+ // check the prestate balance wasn't 0 or missing
+ if balanceStateDiff.CurrentValue == nil || *balanceStateDiff.CurrentValue == zero {
+ t.Fatalf("invalid current value %v", *balanceStateDiff.CurrentValue)
+ }
+ // check that the poststate witness value for the balance is nil,
+ // meaning that it didn't get updated.
+ if balanceStateDiff.NewValue != nil {
+ t.Fatalf("invalid new value")
+ }
+}
+
+// TestProcessVerkleSelfDestructInSeparateTx controls the contents of the witness after
+// a non-eip6780-compliant selfdestruct occurs.
+func TestProcessVerkleSelfDestructInSeparateTx(t *testing.T) {
+ // The test txs were taken from a secondary testnet with chain id 69421
+ config := *testKaustinenLikeChainConfig
+ config.ChainID.SetUint64(69421)
+
+ var (
+ signer = types.LatestSigner(&config)
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d")
+ gspec = verkleTestGenesis(&config)
+ )
+
+ // runtime code: selfdestruct ( 0x6177843db3138ae69679A54b95cf345ED759450d )
+ runtimeCode := slices.Concat(
+ []byte{byte(vm.PUSH20)},
+ account2.Bytes(),
+ []byte{byte(vm.SELFDESTRUCT)})
+
+ //The goal of this test is to test SELFDESTRUCT that happens in a contract
+ // execution which is created in a previous transaction.
+ selfDestructContract := slices.Concat([]byte{
+ byte(vm.PUSH1), byte(len(runtimeCode)),
+ byte(vm.PUSH1), 12,
+ byte(vm.PUSH1), 0x00,
+ byte(vm.CODECOPY), // Codecopy( to-offset: 0, code offset: 12, length: 22 )
+
+ byte(vm.PUSH1), byte(len(runtimeCode)),
+ byte(vm.PUSH1), 0x00,
+ byte(vm.RETURN), // Return ( 0 : len(runtimecode)
+ },
+ runtimeCode)
+
+ deployer := crypto.PubkeyToAddress(testKey.PublicKey)
+ contract := crypto.CreateAddress(deployer, 0)
+
+ _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+
+ if i == 0 {
+ // Create selfdestruct contract, sending 42 wei.
+ tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0,
+ Value: big.NewInt(42),
+ Gas: 100_000,
+ GasPrice: big.NewInt(875000000),
+ Data: selfDestructContract,
+ })
+ gen.AddTx(tx)
+ } else {
+ // Call it.
+ tx, _ := types.SignTx(types.NewTransaction(1, contract, big.NewInt(0), 100_000, big.NewInt(875000000), nil), signer, testKey)
+ gen.AddTx(tx)
+ }
+ })
+
+ var zero [32]byte
+ { // Check self-destructed contract in the witness
+ selfDestructContractTreeKey := utils.CodeHashKey(contract[:])
+
+ var stateDiffIdx = -1
+ for i, stemStateDiff := range statediffs[1] {
+ if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) {
+ stateDiffIdx = i
+ break
+ }
+ }
+ if stateDiffIdx == -1 {
+ t.Fatalf("no state diff found for stem")
+ }
+
+ balanceStateDiff := statediffs[1][stateDiffIdx].SuffixDiffs[0]
+ if balanceStateDiff.Suffix != utils.BasicDataLeafKey {
+ t.Fatalf("balance invalid suffix")
+ }
+
+ // The original balance was 42.
+ var oldBalance [16]byte
+ oldBalance[15] = 42
+ if !bytes.Equal((*balanceStateDiff.CurrentValue)[utils.BasicDataBalanceOffset:], oldBalance[:]) {
+ t.Fatalf("the pre-state balance before self-destruct must be %x, got %x", oldBalance, *balanceStateDiff.CurrentValue)
+ }
+
+ // The new balance must be 0.
+ if !bytes.Equal((*balanceStateDiff.NewValue)[utils.BasicDataBalanceOffset:], zero[utils.BasicDataBalanceOffset:]) {
+ t.Fatalf("the post-state balance after self-destruct must be 0")
+ }
+ }
+ { // Check self-destructed target in the witness.
+ selfDestructTargetTreeKey := utils.CodeHashKey(account2[:])
+
+ var stateDiffIdx = -1
+ for i, stemStateDiff := range statediffs[1] {
+ if bytes.Equal(stemStateDiff.Stem[:], selfDestructTargetTreeKey[:31]) {
+ stateDiffIdx = i
+ break
+ }
+ }
+ if stateDiffIdx == -1 {
+ t.Fatalf("no state diff found for stem")
+ }
+
+ balanceStateDiff := statediffs[1][stateDiffIdx].SuffixDiffs[0]
+ if balanceStateDiff.Suffix != utils.BasicDataLeafKey {
+ t.Fatalf("balance invalid suffix")
+ }
+ if balanceStateDiff.CurrentValue == nil {
+ t.Fatalf("codeHash.CurrentValue must not be empty")
+ }
+ if balanceStateDiff.NewValue == nil {
+ t.Fatalf("codeHash.NewValue must not be empty")
+ }
+ preStateBalance := binary.BigEndian.Uint64(balanceStateDiff.CurrentValue[utils.BasicDataBalanceOffset+8:])
+ postStateBalance := binary.BigEndian.Uint64(balanceStateDiff.NewValue[utils.BasicDataBalanceOffset+8:])
+ if postStateBalance-preStateBalance != 42 {
+ t.Fatalf("the post-state balance after self-destruct must be 42, got %d-%d=%d", postStateBalance, preStateBalance, postStateBalance-preStateBalance)
+ }
+ }
+}
+
+// TestProcessVerkleSelfDestructInSeparateTx controls the contents of the witness after
+// a eip6780-compliant selfdestruct occurs.
+func TestProcessVerkleSelfDestructInSameTx(t *testing.T) {
+ // The test txs were taken from a secondary testnet with chain id 69421
+ config := *testKaustinenLikeChainConfig
+ config.ChainID.SetUint64(69421)
+
+ var (
+ signer = types.LatestSigner(&config)
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d")
+ gspec = verkleTestGenesis(&config)
+ )
+
+ // The goal of this test is to test SELFDESTRUCT that happens in a contract
+ // execution which is created in **the same** transaction sending the remaining
+ // balance to an external (i.e: not itself) account.
+
+ selfDestructContract := slices.Concat(
+ []byte{byte(vm.PUSH20)},
+ account2.Bytes(),
+ []byte{byte(vm.SELFDESTRUCT)})
+ deployer := crypto.PubkeyToAddress(testKey.PublicKey)
+ contract := crypto.CreateAddress(deployer, 0)
+
+ _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+ tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0,
+ Value: big.NewInt(42),
+ Gas: 100_000,
+ GasPrice: big.NewInt(875000000),
+ Data: selfDestructContract,
+ })
+ gen.AddTx(tx)
+ })
+
+ { // Check self-destructed contract in the witness
+ selfDestructContractTreeKey := utils.CodeHashKey(contract[:])
+
+ var stateDiffIdx = -1
+ for i, stemStateDiff := range statediffs[0] {
+ if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) {
+ stateDiffIdx = i
+ break
+ }
+ }
+ if stateDiffIdx == -1 {
+ t.Fatalf("no state diff found for stem")
+ }
+
+ balanceStateDiff := statediffs[0][stateDiffIdx].SuffixDiffs[0]
+ if balanceStateDiff.Suffix != utils.BasicDataLeafKey {
+ t.Fatalf("balance invalid suffix")
+ }
+
+ if balanceStateDiff.CurrentValue != nil {
+ t.Fatalf("the pre-state balance before must be nil, since the contract didn't exist")
+ }
+
+ if balanceStateDiff.NewValue != nil {
+ t.Fatalf("the post-state balance after self-destruct must be nil since the contract shouldn't be created at all")
+ }
+ }
+ { // Check self-destructed target in the witness.
+ selfDestructTargetTreeKey := utils.CodeHashKey(account2[:])
+
+ var stateDiffIdx = -1
+ for i, stemStateDiff := range statediffs[0] {
+ if bytes.Equal(stemStateDiff.Stem[:], selfDestructTargetTreeKey[:31]) {
+ stateDiffIdx = i
+ break
+ }
+ }
+ if stateDiffIdx == -1 {
+ t.Fatalf("no state diff found for stem")
+ }
+
+ balanceStateDiff := statediffs[0][stateDiffIdx].SuffixDiffs[0]
+ if balanceStateDiff.Suffix != utils.BasicDataLeafKey {
+ t.Fatalf("balance invalid suffix")
+ }
+ if balanceStateDiff.CurrentValue == nil {
+ t.Fatalf("codeHash.CurrentValue must not be empty")
+ }
+ if balanceStateDiff.NewValue == nil {
+ t.Fatalf("codeHash.NewValue must not be empty")
+ }
+ preStateBalance := binary.BigEndian.Uint64(balanceStateDiff.CurrentValue[utils.BasicDataBalanceOffset+8:])
+ postStateBalance := binary.BigEndian.Uint64(balanceStateDiff.NewValue[utils.BasicDataBalanceOffset+8:])
+ if postStateBalance-preStateBalance != 42 {
+ t.Fatalf("the post-state balance after self-destruct must be 42. got %d", postStateBalance)
+ }
+ }
+}
+
+// TestProcessVerkleSelfDestructInSeparateTxWithSelfBeneficiary checks the content of the witness
+// if a selfdestruct occurs in a different tx than the one that created it, but the beneficiary
+// is the selfdestructed account.
+func TestProcessVerkleSelfDestructInSeparateTxWithSelfBeneficiary(t *testing.T) {
+ // The test txs were taken from a secondary testnet with chain id 69421
+ config := *testKaustinenLikeChainConfig
+ config.ChainID.SetUint64(69421)
+
+ var (
+ signer = types.LatestSigner(&config)
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ gspec = verkleTestGenesis(&config)
+ )
+ // The goal of this test is to test SELFDESTRUCT that happens in a contract
+ // execution which is created in a *previous* transaction sending the remaining
+ // balance to itself.
+ selfDestructContract := []byte{
+ byte(vm.PUSH1), 2, // PUSH1 2
+ byte(vm.PUSH1), 10, // PUSH1 12
+ byte(vm.PUSH0), // PUSH0
+ byte(vm.CODECOPY), // Codecopy ( to offset 0, code@offset: 10, length: 2)
+
+ byte(vm.PUSH1), 22,
+ byte(vm.PUSH0),
+ byte(vm.RETURN), // RETURN( memory[0:2] )
+
+ // Deployed code
+ byte(vm.ADDRESS),
+ byte(vm.SELFDESTRUCT),
+ }
+ deployer := crypto.PubkeyToAddress(testKey.PublicKey)
+ contract := crypto.CreateAddress(deployer, 0)
+
+ _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+ if i == 0 {
+ // Create self-destruct contract, sending 42 wei.
+ tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0,
+ Value: big.NewInt(42),
+ Gas: 100_000,
+ GasPrice: big.NewInt(875000000),
+ Data: selfDestructContract,
+ })
+ gen.AddTx(tx)
+ } else {
+ // Call it.
+ tx, _ := types.SignTx(types.NewTransaction(1, contract, big.NewInt(0), 100_000, big.NewInt(875000000), nil), signer, testKey)
+ gen.AddTx(tx)
+ }
+ })
+
+ {
+ // Check self-destructed contract in the witness.
+ // The way 6780 is implemented today, it always SubBalance from the self-destructed contract, and AddBalance
+ // to the beneficiary. In this case both addresses are the same, thus this might be optimizable from a gas
+ // perspective. But until that happens, we need to honor this "balance reading" adding it to the witness.
+
+ selfDestructContractTreeKey := utils.CodeHashKey(contract[:])
+
+ var stateDiffIdx = -1
+ for i, stemStateDiff := range statediffs[1] {
+ if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) {
+ stateDiffIdx = i
+ break
+ }
+ }
+ if stateDiffIdx == -1 {
+ t.Fatal("no state diff found for stem")
+ }
+
+ balanceStateDiff := statediffs[1][stateDiffIdx].SuffixDiffs[0]
+ if balanceStateDiff.Suffix != utils.BasicDataLeafKey {
+ t.Fatal("balance invalid suffix")
+ }
+
+ // The original balance was 42.
+ var oldBalance [16]byte
+ oldBalance[15] = 42
+ if !bytes.Equal((*balanceStateDiff.CurrentValue)[utils.BasicDataBalanceOffset:], oldBalance[:]) {
+ t.Fatal("the pre-state balance before self-destruct must be 42")
+ }
+
+ // Note that the SubBalance+AddBalance net effect is a 0 change, so NewValue
+ // must be nil.
+ if balanceStateDiff.NewValue != nil {
+ t.Fatal("the post-state balance after self-destruct must be empty")
+ }
+ }
+}
+
+// TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary checks the content of the witness
+// if a selfdestruct occurs in the same tx as the one that created it, but the beneficiary
+// is the selfdestructed account.
+func TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary(t *testing.T) {
+ // The test txs were taken from a secondary testnet with chain id 69421
+ config := *testKaustinenLikeChainConfig
+ config.ChainID.SetUint64(69421)
+
+ var (
+ signer = types.LatestSigner(&config)
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ gspec = verkleTestGenesis(&config)
+ deployer = crypto.PubkeyToAddress(testKey.PublicKey)
+ contract = crypto.CreateAddress(deployer, 0)
+ )
+
+ // The goal of this test is to test SELFDESTRUCT that happens while executing
+ // the init code of a contract creation, that occurs in **the same** transaction.
+ // The balance is sent to itself.
+ t.Logf("Contract: %v", contract.String())
+
+ selfDestructContract := []byte{byte(vm.ADDRESS), byte(vm.SELFDESTRUCT)}
+
+ _, _, _, _, stateDiffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+ tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0,
+ Value: big.NewInt(42),
+ Gas: 100_000,
+ GasPrice: big.NewInt(875000000),
+ Data: selfDestructContract,
+ })
+ gen.AddTx(tx)
+ })
+ stateDiff := stateDiffs[0] // state difference of block 1
+
+ { // Check self-destructed contract in the witness
+ selfDestructContractTreeKey := utils.CodeHashKey(contract[:])
+
+ var stateDiffIdx = -1
+ for i, stemStateDiff := range stateDiff {
+ if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) {
+ stateDiffIdx = i
+ break
+ }
+ }
+ if stateDiffIdx == -1 {
+ t.Fatal("no state diff found for stem")
+ }
+ balanceStateDiff := stateDiff[stateDiffIdx].SuffixDiffs[0]
+ if balanceStateDiff.Suffix != utils.BasicDataLeafKey {
+ t.Fatal("balance invalid suffix")
+ }
+ if balanceStateDiff.CurrentValue != nil {
+ t.Fatal("the pre-state balance before must be nil, since the contract didn't exist")
+ }
+ // Ensure that the value is burnt, and therefore that the balance of the self-destructed
+ // contract isn't modified (it should remain missing from the state)
+ if balanceStateDiff.NewValue != nil {
+ t.Fatal("the post-state balance after self-destruct must be nil since the contract shouldn't be created at all")
+ }
+ }
+}
+
+// TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiaryAndPrefundedAccount checks the
+// content of the witness if a selfdestruct occurs in the same tx as the one that created it,
+// it, but the beneficiary is the selfdestructed account. The difference with the test above,
+// is that the created account is prefunded and so the final value should be 0.
+func TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiaryAndPrefundedAccount(t *testing.T) {
+ // The test txs were taken from a secondary testnet with chain id 69421
+ config := *testKaustinenLikeChainConfig
+ config.ChainID.SetUint64(69421)
+
+ var (
+ signer = types.LatestSigner(&config)
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ gspec = verkleTestGenesis(&config)
+ deployer = crypto.PubkeyToAddress(testKey.PublicKey)
+ contract = crypto.CreateAddress(deployer, 0)
+ )
+ // Prefund the account, at an address that the contract will be deployed at,
+ // before it selfdestrucs. We can therefore check that the account itseld is
+ // NOT destroyed, which is what the currrent version of the spec requires.
+ // TODO(gballet) revisit after the spec has been modified.
+ gspec.Alloc[contract] = types.Account{
+ Balance: big.NewInt(100),
+ }
+
+ selfDestructContract := []byte{byte(vm.ADDRESS), byte(vm.SELFDESTRUCT)}
+
+ _, _, _, _, stateDiffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) {
+ gen.SetPoS()
+ tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0,
+ Value: big.NewInt(42),
+ Gas: 100_000,
+ GasPrice: big.NewInt(875000000),
+ Data: selfDestructContract,
+ })
+ gen.AddTx(tx)
+ })
+ stateDiff := stateDiffs[0] // state difference of block 1
+
+ { // Check self-destructed contract in the witness
+ selfDestructContractTreeKey := utils.CodeHashKey(contract[:])
+
+ var stateDiffIdx = -1
+ for i, stemStateDiff := range stateDiff {
+ if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) {
+ stateDiffIdx = i
+ break
+ }
+ }
+ if stateDiffIdx == -1 {
+ t.Fatal("no state diff found for stem")
+ }
+ balanceStateDiff := stateDiff[stateDiffIdx].SuffixDiffs[0]
+ if balanceStateDiff.Suffix != utils.BasicDataLeafKey {
+ t.Fatal("balance invalid suffix")
+ }
+ expected, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000064")
+ if balanceStateDiff.CurrentValue == nil || !bytes.Equal(balanceStateDiff.CurrentValue[:], expected) {
+ t.Fatalf("incorrect prestate balance: %x != %x", *balanceStateDiff.CurrentValue, expected)
+ }
+ // Ensure that the value is burnt, and therefore that the balance of the self-destructed
+ // contract isn't modified (it should remain missing from the state)
+ expected = make([]byte, 32)
+ if balanceStateDiff.NewValue == nil {
+ t.Fatal("incorrect nil poststate balance")
+ }
+ if !bytes.Equal(balanceStateDiff.NewValue[:], expected[:]) {
+ t.Fatalf("incorrect poststate balance: %x != %x", *balanceStateDiff.NewValue, expected[:])
+ }
+ }
+}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 26ff495579..0593a32a3e 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -213,9 +213,6 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
code := evm.StateDB.GetCode(addr)
- if witness := evm.StateDB.Witness(); witness != nil {
- witness.AddCode(code)
- }
if len(code) == 0 {
ret, err = nil, nil // gas is unchanged
} else {
@@ -283,9 +280,6 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
- if witness := evm.StateDB.Witness(); witness != nil {
- witness.AddCode(evm.StateDB.GetCode(addrCopy))
- }
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
@@ -333,9 +327,6 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
addrCopy := addr
// Initialise a new contract and make initialise the delegate values
contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
- if witness := evm.StateDB.Witness(); witness != nil {
- witness.AddCode(evm.StateDB.GetCode(addrCopy))
- }
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
@@ -391,9 +382,6 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas)
- if witness := evm.StateDB.Witness(); witness != nil {
- witness.AddCode(evm.StateDB.GetCode(addrCopy))
- }
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 540f0e508d..dc7bf18683 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -340,10 +340,6 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte
func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.peek()
- address := slot.Bytes20()
- if witness := interpreter.evm.StateDB.Witness(); witness != nil {
- witness.AddCode(interpreter.evm.StateDB.GetCode(address))
- }
slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20())))
return nil, nil
}
@@ -383,9 +379,6 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
}
addr := common.Address(a.Bytes20())
code := interpreter.evm.StateDB.GetCode(addr)
- if witness := interpreter.evm.StateDB.Witness(); witness != nil {
- witness.AddCode(code)
- }
codeCopy := getData(code, uint64CodeOffset, length.Uint64())
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
@@ -987,13 +980,13 @@ func makePush(size uint64, pushByteSize int) executionFunc {
start = min(codeLen, int(*pc+1))
end = min(codeLen, start+pushByteSize)
)
- scope.Stack.push(new(uint256.Int).SetBytes(
- common.RightPadBytes(
- scope.Contract.Code[start:end],
- pushByteSize,
- )),
- )
+ a := new(uint256.Int).SetBytes(scope.Contract.Code[start:end])
+ // Missing bytes: pushByteSize - len(pushData)
+ if missing := pushByteSize - (end - start); missing > 0 {
+ a.Lsh(a, uint(8*missing))
+ }
+ scope.Stack.push(a)
*pc += size
return nil, nil
}
diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go
index a3f9ee81d1..b8e62e1de5 100644
--- a/core/vm/instructions_test.go
+++ b/core/vm/instructions_test.go
@@ -927,3 +927,75 @@ func TestOpMCopy(t *testing.T) {
}
}
}
+
+// TestPush sanity-checks how code with immediates are handled when the code size is
+// smaller than the size of the immediate.
+func TestPush(t *testing.T) {
+ code := common.FromHex("0011223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121")
+
+ push32 := makePush(32, 32)
+
+ scope := &ScopeContext{
+ Memory: nil,
+ Stack: newstack(),
+ Contract: &Contract{
+ Code: code,
+ },
+ }
+ for i, want := range []string{
+ "0x11223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1",
+ "0x223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1",
+ "0x3344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1",
+ "0x44556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1",
+ "0x556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1",
+ "0x6677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1",
+ "0x77889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191",
+ "0x889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181",
+ "0x9900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171",
+ "0xaabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191817161",
+ "0xaabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151",
+ "0xbbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141",
+ "0xccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191817161514131",
+ "0xddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121",
+ "0xeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100",
+ "0xff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191817161514131210000",
+ "0x102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121000000",
+ "0x2030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100000000",
+ "0x30405060708090a0b0c0d0e0ff1e1d1c1b1a191817161514131210000000000",
+ "0x405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121000000000000",
+ "0x5060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100000000000000",
+ "0x60708090a0b0c0d0e0ff1e1d1c1b1a191817161514131210000000000000000",
+ "0x708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121000000000000000000",
+ "0x8090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100000000000000000000",
+ "0x90a0b0c0d0e0ff1e1d1c1b1a191817161514131210000000000000000000000",
+ "0xa0b0c0d0e0ff1e1d1c1b1a19181716151413121000000000000000000000000",
+ "0xb0c0d0e0ff1e1d1c1b1a1918171615141312100000000000000000000000000",
+ "0xc0d0e0ff1e1d1c1b1a191817161514131210000000000000000000000000000",
+ "0xd0e0ff1e1d1c1b1a19181716151413121000000000000000000000000000000",
+ "0xe0ff1e1d1c1b1a1918171615141312100000000000000000000000000000000",
+ "0xff1e1d1c1b1a191817161514131210000000000000000000000000000000000",
+ "0xf1e1d1c1b1a19181716151413121000000000000000000000000000000000000",
+ "0xe1d1c1b1a1918171615141312100000000000000000000000000000000000000",
+ "0xd1c1b1a191817161514131210000000000000000000000000000000000000000",
+ "0xc1b1a19181716151413121000000000000000000000000000000000000000000",
+ "0xb1a1918171615141312100000000000000000000000000000000000000000000",
+ "0xa191817161514131210000000000000000000000000000000000000000000000",
+ "0x9181716151413121000000000000000000000000000000000000000000000000",
+ "0x8171615141312100000000000000000000000000000000000000000000000000",
+ "0x7161514131210000000000000000000000000000000000000000000000000000",
+ "0x6151413121000000000000000000000000000000000000000000000000000000",
+ "0x5141312100000000000000000000000000000000000000000000000000000000",
+ "0x4131210000000000000000000000000000000000000000000000000000000000",
+ "0x3121000000000000000000000000000000000000000000000000000000000000",
+ "0x2100000000000000000000000000000000000000000000000000000000000000",
+ "0x0",
+ } {
+ pc := new(uint64)
+ *pc = uint64(i)
+ push32(pc, nil, scope)
+ res := scope.Stack.pop()
+ if have := res.Hex(); have != want {
+ t.Fatalf("case %d, have %v want %v", i, have, want)
+ }
+ }
+}
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index 793f398367..c408994401 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -249,8 +249,11 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
} else if sLen > operation.maxStack {
return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack}
}
- if !contract.UseGas(cost, in.evm.Config.Tracer, tracing.GasChangeIgnored) {
+ // for tracing: this gas consumption event is emitted below in the debug section.
+ if contract.Gas < cost {
return nil, ErrOutOfGas
+ } else {
+ contract.Gas -= cost
}
if operation.dynamicGas != nil {
@@ -279,8 +282,11 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrOutOfGas, err)
}
- if !contract.UseGas(dynamicCost, in.evm.Config.Tracer, tracing.GasChangeIgnored) {
+ // for tracing: this gas consumption event is emitted below in the debug section.
+ if contract.Gas < dynamicCost {
return nil, ErrOutOfGas
+ } else {
+ contract.Gas -= dynamicCost
}
// Do tracing before memory expansion
diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go
index 2ad991ee41..2243e14b65 100644
--- a/core/vm/runtime/runtime.go
+++ b/core/vm/runtime/runtime.go
@@ -142,13 +142,16 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
// set the receiver's (the executing contract) code for execution.
cfg.State.SetCode(address, code)
// Call the code with the given configuration.
- ret, _, err := vmenv.Call(
+ ret, leftOverGas, err := vmenv.Call(
sender,
common.BytesToAddress([]byte("contract")),
input,
cfg.GasLimit,
uint256.MustFromBig(cfg.Value),
)
+ if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
+ cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)
+ }
return ret, cfg.State, err
}
@@ -181,6 +184,9 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
cfg.GasLimit,
uint256.MustFromBig(cfg.Value),
)
+ if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
+ cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)
+ }
return code, address, leftOverGas, err
}
@@ -214,5 +220,8 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
cfg.GasLimit,
uint256.MustFromBig(cfg.Value),
)
+ if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
+ cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)
+ }
return ret, leftOverGas, err
}
diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go
index 1aefc810bd..97234368ee 100644
--- a/core/vm/runtime/runtime_test.go
+++ b/core/vm/runtime/runtime_test.go
@@ -514,6 +514,17 @@ func BenchmarkSimpleLoop(b *testing.B) {
byte(vm.JUMP),
}
+ loopingCode2 := []byte{
+ byte(vm.JUMPDEST), // [ count ]
+ // push args for the call
+ byte(vm.PUSH4), 1, 2, 3, 4,
+ byte(vm.PUSH5), 1, 2, 3, 4, 5,
+
+ byte(vm.POP), byte(vm.POP),
+ byte(vm.PUSH6), 0, 0, 0, 0, 0, 0, // jumpdestination
+ byte(vm.JUMP),
+ }
+
callRevertingContractWithInput := []byte{
byte(vm.JUMPDEST), //
// push args for the call
@@ -540,6 +551,7 @@ func BenchmarkSimpleLoop(b *testing.B) {
benchmarkNonModifyingCode(100000000, staticCallIdentity, "staticcall-identity-100M", "", b)
benchmarkNonModifyingCode(100000000, callIdentity, "call-identity-100M", "", b)
benchmarkNonModifyingCode(100000000, loopingCode, "loop-100M", "", b)
+ benchmarkNonModifyingCode(100000000, loopingCode2, "loop2-100M", "", b)
benchmarkNonModifyingCode(100000000, callInexistant, "call-nonexist-100M", "", b)
benchmarkNonModifyingCode(100000000, callEOA, "call-EOA-100M", "", b)
benchmarkNonModifyingCode(100000000, callRevertingContractWithInput, "call-reverting-100M", "", b)
diff --git a/docs/postmortems/2021-08-22-split-postmortem.md b/docs/postmortems/2021-08-22-split-postmortem.md
index 5ec4f37e87..2e5c41c764 100644
--- a/docs/postmortems/2021-08-22-split-postmortem.md
+++ b/docs/postmortems/2021-08-22-split-postmortem.md
@@ -56,7 +56,7 @@ On the evening of 17th, we discussed options on how to handle it. We made a stat
It was decided that in this specific instance, it would be possible to make a public announcement and a patch release:
- The fix can be made pretty 'generically', e.g. always copying data on input to precompiles.
-- The flaw is pretty difficult to find, given a generic fix in the call. The attacker needs to figure out that it concerns the precompiles, specifically the datcopy, and that it concerns the `RETURNDATA` buffer rather than the regular memory, and lastly the special circumstances to trigger it (overlapping but shifted input/output).
+- The flaw is pretty difficult to find, given a generic fix in the call. The attacker needs to figure out that it concerns the precompiles, specifically the datacopy, and that it concerns the `RETURNDATA` buffer rather than the regular memory, and lastly the special circumstances to trigger it (overlapping but shifted input/output).
Since we had merged the removal of `ETH65`, if the entire network were to upgrade, then nodes which have not yet implemented `ETH66` would be cut off from the network. After further discussions, we decided to:
diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go
index 7bb31329c6..3ac719c23e 100644
--- a/eth/catalyst/api_test.go
+++ b/eth/catalyst/api_test.go
@@ -208,7 +208,6 @@ func TestEth2PrepareAndGetPayload(t *testing.T) {
t.Fatalf("error preparing payload, err=%v", err)
}
// give the payload some time to be built
- time.Sleep(100 * time.Millisecond)
payloadID := (&miner.BuildPayloadArgs{
Parent: fcState.HeadBlockHash,
Timestamp: blockParams.Timestamp,
@@ -217,12 +216,12 @@ func TestEth2PrepareAndGetPayload(t *testing.T) {
BeaconRoot: blockParams.BeaconRoot,
Version: engine.PayloadV1,
}).Id()
- execData, err := api.GetPayloadV1(payloadID)
+ execData, err := api.getPayload(payloadID, true)
if err != nil {
t.Fatalf("error getting payload, err=%v", err)
}
- if len(execData.Transactions) != blocks[9].Transactions().Len() {
- t.Fatalf("invalid number of transactions %d != 1", len(execData.Transactions))
+ if len(execData.ExecutionPayload.Transactions) != blocks[9].Transactions().Len() {
+ t.Fatalf("invalid number of transactions %d != 1", len(execData.ExecutionPayload.Transactions))
}
// Test invalid payloadID
var invPayload engine.PayloadID
@@ -453,7 +452,6 @@ func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block)
}
mcfg := miner.DefaultConfig
- mcfg.PendingFeeRecipient = testAddr
ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: mcfg}
ethservice, err := eth.New(n, ethcfg)
if err != nil {
@@ -628,7 +626,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
SafeBlockHash: common.Hash{},
FinalizedBlockHash: common.Hash{},
}
- payload *engine.ExecutableData
+ payload *engine.ExecutionPayloadEnvelope
resp engine.ForkChoiceResponse
err error
)
@@ -640,11 +638,10 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
t.Fatalf("error preparing payload, invalid status: %v", resp.PayloadStatus.Status)
}
// give the payload some time to be built
- time.Sleep(50 * time.Millisecond)
- if payload, err = api.GetPayloadV1(*resp.PayloadID); err != nil {
+ if payload, err = api.getPayload(*resp.PayloadID, true); err != nil {
t.Fatalf("can't get payload: %v", err)
}
- if len(payload.Transactions) > 0 {
+ if len(payload.ExecutionPayload.Transactions) > 0 {
break
}
// No luck this time we need to update the params and try again.
@@ -653,7 +650,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
t.Fatalf("payload should not be empty")
}
}
- execResp, err := api.NewPayloadV1(*payload)
+ execResp, err := api.NewPayloadV1(*payload.ExecutionPayload)
if err != nil {
t.Fatalf("can't execute payload: %v", err)
}
@@ -661,14 +658,14 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
t.Fatalf("invalid status: %v", execResp.Status)
}
fcState = engine.ForkchoiceStateV1{
- HeadBlockHash: payload.BlockHash,
- SafeBlockHash: payload.ParentHash,
- FinalizedBlockHash: payload.ParentHash,
+ HeadBlockHash: payload.ExecutionPayload.BlockHash,
+ SafeBlockHash: payload.ExecutionPayload.ParentHash,
+ FinalizedBlockHash: payload.ExecutionPayload.ParentHash,
}
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
t.Fatalf("Failed to insert block: %v", err)
}
- if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.Number {
+ if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.ExecutionPayload.Number {
t.Fatalf("Chain head should be updated")
}
parent = ethservice.BlockChain().CurrentBlock()
@@ -1736,9 +1733,6 @@ func TestWitnessCreationAndConsumption(t *testing.T) {
if err != nil {
t.Fatalf("error preparing payload, err=%v", err)
}
- // Give the payload some time to be built
- time.Sleep(100 * time.Millisecond)
-
payloadID := (&miner.BuildPayloadArgs{
Parent: fcState.HeadBlockHash,
Timestamp: blockParams.Timestamp,
@@ -1748,7 +1742,7 @@ func TestWitnessCreationAndConsumption(t *testing.T) {
BeaconRoot: blockParams.BeaconRoot,
Version: engine.PayloadV3,
}).Id()
- envelope, err := api.GetPayloadV3(payloadID)
+ envelope, err := api.getPayload(payloadID, true)
if err != nil {
t.Fatalf("error getting payload, err=%v", err)
}
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
index c325e5010c..f1a815e6d3 100644
--- a/eth/ethconfig/config.go
+++ b/eth/ethconfig/config.go
@@ -138,9 +138,6 @@ type Config struct {
VMTrace string
VMTraceJsonConfig string
- // Miscellaneous options
- DocRoot string `toml:"-"`
-
// RPCGasCap is the global gas cap for eth-call variants.
RPCGasCap uint64
diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go
index d96ba0ccb7..0ec0eaddeb 100644
--- a/eth/ethconfig/gen_config.go
+++ b/eth/ethconfig/gen_config.go
@@ -46,7 +46,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
EnablePreimageRecording bool
VMTrace string
VMTraceJsonConfig string
- DocRoot string `toml:"-"`
RPCGasCap uint64
RPCEVMTimeout time.Duration
RPCTxFeeCap float64
@@ -83,7 +82,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
enc.EnablePreimageRecording = c.EnablePreimageRecording
enc.VMTrace = c.VMTrace
enc.VMTraceJsonConfig = c.VMTraceJsonConfig
- enc.DocRoot = c.DocRoot
enc.RPCGasCap = c.RPCGasCap
enc.RPCEVMTimeout = c.RPCEVMTimeout
enc.RPCTxFeeCap = c.RPCTxFeeCap
@@ -124,7 +122,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
EnablePreimageRecording *bool
VMTrace *string
VMTraceJsonConfig *string
- DocRoot *string `toml:"-"`
RPCGasCap *uint64
RPCEVMTimeout *time.Duration
RPCTxFeeCap *float64
@@ -222,9 +219,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
if dec.VMTraceJsonConfig != nil {
c.VMTraceJsonConfig = *dec.VMTraceJsonConfig
}
- if dec.DocRoot != nil {
- c.DocRoot = *dec.DocRoot
- }
if dec.RPCGasCap != nil {
c.RPCGasCap = *dec.RPCGasCap
}
diff --git a/eth/filters/bench_test.go b/eth/filters/bench_test.go
deleted file mode 100644
index 73b96b77af..0000000000
--- a/eth/filters/bench_test.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package filters
-
-import (
- "context"
- "fmt"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/node"
-)
-
-func BenchmarkBloomBits512(b *testing.B) {
- benchmarkBloomBits(b, 512)
-}
-
-func BenchmarkBloomBits1k(b *testing.B) {
- benchmarkBloomBits(b, 1024)
-}
-
-func BenchmarkBloomBits2k(b *testing.B) {
- benchmarkBloomBits(b, 2048)
-}
-
-func BenchmarkBloomBits4k(b *testing.B) {
- benchmarkBloomBits(b, 4096)
-}
-
-func BenchmarkBloomBits8k(b *testing.B) {
- benchmarkBloomBits(b, 8192)
-}
-
-func BenchmarkBloomBits16k(b *testing.B) {
- benchmarkBloomBits(b, 16384)
-}
-
-func BenchmarkBloomBits32k(b *testing.B) {
- benchmarkBloomBits(b, 32768)
-}
-
-const benchFilterCnt = 2000
-
-func benchmarkBloomBits(b *testing.B, sectionSize uint64) {
- b.Skip("test disabled: this tests presume (and modify) an existing datadir.")
- benchDataDir := node.DefaultDataDir() + "/geth/chaindata"
- b.Log("Running bloombits benchmark section size:", sectionSize)
-
- db, err := rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "", false)
- if err != nil {
- b.Fatalf("error opening database at %v: %v", benchDataDir, err)
- }
- head := rawdb.ReadHeadBlockHash(db)
- if head == (common.Hash{}) {
- b.Fatalf("chain data not found at %v", benchDataDir)
- }
-
- clearBloomBits(db)
- b.Log("Generating bloombits data...")
- headNum := rawdb.ReadHeaderNumber(db, head)
- if headNum == nil || *headNum < sectionSize+512 {
- b.Fatalf("not enough blocks for running a benchmark")
- }
-
- start := time.Now()
- cnt := (*headNum - 512) / sectionSize
- var dataSize, compSize uint64
- for sectionIdx := uint64(0); sectionIdx < cnt; sectionIdx++ {
- bc, err := bloombits.NewGenerator(uint(sectionSize))
- if err != nil {
- b.Fatalf("failed to create generator: %v", err)
- }
- var header *types.Header
- for i := sectionIdx * sectionSize; i < (sectionIdx+1)*sectionSize; i++ {
- hash := rawdb.ReadCanonicalHash(db, i)
- if header = rawdb.ReadHeader(db, hash, i); header == nil {
- b.Fatalf("Error creating bloomBits data")
- return
- }
- bc.AddBloom(uint(i-sectionIdx*sectionSize), header.Bloom)
- }
- sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*sectionSize-1)
- for i := 0; i < types.BloomBitLength; i++ {
- data, err := bc.Bitset(uint(i))
- if err != nil {
- b.Fatalf("failed to retrieve bitset: %v", err)
- }
- comp := bitutil.CompressBytes(data)
- dataSize += uint64(len(data))
- compSize += uint64(len(comp))
- rawdb.WriteBloomBits(db, uint(i), sectionIdx, sectionHead, comp)
- }
- //if sectionIdx%50 == 0 {
- // b.Log(" section", sectionIdx, "/", cnt)
- //}
- }
-
- d := time.Since(start)
- b.Log("Finished generating bloombits data")
- b.Log(" ", d, "total ", d/time.Duration(cnt*sectionSize), "per block")
- b.Log(" data size:", dataSize, " compressed size:", compSize, " compression ratio:", float64(compSize)/float64(dataSize))
-
- b.Log("Running filter benchmarks...")
- start = time.Now()
-
- var (
- backend *testBackend
- sys *FilterSystem
- )
- for i := 0; i < benchFilterCnt; i++ {
- if i%20 == 0 {
- db.Close()
- db, _ = rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "", false)
- backend = &testBackend{db: db, sections: cnt}
- sys = NewFilterSystem(backend, Config{})
- }
- var addr common.Address
- addr[0] = byte(i)
- addr[1] = byte(i / 256)
- filter := sys.NewRangeFilter(0, int64(cnt*sectionSize-1), []common.Address{addr}, nil)
- if _, err := filter.Logs(context.Background()); err != nil {
- b.Error("filter.Logs error:", err)
- }
- }
-
- d = time.Since(start)
- b.Log("Finished running filter benchmarks")
- b.Log(" ", d, "total ", d/time.Duration(benchFilterCnt), "per address", d*time.Duration(1000000)/time.Duration(benchFilterCnt*cnt*sectionSize), "per million blocks")
- db.Close()
-}
-
-//nolint:unused
-func clearBloomBits(db ethdb.Database) {
- var bloomBitsPrefix = []byte("bloomBits-")
- fmt.Println("Clearing bloombits data...")
- it := db.NewIterator(bloomBitsPrefix, nil)
- for it.Next() {
- db.Delete(it.Key())
- }
- it.Release()
-}
-
-func BenchmarkNoBloomBits(b *testing.B) {
- b.Skip("test disabled: this tests presume (and modify) an existing datadir.")
- benchDataDir := node.DefaultDataDir() + "/geth/chaindata"
- b.Log("Running benchmark without bloombits")
- db, err := rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "", false)
- if err != nil {
- b.Fatalf("error opening database at %v: %v", benchDataDir, err)
- }
- head := rawdb.ReadHeadBlockHash(db)
- if head == (common.Hash{}) {
- b.Fatalf("chain data not found at %v", benchDataDir)
- }
- headNum := rawdb.ReadHeaderNumber(db, head)
-
- clearBloomBits(db)
-
- _, sys := newTestFilterSystem(b, db, Config{})
-
- b.Log("Running filter benchmarks...")
- start := time.Now()
- filter := sys.NewRangeFilter(0, int64(*headNum), []common.Address{{}}, nil)
- filter.Logs(context.Background())
- d := time.Since(start)
- b.Log("Finished running filter benchmarks")
- b.Log(" ", d, "total ", d*time.Duration(1000000)/time.Duration(*headNum+1), "per million blocks")
- db.Close()
-}
diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go
index d8b703fee4..6a3057326d 100644
--- a/eth/filters/filter_test.go
+++ b/eth/filters/filter_test.go
@@ -48,7 +48,7 @@ func makeReceipt(addr common.Address) *types.Receipt {
func BenchmarkFilters(b *testing.B) {
var (
- db, _ = rawdb.NewLevelDBDatabase(b.TempDir(), 0, 0, "", false)
+ db = rawdb.NewMemoryDatabase()
_, sys = newTestFilterSystem(b, db, Config{})
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go
index faf360cc53..d0509f2f3d 100644
--- a/eth/protocols/eth/handler_test.go
+++ b/eth/protocols/eth/handler_test.go
@@ -17,10 +17,12 @@
package eth
import (
+ "bytes"
"math"
"math/big"
"math/rand"
"testing"
+ "time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
@@ -37,6 +39,7 @@ import (
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/params"
+ "github.com/ethereum/go-ethereum/rlp"
)
var (
@@ -142,10 +145,12 @@ func (b *testBackend) RunPeer(peer *Peer, handler Handler) error {
func (b *testBackend) PeerInfo(enode.ID) interface{} { panic("not implemented") }
func (b *testBackend) AcceptTxs() bool {
- panic("data processing tests should be done in the handler package")
+ return true
+ //panic("data processing tests should be done in the handler package")
}
func (b *testBackend) Handle(*Peer, Packet) error {
- panic("data processing tests should be done in the handler package")
+ return nil
+ //panic("data processing tests should be done in the handler package")
}
// Tests that block headers can be retrieved from a remote chain based on user queries.
@@ -498,3 +503,76 @@ func testGetBlockReceipts(t *testing.T, protocol uint) {
t.Errorf("receipts mismatch: %v", err)
}
}
+
+type decoder struct {
+ msg []byte
+}
+
+func (d decoder) Decode(val interface{}) error {
+ buffer := bytes.NewBuffer(d.msg)
+ s := rlp.NewStream(buffer, uint64(len(d.msg)))
+ return s.Decode(val)
+}
+
+func (d decoder) Time() time.Time {
+ return time.Now()
+}
+
+func setup() (*testBackend, *testPeer) {
+ // Generate some transactions etc.
+ acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
+ acc2Key, _ := crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
+ acc1Addr := crypto.PubkeyToAddress(acc1Key.PublicKey)
+ acc2Addr := crypto.PubkeyToAddress(acc2Key.PublicKey)
+ signer := types.HomesteadSigner{}
+ gen := func(n int, block *core.BlockGen) {
+ if n%2 == 0 {
+ w := &types.Withdrawal{
+ Address: common.Address{0xaa},
+ Amount: 42,
+ }
+ block.AddWithdrawal(w)
+ }
+ switch n {
+ case 0:
+ // In block 1, the test bank sends account #1 some ether.
+ tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(10_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testKey)
+ block.AddTx(tx)
+ case 1:
+ // In block 2, the test bank sends some more ether to account #1.
+ // acc1Addr passes it on to account #2.
+ tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testKey)
+ tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, acc1Key)
+ block.AddTx(tx1)
+ block.AddTx(tx2)
+ case 2:
+ // Block 3 is empty but was mined by account #2.
+ block.SetCoinbase(acc2Addr)
+ block.SetExtra([]byte("yeehaw"))
+ }
+ }
+ backend := newTestBackendWithGenerator(maxBodiesServe+15, true, gen)
+ peer, _ := newTestPeer("peer", ETH68, backend)
+ // Discard all messages
+ go func() {
+ for {
+ msg, err := peer.app.ReadMsg()
+ if err == nil {
+ msg.Discard()
+ }
+ }
+ }()
+ return backend, peer
+}
+
+func FuzzEthProtocolHandlers(f *testing.F) {
+ handlers := eth68
+ backend, peer := setup()
+ f.Fuzz(func(t *testing.T, code byte, msg []byte) {
+ handler := handlers[uint64(code)%protocolLengths[ETH68]]
+ if handler == nil {
+ return
+ }
+ handler(backend, decoder{msg: msg}, peer.Peer)
+ })
+}
diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go
index 5b9c809596..cb635e7127 100644
--- a/eth/tracers/internal/tracetest/calltrace_test.go
+++ b/eth/tracers/internal/tracetest/calltrace_test.go
@@ -35,7 +35,6 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/tests"
)
@@ -202,7 +201,7 @@ func BenchmarkTracers(b *testing.B) {
func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
// Configure a blockchain with the given prestate
tx := new(types.Transaction)
- if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil {
+ if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil {
b.Fatalf("failed to parse testcase input: %v", err)
}
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
@@ -211,15 +210,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
Origin: origin,
GasPrice: tx.GasPrice(),
}
- context := vm.BlockContext{
- CanTransfer: core.CanTransfer,
- Transfer: core.Transfer,
- Coinbase: test.Context.Miner,
- BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
- Time: uint64(test.Context.Time),
- Difficulty: (*big.Int)(test.Context.Difficulty),
- GasLimit: uint64(test.Context.GasLimit),
- }
+ context := test.Context.toBlockContext(test.Genesis)
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
if err != nil {
b.Fatalf("failed to prepare transaction for tracing: %v", err)
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json
index 26495dfbce..7acb221666 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json
@@ -44,6 +44,7 @@
"result": [
{
"action": {
+ "creationMethod": "create",
"from": "0xf8bda96b67036ee48107f2a0695ea673479dda56",
"gas": "0x231860",
"init": "0x5b620186a05a131560135760016020526000565b600080601f600039601f565b6000f3",
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json
index 72a4db6901..a098b57029 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json
@@ -51,6 +51,7 @@
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x19f78",
@@ -66,8 +67,7 @@
"transactionPosition": 74,
"transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4",
"blockNumber": 1555279,
- "blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46",
- "time": "209.346µs"
+ "blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46"
},
{
"action": {
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json
index 0c4d29dd5b..6baa57689f 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json
@@ -51,6 +51,7 @@
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x1a758",
@@ -66,8 +67,7 @@
"transactionPosition": 141,
"transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1",
"blockNumber": 1555278,
- "blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b",
- "time": "300.9µs"
+ "blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b"
},
{
"type": "call",
@@ -80,9 +80,7 @@
"callType": "callcode"
},
"error": "out of gas",
- "traceAddress": [
- 0
- ],
+ "traceAddress": [0],
"subtraces": 0,
"transactionPosition": 141,
"transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1",
@@ -90,4 +88,4 @@
"blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b"
}
]
-}
\ No newline at end of file
+}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json
index 5538a708ea..8949dcfe57 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json
@@ -51,6 +51,7 @@
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x1a034",
@@ -62,8 +63,7 @@
"transactionPosition": 117,
"transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9",
"blockNumber": 1555275,
- "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd",
- "time": "332.877µs"
+ "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd"
},
{
"type": "call",
@@ -76,9 +76,7 @@
"callType": "callcode"
},
"error": "invalid input length",
- "traceAddress": [
- 0
- ],
+ "traceAddress": [0],
"subtraces": 0,
"transactionPosition": 117,
"transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9",
@@ -86,4 +84,4 @@
"blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd"
}
]
-}
\ No newline at end of file
+}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json
index 83d20fb078..2de8f8d4d5 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json
@@ -47,6 +47,7 @@
"result": [
{
"action": {
+ "creationMethod": "create",
"from": "0x13e4acefe6a6700604929946e70e6443e4e73447",
"gas": "0x897be",
"init": "0x606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a11",
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create_oog_parity.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create_oog_parity.json
new file mode 100644
index 0000000000..5e79e6ad45
--- /dev/null
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create_oog_parity.json
@@ -0,0 +1,94 @@
+{
+ "genesis": {
+ "difficulty": "4639933",
+ "extraData": "0xd883010b05846765746888676f312e31342e33856c696e7578",
+ "gasLimit": "9280188",
+ "hash": "0x9a5f3a98eb1c60f6e3f450658a9cea190157e7021d04f927b752ad6482cf9194",
+ "miner": "0x73f26d124436b0791169d63a3af29c2ae47765a3",
+ "mixHash": "0x6b6f8fcaa54b8565c4c1ae7cf0a020e938a53007f4561e758b17bc05c9044d78",
+ "nonce": "0x773aba50dc51b462",
+ "number": "1555169",
+ "stateRoot": "0xc4b9703de3e59ff795baae2c3afa010cf039c37244a7a6af7f3f491a10601348",
+ "timestamp": "1590794111",
+ "totalDifficulty": "2242105342155",
+ "alloc": {
+ "0x5ac5599fc9df172c89ee7ec55ad9104ccbfed40d": {
+ "balance": "0x0",
+ "nonce": "0",
+ "code": "0x",
+ "storage": {}
+ },
+ "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
+ "balance": "0x62325b40cbbd0915c4b9",
+ "nonce": "260875",
+ "code": "0x",
+ "storage": {}
+ }
+ },
+ "config": {
+ "chainId": 63,
+ "daoForkSupport": true,
+ "eip150Block": 0,
+ "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
+ "eip155Block": 0,
+ "eip158Block": 0,
+ "ethash": {},
+ "homesteadBlock": 0,
+ "byzantiumBlock": 0,
+ "constantinopleBlock": 301243,
+ "petersburgBlock": 999983,
+ "istanbulBlock": 999983
+ }
+ },
+ "context": {
+ "number": "1555170",
+ "difficulty": "4642198",
+ "timestamp": "1590794112",
+ "gasLimit": "9289249",
+ "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
+ },
+ "input": "0xf8658303fb0b843b9aca0083019ee48080915a600055600060006000f0505a6001550081a2a01a7deb3a16d967b766459ef486b00656c6581e5ad58968184a33701e27e0eb8aa07162ccdfe2018d64360a605310a62c399dd586c7282dd42a88c54f02f51d451f",
+ "tracerConfig": {
+ "convertParityErrors": true
+ },
+ "result": [
+ {
+ "type": "create",
+ "action": {
+ "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
+ "value": "0x0",
+ "gas": "0x19ee4",
+ "init": "0x5a600055600060006000f0505a60015500",
+ "creationMethod": "create"
+ },
+ "error": "Out of gas",
+ "traceAddress": [],
+ "subtraces": 1,
+ "transactionPosition": 63,
+ "transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650",
+ "blockNumber": 1555170,
+ "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e"
+ },
+ {
+ "type": "create",
+ "action": {
+ "from": "0x9c5cfe45b15eaff4ad617af4250189e26024a4f8",
+ "value": "0x0",
+ "gas": "0x3cb",
+ "init": "0x",
+ "creationMethod": "create"
+ },
+ "result": {
+ "gasUsed": "0x0",
+ "code": "0x",
+ "address": "0x5ac5599fc9df172c89ee7ec55ad9104ccbfed40d"
+ },
+ "traceAddress": [0],
+ "subtraces": 0,
+ "transactionPosition": 63,
+ "transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650",
+ "blockNumber": 1555170,
+ "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e"
+ }
+ ]
+}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json
index 250c402808..2fad32afe2 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json
@@ -51,6 +51,7 @@
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x1a9c8",
@@ -66,8 +67,7 @@
"transactionPosition": 18,
"transactionHash": "0xc1c42a325856d513523aec464811923b2e2926f54015c7ba37877064cf889803",
"blockNumber": 1555275,
- "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd",
- "time": "453.925µs"
+ "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd"
},
{
"type": "call",
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json
index 3747d7f0f8..0af816e683 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json
@@ -71,6 +71,7 @@
},
{
"action": {
+ "creationMethod": "create",
"from": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a",
"gas": "0x39ff0",
"init": "0x606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182",
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json
index 7dc6cc8098..4383af2d8a 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json
@@ -51,6 +51,7 @@
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x53e90",
@@ -66,12 +67,12 @@
"transactionPosition": 23,
"transactionHash": "0xe267552ce8437a5bc7081385c99f912de5723ad34b958db215dbc41abd5f6c03",
"blockNumber": 555462,
- "blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1",
- "time": "1.147715ms"
+ "blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1"
},
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x9db7a1baf185a865ffee3824946ccd8958191e5e",
"value": "0x0",
"gas": "0x30b34",
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json
index 82692d181a..9fe9ba2b9d 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json
@@ -51,6 +51,7 @@
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x19ed8",
@@ -66,12 +67,12 @@
"transactionPosition": 31,
"transactionHash": "0x1257b698c5833c54ce786734087002b097275abc3877af082b5c2a538e894a41",
"blockNumber": 1555161,
- "blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171",
- "time": "889.048µs"
+ "blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171"
},
{
"type": "create",
"action": {
+ "creationMethod": "create2",
"from": "0x2e8eded627eead210cb6143eb39ef7a3e44e4f00",
"value": "0x0",
"gas": "0x5117",
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json
index d9595a7210..f8ad3b5b0e 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json
@@ -51,6 +51,7 @@
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x19ee4",
@@ -62,12 +63,12 @@
"transactionPosition": 63,
"transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650",
"blockNumber": 1555170,
- "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e",
- "time": "952.736µs"
+ "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e"
},
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x9c5cfe45b15eaff4ad617af4250189e26024a4f8",
"value": "0x0",
"gas": "0x3cb",
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json
index cb4954d9b7..41199e90e3 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json
@@ -73,11 +73,11 @@
"transactionPosition": 26,
"transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4",
"blockNumber": 839247,
- "blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c",
- "time": "182.267µs"
+ "blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c"
},
{
"action": {
+ "creationMethod": "create",
"from": "0x76554b33410b6d90b7dc889bfed0451ad195f27e",
"gas": "0x25a18",
"init": "0x0000000000000000000000000000000000000000000000000000000000000000",
@@ -90,4 +90,4 @@
"type": "create"
}
]
-}
\ No newline at end of file
+}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json
index b8b20e1b8c..a7421d294d 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json
@@ -96,6 +96,7 @@
"result": [
{
"action": {
+ "creationMethod": "create",
"from": "0x5409ed021d9299bf6814279a6a1411a7e866a631",
"gas": "0x2c8c7f",
"init": "0x60806040523480156200001157600080fd5b5060405162002d2c38038062002d2c83398101806040526200003791908101906200051d565b6000805433600160a060020a031991821617825560018054909116600160a060020a0386161790558251849084908490849081906200007e906004906020870190620003d0565b50825162000094906005906020860190620003d0565b50620000b0836010640100000000620019476200036f82021704565b9150620000cd846010640100000000620019476200036f82021704565b60028054600160a060020a03948516600160a060020a031991821617909155600380549285169290911691909117905550600154604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130181207f6070410800000000000000000000000000000000000000000000000000000000825291909216945063607041089350620001739250906004016200068e565b602060405180830381600087803b1580156200018e57600080fd5b505af1158015620001a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620001c99190810190620004f4565b9050600160a060020a038116151562000219576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200021090620006b0565b60405180910390fd5b6002546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b39062000268908490600019906004016200066f565b602060405180830381600087803b1580156200028357600080fd5b505af115801562000298573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620002be9190810190620005a1565b506003546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b3906200030e908490600019906004016200066f565b602060405180830381600087803b1580156200032957600080fd5b505af11580156200033e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620003649190810190620005a1565b50505050506200077a565b600081601401835110151515620003b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000210906200069e565b506014818301810151910190600160a060020a03165b92915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200041357805160ff191683800117855562000443565b8280016001018555821562000443579182015b828111156200044357825182559160200191906001019062000426565b506200045192915062000455565b5090565b6200047291905b808211156200045157600081556001016200045c565b90565b600062000483825162000711565b9392505050565b600062000483825162000742565b6000601f82018313620004aa57600080fd5b8151620004c1620004bb82620006e9565b620006c2565b91508082526020830160208301858383011115620004de57600080fd5b620004eb83828462000747565b50505092915050565b6000602082840312156200050757600080fd5b600062000515848462000475565b949350505050565b6000806000606084860312156200053357600080fd5b600062000541868662000475565b93505060208401516001604060020a038111156200055e57600080fd5b6200056c8682870162000498565b92505060408401516001604060020a038111156200058957600080fd5b620005978682870162000498565b9150509250925092565b600060208284031215620005b457600080fd5b60006200051584846200048a565b620005cd8162000711565b82525050565b620005cd816200071d565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601881527f554e524547495354455245445f41535345545f50524f58590000000000000000602082015260400190565b620005cd8162000472565b604081016200067f8285620005c2565b62000483602083018462000664565b60208101620003ca8284620005d3565b60208082528101620003ca81620005de565b60208082528101620003ca8162000634565b6040518181016001604060020a0381118282101715620006e157600080fd5b604052919050565b60006001604060020a038211156200070057600080fd5b506020601f91909101601f19160190565b600160a060020a031690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b151590565b60005b83811015620007645781810151838201526020016200074a565b8381111562000774576000848401525b50505050565b6125a2806200078a6000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318978e8281146100c8578063630f1e6c146100f25780638da5cb5b146101125780639395525c14610134578063f2fde38b14610147575b60025473ffffffffffffffffffffffffffffffffffffffff1633146100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612388565b60405180910390fd5b005b6100db6100d6366004611df1565b610167565b6040516100e9929190612488565b60405180910390f35b3480156100fe57600080fd5b506100c661010d366004611eec565b6102f7565b34801561011e57600080fd5b50610127610388565b6040516100e99190612337565b6100db610142366004611d0b565b6103a4565b34801561015357600080fd5b506100c6610162366004611ce5565b61050a565b61016f6119fa565b6101776119fa565b6000806101826105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815261025c939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b50505050508c600081518110151561024157fe5b6020908102909101015161014001519063ffffffff61069616565b156102875761026c8b8b8b6107c3565b935061028084600001518560600151610ac1565b90506102ae565b6102928b8b8b610b03565b9350836060015191506102a68883896107c3565b845190935090505b6102c2846020015184602001518888610d15565b6102e98b60008151811015156102d457fe5b90602001906020020151610140015182610f29565b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610348576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b61038383838080601f01602080910402602001604051908101604052809392919081815260200183838082843750879450610f299350505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6103ac6119fa565b6103b46119fa565b60008060006103c16105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152610441939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b156104925761046a670de0b6b3a7640000610464670de0b6b3a76400008a611045565b3461108f565b92506104778b848c6110e7565b945061048b85600001518660600151610ac1565b90506104d6565b6104ad670d2f13f7789f0000670de0b6b3a76400003461108f565b92506104ba8b848c6110e7565b9450846060015191506104ce89838a6107c3565b855190945090505b6104ea856020015185602001518989610d15565b6104fc8b60008151811015156102d457fe5b505050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461055b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b73ffffffffffffffffffffffffffffffffffffffff8116156105b857600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b600034116105f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612398565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b5050505050565b6000815183511480156107ba5750816040518082805190602001908083835b602083106106f257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016106b5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604051919093018190038120885190955088945090928392508401908083835b6020831061078757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161074a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b90505b92915050565b6107cb6119fa565b60608060008060008060006107de6119fa565b8a15156107ea57610ab2565b6004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561088e5780601f106108635761010080835404028352916020019161088e565b820191906000526020600020905b81548152906001019060200180831161087157829003601f168201915b505060058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152969e509194509250840190508282801561093d5780601f106109125761010080835404028352916020019161093d565b820191906000526020600020905b81548152906001019060200180831161092057829003601f168201915b50505050509650600095508b519450600093505b838514610a7857878c8581518110151561096757fe5b6020908102909101015161014001528b5187908d908690811061098657fe5b60209081029091010151610160015261099f8b87610ac1565b9250610a068c858151811015156109b257fe5b9060200190602002015160a00151610a008e878151811015156109d157fe5b90602001906020020151608001518f888151811015156109ed57fe5b9060200190602002015160e00151610ac1565b8561128b565b9150610a418c85815181101515610a1957fe5b90602001906020020151838c87815181101515610a3257fe5b906020019060200201516112e6565b9050610a4d898261135e565b610a5f89600001518a60600151610ac1565b95508a8610610a6d57610a78565b600190930192610951565b8a861015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b50505050505050509392505050565b600082821115610afd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123b8565b50900390565b610b0b6119fa565b606080600080600080610b1c6119fa565b60008b6000815181101515610b2d57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929b5092909190830182828015610be55780601f10610bba57610100808354040283529160200191610be5565b820191906000526020600020905b815481529060010190602001808311610bc857829003601f168201915b505050505096508b519550600094505b848614610cdb57878c86815181101515610c0b57fe5b6020908102909101015161014001528b5187908d9087908110610c2a57fe5b6020908102909101015161016001528851610c46908c90610ac1565b9350610c898c86815181101515610c5957fe5b9060200190602002015160a001518d87815181101515610c7557fe5b90602001906020020151608001518661128b565b9250610cb58c86815181101515610c9c57fe5b90602001906020020151848c88815181101515610a3257fe5b9150610cc1898361135e565b5087518a8110610cd057610cdb565b600190940193610bf5565b8a811015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b600080808066b1a2bc2ec50000861115610d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612448565b610d658888611045565b935034841115610da1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123a8565b610dab3485610ac1565b9250610dc086670de0b6b3a76400008a61108f565b915082821115610dfc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612428565b6000831115610f1f576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90610e5b9086906004016124a4565b600060405180830381600087803b158015610e7557600080fd5b505af1158015610e89573d6000803e3d6000fd5b505050506000821115610edb5760405173ffffffffffffffffffffffffffffffffffffffff86169083156108fc029084906000818181858888f19350505050158015610ed9573d6000803e3d6000fd5b505b610ee58383610ac1565b90506000811115610f1f57604051339082156108fc029083906000818181858888f19350505050158015610f1d573d6000803e3d6000fd5b505b5050505050505050565b6000610f3b838263ffffffff6113c016565b604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190209091507fffffffff0000000000000000000000000000000000000000000000000000000080831691161415610fab57610fa6838361142d565b610383565b604080517f455243373231546f6b656e28616464726573732c75696e7432353629000000008152905190819003601c0190207fffffffff000000000000000000000000000000000000000000000000000000008281169116141561101357610fa6838361161b565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123f8565b600082820183811015611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b8091505b5092915050565b60008083116110ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d78584611703565b8461175e565b90505b9392505050565b6110ef6119fa565b60608060008060006110ff6119fa565b89600081518110151561110e57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929950929091908301828280156111c65780601f1061119b576101008083540402835291602001916111c6565b820191906000526020600020905b8154815290600101906020018083116111a957829003601f168201915b5050505050945089519350600092505b82841461127e57858a848151811015156111ec57fe5b602090810290910101516101400152895185908b908590811061120b57fe5b90602001906020020151610160018190525061122b898860200151610ac1565b91506112578a8481518110151561123e57fe5b90602001906020020151838a86815181101515610a3257fe5b9050611263878261135e565b602087015189116112735761127e565b6001909201916111d6565b5050505050509392505050565b60008083116112c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d76112d68685611703565b6112e1866001610ac1565b611045565b6112ee6119fa565b606060006112fd868686611775565b600154815191935073ffffffffffffffffffffffffffffffffffffffff1691506080908390602082016000855af1801561135457825184526020830151602085015260408301516040850152606083015160608501525b5050509392505050565b8151815161136c9190611045565b8252602080830151908201516113829190611045565b60208301526040808301519082015161139b9190611045565b6040830152606080830151908201516113b49190611045565b60609092019190915250565b600081600401835110151515611402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612468565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b60008061144184601063ffffffff61194716565b604080517f7472616e7366657228616464726573732c75696e7432353629000000000000008152905190819003601901812091935073ffffffffffffffffffffffffffffffffffffffff8416919061149f903390879060240161236d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783525181519192909182919080838360005b8381101561154357818101518382015260200161152b565b50505050905090810190601f1680156115705780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1925050508015156115bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b3d156115dc575060003d602014156115dc5760206000803e506000515b801515611615576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b50505050565b60008060018314611658576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612478565b61166984601063ffffffff61194716565b915061167c84602463ffffffff6119a816565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8316906323b872dd906116d590309033908690600401612345565b600060405180830381600087803b1580156116ef57600080fd5b505af1158015610f1f573d6000803e3d6000fd5b6000808315156117165760009150611088565b5082820282848281151561172657fe5b0414611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b600080828481151561176c57fe5b04949350505050565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000006020808301919091526060602483018181528751608485019081528884015160a48601529488015160c48501529087015160e4840152608087015161010484015260a087015161012484015260c087015161014484015260e08701516101648401526101008701516101848401526101208701516101a4840152610140870180516101c485019081526101608901516101e4860152610180905251805161020485018190529394919384936044870192849261022489019291820191601f82010460005b8181101561187c57835185526020948501949093019260010161185e565b50505050818103610160808401919091528a0151805180835260209283019291820191601f82010460005b818110156118c55783518552602094850194909301926001016118a7565b50505089845250848103602093840190815288518083529093918201918981019190601f82010460005b8181101561190d5783518552602094850194909301926001016118ef565b5050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08883030188525060405250505050509392505050565b600081601401835110151515611989576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612458565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b60006107ba83836000816020018351101515156119f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123c8565b50016020015190565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b60006107ba8235612540565b6000601f82018313611a4057600080fd5b8135611a53611a4e826124d9565b6124b2565b81815260209384019390925082018360005b83811015611a915781358601611a7b8882611b41565b8452506020928301929190910190600101611a65565b5050505092915050565b6000601f82018313611aac57600080fd5b8135611aba611a4e826124d9565b81815260209384019390925082018360005b83811015611a915781358601611ae28882611b90565b8452506020928301929190910190600101611acc565b600080601f83018413611b0a57600080fd5b50813567ffffffffffffffff811115611b2257600080fd5b602083019150836001820283011115611b3a57600080fd5b9250929050565b6000601f82018313611b5257600080fd5b8135611b60611a4e826124fa565b91508082526020830160208301858383011115611b7c57600080fd5b611b8783828461255c565b50505092915050565b60006101808284031215611ba357600080fd5b611bae6101806124b2565b90506000611bbc8484611a23565b8252506020611bcd84848301611a23565b6020830152506040611be184828501611a23565b6040830152506060611bf584828501611a23565b6060830152506080611c0984828501611cd9565b60808301525060a0611c1d84828501611cd9565b60a08301525060c0611c3184828501611cd9565b60c08301525060e0611c4584828501611cd9565b60e083015250610100611c5a84828501611cd9565b61010083015250610120611c7084828501611cd9565b6101208301525061014082013567ffffffffffffffff811115611c9257600080fd5b611c9e84828501611b41565b6101408301525061016082013567ffffffffffffffff811115611cc057600080fd5b611ccc84828501611b41565b6101608301525092915050565b60006107ba8235612559565b600060208284031215611cf757600080fd5b6000611d038484611a23565b949350505050565b60008060008060008060c08789031215611d2457600080fd5b863567ffffffffffffffff811115611d3b57600080fd5b611d4789828a01611a9b565b965050602087013567ffffffffffffffff811115611d6457600080fd5b611d7089828a01611a2f565b955050604087013567ffffffffffffffff811115611d8d57600080fd5b611d9989828a01611a9b565b945050606087013567ffffffffffffffff811115611db657600080fd5b611dc289828a01611a2f565b9350506080611dd389828a01611cd9565b92505060a0611de489828a01611a23565b9150509295509295509295565b600080600080600080600060e0888a031215611e0c57600080fd5b873567ffffffffffffffff811115611e2357600080fd5b611e2f8a828b01611a9b565b9750506020611e408a828b01611cd9565b965050604088013567ffffffffffffffff811115611e5d57600080fd5b611e698a828b01611a2f565b955050606088013567ffffffffffffffff811115611e8657600080fd5b611e928a828b01611a9b565b945050608088013567ffffffffffffffff811115611eaf57600080fd5b611ebb8a828b01611a2f565b93505060a0611ecc8a828b01611cd9565b92505060c0611edd8a828b01611a23565b91505092959891949750929550565b600080600060408486031215611f0157600080fd5b833567ffffffffffffffff811115611f1857600080fd5b611f2486828701611af8565b93509350506020611f3786828701611cd9565b9150509250925092565b611f4a81612540565b82525050565b602381527f44454641554c545f46554e4354494f4e5f574554485f434f4e54524143545f4f60208201527f4e4c590000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f494e56414c49445f4d53475f56414c5545000000000000000000000000000000602082015260400190565b600d81527f4f564552534f4c445f5745544800000000000000000000000000000000000000602082015260400190565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4449564953494f4e5f42595f5a45524f00000000000000000000000000000000602082015260400190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b601781527f554e535550504f525445445f41535345545f50524f5859000000000000000000602082015260400190565b600f81527f5452414e534645525f4641494c45440000000000000000000000000000000000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601a81527f494e53554646494349454e545f4554485f52454d41494e494e47000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b601881527f4645455f50455243454e544147455f544f4f5f4c415247450000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b600e81527f494e56414c49445f414d4f554e54000000000000000000000000000000000000602082015260400190565b805160808301906122f9848261232e565b50602082015161230c602085018261232e565b50604082015161231f604085018261232e565b50606082015161161560608501825b611f4a81612559565b602081016107bd8284611f41565b606081016123538286611f41565b6123606020830185611f41565b611d03604083018461232e565b6040810161237b8285611f41565b6110e0602083018461232e565b602080825281016107bd81611f50565b602080825281016107bd81611fa6565b602080825281016107bd81611fd6565b602080825281016107bd81612006565b602080825281016107bd81612036565b602080825281016107bd8161208c565b602080825281016107bd816120bc565b602080825281016107bd816120ec565b602080825281016107bd8161211c565b602080825281016107bd8161214c565b602080825281016107bd8161217c565b602080825281016107bd816121ac565b602080825281016107bd816121dc565b602080825281016107bd8161220c565b602080825281016107bd81612262565b602080825281016107bd816122b8565b610100810161249782856122e8565b6110e060808301846122e8565b602081016107bd828461232e565b60405181810167ffffffffffffffff811182821017156124d157600080fd5b604052919050565b600067ffffffffffffffff8211156124f057600080fd5b5060209081020190565b600067ffffffffffffffff82111561251157600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b828183375060009101525600a265627a7a72305820d9f418f11e0f91f06f6f9d22924be0add925495eeb76a6388b5417adb505eeb36c6578706572696d656e74616cf5003700000000000000000000000048bacb9266a570d521063ef5dd96e61686dbe788000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e808200000000000000000000000000000000000000000000000000000000",
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json
index f6215a2b3f..544fff9dd3 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json
@@ -80,8 +80,7 @@
"transactionPosition": 5,
"transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada",
"blockNumber": 553416,
- "blockHash": "0x8df024322173d225a09681d35edeaa528aca60743a11a70f854c158862bf5282",
- "time": "617.42µs"
+ "blockHash": "0x8df024322173d225a09681d35edeaa528aca60743a11a70f854c158862bf5282"
},
{
"type": "call",
@@ -97,9 +96,7 @@
"gasUsed": "0x0",
"output": "0x"
},
- "traceAddress": [
- 0
- ],
+ "traceAddress": [0],
"subtraces": 0,
"transactionPosition": 5,
"transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada",
@@ -107,4 +104,4 @@
"blockHash": "0x8df024322173d225a09681d35edeaa528aca60743a11a70f854c158862bf5282"
}
]
-}
\ No newline at end of file
+}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json
index c8c6dc65c1..d7b4a22cf5 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json
@@ -51,6 +51,7 @@
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x19ecc",
@@ -66,11 +67,11 @@
"transactionPosition": 14,
"transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",
"blockNumber": 1555146,
- "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e",
- "time": "187.145µs"
+ "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e"
},
{
"action": {
+ "creationMethod": "create",
"from": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca",
"gas": "0x50ac",
"init": "0x5a",
@@ -90,9 +91,7 @@
"balance": "0x0"
},
"result": null,
- "traceAddress": [
- 1
- ],
+ "traceAddress": [1],
"subtraces": 0,
"transactionPosition": 14,
"transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",
@@ -100,4 +99,4 @@
"blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e"
}
]
-}
\ No newline at end of file
+}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json
index a25f2383d6..6e020fe2b7 100644
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json
+++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json
@@ -51,6 +51,7 @@
{
"type": "create",
"action": {
+ "creationMethod": "create",
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x1aab0",
@@ -62,11 +63,11 @@
"transactionPosition": 16,
"transactionHash": "0x384487e5ae8d2997aece8e28403d393cb9752425e6de358891bed981c5af1c05",
"blockNumber": 1555285,
- "blockHash": "0x93231d8e9662adb4c5c703583a92c7b3112cd5448f43ab4fa1f0f00a0183ed3f",
- "time": "665.278µs"
+ "blockHash": "0x93231d8e9662adb4c5c703583a92c7b3112cd5448f43ab4fa1f0f00a0183ed3f"
},
{
"action": {
+ "creationMethod": "create",
"from": "0xf84bf5189ccd19f5897739756d214fa0dc099e0d",
"gas": "0x1d5c",
"init": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
@@ -79,4 +80,4 @@
"type": "create"
}
]
-}
\ No newline at end of file
+}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json
new file mode 100644
index 0000000000..d60c3d7385
--- /dev/null
+++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json
@@ -0,0 +1,83 @@
+{
+ "context": {
+ "difficulty": "3502894804",
+ "gasLimit": "4722976",
+ "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
+ "number": "2289806",
+ "timestamp": "1513601314"
+ },
+ "genesis": {
+ "alloc": {
+ "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
+ "balance": "0x0",
+ "code": "0x",
+ "nonce": "22",
+ "storage": {}
+ },
+ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
+ "balance": "0x4d87094125a369d9bd5",
+ "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
+ "nonce": "1",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
+ "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
+ }
+ },
+ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
+ "balance": "0x1780d77678137ac1b775",
+ "code": "0x",
+ "nonce": "29072",
+ "storage": {}
+ }
+ },
+ "config": {
+ "byzantiumBlock": 1700000,
+ "chainId": 3,
+ "eip150Block": 0,
+ "eip155Block": 10,
+ "eip158Block": 10,
+ "ethash": {},
+ "homesteadBlock": 0
+ },
+ "difficulty": "3509749784",
+ "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
+ "gasLimit": "4727564",
+ "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
+ "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
+ "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
+ "nonce": "0x4eb12e19c16d43da",
+ "number": "2289805",
+ "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
+ "timestamp": "1513601261",
+ "totalDifficulty": "7143276353481064"
+ },
+ "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
+ "tracerConfig": {
+ "disableCode": true
+ },
+ "result": {
+ "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
+ "balance": "0x0",
+ "nonce": 22
+ },
+ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
+ "balance": "0x4d87094125a369d9bd5",
+ "nonce": 1,
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
+ "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
+ }
+ },
+ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
+ "balance": "0x1780d77678137ac1b775",
+ "nonce": 29072
+ },
+ "0x1585936b53834b021f68cc13eeefdec2efc8e724": {
+ "balance": "0x0"
+ }
+ }
+}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json
new file mode 100644
index 0000000000..b37dfa90a1
--- /dev/null
+++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json
@@ -0,0 +1,78 @@
+{
+ "context": {
+ "difficulty": "3502894804",
+ "gasLimit": "4722976",
+ "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
+ "number": "2289806",
+ "timestamp": "1513601314"
+ },
+ "genesis": {
+ "alloc": {
+ "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
+ "balance": "0x0",
+ "code": "0x",
+ "nonce": "22",
+ "storage": {}
+ },
+ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
+ "balance": "0x4d87094125a369d9bd5",
+ "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
+ "nonce": "1",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
+ "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
+ }
+ },
+ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
+ "balance": "0x1780d77678137ac1b775",
+ "code": "0x",
+ "nonce": "29072",
+ "storage": {}
+ }
+ },
+ "config": {
+ "byzantiumBlock": 1700000,
+ "chainId": 3,
+ "eip150Block": 0,
+ "eip155Block": 10,
+ "eip158Block": 10,
+ "ethash": {},
+ "homesteadBlock": 0
+ },
+ "difficulty": "3509749784",
+ "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
+ "gasLimit": "4727564",
+ "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
+ "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
+ "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
+ "nonce": "0x4eb12e19c16d43da",
+ "number": "2289805",
+ "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
+ "timestamp": "1513601261",
+ "totalDifficulty": "7143276353481064"
+ },
+ "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
+ "tracerConfig": {
+ "disableCode": true,
+ "disableStorage": true
+ },
+ "result": {
+ "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
+ "balance": "0x0",
+ "nonce": 22
+ },
+ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
+ "balance": "0x4d87094125a369d9bd5",
+ "nonce": 1
+ },
+ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
+ "balance": "0x1780d77678137ac1b775",
+ "nonce": 29072
+ },
+ "0x1585936b53834b021f68cc13eeefdec2efc8e724": {
+ "balance": "0x0"
+ }
+ }
+}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json
new file mode 100644
index 0000000000..43d6e03b44
--- /dev/null
+++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json
@@ -0,0 +1,78 @@
+{
+ "context": {
+ "difficulty": "3502894804",
+ "gasLimit": "4722976",
+ "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
+ "number": "2289806",
+ "timestamp": "1513601314"
+ },
+ "genesis": {
+ "alloc": {
+ "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
+ "balance": "0x0",
+ "code": "0x",
+ "nonce": "22",
+ "storage": {}
+ },
+ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
+ "balance": "0x4d87094125a369d9bd5",
+ "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
+ "nonce": "1",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
+ "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
+ }
+ },
+ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
+ "balance": "0x1780d77678137ac1b775",
+ "code": "0x",
+ "nonce": "29072",
+ "storage": {}
+ }
+ },
+ "config": {
+ "byzantiumBlock": 1700000,
+ "chainId": 3,
+ "eip150Block": 0,
+ "eip155Block": 10,
+ "eip158Block": 10,
+ "ethash": {},
+ "homesteadBlock": 0
+ },
+ "difficulty": "3509749784",
+ "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
+ "gasLimit": "4727564",
+ "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
+ "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
+ "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
+ "nonce": "0x4eb12e19c16d43da",
+ "number": "2289805",
+ "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
+ "timestamp": "1513601261",
+ "totalDifficulty": "7143276353481064"
+ },
+ "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
+ "tracerConfig": {
+ "disableStorage": true
+ },
+ "result": {
+ "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
+ "balance": "0x0",
+ "nonce": 22
+ },
+ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
+ "balance": "0x4d87094125a369d9bd5",
+ "nonce": 1,
+ "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029"
+ },
+ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
+ "balance": "0x1780d77678137ac1b775",
+ "nonce": 29072
+ },
+ "0x1585936b53834b021f68cc13eeefdec2efc8e724": {
+ "balance": "0x0"
+ }
+ }
+}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_code.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_code.json
new file mode 100644
index 0000000000..5d7c024a5e
--- /dev/null
+++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_code.json
@@ -0,0 +1,100 @@
+{
+ "genesis": {
+ "difficulty": "13756228101629",
+ "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773",
+ "gasLimit": "3141592",
+ "hash": "0x58b7a87b6ba10b46b4e251d64ebc3d9822dd82218eaf24dff6796f6f1f687251",
+ "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
+ "mixHash": "0x5984b9a316116bd890e6e5f4c52d655184b0d7aa74821e1382d7760f9803c1dd",
+ "nonce": "0xea4bb4997242c681",
+ "number": "1061221",
+ "stateRoot": "0x5402c04d481414248d824c3b61e924e0c9307adbc9fbaae774a74cce30a4163d",
+ "timestamp": "1456458069",
+ "totalDifficulty": "7930751135586064334",
+ "alloc": {
+ "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
+ "balance": "0x9fb6b81e112638b886",
+ "nonce": "217865",
+ "code": "0x"
+ },
+ "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": {
+ "balance": "0x15b6828e22bb12188",
+ "nonce": "747",
+ "code": "0x"
+ }
+ },
+ "config": {
+ "chainId": 1,
+ "homesteadBlock": 1150000,
+ "daoForkBlock": 1920000,
+ "eip150Block": 2463000,
+ "eip155Block": 2675000,
+ "eip158Block": 2675000,
+ "byzantiumBlock": 4370000,
+ "constantinopleBlock": 7280000,
+ "petersburgBlock": 7280000,
+ "istanbulBlock": 9069000,
+ "muirGlacierBlock": 9200000,
+ "berlinBlock": 12244000,
+ "londonBlock": 12965000,
+ "arrowGlacierBlock": 13773000,
+ "grayGlacierBlock": 15050000,
+ "ethash": {}
+ }
+ },
+ "context": {
+ "number": "1061222",
+ "difficulty": "13749511193633",
+ "timestamp": "1456458097",
+ "gasLimit": "3141592",
+ "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226"
+ },
+ "input": "0xf905498202eb850ba43b7400830f42408080b904f460606040526040516102b43803806102b48339016040526060805160600190602001505b5b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b806001600050908051906020019082805482825590600052602060002090601f01602090048101928215609e579182015b82811115609d5782518260005055916020019190600101906081565b5b50905060c5919060a9565b8082111560c1576000818150600090555060010160a9565b5090565b50505b506101dc806100d86000396000f30060606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001ee7b225f6964223a225a473466784a7245323639384866623839222c22666f726d5f736f75726365223a22434c54523031222c22636f6d6d69746d656e745f64617465223a22222c22626f72726f7765725f6e616d65223a22222c22626f72726f7765725f616464726573735f6c696e6531223a22222c22626f72726f7765725f616464726573735f6c696e6532223a22222c22626f72726f7765725f636f6e74616374223a22222c22626f72726f7765725f7374617465223a22222c22626f72726f7765725f74797065223a22222c2270726f70657274795f61646472657373223a22222c226c6f616e5f616d6f756e745f7772697474656e223a22222c226c6f616e5f616d6f756e74223a22222c224c54565f7772697474656e223a22222c224c5456223a22222c2244534352223a22222c2270726f70657274795f74797065223a22222c2270726f70657274795f6465736372697074696f6e223a22222c226c656e646572223a22222c2267756172616e746f7273223a22222c226c696d69746564223a22222c226361705f616d6f756e74223a22222c226361705f70657263656e745f7772697474656e223a22222c226361705f70657263656e74616765223a22222c227465726d5f7772697474656e223a22222c227465726d223a22222c22657874656e64223a22227d0000000000000000000000000000000000001ba027d54712289af34f0ec0f06092745104d68e5801cd17097bc1104111f855258da070ec9f1c942d9bedf89f9660a684d3bb8cd9c2ac7f6dd883cb3e26a193180244",
+ "tracerConfig": {
+ "diffMode": true,
+ "disableCode": true
+ },
+ "result": {
+ "pre": {
+ "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
+ "balance": "0x9fb6b81e112638b886",
+ "nonce": 217865
+ },
+ "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": {
+ "balance": "0x15b6828e22bb12188",
+ "nonce": 747
+ }
+ },
+ "post": {
+ "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
+ "balance": "0x9fb71abdd2621d8886"
+ },
+ "0x40f2f445da6c9047554683fb382fba6769717116": {
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f0c5cef39b17c213cfe090a46b8c7760ffb7928a",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000000000000000001ee",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6": "0x7b225f6964223a225a473466784a7245323639384866623839222c22666f726d",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7": "0x5f736f75726365223a22434c54523031222c22636f6d6d69746d656e745f6461",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8": "0x7465223a22222c22626f72726f7765725f6e616d65223a22222c22626f72726f",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9": "0x7765725f616464726573735f6c696e6531223a22222c22626f72726f7765725f",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa": "0x616464726573735f6c696e6532223a22222c22626f72726f7765725f636f6e74",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfb": "0x616374223a22222c22626f72726f7765725f7374617465223a22222c22626f72",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfc": "0x726f7765725f74797065223a22222c2270726f70657274795f61646472657373",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfd": "0x223a22222c226c6f616e5f616d6f756e745f7772697474656e223a22222c226c",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfe": "0x6f616e5f616d6f756e74223a22222c224c54565f7772697474656e223a22222c",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cff": "0x224c5456223a22222c2244534352223a22222c2270726f70657274795f747970",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d00": "0x65223a22222c2270726f70657274795f6465736372697074696f6e223a22222c",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d01": "0x226c656e646572223a22222c2267756172616e746f7273223a22222c226c696d",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d02": "0x69746564223a22222c226361705f616d6f756e74223a22222c226361705f7065",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d03": "0x7263656e745f7772697474656e223a22222c226361705f70657263656e746167",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d04": "0x65223a22222c227465726d5f7772697474656e223a22222c227465726d223a22",
+ "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d05": "0x222c22657874656e64223a22227d000000000000000000000000000000000000"
+ }
+ },
+ "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": {
+ "balance": "0x15b058920efcc5188",
+ "nonce": 748
+ }
+ }
+ }
+}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_storage.json
new file mode 100644
index 0000000000..65594feb44
--- /dev/null
+++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_storage.json
@@ -0,0 +1,81 @@
+{
+ "genesis": {
+ "difficulty": "13756228101629",
+ "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773",
+ "gasLimit": "3141592",
+ "hash": "0x58b7a87b6ba10b46b4e251d64ebc3d9822dd82218eaf24dff6796f6f1f687251",
+ "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
+ "mixHash": "0x5984b9a316116bd890e6e5f4c52d655184b0d7aa74821e1382d7760f9803c1dd",
+ "nonce": "0xea4bb4997242c681",
+ "number": "1061221",
+ "stateRoot": "0x5402c04d481414248d824c3b61e924e0c9307adbc9fbaae774a74cce30a4163d",
+ "timestamp": "1456458069",
+ "totalDifficulty": "7930751135586064334",
+ "alloc": {
+ "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
+ "balance": "0x9fb6b81e112638b886",
+ "nonce": "217865",
+ "code": "0x"
+ },
+ "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": {
+ "balance": "0x15b6828e22bb12188",
+ "nonce": "747",
+ "code": "0x"
+ }
+ },
+ "config": {
+ "chainId": 1,
+ "homesteadBlock": 1150000,
+ "daoForkBlock": 1920000,
+ "eip150Block": 2463000,
+ "eip155Block": 2675000,
+ "eip158Block": 2675000,
+ "byzantiumBlock": 4370000,
+ "constantinopleBlock": 7280000,
+ "petersburgBlock": 7280000,
+ "istanbulBlock": 9069000,
+ "muirGlacierBlock": 9200000,
+ "berlinBlock": 12244000,
+ "londonBlock": 12965000,
+ "arrowGlacierBlock": 13773000,
+ "grayGlacierBlock": 15050000,
+ "ethash": {}
+ }
+ },
+ "context": {
+ "number": "1061222",
+ "difficulty": "13749511193633",
+ "timestamp": "1456458097",
+ "gasLimit": "3141592",
+ "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226"
+ },
+ "input": "0xf905498202eb850ba43b7400830f42408080b904f460606040526040516102b43803806102b48339016040526060805160600190602001505b5b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b806001600050908051906020019082805482825590600052602060002090601f01602090048101928215609e579182015b82811115609d5782518260005055916020019190600101906081565b5b50905060c5919060a9565b8082111560c1576000818150600090555060010160a9565b5090565b50505b506101dc806100d86000396000f30060606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001ee7b225f6964223a225a473466784a7245323639384866623839222c22666f726d5f736f75726365223a22434c54523031222c22636f6d6d69746d656e745f64617465223a22222c22626f72726f7765725f6e616d65223a22222c22626f72726f7765725f616464726573735f6c696e6531223a22222c22626f72726f7765725f616464726573735f6c696e6532223a22222c22626f72726f7765725f636f6e74616374223a22222c22626f72726f7765725f7374617465223a22222c22626f72726f7765725f74797065223a22222c2270726f70657274795f61646472657373223a22222c226c6f616e5f616d6f756e745f7772697474656e223a22222c226c6f616e5f616d6f756e74223a22222c224c54565f7772697474656e223a22222c224c5456223a22222c2244534352223a22222c2270726f70657274795f74797065223a22222c2270726f70657274795f6465736372697074696f6e223a22222c226c656e646572223a22222c2267756172616e746f7273223a22222c226c696d69746564223a22222c226361705f616d6f756e74223a22222c226361705f70657263656e745f7772697474656e223a22222c226361705f70657263656e74616765223a22222c227465726d5f7772697474656e223a22222c227465726d223a22222c22657874656e64223a22227d0000000000000000000000000000000000001ba027d54712289af34f0ec0f06092745104d68e5801cd17097bc1104111f855258da070ec9f1c942d9bedf89f9660a684d3bb8cd9c2ac7f6dd883cb3e26a193180244",
+ "tracerConfig": {
+ "diffMode": true,
+ "disableStorage": true
+ },
+ "result": {
+ "pre": {
+ "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
+ "balance": "0x9fb6b81e112638b886",
+ "nonce": 217865
+ },
+ "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": {
+ "balance": "0x15b6828e22bb12188",
+ "nonce": 747
+ }
+ },
+ "post": {
+ "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
+ "balance": "0x9fb71abdd2621d8886"
+ },
+ "0x40f2f445da6c9047554683fb382fba6769717116": {
+ "code": "0x60606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056"
+ },
+ "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": {
+ "balance": "0x15b058920efcc5188",
+ "nonce": 748
+ }
+ }
+ }
+}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create_disable_code_and_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create_disable_code_and_storage.json
new file mode 100644
index 0000000000..96c93e7cf8
--- /dev/null
+++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create_disable_code_and_storage.json
@@ -0,0 +1,256 @@
+{
+ "genesis": {
+ "difficulty": "13707196986889",
+ "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773",
+ "gasLimit": "3141592",
+ "hash": "0x607b38fe7e94427ee8f3b9a62375c67f953f8d49e05dbfd0145f9d3bac142193",
+ "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
+ "mixHash": "0x98c74c9e76fd0078157e1696e4334a7e787396459693a84536d8b96414dafd5d",
+ "nonce": "0x77a5a0a73ad8745e",
+ "number": "1062502",
+ "stateRoot": "0x1df615df5fdbc8d5397bf3574f462f6d9696428eb8796d8e9252bccc8e3a8996",
+ "timestamp": "1456480432",
+ "totalDifficulty": "7948153536501153741",
+ "alloc": {
+ "0x0000000000000000000000000000000000000004": {
+ "balance": "0x0",
+ "code": "0x"
+ },
+ "0x1deeda36e15ec9e80f3d7414d67a4803ae45fc80": {
+ "balance": "0x0",
+ "code": "0x650200d2f18c7350606060405236156100c15760e060020a60003504630bd295e681146100c65780630fd1f94e1461017d5780630fee183d1461018c578063349501b7146101ad5780635054d98a146101c75780637c0278fc146101ef5780637e92656214610287578063a0943154146102f6578063a1873db61461030e578063a9d2293d14610355578063b5d0f16e146103ad578063c17e6817146103ce578063cc3471af1461046a578063da46be0a1461047a578063f55627531461052a575b610007565b6105d36004356024356044355b60006000600030915081600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515191505080841080610173575081600160a060020a031663a06db7dc6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050506040518051906020015060ff16810184115b1561100d57610007565b6105d3600060f0610f6d61046e565b6105d3600435602435604435606435600081600202831015610ff657610fee565b6105d36004355b600081600014156109115750600161098f565b6105d36004355b6008810154600090819062010000900460ff16156105f257600691506105ec565b60408051602060248035600481810135601f81018590048502860185019096528585526105e5958135959194604494929390920191819084018382808284375094965050505050505060006004825103836001016000508181546001816001161561010002031660029004825481601f106108005782601f1061083a575b826008026101000360020a80910402828001178355610851565b6105e5600435602435604051600090600160a060020a038316907f398bd6b21ae4164ec322fb0eb8c2eb6277f36fd41903fbbed594dfe125591281908390a26007830154819010610e415760078301546005840154610e3f9162010000909104600160a060020a0316906103d8565b6105d3600435602435600060006000611064856101ce565b6105d36004356024356044356004830154600090819030908410156110e4577f4e4f545f454e4f5547485f47415300000000000000000000000000000000000091506112dd565b6105d35b60006000309050600a81600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515160091901935050505b5090565b6105d36004356024355b60008282111561099e578183606402049050610998565b6105d36004356024355b600030600160a060020a0316318211156103fa57600160a060020a0330163191505b6000821115610994577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc84846040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100075750839250610998915050565b6105d35b6000600f610f6d610359565b6105e560043560243560443560643560843560088501805461ff00191661010017905584543090600090819081908190819060a060020a900460e060020a02811480156104db575060018b8101546002918116156101000260001901160481145b156109b3578a5460028c0154600160a060020a039190911690895a60405191900391906000818181858888f193505050508b60080160006101000a81548160ff02191690830217905550610bfa565b6105d36004355b6000600060006000309250600a83600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505060405151600919019350505081851115610eb05782600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519450610ea89050565b60408051918252519081900360200190f35b005b600291505b50919050565b6008830154610100900460ff161561060d57600591506105ec565b30905080600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515143610109011015905061066457600091506105ec565b80600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515143600a01101590506106d3576005830154620100009004600160a060020a0316600014156105e757600191506105ec565b80600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505060405151431015905061072357600391506105ec565b80600160a060020a031663a06db7dc6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050506040518051906020015060ff1681600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519190910143101590506107bf57600491506105ec565b600791506105ec565b5081800160010183558181151161085157601f016020900481601f016020900483600052602060002091820191016108519190610826565b82601f106107c8575082600052602060002080549082601f016020900481019061090691905b808211156103a95760008155600101610826565b60ff19168360005260206000205581800160010183555b5050505060048251111561090c575060005b6001838101546002918116156101000260001901160481101561090c57818160040181518110156100075790602001015160f860020a900460f860020a02836001016000508281546001816001161561010002031660029004811015610007578154600116156108e25790600052602060002090602091828204019190065b601f036101000a81548160ff0219169060f860020a84040217905550600101610863565b5061026d565b505050565b604080517f5f5f6469672875696e74323536290000000000000000000000000000000000008152815190819003600e01812060e060020a9081900481028190049081028252600019850160048301529151600160a060020a03301692916102bc86029160248281019260009291908290030181838887f19450505050505b919050565b5060005b92915050565b818360020203836064020460c8039050610998565b8a5460a060020a900460e060020a0260001415610a23578a5460028c0154600160a060020a039190911690895a03908d6001016000506040518082805460018160011615610100020316600290048015610ae55780601f10610aba57610100808354040283529160200191610ae5565b60018b8101546002918116156101000260001901160460001415610b1a578a5460028c0154600160a060020a039190911690895a03908d60000160149054906101000a900460e060020a0260e060020a900491906040518360e060020a028152600401809050600060405180830381858988f19450505050508b60080160006101000a81548160ff02191690830217905550610bfa565b820191906000526020600020905b815481529060010190602001808311610ac857829003601f168201915b5050915050600060405180830381858888f193505050508b60080160006101000a81548160ff02191690830217905550610bfa565b8a5460028c0154600160a060020a039190911690895a03908d60000160149054906101000a900460e060020a0260e060020a900491908e6001016000506040518460e060020a0281526004018082805460018160011615610100020316600290048015610bc85780601f10610b9d57610100808354040283529160200191610bc8565b820191906000526020600020905b815481529060010190602001808311610bab57829003601f168201915b5050915050600060405180830381858988f19450505050508b60080160006101000a81548160ff021916908302179055505b85600160a060020a031663938b5f326040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750505060405180519060200150600160a060020a031660405180807f75706461746544656661756c745061796d656e742829000000000000000000008152602001506016019050604051809103902060e060020a8091040260e060020a90046040518160e060020a0281526004018090506000604051808303816000876161da5a03f15050505060038b0154610cc8903a6103b7565b60058c0154909550620100009004600160a060020a03908116908a161415610cf65760068b01549350610d38565b85600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519450505b6064858502048b6007016000505401925060648587600160a060020a031663625cc4656040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505050604051805190602001500204915060008b60070160005081905550865a8b03013a029050610db7898285016103d8565b9250610dd773d3cda913deb6f67967b99d67acdfa1712c293601836103d8565b6040805160088e01548482526020820187905281830184905260ff1660608201529051919350600160a060020a038b16917f4538b7ec91dae8fada01e66a052482086d3e690c3db5a80457fbcd55457b4ae19181900360800190a25050505050505050505050565b505b309050610e8c81600160a060020a031663ae45850b6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515190316103d8565b505050600801805462ff0000191662010000179055565b600093505b505050919050565b600e19919091019081851115610f075782600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519450610ea89050565b60ef19919091019081851115610ea357818503905060f08184600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050506040518051906020015002049350610ea8565b03905090565b6006860181905560058601805475ffffffffffffffffffffffffffffffffffffffff000019166201000087021790556007860184905560408051600160a060020a0387168152602081019290925280517fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a9281900390910190a15b949350505050565b610f7343610531565b600192505b50509392505050565b60108185031015610fff576005860154620100009004600160a060020a03166000148061105057506005860154620100009004600160a060020a03908116908616145b9250611004565b600092505b505092915050565b91503090506000821480156110c4575080600160a060020a031663ae45850b6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505060405151600160a060020a039081169086161490505b156110d2576001925061105c565b6007821415611057576001925061105c565b6008860154610100900460ff161561111e577f414c52454144595f43414c4c454400000000000000000000000000000000000091506112dd565b80600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051514310905080611206575080600160a060020a031663a06db7dc6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040805180517f0a16697a000000000000000000000000000000000000000000000000000000008252915160ff9092169291630a16697a9160048181019260209290919082900301816000876161da5a03f1156100075750506040515191909101431190505b15611233577f4e4f545f494e5f43414c4c5f57494e444f57000000000000000000000000000091506112dd565b61123e8686436100d3565b151561126c577f4e4f545f415554484f52495a454400000000000000000000000000000000000091506112dd565b6005860154600061ffff91909116118015611299575032600160a060020a031685600160a060020a031614155b80156112b4575060058601546112b29061ffff166101b4565b155b156112dd577f535441434b5f544f4f5f4445455000000000000000000000000000000000000091505b60008214610fff5760408051600160a060020a03871681526020810184905281517fdcb278834ca505ad219cf8e4b5d11f026080abef6ec68e249ea5e4d9bb3dc7b2929181900390910190a16000925061100456"
+ },
+ "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
+ "balance": "0x98e1c608601c2496b2",
+ "nonce": "218916",
+ "code": "0x"
+ },
+ "0x651913977e8140c323997fce5e03c19e0015eebf": {
+ "balance": "0x0",
+ "code": "0x",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000000000000000000000000000000000000000000d": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000000000000000000000000000000000000000000e": "0x0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": {
+ "balance": "0x0",
+ "nonce": "237",
+ "code": "0x6060604052361561027c5760e060020a600035046301991313811461027e57806303d22885146102ca5780630450991814610323578063049ae734146103705780630ce46c43146103c35780630e85023914610602578063112e39a8146106755780631b4fa6ab146106c25780631e74a2d3146106d057806326a7985a146106fd5780633017fe2414610753578063346cabbc1461075c578063373a1bc3146107d55780633a9e74331461081e5780633c2c21a01461086e5780633d9ce89b146108ba578063480b70bd1461092f578063481078431461097e57806348f0518714610a0e5780634c471cde14610a865780634db3da8314610b09578063523ccfa814610b4f578063586a69fa14610be05780635a9f2def14610c3657806364ee49fe14610caf57806367beaccb14610d055780636840246014610d74578063795b9a6f14610dca5780637b55c8b514610e415780637c73f84614610ee15780638c0e156d14610f145780638c1d01c814610f605780638e46afa914610f69578063938c430714610fc0578063971c803f146111555780639772c982146111ac57806398c9cdf41461122857806398e00e541461127f5780639f927be7146112d5578063a00aede914611383578063a1c0539d146113d3578063aff21c6514611449578063b152f19e14611474578063b549793d146114cb578063b5b33eda1461154b578063bbc6eb1f1461159b578063c0f68859146115ab578063c3a2c0c314611601578063c43d05751461164b578063d8e5c04814611694578063dbfef71014611228578063e29fb547146116e7578063e6470fbe1461173a578063ea27a8811461174c578063ee77fe86146117d1578063f158458c14611851575b005b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387876020604051908101604052806000815260200150612225610f6d565b61188260043560243560443560643560843560a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338b8a6020604051908101604052806000815260200150896125196106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a026020604051908101604052806000815260200150611e4a610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503389896020604051908101604052806000815260200150886124e86106c6565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750506040805160a08082019092529597963596608435969095506101449450925060a491506005908390839080828437509095505050505050604080518082018252600160a060020a03338116825288166020820152815160c0810190925260009173e54d323f9ef17c1f0dede47ecc86a9718fe5ea349163e3042c0f91600191908a908a9089908b90808b8b9090602002015181526020018b60016005811015610002579090602002015181526020018b60026005811015610002579090602002015181526020018b60036005811015610002579090602002015181526020018b6004600581101561000257909060200201518152602001348152602001506040518860e060020a02815260040180888152602001876002602002808383829060006004602084601f0104600f02600301f150905001868152602001806020018560ff1681526020018461ffff168152602001836006602002808383829060006004602084601f0104600f02600301f1509050018281038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d25780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038160008760325a03f2156100025750506040515191506124cd9050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808787611e64610f6d565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611d28610f6d565b61189f5b6000611bf8611159565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881600060005054611a9561159f565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346326a7985a6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b760075b90565b604080516020606435600481810135601f8101849004840285018401909552848452611882948135946024803595604435956084949201919081908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160013389898861224b610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386866020604051908101604052806000815260200150611e64610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333896020604051908101604052806000815260200150886123bc6106c6565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387866020604051908101604052806000815260200150611f8d610f6d565b60408051602060248035600481810135601f810185900485028601850190965285855261188295813595919460449492939092019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808888612225610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503388886020604051908101604052806000815260200150612388610f6d565b611882600435604080517fc4144b2600000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163c4144b26916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133888888612238610f6d565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338b8b8b896126536106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333866020604051908101604052806000815260200150611e4a610f6d565b6118b76004355b604080517fed5bd7ea00000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163ed5bd7ea916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b61189f600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463586a69fa6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650509335935050606435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808989612388610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a896020604051908101604052806000815260200150886124d76106c6565b6040805160206004803580820135601f8101849004840285018401909552848452611882949193602493909291840191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808587611e4a610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a8a60206040519081016040528060008152602001508961262d6106c6565b604080516020606435600481810135601f810184900484028501840190955284845261188294813594602480359560443595608494920191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338888876120c7610f6d565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437505060408051608080820190925295979635969561010495509350608492508591508390839080828437509095505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989898961263a6106c6565b6118b7600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881858585611ba361122c565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050333388602060405190810160405280600081526020015061236e610f6d565b6118b760005481565b6118c95b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea34638e46afa96040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a43560c43560e43561010435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338e8e8d8f8e8e8e8e8e346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111195780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519b9a5050505050505050505050565b61189f5b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463971c803f6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650509335935050608435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989896123a2610f6d565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398c9cdf46040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398e00e546040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600435604080517fe6ce3a6a000000000000000000000000000000000000000000000000000000008152600160048201527f3e3d0000000000000000000000000000000000000000000000000000000000006024820152604481018390529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163e6ce3a6a916064818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a0260206040519081016040528060008152602001506121ef610f6d565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338787876120b5610f6d565b6118b7600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88183611b4561159f565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463b152f19e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808b8b8961262d6106c6565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386600060e060020a026020604051908101604052806000815260200150612200610f6d565b6118b75b60005460649004610759565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463c0f688596040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611bff610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333876020604051908101604052806000815260200150612200610f6d565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387600060e060020a026020604051908101604052806000815260200150612213610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338a60206040519081016040528060008152602001508961250c6106c6565b61027c6000600060006118e033610b56565b6118b7600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881868686866040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b949350505050565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338a8a8a886124fa6106c6565b6118b7600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88184846000611b4f61122c565b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b60408051918252519081900360200190f35b6040805160ff929092168252519081900360200190f35b15611a905733925082600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fc6803622000000000000000000000000000000000000000000000000000000008252915191945063c680362291600482810192602092919082900301816000876161da5a03f11561000257505060405151905080156119d1575082600160a060020a031663d379be236040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a03166000141590505b80156119dd5750600082115b80156119ec5750600054600190115b15611a90578183600160a060020a031663830953ab6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040515160640291909104915050604281118015611a4d5750600054829011155b15611a675760008054612710612711909102049055611a90565b602181108015611a7a5750600054829010155b15611a90576000805461271061270f9091020490555b505050565b6000611a9f61122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b919050565b6000611af261122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b9392505050565b9050610759565b611c076106c6565b6000611c11611478565b611c1961122c565b600054611c2461159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611cf25780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b611d306106c6565b60008b611d3b61122c565b600054611d4661159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611e145780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b409050565b611e526106c6565b6000611e5c611478565b611d3b61122c565b611e6c6106c6565b6000611e76611478565b611e7e61122c565b600054611e8961159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611f575780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b9d9050565b611f956106c6565b8b611f9e611478565b611fa661122c565b600054611fb161159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561207f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611bf19050565b6120bd6106c6565b6000611f9e611478565b6120cf6106c6565b8b6120d8611478565b6120e061122c565b6000546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506117c99050565b6121f76106c6565b8b611e76611478565b6122086106c6565b60008b611e7e61122c565b61221b6106c6565b8a8c611fa661122c565b61222d6106c6565b60008b611fa661122c565b6122406106c6565b60008b6120e061122c565b6122536106c6565b8c8b61225d61122c565b60005461226861159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156123365780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f21561000257505060405151979650505050505050565b6123766106c6565b60008c8c600060005054611fb161159f565b6123906106c6565b60008c8c6000600050546120eb61159f565b6123aa6106c6565b60008c8c60006000505461226861159f565b60008d8d6000600050546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561249c5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150505b9695505050505050565b8e8d8d6000600050546123ce61159f565b60008d8d60006000505461226861159f565b60008d8d6000600050546123ce61159f565b60008e8e8d61226861159f565b8f8e8e8d61252561159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156125f35780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519998505050505050505050565b60008e8e8d6123ce61159f565b8a5160208c015160408d015160608e015161226861159f565b60008e8e8d61252561159f56",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000011f8119429ed3a",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000f5d861791e76fa01433e0d7421aee565290e4afe",
+ "0x031b9ec274101cc3ccff4d6d98ef4513742dadbaadba538bff48b88403253234": "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x20ef51bb8ea9e8e8d5e2c17d28e47285698893c1017db4b4e40b792358a3dbc7": "0x0000000000000000000000000000000000000000000000000000000000000004",
+ "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abd": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01",
+ "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abf": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
+ "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8ac2": "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfb": "0x000000000000000000000000f5d861791e76fa01433e0d7421aee565290e4afe",
+ "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfc": "0x00000000000000000000000000000000000000000000000000000000000f6897",
+ "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfd": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfe": "0x0000000000000000000000002859ddf2877c46d54e67b6becdb1cafb8ef4a458",
+ "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dff": "0x000000000000000000000000b7df3c43a8b13ecf45777c267404e15c7cdb04c9",
+ "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794e00": "0x0000000000000000000000000000000000000000000000000000000000000008",
+ "0x3b20a4b931bc4ae9450774ee52b8f5da1b248d23e61cd20c09b25662f73894fd": "0x0000000000000000000000000000000000000000000000000000000000000006",
+ "0x3b99aee1e3090227401ac2055c861246ca6ec62f426b4b4d74df88510f841b89": "0x0000000000000000000000000000000000000000000000000000000000000007",
+ "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef711": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c",
+ "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef712": "0x0000000000000000000000000000000000000000000000000000000000102ce9",
+ "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef713": "0x000000000000000000000000fd97a0d81cc92eecd52452831930b27889925ef0",
+ "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef714": "0x00000000000000000000000016917c151bb1399852a0741eb7b317b443e2cfa3",
+ "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef715": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
+ "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef716": "0x0000000000000000000000000000000000000000000000000000000000000004",
+ "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a3fe": "0x000000000000000000000000c5ef24ec3bf0e3522cfc8e53f3e076b043547ce1",
+ "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a3ff": "0x00000000000000000000000000000000000000000000000000000000000fff67",
+ "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a400": "0x000000000000000000000000b7df3c43a8b13ecf45777c267404e15c7cdb04c9",
+ "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a401": "0x00000000000000000000000010fc2e8ba5f40336c3576ffaa25177f1cdedf836",
+ "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a402": "0x000000000000000000000000fd97a0d81cc92eecd52452831930b27889925ef0",
+ "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a403": "0x0000000000000000000000000000000000000000000000000000000000000006",
+ "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5ba": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
+ "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bb": "0x000000000000000000000000000000000000000000000000000000000010347b",
+ "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bc": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
+ "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bd": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01",
+ "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5be": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b",
+ "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bf": "0x0000000000000000000000000000000000000000000000000000000000000002",
+ "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2751": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2752": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2753": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2754": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2755": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2756": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826a7": "0x000000000000000000000000b7df3c43a8b13ecf45777c267404e15c7cdb04c9",
+ "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826a8": "0x00000000000000000000000000000000000000000000000000000000000fe13d",
+ "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826a9": "0x000000000000000000000000f5d861791e76fa01433e0d7421aee565290e4afe",
+ "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826aa": "0x00000000000000000000000063110531142fb314118164ff579ba52746504408",
+ "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826ab": "0x000000000000000000000000c5ef24ec3bf0e3522cfc8e53f3e076b043547ce1",
+ "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826ac": "0x0000000000000000000000000000000000000000000000000000000000000007",
+ "0xac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c890780": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0xccd2cbc946692be8ade97db99353304e3af0fa6202f93649d4e185ad8b1f385c": "0x0000000000000000000000000000000000000000000000000000000000000004",
+ "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4ef": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
+ "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f0": "0x00000000000000000000000000000000000000000000000000000000001030b3",
+ "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f1": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c",
+ "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f2": "0x000000000000000000000000dd87a67740c2acf48a31829783a095a81c3628d9",
+ "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f3": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
+ "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f4": "0x0000000000000000000000000000000000000000000000000000000000000003",
+ "0xdabde47554d6a6cfcff3c968abb145f298585fafa9e24c10fc526269794bd626": "0x0000000000000000000000000000000000000000000000000000000000000003",
+ "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64db7": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b",
+ "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64db8": "0x000000000000000000000000000000000000000000000000000000000010365c",
+ "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64db9": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
+ "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dba": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbb": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbc": "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdec": "0x000000000000000000000000fd97a0d81cc92eecd52452831930b27889925ef0",
+ "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bded": "0x0000000000000000000000000000000000000000000000000000000000101dc2",
+ "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdee": "0x000000000000000000000000c5ef24ec3bf0e3522cfc8e53f3e076b043547ce1",
+ "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdef": "0x000000000000000000000000173243e117a6382211b1ac91eeb262f4a7021c16",
+ "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdf0": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c",
+ "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdf1": "0x0000000000000000000000000000000000000000000000000000000000000005"
+ }
+ },
+ "0x741467b251fca923d6229c4b439078b55dca233b": {
+ "balance": "0x29c613529e8218f8",
+ "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000011f79bd42b0c7c",
+ "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000002dfeff8fca5d",
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x00000000000000003defb9627dd677b54fc954824a7bc49bd26cbdfa12c75adf",
+ "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000ba43b7400",
+ "0x0000000000000000000000000000000000000000000000000000000000000007": "0x00000000000000000000000000000000000000000000000000000000001e8480",
+ "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000000000000a",
+ "0x000000000000000000000000000000000000000000000000000000000000000a": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b",
+ "0x000000000000000000000000000000000000000000000000000000000000000d": "0x000000000000000000000000000000000000000000000000000000000010365c",
+ "0x000000000000000000000000000000000000000000000000000000000000000e": "0x00000000000000000000000000000000000000000000000000000000000000ff"
+ }
+ },
+ "0x7c1eb207c07e7ab13cf245585bd03d0fa478d034": {
+ "balance": "0x0",
+ "code": "0x650200d2f18c7350606060405236156100a05760e060020a60003504630e9f1a3c81146100a55780632b4096b4146100c95780636ec13982146100eb578063a3119e571461010d578063a749f19b1461012f578063ab7366f714610151578063bacd69581461017f578063bfdf87c0146101c2578063c4144b26146101e1578063caa46c9c1461023c578063e6ce3a6a14610297578063ed5bd7ea146102b6575b610007565b6102d960043560243560008181526001830160205260409020600401545b92915050565b6102d960043560243560008181526001830160205260409020600301546100c3565b6102d960043560243560008181526001830160205260409020600201546100c3565b6102d960043560243560008181526001838101602052604090912001546100c3565b6102d960043560243560008181526001830160205260409020600501546100c3565b6102eb6004356024355b600081815260018301602052604081208054829182918291908614610790576101b9565b6102eb600435602435604435600082815260018401602052604081205481908190819086141561068a576040812060010154851415610680575b50505050505050565b6102d960043560243560008181526001830160205260409020546100c3565b6102d96004356024355b6040805160c08101825260008082526020828101829052828401829052606083018290526080830182905260a08301829052848252600186019052918220805490919083908114156102fb576102f2565b6102d96004356024355b6040805160c08101825260008082526020828101829052828401829052606083018290526080830182905260a08301829052848252600186019052918220805490919083908114156104c0576102f2565b6102d960043560243560443582546000908181811415610a6557610a8c565b6102d96004356024356000818152600183016020526040812060050154116100c3565b60408051918252519081900360200190f35b005b815193505b50505092915050565b60048301546000146103d257600483810154600090815260018881016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252600382015460608201529181015460808301526005015460a082015291505b60608201516000146102ed57606091820151600090815260018781016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252600382015493810193909352600481015460808401526005015460a0830152610364565b600283015460001461045b5750506002810154600081815260018681016020908152604092839020835160c081018552865481529286015491830191909152918101929092526003830154606083015260048301546080830152600583015460a08301525b81516003820154141561044d57805493506102f2565b600281015460001415610464575b600093506102f2565b6040805160c08101825282548152600183810154602083810191909152600285015483850181905260038601546060850152600486015460808501526005959095015460a0840152600094855290890190529120909150610437565b600383015460001461059757600383810154600090815260018881016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252918101546060830152600481015460808301526005015460a082015291505b60808201516000146102ed57608091820151600090815260018781016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252600382015460608201526004820154938101939093526005015460a0830152610529565b600283015460001461045b5750506002810154600081815260018681016020908152604092839020835160c081018552865481529286015491830191909152918101929092526003830154606083015260048301546080830152600583015460a08301525b81516004820154141561061257805493506102f2565b6002810154600014156106245761045b565b6040805160c08101825282548152600183810154602083810191909152600285015483850181905260038601546060850152600486015460808501526005959095015460a08401526000948552908901905291209091506105fc565b61068a878761015b565b86546000925082141561069b578587555b508554600090815260018701602052604090205b8054600014156107255785815560028101829055600181018590556101b987875b60008181526001830160205260408120905b8154610d8e9085905b60008181526001830160205260408082206004810154835281832060059081015460038301548552929093209092015403905b5092915050565b60018101548154925085126107625760048101546000141561074957600481018690555b60040154600090815260018701602052604090206106af565b60038101546000141561077757600381018690555b60030154600090815260018701602052604090206106af565b600381015460001415806107a957506004810154600014155b156107cf576003810154600014610826578054600188019060009061083b908a90610246565b6002810154600014610a285760028101546000908152600188016020526040902060038101548254919550141561080857600060038501555b60048401548154141561081d57600060048501555b83549150610a2d565b80546001880190600090610852908a906101eb565b815260208101919091526040016000209450610865565b8152602081019190915260400160002094505b600285015460009081526001880160205260409020600381015486549195509092508214156108b9576004850154600385018190556000146108b95760048501546000908152604090208454600282015592505b60048401548554141561091357600385015460048501819055600014610913578660010160005060008660030160005054815260200190815260200160002060005092508250836000016000505483600201600050819055505b60028082015490860181905560001461098457866001016000506000826002016000505481526020019081526020016000206000509350835080600001600050548460030160005054141561096a57845460038501555b60048401548154141561097f57845460048501555b610989565b845487555b6003818101549086018190556000146109d6578660010160005060008260030160005054815260200190815260200160002060005092508250846000016000505483600201600050819055505b600481810154908601819055600014610a23578660010160005060008260040160005054815260200190815260200160002060005092508250846000016000505483600201600050819055505b610a2d565b600087555b6000808255600182018190556002820181905560038201819055600482018190556005820181905582146101b9576101b987836106d0565b50600081815260018601602052604090205b6001810154610a95908686610ad4565b805492505b50509392505050565b15610b915760fa60020a600f02851480610ab6575060f060020a613c3d0285145b15610af157600481015460001415610b3a5780549250610a8c565b86865b600060f960020a601f02831415610ce357508083135b9392505050565b60f960020a601f02851480610b0d575060f060020a613e3d0285145b80610b1f575060f060020a613d3d0285145b15610b9157600381015460001415610bc85780549250610a8c565b610b73610ad1878360040160005054600081815260018301602052604081205b600381015460001415610d61576001810154915061071e565b15610a87576004015460009081526001860160205260409020610a77565b60fa60020a600f02851480610bad575060f060020a613c3d0285145b15610c1f57600381015460001415610c565760009250610a8c565b610c01610ad1878360030160005054600081815260018301602052604081205b600481015460001415610d48576001810154915061071e565b15610a87576003015460009081526001860160205260409020610a77565b60f960020a601f02851480610c3b575060f060020a613e3d0285145b15610c6f57600481015460001415610ca25760009250610a8c565b6003015460009081526001860160205260409020610a77565b60f060020a613d3d02851415610cde57600181015484901215610cbb57600481015460001415610ca25760009250610a8c565b6004015460009081526001860160205260409020610a77565b600181015484901315610cde57600381015460001415610c565760009250610a8c565b610a77565b60fa60020a600f02831415610cfb5750808312610aea565b60f060020a613e3d02831415610d15575080831215610aea565b60f060020a613c3d02831415610d2f575080831315610aea565b60f060020a613d3d028314156100a05750828114610aea565b6004015460009081526001840160205260409020610be8565b6003015460009081526001840160205260409020610b5a565b600282015460001415610fbd575b50505050565b90508060021415610e2657610daa8483600301600050546106eb565b6000191415610dc457610dc4848360030160005054610dfe565b8154610e269085905b60008181526001830160205260408120600381015490919081908190811415610ffb57610007565b8154610e5a9085905b60008181526001830160205260408120600481015490919081908190811415610e7f57610007565b806001191415610e5a57610e418483600401600050546106eb565b60011415610df557610df5848360040160005054610dcd565b8060001913158015610e6d575060018113155b15610d7a578154610d7a908590610f7a565b6004840180546000908152600188016020526040812060028088015490820181905592829055945014610f0f57856001016000506000856002016000505481526020019081526020016000206000509150836000016000505482600301600050541415610efa57826000016000505482600301600050819055505b835460048301541415610f0f57825460048301555b6003830154600014610f40575060038201546000908152600186016020526040902080546004850155835460028201555b82546002808601919091558454600385015583015460001415610f7157826000016000505486600001600050819055505b8354610fe69087905b6000818152600183016020526040808220600381015483528183206005908101546004830154855292842001549092610fd99291908183106110fa5750816100c3565b60029091015460009081526001840160205260409020906106e2565b6001016005820155505050565b8254610ff3908790610f7a565b505050505050565b600384018054600090815260018801602052604081206002808801549082018190559282905594501461108b5785600101600050600085600201600050548152602001908152602001600020600050915083600001600050548260030160005054141561107657826000016000505482600301600050819055505b83546004830154141561108b57825460048301555b60048301546000146110bd57506004820154600081815260018701602052604090206003850191909155835460028201555b82546002808601919091558454600485015583015460001415610f7157826000016000505486600001600050819055508354610fe6908790610f7a565b50806100c356"
+ },
+ "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": {
+ "balance": "0xd7a58f5b73b4b6c4",
+ "code": "0x606060405236156100985760e060020a60003504633896002781146100e15780633defb962146100ea5780633f4be8891461010c5780634136aa351461011f5780634a420138146101a057806369c1a7121461028c5780638129fc1c146102955780638da5cb5b146102a6578063ae45850b146102b8578063af3309d8146102cc578063ea8a1af0146102d5578063ead50da3146102f4575b610308671bc16d674ec8000030600160a060020a03163110156100df57600554604051600160a060020a03918216916000913091909116319082818181858883f150505050505b565b61030a60005481565b610308671bc16d674ec8000030600160a060020a031631101561040f576100df565b61031c600454600160a060020a03165b90565b61030a5b600080548190118015610199575060408051600480547f0a16697a0000000000000000000000000000000000000000000000000000000083529251600160a060020a039390931692630a16697a928083019260209291829003018187876161da5a03f1156100025750506040515160ff01431090505b905061011c565b6103085b600354600554604080517f8c0e156d0000000000000000000000000000000000000000000000000000000081527f3defb96200000000000000000000000000000000000000000000000000000000600482015260a060020a90920461ffff1643016024830152621e8480604483015251600092600160a060020a031691638c0e156d916729a2241af62c000091606481810192602092909190829003018185886185025a03f1156100025750506040515192600160a060020a0384161491506102899050576004805473ffffffffffffffffffffffffffffffffffffffff1916821790555b50565b61030a60015481565b61030860008054146103f2576100df565b61031c600554600160a060020a031681565b61031c600354600160a060020a031661011c565b61030a60025481565b610308600554600160a060020a03908116339091161461035157610002565b61033960055460a060020a900461ffff1681565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b6004546000600160a060020a03919091163111156103c75760408051600480547fea8a1af00000000000000000000000000000000000000000000000000000000083529251600160a060020a03939093169263ea8a1af0928083019260009291829003018183876161da5a03f115610002575050505b600554604051600160a060020a03918216916000913091909116319082818181858883f15050505050565b426000556100df6101a4565b600280546001908101909155429055565b600454600160a060020a03908116339091161461042b576100df565b610433610123565b151561043e576100df565b6103fe6101a456",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000056be5b99",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000056d0009b",
+ "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000008b",
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b",
+ "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b",
+ "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000001e0d3cda913deb6f67967b99d67acdfa1712c293601"
+ }
+ },
+ "0x89efe605e9ecbe22849cd85d5449cc946c26f8f3": {
+ "balance": "0x0",
+ "code": "0x650200d2f18c73506060604052361561007f5760e060020a600035046312c82bcc81146100845780635548c837146100a55780635c54305e146101015780636b103966146101555780637fcf532c14610189578063b1df3d80146101d5578063b5bc6dbb146101ee578063c6ab451414610225578063e62af6c114610293575b610007565b6102c56004356024356000620186a05a10156103855761030083835a610232565b6102d760043560243560443581600160a060020a031683600160a060020a03167f47a08955ce2b7f21ea62ff0024e1ea0ad87430953554a87e6bc65d777f18e639836040518082815260200191505060405180910390a3505050565b6102d760043560243560443560408051838152602081018390528151600160a060020a038616927f9b24879829bed3003de08d5c5d7e18dcbb8dc76faebd95cafc5d4dec8c61a3a5928290030190a2505050565b6102d76004356024356044355b600160a060020a03821660009081526020849052604090205480820110156102d957610007565b6102d7600435602435604080518281529051600160a060020a038416917fd0c5cf41ee8ebf084ad0bce53de7cbc6e4693d9b53a4019ca36a2f91cdc20b3a919081900360200190a25050565b6102c560043560243560443560006102fc848484610162565b6102c5600435602435604435600160a060020a03821660009081526020849052604081205482901061032b576103338484846102a0565b6102c56004356024356044355b60006000831180156102605750604051600160a060020a038516908290859082818181858883f19350505050155b156102fc57604051600160a060020a03851690839085906000818181858888f1935050505015156102fc57506000610300565b6102d76004356024356044355b600160a060020a03821660009081526020849052604090205481111561030757610007565b60408051918252519081900360200190f35b005b600160a060020a0382166000908152602084905260409020805482019055505050565b5060015b9392505050565b600160a060020a038216600090815260208490526040902080548290039055505050565b506000610300565b604051600160a060020a03841690600090849082818181858883f1935050505015156102fc57604051600160a060020a038416908390600081818185876185025a03f19250505015156102fc57610007565b6103008383620186a061023256"
+ },
+ "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": {
+ "balance": "0xffe9b09a5c474dca",
+ "nonce": "975",
+ "code": "0x"
+ },
+ "0xd3cda913deb6f67967b99d67acdfa1712c293601": {
+ "balance": "0x4f5807198e238f13e",
+ "nonce": "283",
+ "code": "0x"
+ },
+ "0xe54d323f9ef17c1f0dede47ecc86a9718fe5ea34": {
+ "balance": "0x0",
+ "code": "0x650200d2f18c7350606060405236156100ab5760e060020a600035046326a7985a81146100b057806350d4e411146100be57806354fd4d501461023d578063586a69fa1461025d5780638e46afa91461026857806396cff3df14610272578063971c803f1461029657806398c9cdf4146102a157806398e00e54146102ae578063b152f19e146102b8578063c0f68859146102c4578063e3042c0f146102cf578063ea27a88114610461575b610007565b6102845b60006104cb6102a5565b604080516020601f60843560048181013592830184900484028501840190955281845261047f948035946024803595604435956064359560a494930191819084018382808284375094965050933593505060c43591505060e435610104356101243561014435610164356101843560006101806040519081016040528060008152602001600081526020016000815260200160206040519081016040528060008152602001508152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200150610180604051908101604052808f81526020018e81526020018d81526020018c81526020018981526020018b81526020018a81526020018881526020018781526020018681526020018581526020018481526020015090506104d48f825b600060006000600a43018460e0015110156105de577f544f4f5f534f4f4e0000000000000000000000000000000000000000000000009150610524565b604080516000808252600760208301528183015290519081900360600190f35b61049c5b6103e85b90565b6104b460ff610265565b62030d403a0260026024356004350102015b60408051918252519081900360200190f35b61049c5b600a610265565b6102845b62030d40610265565b6102846010610265565b61028443600a01610265565b6102845b6020610265565b60408051808201825261047f916004803592909160649190602490600290839083908082843780516020601f608435808c01359182018390048302840183019094528083529499983598975060a49650909450910191908190840183828082843750506040805160c0818101909252959796359660c435969095506101a49450925060e491506006908390839080828437509095505050505050604080516101808181018352600080835260208381018290528385018290528451908101855281815260608401526080830181905260a0830181905260c0830181905260e0830181905261010083018190526101208301819052610140830181905261016083018190528351918201909352808984505181526020018960015060209081015182528101899052604081018890526060018484505181526020810187905260408101869052606001846001506020908101518252018460025060400151815260200184600350606001518152602001846004506080015181526020018460055060a00151905290506104e78982610200565b6102846004356024356044356064355b3a0291909201600202010190565b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b6040805160ff929092168252519081900360200190f35b45039050610265565b9f9e505050505050505050505050505050565b9998505050505050505050565b8461016001511015610524577f494e53554646494349454e545f46554e4453000000000000000000000000000091505b600082146106ed576040805185518482529151600160a060020a0392909216917f513485fc54ef019ef1bc1ea683ef7d5d522f2865224ae10871ff992749c0ba4f9181900360200190a27389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc85600001518661016001516040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f215610007575050505b505092915050565b8360c0015161ffff166105ef61029a565b61ffff1611806106115750610602610261565b61ffff168460c0015161ffff16115b1561063e577f535441434b5f434845434b5f4f55545f4f465f52414e474500000000000000009150610524565b6106466102c8565b8460a0015160ff16101561067c577f47524143455f544f4f5f53484f525400000000000000000000000000000000009150610524565b6106846102a5565b84610100015110806106a157506106996100b4565b846101000151115b156106ce577f52455155495245445f4741535f4f55545f4f465f52414e4745000000000000009150610524565b6104f48461012001518561014001518660800151876101000151610471565b83610160015184600001518560e001518660a001518760200151886040015189606001518a608001518b61010001518c60c001518d61012001518e6101400151604051611078806108fa833901808c600160a060020a031681526020018b81526020018a60ff16815260200189600160a060020a03168152602001888152602001806020018781526020018681526020018561ffff1681526020018481526020018381526020018281038252888181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b509c505050505050505050505050506040518091039082f090509050737c1eb207c07e7ab13cf245585bd03d0fa478d03463bacd69588683600160a060020a031660010284600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505050604051805190602001506040518460e060020a02815260040180848152602001838152602001828152602001935050505060006040518083038160008760325a03f21561000757505060408051600160a060020a038416815290517f2b05d346f0b0b9fd470024751c52d3b5dac5c37796f077c1a66241f2eada44b792509081900360200190a18092506105d656606060405260405161107838038061107883398101604052805160805160a05160c05160e05161010051610120516101405161016051610180516101a051999a98999798969795969490940194929391929091908a84848a8a8a8a88886101008051600c8054600160a060020a031990811633179091556000805482168d1781556001868155600286815560078e90556008805461ffff19168e1790553a600655600380547c01000000000000000000000000000000000000000000000000000000008d04740100000000000000000000000000000000000000000260a060020a63ffffffff0219919096168e17169490941790935588516004805493819052956020601f9385161590910260001901909316939093048101919091047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b908101939091608091909101908390106101ee57805160ff19168380011785555b5061017a9291505b8082111561021e5760008155600101610166565b5050826003600050600201600050819055505050505050505050508a600060006101000a815481600160a060020a030219169083021790555089600d6000508190555088600e60006101000a81548160ff021916908302179055505050505050505050505050610e56806102226000396000f35b8280016001018555821561015e579182015b8281111561015e578251826000505591602001919060010190610200565b509056606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256"
+ }
+ },
+ "config": {
+ "chainId": 1,
+ "homesteadBlock": 1150000,
+ "daoForkBlock": 1920000,
+ "eip150Block": 2463000,
+ "eip155Block": 2675000,
+ "eip158Block": 2675000,
+ "byzantiumBlock": 4370000,
+ "constantinopleBlock": 7280000,
+ "petersburgBlock": 7280000,
+ "istanbulBlock": 9069000,
+ "muirGlacierBlock": 9200000,
+ "berlinBlock": 12244000,
+ "londonBlock": 12965000,
+ "arrowGlacierBlock": 13773000,
+ "grayGlacierBlock": 15050000,
+ "ethash": {}
+ }
+ },
+ "context": {
+ "number": "1062503",
+ "difficulty": "13700504019867",
+ "timestamp": "1456480446",
+ "gasLimit": "3141592",
+ "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226"
+ },
+ "input": "0xf86b8203cf850ba43b740083200b2094741467b251fca923d6229c4b439078b55dca233b8084614619541ca078293714f69a810356f1ee29dc686ec2ca3a0e5448e1ef6322c77369ebdd26c2a01c3836fa363548959554ee5360361be9db4aea9eb7c31f61550f0e9a10138adf",
+ "tracerConfig": {
+ "diffMode": true,
+ "disableCode": true,
+ "disableStorage": true
+ },
+ "result": {
+ "pre": {
+ "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
+ "balance": "0x98e1c608601c2496b2",
+ "nonce": 218916
+ },
+ "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": {
+ "balance": "0x0",
+ "nonce": 237
+ },
+ "0x741467b251fca923d6229c4b439078b55dca233b": {
+ "balance": "0x29c613529e8218f8"
+ },
+ "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": {
+ "balance": "0xd7a58f5b73b4b6c4"
+ },
+ "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": {
+ "balance": "0xffe9b09a5c474dca",
+ "nonce": 975
+ },
+ "0xd3cda913deb6f67967b99d67acdfa1712c293601": {
+ "balance": "0x4f5807198e238f13e",
+ "nonce": 283
+ }
+ },
+ "post": {
+ "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
+ "balance": "0x98e2b02f14529b1eb2"
+ },
+ "0x651913977e8140c323997fce5e03c19e0015eebf": {
+ "balance": "0x29a2241af62c0000"
+ },
+ "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": {
+ "nonce": 238
+ },
+ "0x741467b251fca923d6229c4b439078b55dca233b": {
+ "balance": "0x0"
+ },
+ "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": {
+ "balance": "0xd6c5f42b8502a0e3"
+ },
+ "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": {
+ "balance": "0x10002e64ebd492a46",
+ "nonce": 976
+ },
+ "0xd3cda913deb6f67967b99d67acdfa1712c293601": {
+ "balance": "0x4f5809f97e1c8bb9b"
+ }
+ }
+ }
+}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json
new file mode 100644
index 0000000000..5f939ba2df
--- /dev/null
+++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json
@@ -0,0 +1,101 @@
+{
+ "context": {
+ "difficulty": "3502894804",
+ "gasLimit": "4722976",
+ "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
+ "number": "2289806",
+ "timestamp": "1513601314"
+ },
+ "genesis": {
+ "alloc": {
+ "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
+ "balance": "0x0",
+ "code": "0x",
+ "nonce": "22",
+ "storage": {}
+ },
+ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
+ "balance": "0x4d87094125a369d9bd5",
+ "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
+ "nonce": "1",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
+ "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
+ }
+ },
+ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
+ "balance": "0x1780d77678137ac1b775",
+ "code": "0x",
+ "nonce": "29072",
+ "storage": {}
+ }
+ },
+ "config": {
+ "byzantiumBlock": 1700000,
+ "chainId": 3,
+ "eip150Block": 0,
+ "eip155Block": 10,
+ "eip158Block": 10,
+ "ethash": {},
+ "homesteadBlock": 0
+ },
+ "difficulty": "3509749784",
+ "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
+ "gasLimit": "4727564",
+ "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
+ "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
+ "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
+ "nonce": "0x4eb12e19c16d43da",
+ "number": "2289805",
+ "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
+ "timestamp": "1513601261",
+ "totalDifficulty": "7143276353481064"
+ },
+ "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
+ "tracerConfig": {
+ "diffMode": true
+ },
+ "result": {
+ "pre": {
+ "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
+ "balance": "0x0",
+ "nonce": 22
+ },
+ "0x1585936b53834b021f68cc13eeefdec2efc8e724": {
+ "balance": "0x0"
+ },
+ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
+ "balance": "0x4d87094125a369d9bd5",
+ "nonce": 1,
+ "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
+ }
+ },
+ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
+ "balance": "0x1780d77678137ac1b775",
+ "nonce": 29072
+ }
+ },
+ "post": {
+ "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
+ "balance": "0x6f05b59d3b20000"
+ },
+ "0x1585936b53834b021f68cc13eeefdec2efc8e724": {
+ "balance": "0x420eed1bd6c00"
+ },
+ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
+ "balance": "0x4d869a3b70062eb9bd5",
+ "storage": {
+ "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b95e"
+ }
+ },
+ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
+ "balance": "0x1780d7725724a9044b75",
+ "nonce": 29073
+ }
+ }
+ }
+}
diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go
index b7cc60b096..e56d011139 100644
--- a/eth/tracers/native/call_flat.go
+++ b/eth/tracers/native/call_flat.go
@@ -55,6 +55,7 @@ var parityErrorMapping = map[string]string{
}
var parityErrorMappingStartingWith = map[string]string{
+ "out of gas:": "Out of gas", // convert OOG wrapped errors, eg `out of gas: not enough gas for reentrancy sentry`
"invalid opcode:": "Bad instruction",
"stack underflow": "Stack underflow",
}
@@ -296,10 +297,11 @@ func newFlatCreate(input *callFrame) *flatCallFrame {
return &flatCallFrame{
Type: strings.ToLower(vm.CREATE.String()),
Action: flatCallAction{
- From: &input.From,
- Gas: &input.Gas,
- Value: input.Value,
- Init: &actionInit,
+ CreationMethod: strings.ToLower(input.Type.String()),
+ From: &input.From,
+ Gas: &input.Gas,
+ Value: input.Value,
+ Init: &actionInit,
},
Result: &flatCallResult{
GasUsed: &input.GasUsed,
@@ -370,6 +372,7 @@ func convertErrorToParity(call *flatCallFrame) {
for gethError, parityError := range parityErrorMappingStartingWith {
if strings.HasPrefix(call.Error, gethError) {
call.Error = parityError
+ break
}
}
}
diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go
index 978ba0670c..9706eb43f6 100644
--- a/eth/tracers/native/prestate.go
+++ b/eth/tracers/native/prestate.go
@@ -72,7 +72,9 @@ type prestateTracer struct {
}
type prestateTracerConfig struct {
- DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications
+ DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications
+ DisableCode bool `json:"disableCode"` // If true, this tracer will not return the contract code
+ DisableStorage bool `json:"disableStorage"` // If true, this tracer will not return the contract storage
}
func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
@@ -210,7 +212,6 @@ func (t *prestateTracer) processDiffState() {
postAccount := &account{Storage: make(map[common.Hash]common.Hash)}
newBalance := t.env.StateDB.GetBalance(addr).ToBig()
newNonce := t.env.StateDB.GetNonce(addr)
- newCode := t.env.StateDB.GetCode(addr)
if newBalance.Cmp(t.pre[addr].Balance) != 0 {
modified = true
@@ -220,25 +221,30 @@ func (t *prestateTracer) processDiffState() {
modified = true
postAccount.Nonce = newNonce
}
- if !bytes.Equal(newCode, t.pre[addr].Code) {
- modified = true
- postAccount.Code = newCode
+ if !t.config.DisableCode {
+ newCode := t.env.StateDB.GetCode(addr)
+ if !bytes.Equal(newCode, t.pre[addr].Code) {
+ modified = true
+ postAccount.Code = newCode
+ }
}
- for key, val := range state.Storage {
- // don't include the empty slot
- if val == (common.Hash{}) {
- delete(t.pre[addr].Storage, key)
- }
+ if !t.config.DisableStorage {
+ for key, val := range state.Storage {
+ // don't include the empty slot
+ if val == (common.Hash{}) {
+ delete(t.pre[addr].Storage, key)
+ }
- newVal := t.env.StateDB.GetState(addr, key)
- if val == newVal {
- // Omit unchanged slots
- delete(t.pre[addr].Storage, key)
- } else {
- modified = true
- if newVal != (common.Hash{}) {
- postAccount.Storage[key] = newVal
+ newVal := t.env.StateDB.GetState(addr, key)
+ if val == newVal {
+ // Omit unchanged slots
+ delete(t.pre[addr].Storage, key)
+ } else {
+ modified = true
+ if newVal != (common.Hash{}) {
+ postAccount.Storage[key] = newVal
+ }
}
}
}
@@ -263,11 +269,17 @@ func (t *prestateTracer) lookupAccount(addr common.Address) {
Balance: t.env.StateDB.GetBalance(addr).ToBig(),
Nonce: t.env.StateDB.GetNonce(addr),
Code: t.env.StateDB.GetCode(addr),
- Storage: make(map[common.Hash]common.Hash),
}
if !acc.exists() {
acc.empty = true
}
+ // The code must be fetched first for the emptiness check.
+ if t.config.DisableCode {
+ acc.Code = nil
+ }
+ if !t.config.DisableStorage {
+ acc.Storage = make(map[common.Hash]common.Hash)
+ }
t.pre[addr] = acc
}
@@ -275,6 +287,9 @@ func (t *prestateTracer) lookupAccount(addr common.Address) {
// it to the prestate of the given contract. It assumes `lookupAccount`
// has been performed on the contract before.
func (t *prestateTracer) lookupStorage(addr common.Address, key common.Hash) {
+ if t.config.DisableStorage {
+ return
+ }
if _, ok := t.pre[addr].Storage[key]; ok {
return
}
diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go
index 3cce7bffa1..31e14b9112 100644
--- a/eth/tracers/tracers_test.go
+++ b/eth/tracers/tracers_test.go
@@ -99,11 +99,13 @@ func BenchmarkTransactionTrace(b *testing.B) {
for i := 0; i < b.N; i++ {
snap := state.StateDB.Snapshot()
+ tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
- _, err = st.TransitionDb()
+ res, err := st.TransitionDb()
if err != nil {
b.Fatal(err)
}
+ tracer.OnTxEnd(&types.Receipt{GasUsed: res.UsedGas}, nil)
state.StateDB.RevertToSnapshot(snap)
if have, want := len(tracer.StructLogs()), 244752; have != want {
b.Fatalf("trace wrong, want %d steps, have %d", want, have)
diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go
index 0972644d80..f10626c01f 100644
--- a/ethclient/ethclient.go
+++ b/ethclient/ethclient.go
@@ -630,6 +630,23 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er
return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data))
}
+// RevertErrorData returns the 'revert reason' data of a contract call.
+//
+// This can be used with CallContract and EstimateGas, and only when the server is Geth.
+func RevertErrorData(err error) ([]byte, bool) {
+ var ec rpc.Error
+ var ed rpc.DataError
+ if errors.As(err, &ec) && errors.As(err, &ed) && ec.ErrorCode() == 3 {
+ if eds, ok := ed.ErrorData().(string); ok {
+ revertData, err := hexutil.Decode(eds)
+ if err == nil {
+ return revertData, true
+ }
+ }
+ }
+ return nil, false
+}
+
func toBlockNumArg(number *big.Int) string {
if number == nil {
return "latest"
diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go
index 1b7e26fb74..4ad8a552d2 100644
--- a/ethclient/ethclient_test.go
+++ b/ethclient/ethclient_test.go
@@ -14,18 +14,20 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see .
-package ethclient
+package ethclient_test
import (
"bytes"
"context"
"errors"
+ "fmt"
"math/big"
"reflect"
"testing"
"time"
"github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
@@ -33,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/ethconfig"
+ "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
@@ -40,154 +43,33 @@ import (
// Verify that Client implements the ethereum interfaces.
var (
- _ = ethereum.ChainReader(&Client{})
- _ = ethereum.TransactionReader(&Client{})
- _ = ethereum.ChainStateReader(&Client{})
- _ = ethereum.ChainSyncReader(&Client{})
- _ = ethereum.ContractCaller(&Client{})
- _ = ethereum.GasEstimator(&Client{})
- _ = ethereum.GasPricer(&Client{})
- _ = ethereum.LogFilterer(&Client{})
- _ = ethereum.PendingStateReader(&Client{})
- // _ = ethereum.PendingStateEventer(&Client{})
- _ = ethereum.PendingContractCaller(&Client{})
+ _ = ethereum.ChainReader(ðclient.Client{})
+ _ = ethereum.TransactionReader(ðclient.Client{})
+ _ = ethereum.ChainStateReader(ðclient.Client{})
+ _ = ethereum.ChainSyncReader(ðclient.Client{})
+ _ = ethereum.ContractCaller(ðclient.Client{})
+ _ = ethereum.GasEstimator(ðclient.Client{})
+ _ = ethereum.GasPricer(ðclient.Client{})
+ _ = ethereum.LogFilterer(ðclient.Client{})
+ _ = ethereum.PendingStateReader(ðclient.Client{})
+ // _ = ethereum.PendingStateEventer(ðclient.Client{})
+ _ = ethereum.PendingContractCaller(ðclient.Client{})
)
-func TestToFilterArg(t *testing.T) {
- blockHashErr := errors.New("cannot specify both BlockHash and FromBlock/ToBlock")
- addresses := []common.Address{
- common.HexToAddress("0xD36722ADeC3EdCB29c8e7b5a47f352D701393462"),
- }
- blockHash := common.HexToHash(
- "0xeb94bb7d78b73657a9d7a99792413f50c0a45c51fc62bdcb08a53f18e9a2b4eb",
- )
-
- for _, testCase := range []struct {
- name string
- input ethereum.FilterQuery
- output interface{}
- err error
- }{
- {
- "without BlockHash",
- ethereum.FilterQuery{
- Addresses: addresses,
- FromBlock: big.NewInt(1),
- ToBlock: big.NewInt(2),
- Topics: [][]common.Hash{},
- },
- map[string]interface{}{
- "address": addresses,
- "fromBlock": "0x1",
- "toBlock": "0x2",
- "topics": [][]common.Hash{},
- },
- nil,
- },
- {
- "with nil fromBlock and nil toBlock",
- ethereum.FilterQuery{
- Addresses: addresses,
- Topics: [][]common.Hash{},
- },
- map[string]interface{}{
- "address": addresses,
- "fromBlock": "0x0",
- "toBlock": "latest",
- "topics": [][]common.Hash{},
- },
- nil,
- },
- {
- "with negative fromBlock and negative toBlock",
- ethereum.FilterQuery{
- Addresses: addresses,
- FromBlock: big.NewInt(-1),
- ToBlock: big.NewInt(-1),
- Topics: [][]common.Hash{},
- },
- map[string]interface{}{
- "address": addresses,
- "fromBlock": "pending",
- "toBlock": "pending",
- "topics": [][]common.Hash{},
- },
- nil,
- },
- {
- "with blockhash",
- ethereum.FilterQuery{
- Addresses: addresses,
- BlockHash: &blockHash,
- Topics: [][]common.Hash{},
- },
- map[string]interface{}{
- "address": addresses,
- "blockHash": blockHash,
- "topics": [][]common.Hash{},
- },
- nil,
- },
- {
- "with blockhash and from block",
- ethereum.FilterQuery{
- Addresses: addresses,
- BlockHash: &blockHash,
- FromBlock: big.NewInt(1),
- Topics: [][]common.Hash{},
- },
- nil,
- blockHashErr,
- },
- {
- "with blockhash and to block",
- ethereum.FilterQuery{
- Addresses: addresses,
- BlockHash: &blockHash,
- ToBlock: big.NewInt(1),
- Topics: [][]common.Hash{},
- },
- nil,
- blockHashErr,
- },
- {
- "with blockhash and both from / to block",
- ethereum.FilterQuery{
- Addresses: addresses,
- BlockHash: &blockHash,
- FromBlock: big.NewInt(1),
- ToBlock: big.NewInt(2),
- Topics: [][]common.Hash{},
- },
- nil,
- blockHashErr,
- },
- } {
- t.Run(testCase.name, func(t *testing.T) {
- output, err := toFilterArg(testCase.input)
- if (testCase.err == nil) != (err == nil) {
- t.Fatalf("expected error %v but got %v", testCase.err, err)
- }
- if testCase.err != nil {
- if testCase.err.Error() != err.Error() {
- t.Fatalf("expected error %v but got %v", testCase.err, err)
- }
- } else if !reflect.DeepEqual(testCase.output, output) {
- t.Fatalf("expected filter arg %v but got %v", testCase.output, output)
- }
- })
- }
-}
-
var (
- testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
- testBalance = big.NewInt(2e15)
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
+ testBalance = big.NewInt(2e15)
+ revertContractAddr = common.HexToAddress("290f1b36649a61e369c6276f6d29463335b4400c")
+ revertCode = common.FromHex("7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f75736572206572726f7200000000000000000000000000000000000000000000604452604e6000fd")
)
var genesis = &core.Genesis{
- Config: params.AllEthashProtocolChanges,
- Alloc: types.GenesisAlloc{testAddr: {Balance: testBalance}},
+ Config: params.AllEthashProtocolChanges,
+ Alloc: types.GenesisAlloc{
+ testAddr: {Balance: testBalance},
+ revertContractAddr: {Code: revertCode},
+ },
ExtraData: []byte("test genesis"),
Timestamp: 9000,
BaseFee: big.NewInt(params.InitialBaseFee),
@@ -209,27 +91,30 @@ var testTx2 = types.MustSignNewTx(testKey, types.LatestSigner(genesis.Config), &
To: &common.Address{2},
})
-func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
+func newTestBackend(config *node.Config) (*node.Node, []*types.Block, error) {
// Generate test chain.
blocks := generateTestChain()
// Create node
- n, err := node.New(&node.Config{})
+ if config == nil {
+ config = new(node.Config)
+ }
+ n, err := node.New(config)
if err != nil {
- t.Fatalf("can't create new node: %v", err)
+ return nil, nil, fmt.Errorf("can't create new node: %v", err)
}
// Create Ethereum Service
- config := ðconfig.Config{Genesis: genesis, RPCGasCap: 1000000}
- ethservice, err := eth.New(n, config)
+ ecfg := ðconfig.Config{Genesis: genesis, RPCGasCap: 1000000}
+ ethservice, err := eth.New(n, ecfg)
if err != nil {
- t.Fatalf("can't create new ethereum service: %v", err)
+ return nil, nil, fmt.Errorf("can't create new ethereum service: %v", err)
}
// Import the test chain.
if err := n.Start(); err != nil {
- t.Fatalf("can't start test node: %v", err)
+ return nil, nil, fmt.Errorf("can't start test node: %v", err)
}
if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil {
- t.Fatalf("can't import test blocks: %v", err)
+ return nil, nil, fmt.Errorf("can't import test blocks: %v", err)
}
// Ensure the tx indexing is fully generated
for ; ; time.Sleep(time.Millisecond * 100) {
@@ -238,7 +123,7 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
break
}
}
- return n, blocks
+ return n, blocks, nil
}
func generateTestChain() []*types.Block {
@@ -256,7 +141,10 @@ func generateTestChain() []*types.Block {
}
func TestEthClient(t *testing.T) {
- backend, chain := newTestBackend(t)
+ backend, chain, err := newTestBackend(nil)
+ if err != nil {
+ t.Fatal(err)
+ }
client := backend.Attach()
defer backend.Close()
defer client.Close()
@@ -324,7 +212,7 @@ func testHeader(t *testing.T, chain []*types.Block, client *rpc.Client) {
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
@@ -373,7 +261,7 @@ func testBalanceAt(t *testing.T, client *rpc.Client) {
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
@@ -389,7 +277,7 @@ func testBalanceAt(t *testing.T, client *rpc.Client) {
}
func testTransactionInBlock(t *testing.T, client *rpc.Client) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
// Get current block by number.
block, err := ec.BlockByNumber(context.Background(), nil)
@@ -421,7 +309,7 @@ func testTransactionInBlock(t *testing.T, client *rpc.Client) {
}
func testChainID(t *testing.T, client *rpc.Client) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
id, err := ec.ChainID(context.Background())
if err != nil {
t.Fatalf("unexpected error: %v", err)
@@ -432,7 +320,7 @@ func testChainID(t *testing.T, client *rpc.Client) {
}
func testGetBlock(t *testing.T, client *rpc.Client) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
// Get current block number
blockNumber, err := ec.BlockNumber(context.Background())
@@ -477,7 +365,7 @@ func testGetBlock(t *testing.T, client *rpc.Client) {
}
func testStatusFunctions(t *testing.T, client *rpc.Client) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
// Sync progress
progress, err := ec.SyncProgress(context.Background())
@@ -540,7 +428,7 @@ func testStatusFunctions(t *testing.T, client *rpc.Client) {
}
func testCallContractAtHash(t *testing.T, client *rpc.Client) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
// EstimateGas
msg := ethereum.CallMsg{
@@ -567,7 +455,7 @@ func testCallContractAtHash(t *testing.T, client *rpc.Client) {
}
func testCallContract(t *testing.T, client *rpc.Client) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
// EstimateGas
msg := ethereum.CallMsg{
@@ -594,7 +482,7 @@ func testCallContract(t *testing.T, client *rpc.Client) {
}
func testAtFunctions(t *testing.T, client *rpc.Client) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
block, err := ec.HeaderByNumber(context.Background(), big.NewInt(1))
if err != nil {
@@ -697,7 +585,7 @@ func testAtFunctions(t *testing.T, client *rpc.Client) {
}
func testTransactionSender(t *testing.T, client *rpc.Client) {
- ec := NewClient(client)
+ ec := ethclient.NewClient(client)
ctx := context.Background()
// Retrieve testTx1 via RPC.
@@ -737,7 +625,7 @@ func testTransactionSender(t *testing.T, client *rpc.Client) {
}
}
-func sendTransaction(ec *Client) error {
+func sendTransaction(ec *ethclient.Client) error {
chainID, err := ec.ChainID(context.Background())
if err != nil {
return err
@@ -760,3 +648,40 @@ func sendTransaction(ec *Client) error {
}
return ec.SendTransaction(context.Background(), tx)
}
+
+// Here we show how to get the error message of reverted contract call.
+func ExampleRevertErrorData() {
+ // First create an ethclient.Client instance.
+ ctx := context.Background()
+ ec, _ := ethclient.DialContext(ctx, exampleNode.HTTPEndpoint())
+
+ // Call the contract.
+ // Note we expect the call to return an error.
+ contract := common.HexToAddress("290f1b36649a61e369c6276f6d29463335b4400c")
+ call := ethereum.CallMsg{To: &contract, Gas: 30000}
+ result, err := ec.CallContract(ctx, call, nil)
+ if len(result) > 0 {
+ panic("got result")
+ }
+ if err == nil {
+ panic("call did not return error")
+ }
+
+ // Extract the low-level revert data from the error.
+ revertData, ok := ethclient.RevertErrorData(err)
+ if !ok {
+ panic("unpacking revert failed")
+ }
+ fmt.Printf("revert: %x\n", revertData)
+
+ // Parse the revert data to obtain the error message.
+ message, err := abi.UnpackRevert(revertData)
+ if err != nil {
+ panic("parsing ABI error failed: " + err.Error())
+ }
+ fmt.Println("message:", message)
+
+ // Output:
+ // revert: 08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a75736572206572726f72
+ // message: user error
+}
diff --git a/console/bridge_test.go b/ethclient/example_test.go
similarity index 52%
rename from console/bridge_test.go
rename to ethclient/example_test.go
index e57e294fc5..5d0038f0c7 100644
--- a/console/bridge_test.go
+++ b/ethclient/example_test.go
@@ -1,4 +1,4 @@
-// Copyright 2020 The go-ethereum Authors
+// Copyright 2024 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -14,35 +14,22 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see .
-package console
+package ethclient_test
import (
- "testing"
-
- "github.com/dop251/goja"
- "github.com/ethereum/go-ethereum/internal/jsre"
+ "github.com/ethereum/go-ethereum/node"
)
-// TestUndefinedAsParam ensures that personal functions can receive
-// `undefined` as a parameter.
-func TestUndefinedAsParam(t *testing.T) {
- b := bridge{}
- call := jsre.Call{}
- call.Arguments = []goja.Value{goja.Undefined()}
+var exampleNode *node.Node
- b.UnlockAccount(call)
- b.Sign(call)
- b.Sleep(call)
-}
-
-// TestNullAsParam ensures that personal functions can receive
-// `null` as a parameter.
-func TestNullAsParam(t *testing.T) {
- b := bridge{}
- call := jsre.Call{}
- call.Arguments = []goja.Value{goja.Null()}
-
- b.UnlockAccount(call)
- b.Sign(call)
- b.Sleep(call)
+// launch example server
+func init() {
+ config := &node.Config{
+ HTTPHost: "127.0.0.1",
+ }
+ n, _, err := newTestBackend(config)
+ if err != nil {
+ panic("can't launch node: " + err.Error())
+ }
+ exampleNode = n
}
diff --git a/ethclient/gethclient/gethclient_test.go b/ethclient/gethclient/gethclient_test.go
index 36ea290a85..65d006d1e6 100644
--- a/ethclient/gethclient/gethclient_test.go
+++ b/ethclient/gethclient/gethclient_test.go
@@ -21,6 +21,7 @@ import (
"context"
"encoding/json"
"math/big"
+ "strings"
"testing"
"github.com/ethereum/go-ethereum"
@@ -164,55 +165,85 @@ func TestGethClient(t *testing.T) {
func testAccessList(t *testing.T, client *rpc.Client) {
ec := New(client)
- // Test transfer
- msg := ethereum.CallMsg{
- From: testAddr,
- To: &common.Address{},
- Gas: 21000,
- GasPrice: big.NewInt(875000000),
- Value: big.NewInt(1),
- }
- al, gas, vmErr, err := ec.CreateAccessList(context.Background(), msg)
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- if vmErr != "" {
- t.Fatalf("unexpected vm error: %v", vmErr)
- }
- if gas != 21000 {
- t.Fatalf("unexpected gas used: %v", gas)
- }
- if len(*al) != 0 {
- t.Fatalf("unexpected length of accesslist: %v", len(*al))
- }
- // Test reverting transaction
- msg = ethereum.CallMsg{
- From: testAddr,
- To: nil,
- Gas: 100000,
- GasPrice: big.NewInt(1000000000),
- Value: big.NewInt(1),
- Data: common.FromHex("0x608060806080608155fd"),
- }
- al, gas, vmErr, err = ec.CreateAccessList(context.Background(), msg)
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- if vmErr == "" {
- t.Fatalf("wanted vmErr, got none")
- }
- if gas == 21000 {
- t.Fatalf("unexpected gas used: %v", gas)
- }
- if len(*al) != 1 || al.StorageKeys() != 1 {
- t.Fatalf("unexpected length of accesslist: %v", len(*al))
- }
- // address changes between calls, so we can't test for it.
- if (*al)[0].Address == common.HexToAddress("0x0") {
- t.Fatalf("unexpected address: %v", (*al)[0].Address)
- }
- if (*al)[0].StorageKeys[0] != common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000081") {
- t.Fatalf("unexpected storage key: %v", (*al)[0].StorageKeys[0])
+
+ for i, tc := range []struct {
+ msg ethereum.CallMsg
+ wantGas uint64
+ wantErr string
+ wantVMErr string
+ wantAL string
+ }{
+ { // Test transfer
+ msg: ethereum.CallMsg{
+ From: testAddr,
+ To: &common.Address{},
+ Gas: 21000,
+ GasPrice: big.NewInt(875000000),
+ Value: big.NewInt(1),
+ },
+ wantGas: 21000,
+ wantAL: `[]`,
+ },
+ { // Test reverting transaction
+ msg: ethereum.CallMsg{
+ From: testAddr,
+ To: nil,
+ Gas: 100000,
+ GasPrice: big.NewInt(1000000000),
+ Value: big.NewInt(1),
+ Data: common.FromHex("0x608060806080608155fd"),
+ },
+ wantGas: 77496,
+ wantVMErr: "execution reverted",
+ wantAL: `[
+ {
+ "address": "0x3a220f351252089d385b29beca14e27f204c296a",
+ "storageKeys": [
+ "0x0000000000000000000000000000000000000000000000000000000000000081"
+ ]
+ }
+]`,
+ },
+ { // error when gasPrice is less than baseFee
+ msg: ethereum.CallMsg{
+ From: testAddr,
+ To: &common.Address{},
+ Gas: 21000,
+ GasPrice: big.NewInt(1), // less than baseFee
+ Value: big.NewInt(1),
+ },
+ wantErr: "max fee per gas less than block base fee",
+ },
+ { // when gasPrice is not specified
+ msg: ethereum.CallMsg{
+ From: testAddr,
+ To: &common.Address{},
+ Gas: 21000,
+ Value: big.NewInt(1),
+ },
+ wantGas: 21000,
+ wantAL: `[]`,
+ },
+ } {
+ al, gas, vmErr, err := ec.CreateAccessList(context.Background(), tc.msg)
+ if tc.wantErr != "" {
+ if !strings.Contains(err.Error(), tc.wantErr) {
+ t.Fatalf("test %d: wrong error: %v", i, err)
+ }
+ continue
+ } else if err != nil {
+ t.Fatalf("test %d: wrong error: %v", i, err)
+ }
+ if have, want := vmErr, tc.wantVMErr; have != want {
+ t.Fatalf("test %d: vmErr wrong, have %v want %v", i, have, want)
+ }
+ if have, want := gas, tc.wantGas; have != want {
+ t.Fatalf("test %d: gas wrong, have %v want %v", i, have, want)
+ }
+ haveList, _ := json.MarshalIndent(al, "", " ")
+ if have, want := string(haveList), tc.wantAL; have != want {
+ t.Fatalf("test %d: access list wrong, have:\n%v\nwant:\n%v", i, have, want)
+ }
}
}
diff --git a/ethclient/types_test.go b/ethclient/types_test.go
new file mode 100644
index 0000000000..02f9f21758
--- /dev/null
+++ b/ethclient/types_test.go
@@ -0,0 +1,153 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package ethclient
+
+import (
+ "errors"
+ "math/big"
+ "reflect"
+ "testing"
+
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/common"
+)
+
+func TestToFilterArg(t *testing.T) {
+ blockHashErr := errors.New("cannot specify both BlockHash and FromBlock/ToBlock")
+ addresses := []common.Address{
+ common.HexToAddress("0xD36722ADeC3EdCB29c8e7b5a47f352D701393462"),
+ }
+ blockHash := common.HexToHash(
+ "0xeb94bb7d78b73657a9d7a99792413f50c0a45c51fc62bdcb08a53f18e9a2b4eb",
+ )
+
+ for _, testCase := range []struct {
+ name string
+ input ethereum.FilterQuery
+ output interface{}
+ err error
+ }{
+ {
+ "without BlockHash",
+ ethereum.FilterQuery{
+ Addresses: addresses,
+ FromBlock: big.NewInt(1),
+ ToBlock: big.NewInt(2),
+ Topics: [][]common.Hash{},
+ },
+ map[string]interface{}{
+ "address": addresses,
+ "fromBlock": "0x1",
+ "toBlock": "0x2",
+ "topics": [][]common.Hash{},
+ },
+ nil,
+ },
+ {
+ "with nil fromBlock and nil toBlock",
+ ethereum.FilterQuery{
+ Addresses: addresses,
+ Topics: [][]common.Hash{},
+ },
+ map[string]interface{}{
+ "address": addresses,
+ "fromBlock": "0x0",
+ "toBlock": "latest",
+ "topics": [][]common.Hash{},
+ },
+ nil,
+ },
+ {
+ "with negative fromBlock and negative toBlock",
+ ethereum.FilterQuery{
+ Addresses: addresses,
+ FromBlock: big.NewInt(-1),
+ ToBlock: big.NewInt(-1),
+ Topics: [][]common.Hash{},
+ },
+ map[string]interface{}{
+ "address": addresses,
+ "fromBlock": "pending",
+ "toBlock": "pending",
+ "topics": [][]common.Hash{},
+ },
+ nil,
+ },
+ {
+ "with blockhash",
+ ethereum.FilterQuery{
+ Addresses: addresses,
+ BlockHash: &blockHash,
+ Topics: [][]common.Hash{},
+ },
+ map[string]interface{}{
+ "address": addresses,
+ "blockHash": blockHash,
+ "topics": [][]common.Hash{},
+ },
+ nil,
+ },
+ {
+ "with blockhash and from block",
+ ethereum.FilterQuery{
+ Addresses: addresses,
+ BlockHash: &blockHash,
+ FromBlock: big.NewInt(1),
+ Topics: [][]common.Hash{},
+ },
+ nil,
+ blockHashErr,
+ },
+ {
+ "with blockhash and to block",
+ ethereum.FilterQuery{
+ Addresses: addresses,
+ BlockHash: &blockHash,
+ ToBlock: big.NewInt(1),
+ Topics: [][]common.Hash{},
+ },
+ nil,
+ blockHashErr,
+ },
+ {
+ "with blockhash and both from / to block",
+ ethereum.FilterQuery{
+ Addresses: addresses,
+ BlockHash: &blockHash,
+ FromBlock: big.NewInt(1),
+ ToBlock: big.NewInt(2),
+ Topics: [][]common.Hash{},
+ },
+ nil,
+ blockHashErr,
+ },
+ } {
+ t.Run(testCase.name, func(t *testing.T) {
+ output, err := toFilterArg(testCase.input)
+ if (testCase.err == nil) != (err == nil) {
+ t.Fatalf("expected error %v but got %v", testCase.err, err)
+ }
+ if testCase.err != nil {
+ if testCase.err.Error() != err.Error() {
+ t.Fatalf("expected error %v but got %v", testCase.err, err)
+ }
+ } else if !reflect.DeepEqual(testCase.output, output) {
+ t.Fatalf("expected filter arg %v but got %v", testCase.output, output)
+ }
+ })
+ }
+}
diff --git a/ethdb/database.go b/ethdb/database.go
index c6e76fd2fe..323f8f5d6f 100644
--- a/ethdb/database.go
+++ b/ethdb/database.go
@@ -37,6 +37,13 @@ type KeyValueWriter interface {
Delete(key []byte) error
}
+// KeyValueRangeDeleter wraps the DeleteRange method of a backing data store.
+type KeyValueRangeDeleter interface {
+ // DeleteRange deletes all of the keys (and values) in the range [start,end)
+ // (inclusive on start, exclusive on end).
+ DeleteRange(start, end []byte) error
+}
+
// KeyValueStater wraps the Stat method of a backing data store.
type KeyValueStater interface {
// Stat returns the statistic data of the database.
@@ -61,6 +68,7 @@ type KeyValueStore interface {
KeyValueReader
KeyValueWriter
KeyValueStater
+ KeyValueRangeDeleter
Batcher
Iteratee
Compacter
@@ -154,25 +162,12 @@ type Reader interface {
AncientReader
}
-// Writer contains the methods required to write data to both key-value as well as
-// immutable ancient data.
-type Writer interface {
- KeyValueWriter
- AncientWriter
-}
-
-// Stater contains the methods required to retrieve states from both key-value as well as
-// immutable ancient data.
-type Stater interface {
- KeyValueStater
- AncientStater
-}
-
// AncientStore contains all the methods required to allow handling different
// ancient data stores backing immutable data store.
type AncientStore interface {
AncientReader
AncientWriter
+ AncientStater
io.Closer
}
@@ -187,11 +182,6 @@ type ResettableAncientStore interface {
// Database contains all the methods required by the high level database to not
// only access the key-value data store but also the ancient chain store.
type Database interface {
- Reader
- Writer
- Batcher
- Iteratee
- Stater
- Compacter
- io.Closer
+ KeyValueStore
+ AncientStore
}
diff --git a/ethdb/dbtest/testsuite.go b/ethdb/dbtest/testsuite.go
index 1af55a0e38..52e6b287cf 100644
--- a/ethdb/dbtest/testsuite.go
+++ b/ethdb/dbtest/testsuite.go
@@ -21,6 +21,7 @@ import (
"crypto/rand"
"slices"
"sort"
+ "strconv"
"testing"
"github.com/ethereum/go-ethereum/ethdb"
@@ -343,6 +344,64 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) {
t.Fatalf("expected error on batch.Write after Close")
}
})
+
+ t.Run("DeleteRange", func(t *testing.T) {
+ db := New()
+ defer db.Close()
+
+ addRange := func(start, stop int) {
+ for i := start; i <= stop; i++ {
+ db.Put([]byte(strconv.Itoa(i)), nil)
+ }
+ }
+
+ checkRange := func(start, stop int, exp bool) {
+ for i := start; i <= stop; i++ {
+ has, _ := db.Has([]byte(strconv.Itoa(i)))
+ if has && !exp {
+ t.Fatalf("unexpected key %d", i)
+ }
+ if !has && exp {
+ t.Fatalf("missing expected key %d", i)
+ }
+ }
+ }
+
+ addRange(1, 9)
+ db.DeleteRange([]byte("9"), []byte("1"))
+ checkRange(1, 9, true)
+ db.DeleteRange([]byte("5"), []byte("5"))
+ checkRange(1, 9, true)
+ db.DeleteRange([]byte("5"), []byte("50"))
+ checkRange(1, 4, true)
+ checkRange(5, 5, false)
+ checkRange(6, 9, true)
+ db.DeleteRange([]byte(""), []byte("a"))
+ checkRange(1, 9, false)
+
+ addRange(1, 999)
+ db.DeleteRange([]byte("12345"), []byte("54321"))
+ checkRange(1, 1, true)
+ checkRange(2, 5, false)
+ checkRange(6, 12, true)
+ checkRange(13, 54, false)
+ checkRange(55, 123, true)
+ checkRange(124, 543, false)
+ checkRange(544, 999, true)
+
+ addRange(1, 999)
+ db.DeleteRange([]byte("3"), []byte("7"))
+ checkRange(1, 2, true)
+ checkRange(3, 6, false)
+ checkRange(7, 29, true)
+ checkRange(30, 69, false)
+ checkRange(70, 299, true)
+ checkRange(300, 699, false)
+ checkRange(700, 999, true)
+
+ db.DeleteRange([]byte(""), []byte("a"))
+ checkRange(1, 999, false)
+ })
}
// BenchDatabaseSuite runs a suite of benchmarks against a KeyValueStore database
@@ -438,6 +497,29 @@ func BenchDatabaseSuite(b *testing.B, New func() ethdb.KeyValueStore) {
benchBatchWrite(b, keys, vals)
})
})
+ b.Run("DeleteRange", func(b *testing.B) {
+ benchDeleteRange := func(b *testing.B, count int) {
+ db := New()
+ defer db.Close()
+
+ for i := 0; i < count; i++ {
+ db.Put([]byte(strconv.Itoa(i)), nil)
+ }
+ b.ResetTimer()
+ b.ReportAllocs()
+
+ db.DeleteRange([]byte("0"), []byte("999999999"))
+ }
+ b.Run("DeleteRange100", func(b *testing.B) {
+ benchDeleteRange(b, 100)
+ })
+ b.Run("DeleteRange1k", func(b *testing.B) {
+ benchDeleteRange(b, 1000)
+ })
+ b.Run("DeleteRange10k", func(b *testing.B) {
+ benchDeleteRange(b, 10000)
+ })
+ })
}
func iterateKeys(it ethdb.Iterator) []string {
diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go
index 24925a4f04..ce7d823561 100644
--- a/ethdb/leveldb/leveldb.go
+++ b/ethdb/leveldb/leveldb.go
@@ -21,6 +21,7 @@
package leveldb
import (
+ "bytes"
"fmt"
"sync"
"time"
@@ -206,6 +207,36 @@ func (db *Database) Delete(key []byte) error {
return db.db.Delete(key, nil)
}
+var ErrTooManyKeys = errors.New("too many keys in deleted range")
+
+// DeleteRange deletes all of the keys (and values) in the range [start,end)
+// (inclusive on start, exclusive on end).
+// Note that this is a fallback implementation as leveldb does not natively
+// support range deletion. It can be slow and therefore the number of deleted
+// keys is limited in order to avoid blocking for a very long time.
+// ErrTooManyKeys is returned if the range has only been partially deleted.
+// In this case the caller can repeat the call until it finally succeeds.
+func (db *Database) DeleteRange(start, end []byte) error {
+ batch := db.NewBatch()
+ it := db.NewIterator(nil, start)
+ defer it.Release()
+
+ var count int
+ for it.Next() && bytes.Compare(end, it.Key()) > 0 {
+ count++
+ if count > 10000 { // should not block for more than a second
+ if err := batch.Write(); err != nil {
+ return err
+ }
+ return ErrTooManyKeys
+ }
+ if err := batch.Delete(it.Key()); err != nil {
+ return err
+ }
+ }
+ return batch.Write()
+}
+
// NewBatch creates a write-only key-value store that buffers changes to its host
// database until a final write is called.
func (db *Database) NewBatch() ethdb.Batch {
diff --git a/ethdb/memorydb/memorydb.go b/ethdb/memorydb/memorydb.go
index 532e0dfe3f..c6fba39cfd 100644
--- a/ethdb/memorydb/memorydb.go
+++ b/ethdb/memorydb/memorydb.go
@@ -18,6 +18,7 @@
package memorydb
import (
+ "bytes"
"errors"
"sort"
"strings"
@@ -121,6 +122,20 @@ func (db *Database) Delete(key []byte) error {
return nil
}
+// DeleteRange deletes all of the keys (and values) in the range [start,end)
+// (inclusive on start, exclusive on end).
+func (db *Database) DeleteRange(start, end []byte) error {
+ it := db.NewIterator(nil, start)
+ defer it.Release()
+
+ for it.Next() && bytes.Compare(end, it.Key()) > 0 {
+ if err := db.Delete(it.Key()); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
// NewBatch creates a write-only key-value store that buffers changes to its host
// database until a final write is called.
func (db *Database) NewBatch() ethdb.Batch {
diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go
index e2ba9b8c7b..a9151a3bb5 100644
--- a/ethdb/pebble/pebble.go
+++ b/ethdb/pebble/pebble.go
@@ -335,7 +335,18 @@ func (d *Database) Delete(key []byte) error {
if d.closed {
return pebble.ErrClosed
}
- return d.db.Delete(key, nil)
+ return d.db.Delete(key, d.writeOptions)
+}
+
+// DeleteRange deletes all of the keys (and values) in the range [start,end)
+// (inclusive on start, exclusive on end).
+func (d *Database) DeleteRange(start, end []byte) error {
+ d.quitLock.RLock()
+ defer d.quitLock.RUnlock()
+ if d.closed {
+ return pebble.ErrClosed
+ }
+ return d.db.DeleteRange(start, end, d.writeOptions)
}
// NewBatch creates a write-only key-value store that buffers changes to its host
diff --git a/ethdb/remotedb/remotedb.go b/ethdb/remotedb/remotedb.go
index d0f018cb01..247a4392db 100644
--- a/ethdb/remotedb/remotedb.go
+++ b/ethdb/remotedb/remotedb.go
@@ -94,6 +94,10 @@ func (db *Database) Delete(key []byte) error {
panic("not supported")
}
+func (db *Database) DeleteRange(start, end []byte) error {
+ panic("not supported")
+}
+
func (db *Database) ModifyAncients(f func(ethdb.AncientWriteOp) error) (int64, error) {
panic("not supported")
}
diff --git a/go.mod b/go.mod
index fc469f3e93..1a26321def 100644
--- a/go.mod
+++ b/go.mod
@@ -31,7 +31,7 @@ require (
github.com/fsnotify/fsnotify v1.6.0
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
github.com/gofrs/flock v0.8.1
- github.com/golang-jwt/jwt/v4 v4.5.0
+ github.com/golang-jwt/jwt/v4 v4.5.1
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb
github.com/google/gofuzz v1.2.0
github.com/google/uuid v1.3.0
@@ -63,7 +63,6 @@ require (
github.com/stretchr/testify v1.9.0
github.com/supranational/blst v0.3.13
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
- github.com/tyler-smith/go-bip39 v1.1.0
github.com/urfave/cli/v2 v2.25.7
go.uber.org/automaxprocs v1.5.2
golang.org/x/crypto v0.22.0
diff --git a/go.sum b/go.sum
index 7b88051b5c..19a7b9d25c 100644
--- a/go.sum
+++ b/go.sum
@@ -213,8 +213,8 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
-github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
+github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -499,8 +499,6 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
-github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
-github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
diff --git a/internal/build/file.go b/internal/build/file.go
index c159b51892..2d8c993f36 100644
--- a/internal/build/file.go
+++ b/internal/build/file.go
@@ -16,7 +16,14 @@
package build
-import "os"
+import (
+ "crypto/sha256"
+ "io"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+)
// FileExist checks if a file exists at path.
func FileExist(path string) bool {
@@ -26,3 +33,70 @@ func FileExist(path string) bool {
}
return true
}
+
+// HashFiles iterates the provided set of files, computing the hash of each.
+func HashFiles(files []string) (map[string][32]byte, error) {
+ res := make(map[string][32]byte)
+ for _, filePath := range files {
+ f, err := os.OpenFile(filePath, os.O_RDONLY, 0666)
+ if err != nil {
+ return nil, err
+ }
+ hasher := sha256.New()
+ if _, err := io.Copy(hasher, f); err != nil {
+ return nil, err
+ }
+ res[filePath] = [32]byte(hasher.Sum(nil))
+ }
+ return res, nil
+}
+
+// HashFolder iterates all files under the given directory, computing the hash
+// of each.
+func HashFolder(folder string, exlude []string) (map[string][32]byte, error) {
+ res := make(map[string][32]byte)
+ err := filepath.WalkDir(folder, func(path string, d os.DirEntry, _ error) error {
+ // Skip anything that's exluded or not a regular file
+ for _, skip := range exlude {
+ if strings.HasPrefix(path, filepath.FromSlash(skip)) {
+ return filepath.SkipDir
+ }
+ }
+ if !d.Type().IsRegular() {
+ return nil
+ }
+ // Regular file found, hash it
+ f, err := os.OpenFile(path, os.O_RDONLY, 0666)
+ if err != nil {
+ return err
+ }
+ hasher := sha256.New()
+ if _, err := io.Copy(hasher, f); err != nil {
+ return err
+ }
+ res[path] = [32]byte(hasher.Sum(nil))
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ return res, nil
+}
+
+// DiffHashes compares two maps of file hashes and returns the changed files.
+func DiffHashes(a map[string][32]byte, b map[string][32]byte) []string {
+ var updates []string
+
+ for file := range a {
+ if _, ok := b[file]; !ok || a[file] != b[file] {
+ updates = append(updates, file)
+ }
+ }
+ for file := range b {
+ if _, ok := a[file]; !ok {
+ updates = append(updates, file)
+ }
+ }
+ sort.Strings(updates)
+ return updates
+}
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 10d79c85ae..a508b0ca5b 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -29,8 +29,6 @@ import (
"github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/accounts/scwallet"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
@@ -51,7 +49,6 @@ import (
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/trie"
"github.com/holiman/uint256"
- "github.com/tyler-smith/go-bip39"
)
// estimateGasErrorRatio is the amount of overestimation eth_estimateGas is
@@ -298,344 +295,6 @@ func (api *EthereumAccountAPI) Accounts() []common.Address {
return api.am.Accounts()
}
-// PersonalAccountAPI provides an API to access accounts managed by this node.
-// It offers methods to create, (un)lock en list accounts. Some methods accept
-// passwords and are therefore considered private by default.
-type PersonalAccountAPI struct {
- am *accounts.Manager
- nonceLock *AddrLocker
- b Backend
-}
-
-// NewPersonalAccountAPI creates a new PersonalAccountAPI.
-func NewPersonalAccountAPI(b Backend, nonceLock *AddrLocker) *PersonalAccountAPI {
- return &PersonalAccountAPI{
- am: b.AccountManager(),
- nonceLock: nonceLock,
- b: b,
- }
-}
-
-// ListAccounts will return a list of addresses for accounts this node manages.
-func (api *PersonalAccountAPI) ListAccounts() []common.Address {
- return api.am.Accounts()
-}
-
-// rawWallet is a JSON representation of an accounts.Wallet interface, with its
-// data contents extracted into plain fields.
-type rawWallet struct {
- URL string `json:"url"`
- Status string `json:"status"`
- Failure string `json:"failure,omitempty"`
- Accounts []accounts.Account `json:"accounts,omitempty"`
-}
-
-// ListWallets will return a list of wallets this node manages.
-func (api *PersonalAccountAPI) ListWallets() []rawWallet {
- wallets := make([]rawWallet, 0) // return [] instead of nil if empty
- for _, wallet := range api.am.Wallets() {
- status, failure := wallet.Status()
-
- raw := rawWallet{
- URL: wallet.URL().String(),
- Status: status,
- Accounts: wallet.Accounts(),
- }
- if failure != nil {
- raw.Failure = failure.Error()
- }
- wallets = append(wallets, raw)
- }
- return wallets
-}
-
-// OpenWallet initiates a hardware wallet opening procedure, establishing a USB
-// connection and attempting to authenticate via the provided passphrase. Note,
-// the method may return an extra challenge requiring a second open (e.g. the
-// Trezor PIN matrix challenge).
-func (api *PersonalAccountAPI) OpenWallet(url string, passphrase *string) error {
- wallet, err := api.am.Wallet(url)
- if err != nil {
- return err
- }
- pass := ""
- if passphrase != nil {
- pass = *passphrase
- }
- return wallet.Open(pass)
-}
-
-// DeriveAccount requests an HD wallet to derive a new account, optionally pinning
-// it for later reuse.
-func (api *PersonalAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) {
- wallet, err := api.am.Wallet(url)
- if err != nil {
- return accounts.Account{}, err
- }
- derivPath, err := accounts.ParseDerivationPath(path)
- if err != nil {
- return accounts.Account{}, err
- }
- if pin == nil {
- pin = new(bool)
- }
- return wallet.Derive(derivPath, *pin)
-}
-
-// NewAccount will create a new account and returns the address for the new account.
-func (api *PersonalAccountAPI) NewAccount(password string) (common.AddressEIP55, error) {
- ks, err := fetchKeystore(api.am)
- if err != nil {
- return common.AddressEIP55{}, err
- }
- acc, err := ks.NewAccount(password)
- if err == nil {
- addrEIP55 := common.AddressEIP55(acc.Address)
- log.Info("Your new key was generated", "address", addrEIP55.String())
- log.Warn("Please backup your key file!", "path", acc.URL.Path)
- log.Warn("Please remember your password!")
- return addrEIP55, nil
- }
- return common.AddressEIP55{}, err
-}
-
-// fetchKeystore retrieves the encrypted keystore from the account manager.
-func fetchKeystore(am *accounts.Manager) (*keystore.KeyStore, error) {
- if ks := am.Backends(keystore.KeyStoreType); len(ks) > 0 {
- return ks[0].(*keystore.KeyStore), nil
- }
- return nil, errors.New("local keystore not used")
-}
-
-// ImportRawKey stores the given hex encoded ECDSA key into the key directory,
-// encrypting it with the passphrase.
-func (api *PersonalAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) {
- key, err := crypto.HexToECDSA(privkey)
- if err != nil {
- return common.Address{}, err
- }
- ks, err := fetchKeystore(api.am)
- if err != nil {
- return common.Address{}, err
- }
- acc, err := ks.ImportECDSA(key, password)
- return acc.Address, err
-}
-
-// UnlockAccount will unlock the account associated with the given address with
-// the given password for duration seconds. If duration is nil it will use a
-// default of 300 seconds. It returns an indication if the account was unlocked.
-func (api *PersonalAccountAPI) UnlockAccount(ctx context.Context, addr common.Address, password string, duration *uint64) (bool, error) {
- // When the API is exposed by external RPC(http, ws etc), unless the user
- // explicitly specifies to allow the insecure account unlocking, otherwise
- // it is disabled.
- if api.b.ExtRPCEnabled() && !api.b.AccountManager().Config().InsecureUnlockAllowed {
- return false, errors.New("account unlock with HTTP access is forbidden")
- }
-
- const max = uint64(time.Duration(gomath.MaxInt64) / time.Second)
- var d time.Duration
- if duration == nil {
- d = 300 * time.Second
- } else if *duration > max {
- return false, errors.New("unlock duration too large")
- } else {
- d = time.Duration(*duration) * time.Second
- }
- ks, err := fetchKeystore(api.am)
- if err != nil {
- return false, err
- }
- err = ks.TimedUnlock(accounts.Account{Address: addr}, password, d)
- if err != nil {
- log.Warn("Failed account unlock attempt", "address", addr, "err", err)
- }
- return err == nil, err
-}
-
-// LockAccount will lock the account associated with the given address when it's unlocked.
-func (api *PersonalAccountAPI) LockAccount(addr common.Address) bool {
- if ks, err := fetchKeystore(api.am); err == nil {
- return ks.Lock(addr) == nil
- }
- return false
-}
-
-// signTransaction sets defaults and signs the given transaction
-// NOTE: the caller needs to ensure that the nonceLock is held, if applicable,
-// and release it after the transaction has been submitted to the tx pool
-func (api *PersonalAccountAPI) signTransaction(ctx context.Context, args *TransactionArgs, passwd string) (*types.Transaction, error) {
- // Look up the wallet containing the requested signer
- account := accounts.Account{Address: args.from()}
- wallet, err := api.am.Find(account)
- if err != nil {
- return nil, err
- }
- // Set some sanity defaults and terminate on failure
- if err := args.setDefaults(ctx, api.b, false); err != nil {
- return nil, err
- }
- // Assemble the transaction and sign with the wallet
- tx := args.ToTransaction(types.LegacyTxType)
-
- return wallet.SignTxWithPassphrase(account, passwd, tx, api.b.ChainConfig().ChainID)
-}
-
-// SendTransaction will create a transaction from the given arguments and
-// tries to sign it with the key associated with args.From. If the given
-// passwd isn't able to decrypt the key it fails.
-func (api *PersonalAccountAPI) SendTransaction(ctx context.Context, args TransactionArgs, passwd string) (common.Hash, error) {
- if args.Nonce == nil {
- // Hold the mutex around signing to prevent concurrent assignment of
- // the same nonce to multiple accounts.
- api.nonceLock.LockAddr(args.from())
- defer api.nonceLock.UnlockAddr(args.from())
- }
- if args.IsEIP4844() {
- return common.Hash{}, errBlobTxNotSupported
- }
- signed, err := api.signTransaction(ctx, &args, passwd)
- if err != nil {
- log.Warn("Failed transaction send attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err)
- return common.Hash{}, err
- }
- return SubmitTransaction(ctx, api.b, signed)
-}
-
-// SignTransaction will create a transaction from the given arguments and
-// tries to sign it with the key associated with args.From. If the given passwd isn't
-// able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast
-// to other nodes
-func (api *PersonalAccountAPI) SignTransaction(ctx context.Context, args TransactionArgs, passwd string) (*SignTransactionResult, error) {
- // No need to obtain the noncelock mutex, since we won't be sending this
- // tx into the transaction pool, but right back to the user
- if args.From == nil {
- return nil, errors.New("sender not specified")
- }
- if args.Gas == nil {
- return nil, errors.New("gas not specified")
- }
- if args.GasPrice == nil && (args.MaxFeePerGas == nil || args.MaxPriorityFeePerGas == nil) {
- return nil, errors.New("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas")
- }
- if args.IsEIP4844() {
- return nil, errBlobTxNotSupported
- }
- if args.Nonce == nil {
- return nil, errors.New("nonce not specified")
- }
- // Before actually signing the transaction, ensure the transaction fee is reasonable.
- tx := args.ToTransaction(types.LegacyTxType)
- if err := checkTxFee(tx.GasPrice(), tx.Gas(), api.b.RPCTxFeeCap()); err != nil {
- return nil, err
- }
- signed, err := api.signTransaction(ctx, &args, passwd)
- if err != nil {
- log.Warn("Failed transaction sign attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err)
- return nil, err
- }
- data, err := signed.MarshalBinary()
- if err != nil {
- return nil, err
- }
- return &SignTransactionResult{data, signed}, nil
-}
-
-// Sign calculates an Ethereum ECDSA signature for:
-// keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))
-//
-// Note, the produced signature conforms to the secp256k1 curve R, S and V values,
-// where the V value will be 27 or 28 for legacy reasons.
-//
-// The key used to calculate the signature is decrypted with the given password.
-//
-// https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-personal#personal-sign
-func (api *PersonalAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) {
- // Look up the wallet containing the requested signer
- account := accounts.Account{Address: addr}
-
- wallet, err := api.b.AccountManager().Find(account)
- if err != nil {
- return nil, err
- }
- // Assemble sign the data with the wallet
- signature, err := wallet.SignTextWithPassphrase(account, passwd, data)
- if err != nil {
- log.Warn("Failed data sign attempt", "address", addr, "err", err)
- return nil, err
- }
- signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
- return signature, nil
-}
-
-// EcRecover returns the address for the account that was used to create the signature.
-// Note, this function is compatible with eth_sign and personal_sign. As such it recovers
-// the address of:
-// hash = keccak256("\x19Ethereum Signed Message:\n"${message length}${message})
-// addr = ecrecover(hash, signature)
-//
-// Note, the signature must conform to the secp256k1 curve R, S and V values, where
-// the V value must be 27 or 28 for legacy reasons.
-//
-// https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-personal#personal-ecrecover
-func (api *PersonalAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) {
- if len(sig) != crypto.SignatureLength {
- return common.Address{}, fmt.Errorf("signature must be %d bytes long", crypto.SignatureLength)
- }
- if sig[crypto.RecoveryIDOffset] != 27 && sig[crypto.RecoveryIDOffset] != 28 {
- return common.Address{}, errors.New("invalid Ethereum signature (V is not 27 or 28)")
- }
- sig[crypto.RecoveryIDOffset] -= 27 // Transform yellow paper V from 27/28 to 0/1
-
- rpk, err := crypto.SigToPub(accounts.TextHash(data), sig)
- if err != nil {
- return common.Address{}, err
- }
- return crypto.PubkeyToAddress(*rpk), nil
-}
-
-// InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key.
-func (api *PersonalAccountAPI) InitializeWallet(ctx context.Context, url string) (string, error) {
- wallet, err := api.am.Wallet(url)
- if err != nil {
- return "", err
- }
-
- entropy, err := bip39.NewEntropy(256)
- if err != nil {
- return "", err
- }
-
- mnemonic, err := bip39.NewMnemonic(entropy)
- if err != nil {
- return "", err
- }
-
- seed := bip39.NewSeed(mnemonic, "")
-
- switch wallet := wallet.(type) {
- case *scwallet.Wallet:
- return mnemonic, wallet.Initialize(seed)
- default:
- return "", errors.New("specified wallet does not support initialization")
- }
-}
-
-// Unpair deletes a pairing between wallet and geth.
-func (api *PersonalAccountAPI) Unpair(ctx context.Context, url string, pin string) error {
- wallet, err := api.am.Wallet(url)
- if err != nil {
- return err
- }
-
- switch wallet := wallet.(type) {
- case *scwallet.Wallet:
- return wallet.Unpair([]byte(pin))
- default:
- return errors.New("specified wallet does not support pairing")
- }
-}
-
// BlockChainAPI provides an API to access Ethereum blockchain data.
type BlockChainAPI struct {
b Backend
@@ -1628,9 +1287,18 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
}
// Ensure any missing fields are filled, extract the recipient and input data
- if err := args.setDefaults(ctx, b, true); err != nil {
+ if err = args.setFeeDefaults(ctx, b, header); err != nil {
return nil, 0, nil, err
}
+ if args.Nonce == nil {
+ nonce := hexutil.Uint64(db.GetNonce(args.from()))
+ args.Nonce = &nonce
+ }
+ blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil)
+ if err = args.CallDefaults(b.RPCGasCap(), blockCtx.BaseFee, b.ChainConfig().ChainID); err != nil {
+ return nil, 0, nil, err
+ }
+
var to common.Address
if args.To != nil {
to = *args.To
diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go
index ccc11472b7..82465ca7d7 100644
--- a/internal/ethapi/backend.go
+++ b/internal/ethapi/backend.go
@@ -118,9 +118,6 @@ func GetAPIs(apiBackend Backend) []rpc.API {
}, {
Namespace: "eth",
Service: NewEthereumAccountAPI(apiBackend.AccountManager()),
- }, {
- Namespace: "personal",
- Service: NewPersonalAccountAPI(apiBackend, nonceLock),
},
}
}
diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go
index b6346e910d..91e05544dc 100644
--- a/internal/ethapi/transaction_args.go
+++ b/internal/ethapi/transaction_args.go
@@ -100,7 +100,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas
if err := args.setBlobTxSidecar(ctx); err != nil {
return err
}
- if err := args.setFeeDefaults(ctx, b); err != nil {
+ if err := args.setFeeDefaults(ctx, b, b.CurrentHeader()); err != nil {
return err
}
@@ -183,8 +183,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas
}
// setFeeDefaults fills in default fee values for unspecified tx fields.
-func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend) error {
- head := b.CurrentHeader()
+func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend, head *types.Header) error {
// Sanity check the EIP-4844 fee parameters.
if args.BlobFeeCap != nil && args.BlobFeeCap.ToInt().Sign() == 0 {
return errors.New("maxFeePerBlobGas, if specified, must be non-zero")
diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go
index a3bf19b686..5f59b491e1 100644
--- a/internal/ethapi/transaction_args_test.go
+++ b/internal/ethapi/transaction_args_test.go
@@ -238,7 +238,7 @@ func TestSetFeeDefaults(t *testing.T) {
t.Fatalf("failed to set fork: %v", err)
}
got := test.in
- err := got.setFeeDefaults(ctx, b)
+ err := got.setFeeDefaults(ctx, b, b.CurrentHeader())
if err != nil {
if test.err == nil {
t.Fatalf("test %d (%s): unexpected error: %s", i, test.name, err)
diff --git a/internal/flags/flags.go b/internal/flags/flags.go
index bf62c53adf..1f6be3d3d3 100644
--- a/internal/flags/flags.go
+++ b/internal/flags/flags.go
@@ -17,7 +17,6 @@
package flags
import (
- "encoding"
"errors"
"flag"
"fmt"
@@ -122,119 +121,6 @@ func (f *DirectoryFlag) GetDefaultText() string {
return f.GetValue()
}
-type TextMarshaler interface {
- encoding.TextMarshaler
- encoding.TextUnmarshaler
-}
-
-// textMarshalerVal turns a TextMarshaler into a flag.Value
-type textMarshalerVal struct {
- v TextMarshaler
-}
-
-func (v textMarshalerVal) String() string {
- if v.v == nil {
- return ""
- }
- text, _ := v.v.MarshalText()
- return string(text)
-}
-
-func (v textMarshalerVal) Set(s string) error {
- return v.v.UnmarshalText([]byte(s))
-}
-
-var (
- _ cli.Flag = (*TextMarshalerFlag)(nil)
- _ cli.RequiredFlag = (*TextMarshalerFlag)(nil)
- _ cli.VisibleFlag = (*TextMarshalerFlag)(nil)
- _ cli.DocGenerationFlag = (*TextMarshalerFlag)(nil)
- _ cli.CategorizableFlag = (*TextMarshalerFlag)(nil)
-)
-
-// TextMarshalerFlag wraps a TextMarshaler value.
-type TextMarshalerFlag struct {
- Name string
-
- Category string
- DefaultText string
- Usage string
-
- Required bool
- Hidden bool
- HasBeenSet bool
-
- Value TextMarshaler
-
- Aliases []string
- EnvVars []string
-}
-
-// For cli.Flag:
-
-func (f *TextMarshalerFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) }
-func (f *TextMarshalerFlag) IsSet() bool { return f.HasBeenSet }
-func (f *TextMarshalerFlag) String() string { return cli.FlagStringer(f) }
-
-func (f *TextMarshalerFlag) Apply(set *flag.FlagSet) error {
- for _, envVar := range f.EnvVars {
- envVar = strings.TrimSpace(envVar)
- if value, found := syscall.Getenv(envVar); found {
- if err := f.Value.UnmarshalText([]byte(value)); err != nil {
- return fmt.Errorf("could not parse %q from environment variable %q for flag %s: %s", value, envVar, f.Name, err)
- }
- f.HasBeenSet = true
- break
- }
- }
- eachName(f, func(name string) {
- set.Var(textMarshalerVal{f.Value}, f.Name, f.Usage)
- })
- return nil
-}
-
-// For cli.RequiredFlag:
-
-func (f *TextMarshalerFlag) IsRequired() bool { return f.Required }
-
-// For cli.VisibleFlag:
-
-func (f *TextMarshalerFlag) IsVisible() bool { return !f.Hidden }
-
-// For cli.CategorizableFlag:
-
-func (f *TextMarshalerFlag) GetCategory() string { return f.Category }
-
-// For cli.DocGenerationFlag:
-
-func (f *TextMarshalerFlag) TakesValue() bool { return true }
-func (f *TextMarshalerFlag) GetUsage() string { return f.Usage }
-func (f *TextMarshalerFlag) GetEnvVars() []string { return f.EnvVars }
-
-func (f *TextMarshalerFlag) GetValue() string {
- t, err := f.Value.MarshalText()
- if err != nil {
- return "(ERR: " + err.Error() + ")"
- }
- return string(t)
-}
-
-func (f *TextMarshalerFlag) GetDefaultText() string {
- if f.DefaultText != "" {
- return f.DefaultText
- }
- return f.GetValue()
-}
-
-// GlobalTextMarshaler returns the value of a TextMarshalerFlag from the global flag set.
-func GlobalTextMarshaler(ctx *cli.Context, name string) TextMarshaler {
- val := ctx.Generic(name)
- if val == nil {
- return nil
- }
- return val.(textMarshalerVal).v
-}
-
var (
_ cli.Flag = (*BigFlag)(nil)
_ cli.RequiredFlag = (*BigFlag)(nil)
diff --git a/internal/flags/helpers.go b/internal/flags/helpers.go
index 32be3d11a7..fd706869f1 100644
--- a/internal/flags/helpers.go
+++ b/internal/flags/helpers.go
@@ -48,15 +48,6 @@ func NewApp(usage string) *cli.App {
return app
}
-// Merge merges the given flag slices.
-func Merge(groups ...[]cli.Flag) []cli.Flag {
- var ret []cli.Flag
- for _, group := range groups {
- ret = append(ret, group...)
- }
- return ret
-}
-
var migrationApplied = map[*cli.Command]struct{}{}
// MigrateGlobalFlags makes all global flag values available in the
@@ -265,9 +256,6 @@ func AutoEnvVars(flags []cli.Flag, prefix string) {
case *BigFlag:
flag.EnvVars = append(flag.EnvVars, envvar)
- case *TextMarshalerFlag:
- flag.EnvVars = append(flag.EnvVars, envvar)
-
case *DirectoryFlag:
flag.EnvVars = append(flag.EnvVars, envvar)
}
diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go
index 927ebc2ef0..0c346bbf79 100644
--- a/internal/web3ext/web3ext.go
+++ b/internal/web3ext/web3ext.go
@@ -18,16 +18,15 @@
package web3ext
var Modules = map[string]string{
- "admin": AdminJs,
- "clique": CliqueJs,
- "debug": DebugJs,
- "eth": EthJs,
- "miner": MinerJs,
- "net": NetJs,
- "personal": PersonalJs,
- "rpc": RpcJs,
- "txpool": TxpoolJs,
- "dev": DevJs,
+ "admin": AdminJs,
+ "clique": CliqueJs,
+ "debug": DebugJs,
+ "eth": EthJs,
+ "miner": MinerJs,
+ "net": NetJs,
+ "rpc": RpcJs,
+ "txpool": TxpoolJs,
+ "dev": DevJs,
}
const CliqueJs = `
@@ -658,62 +657,6 @@ web3._extend({
});
`
-const PersonalJs = `
-web3._extend({
- property: 'personal',
- methods: [
- new web3._extend.Method({
- name: 'importRawKey',
- call: 'personal_importRawKey',
- params: 2
- }),
- new web3._extend.Method({
- name: 'sign',
- call: 'personal_sign',
- params: 3,
- inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, null]
- }),
- new web3._extend.Method({
- name: 'ecRecover',
- call: 'personal_ecRecover',
- params: 2
- }),
- new web3._extend.Method({
- name: 'openWallet',
- call: 'personal_openWallet',
- params: 2
- }),
- new web3._extend.Method({
- name: 'deriveAccount',
- call: 'personal_deriveAccount',
- params: 3
- }),
- new web3._extend.Method({
- name: 'signTransaction',
- call: 'personal_signTransaction',
- params: 2,
- inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null]
- }),
- new web3._extend.Method({
- name: 'unpair',
- call: 'personal_unpair',
- params: 2
- }),
- new web3._extend.Method({
- name: 'initializeWallet',
- call: 'personal_initializeWallet',
- params: 1
- })
- ],
- properties: [
- new web3._extend.Property({
- name: 'listWallets',
- getter: 'personal_listWallets'
- }),
- ]
-})
-`
-
const RpcJs = `
web3._extend({
property: 'rpc',
diff --git a/log/logger_test.go b/log/logger_test.go
index f1a9a93bce..3ec6d2e19c 100644
--- a/log/logger_test.go
+++ b/log/logger_test.go
@@ -7,7 +7,6 @@ import (
"io"
"log/slog"
"math/big"
- "os"
"strings"
"testing"
"time"
@@ -70,7 +69,7 @@ func TestJSONHandler(t *testing.T) {
}
func BenchmarkTraceLogging(b *testing.B) {
- SetDefault(NewLogger(NewTerminalHandler(os.Stderr, true)))
+ SetDefault(NewLogger(NewTerminalHandler(io.Discard, true)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
Trace("a message", "v", i)
diff --git a/metrics/sample_test.go b/metrics/sample_test.go
index 4227b43ef7..c855671ae2 100644
--- a/metrics/sample_test.go
+++ b/metrics/sample_test.go
@@ -3,7 +3,6 @@ package metrics
import (
"math"
"math/rand"
- "runtime"
"testing"
"time"
)
@@ -27,6 +26,7 @@ func BenchmarkCompute1000(b *testing.B) {
SampleVariance(mean, s)
}
}
+
func BenchmarkCompute1000000(b *testing.B) {
s := make([]int64, 1000000)
var sum int64
@@ -40,28 +40,6 @@ func BenchmarkCompute1000000(b *testing.B) {
SampleVariance(mean, s)
}
}
-func BenchmarkCopy1000(b *testing.B) {
- s := make([]int64, 1000)
- for i := 0; i < len(s); i++ {
- s[i] = int64(i)
- }
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- sCopy := make([]int64, len(s))
- copy(sCopy, s)
- }
-}
-func BenchmarkCopy1000000(b *testing.B) {
- s := make([]int64, 1000000)
- for i := 0; i < len(s); i++ {
- s[i] = int64(i)
- }
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- sCopy := make([]int64, len(s))
- copy(sCopy, s)
- }
-}
func BenchmarkExpDecaySample257(b *testing.B) {
benchmarkSample(b, NewExpDecaySample(257, 0.015))
@@ -237,17 +215,9 @@ func TestUniformSampleStatistics(t *testing.T) {
}
func benchmarkSample(b *testing.B, s Sample) {
- var memStats runtime.MemStats
- runtime.ReadMemStats(&memStats)
- pauseTotalNs := memStats.PauseTotalNs
- b.ResetTimer()
for i := 0; i < b.N; i++ {
s.Update(1)
}
- b.StopTimer()
- runtime.GC()
- runtime.ReadMemStats(&memStats)
- b.Logf("GC cost: %d ns/op", int(memStats.PauseTotalNs-pauseTotalNs)/b.N)
}
func testExpDecaySampleStatistics(t *testing.T, s SampleSnapshot) {
diff --git a/node/database.go b/node/database.go
new file mode 100644
index 0000000000..e3ccb91066
--- /dev/null
+++ b/node/database.go
@@ -0,0 +1,111 @@
+// Copyright 2024 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package node
+
+import (
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/core/rawdb"
+ "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/ethdb/leveldb"
+ "github.com/ethereum/go-ethereum/ethdb/pebble"
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// openOptions contains the options to apply when opening a database.
+// OBS: If AncientsDirectory is empty, it indicates that no freezer is to be used.
+type openOptions struct {
+ Type string // "leveldb" | "pebble"
+ Directory string // the datadir
+ AncientsDirectory string // the ancients-dir
+ Namespace string // the namespace for database relevant metrics
+ Cache int // the capacity(in megabytes) of the data caching
+ Handles int // number of files to be open simultaneously
+ ReadOnly bool
+}
+
+// openDatabase opens both a disk-based key-value database such as leveldb or pebble, but also
+// integrates it with a freezer database -- if the AncientDir option has been
+// set on the provided OpenOptions.
+// The passed o.AncientDir indicates the path of root ancient directory where
+// the chain freezer can be opened.
+func openDatabase(o openOptions) (ethdb.Database, error) {
+ kvdb, err := openKeyValueDatabase(o)
+ if err != nil {
+ return nil, err
+ }
+ if len(o.AncientsDirectory) == 0 {
+ return kvdb, nil
+ }
+ frdb, err := rawdb.NewDatabaseWithFreezer(kvdb, o.AncientsDirectory, o.Namespace, o.ReadOnly)
+ if err != nil {
+ kvdb.Close()
+ return nil, err
+ }
+ return frdb, nil
+}
+
+// openKeyValueDatabase opens a disk-based key-value database, e.g. leveldb or pebble.
+//
+// type == null type != null
+// +----------------------------------------
+// db is non-existent | pebble default | specified type
+// db is existent | from db | specified type (if compatible)
+func openKeyValueDatabase(o openOptions) (ethdb.Database, error) {
+ // Reject any unsupported database type
+ if len(o.Type) != 0 && o.Type != rawdb.DBLeveldb && o.Type != rawdb.DBPebble {
+ return nil, fmt.Errorf("unknown db.engine %v", o.Type)
+ }
+ // Retrieve any pre-existing database's type and use that or the requested one
+ // as long as there's no conflict between the two types
+ existingDb := rawdb.PreexistingDatabase(o.Directory)
+ if len(existingDb) != 0 && len(o.Type) != 0 && o.Type != existingDb {
+ return nil, fmt.Errorf("db.engine choice was %v but found pre-existing %v database in specified data directory", o.Type, existingDb)
+ }
+ if o.Type == rawdb.DBPebble || existingDb == rawdb.DBPebble {
+ log.Info("Using pebble as the backing database")
+ return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
+ }
+ if o.Type == rawdb.DBLeveldb || existingDb == rawdb.DBLeveldb {
+ log.Info("Using leveldb as the backing database")
+ return newLevelDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
+ }
+ // No pre-existing database, no user-requested one either. Default to Pebble.
+ log.Info("Defaulting to pebble as the backing database")
+ return newPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
+}
+
+// newLevelDBDatabase creates a persistent key-value database without a freezer
+// moving immutable chain segments into cold storage.
+func newLevelDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) {
+ db, err := leveldb.New(file, cache, handles, namespace, readonly)
+ if err != nil {
+ return nil, err
+ }
+ log.Info("Using LevelDB as the backing database")
+ return rawdb.NewDatabase(db), nil
+}
+
+// newPebbleDBDatabase creates a persistent key-value database without a freezer
+// moving immutable chain segments into cold storage.
+func newPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) {
+ db, err := pebble.New(file, cache, handles, namespace, readonly)
+ if err != nil {
+ return nil, err
+ }
+ return rawdb.NewDatabase(db), nil
+}
diff --git a/node/node.go b/node/node.go
index 633f88f058..92c0c35607 100644
--- a/node/node.go
+++ b/node/node.go
@@ -375,25 +375,13 @@ func (n *Node) obtainJWTSecret(cliParam string) ([]byte, error) {
// startup. It's not meant to be called at any time afterwards as it makes certain
// assumptions about the state of the node.
func (n *Node) startRPC() error {
- // Filter out personal api
- var apis []rpc.API
- for _, api := range n.rpcAPIs {
- if api.Namespace == "personal" {
- if n.config.EnablePersonal {
- log.Warn("Deprecated personal namespace activated")
- } else {
- continue
- }
- }
- apis = append(apis, api)
- }
- if err := n.startInProc(apis); err != nil {
+ if err := n.startInProc(n.rpcAPIs); err != nil {
return err
}
// Configure IPC.
if n.ipc.endpoint != "" {
- if err := n.ipc.start(apis); err != nil {
+ if err := n.ipc.start(n.rpcAPIs); err != nil {
return err
}
}
@@ -723,7 +711,7 @@ func (n *Node) OpenDatabase(name string, cache, handles int, namespace string, r
if n.config.DataDir == "" {
db = rawdb.NewMemoryDatabase()
} else {
- db, err = rawdb.Open(rawdb.OpenOptions{
+ db, err = openDatabase(openOptions{
Type: n.config.DBEngine,
Directory: n.ResolvePath(name),
Namespace: namespace,
@@ -732,7 +720,6 @@ func (n *Node) OpenDatabase(name string, cache, handles int, namespace string, r
ReadOnly: readonly,
})
}
-
if err == nil {
db = n.wrapDatabase(db)
}
@@ -755,7 +742,7 @@ func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, ancient
if n.config.DataDir == "" {
db, err = rawdb.NewDatabaseWithFreezer(memorydb.New(), "", namespace, readonly)
} else {
- db, err = rawdb.Open(rawdb.OpenOptions{
+ db, err = openDatabase(openOptions{
Type: n.config.DBEngine,
Directory: n.ResolvePath(name),
AncientsDirectory: n.ResolveAncient(name, ancient),
@@ -765,7 +752,6 @@ func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, ancient
ReadOnly: readonly,
})
}
-
if err == nil {
db = n.wrapDatabase(db)
}
diff --git a/oss-fuzz.sh b/oss-fuzz.sh
index 7993dc9c64..50491b9155 100644
--- a/oss-fuzz.sh
+++ b/oss-fuzz.sh
@@ -220,6 +220,10 @@ compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/secp256k1 \
Fuzz fuzzSecp256k1\
$repo/tests/fuzzers/secp256k1/secp_test.go
+compile_fuzzer github.com/ethereum/go-ethereum/eth/protocols/eth \
+ FuzzEthProtocolHandlers fuzz_eth_protocol_handlers \
+ $repo/eth/protocols/eth/handler_test.go
+
#compile_fuzzer tests/fuzzers/vflux FuzzClientPool fuzzClientPool
#compile_fuzzer tests/fuzzers/difficulty Fuzz fuzzDifficulty
diff --git a/p2p/netutil/addrutil_test.go b/p2p/netutil/addrutil_test.go
new file mode 100644
index 0000000000..0abbabb54b
--- /dev/null
+++ b/p2p/netutil/addrutil_test.go
@@ -0,0 +1,140 @@
+// Copyright 2024 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package netutil
+
+import (
+ "net"
+ "net/netip"
+ "path/filepath"
+ "testing"
+)
+
+// customNetAddr is a custom implementation of net.Addr for testing purposes.
+type customNetAddr struct{}
+
+func (c *customNetAddr) Network() string { return "custom" }
+func (c *customNetAddr) String() string { return "custom" }
+
+func TestAddrAddr(t *testing.T) {
+ tempDir := t.TempDir()
+ tests := []struct {
+ name string
+ addr net.Addr
+ want netip.Addr
+ }{
+ {
+ name: "IPAddr IPv4",
+ addr: &net.IPAddr{IP: net.ParseIP("192.0.2.1")},
+ want: netip.MustParseAddr("192.0.2.1"),
+ },
+ {
+ name: "IPAddr IPv6",
+ addr: &net.IPAddr{IP: net.ParseIP("2001:db8::1")},
+ want: netip.MustParseAddr("2001:db8::1"),
+ },
+ {
+ name: "TCPAddr IPv4",
+ addr: &net.TCPAddr{IP: net.ParseIP("192.0.2.1"), Port: 8080},
+ want: netip.MustParseAddr("192.0.2.1"),
+ },
+ {
+ name: "TCPAddr IPv6",
+ addr: &net.TCPAddr{IP: net.ParseIP("2001:db8::1"), Port: 8080},
+ want: netip.MustParseAddr("2001:db8::1"),
+ },
+ {
+ name: "UDPAddr IPv4",
+ addr: &net.UDPAddr{IP: net.ParseIP("192.0.2.1"), Port: 8080},
+ want: netip.MustParseAddr("192.0.2.1"),
+ },
+ {
+ name: "UDPAddr IPv6",
+ addr: &net.UDPAddr{IP: net.ParseIP("2001:db8::1"), Port: 8080},
+ want: netip.MustParseAddr("2001:db8::1"),
+ },
+ {
+ name: "Unsupported Addr type",
+ addr: &net.UnixAddr{Name: filepath.Join(tempDir, "test.sock"), Net: "unix"},
+ want: netip.Addr{},
+ },
+ {
+ name: "Nil input",
+ addr: nil,
+ want: netip.Addr{},
+ },
+ {
+ name: "Custom net.Addr implementation",
+ addr: &customNetAddr{},
+ want: netip.Addr{},
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := AddrAddr(tt.addr); got != tt.want {
+ t.Errorf("AddrAddr() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestIPToAddr(t *testing.T) {
+ tests := []struct {
+ name string
+ ip net.IP
+ want netip.Addr
+ }{
+ {
+ name: "IPv4",
+ ip: net.ParseIP("192.0.2.1"),
+ want: netip.MustParseAddr("192.0.2.1"),
+ },
+ {
+ name: "IPv6",
+ ip: net.ParseIP("2001:db8::1"),
+ want: netip.MustParseAddr("2001:db8::1"),
+ },
+ {
+ name: "Invalid IP",
+ ip: net.IP{1, 2, 3},
+ want: netip.Addr{},
+ },
+ {
+ name: "Invalid IP (5 octets)",
+ ip: net.IP{192, 0, 2, 1, 1},
+ want: netip.Addr{},
+ },
+ {
+ name: "IPv4-mapped IPv6",
+ ip: net.ParseIP("::ffff:192.0.2.1"),
+ want: netip.MustParseAddr("192.0.2.1"),
+ },
+ {
+ name: "Nil input",
+ ip: nil,
+ want: netip.Addr{},
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := IPToAddr(tt.ip); got != tt.want {
+ t.Errorf("IPToAddr() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/signer/core/apitypes/signed_data_internal_test.go b/signer/core/apitypes/signed_data_internal_test.go
index 8b4a839c1d..1a14b35ef2 100644
--- a/signer/core/apitypes/signed_data_internal_test.go
+++ b/signer/core/apitypes/signed_data_internal_test.go
@@ -18,12 +18,18 @@ package apitypes
import (
"bytes"
+ "encoding/json"
+ "fmt"
"math/big"
+ "os"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestBytesPadding(t *testing.T) {
@@ -244,45 +250,42 @@ func TestConvertAddressDataToSlice(t *testing.T) {
func TestTypedDataArrayValidate(t *testing.T) {
t.Parallel()
- typedData := TypedData{
- Types: Types{
- "BulkOrder": []Type{
- // Should be able to accept fixed size arrays
- {Name: "tree", Type: "OrderComponents[2][2]"},
- },
- "OrderComponents": []Type{
- {Name: "offerer", Type: "address"},
- {Name: "amount", Type: "uint8"},
- },
- "EIP712Domain": []Type{
- {Name: "name", Type: "string"},
- {Name: "version", Type: "string"},
- {Name: "chainId", Type: "uint8"},
- {Name: "verifyingContract", Type: "address"},
- },
- },
- PrimaryType: "BulkOrder",
- Domain: TypedDataDomain{
- VerifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
- },
- Message: TypedDataMessage{},
+ type testDataInput struct {
+ Name string `json:"name"`
+ Domain TypedDataDomain `json:"domain"`
+ PrimaryType string `json:"primaryType"`
+ Types Types `json:"types"`
+ Message TypedDataMessage `json:"data"`
+ Digest string `json:"digest"`
}
+ fc, err := os.ReadFile("./testdata/typed-data.json")
+ require.NoError(t, err, "error reading test data file")
- if err := typedData.validate(); err != nil {
- t.Errorf("expected typed data to pass validation, got: %v", err)
- }
+ var tests []testDataInput
+ err = json.Unmarshal(fc, &tests)
+ require.NoError(t, err, "error unmarshalling test data file contents")
- // Should be able to accept dynamic arrays
- typedData.Types["BulkOrder"][0].Type = "OrderComponents[]"
+ for _, tc := range tests {
+ t.Run(tc.Name, func(t *testing.T) {
+ t.Parallel()
- if err := typedData.validate(); err != nil {
- t.Errorf("expected typed data to pass validation, got: %v", err)
- }
+ td := TypedData{
+ Types: tc.Types,
+ PrimaryType: tc.PrimaryType,
+ Domain: tc.Domain,
+ Message: tc.Message,
+ }
- // Should be able to accept standard types
- typedData.Types["BulkOrder"][0].Type = "OrderComponents"
+ domainSeparator, tErr := td.HashStruct("EIP712Domain", td.Domain.Map())
+ assert.NoError(t, tErr, "failed to hash domain separator: %v", tErr)
- if err := typedData.validate(); err != nil {
- t.Errorf("expected typed data to pass validation, got: %v", err)
+ messageHash, tErr := td.HashStruct(td.PrimaryType, td.Message)
+ assert.NoError(t, tErr, "failed to hash message: %v", tErr)
+
+ digest := crypto.Keccak256Hash([]byte(fmt.Sprintf("%s%s%s", "\x19\x01", string(domainSeparator), string(messageHash))))
+ assert.Equal(t, tc.Digest, digest.String(), "digest doesn't not match")
+
+ assert.NoError(t, td.validate(), "validation failed", tErr)
+ })
}
}
diff --git a/signer/core/apitypes/testdata/typed-data.json b/signer/core/apitypes/testdata/typed-data.json
new file mode 100644
index 0000000000..f77f72e5eb
--- /dev/null
+++ b/signer/core/apitypes/testdata/typed-data.json
@@ -0,0 +1,6089 @@
+[
+ {
+ "name": "random-0",
+ "domain": {
+ "name": "Moo é🚀ooéééMooooM🚀 o🚀🚀o M oM🚀éo 🚀🚀🚀🚀éoMoéo🚀o",
+ "version": "28.44.13"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xdce44ca98616ee629199215ae5401c97040664637c48"
+ },
+ "encoded": "0xcdf7d44b9a42bfc5a90b1624215e30c70425b44f1c62f94244b32551826d2dd995cff8fcf943ffa581b017b61b02703628c843642652c382dd15c9a471fe28d9",
+ "digest": "0xf1a2769507736a9aa306204169e6862f4416e055035d7d2cc9ab6f1921604905"
+ },
+ {
+ "name": "random-1",
+ "domain": {
+ "name": "Moo é🚀éoMo🚀 oé🚀🚀🚀MéooMéooo éo oé 🚀M🚀 🚀 o",
+ "version": "22.43.44",
+ "chainId": 1268,
+ "salt": "0x6ebb306942854acbb10134c9dee015937042c39da2ee124eb926ad77df52dbe0"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bytes11"
+ },
+ {
+ "name": "param4",
+ "type": "bytes"
+ },
+ {
+ "name": "param5",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x2364d8559a1777b684a9121d132c4b4237e2534bd5a0",
+ "param3": "0x90166c1d5cf7f1be5e4535",
+ "param4": "0x0f6c35f4b0fa348c603ee0070c8f4f971805c4d9d2ddb8acb82e806e1f4b2c1bc500e41b882213648af39dd4a29d303a31f68476cf803ef8c9024509b2f164",
+ "param5": "Moo é🚀MoM🚀éoMMooM🚀ooéM Mééo"
+ },
+ "encoded": "0xda8977a44f657114a662894ef7761924845f9e7530ec21622e1a6d5526de0d1ec611cbc6650fb22a47f359606312a4412acbc7b648fa712da2d0e65a00e44f8990166c1d5cf7f1be5e453500000000000000000000000000000000000000000082609c13a160a82264f3293420c066ad847fc2c658862f6282c13848e7c2bfa3c422f8f8d57a0d73e4448edcb393d45cd1969652b199e87011a5c54171f7a548",
+ "digest": "0xdca475186d6626bdd727f5a216758f6351c56b36ae77683f3b381c5b296d1099"
+ },
+ {
+ "name": "random-2",
+ "domain": {
+ "verifyingContract": "0xb98ccb3b2f1843cdd391295779890c162f2833ea"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "int32"
+ },
+ {
+ "name": "param3",
+ "type": "string[3]"
+ },
+ {
+ "name": "param5",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "-828619503",
+ "param3": [
+ "Moo é🚀o🚀oo🚀o ooééM M🚀éoééoMMooo🚀éoooéooMéoéMM oé🚀Mé éé",
+ "Moo é🚀o🚀M ééé🚀 o oMéoMéM o🚀oMoo🚀é🚀 é é🚀M🚀é Mooééo🚀é",
+ "Moo é🚀 🚀oooéé o🚀oéMooM🚀🚀 oo M🚀M🚀ooMoMoooé🚀M🚀 🚀M🚀🚀🚀éM"
+ ],
+ "param5": "0xd5cf50b584016c19732d845cc9c8d3a43ce41362"
+ },
+ "encoded": "0x67fb8e8c0399ea6a53c5be40a9cc57f8682c0e4887d4e92733d7e77e358fb473ffffffffffffffffffffffffffffffffffffffffffffffffffffffffce9c451142865dc16e0353e94811b8b8df478cf0a5714219aa578dd5881f162ef224cb2c000000000000000000000000d5cf50b584016c19732d845cc9c8d3a43ce41362",
+ "digest": "0x6c32dc60957ea693087837ae10ba9d9e31febf7a0c2ed00f6b57ac02f4d4b37e"
+ },
+ {
+ "name": "random-3",
+ "domain": {
+ "name": "Moo é🚀M oMoo🚀éoo🚀ooo ooéééo🚀éMoo🚀o o oo 🚀oooM ",
+ "version": "31.7.9",
+ "chainId": 793
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ },
+ {
+ "name": "param4",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x2302fce888f2dc9d6ec2b3d3fc06aa212ec06b07f4035f64fcc58f1e178bee",
+ "param3": "0xb1d7e299",
+ "param4": "Moo é🚀 ooo🚀🚀o🚀ooéé oé"
+ },
+ "encoded": "0xb294e832799f75dfe653c1529c1464de82ad988a243b4cd2dad2e8231ce02ac8f98e5673d8c98474e896eb51f7710e3096ac480f57c343aa4b6940f14ba864cfc9825dc5acadefe8114be8b3b40ff1735c38ce7a2bd1af26b8f896f448f71b2d92ca886c2f1728e95855af472331fec2b8cbcb28901e0b5e5e7c0fcdfb82df75",
+ "digest": "0x29afbb5d796c6d1b9e79071d245061a8d284ffabf3138483d13736a61780ccdd"
+ },
+ {
+ "name": "random-4",
+ "domain": {
+ "name": "Moo é🚀oo ",
+ "chainId": 1190,
+ "salt": "0x1f37012abd2887491b2dc97283565221433f671fe1e39aa52501bfb6aa8b93c3"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes10"
+ },
+ {
+ "name": "param3",
+ "type": "string[1]"
+ },
+ {
+ "name": "param5",
+ "type": "bytes27"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x9bb8048b699386b24539",
+ "param3": [
+ "Moo é🚀 éo🚀oMMéoo ooM🚀ooMo oMoéoéé oo 🚀oMMé🚀🚀ooooMéMoé 🚀oéooooéM"
+ ],
+ "param5": "0x87522812e1a8337045160896fb3e61f869b4154b737a082b3dfeb7"
+ },
+ "encoded": "0xd6c2b6107cccf91b779f9954f2110d1b60cbc77e11fba6eaea01e944fd9cf1779bb8048b699386b2453900000000000000000000000000000000000000000000efd410fd47fe79acfda00711d702442f7cf6312190754acb4613b1c2aca0dec187522812e1a8337045160896fb3e61f869b4154b737a082b3dfeb70000000000",
+ "digest": "0xf4f1328085f730d46a20fa49f6e7ac254f35447282c91a7530242a3a14474116"
+ },
+ {
+ "name": "random-5",
+ "domain": {
+ "version": "7.9.9"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "int224"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x2f89d3d2d83f46d0147efc081e3a3f1012406c69",
+ "param3": "-1117663001459922125771233981131891587208615016687544676675378200714"
+ },
+ "encoded": "0xded571df13886530cfad8a76abc529603094afe8d4763a3c714a8a86241c16b10000000000000000000000002f89d3d2d83f46d0147efc081e3a3f1012406c69fffffffff5631c9b4cdb160013e3cedb0d8e15ad26177e422ad39cfdf0483f76",
+ "digest": "0x1f4896667fd2210e54760bd5f00b964447be3c0a20d9d64f8324821a44dbe9a8"
+ },
+ {
+ "name": "random-6",
+ "domain": {
+ "name": "Moo é🚀",
+ "verifyingContract": "0x501809f11ffb4ec90411dca095641b87f3229df9",
+ "salt": "0x613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a89179ef2774f76e"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ },
+ {
+ "name": "param4",
+ "type": "bool"
+ },
+ {
+ "name": "param5",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x85a6f822054409e83460b9da070ce6c48843e4793c5720ad69102099b4a52978a90e32242a8b7df6fc70ddc8f6056c1df4585c727e4dac",
+ "param3": "0xac0ca9396225af9df605b4d3a3273d0c075c5dc2254b1d69fabcffb9cb191cb7253e55c547f8627a79",
+ "param4": false,
+ "param5": "0x083e80e0d94dbb979ce2c44a2c746ecfa1fca9f1"
+ },
+ "encoded": "0xe5b40a524086d02c883ca8067a58dc9b784c44542de0bc37d5769a0dbeca31dfdcd5d1450de8a86034460ed9842ded280ce4faa8919759337539cca0876a7da6c95d6f26124f374b1007778a627aabfe799b09620b14cd82e0ce2dc27b5b4aba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083e80e0d94dbb979ce2c44a2c746ecfa1fca9f1",
+ "digest": "0x77f779953f0ad6e059d13f714999b8f2e0916f3c4263db272606efa34c18c4eb"
+ },
+ {
+ "name": "random-7",
+ "domain": {
+ "version": "29.42.9",
+ "verifyingContract": "0xa2f34b603e4ee3de26502a40c8dc33886c1bb7e0"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bytes[2]"
+ },
+ {
+ "name": "param5",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xb7788f98b3107c588bee30ccc844e129a7772df540c3193239df",
+ "param3": [
+ "0xe85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11",
+ "0x10ec7831da9a49dbf10818"
+ ],
+ "param5": "Moo é🚀ooooM🚀 oMééM éé🚀🚀oMé 🚀 é éé"
+ },
+ "encoded": "0xcf3bbe1dcf56fb9655824a3f90f1953ea791787867fb34004275382e4f47a2bb1c88290b2a99cb28a10db644f89833ecc797c9d2d9c142a5b633939e1c8819bc58bf6d520785f87bcfe82d2eab0d7ba35d93478d835dd7de28c44e0dccc8619c45dd7a5ec721fb2064788313d7807140e33459ce08dbf30bceb4d093096db6f3",
+ "digest": "0x446d1bab14cbf7b0bc6dad1cf30aeb89585df7150e0a19d809ea23c7bc4d0908"
+ },
+ {
+ "name": "random-8",
+ "domain": {
+ "name": "Moo é🚀oo Moé🚀oMM🚀🚀o oéoéooé é"
+ },
+ "primaryType": "Struct12",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param4",
+ "type": "int40[3]"
+ },
+ {
+ "name": "param6",
+ "type": "string"
+ },
+ {
+ "name": "param7",
+ "type": "int152[1]"
+ },
+ {
+ "name": "param9",
+ "type": "bytes10"
+ }
+ ],
+ "Struct12": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "Struct10"
+ },
+ {
+ "name": "param11",
+ "type": "bytes7"
+ }
+ ]
+ },
+ "data": {
+ "param11": "0x35c68a72cc994a",
+ "param2": "Moo é🚀ooM🚀 MooMoo oM🚀M🚀🚀oMoo🚀éoéMoooM ",
+ "param3": {
+ "param4": [
+ "-502183273437",
+ "-181945777056",
+ "-454055253301"
+ ],
+ "param6": "Moo é🚀 🚀ooMo🚀Mo Mé MééM🚀éo🚀é 🚀é éé oééé🚀🚀ooéM🚀🚀o",
+ "param7": [
+ "2830948558399330007235690811772897616211515216"
+ ],
+ "param9": "0x31ee08b2239ded1369a2"
+ }
+ },
+ "encoded": "0xb791414599e8b56f4b0391cb8b4d422bcf755603c5ddd6e103893a71ceba46241f5744b35eb3f3ef0a6e8cab59bf3b8b6a6691dd30ebf8939d36dd52b98acaea10c8cdc69e509a68998f2d5e30e095c9849a68b644b21c3dfcfd30ffc502114735c68a72cc994a00000000000000000000000000000000000000000000000000",
+ "digest": "0x8694ca7a01c36837d2449232907509801ed64e23dc023fcf736315f5eec1053c"
+ },
+ {
+ "name": "random-9",
+ "domain": {
+ "chainId": 437
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "bytes8"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀🚀M🚀🚀oé Mo ééMo",
+ "param3": "0xc4737eceba804e84"
+ },
+ "encoded": "0x979ff42839e8663fdf777083b1648c659b691503a28c6a2910d1d7cd162a3aa17bcd164aa59dabcd7c3be7e32492e7fe4a48e70aee5b964137249e361ebc9a41c4737eceba804e84000000000000000000000000000000000000000000000000",
+ "digest": "0x32e8f650680b00d4b5515e9de9684995c3245b4761046780b33ef9f6ee05362c"
+ },
+ {
+ "name": "random-10",
+ "domain": {
+ "name": "Moo é🚀 o éé Mé🚀éoo 🚀oéM MM🚀é 🚀éMM🚀éMo M oé🚀MMoo é o é 🚀o🚀ooo",
+ "version": "45.0.46"
+ },
+ "primaryType": "Struct8",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param2",
+ "type": "bytes2"
+ },
+ {
+ "name": "param3",
+ "type": "address[3]"
+ },
+ {
+ "name": "param5",
+ "type": "int8[3][1]"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xdc77",
+ "param3": [
+ "0x6fe07a398b47ee3d064460f74fb00b8454577d8f",
+ "0x4489956d5c84285dd2337de059733fd7caff5e3b",
+ "0xc562d2e19f4c8416f7adcdecacb47c7f3b429a18"
+ ],
+ "param5": [
+ [
+ "-10",
+ "-97",
+ "-22"
+ ]
+ ]
+ },
+ "encoded": "0x9ca5f56281a4926287c930891cd4218d7e9d7e5bd6f8f35ca52190b2a54c5989dc7700000000000000000000000000000000000000000000000000000000000050b4d189d5c6d2e1fe9f152de6692da9fc34d41324dab5ced8a52397fa5ebfff5bb6e21b54c9b4e7f21b6cfe5999121f5dec6f1101cd5e0fb73a634001e5f2ea",
+ "digest": "0x59c2336278c748fca8889f8b98d6c386f1badb72f28668a5c760c3aff20a922a"
+ },
+ {
+ "name": "random-11",
+ "domain": {
+ "salt": "0x60a7ef7f891f64c8c659e7b3f448e0e82939483d467088aae991d873c2371932"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "int88"
+ }
+ ]
+ },
+ "data": {
+ "param2": "-109147385638873134356016336"
+ },
+ "encoded": "0x22f16ecbd883f7cd7823cc5ec368999cf3bf08546bbd7c708ca231a54353cb86ffffffffffffffffffffffffffffffffffffffffffa5b7245e537649c9e75330",
+ "digest": "0x1c1c3e593358ec697d2f26c497abc72af68d617441a9825b6cb7c79e92bb2a01"
+ },
+ {
+ "name": "random-12",
+ "domain": {
+ "name": "Moo é🚀oéé🚀🚀🚀o🚀é MoéoMooooo🚀 MMo Moo 🚀 ééo",
+ "version": "13.24.35",
+ "salt": "0x9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d275677ef"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xff4d2657142a58d3cc787e089ca7f20a6b66776e"
+ },
+ "encoded": "0x98edda54668461e736d24a4033f2d11540bceac48ea14c7da0fea73b8b9a55db000000000000000000000000ff4d2657142a58d3cc787e089ca7f20a6b66776e",
+ "digest": "0xf73e0203cb874ce615b0ceb1c8c8358eb44719bbab11ebe963e00a914434ce62"
+ },
+ {
+ "name": "random-13",
+ "domain": {
+ "name": "Moo é🚀",
+ "chainId": 348,
+ "salt": "0xc70f3b18e636eee4a800a307d1b38bf2cf6fbb923a5c3ae3b14becbfc2ce1f9b"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀🚀oé MoMMéo",
+ "param3": "0xc3e57dbac4c0a82334953baa752df10cffd5a75a2edcbe00c7f2"
+ },
+ "encoded": "0x4d0024736263d208aca6e84c7bb7336060a12a4693f70ea14290ed4308d052e5eb273f8d13bbd23d14b25bd00e006757fa7de6d637f4c49e5fdcf4a07f024aea1f53f499e56140df7f6326e0c99cd10d9a7ceac70c4f9343111769b6ac62e1ed",
+ "digest": "0x407d6005ebd258cd798e326e17786b0b61a927309b8584db513bdb62f4f5ee3f"
+ },
+ {
+ "name": "random-14",
+ "domain": {
+ "version": "25.49.7",
+ "verifyingContract": "0xb0e0d9999c8c74a0d4ed79414a9f8bf363e9caaa"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "bytes[]"
+ }
+ ]
+ },
+ "data": {
+ "param2": true,
+ "param3": [
+ "0x96ae69774e732b9214a3ebb03c0fd01602bc7a5fcd21",
+ "0x60a6103ace6cc41a8df5b6518b24e6ecd490c13acfc67765f3540a4a7aa93d074a77313622786513f0199d0dad5e012c"
+ ]
+ },
+ "encoded": "0x8a9a6129ffa166123d1ac6c76c2bfc752f7cf2e64b76b36df081cfc7c032a75b0000000000000000000000000000000000000000000000000000000000000001e8da1f36005f78d7a373d2f0da3b4215c9b2ab40e5a8d62e8ab338374600329f",
+ "digest": "0x0b1d8e9823e30d163cbd911aea02c15a62bd0bbc0168183ccd2965a8b601a40b"
+ },
+ {
+ "name": "random-15",
+ "domain": {
+ "verifyingContract": "0x6f5c960aebe912340a5a72935aa334afa8fbfe58"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bytes31"
+ },
+ {
+ "name": "param4",
+ "type": "bytes31"
+ },
+ {
+ "name": "param5",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x4a18799bc6b7f0fab7d57bc456346bca7261a53cb04fb48d82dba056",
+ "param3": "0x8d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a846421180",
+ "param4": "0xb165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0",
+ "param5": "Moo é🚀M🚀éééé oooMé🚀ooM🚀 o🚀oMMooMé🚀é 🚀oMoé🚀"
+ },
+ "encoded": "0x195b09fb47455d098743f9c930f4078d642ea0a6f994b66198c7213629164dc250d60588d6db4ae7e3b0d4d8f93aed4781b86403d576fb4e374af761f1238cc38d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a84642118000b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e000a315cbc15f8ad1d34c761a0523412f8bd958f3b121ab055ad39eed2d1c894c3c",
+ "digest": "0x859f85bc1d34695b4db0f3650dc448e4f26e1310bbf4386a47154dd0ff2f7134"
+ },
+ {
+ "name": "random-16",
+ "domain": {
+ "version": "46.37.5",
+ "chainId": 398,
+ "verifyingContract": "0x7d5c6babf358d15f834e4e66fb38f47029692f45",
+ "salt": "0xf631d7b0a81f0bb5d43c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "uint200"
+ },
+ {
+ "name": "param3",
+ "type": "uint192"
+ }
+ ]
+ },
+ "data": {
+ "param2": "902991113240896234120897942256968907309321984644966427837857",
+ "param3": "1793643122398654278545911502385423630752811461294794060392"
+ },
+ "encoded": "0xc905891cccd69edb3dcead4f2229a9b1c0f7ad0264bd9e32ca83cf8d4835ca94000000000000008fdad31cff441c443d69458e4033c11eeb0b4928ce9452c5a100000000000000004926820a408021ed575bd94e89af5672c9c4faaa93adb268",
+ "digest": "0xa8ca54bd8b0380e9680fee86021be77dd65fe79954ca8aace6708fda1e62d959"
+ },
+ {
+ "name": "random-17",
+ "domain": {
+ "version": "13.22.4",
+ "salt": "0x9a939ab1fd21216c5fcfed335f5d6ad5e83f7815e6bf7d521dd0341e9445415a"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xde2c0dae771d5cb66092b8905ba5691226740d7398459c60712a5793f0c9434c",
+ "param3": "Moo é🚀 oooéMo é🚀o🚀MM 🚀o MMMoMoooooooo o🚀éoM"
+ },
+ "encoded": "0x686167f4c27dbc607c8b7b3febaeb35fa7dbcccbfac18ae20803b8e2bfc040fb053664f618ae8de97996df7189f0b8b97619489a71e0b0e370e6ef9b581df98208744de9ee650d2089505fa1d121e39ff8bd12472e14e192ad7a450cce4feb3b",
+ "digest": "0x0b5413c0bce8ba1599a5415a0a8729659df2c4dbfc6f71655c228101a523126b"
+ },
+ {
+ "name": "random-18",
+ "domain": {
+ "chainId": 1154
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes12"
+ },
+ {
+ "name": "param3",
+ "type": "bytes22"
+ },
+ {
+ "name": "param4",
+ "type": "string"
+ },
+ {
+ "name": "param5",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x5f7bd6650aedd689f688617f",
+ "param3": "0x9d8ca86236fa8ca5e654b767c43bc31e4e2be542b128",
+ "param4": "Moo é🚀MoMoo🚀 🚀MoooM ooMM oMoo🚀 é oooM🚀Mo é 🚀 éo",
+ "param5": "0xae09d2fea99189d5171ddcd7c90e4ba4902e9df3"
+ },
+ "encoded": "0x7a78c404a07e9f6956aaff71efb4b16130954663e72d5ee2de28e982b75d86675f7bd6650aedd689f688617f00000000000000000000000000000000000000009d8ca86236fa8ca5e654b767c43bc31e4e2be542b128000000000000000000000fb03f67aff6a2b40a0dbb1b99236c9ca92063bb9c1a604b32893a7f03e9364f000000000000000000000000ae09d2fea99189d5171ddcd7c90e4ba4902e9df3",
+ "digest": "0x680060a5f5fc62a31a89bfa6ee31116827439b3a46de888d9d43b1251fb8a3f2"
+ },
+ {
+ "name": "random-19",
+ "domain": {
+ "chainId": 1013,
+ "verifyingContract": "0x9b76aa9473e60427cbc99f4161665fc37a013015",
+ "salt": "0xb99a959f6fcb296e9be34584a14761c7b4ce82e99d4394a5f109ed1c55cde477"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x010d8955e5cecc6705b73064baa37a703d65cb97"
+ },
+ "encoded": "0x98edda54668461e736d24a4033f2d11540bceac48ea14c7da0fea73b8b9a55db000000000000000000000000010d8955e5cecc6705b73064baa37a703d65cb97",
+ "digest": "0x8ca2e0e8b9d5ce1c66d5ea245d6a9c653e10adc303e7440d4298c331b011c503"
+ },
+ {
+ "name": "random-20",
+ "domain": {
+ "chainId": 888
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x981ad5555974b8b6b4f767d774c32f9e09e0009d5d914e29614ec739e70c36aaaa454aab9a9409b890c32e9304c42ec8b05a7f7ac0f60be35f1e",
+ "param3": true
+ },
+ "encoded": "0x889d1fd6a543c2550a4d6fbf451f7004ee9509e508b7627d82b578e77ed3541a1d8c4d6a1c1c4c8ed69df55267e53b5289aca47b178f775978694815b4f990640000000000000000000000000000000000000000000000000000000000000001",
+ "digest": "0xc1319be39e82c2e51795b588e89ae2ffa116d8e6e5e0aaff6c9a42379e18e35d"
+ },
+ {
+ "name": "random-21",
+ "domain": {
+ "name": "Moo é🚀éM",
+ "chainId": 1189,
+ "verifyingContract": "0x20595d9bc36f43302fc02a5b8b1afcd8751ec829",
+ "salt": "0x616e7f89169e2cc84d244f9e3fe0e03661dfd04909f43f379752069848cccf7e"
+ },
+ "primaryType": "Struct8",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param5",
+ "type": "bytes"
+ },
+ {
+ "name": "param6",
+ "type": "bool"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param2",
+ "type": "bytes[2]"
+ },
+ {
+ "name": "param4",
+ "type": "Struct7"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ "0xb7bdd490b49bd7ab",
+ "0x864b5bb60e5d3fe67c853222aa05ff96aa441cf26a394fc4"
+ ],
+ "param4": {
+ "param5": "0x109f4bc90e17530b89b8fbbd2c39477a4a8bf23a1109d71902516214aa",
+ "param6": false
+ }
+ },
+ "encoded": "0xc870a8ea20ea5a0e48665e1cceac4d0911ebdd5211d9bbe9ea6b02742610630c2274465ff0a09b20e8e027da59fb88f7c11871f7ecd6354e3ed5099296cfd04be1885a775bd5e9fe96ba4a0d693d8c0ff869e2956d2445c820173815e807f2e9",
+ "digest": "0xfe17ec225aeca7f68177514dcf12e22fb0b39840aa6a6c22c26f59dd033ec5c7"
+ },
+ {
+ "name": "random-22",
+ "domain": {
+ "name": "Moo é🚀M M🚀ééoMoMo o é oMéé🚀",
+ "chainId": 941,
+ "salt": "0x504bcce324addceda39d36f209fbfcb3b14f834e21f104979f550ea5c6f9917b"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x7d44e5363b38914b63ccfe012685ce3d2e65121a",
+ "param3": "0x0e"
+ },
+ "encoded": "0x424c0018d1cc135145554306c5c9e3e9e8a4cca8848cfa101804ff94674c8d6c0000000000000000000000007d44e5363b38914b63ccfe012685ce3d2e65121a7d74985e988688526ac76b8ff8f86df2934c34abd4c430c49bf3b8a821b4e87e",
+ "digest": "0xb701808badfe14419c62c8108a8123a1531555b8d6c40bd0aea773e4cc7faff5"
+ },
+ {
+ "name": "random-23",
+ "domain": {
+ "name": "Moo é🚀éé oé🚀🚀éoo 🚀o🚀🚀 M🚀éo🚀é🚀 o",
+ "verifyingContract": "0x4b290dacba7bd6da6bb491d627c27c59abcd55c8"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "bytes27"
+ },
+ {
+ "name": "param4",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀 éo ooo🚀🚀oMéooo🚀ooo🚀ooo🚀 M🚀 ooMoéooo Méé🚀oéoo",
+ "param3": "0xb72fa668214dee979e4ab0b212697763c7a644140a47417af60c4b",
+ "param4": "0x0526eab9"
+ },
+ "encoded": "0x381b9d935686d6436962f0aa124ec705db0c223f0aa58c87e2e87a502e83b175cdd03bb0b8d5f0ab36918e793771d1a727264b826e6d52705aa7d8ac060af095b72fa668214dee979e4ab0b212697763c7a644140a47417af60c4b00000000005315d4abcf9b7169289f8f9fb986abe1e1648425138878b59807cf047bdcf743",
+ "digest": "0x9d78aed8da7518e44916c6da939b27f32296254456d1d12317f9d8d49414f704"
+ },
+ {
+ "name": "random-24",
+ "domain": {
+ "version": "33.33.10",
+ "salt": "0xa465767278b9436adbcda02c178d53ced5ad9a5063042056fafac91f3eb256aa"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "bytes29"
+ },
+ {
+ "name": "param4",
+ "type": "address"
+ },
+ {
+ "name": "param5",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xa41a2812f302436d74f6322e3d24f7d0894d445b",
+ "param3": "0xfbd8fa19905015b516f07997d9ee9ef2a3e70acb6a5cef4d58d25ae9a6",
+ "param4": "0xf8f1b9b200727a131c0868f5b0d5224e91acdd49",
+ "param5": "Moo é🚀"
+ },
+ "encoded": "0x3406cf367962412603498937e52eb1fae44b403ffce6931f487e0191dc1da76e000000000000000000000000a41a2812f302436d74f6322e3d24f7d0894d445bfbd8fa19905015b516f07997d9ee9ef2a3e70acb6a5cef4d58d25ae9a6000000000000000000000000000000f8f1b9b200727a131c0868f5b0d5224e91acdd4973afb58374689378893745fc96a2fc65d1568ee4015275cae05c7ad1ba4ee814",
+ "digest": "0x776fdda1fd58d3c90228f4bfe52e9243a6a0c1b8804f91ecf7570b51038090f4"
+ },
+ {
+ "name": "random-25",
+ "domain": {
+ "chainId": 725,
+ "salt": "0xc2de9b40a3c72c4b8080784d0abe7e2a81ee8c6d00ade54cbfa186d05b80a30f"
+ },
+ "primaryType": "Struct10",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "address"
+ },
+ {
+ "name": "param4",
+ "type": "bytes"
+ },
+ {
+ "name": "param5",
+ "type": "Struct9"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param6",
+ "type": "uint80"
+ },
+ {
+ "name": "param7",
+ "type": "bool"
+ },
+ {
+ "name": "param8",
+ "type": "bytes17"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x0e1c5e8d98e793c508605de14b557517086a154a",
+ "param3": "0x4643f9f0fff83c5992655ea60b4ee4d87962402c",
+ "param4": "0xe24ad838b2dff3ce1ceb5cf89d5382a3b7ae58e3b83ed04b361dd24e858604e086cf3aae72e10af9157ca91a07aacb76ff5f4e714bf0af4e2767a5c1b7",
+ "param5": {
+ "param6": "1037360565969580415751062",
+ "param7": true,
+ "param8": "0xb400c0f629151c1c2efc8678b90a90db50"
+ }
+ },
+ "encoded": "0xda5e84ad82b98296cf11f22beffa9ac554199abd2907793cf612a0cde3a3a6e00000000000000000000000000e1c5e8d98e793c508605de14b557517086a154a0000000000000000000000004643f9f0fff83c5992655ea60b4ee4d87962402cb5c868e1fa67a6af58ad2de258728150a4257a8fc3a0e8b1cd0c693a9154e78a19b8a5510cc83eb41b72cdb218809b5fb097d4f56a210465d7e4434ae4f93ae2",
+ "digest": "0x20c6d3b7d3a08127d2675417f10192a19404eb7f2b4a7cc826291c200d059c51"
+ },
+ {
+ "name": "random-26",
+ "domain": {
+ "salt": "0x84ecb12e99120d7e16d5ea8b41f3a1712b04779027244978e3c14e6b779bff43"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bytes15"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xd9d920215e9cef3f5d2c992b29d02c"
+ },
+ "encoded": "0x3124ca50b2729655ab7183f9cdc9ce21f39c5f9af1539ebbebddafd8d5124eebd9d920215e9cef3f5d2c992b29d02c0000000000000000000000000000000000",
+ "digest": "0x98647f029b556997bd7cf686927a1075276cdeb949c7324cb258265daa43e9d0"
+ },
+ {
+ "name": "random-27",
+ "domain": {
+ "name": "Moo é🚀Mo🚀o M ééoééoMéMoMooooéoéoo o🚀oM🚀 oMo o🚀 Mo oé",
+ "verifyingContract": "0xa25337ce36273880f4e9e61f7d6e42cdf375343e"
+ },
+ "primaryType": "Struct9",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param3",
+ "type": "int88"
+ },
+ {
+ "name": "param4",
+ "type": "address"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param2",
+ "type": "Struct5"
+ },
+ {
+ "name": "param6",
+ "type": "string"
+ },
+ {
+ "name": "param7",
+ "type": "uint144"
+ },
+ {
+ "name": "param8",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": {
+ "param3": "-127309812032058079971015355",
+ "param4": "0xfea50d6aa0beb7541421a003b305176bfafd3bf7"
+ },
+ "param6": "Moo é🚀 🚀🚀M🚀Mo",
+ "param7": "21679346468763708829870107432985082613037936",
+ "param8": "Moo é🚀🚀M é🚀🚀oMo oo🚀éoooéMo"
+ },
+ "encoded": "0x5ed3e5cf198704fbd48783461bff2bf9894ce18fa02dfd09804f85f9897fe3b6457fa76bc117d82ca5c78822611af029603b99095c728469d2b6e0db0d38430dab622c3246af0064a7ca87eee9696c6f580b5b628a1c3ccc7ca8ccb5d099b5b30000000000000000000000000000f8dddf8de4ce294ba243327c1bb5c1bd7b7017c8ef26c2ec6558fcdaa26969c050886d3cd13aa63fd7c1b4c951a029775a19",
+ "digest": "0xc01ab63f5b6821f38672244e3f54b38b1f997cfa987996d97c2d0b45e4378116"
+ },
+ {
+ "name": "random-28",
+ "domain": {
+ "name": "Moo é🚀Moéo oéMMéMé o ooo 🚀o o éMo🚀M 🚀oo🚀🚀oM🚀éM🚀🚀ooM ooooé",
+ "version": "6.36.29",
+ "verifyingContract": "0xbda80f1b5ee3f31847bfab9e1f2d577a736ae9ae"
+ },
+ "primaryType": "Struct16",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct15": [
+ {
+ "name": "param11",
+ "type": "bytes26"
+ },
+ {
+ "name": "param12",
+ "type": "address"
+ },
+ {
+ "name": "param13",
+ "type": "uint240"
+ },
+ {
+ "name": "param14",
+ "type": "string"
+ }
+ ],
+ "Struct16": [
+ {
+ "name": "param2",
+ "type": "Struct7"
+ },
+ {
+ "name": "param8",
+ "type": "string"
+ },
+ {
+ "name": "param9",
+ "type": "int240"
+ },
+ {
+ "name": "param10",
+ "type": "Struct15"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param3",
+ "type": "bytes[1]"
+ },
+ {
+ "name": "param5",
+ "type": "bool"
+ },
+ {
+ "name": "param6",
+ "type": "bytes21"
+ }
+ ]
+ },
+ "data": {
+ "param10": {
+ "param11": "0x3c8aa45d6e60df8fa4b94a9f1a9873982cf117b7870019a77257",
+ "param12": "0x18dbfcc4b58ac047af1fa1ea5014e9a3c122d695",
+ "param13": "1403160610370024385322518859671151374504293477415157376516004093379141099",
+ "param14": "Moo é🚀MéM 🚀éoéé🚀 M 🚀🚀 🚀éooMéoMoM é"
+ },
+ "param2": {
+ "param3": [
+ "0xdd89a7e45431dc5bcf2575124ce071addb7e049856e3ec3a698aa73965f2cdebe3d8c1561c943beb06906bc333a5"
+ ],
+ "param5": false,
+ "param6": "0x40cdeaa8cfa786861d28835935341469073906c16c"
+ },
+ "param8": "Moo é🚀o🚀o🚀 oé🚀oMoéo🚀 o",
+ "param9": "-728201913157045709305151288883895292116444273394221376510603682943551543"
+ },
+ "encoded": "0xdb90bb6421637471a75a3d7bc8dc38f85ab6d86fe66817a5c5e52e1582dc9d8d05eae0968871a1fb36bb967307259c285125d151dee777d1b9bba85ec0c5924ab953967c8b9dd2e0f5cd1fe230ad4ddf4fa6f38f5286db1d29957c90a18c2d8bffff967d7d66a999668fc7fbff14f873fe30522876aee45bc8ad4fbc9c24b7c936513d68064480110d163aeea34e925427d939bc37d8892caa329a9d3558c51e",
+ "digest": "0x4f9a08cb3212e843a37e628e8a3899c9632ba8fe184f4955aabfd568690c8cbc"
+ },
+ {
+ "name": "random-29",
+ "domain": {
+ "chainId": 356,
+ "verifyingContract": "0xa2cb255c54cb952b1d29aa906d0db8a0369b07ac",
+ "salt": "0xa747cdaee63c094c448b58b76e9b7555459bf28fe41e33d8e485334b3955dee3"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀ééé🚀o M🚀🚀 🚀🚀🚀oM🚀oé🚀🚀oéoM éM🚀éMé o🚀 "
+ },
+ "encoded": "0x5927d86a0ef9a01a131f7a41d2a9c89a8c82e0f454d6b4502f955f90f152eb512a656f0bd407a79f684b714713b1e71478383b1f47d7c72f652658ece534dd0b",
+ "digest": "0x8f21c436df4d7b8ea1470f3f4cac3d756774982b25a60bd7e76587c6b519df6a"
+ },
+ {
+ "name": "random-30",
+ "domain": {
+ "version": "1.46.13",
+ "salt": "0x13ae4c3150715b5ad9a1e19f9e5d7acb57041c056751bf3517085406225bc939"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "int136[1]"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ "8166199623935941567874687986584718264154"
+ ]
+ },
+ "encoded": "0x4d74029cfac37baeca9753d910ae221b711f6f012a1bea4dab197ee55395b8c7639803471fd3db6691ea1e09d239e931d1e355db6dd3a8e271e91cd893cfb588",
+ "digest": "0xb6546c223ab20fefa301d938ffbc21f17128f0620fd926a149725887b3cccf4a"
+ },
+ {
+ "name": "random-31",
+ "domain": {
+ "name": "Moo é🚀 o 🚀 🚀M M oooMM ",
+ "chainId": 908
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ },
+ {
+ "name": "param4",
+ "type": "string"
+ },
+ {
+ "name": "param5",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x4ede0deacb3773e5137435f4d889ed859498566a",
+ "param3": "0x62dd238d0e2d216ab536acf19569d82284ec73724af965e1e635a5e02de69f89315c86d4b43dd3fea6b5",
+ "param4": "Moo é🚀éoo🚀MooM🚀Moo oéM🚀🚀ooé🚀 oé oéoM🚀MéoMé🚀Mo🚀oooo🚀🚀ooo🚀 ",
+ "param5": "0x4e35a3945fb38294c8acf415464978b576dddadd"
+ },
+ "encoded": "0x7f6d973155b0bcc8d11dd8547d4396f95e47a6b1663de76876af0dd85aa48b3f0000000000000000000000004ede0deacb3773e5137435f4d889ed859498566a84c9e1c43faf98cea6c5fcbc1fd1dd44de98d2a6fd8094cd3379479cf19d02d3f60e96d7ac3d6507f6e8030df384f326924853ce6a85f91dfae3efb3d566f6170000000000000000000000004e35a3945fb38294c8acf415464978b576dddadd",
+ "digest": "0xb6efd1b092fc83b8ad6f1562b7b87e3d06f28ff1ad2287008b557a4b325e4c94"
+ },
+ {
+ "name": "random-32",
+ "domain": {
+ "version": "28.18.35",
+ "verifyingContract": "0x860a0e50434a1e67fea76e2ecaadd0f7a34606a5",
+ "salt": "0xa79039bbd2738722f49a7a10b34a89be4701d18545207a60ed7b1a0d647d3ede"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "address"
+ },
+ {
+ "name": "param4",
+ "type": "address"
+ },
+ {
+ "name": "param5",
+ "type": "bytes19"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀M oo 🚀Mé 🚀🚀 ooo🚀oMéoéo 🚀🚀oooo 🚀ooé🚀ooo",
+ "param3": "0x47fe050a8243b24324599b07443a44409ae0ae5f",
+ "param4": "0x4e9cfb53ea5657c6f71a9f6d180ef603b1491593",
+ "param5": "0x9bb5cc4641fd491758c28f1334074c4fd8c30d"
+ },
+ "encoded": "0x1cf4f0e08a7941dbcc88554ec00340e272c27c135e2814a9aa84b7a0cb59090ac3fc89c9396771c6833539097c737e43749df63d9374e94038e87806138dbf3e00000000000000000000000047fe050a8243b24324599b07443a44409ae0ae5f0000000000000000000000004e9cfb53ea5657c6f71a9f6d180ef603b14915939bb5cc4641fd491758c28f1334074c4fd8c30d00000000000000000000000000",
+ "digest": "0x44170d64ef7cf254e72fa3a1fce021939881e52ddc6b53804b7ed17c3cc2cf4b"
+ },
+ {
+ "name": "random-34",
+ "domain": {
+ "name": "Moo é🚀 é 🚀oé🚀o🚀é éoMMo🚀oooéo é MMoo 🚀 é 🚀MM🚀o🚀oo Moo",
+ "version": "13.20.41",
+ "chainId": 168,
+ "verifyingContract": "0x4cb0f9a774003fde250f9498bf59af14a58a4ba6",
+ "salt": "0xd10a489e053686f001e06c5f95be04abf66384251beee98aac3352a576309497"
+ },
+ "primaryType": "Struct11",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct11": [
+ {
+ "name": "param2",
+ "type": "Struct7"
+ },
+ {
+ "name": "param8",
+ "type": "string"
+ },
+ {
+ "name": "param9",
+ "type": "address"
+ },
+ {
+ "name": "param10",
+ "type": "bytes"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param3",
+ "type": "bool"
+ },
+ {
+ "name": "param4",
+ "type": "bytes30"
+ },
+ {
+ "name": "param5",
+ "type": "address"
+ },
+ {
+ "name": "param6",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param10": "0x172fb5da45fc748aab90701f16e488faf3aeb7e2631bdb4e89178e291c54276fc0a09fde49c1d8d83ae459b0de8af4a32e752f7cde484933c819bb984fdd",
+ "param2": {
+ "param3": false,
+ "param4": "0x5f13d3b44f1f7b3e9509e0e6a6e86a82bad560c0463ff6f4107ed0f91ce9",
+ "param5": "0x854a1ce60d811708da436e758e7bb7cb3c4d3645",
+ "param6": "0x631b36ea5aac0b4b7a59d000cde1336adc46b54c9e2c27211a"
+ },
+ "param8": "Moo é🚀éoéMo oéo🚀",
+ "param9": "0xd4116d1167d22db322c0f7ea24958097646ee98c"
+ },
+ "encoded": "0x8d56be8d93acc8d9b7c480a48b942024d438e759597af81d8ce0c269bbfd7ba148f76de9e7e52c7befac76d291947c16f2d706470cb5a7fa41f654e7a6515feab9ae4544a83872d12bd236f00a1e723895219ed2e761b1451b728f7da4c07fea000000000000000000000000d4116d1167d22db322c0f7ea24958097646ee98c57aea085c98b9350d480022e6d063faa8011110987c0cd42488d34ffaad7596f",
+ "digest": "0xd916f454522d064210bb959fdb97edfc71ed9d6493f69ef3aa59ac602a4cb557"
+ },
+ {
+ "name": "random-35",
+ "domain": {
+ "version": "18.1.21",
+ "salt": "0xa30efc1f7cb3062cc649929f0661f023168871c712710e3e2bcfb86cea245bfa"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ },
+ {
+ "name": "param4",
+ "type": "address[]"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x6d5b8e2c382bcf3f732b63a56fd3a40216ce312c135083ffd5e345323397d458a568e0b5677f5b037db50782",
+ "param3": false,
+ "param4": []
+ },
+ "encoded": "0x3196893d5e65faa04abf32b95ea06dd0d6c08930740797c9505a8db7c0dd8d783c9347e5b56b01554824ad8ab3894c26f214fefd98de34e7c5ca8fe394ab16040000000000000000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
+ "digest": "0x55d568f5b6d8fcb20a1daf9434f22bef6f84008a548c2011c428c3fefa5f5ecf"
+ },
+ {
+ "name": "random-36",
+ "domain": {
+ "name": "Moo é🚀o🚀MMoM ooé🚀MMM 🚀éooo🚀o🚀oo🚀 oM ",
+ "chainId": 640,
+ "verifyingContract": "0xd83848a872fece3b3d46e7db4c2b77d3f860e293"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param3",
+ "type": "uint208"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "Struct4"
+ },
+ {
+ "name": "param5",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": {
+ "param3": "328075064361718410561598645543330760805893258006339352712528380"
+ },
+ "param5": false
+ },
+ "encoded": "0xd9c78b76c5945cdad51cc594f4f98013082d5b29c5acd60ecaae6e197d0282175d5d216ebd03b033f8465a6ad96f1018494e4217e6f613aafe8b727c911047170000000000000000000000000000000000000000000000000000000000000000",
+ "digest": "0x199e8bfe6ee9ef6a4a030554635b74168da0c20cf8c5a19ec689aa5df1161795"
+ },
+ {
+ "name": "random-37",
+ "domain": {
+ "name": "Moo é🚀🚀 o🚀oéooMMo éMM é",
+ "version": "28.27.34",
+ "verifyingContract": "0x7eabc8de425d63e9221ab1d30fa6dd0cefc081a3",
+ "salt": "0xe0523cb396cb9dc27ff363d713948ac735f273623989b6af7612f2fcd2ff6d2b"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "int200"
+ },
+ {
+ "name": "param3",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "-444299975383749025331326339923423112873391432830281341721190",
+ "param3": "0xed41029f84e192af5415531ee38e17f30d120a88"
+ },
+ "encoded": "0xfa093f4ea3bf0aa4213f3f060eac93ca7ab21ae17ace77be8dc0692eb11b3bf8ffffffffffffffb9380bd11977ced6065cd29a646828eb18b6e6f2b19f3c259a000000000000000000000000ed41029f84e192af5415531ee38e17f30d120a88",
+ "digest": "0x863b7af213ea9f4d6e5bddd79a651e5868a89780ea3fe954aa60bc4265ed20d7"
+ },
+ {
+ "name": "random-38",
+ "domain": {
+ "name": "Moo é🚀o🚀é🚀 oo Mé o",
+ "chainId": 1268,
+ "verifyingContract": "0x929fa2120c0710256df5b8617b56ab4e970ecb45"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ },
+ {
+ "name": "param4",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x6271d301aedc2d2eace8d5c39530cb69fa33c087",
+ "param3": "0xee756a5c2cd1aa40fb2b0ae05eea3e40b7436592",
+ "param4": "0x7909af95849ea0e6482d4979aa97b6de40184c5a"
+ },
+ "encoded": "0xd76e74eec5c6ba52563c5d6c259dd7ab7b3c1c568662d8e52ee9e9eb1fb3b08f0000000000000000000000006271d301aedc2d2eace8d5c39530cb69fa33c087d37b7d384539b90a02ac9a5fcdffb5ea5e19dcd612cac7a8d08e701244f586f10000000000000000000000007909af95849ea0e6482d4979aa97b6de40184c5a",
+ "digest": "0x7fa9e8243fd155df5677ac9c26861ade73b0a6ab52e98999956cbef093e96249"
+ },
+ {
+ "name": "random-39",
+ "domain": {
+ "verifyingContract": "0xe3ac435708684db0ae31e22bbefb1e44317338c4",
+ "salt": "0xe26aafa719c7da18b0ded1aa1520a9366af0fb6b459916877728cb9a5c87a7d6"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "bytes26"
+ },
+ {
+ "name": "param4",
+ "type": "bytes32"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀oé 🚀M🚀éMééoo é🚀o éo o🚀 o ééM🚀é🚀ooooMoé oo éo🚀🚀oooo🚀o 🚀oM",
+ "param3": "0xdc0aa250b183fce60762c98a54246dd7b9bb956bd6341da3e3b8",
+ "param4": "0xb72dc336b24a1bbf207488efe80ffcb2fcac731fd7663809b3d2fc49ba7dfc41"
+ },
+ "encoded": "0x7dfa18ea85b7f90d6621faeda9cf913de2386da0479309954a0255dc716d1597813bc527d887adf055ba505a819f5c99c5959f37552f3546a3621eecdbab9fa9dc0aa250b183fce60762c98a54246dd7b9bb956bd6341da3e3b8000000000000b72dc336b24a1bbf207488efe80ffcb2fcac731fd7663809b3d2fc49ba7dfc41",
+ "digest": "0x657847e82a36f749a49a0249eb01d42a8f84e155799a89a361326c7e059f4857"
+ },
+ {
+ "name": "random-40",
+ "domain": {
+ "version": "27.48.40",
+ "verifyingContract": "0xb01dee94f0bffe39c63b53c94d0a9fcbc1384c7d",
+ "salt": "0x2d69edf19eed3feff59d5ff3d202299b0a2f7cfd471953c708c84ff2c8ef15e3"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": false,
+ "param3": "0xaf4961b17878b5ba9013de1d9fd0f3642f1e7294"
+ },
+ "encoded": "0x08b05ab3afcc030e7935ce6c66d5d4b79136f50d1f567b347bde3906d91197e800000000000000000000000000000000000000000000000000000000000000007a9bca0401d98432dd02eb0e29aa6b8a2d7db41d77d60789e3f2a6b4672eb697",
+ "digest": "0xe8d2de50871488e0d941f58e407218d0e53232673e4f0c087c4ddc60f4b12997"
+ },
+ {
+ "name": "random-41",
+ "domain": {
+ "chainId": 1047,
+ "verifyingContract": "0x374b2b8301b1edbcc86612a691376d7ac3ced722",
+ "salt": "0x35b3516e1c75b47e8c6c9e67c454eeb7ee4bdfdce3bff554800152182ef7c097"
+ },
+ "primaryType": "Struct7",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "int80"
+ },
+ {
+ "name": "param4",
+ "type": "bool[]"
+ },
+ {
+ "name": "param6",
+ "type": "bytes4"
+ }
+ ]
+ },
+ "data": {
+ "param2": true,
+ "param3": "29080156520360861738698",
+ "param4": [
+ true,
+ false
+ ],
+ "param6": "0x5aedc9f9"
+ },
+ "encoded": "0x9ca37edfac674c2ff136c55e6301a602590e506fcacca5c9b6b9620af18ee3d60000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000628703dd9fee4a7a6caada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d5aedc9f900000000000000000000000000000000000000000000000000000000",
+ "digest": "0x6c6d10e7a34cd9b044d3ef2f2ed2d4333e2822ac7d10b38eb6d99bb8b1771bed"
+ },
+ {
+ "name": "random-42",
+ "domain": {
+ "version": "5.35.42",
+ "verifyingContract": "0x43b33fe40f841899d259fa0c36dea65ec8fde1d3",
+ "salt": "0x081bea430df1ade6eb0b35829797621ef878f32df1dc4b9d0c53cb94d441390b"
+ },
+ "primaryType": "Struct7",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "address[]"
+ },
+ {
+ "name": "param5",
+ "type": "address"
+ },
+ {
+ "name": "param6",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x3b9ca4b5f6b5e21e938265fa8c67e1caf4aab1f01b17be03ae60ee2d6635a495847dedc266f2a7c2e5567b52e52be5d3",
+ "param3": [
+ "0x699d241b2b53540a703d8f00870c1739b6e5f72d"
+ ],
+ "param5": "0x0109f2064fb32e6c22911ac905fb319ef0cee5a4",
+ "param6": "0x0ca1fb3d6077a402783877ceff53"
+ },
+ "encoded": "0x853568bcfdf9ba7ef41211e721fea9318ec93b8bf70306ce21829c25ba577bbd6865c9161273dd536df66549067730a5b9d1f65060fad8a53e1ac0f39ccdaa52f571a282e60d64a3ded8eaa67254087841c598a176a7cd626f00d50732f7f95f0000000000000000000000000109f2064fb32e6c22911ac905fb319ef0cee5a4c435cc0d815f1d138a42be987d6cc47160918ac555121a5bd5278c32fd472060",
+ "digest": "0x804d08480ce1b1d7ddf3646c58bf0a49a114f62d28e81ec9210e03f4f9f3a617"
+ },
+ {
+ "name": "random-43",
+ "domain": {
+ "version": "24.21.37"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ },
+ {
+ "name": "param4",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xfe1827974ce7e150af244d1b889f747c8f0a776e",
+ "param3": true,
+ "param4": "0x13a081fac5b7be3ce686e044bf4da3abef57fe9b"
+ },
+ "encoded": "0xd9df0580bd644a74f3c333bfcc151b8847cff76c671a86edc3130dbf71458cfb000000000000000000000000fe1827974ce7e150af244d1b889f747c8f0a776e000000000000000000000000000000000000000000000000000000000000000100000000000000000000000013a081fac5b7be3ce686e044bf4da3abef57fe9b",
+ "digest": "0xced726b5f99a87ac8035856b471812b2d20ad43e8e600fe5ef6e82ef52f1d653"
+ },
+ {
+ "name": "random-44",
+ "domain": {
+ "chainId": 437
+ },
+ "primaryType": "Struct10",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "int32"
+ },
+ {
+ "name": "param4",
+ "type": "Struct9"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param5",
+ "type": "bytes22"
+ },
+ {
+ "name": "param6",
+ "type": "string"
+ },
+ {
+ "name": "param7",
+ "type": "bytes28"
+ },
+ {
+ "name": "param8",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀Mo o",
+ "param3": "582504756",
+ "param4": {
+ "param5": "0x111983d0af17dcfcc318c61ae1136ee42ccf1f2687e1",
+ "param6": "Moo é🚀Méoo🚀 oooé 🚀o🚀🚀éMéMooo Moo🚀oMo🚀é 🚀 oo🚀🚀M🚀é🚀Méé",
+ "param7": "0xd6c6a4a7600a2e4bf9c4add944c09f63cbde8e22b0d6fcbf19615fef",
+ "param8": false
+ }
+ },
+ "encoded": "0x52230b1722ba9fa8df5a2874a719206cde8f49cae1cc265121e414b677873a98fb6852300dd5f88a8abd38b78e451c8cb00c5a9868c44b7df99b4a2f1c2d25620000000000000000000000000000000000000000000000000000000022b851341e0d5386101b1d456726a186dea7a1d769e76ac7dcf595f563d047ae9d74727d",
+ "digest": "0x205d02e271ba4c6b9f25c8f47ee1d77575d64cd4f00e63fffdc59472397d92e1"
+ },
+ {
+ "name": "random-45",
+ "domain": {
+ "version": "47.45.42",
+ "chainId": 1206,
+ "verifyingContract": "0xf947022a0e71d11aab373afabfe9befd44681e93"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes29"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ },
+ {
+ "name": "param4",
+ "type": "string[]"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x8bc51a1cd258fe6d63ac29ace059b760205588a0a9161c84c856c159f7",
+ "param3": "0x413b8e4fe25c1c744f85d99604ca804e2244bd4dab2ce6f5887da8e1d44ff150224b771fa7fcfdd80522c67e2315e1a2",
+ "param4": [
+ "Moo é🚀M 🚀o 🚀o",
+ "Moo é🚀oo🚀Méoé🚀🚀éé🚀é🚀éoM🚀MoMéMM",
+ "Moo é🚀"
+ ]
+ },
+ "encoded": "0x3ae8fde34490f7400f057134dfa1b5e09466c9c820ae931d27906d7f0ad91c9c8bc51a1cd258fe6d63ac29ace059b760205588a0a9161c84c856c159f7000000283f4a8f7f4aa0508213c3acfea1b9eadcc0134f291f7062983fb7b5faa4c0433ce102fe157fdae81a22e96b212ccdb916af0903abd81ed9dede694888ad8069",
+ "digest": "0x594e4bf0d590269799cca8859ba0a0bbdc1f50f79b62484b426596dd352185eb"
+ },
+ {
+ "name": "random-46",
+ "domain": {
+ "version": "20.6.0",
+ "chainId": 1182,
+ "verifyingContract": "0x48828af2bff4cea1847888835dd26ef645440919"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": false
+ },
+ "encoded": "0xd827c65b54cb667b8cb0c84a4aa21ffe3d188aa9cdaede527a285c318ad7274e0000000000000000000000000000000000000000000000000000000000000000",
+ "digest": "0x95645087033defeaf6a222f850ccd5f3f6ff9d051aeb02dd2c25cc7e237f38d9"
+ },
+ {
+ "name": "random-47",
+ "domain": {
+ "name": "Moo é🚀",
+ "version": "17.27.18"
+ },
+ "primaryType": "Struct19",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param8",
+ "type": "bool"
+ },
+ {
+ "name": "param9",
+ "type": "uint248"
+ }
+ ],
+ "Struct13": [
+ {
+ "name": "param7",
+ "type": "Struct10"
+ },
+ {
+ "name": "param11",
+ "type": "uint8"
+ },
+ {
+ "name": "param12",
+ "type": "bytes"
+ }
+ ],
+ "Struct14": [
+ {
+ "name": "param6",
+ "type": "Struct13"
+ }
+ ],
+ "Struct18": [
+ {
+ "name": "param5",
+ "type": "Struct14"
+ },
+ {
+ "name": "param15",
+ "type": "bool"
+ },
+ {
+ "name": "param16",
+ "type": "bytes25"
+ },
+ {
+ "name": "param17",
+ "type": "string"
+ }
+ ],
+ "Struct19": [
+ {
+ "name": "param2",
+ "type": "bytes[2]"
+ },
+ {
+ "name": "param4",
+ "type": "Struct18"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ "0x3cce5e65b51c8ab21c69ab4c6cf7a0098464d6fd4cc4dab8916ac0221f3ee8ea47479755ffbf",
+ "0xad11241adfe1c3d9ff8487a28064a49b65e77955dd25cbd4a6874161c9c93aa0502f1644dd08ce5b717e08f3eec80232527d509a8da2bcbf"
+ ],
+ "param4": {
+ "param15": false,
+ "param16": "0xeaba82b14185bf405877677729bd3cf35984e2de6795d26af8",
+ "param17": "Moo é🚀oM🚀ooééoo é M🚀oéo 🚀 o oooooMMéoéMoMM🚀oMo🚀MoéM é oo ",
+ "param5": {
+ "param6": {
+ "param11": "250",
+ "param12": "0xdf",
+ "param7": {
+ "param8": false,
+ "param9": "100895587724354576608296576780149850234295977769426801441167174141880048070"
+ }
+ }
+ }
+ }
+ },
+ "encoded": "0xa2503d8dab2dd52492c8bd1e75e197a963b1be16d8704f24b034c5c3ebb5ae22ab435560740a636c972580194f75d3a1a37686a2281bff1c37e9ca6ccc1c69bebed7f0eb879274b19967141ea60f229549d8509e8c2719506fca12599149d972",
+ "digest": "0xf87ee3f08c482046207edfd23e1303358eb48bd840500f424192948eed97c044"
+ },
+ {
+ "name": "random-48",
+ "domain": {
+ "name": "Moo é🚀Méoooo🚀 🚀🚀ééMMo o MM 🚀o é o",
+ "salt": "0xc03f10b7364e134ddc9de679561060f22c44058fc7abab3b8a06eeff8a0cda3e"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x6be8",
+ "param3": "0x48c2efb8ba7ee5d877ba4641d56d960ef4857d19b913c44af5c4b9bda9cfa25179"
+ },
+ "encoded": "0x39b0d4be9d0cd319e0a49b11a9725cad68c2545bda0a2875a0510a5846e63ce43b716dc9026fa5a0f9d7f44f4f87e3bf20d3ba1c57dc9820987bf547c9cd1c92caefa7da9321f9199f0d71f17e36c56f1ec520e39306893bb0216f64129f029d",
+ "digest": "0x32e5e620ebdc87817f3c8028e2e1dfa11bc8281ce740d373ec1d3e6944eb795d"
+ },
+ {
+ "name": "random-49",
+ "domain": {
+ "name": "Moo é🚀o",
+ "chainId": 103,
+ "salt": "0x3a5a1eb3351d1a1688d37b0d12422c89298146d8fb17ba3c25fb4b5c86c4bac9"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "string"
+ },
+ {
+ "name": "param4",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x26dfef70c4ef8dcc7b392b64e54778600e4342729ff538043a4180f710d08d7b5456214a42f08ba7fac949be1bbc22b9de57aa01223cb5556b82844077",
+ "param3": "Moo é🚀o🚀 éMMoo",
+ "param4": false
+ },
+ "encoded": "0xbb972fe1a70ee0d67e7cacbc55c17b51b6f3a17a25f4f86f5941e8562149d8baf133a0ff1f13504e6c624d2de18b24dcea844936d869bcec139368394b038fd1dd59271cb718f83ded679ab9a17cd95cf12c4045bddd47bb221f8ba9f1d192320000000000000000000000000000000000000000000000000000000000000000",
+ "digest": "0xf5f4417e3f7452c53925e17a8d761742c795a21d1399bbdbcc6655d28ae01898"
+ },
+ {
+ "name": "random-50",
+ "domain": {
+ "version": "29.42.1",
+ "chainId": 1327,
+ "verifyingContract": "0xfa7dc57fcaae354b92e4116c0bdd2cf47d8f689b",
+ "salt": "0x03da468bb06a9b9dab725571b916aff5422068b4ed5447355b3c5f70bc15171f"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀ooé MM🚀o🚀éoéé🚀oM éoMMMMoo 🚀 o"
+ },
+ "encoded": "0x5927d86a0ef9a01a131f7a41d2a9c89a8c82e0f454d6b4502f955f90f152eb51cb99a22ed97e79bbd189fcbf151341d2ba13a10693a9f98ff01bde8e4b54b0ed",
+ "digest": "0xd10b65f29d8c77544a7a31a419b8158854a6efdbd142c11b13e5e914720eab09"
+ },
+ {
+ "name": "random-51",
+ "domain": {
+ "name": "Moo é🚀éMMoéMéMoooo oo🚀 é🚀é ",
+ "version": "17.12.32",
+ "chainId": 850,
+ "verifyingContract": "0xee57c317107b6016ee17355d870066437b91cfc4"
+ },
+ "primaryType": "Struct9",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param4",
+ "type": "string"
+ },
+ {
+ "name": "param5",
+ "type": "bytes2"
+ },
+ {
+ "name": "param6",
+ "type": "address[3]"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param2",
+ "type": "uint176"
+ },
+ {
+ "name": "param3",
+ "type": "Struct8"
+ }
+ ]
+ },
+ "data": {
+ "param2": "41925907111722419066054857838161787127898051241694288",
+ "param3": {
+ "param4": "Moo é🚀M o🚀 oéé éM 🚀M🚀 é 🚀🚀 oo 🚀é o ééMoMé 🚀o o Moé éoMo o🚀 ",
+ "param5": "0x34cf",
+ "param6": [
+ "0x93ec006c48ba16d99c6a572425637e732a9ea0dc",
+ "0x31cf2777fa3591e4d92e44b68f531fe304770850",
+ "0xf193bb64fd886bbb4490a31d7ab87a4e69f72240"
+ ]
+ }
+ },
+ "encoded": "0x6b5499a7890f6a8255933b37decd0f637928da8bd61d925b3fc04f155551707200000000000000000000700edea808dc2e1e1937df49f85355a1244560c5d450fb8722e70eec19fe4a54da68f47326495d284ae333f3f2db8057ec987bb743b0",
+ "digest": "0x95199a1c903ef5b161ea35770728ff9753d9fe4cf63a68001bd910bfd7cd8930"
+ },
+ {
+ "name": "random-52",
+ "domain": {
+ "name": "Moo é🚀éo oéé é M é 🚀🚀oo🚀Mo 🚀oooéMé",
+ "chainId": 1092,
+ "salt": "0xab35002bd126820952bb44438b2a342cefd29a7e41533cf101af42d980f231e5"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "int168[3]"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ "95857240772386493629523551458434344427800456907887",
+ "28274122495329753421185292621092753236174200542842",
+ "32557294196900688742163694164485808400870334488946"
+ ]
+ },
+ "encoded": "0x9c928539a37b7c8e4f1ce136ca12eba2a05b8ae934748884491b03ad7547973a0a839d9c631d1e54947847568fb9b7170b4c91ff638a57cd7bdee89b100734ae",
+ "digest": "0xf56d12fc86d9c13a69e7e53913981ae56a0bfdc19f6c1693cb3a808aef256f80"
+ },
+ {
+ "name": "random-53",
+ "domain": {
+ "name": "Moo é🚀oooo🚀éoooéoéoé🚀é é Moéo oooMo ooo",
+ "version": "13.16.19",
+ "chainId": 568,
+ "verifyingContract": "0x1c60b5eb2fef17a1cdd14f962e6f7d3b3b6d6500"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "uint72"
+ },
+ {
+ "name": "param4",
+ "type": "bool"
+ },
+ {
+ "name": "param5",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x2a82f8de19144e48d8bd0ca7dcdcffc3efdcad1c261eb97bd6111b6918b4daab39158153",
+ "param3": "1620817067840645147941",
+ "param4": true,
+ "param5": true
+ },
+ "encoded": "0x09cfbba2e1e5ea4a3a82d13e5af185c9af63919209274a8b7c749ae5d84b713cb669a821b131bc1c35ea0a46ea180437711dceaf7c7157512bc9794f513ae1c0000000000000000000000000000000000000000000000057dd5af7be83dcad2500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001",
+ "digest": "0x508f38594346bfeecaf00d106d48313a5fda1a95aad52b5543d5b14b9d7196a7"
+ },
+ {
+ "name": "random-54",
+ "domain": {
+ "name": "Moo é🚀éo é🚀🚀oéMMooéé MéMMéoooooo Mo 🚀o",
+ "chainId": 903
+ },
+ "primaryType": "Struct10",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param2",
+ "type": "bool[1][2][1]"
+ },
+ {
+ "name": "param6",
+ "type": "address"
+ },
+ {
+ "name": "param7",
+ "type": "Struct9"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param8",
+ "type": "uint216"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ [
+ [
+ false
+ ],
+ [
+ true
+ ]
+ ]
+ ],
+ "param6": "0x8e95a960e9a83b777c7862a94e8110fe91da147a",
+ "param7": {
+ "param8": "86338055400144793659912925038806297757314957088810913205015089413"
+ }
+ },
+ "encoded": "0xc2160e538078feaa17b54d2e42d2d30202df0ca254993ea38c93773174f229ffc62f64b185683f6d01ccc0e8d936d70806faa97827a9a5f882dfd39e417384780000000000000000000000008e95a960e9a83b777c7862a94e8110fe91da147aafdbe910404b0c3b44c47734e11d0efc9d25900e7fcb2a08b20eb55cf7c271e6",
+ "digest": "0xbc69ff6a3a430987fe2afffe25c78d68fe98948b160b03aa8bb31dc93bb40cf8"
+ },
+ {
+ "name": "random-55",
+ "domain": {
+ "version": "14.37.24",
+ "chainId": 406,
+ "verifyingContract": "0xfa8846e816297a43ce7d94b8c6bdb6cca1159fd7",
+ "salt": "0x242778aa1964c438a31f0e78cb2939d4452e9498a49b3765a9a401a5ac362230"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bytes21"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xa6eacd95abf006c234ec8ada1a0a1efe733fb8fecf"
+ },
+ "encoded": "0xe3f2482dcc01a81435fc0dd8a8d9e82fb6aeac6d724cfcb3ec568286b0182780a6eacd95abf006c234ec8ada1a0a1efe733fb8fecf0000000000000000000000",
+ "digest": "0x49a860a4b3d28e51559860477bea7a0dd0cd2cc65aefc1be534af93dbda125cd"
+ },
+ {
+ "name": "random-56",
+ "domain": {
+ "chainId": 1035,
+ "verifyingContract": "0x1c37f1b939feea69ce5757b2ff01a4dbe98cee99"
+ },
+ "primaryType": "Struct9",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param6",
+ "type": "address"
+ },
+ {
+ "name": "param7",
+ "type": "bytes"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param2",
+ "type": "int248"
+ },
+ {
+ "name": "param3",
+ "type": "bool[2]"
+ },
+ {
+ "name": "param5",
+ "type": "Struct8"
+ }
+ ]
+ },
+ "data": {
+ "param2": "189736845901057709645072716699447242597536589852507924815517840586006295739",
+ "param3": [
+ true,
+ false
+ ],
+ "param5": {
+ "param6": "0xc84f54254fadc15051904a3aaf01a63695b229c6",
+ "param7": "0x17e0e79daf5a18eeea785f936e9d0b2f867e5adbf00c319da45f5db04d42397d4b9439754f98bef9ea96a1f6b3d8517c9c272e7d7ba1dc6852c8ea06b9de"
+ }
+ },
+ "encoded": "0xb9cd0c37eacfb7cce86fa6e1179348a2dffc13cef7976b514a468bdf7afb4063006b6322c21ecaba15e76c656e3fc5d69ed353a0eb9ae49a9c4ef0ed9f0b74bbada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7de75e33b115454660e8bf1399340fd2a08c02c80da600b7f6607e4fdaa98b71dd",
+ "digest": "0x89a21c0061b072cf4fe51034a22f646423cb79528c45920db9f8dd9b8ef023d1"
+ },
+ {
+ "name": "random-57",
+ "domain": {
+ "name": "Moo é🚀oooooéo🚀MM🚀o",
+ "verifyingContract": "0xd5fdebacaa6fd0e4c4e3dcb01d49d0d0b5169fd3",
+ "salt": "0xf46bae2676d80f6d7ed7eebfe927e808a1a9d7f16bb9c5733025eb1c54fb3cd7"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bytes24"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x11e04fffbb632f04623d274c69004680bbfe47f642d78193",
+ "param3": "0xc4340156b62bc39a03b5f8bf3405e1"
+ },
+ "encoded": "0x15a4a682c969e6c9e1a691efb9e6eac924562774edc9c70b2dea59192b5ffc4511e04fffbb632f04623d274c69004680bbfe47f642d78193000000000000000059b64b2801ddb0f37604d34c0c2b712b9ba10b111c50bf93ad769dc5372943f4",
+ "digest": "0xfdd39c246fa31fb5a02b7eed6bc3ccf206bf15199c22155fc730d523c884376f"
+ },
+ {
+ "name": "random-58",
+ "domain": {
+ "chainId": 382,
+ "salt": "0xedba234675d29838cea84fca64d51c6ec1a8569eb7dc50ab6db9fdf81cbda9c7"
+ },
+ "primaryType": "Struct7",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ },
+ {
+ "name": "param4",
+ "type": "address[2]"
+ },
+ {
+ "name": "param6",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xea0f9d8e13e45e85a35d02b4523d47aed0e2acb5",
+ "param3": false,
+ "param4": [
+ "0x0c861e080792c701e98212618cf4fa7fab7bf08b",
+ "0x899bb3224127617acf0ba2c0002c2f2ab1fa53b8"
+ ],
+ "param6": "0xf36ebef74931bfa226e964551dfe43911f2d130e"
+ },
+ "encoded": "0xc143354b22d04023559bed7cae63b574cfb78cfd7ac0c43a128d77d6e5e614ec000000000000000000000000ea0f9d8e13e45e85a35d02b4523d47aed0e2acb50000000000000000000000000000000000000000000000000000000000000000c71de37770f9c52cb0725ff89e17b4cf1847e4d111693996075aacaff8157569000000000000000000000000f36ebef74931bfa226e964551dfe43911f2d130e",
+ "digest": "0x2d06931eec7d70a1db63d07d25e4b8b90f7bcb3a2b55d972c48278dd66acb0db"
+ },
+ {
+ "name": "random-59",
+ "domain": {
+ "version": "30.30.24",
+ "verifyingContract": "0x561277eeb6bbd800e12ebc6cd0dbee892d139824",
+ "salt": "0x14bc6a6ff4765450e40c9f760db83f7b207a736f8588a22106af54f936524eda"
+ },
+ "primaryType": "Struct10",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param2",
+ "type": "Struct7"
+ },
+ {
+ "name": "param8",
+ "type": "bool"
+ },
+ {
+ "name": "param9",
+ "type": "bool"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param3",
+ "type": "bytes22[1][3]"
+ },
+ {
+ "name": "param6",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": {
+ "param3": [
+ [
+ "0x507f079711e94366216b3db9f773265034311ecd25b8"
+ ],
+ [
+ "0x5f6c0a03617cd85a8d36eaf3b00f3bf7250d52ef44d1"
+ ],
+ [
+ "0xaaffa60b2f4aeca0cd5e1633701c0fbc7801574995f3"
+ ]
+ ],
+ "param6": "Moo é🚀oéoMéoé🚀M🚀"
+ },
+ "param8": true,
+ "param9": false
+ },
+ "encoded": "0xaf138bad46576af052316d07c060c9e4148c2bff6809ec200b5bd3de4aa870cf4f3e0e37be2547e04487ab720f75f451fc5f4feabfe1102ce08d0e4ec14306d000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000",
+ "digest": "0xaf9d9edf7f72d55542c3a9d8b875cee65261f3aa6c7e96280440c183661bed0d"
+ },
+ {
+ "name": "random-60",
+ "domain": {
+ "chainId": 563,
+ "verifyingContract": "0x724d9d0a75aeefec930256ab77b13f018432dc13",
+ "salt": "0xf766cba081e9030cf506f1616682083a65c89daebf5cf7e828d5bf85a47a819f"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "int80"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": "-149389809661940077828877",
+ "param3": false
+ },
+ "encoded": "0x773a0a5ad6d608cfce67b33cbffe13f6c510c8e08ce51877432cbe3f5e8efe0effffffffffffffffffffffffffffffffffffffffffffe05d8febbd996b6de4f30000000000000000000000000000000000000000000000000000000000000000",
+ "digest": "0x638795e70617a8e19fb1971a5531c28225e07cbf26f3330c59f6d5bee2b237ed"
+ },
+ {
+ "name": "random-61",
+ "domain": {
+ "version": "7.6.2"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "uint40"
+ },
+ {
+ "name": "param4",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x2ea8b4cdab8e0585a626248968a0f3a97dbc1668",
+ "param3": "113948542974",
+ "param4": "0xde0c11a1e17e64435e2d0a8414cc368302fe788c8aac8e47741336362229cf9b9c4b029f6b"
+ },
+ "encoded": "0x1bf518570cadc618d41542f220dc4096c36b1bdf93cbd49b2a8d9d8702b1b6540000000000000000000000002ea8b4cdab8e0585a626248968a0f3a97dbc16680000000000000000000000000000000000000000000000000000001a87dcc7fedee76d97debe8dea474b08619fc6a3b04e96d191aa5ddd4309330f5f6cc24603",
+ "digest": "0xe825e97cef6530ad8cd98b08e3d94b08c18a3ae7be1a742e6c9378b419c266ab"
+ },
+ {
+ "name": "random-62",
+ "domain": {
+ "name": "Moo é🚀ééMMMMM🚀é",
+ "version": "39.10.1",
+ "chainId": 955,
+ "verifyingContract": "0x72c212d52a7da827cf299e1063d0f5481a10aba3",
+ "salt": "0x911b6be26e46725a5a9b2f66813850cb246cf850f316a8abd17c3255a59b1b73"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "uint120"
+ },
+ {
+ "name": "param4",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": true,
+ "param3": "267318752341245407126510725002347495",
+ "param4": "0x12a0cdc5797b0e2cd0fcc3b5f3d63d0b40060713"
+ },
+ "encoded": "0xb1d573600e493816acf7786e0db884238646f98d2925ad6bc1d0e58f7a84557600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000337bd501dc8adfc1e062ad2c26c3e700000000000000000000000012a0cdc5797b0e2cd0fcc3b5f3d63d0b40060713",
+ "digest": "0xa6448bcf64129f8f3357ad27ea6cb54528261ae82c77fa911cfd42326c5a32b9"
+ },
+ {
+ "name": "random-63",
+ "domain": {
+ "chainId": 52,
+ "salt": "0x63a0b8d00ebb49dc92aa7466795df26f52f7f097a8951212994dcf084f3115ee"
+ },
+ "primaryType": "Struct11",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param6",
+ "type": "string[3]"
+ },
+ {
+ "name": "param8",
+ "type": "bytes"
+ },
+ {
+ "name": "param9",
+ "type": "string"
+ }
+ ],
+ "Struct11": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "uint176"
+ },
+ {
+ "name": "param4",
+ "type": "string"
+ },
+ {
+ "name": "param5",
+ "type": "Struct10"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x3e22bfaf4192ea7bbd24be98894f62",
+ "param3": "8643822919333434052426646511186265705818267649977701",
+ "param4": "Moo é🚀 MoéM 🚀oo🚀M🚀é🚀ooooéoMoMMé é🚀🚀ééoooo🚀oo🚀ééo🚀 ooé ",
+ "param5": {
+ "param6": [
+ "Moo é🚀éM MoMoéooé🚀oéo",
+ "Moo é🚀MMooéoo🚀é🚀🚀é🚀oéoé éo Méooo 🚀M oé🚀oé M o🚀éoé oéoo o",
+ "Moo é🚀"
+ ],
+ "param8": "0x855aef",
+ "param9": "Moo é🚀"
+ }
+ },
+ "encoded": "0xac316d647c74bc3589294fae161068a7566854edd7dd16d2eda15b770a4375daa7942ff4d68d8349802c6984bdc9c4c2b6d470e42e79142bbc940d35ac64002400000000000000000000171a57f90c59a9aa6004324b4c1e5ca16b31e5062d65320516b8c2848eb919a422085947b5272cee2812540b5bf353b28c2cb5f048a86ed4f8451f4da89498fab2ccc0b5f4f96071ca26c12b291e2fb6545c1fdf6657",
+ "digest": "0x3312dae7779358b36e3d0901d23210c35ae47615a6ced82730958afeecba27b4"
+ },
+ {
+ "name": "random-64",
+ "domain": {
+ "version": "12.22.26",
+ "chainId": 1072,
+ "verifyingContract": "0xcfadcc6d18290da205685c27be85e3d12daef93a"
+ },
+ "primaryType": "Struct7",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "address[]"
+ },
+ {
+ "name": "param5",
+ "type": "bytes14"
+ },
+ {
+ "name": "param6",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": true,
+ "param3": [],
+ "param5": "0x8e08e58d1d810440dff7199e28d0",
+ "param6": "Moo é🚀🚀oooéé "
+ },
+ "encoded": "0x1a13a4e4f65db23bb29d9f84dd419677df8345f546cd92242e7e392b4fbc15360000000000000000000000000000000000000000000000000000000000000001c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708e08e58d1d810440dff7199e28d00000000000000000000000000000000000000d7aba156c05cec0dbf187401b9ed4df82bcd9fd30870c0924ad1cf2b4f3d704",
+ "digest": "0xaf2a42e1f7ec4b6c7b7dba5b36c575bda2972f52479f34190d1c3750e18ad5a7"
+ },
+ {
+ "name": "random-66",
+ "domain": {
+ "chainId": 1336
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "bytes5"
+ }
+ ]
+ },
+ "data": {
+ "param2": true,
+ "param3": "0xec970b3168"
+ },
+ "encoded": "0x2bc752ac2910b71f3084d69bc9772a7de5341093c84f7c9e5fd2ac361544ad460000000000000000000000000000000000000000000000000000000000000001ec970b3168000000000000000000000000000000000000000000000000000000",
+ "digest": "0x8feef116af30b282bfe16c1890206276e9aae7dd7f74e5f988614956135e273f"
+ },
+ {
+ "name": "random-68",
+ "domain": {
+ "version": "18.42.3",
+ "chainId": 5,
+ "verifyingContract": "0x2909159c78bf78c499a576986e657f6221814a1b",
+ "salt": "0x4757ed28e3e7f1ce3bdcb44424f8d26cc8f55f00ea55759f5200e5e58c2df0f4"
+ },
+ "primaryType": "Struct9",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "string"
+ },
+ {
+ "name": "param4",
+ "type": "bool[3][3][1]"
+ },
+ {
+ "name": "param8",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀 🚀ooMMé",
+ "param3": "Moo é🚀ééoooéM ooM Mé🚀Mo Mo",
+ "param4": [
+ [
+ [
+ true,
+ false,
+ true
+ ],
+ [
+ true,
+ true,
+ false
+ ],
+ [
+ false,
+ true,
+ false
+ ]
+ ]
+ ],
+ "param8": false
+ },
+ "encoded": "0xe1a6b9ce8570dfc1929b0986ecaa84c675a38f130aa0dd754f0f3efb28a7946e7b41e0b88acf6e22ccb8ab0ceb0b4e4498e5569bdada5470159cb4aee1977181aec0dcca7af9e7739a3bb043c812bb554c938bd178a9b815ff2bcc12571dedcdcb524ab786db4edc230bef0de43dcb5bc64e388a0e6e7e776ad754bde112e7530000000000000000000000000000000000000000000000000000000000000000",
+ "digest": "0x93c2c7376679e56c01ad0855a122657ad37474c3c3cf2d943693ed74c9bdf20a"
+ },
+ {
+ "name": "random-69",
+ "domain": {
+ "version": "29.38.34",
+ "chainId": 479,
+ "salt": "0x4d41456ce1c41c3d581d10c26cb759d4a47f54ce1a9368f438e2a81977f51d93"
+ },
+ "primaryType": "Struct7",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param3",
+ "type": "address"
+ },
+ {
+ "name": "param4",
+ "type": "bool"
+ },
+ {
+ "name": "param5",
+ "type": "string"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param2",
+ "type": "Struct6"
+ }
+ ]
+ },
+ "data": {
+ "param2": {
+ "param3": "0x824518b68d26baa46978e389d86ffce76fc865b6",
+ "param4": true,
+ "param5": "Moo é🚀éMMéééoo 🚀o🚀o🚀oM oé🚀o oéooé🚀éoéoMéMoo🚀🚀oo🚀"
+ }
+ },
+ "encoded": "0x30c11efb6065f6bda2985909969cdeae08dca57414e9e0f27cd2aa3b7be28049e16d3c3bef1a3a648aefca75d723e43c4c44ae6a69831e585a5e3cf1af9cb02e",
+ "digest": "0x5f28a72d46bcf0e734304e0fdcdb6ce0371bff2f2db3c66dbef72582ca768429"
+ },
+ {
+ "name": "random-70",
+ "domain": {
+ "version": "18.40.21",
+ "verifyingContract": "0xb24a517ffcbfdd9bc47720db3e5190fda2e01002"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bytes3"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x41ce81",
+ "param3": "0xc83aff0255120cca20588d23ada5f3f38f7195f030873a49a7d16fe8dcaf2b19ac789fca2b3f90470ffe0345332fdcb0"
+ },
+ "encoded": "0x3ba0a68a11c3149e7b8cce5c07245e59ffa9acdaf38fcc613b25ec0abd0fde9b41ce8100000000000000000000000000000000000000000000000000000000003a478a822fa1170b9116c77ad351ea423f4a9ea13a9942e3f02beff4c8c9e6cf",
+ "digest": "0x26a000eff8c5171403d5d31329e4675bbb567bf0fb2938737fc72b35070bd0a8"
+ },
+ {
+ "name": "random-72",
+ "domain": {
+ "name": "Moo é🚀é🚀 M🚀 ",
+ "version": "5.17.26"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bytes32"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x1a4984f48e88befe512b3cb96ab6dcd897b12c4178dc46a3eb0174834581a306"
+ },
+ "encoded": "0xf0b1d4f6e88accb50c11c83238640185fa1db3c76ce20f17fa4916dadf9db31c1a4984f48e88befe512b3cb96ab6dcd897b12c4178dc46a3eb0174834581a306",
+ "digest": "0x56403e65cffb42a3d27fc46982bf5f109216c216e600ae1d5e9eeb0f2d535c4c"
+ },
+ {
+ "name": "random-73",
+ "domain": {
+ "name": "Moo é🚀ooMo🚀oo🚀é ooo M🚀éM oo🚀 éooo🚀 MMoé 🚀oM 🚀 é é 🚀oé🚀ooooéo",
+ "version": "35.11.14",
+ "chainId": 1042,
+ "salt": "0x7b9937e8531f141e3ee6fe381c9a9e86ffdcd0c68a8e1ae17112e620aaab338c"
+ },
+ "primaryType": "Struct12",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param3",
+ "type": "bytes30"
+ },
+ {
+ "name": "param4",
+ "type": "bytes"
+ },
+ {
+ "name": "param5",
+ "type": "Struct8"
+ },
+ {
+ "name": "param9",
+ "type": "address"
+ }
+ ],
+ "Struct12": [
+ {
+ "name": "param2",
+ "type": "Struct10"
+ },
+ {
+ "name": "param11",
+ "type": "string"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param6",
+ "type": "bool"
+ },
+ {
+ "name": "param7",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param11": "Moo é🚀oéoéé",
+ "param2": {
+ "param3": "0x36edbef26bd4681e7135942feae3864374031194d1426af5a7e481a728d8",
+ "param4": "0x1a59b3c0be1b6635e52bdf4cfe067940b50d4e696c363000edc866d8d22c9e49398b54f25d4e9718feb3f99eb46ce3751b926fa7855343150f9d",
+ "param5": {
+ "param6": false,
+ "param7": "0xe6e18c2cb91d1abe36baf44ab6122b3fd30a74c0"
+ },
+ "param9": "0xc6013a4ce04bb384ce0b272cd0680e04df0cc7b7"
+ }
+ },
+ "encoded": "0xeb7ccb02ebd334f8f8df1a4ee2070e684c143ac9a985b10cd81de8a58fc80adbc5dd6b5081adebdb29fdae09d95ee5ea84d03f41c3772434f05e3b05708112fc70204aaa5c94f68894203bf3369b48b4d60e7f149b87d2b0805639a833c2fe66",
+ "digest": "0x67912c3108d4a59226f95dc0c3c275382f78beac03a86f9e077c1caa1eeec14a"
+ },
+ {
+ "name": "random-74",
+ "domain": {
+ "name": "Moo é🚀é 🚀éo🚀o 🚀o é M🚀é🚀éMo🚀🚀o🚀Mo oMo🚀 oo🚀 éo é",
+ "salt": "0x370860feeba70f3953279dba52f02a3a04612484aefa84f31663d9e5227e1d6c"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "uint80"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ },
+ {
+ "name": "param4",
+ "type": "bytes5"
+ },
+ {
+ "name": "param5",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "908478282363712209846374",
+ "param3": "0xef8eb40ace87b08ffe0e7aefbe3bd8e6",
+ "param4": "0x597d2ea26a",
+ "param5": "0x8922c08275eb23909ccfca4daf11662e5d"
+ },
+ "encoded": "0x76603b49ee0d4f7ea115ee0a57044fe4c0401d1221ad71b9dc5321cc33fef7b900000000000000000000000000000000000000000000c060b4d4a59107f2806606a0b7daf9092ca6ab2e9126f86c784769009fa8f8d71e7e03679ce2ca8d87a0597d2ea26a000000000000000000000000000000000000000000000000000000cd50ee07435f2e2e828292fc6ef0446ca0f9be9bdc428a8eaffa42a5286a965f",
+ "digest": "0xa75d4290b6749b842bf573b2eb09823bb3873d1027d942b4ea6d4d81b842d6c0"
+ },
+ {
+ "name": "random-75",
+ "domain": {
+ "name": "Moo é🚀🚀🚀MoééMoo M🚀 o MoMéMoo🚀Méééé éééo Mo",
+ "salt": "0x38eaa8c2cfc07d160da608dbe8f1e194e7effef6978024db13d7dca0f3272c39"
+ },
+ "primaryType": "Struct7",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param4",
+ "type": "address"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param2",
+ "type": "bytes13"
+ },
+ {
+ "name": "param3",
+ "type": "Struct5"
+ },
+ {
+ "name": "param6",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x784f74ad457e1d6fcfb45d7367",
+ "param3": {
+ "param4": "0xdce541656a93cfcb9e179045ad051a9ecdd7189b"
+ },
+ "param6": false
+ },
+ "encoded": "0xcb86038251ab323aac49c6b590bcaa00d47d51116aa52134673db28594f5bf75784f74ad457e1d6fcfb45d736700000000000000000000000000000000000000a8a20cb63e84557a5347128e3f0c2a1b5a0afb541230866c1088af198275a6b80000000000000000000000000000000000000000000000000000000000000000",
+ "digest": "0xefef2081cc8e3873505b925f3297102ae37293e502c1a8f0c8f74ccdbb89d4bc"
+ },
+ {
+ "name": "random-76",
+ "domain": {
+ "version": "36.49.23",
+ "chainId": 754,
+ "salt": "0x43db1a3f28a17091824b3c3dab8e15ec297daf2313c6755b3e40e58f96c9b179"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x3a0cba0c53b27c471b7897a7d6b055079c47d518"
+ },
+ "encoded": "0x98edda54668461e736d24a4033f2d11540bceac48ea14c7da0fea73b8b9a55db0000000000000000000000003a0cba0c53b27c471b7897a7d6b055079c47d518",
+ "digest": "0x6e9544e309d43df400883cf848f3963329e1e69e89a787509df5a9d5cefe94c7"
+ },
+ {
+ "name": "random-78",
+ "domain": {
+ "name": "Moo é🚀 ",
+ "chainId": 1205,
+ "salt": "0x9af868b51e603e4c79a4f3ec3f3117dc294b46a36297214095a50f193489bb42"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ },
+ {
+ "name": "param4",
+ "type": "bytes15"
+ }
+ ]
+ },
+ "data": {
+ "param2": false,
+ "param3": false,
+ "param4": "0x60217b1a8953bfec781042b8770a75"
+ },
+ "encoded": "0x1676a9ea413a00e543593a76cb92d87b3f3d82e3116ed0efa051c85413c5ee3d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060217b1a8953bfec781042b8770a750000000000000000000000000000000000",
+ "digest": "0x7f79e4826551d80cda20954308c0daf2e009e2af2aa6f3d60bec8130d535dda6"
+ },
+ {
+ "name": "random-79",
+ "domain": {
+ "version": "6.7.22",
+ "chainId": 483,
+ "verifyingContract": "0x55f4aa781b99afe9ce65b85e20b467cbdec997e6"
+ },
+ "primaryType": "Struct8",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param5",
+ "type": "uint80"
+ },
+ {
+ "name": "param6",
+ "type": "bytes18"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param2",
+ "type": "bytes8"
+ },
+ {
+ "name": "param3",
+ "type": "string"
+ },
+ {
+ "name": "param4",
+ "type": "Struct7"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x8b52a6ddb851805f",
+ "param3": "Moo é🚀🚀🚀ooo🚀MoM o🚀🚀é",
+ "param4": {
+ "param5": "610461354364077444926076",
+ "param6": "0x7161dd90da510a700714562a8e29d7bf559f"
+ }
+ },
+ "encoded": "0xfcabf7393dcfae718d48a70508ca009b50740ada3608bceaff6b492ed20c200f8b52a6ddb851805f000000000000000000000000000000000000000000000000aca36f7ecb9904e737ae9a06d9a7bc75f52075619eb5d2238d49e56ff0722a4c50896c94a314c8d9e77fdb0734871b909b734cdaac41d6f6412bac6bbe685e74",
+ "digest": "0x52bc2e8e33e9a8f5c1e02b4eb1af26d9bfb646f90a802b87e7b05e1c492334b5"
+ },
+ {
+ "name": "random-80",
+ "domain": {
+ "name": "Moo é🚀 oo é ",
+ "salt": "0x12196565c18218e3d5c30fb8c3ed8aa5368b9270d1e50f96dae8c01c9524bd66"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ },
+ {
+ "name": "param4",
+ "type": "uint152"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x51f4089446d4fac6b978ebc92cb8c136a3ec12d4",
+ "param3": "0x9fa41910ccf9",
+ "param4": "1327849360637990991145689530428201101848957792"
+ },
+ "encoded": "0xc3cf69c88a7f7d51e14da0539c7562c4aef44fdccccf126abab02153850a06c900000000000000000000000051f4089446d4fac6b978ebc92cb8c136a3ec12d43550fb9376fce556153ac9c01b5a3d92905e20a0f5e9d20c7f84b82b55b23996000000000000000000000000003b8af68e30d0b55cd77e2a766ab742aacb5360",
+ "digest": "0xfa4436f23aab9a7adce0a1ed9ccb76fb12aa9c3fd4ea8f550d3d9c21ea8ad71b"
+ },
+ {
+ "name": "random-81",
+ "domain": {
+ "version": "37.42.30",
+ "verifyingContract": "0x8ddfee525b882a427923e62ea4c6c4f15fd30ac4",
+ "salt": "0xea7e38d5a4a991401101f92da453029636a589cc8a5a04f5e8b821d09fb72d62"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bytes6"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xa15ee47cd2ae"
+ },
+ "encoded": "0xb6ad09a6e56a9b085d21c37fc35456a42e929d83a6c454464108bba8e5bd24eaa15ee47cd2ae0000000000000000000000000000000000000000000000000000",
+ "digest": "0x5cf352f0b86d7a40b2722d6fee422cc31791ea6a756e975f94cc418482322967"
+ },
+ {
+ "name": "random-82",
+ "domain": {
+ "chainId": 1294,
+ "verifyingContract": "0xedd346d21be942f85ef9d7e2837019da832bdd15"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "uint216"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀o éMo🚀oM",
+ "param3": "60842439233483756494403810394413324880914448649588060989930178516"
+ },
+ "encoded": "0x0005f47efff5a6a0a15e05a2eec2b6e6fc783b60032aa8390118dbd32ba2cad636c6269b518467469df2499c64aa468f9cb44ac0c27f5aff6efe92d99caae298000000000093e657c796b03e22877711b903453f372f0a33b18b1f15119187d4",
+ "digest": "0xd4949695b7d6eec2e8c8f26d6d861ba735fcd61670fbca8de68609e0fd469e30"
+ },
+ {
+ "name": "random-83",
+ "domain": {
+ "verifyingContract": "0x7b9546d050c94a8270fa5c0d0e37ad2df4a1e763"
+ },
+ "primaryType": "Struct11",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param5",
+ "type": "bytes"
+ },
+ {
+ "name": "param6",
+ "type": "bool"
+ },
+ {
+ "name": "param7",
+ "type": "bytes27[3]"
+ },
+ {
+ "name": "param9",
+ "type": "uint176"
+ }
+ ],
+ "Struct11": [
+ {
+ "name": "param2",
+ "type": "int232"
+ },
+ {
+ "name": "param3",
+ "type": "Struct10[1]"
+ }
+ ]
+ },
+ "data": {
+ "param2": "753575330828539899242077719223027729803561407233093589597780073631396",
+ "param3": [
+ {
+ "param5": "0x43e53fca9177478563526d0765abe7705b1808451964d8207fb75278cac13fb991bb4dff4c6dde00456d5236a93fd20edc2081b46c087d9f",
+ "param6": true,
+ "param7": [
+ "0xa413dea0bd7fb350af2baf9e1878c127d2ab62367c57b6d4b4efc8",
+ "0x7514110a681f7d3bf5b932d467bedbdeee6681d6cb7a454978d6b2",
+ "0xdb56718cbc96a605ae9624a29a2432db87f2ff1cc1f86e2e70648a"
+ ],
+ "param9": "57122701991999599773377300580648345488081114848136112"
+ }
+ ]
+ },
+ "encoded": "0x7c13f5ac1c582fab4bda02838e5b34f88377ed3a9f2e39c4e9a99259893244cd0000001bf3a027ad30dc440fff233a7cc1bb6d49fee7c5273eff291e2f99cea417512f0ab3c462fc44f916934f29d7ab18f18c1b7cffe28b41d46b729680442e",
+ "digest": "0x2d36f076787c1920a351171a2c32575d984b68f652b1dca4db83687b2be45551"
+ },
+ {
+ "name": "random-84",
+ "domain": {
+ "version": "0.4.17",
+ "chainId": 911,
+ "salt": "0x3e7b8591b2ff12889933bff797d082b473fc6519049106aa59b07753e926bd66"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x41ca2691711b6289b07e9d60adcd530d82049e195a22202170b18328a7852d66398d41a006185887266fa7aad4ac89bfb33f94dc6cd2eaa7f2b9b12a01",
+ "param3": true
+ },
+ "encoded": "0x889d1fd6a543c2550a4d6fbf451f7004ee9509e508b7627d82b578e77ed3541a549ef74b3d255ff952161e092604766989b5f79184cb72d5f1687d04ddedb4390000000000000000000000000000000000000000000000000000000000000001",
+ "digest": "0x789a03f8f59d24aee8073b378663b9289f823791b818602a0477434b99c8b768"
+ },
+ {
+ "name": "random-85",
+ "domain": {
+ "name": "Moo é🚀oM o MMoéMé🚀MéMéM",
+ "chainId": 900
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "string[3][3]"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ [
+ "Moo é🚀MMo 🚀🚀MM oéoooéé",
+ "Moo é🚀 éo🚀 🚀oéoMo",
+ "Moo é🚀oééoéM oMé Moéoo oo M MMoééoooo🚀M🚀o🚀oéMo oo é Moo ooo oo🚀 "
+ ],
+ [
+ "Moo é🚀o🚀ooéMMooooMo oo o🚀 M🚀Mooo oé🚀o🚀oéoM 🚀M oéo🚀 🚀🚀 🚀o🚀 M",
+ "Moo é🚀oéé🚀ooéo ooooM🚀🚀éo🚀🚀🚀ooé🚀 éooM🚀oooooMoo Mo🚀ooooMM 🚀 🚀",
+ "Moo é🚀oo🚀M o🚀oo🚀éoMoooM oM M🚀ooMM🚀 éo MooMM éooo"
+ ],
+ [
+ "Moo é🚀MMMééo oM o🚀 🚀🚀 Mo o🚀éo🚀oMoé éé oo🚀éé🚀Méoé🚀🚀oéoo 🚀",
+ "Moo é🚀 🚀M",
+ "Moo é🚀oo🚀Mo🚀🚀oMo🚀M🚀 o MMoo ééMoé MoMoMMooééoo🚀 éo"
+ ]
+ ]
+ },
+ "encoded": "0x988b57712611b9efb362d55270a70ca3e280c7c23ee803db000637ee03249611aa5a4b824d61608ae0c2f6d5840f3f4e9f9984b3536adf111a3b3f81e01b75c0",
+ "digest": "0x42bfc8f80f73b02a800f2cf5f3b9b96c6774a43c706758c8f34f1fabf946b001"
+ },
+ {
+ "name": "random-86",
+ "domain": {
+ "name": "Moo é🚀Mééo🚀oé",
+ "verifyingContract": "0xa55e763720cf41f5a539aab57701a95d60e29f67"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "uint104"
+ },
+ {
+ "name": "param3",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "1292496995405503073422960358486",
+ "param3": "Moo é🚀MM o🚀o🚀 éMMoooéoo éé🚀oé🚀 éMoo🚀é🚀M é🚀oo Mo🚀 éoo"
+ },
+ "encoded": "0xa7b111f9ba803946689ccd05331e3dfd450deaf9afc546b5d2a08764dbb3075f0000000000000000000000000000000000000010504874d57b4ef8afc891f456a48ff30b0c7e041b00beb25671621131298873a003e9ec839b5d75eb5b1da286",
+ "digest": "0xf3af9321483c3d61bcdda3a128184aa6841318dc718edc3be9a2f0b976416641"
+ },
+ {
+ "name": "random-87",
+ "domain": {
+ "name": "Moo é🚀 éooo🚀Moo🚀oooMMo🚀🚀o ooMé éo o🚀éM ",
+ "version": "45.45.47",
+ "chainId": 759,
+ "verifyingContract": "0xdd7404edd91ced2e440ae26be5de770826936aa1",
+ "salt": "0x3e9fe589ec829de82a24cfdfb4f51be7b494d92d767ddce47df39f2d695fef40"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bytes31"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x76418c1f3cc8305025ce913e271c62064302cfc52a3cbcee02ffae444e402b"
+ },
+ "encoded": "0x5d03dd39f516dbdce0dda1249a18778b381083c568572fa40e677a1e8bcba69176418c1f3cc8305025ce913e271c62064302cfc52a3cbcee02ffae444e402b00",
+ "digest": "0x70669d88e5b14dde860f7967400d4001ea51ad347d9dc8e9e14a78a046620a0f"
+ },
+ {
+ "name": "random-88",
+ "domain": {
+ "version": "34.19.0"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bool[3]"
+ },
+ {
+ "name": "param4",
+ "type": "string"
+ },
+ {
+ "name": "param5",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ true,
+ false,
+ true
+ ],
+ "param4": "Moo é🚀o éo🚀é Moo🚀Mo🚀 éoMoooooM ",
+ "param5": true
+ },
+ "encoded": "0xeb561f00a2ce847d36d192a18b66be2e5938b7c84798b9a1730ef44ce41ef7c35c6090c0461491a2941743bda5c3658bf1ea53bbd3edcde54e16205e18b457922e1277d90577b137ca94be5c47d97fdd62924edbcd364fffd8f2543a0b3974cb0000000000000000000000000000000000000000000000000000000000000001",
+ "digest": "0x284ff781d137b80a6aedaf25217692a7bee1529b50f717d20fc8b113ea3d10eb"
+ },
+ {
+ "name": "random-89",
+ "domain": {
+ "name": "Moo é🚀MooMé 🚀é é éM ooo🚀M 🚀oo🚀 🚀oooo🚀éooooM 🚀🚀 oMé",
+ "verifyingContract": "0x94104688cc800c04a9f4ce356606469f7aaf0889",
+ "salt": "0xccd084925ccd16ac0a852763036118c175fe5a86811c7ed8ba75bd427a63985b"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x7af6a9843bfac96994bcecebe57b40d67942fded"
+ },
+ "encoded": "0x98edda54668461e736d24a4033f2d11540bceac48ea14c7da0fea73b8b9a55db0000000000000000000000007af6a9843bfac96994bcecebe57b40d67942fded",
+ "digest": "0x7db9f61f14ad00540fd7f51c7adeeff792ab7ef3bdfd672713223f0ff3920fea"
+ },
+ {
+ "name": "random-90",
+ "domain": {
+ "verifyingContract": "0x9511e9dcad6fbe5e6693a1d7031a592f27c5c4ef"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "bytes16"
+ },
+ {
+ "name": "param3",
+ "type": "uint56"
+ },
+ {
+ "name": "param4",
+ "type": "bytes25"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x88f0dd9c8cbee263cf947a650a3b3151",
+ "param3": "17583036303696475",
+ "param4": "0x00153b38e3509586ea81d62acfaf69f58033c03989a5e9ed83"
+ },
+ "encoded": "0x192ce62b78aff9164de71a0394d492eb37f524dfda52e333ccd477c065fbe73a88f0dd9c8cbee263cf947a650a3b315100000000000000000000000000000000000000000000000000000000000000000000000000000000003e77ada8f4625b00153b38e3509586ea81d62acfaf69f58033c03989a5e9ed8300000000000000",
+ "digest": "0x39c13ee9471e159919485ab461d454a50ca52a6ddd8cdadfbed90326801f74ee"
+ },
+ {
+ "name": "random-91",
+ "domain": {
+ "version": "48.32.32",
+ "verifyingContract": "0xdc2f8681bcb020c14bb5a61803be1f1904934a7c"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": true
+ },
+ "encoded": "0xd827c65b54cb667b8cb0c84a4aa21ffe3d188aa9cdaede527a285c318ad7274e0000000000000000000000000000000000000000000000000000000000000001",
+ "digest": "0x465f1b1db471abcc586e028f388b54cb4e0c9d341d9c03fd4def6118ca7ac479"
+ },
+ {
+ "name": "random-92",
+ "domain": {
+ "name": "Moo é🚀🚀MMéo 🚀🚀MoooooéMM🚀ooMoo🚀ooo 🚀o oéoo 🚀éoooé🚀Moo 🚀éooM🚀é🚀",
+ "version": "15.24.22",
+ "salt": "0xf6b0ebe21875667066601b50ad91163654013e109e51fae6a8bf19a988a51adf"
+ },
+ "primaryType": "Struct8",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param3",
+ "type": "uint160"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param2",
+ "type": "Struct4"
+ },
+ {
+ "name": "param5",
+ "type": "bytes25"
+ },
+ {
+ "name": "param6",
+ "type": "bool"
+ },
+ {
+ "name": "param7",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": {
+ "param3": "990067310911447424079721892655020403107523900579"
+ },
+ "param5": "0x929ecef7eecff36ca4a793303bfeb2f7666d3015f472177f92",
+ "param6": false,
+ "param7": true
+ },
+ "encoded": "0xfc75a8485d94b0cf924739d8db8392a3933b768aaf87990e0ef313c9613af2d569d3dc7ee6ddfd3cff85001b724976fea388b0d40fe7864b4d79e32eb76adc8c929ecef7eecff36ca4a793303bfeb2f7666d3015f472177f920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "digest": "0x650fa8632ebb3ad17d74fd519317c5bd99cf2210d6742be16bba20ad7bdb3055"
+ },
+ {
+ "name": "random-93",
+ "domain": {
+ "name": "Moo é🚀MéMM éooéoMoo🚀 M🚀M🚀o🚀🚀🚀🚀oo🚀🚀🚀Mo🚀🚀🚀M o🚀oMMoé M M"
+ },
+ "primaryType": "Struct9",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param4",
+ "type": "bytes21"
+ },
+ {
+ "name": "param5",
+ "type": "bool"
+ },
+ {
+ "name": "param6",
+ "type": "bool"
+ },
+ {
+ "name": "param7",
+ "type": "address"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param2",
+ "type": "Struct8[]"
+ }
+ ]
+ },
+ "data": {
+ "param2": []
+ },
+ "encoded": "0xef6a7dac2342e48bc7bee2421009cf3129bbeb0bb7fdeaba99402bea15f82c76c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
+ "digest": "0xba75038176156de4c9a80a8bb70ac20bb140c22b707179be3ae4a554a4e8ea23"
+ },
+ {
+ "name": "random-94",
+ "domain": {
+ "name": "Moo é🚀 🚀éooéoooo ooMo éMo o M🚀Mé🚀ooM o Mé🚀éoMMoo",
+ "chainId": 1017
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": true
+ },
+ "encoded": "0xd827c65b54cb667b8cb0c84a4aa21ffe3d188aa9cdaede527a285c318ad7274e0000000000000000000000000000000000000000000000000000000000000001",
+ "digest": "0x69ec47b02da2c0ebfa801692ca474f282d9f0df84f87c45cdc921ce1a0d860bb"
+ },
+ {
+ "name": "random-95",
+ "domain": {
+ "version": "18.32.12",
+ "chainId": 742,
+ "verifyingContract": "0xabe3c4f5cf4ed1b97303bd7cae8b067c5e7f8c26"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bytes[]"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ "0x38a9ee766abe7a928c112125e65ffb984ace",
+ "0x3a3613418bc9b1045fe5809d"
+ ]
+ },
+ "encoded": "0xfbb1adeb7d907dcad24d9dcc6c70efeb95e9983697f2b3d761bbc66df10b6de0c645b2e2e519bae0fadbaf7ef2932226f7e7935d3d837af12839bd360aa64a4d",
+ "digest": "0xc58c6e7c7e79b525438c151e97c6457f8c4c7b3065827d36e227d6efdbd5cb94"
+ },
+ {
+ "name": "random-96",
+ "domain": {
+ "chainId": 239,
+ "verifyingContract": "0x0f77912b8136385729a659bd3ef9107a61df2481"
+ },
+ "primaryType": "Struct36",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct12": [
+ {
+ "name": "param11",
+ "type": "bool"
+ }
+ ],
+ "Struct25": [
+ {
+ "name": "param21",
+ "type": "bytes"
+ },
+ {
+ "name": "param22",
+ "type": "string"
+ },
+ {
+ "name": "param23",
+ "type": "uint232"
+ },
+ {
+ "name": "param24",
+ "type": "int104"
+ }
+ ],
+ "Struct29": [
+ {
+ "name": "param20",
+ "type": "Struct25"
+ },
+ {
+ "name": "param26",
+ "type": "bool"
+ },
+ {
+ "name": "param27",
+ "type": "string"
+ },
+ {
+ "name": "param28",
+ "type": "string"
+ }
+ ],
+ "Struct30": [
+ {
+ "name": "param19",
+ "type": "Struct29"
+ }
+ ],
+ "Struct31": [
+ {
+ "name": "param15",
+ "type": "address"
+ },
+ {
+ "name": "param16",
+ "type": "bytes"
+ },
+ {
+ "name": "param17",
+ "type": "bytes"
+ },
+ {
+ "name": "param18",
+ "type": "Struct30"
+ }
+ ],
+ "Struct33": [
+ {
+ "name": "param10",
+ "type": "Struct12"
+ },
+ {
+ "name": "param13",
+ "type": "string"
+ },
+ {
+ "name": "param14",
+ "type": "Struct31"
+ },
+ {
+ "name": "param32",
+ "type": "bool"
+ }
+ ],
+ "Struct36": [
+ {
+ "name": "param2",
+ "type": "Struct8"
+ },
+ {
+ "name": "param9",
+ "type": "Struct33"
+ },
+ {
+ "name": "param34",
+ "type": "string"
+ },
+ {
+ "name": "param35",
+ "type": "bytes"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param5",
+ "type": "bytes"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param3",
+ "type": "bool"
+ },
+ {
+ "name": "param4",
+ "type": "Struct6"
+ },
+ {
+ "name": "param7",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": {
+ "param3": false,
+ "param4": {
+ "param5": "0xa997ae99319d4d5f78001116304b85963cfd598ae95fcc739b489ed254c80862bcefb6dd5c83fed172b8"
+ },
+ "param7": "0x6a437c4aa417145b8550cb480a73690dc14b69c7"
+ },
+ "param34": "Moo é🚀🚀Mééé o 🚀 é 🚀éo MMMo Méoéo",
+ "param35": "0xed7ea3d3b80622c23d53b27611234455c18fde3d2ed4b55c99a0d1afaa6b15dc9f",
+ "param9": {
+ "param10": {
+ "param11": true
+ },
+ "param13": "Moo é🚀M ooMooé Moo🚀éMo🚀éoé🚀🚀🚀é🚀 Mo🚀 MMo",
+ "param14": {
+ "param15": "0xba4bc495f2ea2017b703f7ef1fcbbb762fd05bae",
+ "param16": "0xceb6a00304eb1d36e62a93652e03722fa1978be1a5b799a6715055006e3de8d49f47f5dea681b7c3f3e032351f494f4eebd5ecfc2ea1",
+ "param17": "0x53ceecbbeef73e6004a2a48e4b38e8c524fd820f8ac5feba048a31d2c1244c4be8f824f1146f5d882aac2ac4d0421443b56141d09e9b9fc1256c469446",
+ "param18": {
+ "param19": {
+ "param20": {
+ "param21": "0x575b70fdb462625a1e9cdbee09c61a7a9704ee2a1cbdeba468344e2f97f548158c56b0",
+ "param22": "Moo é🚀ééM éé éoooMMooM ",
+ "param23": "3630081370417832362319236809711268993163922661583325307782224246317793",
+ "param24": "7856537978551137247557348592909"
+ },
+ "param26": false,
+ "param27": "Moo é🚀🚀 ooMooo éo oM 🚀oéMM🚀oMMooéoéoMoo 🚀éMooéooo MM🚀 oo éo🚀oo ",
+ "param28": "Moo é🚀oMMéoM o"
+ }
+ }
+ },
+ "param32": true
+ }
+ },
+ "encoded": "0xf9e484b4d24731dcead8e64be7ead35857e953e16e64f5a50ed612f8605ce07d78b6a6b52e423f732676bd55ebd747cc95b670636328d911128444f847b62abd043e6379a56f021f2d7de4165f4f085e23e25ef8e536f8c2415663bfc2ef9323655ae94c06fc9d476b0d105722d4a32d1eb7a4b5529891ec029139fae945d061fcafb084efc157e2ff1daf20bdd536dd513ed329787f2f85f3c3e2c52b597d3b",
+ "digest": "0xbc43bb6f933954e8ed291b32d35556398a692421734dab354bb9401c2ecaa775"
+ },
+ {
+ "name": "random-97",
+ "domain": {
+ "verifyingContract": "0xc0b2427daf81b3b1ae287b45177cd8cb2dd7fcf0"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xa145dd9dccf1d0d72382ec1f2d82d7cd48827ec3",
+ "param3": "Moo é🚀🚀éoM ooooéo Méé M o🚀oééééMoMoéo🚀oo🚀 Mo🚀oo🚀oo o"
+ },
+ "encoded": "0x666400a396b19434e5bdf93d49163a67dd8b6e60e8df8160e510c7c1288ac5da000000000000000000000000a145dd9dccf1d0d72382ec1f2d82d7cd48827ec3d6991f578c45fb43694bc4e1cf51abc5fb10782beff88449580449e1ab8b1b09",
+ "digest": "0xce67b3dc8f8249f8ee121de29a726e1c1f4ac4b73971002fb69823d3e752b5b0"
+ },
+ {
+ "name": "random-98",
+ "domain": {
+ "verifyingContract": "0xd2489de35e4726e26c6d21423d8627a34ed723b1",
+ "salt": "0xdee197f170390ffe117985bc1b6f75d2aa76cffd744a1ed741d9e5fdef371804"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "bytes2"
+ },
+ {
+ "name": "param4",
+ "type": "bool"
+ },
+ {
+ "name": "param5",
+ "type": "bytes8"
+ }
+ ]
+ },
+ "data": {
+ "param2": true,
+ "param3": "0x2512",
+ "param4": false,
+ "param5": "0x0f8158ca29114619"
+ },
+ "encoded": "0x23b6f6f83199a6201a90b8b8b9457c300d054549f0d8c6084fc8a0b44442f7f30000000000000000000000000000000000000000000000000000000000000001251200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8158ca29114619000000000000000000000000000000000000000000000000",
+ "digest": "0xe4baa2c2a442cd32eaabe94c6db4c30460bd5ab3e50e1238cd265e7e39a5b17f"
+ },
+ {
+ "name": "random-99",
+ "domain": {
+ "name": "Moo é🚀 o ooéM🚀🚀🚀éé🚀éoé 🚀🚀oéM éMooooM ooooéo M oMMMoo🚀éooooo ",
+ "version": "44.14.34",
+ "chainId": 401
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "bytes26"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ },
+ {
+ "name": "param4",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x77c8ed30964f4ad426b83e5a079c394eeb6108670d59ea82bbef",
+ "param3": false,
+ "param4": "Moo é🚀 o oM🚀 éoMoé🚀MMooMM🚀 oo🚀🚀oo ooMoo🚀M🚀M"
+ },
+ "encoded": "0x22ff007229938669cf96193b9dcf351dadbe0c48990093a41d72b39335e9accb77c8ed30964f4ad426b83e5a079c394eeb6108670d59ea82bbef000000000000000000000000000000000000000000000000000000000000000000000000000037ed224a35fef81262bbee1f953d29657ee71ff814272f38dd451a46d46ab71f",
+ "digest": "0xdedd776daec0f194b00d73d63004c5e0883fad5072a458f61ba77635fe04b766"
+ },
+ {
+ "name": "random-100",
+ "domain": {
+ "name": "Moo é🚀M éMooo 🚀éM M 🚀oooMéo🚀MoM🚀o🚀oo🚀oéoM🚀🚀éo🚀o é 🚀🚀 MéMooéo",
+ "version": "47.45.45",
+ "chainId": 1297,
+ "salt": "0x46fd6ce92f74a7398373a2ccbcb0585fe3453b45e4a6a0a03dcab2c2dc9c9d7f"
+ },
+ "primaryType": "Struct8",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param4",
+ "type": "address"
+ },
+ {
+ "name": "param5",
+ "type": "address"
+ },
+ {
+ "name": "param6",
+ "type": "string"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param2",
+ "type": "bytes21"
+ },
+ {
+ "name": "param3",
+ "type": "Struct7"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x48cd5f1c09c5e268f1a924b1aa9d6483e7de7344da",
+ "param3": {
+ "param4": "0xee40a1c631d8f9a0ed7522896b5af8909914caa6",
+ "param5": "0xf4e494cef1caac185b2886e37a0c0df00b8ccc95",
+ "param6": "Moo é🚀🚀éoMMoMoéooMo o M🚀o"
+ }
+ },
+ "encoded": "0x8efe36edac72ec5f57c5c2283101ce2d7121dad612fdb566b4b332088a533f1048cd5f1c09c5e268f1a924b1aa9d6483e7de7344da0000000000000000000000490aa4d83fa47e2e7ec10d335cc7598977c6a4c02ac383ac4f0498c6fcf0370d",
+ "digest": "0xc757c9b58178cdd87b024fc62b56cde9056291433a95211420bfc2fd3dc67804"
+ },
+ {
+ "name": "random-101",
+ "domain": {
+ "name": "Moo é🚀🚀 🚀éMo M ooMoo🚀 ooooo🚀Mo🚀é",
+ "version": "32.48.49",
+ "chainId": 1182,
+ "salt": "0x89cb0d39315e605914b2629ef0e737a9b2a18c3393c649515dcad65464619c68"
+ },
+ "primaryType": "Struct18",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct13": [
+ {
+ "name": "param10",
+ "type": "address"
+ },
+ {
+ "name": "param11",
+ "type": "bool"
+ },
+ {
+ "name": "param12",
+ "type": "address"
+ }
+ ],
+ "Struct16": [
+ {
+ "name": "param15",
+ "type": "address"
+ }
+ ],
+ "Struct17": [
+ {
+ "name": "param4",
+ "type": "Struct8"
+ },
+ {
+ "name": "param9",
+ "type": "Struct13"
+ },
+ {
+ "name": "param14",
+ "type": "Struct16"
+ }
+ ],
+ "Struct18": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "Struct17"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param5",
+ "type": "bytes"
+ },
+ {
+ "name": "param6",
+ "type": "bytes"
+ },
+ {
+ "name": "param7",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x6dcdf91a71234de95982294b661b0be4040ab340",
+ "param3": {
+ "param14": {
+ "param15": "0x6e821dcdcc749da3ccacd453a49ba1484ca8cc05"
+ },
+ "param4": {
+ "param5": "0x8f32b8d15469bb5a8cddeb0167cd84302a4e426eb67e11405ab05aac13b295828323e287c95df22a50869d5dd7ce",
+ "param6": "0x5456f8009eb577a667fec8439a686e117fc007519326c10d2e9e55d870266cc277694e42aed00e176912b316d8a91ad20009e8abd316d63963ed4f749c8c9e",
+ "param7": "0x561026b99073b6eecdf3c4c6d47c27e2754a923f461b79c523362b936a"
+ },
+ "param9": {
+ "param10": "0xe59adaff5dc1857e78e568e4a1d128d73b117e42",
+ "param11": true,
+ "param12": "0x4eef176f86a9782d9191463852afd6dd3a1abae3"
+ }
+ }
+ },
+ "encoded": "0x3542196ee308e13b334816ef2496b2d489531edbfedf1df81b61e1d68142a6b30000000000000000000000006dcdf91a71234de95982294b661b0be4040ab340d6736ac6f05a75e17728b8ba7bdb28a31b515912dada4600176132be7e17f85f",
+ "digest": "0x06dadcc084886d4e4d42c01748794cc70125d59dfc9140a304ac4eecc93faaa5"
+ },
+ {
+ "name": "random-102",
+ "domain": {
+ "version": "5.37.45",
+ "chainId": 1112,
+ "verifyingContract": "0xad34d80f19994d30f98da4a9127394233f5d1b62"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param4",
+ "type": "bytes"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes29"
+ },
+ {
+ "name": "param3",
+ "type": "Struct5"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xa22678edf23dbbd8eaff7e09c5a6898c086e15f5b9afa1d3085ef7c551",
+ "param3": {
+ "param4": "0x3d04e4139a6340cf4e183cd5ee6b6d0f585ebad98bbe98a6934a4880a940095e66da08286166fe86feec2b680597deeb4486089095d235"
+ }
+ },
+ "encoded": "0xa8831e2b1ae12bad49bd738de2fec417a85c70cbd1582c58b1a0fa67d0db417ba22678edf23dbbd8eaff7e09c5a6898c086e15f5b9afa1d3085ef7c5510000004e3b46155fd76195aa056c321070eaf751287eb0839bf1f1f03f0b67d98a5331",
+ "digest": "0x53b91d82e450b29ebfcd9d912233db26fd277b4ea288c15a4700981b56a723da"
+ },
+ {
+ "name": "random-103",
+ "domain": {
+ "name": "Moo é🚀o M🚀 MoooMéM🚀🚀oé 🚀o🚀M🚀o éMo ",
+ "version": "34.7.4",
+ "verifyingContract": "0xffb9dcc2ad72de5d51a6523c3c59db76b5efce82",
+ "salt": "0x91a6bbeac26f0d774f89f90732838632f7848fba09dccbbbfc4dd0d0fc1a21ae"
+ },
+ "primaryType": "Struct5",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param2",
+ "type": "uint168"
+ },
+ {
+ "name": "param3",
+ "type": "bytes7"
+ },
+ {
+ "name": "param4",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "52618101586894465619352011808458733029823328733625",
+ "param3": "0xed40337a19d528",
+ "param4": "Moo é🚀oé🚀🚀éoo MM ooéééM MMoM éo MoooM 🚀oo🚀oooM🚀éoM oéMéo🚀"
+ },
+ "encoded": "0x166448b3a08b4d0577e607bbf8fa9117e476d4eebfef40d0a03af3022fc95d3c00000000000000000000002400b54743f81e79d07dbe7589e7130815622ec9b9ed40337a19d52800000000000000000000000000000000000000000000000000fcce90f9868722c814b5068c652b2374b1623dcf15ef57b3a67abfb337c9b30d",
+ "digest": "0xde37ba3588f474a46a8f87b3a97d06f80c18f5f640c2c82eee6b8d35009a2710"
+ },
+ {
+ "name": "random-104",
+ "domain": {
+ "salt": "0x1eda86bf849f89bc2e6f69245118892e38bc6e78ae6b8952228a26f52872db44"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀ooo oo🚀oMoooo🚀M🚀M🚀oMoM🚀 M oooéMM🚀o ooéé",
+ "param3": "0x734299d683c01075c7d7806cabbf"
+ },
+ "encoded": "0x4d0024736263d208aca6e84c7bb7336060a12a4693f70ea14290ed4308d052e586c6628e3abdd5327542024ebfd60ba121feeb94ad0a9fc69718ad35d60e8d7dacc5b4662798e9bfefc01e39285d731e00c77445dad6f1ce9bb875db4cd56e11",
+ "digest": "0x25bfcd9f9bf4070fa8e64500fc1f03d8b47e1d8475454f4164f235b568b61373"
+ },
+ {
+ "name": "random-105",
+ "domain": {
+ "name": "Moo é🚀ooéoM 🚀🚀 o🚀ééé é🚀éoMo",
+ "chainId": 1004,
+ "salt": "0x4bf151c92fcec680b466e8f725517067ecba2bfebd218159b4f7865020861285"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "int40[3]"
+ },
+ {
+ "name": "param5",
+ "type": "int40"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀 o 🚀oM🚀M 🚀🚀éooM🚀🚀éMoéo",
+ "param3": [
+ "242858918476",
+ "77291718371",
+ "530770037136"
+ ],
+ "param5": "263215721237"
+ },
+ "encoded": "0x47b2e0706327e941b7095dbab4500c0798ada3576db783a0499106e8538863be00db7a448333a0944bbe0ded5bee79fc3ea07f15863bc059c42eefdc8a3db436175773b0cff47dcc6167eafef357b7743e0fe0c2e5912473777f63bd463b41fa0000000000000000000000000000000000000000000000000000003d48e12b15",
+ "digest": "0x9ff750f7890c19f215900f6fe0a413c0a18a8765e974c8d73b996f78ad62c0f9"
+ },
+ {
+ "name": "random-106",
+ "domain": {
+ "verifyingContract": "0xfceb71a9ad2869c8e3dff6fa3669abc9352f783d"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀 oMooMoéMoooMo🚀éoMooM🚀M🚀oM M éMéoé🚀MoM oMM 🚀o🚀o🚀o"
+ },
+ "encoded": "0x5927d86a0ef9a01a131f7a41d2a9c89a8c82e0f454d6b4502f955f90f152eb519053df716c21aad94a049e52bc52aad715c95913062abd88cd324bdc0e09d147",
+ "digest": "0xbee1559cffdba5659309d50ed1ad306c33a388b34a1535fd5404851db7fa4ab3"
+ },
+ {
+ "name": "random-107",
+ "domain": {
+ "salt": "0x5bfb5f78bd6682c97b6f3c94bc4cf62d34110e5ad83b21b3f9432fbeaf8bcd4f"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ },
+ {
+ "name": "param4",
+ "type": "bool"
+ },
+ {
+ "name": "param5",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x26d3edf93ed79e6435ed818c07a5dd71b20c7690c3c09850f10f3155ff7e2c1b7e6d993cd4f2df0e05488c19ea16e55e14da0596492eadcd1ae2",
+ "param3": true,
+ "param4": false,
+ "param5": "Moo é🚀🚀éM 🚀🚀Mo é Méé o M🚀é"
+ },
+ "encoded": "0x89e191a0c9d59f32cab1f2423029c95a85ca34531f959e94053e40ebf4267c5f4fccd6381664502c41c49bc5cd078cffe187640d7f9304c0661bb223f9b2dcdb00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000fd174bfd259833e8efb11ee94ba88bfd1632028092b0028084e3ce4c0015cd34",
+ "digest": "0xdc19c7f5a4fb303efd1e2de89b9ca2082a6d702dc248e95764d90a109cd986ef"
+ },
+ {
+ "name": "random-108",
+ "domain": {
+ "version": "39.28.36",
+ "chainId": 631,
+ "verifyingContract": "0x9bd5ff86e47b56b27505902cc94b3d6329a1ed9f"
+ },
+ "primaryType": "Struct8",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param5",
+ "type": "address"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "string"
+ },
+ {
+ "name": "param4",
+ "type": "Struct6"
+ },
+ {
+ "name": "param7",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀o🚀 éooooM oo🚀o o",
+ "param3": "Moo é🚀 Mo",
+ "param4": {
+ "param5": "0xce4186253cc508af322c4e39cff34a1319599a15"
+ },
+ "param7": "0xd75f12aef677e43bdaa89783ee4572178e3bf2a7"
+ },
+ "encoded": "0x0cf85620ea91e290d99f71f9ee10e2d73daa1b4b71b823e2362954720b7005706d7c4cf22de5351fbb6d76b5fa30da35546a802285ffee4d2bbbbbb9b6363631f03d6b228022926635e1c91913f4f990e5091fdfb5833fa5926f70aef635fd07cbed95fc50b5e3a119bc2286b468bb71a1d3fda6d9b488e82b6f9d38eae3f1fd000000000000000000000000d75f12aef677e43bdaa89783ee4572178e3bf2a7",
+ "digest": "0xde95998c10032e5774f76f2cadc5e385237bb061d35ca1ff3e3fec1abc60b2c5"
+ },
+ {
+ "name": "random-109",
+ "domain": {
+ "name": "Moo é🚀 🚀M🚀éooé oMoé",
+ "version": "47.13.9",
+ "chainId": 1135,
+ "verifyingContract": "0xf3e8de92425a724a4b5f5f34ff462f4a21c022a6",
+ "salt": "0x92a39b51b11fe26a4b7c9b5c9dc46e4eed900408b0acdaade7ef2d2000f2180c"
+ },
+ "primaryType": "Struct7",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param3",
+ "type": "bool"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param2",
+ "type": "Struct4"
+ },
+ {
+ "name": "param5",
+ "type": "bool"
+ },
+ {
+ "name": "param6",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": {
+ "param3": false
+ },
+ "param5": true,
+ "param6": "0x2b9eb331163da92c413824164a25f6f94e6e101867847a81de73eb550e5587bcf8737d49f18648d069dbeb0a88bd48c4806a0bd22d07fe7ee7f03096ae61f1"
+ },
+ "encoded": "0x92bcc5ebbe1a24ca641c980aeedbf345d2bb96c75c6e7160a63416ce671e5ba350ba05c95cd64746bc1afc3818f62a6d56861e27a783ff9f39b0f6dc1bebd746000000000000000000000000000000000000000000000000000000000000000114e055471446e3c12424b16ad746b49bb92201f598be3c5f5c500e39cd4b420c",
+ "digest": "0x26ed036a8e9356433ec6273d9d6bc87f49faacb9b4aee0c1922ab2054032a5dd"
+ },
+ {
+ "name": "random-110",
+ "domain": {
+ "version": "33.16.36",
+ "salt": "0x685eeb5072a1173bec4979c7dfdc054601f6f80cbe7ad78f4eb43a7e1bfbf55d"
+ },
+ "primaryType": "Struct7",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct7": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "string[1]"
+ },
+ {
+ "name": "param5",
+ "type": "bytes32"
+ },
+ {
+ "name": "param6",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xa413fc1c6885bc0c48bf8084ef2521d68ee45bc1e23b79e72a7e414511",
+ "param3": [
+ "Moo é🚀🚀ooo🚀Mé🚀M 🚀é🚀é🚀éé M🚀oé🚀ooé🚀Méoé🚀Mo M MMMo🚀 "
+ ],
+ "param5": "0xa1f41b79c9af58bec8b31385ecf4c6f1418a351add6fabfeabfa2014583520e4",
+ "param6": "0xff444eb48a465c6021e011bafad0310066ac09abe890fbe1159732d8f010ca0474270fb7a911db0dfb09882fbb87c29df1f1bf87"
+ },
+ "encoded": "0x2e43045a9a14c67d9b0a9014b72f4aa002f40464467aed0285d4c0c05453173c13b6f03fd29a02d0b024351ffe30c322d189714f11a5645864b1d1ae509c2e6cfe3999130ddf7df630cb54ae95658105ce7dd2c1e39561092b26d42f71c0089fa1f41b79c9af58bec8b31385ecf4c6f1418a351add6fabfeabfa2014583520e436b28fe9e0f31ab8023143ce0634d9618d6068007d0eb02006adbb5fce6c648c",
+ "digest": "0x853e9a5edaa2da1980831dadec0754c352e34785ecf55789d599a00e28287f70"
+ },
+ {
+ "name": "random-111",
+ "domain": {
+ "verifyingContract": "0x96733f3f5e8bcff66190bf82dc5523bbc8145456"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "bytes4"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x1ba2e5ab"
+ },
+ "encoded": "0x19a687863ba581a953b0f694f34073f5005a5d39e5c94be277688507ea013a261ba2e5ab00000000000000000000000000000000000000000000000000000000",
+ "digest": "0x7f0d4714c742f29a9f2a182af25643153529da444383e342937489226f5a0a15"
+ },
+ {
+ "name": "random-112",
+ "domain": {
+ "version": "44.26.33",
+ "salt": "0x2287f7611aabf794bc8f829715f8794eb76fc9c73ba6143df65e32b231cc8e55"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes30"
+ },
+ {
+ "name": "param3",
+ "type": "int152"
+ },
+ {
+ "name": "param4",
+ "type": "address"
+ },
+ {
+ "name": "param5",
+ "type": "bytes27"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xab54e61a59de9271cf657d72cc1fed2256d52d003f3ca02ad8e407182637",
+ "param3": "-316082391023394535331711337027447687645790587",
+ "param4": "0x0af88ce740fb6aa140d5e7a7828bfb6755fd7f98",
+ "param5": "0xd0ae690c13a9cefd7fdf00cc425174f32afc2c13f94bf6fcb96c87"
+ },
+ "encoded": "0x821c71dc6eceb8c412faf525df599ffeb9b576bb83836862f7c6d2bf3817f7aeab54e61a59de9271cf657d72cc1fed2256d52d003f3ca02ad8e4071826370000fffffffffffffffffffffffffff1d38d565f73f2bb8b6566354cf4080bf37e850000000000000000000000000af88ce740fb6aa140d5e7a7828bfb6755fd7f98d0ae690c13a9cefd7fdf00cc425174f32afc2c13f94bf6fcb96c870000000000",
+ "digest": "0x2bea9c81bb7324309e6659333720bcd45837c9360578495badf83b04d2c602c7"
+ },
+ {
+ "name": "random-113",
+ "domain": {
+ "version": "40.24.13",
+ "verifyingContract": "0xc246f6e3450948c0f556d212e3129013f3bbdf3f",
+ "salt": "0x0c5313fdf2e387a82d3e2ce3eda9de53e5c65bfea57db445206b3a4532fc9d10"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "string"
+ },
+ {
+ "name": "param3",
+ "type": "int200"
+ },
+ {
+ "name": "param4",
+ "type": "bool"
+ },
+ {
+ "name": "param5",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": "Moo é🚀éé 🚀 🚀 🚀🚀é",
+ "param3": "-58887618035548045232392023063198065294192444334212910225231",
+ "param4": false,
+ "param5": true
+ },
+ "encoded": "0xa161771f2f5479ff0f53bcfbb589145f09ab64fa5e603ddd44010178ec5e3f62d5e9200f0ca4e5342abc1609bb3d7f8a1d820568d292e810a5b38eff5cf8c2f8fffffffffffffff69e6094a73803f15dc86478bdaeca4e2c460355eaee2ee8b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "digest": "0xca0aeafff982a7caa90778ef79c02370f41d7d3c118d6f0674db47aa844dcb53"
+ },
+ {
+ "name": "random-114",
+ "domain": {
+ "salt": "0x53dd66e28993d92f3726c54eebc889ee1feb5de9e6956f17916a70af94a9be8c"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "bytes23[2]"
+ },
+ {
+ "name": "param4",
+ "type": "bytes"
+ },
+ {
+ "name": "param5",
+ "type": "string"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ "0xe5efc795069c358388b3f891b191fae431455542adeab9",
+ "0x270b5f56338f2e2f812a703007e9b0efd6b563e140f758"
+ ],
+ "param4": "0x6339392fbd707f0e31c2d9069e3903c19b7d37766ae856d49d18d3d9012d313ac1803f91d08af3fd5d7534f11c6f29476ef6c7302d9f5cdb7e408ab9",
+ "param5": "Moo é🚀🚀M🚀éo🚀 oé oéé "
+ },
+ "encoded": "0xcbe088c466df5bc47ff7eb50eee07ae89b3ad92aa609d8de035f94d7e942142df1274645ab982ea41af65c3e80ee1ef7d1c848bcd352be42d34068c3d48695726d07a447e03c51b86b9c89ffe0fe4fb894f1082820e4a6ca78b0a32fa2d3ac3cffd3f56909e6332406c11c8e04dd583a0302d9e70ba15e08c78ebc314a6f3542",
+ "digest": "0xa6298b22e1312894d0867b42c22acac11b272a64e8826554eb644f019ced7080"
+ },
+ {
+ "name": "random-115",
+ "domain": {
+ "name": "Moo é🚀éM éoo🚀🚀🚀MMMM🚀",
+ "chainId": 519,
+ "verifyingContract": "0xb6a9e28479e2eefe2b652cd1035e244aa631ae8b",
+ "salt": "0x37afd12343de89e1a0d00825845be1fff4e39ee71c0047c70e39802a5c647e1c"
+ },
+ "primaryType": "Struct8",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct5": [
+ {
+ "name": "param4",
+ "type": "string"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "Struct5"
+ },
+ {
+ "name": "param6",
+ "type": "int64"
+ },
+ {
+ "name": "param7",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x1a23dd5b36e844d8ff6f162b51fe79f412ab64ecfc0a08f0701ab744dc0a",
+ "param3": {
+ "param4": "Moo é🚀o🚀é🚀🚀 🚀 oéMo"
+ },
+ "param6": "-7428993099217415080",
+ "param7": "0xebcf5f2e21ef4078d79de76bc2136de32d78b8da45785d9320293cf88f56fdbb7ed2d99971bdc91313"
+ },
+ "encoded": "0xf9efb6691f7dd1e64ca5c079b4a65046ce7e9b124f0b5a82fca4df1cef20cbf7fe19a4668dfcc60d76d18f9fdb5404410f46b99cd9c46102434bcfe4b002810aa039e88b3516312fbf1a2f8ba092aadc17e7aba94dec383eac1c3f9d30cd41cfffffffffffffffffffffffffffffffffffffffffffffffff98e6ea23025154585e3ed849708604724bc345250b999c8afbbdc5d2d7d899f6b7f0306fd22804c5",
+ "digest": "0x4c0c04f6ce70c4bbb681ef0ad6b6398acb8b7c6ed135e03749d01ac7581e6aaf"
+ },
+ {
+ "name": "random-116",
+ "domain": {
+ "name": "Moo é🚀🚀🚀🚀M 🚀o🚀Mo🚀MMM o o ooo M🚀",
+ "version": "36.49.20",
+ "salt": "0x153291d7e60f50493d9bef0386f2e52efa990e8ef60f067395b548a323336f52"
+ },
+ "primaryType": "Struct17",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct11": [
+ {
+ "name": "param9",
+ "type": "bool"
+ },
+ {
+ "name": "param10",
+ "type": "int104"
+ }
+ ],
+ "Struct12": [
+ {
+ "name": "param8",
+ "type": "Struct11"
+ }
+ ],
+ "Struct14": [
+ {
+ "name": "param6",
+ "type": "bytes12"
+ },
+ {
+ "name": "param7",
+ "type": "Struct12"
+ },
+ {
+ "name": "param13",
+ "type": "bytes27"
+ }
+ ],
+ "Struct15": [
+ {
+ "name": "param3",
+ "type": "bytes"
+ },
+ {
+ "name": "param4",
+ "type": "bytes21"
+ },
+ {
+ "name": "param5",
+ "type": "Struct14"
+ }
+ ],
+ "Struct17": [
+ {
+ "name": "param2",
+ "type": "Struct15"
+ },
+ {
+ "name": "param16",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param16": "0xce845349870b816ffa1153a0d0d74a4fd43a536acba89d7800946365a8185361b43757a6c74d0bc23c99281b20fa1f21efc8f9e70260",
+ "param2": {
+ "param3": "0x9be214b7b1e40a654367ce51d46d42eefa6aa7583582ad890407c9a7db193b4a23423edabd2ca74f7bff562e7666b14ff056f859623d",
+ "param4": "0x70b9c3d3590df445cd2a809ff3fd39d14633ed606d",
+ "param5": {
+ "param13": "0x945110dc2331d4d36e6625c582a213f159fd3785e81a1ac51adfa4",
+ "param6": "0xb74aa08d1da2d00b53573848",
+ "param7": {
+ "param8": {
+ "param10": "7382596839099108206672673364998",
+ "param9": false
+ }
+ }
+ }
+ }
+ },
+ "encoded": "0x2404a0d0da38cc2a26c0cae1fd80a615dcead8277266a934eb557d4a2a7b7616058530b4284971e4882f70ed579c18add8c7bf057fab40370e1641f4a2c1e84f26bed6a2942cc3da8e01ab975174dc95d1634c469b28a05029e7a338f26447a5",
+ "digest": "0x2859aeba18c02d3b96c7cac2c37cb1fc02efeb93bc0162e93cf849f24fc48ec0"
+ },
+ {
+ "name": "random-117",
+ "domain": {
+ "chainId": 404,
+ "salt": "0xca3833452e02a6b4fa1ac8abc4b15c96f2d7646e05ac0dc999df4c02381fdb4a"
+ },
+ "primaryType": "Struct3",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct3": [
+ {
+ "name": "param2",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xe298d05b8a6eee625460e7ffde7a4080b66181e2"
+ },
+ "encoded": "0x98edda54668461e736d24a4033f2d11540bceac48ea14c7da0fea73b8b9a55db000000000000000000000000e298d05b8a6eee625460e7ffde7a4080b66181e2",
+ "digest": "0x0e9b9a6735b599e2aa2bd15b5a6b6e35ba3f28a6a7727883d8f7b63a9bb6dfc6"
+ },
+ {
+ "name": "random-118",
+ "domain": {
+ "version": "29.19.11",
+ "chainId": 1069
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bytes19"
+ },
+ {
+ "name": "param3",
+ "type": "uint112"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0xa187410677f35e34d7d2d4a67323f45587a17a",
+ "param3": "2374623193016793084186176676934718"
+ },
+ "encoded": "0x6d5a7844c94095e64fa9ad1a945731964eeecfab4dafa5aa7d52244c21f7fabba187410677f35e34d7d2d4a67323f45587a17a000000000000000000000000000000000000000000000000000000000000007513f55b61db9e82c36d9b97b43e",
+ "digest": "0x40254d9a8b1827c010a5df5a2e776142c72a8cb6ac9dca1e4e56853db63c637b"
+ },
+ {
+ "name": "random-119",
+ "domain": {
+ "name": "Moo é🚀MéoM🚀Moé🚀éoM é ooMéMé🚀oéMMoM🚀éMo o 🚀 éé oéé🚀o M🚀o ",
+ "version": "23.47.23",
+ "chainId": 392
+ },
+ "primaryType": "Struct14",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param7",
+ "type": "bytes14[]"
+ },
+ {
+ "name": "param9",
+ "type": "string"
+ }
+ ],
+ "Struct12": [
+ {
+ "name": "param4",
+ "type": "bytes"
+ },
+ {
+ "name": "param5",
+ "type": "int200"
+ },
+ {
+ "name": "param6",
+ "type": "Struct10"
+ },
+ {
+ "name": "param11",
+ "type": "string"
+ }
+ ],
+ "Struct13": [
+ {
+ "name": "param3",
+ "type": "Struct12"
+ }
+ ],
+ "Struct14": [
+ {
+ "name": "param2",
+ "type": "Struct13"
+ }
+ ]
+ },
+ "data": {
+ "param2": {
+ "param3": {
+ "param11": "Moo é🚀é ",
+ "param4": "0x087123d5b3662f",
+ "param5": "731211289069049313617748368694424686603157878585440644275800",
+ "param6": {
+ "param7": [
+ "0xfec28eba8cdd8454e8a263553157"
+ ],
+ "param9": "Moo é🚀éo🚀MM M 🚀🚀o MM🚀o🚀éo éé🚀 oé🚀o Mooéo oooMo "
+ }
+ }
+ }
+ },
+ "encoded": "0x66a8655159b0710afca0f457c3bde2322122bdb9a1fea4237e6c302a129fa9c76a011fb94ca2e8ba68ca2390abc1167bab6b644ce5915ec5f1165b3ce7572375",
+ "digest": "0xbb821d9f1b55a93033ab1e22aff08ea2cdbae58acb7799b89ac7f9583020c16c"
+ },
+ {
+ "name": "random-120",
+ "domain": {
+ "name": "Moo é🚀é🚀é ooM oMo Mo🚀🚀ooé M🚀🚀MooMo Mé 🚀oé oo o🚀é",
+ "version": "2.8.22",
+ "verifyingContract": "0xd92defa9762b6708d9306f94e639013de8bd2b4e",
+ "salt": "0xf2b1503c65653a66bb23b43d0b646d9920e2968aea19375f3f744ab0e2d5d3df"
+ },
+ "primaryType": "Struct6",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param2",
+ "type": "string[2][1]"
+ },
+ {
+ "name": "param5",
+ "type": "bool"
+ }
+ ]
+ },
+ "data": {
+ "param2": [
+ [
+ "Moo é🚀ééoo🚀🚀 oo🚀éo oé🚀oMM🚀o Mooééé",
+ "Moo é🚀🚀ooééoM🚀"
+ ]
+ ],
+ "param5": false
+ },
+ "encoded": "0x73e644b97783bf4c80cd97dff29c383f1205915fd9399b0a95ccc9d335d190d6e3d0ef52ef1875273cf8cadc1df7b0c681dc2c124e44110285e59de2514e06680000000000000000000000000000000000000000000000000000000000000000",
+ "digest": "0x9d331f60c2e243c0c380f493df01d216381cbdfd1e8726bf2d95623b966e12d4"
+ },
+ {
+ "name": "random-122",
+ "domain": {
+ "name": "Moo é🚀🚀Mo éééoééé oéMMM oM 🚀o 🚀MoMooéoMéé oo Méé éM",
+ "version": "38.16.6",
+ "chainId": 1155
+ },
+ "primaryType": "Struct9",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param4",
+ "type": "address"
+ },
+ {
+ "name": "param5",
+ "type": "string"
+ },
+ {
+ "name": "param6",
+ "type": "address"
+ },
+ {
+ "name": "param7",
+ "type": "bytes18"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "Struct8"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x1a97d3dd8afe04195e4cf65f6642bb9abf0e30d0",
+ "param3": {
+ "param4": "0x5438b331d76c3e973291921307c08d5137bccb2f",
+ "param5": "Moo é🚀oooo 🚀oo🚀 oo éo🚀oééé🚀o oo🚀é🚀o Mo🚀éo🚀éoMéMMM🚀 MM 🚀é MM",
+ "param6": "0xa2c5910463111798e60a5dcea5d09fa3928dd865",
+ "param7": "0x38aeb5bff041e7eb1186d63e6dc85a5972fa"
+ }
+ },
+ "encoded": "0x4dc6c24fe5adc7b222933880278854e343fff0c6e3008ff0ae0acb2676515b800000000000000000000000001a97d3dd8afe04195e4cf65f6642bb9abf0e30d0031afafd11b84538ee39d9de32f0581663dde8f1b5b8413f1693cadaf1f5f383",
+ "digest": "0xcf807730a8b53a7c355704e7acd17208573fe6f07eba715f9c3eff5552130cd7"
+ },
+ {
+ "name": "random-123",
+ "domain": {
+ "name": "Moo é🚀🚀🚀oé o🚀 MM🚀 éoé🚀 🚀ooéé 🚀éo🚀 é oM🚀Moéooo MéoéoMo",
+ "verifyingContract": "0x6fb9e64197fbfffeb79e710b1786fad0adcded2a",
+ "salt": "0x50e5121d17089bc449b8a20c541511a7fdd92d31a6e6f028fccd96044f12e2eb"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": true,
+ "param3": "0xd1f004a769a4d83c51ef78ae86c9f45497820157"
+ },
+ "encoded": "0x210ade7f30d7f00dbd3bcfd9b6e33d421cb4677f314bb1d18b47c7532f4a33da0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000d1f004a769a4d83c51ef78ae86c9f45497820157",
+ "digest": "0x3607930da601b81fc487c79b4c2a6a5fd546a2ff2f80e5e45693813adf27a56d"
+ },
+ {
+ "name": "random-124",
+ "domain": {
+ "name": "Moo é🚀 🚀ooo éoéooMM oo🚀Mé🚀o🚀🚀ooo MoooM 🚀ééo🚀é éMéé o",
+ "chainId": 737,
+ "verifyingContract": "0xa67338c83e7cad895cd912fd10b293c30b93507c",
+ "salt": "0x29fec8e11edc8a14fed2ebc136bb9718842edaa9fa0661f05b23adba9bbd360c"
+ },
+ "primaryType": "Struct11",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "name": "salt",
+ "type": "bytes32"
+ }
+ ],
+ "Struct10": [
+ {
+ "name": "param8",
+ "type": "address"
+ },
+ {
+ "name": "param9",
+ "type": "string"
+ }
+ ],
+ "Struct11": [
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "Struct6"
+ },
+ {
+ "name": "param7",
+ "type": "Struct10"
+ }
+ ],
+ "Struct6": [
+ {
+ "name": "param4",
+ "type": "address"
+ },
+ {
+ "name": "param5",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x289a7fc0abbf5814916b435aedd05110f990b8a8",
+ "param3": {
+ "param4": "0xc91643ad99f82f44075c7b2c3176d9fd070b7854",
+ "param5": "0xa45759a377d7c8f1e6684c1ff727b0b33e812797"
+ },
+ "param7": {
+ "param8": "0xfb13444aafca282020cc4a4c5fa66eeee5c9a215",
+ "param9": "Moo é🚀éoo🚀 éM🚀oo o é🚀MoMooM MoM o🚀éo🚀 Méo🚀éoo🚀 é oMé o"
+ }
+ },
+ "encoded": "0xe41195b80dea8f516fb631cf6457d52b859a33fee20b1678715321d816e04f34000000000000000000000000289a7fc0abbf5814916b435aedd05110f990b8a8c975b7d342e5f9bd4cece3275d900bc4463445fe2c102fc24cdd8bdd9c741af46d6c322f4335555294c4862917e57478c76ba1b8b90655a5134f7532df97e50d",
+ "digest": "0x8d1983077b551e2dc3ff4d7c564c4eaf4d8ac90e5d66ff1f778bc642dc729582"
+ },
+ {
+ "name": "random-125",
+ "domain": {
+ "name": "Moo é🚀MMooMo Moé",
+ "version": "49.24.49",
+ "verifyingContract": "0xcf398d52a18e0a6f91a16c23bae18afd490e004a"
+ },
+ "primaryType": "Struct4",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Struct4": [
+ {
+ "name": "param2",
+ "type": "bool"
+ },
+ {
+ "name": "param3",
+ "type": "bytes"
+ }
+ ]
+ },
+ "data": {
+ "param2": false,
+ "param3": "0x40caa66524b856"
+ },
+ "encoded": "0x08b05ab3afcc030e7935ce6c66d5d4b79136f50d1f567b347bde3906d91197e80000000000000000000000000000000000000000000000000000000000000000f234b4abf550f95ad2b3e18a8327dfad72bafbc9c735d4d70db98855f86e4d3e",
+ "digest": "0x8869dd15921fcbfb0942af0803bc4a69e79254d54aecffd8d092de03241b7b29"
+ },
+ {
+ "name": "random-126",
+ "domain": {
+ "chainId": 1089
+ },
+ "primaryType": "Struct9",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "chainId",
+ "type": "uint256"
+ }
+ ],
+ "Struct9": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "uint152[1][2]"
+ },
+ {
+ "name": "param6",
+ "type": "string"
+ },
+ {
+ "name": "param7",
+ "type": "address[1]"
+ }
+ ]
+ },
+ "data": {
+ "param2": "0x3d6cac9f032d82af63c2d077790354598cd194d920dadcf9996b",
+ "param3": [
+ [
+ "2215482091649323250149612409952168968001124083"
+ ],
+ [
+ "3720428939728345178604370629051737310101916132"
+ ]
+ ],
+ "param6": "Moo é🚀o ééo🚀🚀 M🚀éo🚀🚀o🚀éé oéo🚀o🚀🚀oo éoMé🚀o 🚀éoéMM",
+ "param7": [
+ "0xc8ce8e423057eb465576542851c8ae163f44bef2"
+ ]
+ },
+ "encoded": "0xae9a402c7fe6b3d9bde74954593223cd4c7c61f3764929e780ca44432ba4edf88ebaa4befe0af4b10f9ff1d424dc9f2e501c9349db90511b8fc2ae5be855444f4c981d388229b9d3b092a114e1ab19340cd5ea397c66da5afc0bf366562778ba45cee17bca9a453477906b4710d48e03be64fbe1527a2a76f4c454afdec7e47587b1d2abb5f508f09df8e2d9dafbaa5dd87e71487b42b75e4b5a7d89feebfbc2",
+ "digest": "0xdbf3e30a06348c3a82df230158a8d3fe7be0948ba7e7e482eacdc44cae526ff9"
+ },
+ {
+ "name": "random-127",
+ "domain": {
+ "name": "Moo é🚀",
+ "version": "42.13.26"
+ },
+ "primaryType": "Struct13",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ }
+ ],
+ "Struct13": [
+ {
+ "name": "param2",
+ "type": "bytes"
+ },
+ {
+ "name": "param3",
+ "type": "Struct8"
+ },
+ {
+ "name": "param9",
+ "type": "address"
+ },
+ {
+ "name": "param10",
+ "type": "bytes[2][]"
+ }
+ ],
+ "Struct8": [
+ {
+ "name": "param4",
+ "type": "uint40"
+ },
+ {
+ "name": "param5",
+ "type": "bytes"
+ },
+ {
+ "name": "param6",
+ "type": "string[]"
+ }
+ ]
+ },
+ "data": {
+ "param10": [
+ [
+ "0xe0a9f45f1a48a64f182328",
+ "0xd18e3c88f7b41cdb54f9a02dec1f9f2138b6c4f3718241bec86692e6912e4f3bdae4e15c968065966fc4c6"
+ ]
+ ],
+ "param2": "0xeed140f7e6f2069c90466326aca3d6c3af16",
+ "param3": {
+ "param4": "934183269602",
+ "param5": "0xa941fdd7a8fe8bfed7614a3a7ce12d949025684e32ab78ab621caa",
+ "param6": []
+ },
+ "param9": "0x219b81e0367f33c3face28f7ca0f98f42a3aad3f"
+ },
+ "encoded": "0xec4d8bc63ac053b4abb7da4dcf5f9d853222e50f2cf3a7a70102a4ccf963484724c38815168dfc92aea0b45d4da4e474a0cccad6525ff2fa8584df0f4add65567a1e9576f0b9eccfba97fa5a64cec39eafe610e076674eeb749db12c47055f87000000000000000000000000219b81e0367f33c3face28f7ca0f98f42a3aad3f771f547647235bc1319baeaa2a6b4c3a394d0fee465d0d44fe7f3e6cc9cbf7d0",
+ "digest": "0x800e34308adad5c2fb5a176196e58c026d3e7e8a0485bc3f83f5f552bcf7e8aa"
+ },
+ {
+ "name": "EIP712 example",
+ "domain": {
+ "name": "Ether Mail",
+ "version": "1",
+ "chainId": 1,
+ "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
+ },
+ "primaryType": "Mail",
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Mail": [
+ {
+ "name": "from",
+ "type": "Person"
+ },
+ {
+ "name": "to",
+ "type": "Person"
+ },
+ {
+ "name": "contents",
+ "type": "string"
+ }
+ ],
+ "Person": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "wallet",
+ "type": "address"
+ }
+ ]
+ },
+ "data": {
+ "contents": "Hello, Bob!",
+ "from": {
+ "name": "Cow",
+ "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
+ },
+ "to": {
+ "name": "Bob",
+ "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
+ }
+ },
+ "encoded": "0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8",
+ "digest": "0xbe609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2"
+ }
+]
\ No newline at end of file
diff --git a/signer/core/apitypes/types.go b/signer/core/apitypes/types.go
index 72cad88ec2..2ae182279a 100644
--- a/signer/core/apitypes/types.go
+++ b/signer/core/apitypes/types.go
@@ -325,18 +325,17 @@ type Type struct {
Type string `json:"type"`
}
+// isArray returns true if the type is a fixed or variable sized array.
+// This method may return false positives, in case the Type is not a valid
+// expression, e.g. "fooo[[[[".
func (t *Type) isArray() bool {
- return strings.HasSuffix(t.Type, "[]")
+ return strings.IndexByte(t.Type, '[') > 0
}
-// typeName returns the canonical name of the type. If the type is 'Person[]', then
+// typeName returns the canonical name of the type. If the type is 'Person[]' or 'Person[2]', then
// this method returns 'Person'
func (t *Type) typeName() string {
- if strings.Contains(t.Type, "[") {
- re := regexp.MustCompile(`\[\d*\]`)
- return re.ReplaceAllString(t.Type, "")
- }
- return t.Type
+ return strings.Split(t.Type, "[")[0]
}
type Types map[string][]Type
@@ -387,7 +386,7 @@ func (typedData *TypedData) HashStruct(primaryType string, data TypedDataMessage
// Dependencies returns an array of custom types ordered by their hierarchical reference tree
func (typedData *TypedData) Dependencies(primaryType string, found []string) []string {
- primaryType = strings.TrimSuffix(primaryType, "[]")
+ primaryType = strings.Split(primaryType, "[")[0]
if slices.Contains(found, primaryType) {
return found
@@ -465,34 +464,11 @@ func (typedData *TypedData) EncodeData(primaryType string, data map[string]inter
encType := field.Type
encValue := data[field.Name]
if encType[len(encType)-1:] == "]" {
- arrayValue, err := convertDataToSlice(encValue)
+ encodedData, err := typedData.encodeArrayValue(encValue, encType, depth)
if err != nil {
- return nil, dataMismatchError(encType, encValue)
+ return nil, err
}
-
- arrayBuffer := bytes.Buffer{}
- parsedType := strings.Split(encType, "[")[0]
- for _, item := range arrayValue {
- if typedData.Types[parsedType] != nil {
- mapValue, ok := item.(map[string]interface{})
- if !ok {
- return nil, dataMismatchError(parsedType, item)
- }
- encodedData, err := typedData.EncodeData(parsedType, mapValue, depth+1)
- if err != nil {
- return nil, err
- }
- arrayBuffer.Write(crypto.Keccak256(encodedData))
- } else {
- bytesValue, err := typedData.EncodePrimitiveValue(parsedType, item, depth)
- if err != nil {
- return nil, err
- }
- arrayBuffer.Write(bytesValue)
- }
- }
-
- buffer.Write(crypto.Keccak256(arrayBuffer.Bytes()))
+ buffer.Write(encodedData)
} else if typedData.Types[field.Type] != nil {
mapValue, ok := encValue.(map[string]interface{})
if !ok {
@@ -514,6 +490,46 @@ func (typedData *TypedData) EncodeData(primaryType string, data map[string]inter
return buffer.Bytes(), nil
}
+func (typedData *TypedData) encodeArrayValue(encValue interface{}, encType string, depth int) (hexutil.Bytes, error) {
+ arrayValue, err := convertDataToSlice(encValue)
+ if err != nil {
+ return nil, dataMismatchError(encType, encValue)
+ }
+
+ arrayBuffer := new(bytes.Buffer)
+ parsedType := strings.Split(encType, "[")[0]
+ for _, item := range arrayValue {
+ if reflect.TypeOf(item).Kind() == reflect.Slice ||
+ reflect.TypeOf(item).Kind() == reflect.Array {
+ encodedData, err := typedData.encodeArrayValue(item, parsedType, depth+1)
+ if err != nil {
+ return nil, err
+ }
+ arrayBuffer.Write(encodedData)
+ } else {
+ if typedData.Types[parsedType] != nil {
+ mapValue, ok := item.(map[string]interface{})
+ if !ok {
+ return nil, dataMismatchError(parsedType, item)
+ }
+ encodedData, err := typedData.EncodeData(parsedType, mapValue, depth+1)
+ if err != nil {
+ return nil, err
+ }
+ digest := crypto.Keccak256(encodedData)
+ arrayBuffer.Write(digest)
+ } else {
+ bytesValue, err := typedData.EncodePrimitiveValue(parsedType, item, depth)
+ if err != nil {
+ return nil, err
+ }
+ arrayBuffer.Write(bytesValue)
+ }
+ }
+ }
+ return crypto.Keccak256(arrayBuffer.Bytes()), nil
+}
+
// Attempt to parse bytes in different formats: byte array, hex string, hexutil.Bytes.
func parseBytes(encType interface{}) ([]byte, bool) {
// Handle array types.
@@ -871,7 +887,8 @@ func init() {
// Checks if the primitive value is valid
func isPrimitiveTypeValid(primitiveType string) bool {
- _, ok := validPrimitiveTypes[primitiveType]
+ input := strings.Split(primitiveType, "[")[0]
+ _, ok := validPrimitiveTypes[input]
return ok
}
diff --git a/signer/core/apitypes/types_test.go b/signer/core/apitypes/types_test.go
index 7ea32f298c..22bbeba19e 100644
--- a/signer/core/apitypes/types_test.go
+++ b/signer/core/apitypes/types_test.go
@@ -31,8 +31,9 @@ func TestIsPrimitive(t *testing.T) {
t.Parallel()
// Expected positives
for i, tc := range []string{
- "int24", "int24[]", "uint88", "uint88[]", "uint", "uint[]", "int256", "int256[]",
- "uint96", "uint96[]", "int96", "int96[]", "bytes17[]", "bytes17",
+ "int24", "int24[]", "int[]", "int[2]", "uint88", "uint88[]", "uint", "uint[]", "uint[2]", "int256", "int256[]",
+ "uint96", "uint96[]", "int96", "int96[]", "bytes17[]", "bytes17", "address[2]", "bool[4]", "string[5]", "bytes[2]",
+ "bytes32", "bytes32[]", "bytes32[4]",
} {
if !isPrimitiveTypeValid(tc) {
t.Errorf("test %d: expected '%v' to be a valid primitive", i, tc)
@@ -141,3 +142,94 @@ func TestBlobTxs(t *testing.T) {
}
t.Logf("tx %v", string(data))
}
+
+func TestType_IsArray(t *testing.T) {
+ t.Parallel()
+ // Expected positives
+ for i, tc := range []Type{
+ {
+ Name: "type1",
+ Type: "int24[]",
+ },
+ {
+ Name: "type2",
+ Type: "int24[2]",
+ },
+ {
+ Name: "type3",
+ Type: "int24[2][2][2]",
+ },
+ } {
+ if !tc.isArray() {
+ t.Errorf("test %d: expected '%v' to be an array", i, tc)
+ }
+ }
+ // Expected negatives
+ for i, tc := range []Type{
+ {
+ Name: "type1",
+ Type: "int24",
+ },
+ {
+ Name: "type2",
+ Type: "uint88",
+ },
+ {
+ Name: "type3",
+ Type: "bytes32",
+ },
+ } {
+ if tc.isArray() {
+ t.Errorf("test %d: expected '%v' to not be an array", i, tc)
+ }
+ }
+}
+
+func TestType_TypeName(t *testing.T) {
+ t.Parallel()
+
+ for i, tc := range []struct {
+ Input Type
+ Expected string
+ }{
+ {
+ Input: Type{
+ Name: "type1",
+ Type: "int24[]",
+ },
+ Expected: "int24",
+ },
+ {
+ Input: Type{
+ Name: "type2",
+ Type: "int26[2][2][2]",
+ },
+ Expected: "int26",
+ },
+ {
+ Input: Type{
+ Name: "type3",
+ Type: "int24",
+ },
+ Expected: "int24",
+ },
+ {
+ Input: Type{
+ Name: "type4",
+ Type: "uint88",
+ },
+ Expected: "uint88",
+ },
+ {
+ Input: Type{
+ Name: "type5",
+ Type: "bytes32[2]",
+ },
+ Expected: "bytes32",
+ },
+ } {
+ if tc.Input.typeName() != tc.Expected {
+ t.Errorf("test %d: expected typeName value of '%v' but got '%v'", i, tc.Expected, tc.Input)
+ }
+ }
+}
diff --git a/signer/core/signed_data.go b/signer/core/signed_data.go
index f8b3c9d86d..c62b513145 100644
--- a/signer/core/signed_data.go
+++ b/signer/core/signed_data.go
@@ -294,7 +294,7 @@ func typedDataRequest(data any) (*SignDataRequest, error) {
func (api *SignerAPI) EcRecover(ctx context.Context, data hexutil.Bytes, sig hexutil.Bytes) (common.Address, error) {
// Returns the address for the Account that was used to create the signature.
//
- // Note, this function is compatible with eth_sign and personal_sign. As such it recovers
+ // Note, this function is compatible with eth_sign. As such it recovers
// the address of:
// hash = keccak256("\x19Ethereum Signed Message:\n${message length}${message}")
// addr = ecrecover(hash, signature)
diff --git a/tests/fuzzers/bls12381/bls12381_fuzz.go b/tests/fuzzers/bls12381/bls12381_fuzz.go
index 4efc749b6f..74ea6f52a7 100644
--- a/tests/fuzzers/bls12381/bls12381_fuzz.go
+++ b/tests/fuzzers/bls12381/bls12381_fuzz.go
@@ -257,8 +257,12 @@ func fuzzCrossG1MultiExp(data []byte) int {
cp.MultiExp(gnarkPoints, gnarkScalars, ecc.MultiExpConfig{})
// compare result
- if !(bytes.Equal(cp.Marshal(), g1.ToBytes(&kp))) {
- panic("G1 multi exponentiation mismatch gnark / geth ")
+ gnarkRes := cp.Marshal()
+ gethRes := g1.ToBytes(&kp)
+ if !bytes.Equal(gnarkRes, gethRes) {
+ msg := fmt.Sprintf("G1 multi exponentiation mismatch gnark/geth.\ngnark: %x\ngeth: %x\ninput: %x\n ",
+ gnarkRes, gethRes, data)
+ panic(msg)
}
return 1
@@ -283,15 +287,18 @@ func getG1Points(input io.Reader) (*bls12381.PointG1, *gnark.G1Affine, *blst.P1A
if err != nil {
panic(fmt.Sprintf("Could not marshal gnark.G1 -> geth.G1: %v", err))
}
- if !bytes.Equal(g1.ToBytes(kp), cpBytes) {
- panic("bytes(gnark.G1) != bytes(geth.G1)")
+
+ gnarkRes := g1.ToBytes(kp)
+ if !bytes.Equal(gnarkRes, cpBytes) {
+ panic(fmt.Sprintf("bytes(gnark.G1) != bytes(geth.G1)\ngnark.G1: %x\ngeth.G1: %x\n", gnarkRes, cpBytes))
}
// marshal gnark point -> blst point
scalar := new(blst.Scalar).FromBEndian(common.LeftPadBytes(s.Bytes(), 32))
p1 := new(blst.P1Affine).From(scalar)
- if !bytes.Equal(p1.Serialize(), cpBytes) {
- panic("bytes(blst.G1) != bytes(geth.G1)")
+ blstRes := p1.Serialize()
+ if !bytes.Equal(blstRes, cpBytes) {
+ panic(fmt.Sprintf("bytes(blst.G1) != bytes(geth.G1)\nblst.G1: %x\ngeth.G1: %x\n", blstRes, cpBytes))
}
return kp, cp, p1, nil
@@ -316,8 +323,10 @@ func getG2Points(input io.Reader) (*bls12381.PointG2, *gnark.G2Affine, *blst.P2A
if err != nil {
panic(fmt.Sprintf("Could not marshal gnark.G2 -> geth.G2: %v", err))
}
- if !bytes.Equal(g2.ToBytes(kp), cpBytes) {
- panic("bytes(gnark.G2) != bytes(geth.G2)")
+
+ gnarkRes := g2.ToBytes(kp)
+ if !bytes.Equal(gnarkRes, cpBytes) {
+ panic(fmt.Sprintf("bytes(gnark.G2) != bytes(geth.G2)\ngnark.G2: %x\ngeth.G2: %x\n", gnarkRes, cpBytes))
}
// marshal gnark point -> blst point
diff --git a/tests/state_test_util.go b/tests/state_test_util.go
index e9a58694ed..af2cb63d94 100644
--- a/tests/state_test_util.go
+++ b/tests/state_test_util.go
@@ -196,7 +196,7 @@ func (t *StateTest) checkError(subtest StateSubtest, err error) error {
// Run executes a specific subtest and verifies the post-state and logs
func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string, postCheck func(err error, st *StateTestState)) (result error) {
- st, root, err := t.RunNoVerify(subtest, vmconfig, snapshotter, scheme)
+ st, root, _, err := t.RunNoVerify(subtest, vmconfig, snapshotter, scheme)
// Invoke the callback at the end of function for further analysis.
defer func() {
postCheck(result, &st)
@@ -228,10 +228,10 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bo
// RunNoVerify runs a specific subtest and returns the statedb and post-state root.
// Remember to call state.Close after verifying the test result!
-func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string) (st StateTestState, root common.Hash, err error) {
+func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string) (st StateTestState, root common.Hash, gasUsed uint64, err error) {
config, eips, err := GetChainConfig(subtest.Fork)
if err != nil {
- return st, common.Hash{}, UnsupportedForkError{subtest.Fork}
+ return st, common.Hash{}, 0, UnsupportedForkError{subtest.Fork}
}
vmconfig.ExtraEips = eips
@@ -250,7 +250,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
post := t.json.Post[subtest.Fork][subtest.Index]
msg, err := t.json.Tx.toMessage(post, baseFee)
if err != nil {
- return st, common.Hash{}, err
+ return st, common.Hash{}, 0, err
}
{ // Blob transactions may be present after the Cancun fork.
@@ -260,7 +260,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
// Here, we just do this shortcut smaller fix, since state tests do not
// utilize those codepaths
if len(msg.BlobHashes)*params.BlobTxBlobGasPerBlob > params.MaxBlobGasPerBlock {
- return st, common.Hash{}, errors.New("blob gas exceeds maximum")
+ return st, common.Hash{}, 0, errors.New("blob gas exceeds maximum")
}
}
@@ -269,10 +269,10 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
var ttx types.Transaction
err := ttx.UnmarshalBinary(post.TxBytes)
if err != nil {
- return st, common.Hash{}, err
+ return st, common.Hash{}, 0, err
}
if _, err := types.Sender(types.LatestSigner(config), &ttx); err != nil {
- return st, common.Hash{}, err
+ return st, common.Hash{}, 0, err
}
}
@@ -308,6 +308,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
if tracer := evm.Config.Tracer; tracer != nil && tracer.OnTxEnd != nil {
evm.Config.Tracer.OnTxEnd(nil, err)
}
+ return st, common.Hash{}, 0, err
}
// Add 0-value mining reward. This only makes a difference in the cases
// where
@@ -322,7 +323,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
receipt := &types.Receipt{GasUsed: vmRet.UsedGas}
tracer.OnTxEnd(receipt, nil)
}
- return st, root, err
+ return st, root, vmRet.UsedGas, nil
}
func (t *StateTest) gasLimit(subtest StateSubtest) uint64 {
diff --git a/trie/trie_test.go b/trie/trie_test.go
index 9b2530bdd4..423ed30fe8 100644
--- a/trie/trie_test.go
+++ b/trie/trie_test.go
@@ -819,6 +819,7 @@ type spongeDb struct {
func (s *spongeDb) Has(key []byte) (bool, error) { panic("implement me") }
func (s *spongeDb) Get(key []byte) ([]byte, error) { return nil, errors.New("no such elem") }
func (s *spongeDb) Delete(key []byte) error { panic("implement me") }
+func (s *spongeDb) DeleteRange(start, end []byte) error { panic("implement me") }
func (s *spongeDb) NewBatch() ethdb.Batch { return &spongeBatch{s} }
func (s *spongeDb) NewBatchWithSize(size int) ethdb.Batch { return &spongeBatch{s} }
func (s *spongeDb) Stat() (string, error) { panic("implement me") }
diff --git a/trie/trienode/proof.go b/trie/trienode/proof.go
index d3075ecccf..01a07c05b0 100644
--- a/trie/trienode/proof.go
+++ b/trie/trienode/proof.go
@@ -69,6 +69,10 @@ func (db *ProofSet) Delete(key []byte) error {
return nil
}
+func (db *ProofSet) DeleteRange(start, end []byte) error {
+ panic("not supported")
+}
+
// Get returns a stored node
func (db *ProofSet) Get(key []byte) ([]byte, error) {
db.lock.RLock()
diff --git a/trie/utils/verkle.go b/trie/utils/verkle.go
index 12e02de9a4..4294f5e4be 100644
--- a/trie/utils/verkle.go
+++ b/trie/utils/verkle.go
@@ -156,10 +156,6 @@ func GetTreeKey(address []byte, treeIndex *uint256.Int, subIndex byte) []byte {
func GetTreeKeyWithEvaluatedAddress(evaluated *verkle.Point, treeIndex *uint256.Int, subIndex byte) []byte {
var poly [5]fr.Element
- poly[0].SetZero()
- poly[1].SetZero()
- poly[2].SetZero()
-
// little-endian, 32-byte aligned treeIndex
var index [32]byte
for i := 0; i < len(treeIndex); i++ {
@@ -204,10 +200,10 @@ func CodeChunkKey(address []byte, chunk *uint256.Int) []byte {
return GetTreeKey(address, treeIndex, subIndex)
}
-func StorageIndex(bytes []byte) (*uint256.Int, byte) {
+func StorageIndex(storageKey []byte) (*uint256.Int, byte) {
// If the storage slot is in the header, we need to add the header offset.
var key uint256.Int
- key.SetBytes(bytes)
+ key.SetBytes(storageKey)
if key.Cmp(codeStorageDelta) < 0 {
// This addition is always safe; it can't ever overflow since pos