From 6c6bf6fe64ff422b97c1e5011fe5e9d33988937c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Fri, 25 Oct 2024 13:20:18 +0200 Subject: [PATCH 01/42] beacon/blsync: add holesky config and update checkpoints (#30671) This PR adds the beacon chain config for the holesky testnet. It also updates beacon checkpoints for Mainnet and Sepolia. --- beacon/blsync/config.go | 21 ++++++++++++++++++--- cmd/blsync/main.go | 1 + 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/beacon/blsync/config.go b/beacon/blsync/config.go index efc44b47d1..828c14f898 100644 --- a/beacon/blsync/config.go +++ b/beacon/blsync/config.go @@ -41,7 +41,7 @@ var ( 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"), + Checkpoint: common.HexToHash("0x6509b691f4de4f7b083f2784938fd52f0e131675432b3fd85ea549af9aebd3d0"), } SepoliaConfig = lightClientConfig{ @@ -54,19 +54,34 @@ var ( 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"), + Checkpoint: common.HexToHash("0x456e85f5608afab3465a0580bff8572255f6d97af0c5f939e3f7536b5edb2d3f"), + } + + HoleskyConfig = lightClientConfig{ + ChainConfig: (&types.ChainConfig{ + GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"), + GenesisTime: 1695902400, + }). + 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}), + Checkpoint: common.HexToHash("0x6456a1317f54d4b4f2cb5bc9d153b5af0988fe767ef0609f0236cf29030bcff7"), } ) func makeChainConfig(ctx *cli.Context) lightClientConfig { var config lightClientConfig customConfig := ctx.IsSet(utils.BeaconConfigFlag.Name) - utils.CheckExclusive(ctx, utils.MainnetFlag, utils.SepoliaFlag, utils.BeaconConfigFlag) + utils.CheckExclusive(ctx, utils.MainnetFlag, utils.SepoliaFlag, utils.HoleskyFlag, utils.BeaconConfigFlag) switch { case ctx.Bool(utils.MainnetFlag.Name): config = MainnetConfig case ctx.Bool(utils.SepoliaFlag.Name): config = SepoliaConfig + case ctx.Bool(utils.HoleskyFlag.Name): + config = HoleskyConfig default: if !customConfig { config = MainnetConfig diff --git a/cmd/blsync/main.go b/cmd/blsync/main.go index f9b8575edf..586f1b79cf 100644 --- a/cmd/blsync/main.go +++ b/cmd/blsync/main.go @@ -45,6 +45,7 @@ func main() { //TODO datadir for optional permanent database utils.MainnetFlag, utils.SepoliaFlag, + utils.HoleskyFlag, utils.BlsyncApiFlag, utils.BlsyncJWTSecretFlag, }, From 80bdab757dfb0f6d73fb869d834979536fe474e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Fri, 25 Oct 2024 17:33:46 +0200 Subject: [PATCH 02/42] ethdb: add DeleteRange feature (#30668) This PR adds `DeleteRange` to `ethdb.KeyValueWriter`. While range deletion using an iterator can be really slow, `DeleteRange` is natively supported by pebble and apparently runs in O(1) time (typically 20-30ms in my tests for removing hundreds of millions of keys and gigabytes of data). For leveldb and memorydb an iterator based fallback is implemented. Note that since the iterator method can be slow and a database function should not unexpectedly block for a very long time, the number of deleted keys is limited at 10000 which should ensure that it does not block for more than a second. ErrTooManyKeys is returned if the range has only been partially deleted. In this case the caller can repeat the call until it finally succeeds. --- core/rawdb/table.go | 6 +++ ethdb/database.go | 9 +++++ ethdb/dbtest/testsuite.go | 82 ++++++++++++++++++++++++++++++++++++++ ethdb/leveldb/leveldb.go | 31 ++++++++++++++ ethdb/memorydb/memorydb.go | 15 +++++++ ethdb/pebble/pebble.go | 13 +++++- ethdb/remotedb/remotedb.go | 4 ++ trie/trie_test.go | 1 + trie/trienode/proof.go | 4 ++ 9 files changed, 164 insertions(+), 1 deletion(-) 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/ethdb/database.go b/ethdb/database.go index c6e76fd2fe..9bf4427293 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 @@ -158,6 +166,7 @@ type Reader interface { // immutable ancient data. type Writer interface { KeyValueWriter + KeyValueRangeDeleter AncientWriter } 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/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() From c3919f9bda9dd14cf4216109c4d1c3adacb804dd Mon Sep 17 00:00:00 2001 From: jwasinger Date: Mon, 28 Oct 2024 18:26:36 +0900 Subject: [PATCH 03/42] build: document doGoModTidy function in ci.go (#30685) --- build/ci.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/ci.go b/build/ci.go index 1765d750c2..d47e378811 100644 --- a/build/ci.go +++ b/build/ci.go @@ -409,6 +409,8 @@ func compareHashedFilesets(preHashes map[string][32]byte, postHashes map[string] return updates } +// doGoModTidy runs 'go mod tidy' and asserts that go.sum/go.mod do not change +// as a result. func doGoModTidy() { targetFiles := []string{"go.mod", "go.sum"} preHashes, err := hashSourceFiles(targetFiles) From bce420b99fd8b5a7a35a9f38b5246f8e2219acbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 28 Oct 2024 22:29:25 +0200 Subject: [PATCH 04/42] cmd/geth: avoid hard coding the IPC name (#30687) --- cmd/geth/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 8282c80c41..a7f894ab37 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -132,7 +132,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 } From 98056e1ef286d247f2d6107b8db4933dca9064b5 Mon Sep 17 00:00:00 2001 From: Delweng Date: Tue, 29 Oct 2024 14:35:06 +0800 Subject: [PATCH 05/42] eth/tracers: add disableCode/Storage options for prestateTracer (#30648) When using the prestateTracer, in some cases users are only concerned with balances or nonce information, and are not interested in the lengthy contract code or storage data. Therefore, this PR introduces two new configuration options in the `prestateTracerConfig` structure: - `disableCode` - `disableStorage` These options allow users to control whether the tracer returns contract code and storage data during execution tracing. By setting these options, users can more flexibly customize their needs and focus on obtaining information that is more critical and relevant to their specific use cases. These options work with the default mode as well as `diffMode: true`. --------- Signed-off-by: jsvisa Co-authored-by: Sina M <1591639+s1na@users.noreply.github.com> --- .../prestate_tracer/disable_code.json | 83 ++++++ .../disable_code_and_storage.json | 78 ++++++ .../prestate_tracer/disable_storage.json | 78 ++++++ .../create_disable_code.json | 100 +++++++ .../create_disable_storage.json | 81 ++++++ ...inner_create_disable_code_and_storage.json | 256 ++++++++++++++++++ .../simple_disable_code_and_storage.json | 101 +++++++ eth/tracers/native/prestate.go | 53 ++-- 8 files changed, 811 insertions(+), 19 deletions(-) create mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json create mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json create mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json create mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_code.json create mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_storage.json create mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create_disable_code_and_storage.json create mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json 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/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 } From 7180d2653068e8a43d776ecb6fdd629facd44f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 29 Oct 2024 10:31:04 +0200 Subject: [PATCH 06/42] core, eth, node: break rawdb -> {leveldb, pebble} dependency (#30689) --- core/bench_test.go | 26 +++-- core/blockchain_repair_test.go | 45 ++++---- core/blockchain_sethead_test.go | 12 +- core/blockchain_snapshot_test.go | 23 ++-- core/blockchain_test.go | 46 ++------ core/rawdb/database.go | 101 +---------------- eth/filters/bench_test.go | 189 ------------------------------- eth/filters/filter_test.go | 2 +- node/database.go | 111 ++++++++++++++++++ node/node.go | 6 +- 10 files changed, 184 insertions(+), 377 deletions(-) delete mode 100644 eth/filters/bench_test.go create mode 100644 node/database.go diff --git a/core/bench_test.go b/core/bench_test.go index 639d36e9ae..d0305e268a 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" ) @@ -173,18 +174,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{ @@ -281,11 +280,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 +293,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 +309,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/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/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/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..e23425dfbd 100644 --- a/node/node.go +++ b/node/node.go @@ -723,7 +723,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 +732,6 @@ func (n *Node) OpenDatabase(name string, cache, handles int, namespace string, r ReadOnly: readonly, }) } - if err == nil { db = n.wrapDatabase(db) } @@ -755,7 +754,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 +764,6 @@ func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, ancient ReadOnly: readonly, }) } - if err == nil { db = n.wrapDatabase(db) } From 236147bf70a9e52eaba748bdfe61bb600db4dcac Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 29 Oct 2024 09:32:40 +0100 Subject: [PATCH 07/42] ethdb: refactor Database interface (#30693) --- core/rawdb/accessors_indexes_test.go | 8 ++++---- core/rawdb/freezer.go | 11 +++++++++-- core/rawdb/freezer_memory.go | 6 ++++++ core/rawdb/freezer_resettable.go | 8 ++++++++ ethdb/database.go | 25 +++---------------------- 5 files changed, 30 insertions(+), 28 deletions(-) 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/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/ethdb/database.go b/ethdb/database.go index 9bf4427293..323f8f5d6f 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -162,26 +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 - KeyValueRangeDeleter - 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 } @@ -196,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 } From 8c73523812d3a4945bf9d9b7fea24785cfb441b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 29 Oct 2024 13:21:17 +0200 Subject: [PATCH 08/42] appveyor, build, internal: ci.go cleanups, add package dep checker (#30696) --- appveyor.yml | 4 +- build/ci.go | 188 +++++++++++++++++------------------------ internal/build/file.go | 76 ++++++++++++++++- 3 files changed, 156 insertions(+), 112 deletions(-) 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/build/ci.go b/build/ci.go index d47e378811..680bdc9a9c 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,11 +44,9 @@ package main import ( "bytes" - "crypto/sha256" "encoding/base64" "flag" "fmt" - "io" "log" "os" "os/exec" @@ -156,6 +159,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 +177,6 @@ func main() { doPurge(os.Args[2:]) case "sanitycheck": doSanityCheck() - case "generate": - doGenerate() default: log.Fatal("unknown command ", os.Args[1]) } @@ -348,130 +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 -} - -// doGoModTidy runs 'go mod tidy' and asserts that go.sum/go.mod do not change -// as a result. -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. @@ -488,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/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 +} From 87465e98f9dcd33a07595b65857d50a1551681a6 Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Wed, 30 Oct 2024 22:22:10 +0800 Subject: [PATCH 09/42] beacon/light: remove unused CommitteeChain.signerThreshold (#30484) This field is a duplicate of UpdateScore.SignerCount and never referenced. --- beacon/light/committee_chain.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/beacon/light/committee_chain.go b/beacon/light/committee_chain.go index a8d032bb65..778cd3028f 100644 --- a/beacon/light/committee_chain.go +++ b/beacon/light/committee_chain.go @@ -77,7 +77,6 @@ type CommitteeChain struct { sigVerifier committeeSigVerifier // BLS sig verifier (dummy verifier in tests) config *types.ChainConfig - signerThreshold int minimumUpdateScore types.UpdateScore enforceTime bool // enforceTime specifies whether the age of a signed header should be checked } @@ -96,14 +95,13 @@ func NewTestCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, si // 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 { 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, From 25bc07749ce21376e1023a6e16ec173fa3fc4e43 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Wed, 30 Oct 2024 18:01:47 +0100 Subject: [PATCH 10/42] core/vm: speed up push and interpreter loop (#30662) Looking at the cpu profile of a burntpix benchmark, I noticed that a lot of time was spent in gas-used, in the interpreter loop. It's an actual call (not inlined), which explicitly wants to be ignored by tracing ("tracing.GasChangeIgnored"), so it can be safely and simply inlined. The other change is in `pushX`. These also do a call to `common.RightPadBytes`. I replaced that by a doing a corresponding `Lsh` on the `u256` if needed. Note: it's needed only to make the stack output look right, for fuzzers. It technically doesn't matter what we put there: if code ends on a pushdata immediate, nothing will consume the stack element. We could just as well just ignore it, if we didn't care about fuzzers (which I do). Seems quite a lot faster on burntpix, according to my runs. This PR: ``` EVM gas used: 5642735088 execution time: 34.84609475s allocations: 915683 allocated bytes: 175334088 ``` ``` EVM gas used: 5642735088 execution time: 36.671958278s allocations: 915701 allocated bytes: 175340528 ``` Master ``` EVM gas used: 5642735088 execution time: 49.349209526s allocations: 915684 allocated bytes: 175333368 ``` ``` EVM gas used: 5642735088 execution time: 46.581006598s allocations: 915681 allocated bytes: 175330728 ``` --------- Co-authored-by: Sina M <1591639+s1na@users.noreply.github.com> Co-authored-by: Felix Lange --- core/vm/instructions.go | 12 +++--- core/vm/instructions_test.go | 72 +++++++++++++++++++++++++++++++++ core/vm/interpreter.go | 10 ++++- core/vm/runtime/runtime_test.go | 12 ++++++ 4 files changed, 98 insertions(+), 8 deletions(-) diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 0e2fd52b14..427eb3bab5 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -984,13 +984,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_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) From 9afb18dd6ffafaa8c0bcf88287b8f6ec58e67f03 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Thu, 31 Oct 2024 04:19:01 -0600 Subject: [PATCH 11/42] core: add code to witness when state object is accessed (#30698) I think the core code should generally be agnostic about the witness and the statedb layer should determine what elements need to be included in the witness. Because code is accessed via `GetCode`, and `GetCodeLength`, the statedb will always know when it needs to add that code into the witness. The edge case is block hashes, so we continue to add them manually in the implementation of `BLOCKHASH`. It probably makes sense to refactor statedb so we have a wrapped implementation that accumulates the witness, but this is a simpler change that makes #30078 less aggressive. --- core/state/statedb.go | 6 ++++++ core/vm/evm.go | 12 ------------ core/vm/instructions.go | 7 ------- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index 0183c14480..775a224af9 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 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 427eb3bab5..47eb62be08 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) From 5230b06d5151e214e80762eebed9196a670c52b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 31 Oct 2024 17:03:47 +0200 Subject: [PATCH 12/42] cmd/utils, eth/ethconfig: remove some ancient leftover flag (#30705) This is a flag leftover from the swarm era. No need to deprecate it, it's been useless/dead forever now. --- cmd/utils/flags.go | 9 --------- eth/ethconfig/config.go | 3 --- eth/ethconfig/gen_config.go | 6 ------ 3 files changed, 18 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e98d5cc8e3..be8aa34140 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -176,12 +176,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", @@ -1755,9 +1749,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) 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 } From 20bf543a64d7c2a590b18a1e1d907cae65707013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 31 Oct 2024 19:26:02 +0200 Subject: [PATCH 13/42] internal/flags: remove Merge, it's identical to slices.Concat (#30706) This is a noop change to not have custom code for stdlib functionality. --- cmd/blsync/main.go | 3 ++- cmd/devp2p/discv4cmd.go | 6 +++--- cmd/devp2p/discv5cmd.go | 4 ++-- cmd/evm/main.go | 3 ++- cmd/evm/runner.go | 3 ++- cmd/geth/chaincmd.go | 16 ++++++++-------- cmd/geth/config.go | 3 ++- cmd/geth/consolecmd.go | 8 ++++---- cmd/geth/dbcmd.go | 30 +++++++++++++++--------------- cmd/geth/main.go | 5 +++-- cmd/geth/snapshot.go | 16 ++++++++-------- cmd/geth/verkle.go | 6 +++--- internal/flags/helpers.go | 9 --------- 13 files changed, 54 insertions(+), 58 deletions(-) diff --git a/cmd/blsync/main.go b/cmd/blsync/main.go index 586f1b79cf..6a35e9d16a 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, 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..3f82deaf70 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 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 a7f894ab37..842c1c2347 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).`, } 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..7999b3baeb 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, @@ -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/internal/flags/helpers.go b/internal/flags/helpers.go index 32be3d11a7..0fd37151eb 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 From a1d049c1c4b8986a975b7d8492764701503f9ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 31 Oct 2024 20:52:39 +0200 Subject: [PATCH 14/42] internal/flags: remove low-use type TextMarshalerFlag (#30707) Currently we have a custom TextMarshalerFlag. It's a nice idea, allowing anything implementing text marshaller to be used as a flag. That said, we only ever used it in one place because it's not that obvious how to use and it needs some boilerplate on the type itself too, apart of the heavy boilerplate got the custom flag. All in all there's no *need* to drop this feature just now, but while porting the cmds over to cli @v3, all other custom flags worker perfectly, whereas this one started crashing deep inside the cli package. The flag handling in v3 got rebuild on generics and there are a number of new methods needed; and my guess is that maybe one of them doesn't work like this flag currently is designed too. We could definitely try and redesign this flag for cli v3... but all that effort and boilerplate just to use it for 1 flag in 1 location, seems not worth it. So for now I'm suggesting removing it and maybe reconsider a similar feature in cli v3 with however it will work. --- cmd/utils/flags.go | 11 ++-- internal/flags/flags.go | 114 -------------------------------------- internal/flags/helpers.go | 3 - 3 files changed, 6 insertions(+), 122 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index be8aa34140..7a4effdf1a 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -211,8 +211,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, @@ -244,10 +243,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{ @@ -1669,7 +1668,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) 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 0fd37151eb..fd706869f1 100644 --- a/internal/flags/helpers.go +++ b/internal/flags/helpers.go @@ -256,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) } From f3b4bbbaf3db60d0f7f1163cca4aad5cf41ff499 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Thu, 31 Oct 2024 19:53:35 +0100 Subject: [PATCH 15/42] all: remove `personal` RPC namespace (#30704) This PR is a first step towards removing account management from geth, and contains a lot of the user-facing changes. With this PR, the `personal` namespace disappears. **Note**: `personal` namespace has been deprecated for quite some time (since https://github.com/ethereum/go-ethereum/pull/26390 1 year and 8 months ago), and users who have wanted to use it has been forced to used the flag `--rpc.enabledeprecatedpersonal`. So I think it's fairly non-controversial to drop it at this point. Specifically, this means: - Account/wallet listing -`personal.getListAccounts` -`personal.listAccounts` -`personal.getListWallets` -`personal.listWallets` - Lock/unlock -`personal.lockAccount` -`personal.openWallet` -`personal.unlockAccount` - Sign ops -`personal.sign` -`personal.sendTransaction` -`personal.signTransaction` - Imports / inits -`personal.deriveAccount` -`personal.importRawKey` -`personal.initializeWallet` -`personal.newAccount` -`personal.unpair` - Other: -`personal.ecRecover` The underlying keystores and account managent code is still in place, which means that `geth --dev` still works as expected, so that e.g. the example below still works: ``` > eth.sendTransaction({data:"0x6060", value: 1, from:eth.accounts[0]}) ``` Also, `ethkey` and `clef` are untouched. With the removal of `personal`, as far as I know we have no more API methods which contain credentials, and if we want to implement logging-capabilities of RPC ingress payload, it would be possible after this. --------- Co-authored-by: Felix Lange --- cmd/geth/main.go | 2 +- cmd/utils/flags.go | 8 +- cmd/utils/flags_legacy.go | 6 + console/bridge.go | 265 ---------------------------- console/bridge_test.go | 48 ----- console/console.go | 25 --- go.mod | 1 - go.sum | 2 - internal/ethapi/api.go | 341 ------------------------------------ internal/ethapi/backend.go | 3 - internal/web3ext/web3ext.go | 75 +------- node/node.go | 16 +- signer/core/signed_data.go | 2 +- 13 files changed, 20 insertions(+), 774 deletions(-) delete mode 100644 console/bridge_test.go diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 7999b3baeb..10d4052737 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -67,7 +67,7 @@ var ( utils.SmartCardDaemonPathFlag, utils.OverrideCancun, utils.OverrideVerkle, - utils.EnablePersonal, + utils.EnablePersonal, // deprecated utils.TxPoolLocalsFlag, utils.TxPoolNoLocalsFlag, utils.TxPoolJournalFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 7a4effdf1a..f083a25f90 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -734,11 +734,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{ @@ -1392,9 +1387,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) { 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/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/bridge_test.go b/console/bridge_test.go deleted file mode 100644 index e57e294fc5..0000000000 --- a/console/bridge_test.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2020 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 console - -import ( - "testing" - - "github.com/dop251/goja" - "github.com/ethereum/go-ethereum/internal/jsre" -) - -// 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()} - - 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) -} 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/go.mod b/go.mod index fc469f3e93..9c68c95034 100644 --- a/go.mod +++ b/go.mod @@ -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..720acb1caa 100644 --- a/go.sum +++ b/go.sum @@ -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/ethapi/api.go b/internal/ethapi/api.go index 10d79c85ae..bea615bf44 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 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/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/node/node.go b/node/node.go index e23425dfbd..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 } } 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) From a1093d98eb3260f2abf340903c2d968b2b891c11 Mon Sep 17 00:00:00 2001 From: Delweng Date: Fri, 1 Nov 2024 16:51:06 +0800 Subject: [PATCH 16/42] eth/tracers: flatCallTracer error compatible with parity (#30497) Compatible error message in the flat call tracer with parity-style endpoints. Signed-off-by: jsvisa --- .../callcode_precompiled_fail_hide.json | 3 +- .../callcode_precompiled_oog.json | 9 +- .../callcode_precompiled_throw.json | 9 +- .../call_tracer_flat/create_oog_parity.json | 92 +++++++++++++++++++ .../testdata/call_tracer_flat/gas.json | 3 +- .../call_tracer_flat/nested_create.json | 3 +- .../nested_create2_action_gas.json | 3 +- .../nested_create_action_gas.json | 3 +- .../nested_create_inerror.json | 5 +- .../call_tracer_flat/result_output.json | 9 +- .../call_tracer_flat/selfdestruct.json | 9 +- .../skip_no_balance_error.json | 5 +- eth/tracers/native/call_flat.go | 2 + 13 files changed, 115 insertions(+), 40 deletions(-) create mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/create_oog_parity.json 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..a3b9b6a667 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 @@ -66,8 +66,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..dd31abed07 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 @@ -66,8 +66,7 @@ "transactionPosition": 141, "transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1", "blockNumber": 1555278, - "blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b", - "time": "300.9µs" + "blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b" }, { "type": "call", @@ -80,9 +79,7 @@ "callType": "callcode" }, "error": "out of gas", - "traceAddress": [ - 0 - ], + "traceAddress": [0], "subtraces": 0, "transactionPosition": 141, "transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1", @@ -90,4 +87,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..62e3f6c7d6 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 @@ -62,8 +62,7 @@ "transactionPosition": 117, "transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9", "blockNumber": 1555275, - "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd", - "time": "332.877µs" + "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd" }, { "type": "call", @@ -76,9 +75,7 @@ "callType": "callcode" }, "error": "invalid input length", - "traceAddress": [ - 0 - ], + "traceAddress": [0], "subtraces": 0, "transactionPosition": 117, "transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9", @@ -86,4 +83,4 @@ "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd" } ] -} \ No newline at end of file +} 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..acaa43cefd --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create_oog_parity.json @@ -0,0 +1,92 @@ +{ + "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" + }, + "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" + }, + "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..7e40f06723 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json @@ -66,8 +66,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/nested_create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json index 7dc6cc8098..ecdcbfb9df 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 @@ -66,8 +66,7 @@ "transactionPosition": 23, "transactionHash": "0xe267552ce8437a5bc7081385c99f912de5723ad34b958db215dbc41abd5f6c03", "blockNumber": 555462, - "blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1", - "time": "1.147715ms" + "blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1" }, { "type": "create", 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..6b7a20a090 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 @@ -66,8 +66,7 @@ "transactionPosition": 31, "transactionHash": "0x1257b698c5833c54ce786734087002b097275abc3877af082b5c2a538e894a41", "blockNumber": 1555161, - "blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171", - "time": "889.048µs" + "blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171" }, { "type": "create", 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..5245e62074 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 @@ -62,8 +62,7 @@ "transactionPosition": 63, "transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650", "blockNumber": 1555170, - "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e", - "time": "952.736µs" + "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e" }, { "type": "create", 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..0fe4bcb4f2 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,8 +73,7 @@ "transactionPosition": 26, "transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4", "blockNumber": 839247, - "blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c", - "time": "182.267µs" + "blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c" }, { "action": { @@ -90,4 +89,4 @@ "type": "create" } ] -} \ No newline at end of file +} 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..df8ecb7309 100644 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json +++ b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json @@ -66,8 +66,7 @@ "transactionPosition": 14, "transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79", "blockNumber": 1555146, - "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e", - "time": "187.145µs" + "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e" }, { "action": { @@ -90,9 +89,7 @@ "balance": "0x0" }, "result": null, - "traceAddress": [ - 1 - ], + "traceAddress": [1], "subtraces": 0, "transactionPosition": 14, "transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79", @@ -100,4 +97,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..17884fc3b6 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 @@ -62,8 +62,7 @@ "transactionPosition": 16, "transactionHash": "0x384487e5ae8d2997aece8e28403d393cb9752425e6de358891bed981c5af1c05", "blockNumber": 1555285, - "blockHash": "0x93231d8e9662adb4c5c703583a92c7b3112cd5448f43ab4fa1f0f00a0183ed3f", - "time": "665.278µs" + "blockHash": "0x93231d8e9662adb4c5c703583a92c7b3112cd5448f43ab4fa1f0f00a0183ed3f" }, { "action": { @@ -79,4 +78,4 @@ "type": "create" } ] -} \ No newline at end of file +} diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index b7cc60b096..a462591d40 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", } @@ -370,6 +371,7 @@ func convertErrorToParity(call *flatCallFrame) { for gethError, parityError := range parityErrorMappingStartingWith { if strings.HasPrefix(call.Error, gethError) { call.Error = parityError + break } } } From c48e936b7070f57d744f9ed9f7b66bf868bff67d Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Mon, 4 Nov 2024 04:05:44 +0800 Subject: [PATCH 17/42] build: use slices.Clone for copying slice (#30716) --- build/ci.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/ci.go b/build/ci.go index 680bdc9a9c..754d88a86a 100644 --- a/build/ci.go +++ b/build/ci.go @@ -53,6 +53,7 @@ import ( "path" "path/filepath" "runtime" + "slices" "strings" "time" @@ -226,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}) From 6e1fedb12a22a82da5b9c9c327fb0603917a9d26 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Mon, 4 Nov 2024 10:49:23 +0100 Subject: [PATCH 18/42] tests/fuzzers/bls12381: more verbose fuzzing-output (#30724) This PR updates the fuzzing verbosity a bit, in case of mismatches --- tests/fuzzers/bls12381/bls12381_fuzz.go | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) 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 From 484f0f4e84c94c02a12a563b1512030cd5b05489 Mon Sep 17 00:00:00 2001 From: piersy Date: Mon, 4 Nov 2024 10:32:41 +0000 Subject: [PATCH 19/42] core/txpool: improve error responses with wrapped errors (#30715) --- core/txpool/txpool.go | 2 +- core/txpool/validation.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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..5ff92d71c2 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -99,7 +99,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 From 7d6e153fd5ee1ed932e77f9741162f91d7c373e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 4 Nov 2024 12:33:42 +0200 Subject: [PATCH 20/42] eth/catalyst: make engine api test time independent (#30713) This test depends on a 100ms timer, which fails quite often, messing up our pipelines. Hook directly into the internal version of getPayload which has the capacity to wait for the full payload before returning. This might not be absolutely correct from a test perspective, but it beats failing ci. The alternative would be to expose the full build hook into the outside, but it might be a bit overkill for this scenario. --- eth/catalyst/api_test.go | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) 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) } From 014e2b037f5fcc8b7abccf6f17e6f3beed7216f5 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Mon, 4 Nov 2024 11:39:06 +0100 Subject: [PATCH 21/42] core/vm/runtime: invoke tx-end hook (#30711) When using the `core/vm/runtime` helpers to execute code, callbacks for the tx end were not invoked. This change fixes it by invoking them. --- core/vm/runtime/runtime.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 } From 06cbc80754c3930828cc605f151554bc7ec36eb9 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:19:50 +0100 Subject: [PATCH 22/42] core, trie: verkle state processor tests (#30672) Tests that are crucial to for verifying the verkle testnet functions properly. --------- Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Co-authored-by: Ignacio Hagopian Co-authored-by: Gary Rong Co-authored-by: Martin HS --- consensus/beacon/consensus.go | 12 +- core/state/access_events.go | 2 +- core/state/statedb.go | 3 +- core/state_processor_test.go | 194 ------ core/verkle_witness_test.go | 1087 +++++++++++++++++++++++++++++++++ trie/utils/verkle.go | 18 +- trie/verkle.go | 50 +- 7 files changed, 1142 insertions(+), 224 deletions(-) create mode 100644 core/verkle_witness_test.go 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/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/statedb.go b/core/state/statedb.go index 775a224af9..d855e5626d 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -1068,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_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/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/trie/utils/verkle.go b/trie/utils/verkle.go index 12e02de9a4..054fbcf150 100644 --- a/trie/utils/verkle.go +++ b/trie/utils/verkle.go @@ -204,10 +204,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 Date: Mon, 4 Nov 2024 15:10:12 +0100 Subject: [PATCH 23/42] all: fix issues with benchmarks (#30667) This PR fixes some issues with benchmarks - [x] Removes log output from a log-test - [x] Avoids a `nil`-defer in `triedb/pathdb` - [x] Fixes some crashes re tracers - [x] Refactors a very resource-expensive benchmark for blobpol. **NOTE**: this rewrite touches live production code (a little bit), as it makes the validator-function used by the blobpool configurable. - [x] Switch some benches over to use pebble over leveldb - [x] reduce mem overhead in the setup-phase of some tests - [x] Marks some tests with a long setup-phase to be skipped if `-short` is specified (where long is on the order of tens of seconds). Ideally, in my opinion, one should be able to run with `-benchtime 10ms -short` and sanity-check all tests very quickly. - [x] Drops some metrics-bechmark which times the speed of `copy`. --------- Co-authored-by: Sina Mahmoodi --- core/bench_test.go | 26 ++++++++++++++- core/rawdb/accessors_chain_test.go | 6 +++- core/txpool/blobpool/blobpool.go | 20 ++++++++---- core/txpool/blobpool/blobpool_test.go | 29 ++++++++++++++++- core/txpool/blobpool/evictheap_test.go | 22 +++++++++++-- core/txpool/validation.go | 5 +++ .../internal/tracetest/calltrace_test.go | 13 ++------ eth/tracers/tracers_test.go | 4 ++- log/logger_test.go | 3 +- metrics/sample_test.go | 32 +------------------ triedb/pathdb/difflayer_test.go | 7 ++-- 11 files changed, 105 insertions(+), 62 deletions(-) diff --git a/core/bench_test.go b/core/bench_test.go index d0305e268a..6d518e8d3b 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -81,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) @@ -210,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) { @@ -234,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) } 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/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/validation.go b/core/txpool/validation.go index 5ff92d71c2..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). 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/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/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/triedb/pathdb/difflayer_test.go b/triedb/pathdb/difflayer_test.go index e65f379135..61e8b4e064 100644 --- a/triedb/pathdb/difflayer_test.go +++ b/triedb/pathdb/difflayer_test.go @@ -76,7 +76,7 @@ func benchmarkSearch(b *testing.B, depth int, total int) { nblob = common.CopyBytes(blob) } } - return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), nil) + return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil)) } var layer layer layer = emptyLayer() @@ -118,7 +118,7 @@ func BenchmarkPersist(b *testing.B) { ) nodes[common.Hash{}][string(path)] = node } - return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), nil) + return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil)) } for i := 0; i < b.N; i++ { b.StopTimer() @@ -156,8 +156,7 @@ func BenchmarkJournal(b *testing.B) { ) nodes[common.Hash{}][string(path)] = node } - // TODO(rjl493456442) a non-nil state set is expected. - return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), nil) + return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), new(StateSetWithOrigin)) } var layer layer layer = emptyLayer() From 229ce6411a667faeb6d130b1d6f3b4f3e3f89671 Mon Sep 17 00:00:00 2001 From: Delweng Date: Tue, 5 Nov 2024 15:42:22 +0800 Subject: [PATCH 24/42] eth/tracers: fill the creationMethod in flatCall (#30539) `flatCallTracer` will now specify the type of a create in the action via the `creationMethod` field. --------- Signed-off-by: jsvisa Co-authored-by: Sina Mahmoodi --- .../tracetest/testdata/call_tracer_flat/big_slow.json | 1 + .../call_tracer_flat/callcode_precompiled_fail_hide.json | 1 + .../call_tracer_flat/callcode_precompiled_oog.json | 1 + .../call_tracer_flat/callcode_precompiled_throw.json | 1 + .../tracetest/testdata/call_tracer_flat/create.json | 1 + .../testdata/call_tracer_flat/create_oog_parity.json | 6 ++++-- .../tracetest/testdata/call_tracer_flat/gas.json | 1 + .../call_tracer_flat/inner_create_oog_outer_throw.json | 1 + .../testdata/call_tracer_flat/nested_create.json | 2 ++ .../call_tracer_flat/nested_create2_action_gas.json | 2 ++ .../call_tracer_flat/nested_create_action_gas.json | 2 ++ .../testdata/call_tracer_flat/nested_create_inerror.json | 1 + .../testdata/call_tracer_flat/nested_pointer_issue.json | 1 + .../testdata/call_tracer_flat/selfdestruct.json | 2 ++ .../testdata/call_tracer_flat/skip_no_balance_error.json | 2 ++ eth/tracers/native/call_flat.go | 9 +++++---- 16 files changed, 28 insertions(+), 6 deletions(-) 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 a3b9b6a667..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", 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 dd31abed07..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", 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 62e3f6c7d6..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", 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 index acaa43cefd..5e79e6ad45 100644 --- 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 @@ -58,7 +58,8 @@ "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", "value": "0x0", "gas": "0x19ee4", - "init": "0x5a600055600060006000f0505a60015500" + "init": "0x5a600055600060006000f0505a60015500", + "creationMethod": "create" }, "error": "Out of gas", "traceAddress": [], @@ -74,7 +75,8 @@ "from": "0x9c5cfe45b15eaff4ad617af4250189e26024a4f8", "value": "0x0", "gas": "0x3cb", - "init": "0x" + "init": "0x", + "creationMethod": "create" }, "result": { "gasUsed": "0x0", 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 7e40f06723..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", 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 ecdcbfb9df..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", @@ -71,6 +72,7 @@ { "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 6b7a20a090..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", @@ -71,6 +72,7 @@ { "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 5245e62074..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", @@ -67,6 +68,7 @@ { "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 0fe4bcb4f2..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 @@ -77,6 +77,7 @@ }, { "action": { + "creationMethod": "create", "from": "0x76554b33410b6d90b7dc889bfed0451ad195f27e", "gas": "0x25a18", "init": "0x0000000000000000000000000000000000000000000000000000000000000000", 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/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json index df8ecb7309..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", @@ -70,6 +71,7 @@ }, { "action": { + "creationMethod": "create", "from": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca", "gas": "0x50ac", "init": "0x5a", 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 17884fc3b6..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", @@ -66,6 +67,7 @@ }, { "action": { + "creationMethod": "create", "from": "0xf84bf5189ccd19f5897739756d214fa0dc099e0d", "gas": "0x1d5c", "init": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index a462591d40..e56d011139 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -297,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, From e56bbd77a44fc26550a862801690461e49e02503 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Tue, 5 Nov 2024 18:29:37 +0100 Subject: [PATCH 25/42] core/state: small fix in hooked statedb (#30732) fixes a very tiny bug --- core/state/statedb_hooked.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 55b53ded40..3abb0fa65f 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -150,7 +150,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 { From 9c08631bb0057936e0ab3b275811e0743a01f590 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 6 Nov 2024 18:24:55 +0100 Subject: [PATCH 26/42] cmd/utils: change blssync.JWTSecretFlag to DirectoryFlag (#30729) closes https://github.com/ethereum/go-ethereum/issues/30304 We already use `DirectoryFlag` for `authrpc.jwtsecret` which expands the tilde, so this should work out of the box --- cmd/utils/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index f083a25f90..c788b85089 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -319,7 +319,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, From 4bac6e669e9ddc80b968721f0ec5480e05adc2f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:48:51 +0100 Subject: [PATCH 27/42] build(deps): bump github.com/golang-jwt/jwt/v4 from 4.5.0 to 4.5.1 (#30728) Bumps [github.com/golang-jwt/jwt/v4](https://github.com/golang-jwt/jwt) from 4.5.0 to 4.5.1. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9c68c95034..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 diff --git a/go.sum b/go.sum index 720acb1caa..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= From e92e22a7cf8974a3f39a45cbac222f0a8e26590d Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 7 Nov 2024 20:26:02 +0100 Subject: [PATCH 28/42] ethclient: add RevertErrorData function and example (#30669) Here I'm adding a new helper function that extracts the revert reason of a contract call. Unfortunately, this aspect of the API is underspecified. See these spec issues for more detail: - https://github.com/ethereum/execution-apis/issues/232 - https://github.com/ethereum/execution-apis/issues/463 - https://github.com/ethereum/execution-apis/issues/523 The function added here only works with Geth-like servers that return error code `3`. We will not be able to support all possible servers. However, if there is a specific server implementation that makes it possible to extract the same info, we could add it in the same function as well. --------- Co-authored-by: Marius van der Wijden --- ethclient/ethclient.go | 17 +++ ethclient/ethclient_test.go | 253 +++++++++++++----------------------- ethclient/example_test.go | 35 +++++ ethclient/types_test.go | 153 ++++++++++++++++++++++ 4 files changed, 294 insertions(+), 164 deletions(-) create mode 100644 ethclient/example_test.go create mode 100644 ethclient/types_test.go 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/ethclient/example_test.go b/ethclient/example_test.go new file mode 100644 index 0000000000..5d0038f0c7 --- /dev/null +++ b/ethclient/example_test.go @@ -0,0 +1,35 @@ +// 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 ethclient_test + +import ( + "github.com/ethereum/go-ethereum/node" +) + +var exampleNode *node.Node + +// 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/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) + } + }) + } +} From 8e00f95056ace679770a61b84c53a07ba3354c83 Mon Sep 17 00:00:00 2001 From: SangIlMo <156392700+SangIlMo@users.noreply.github.com> Date: Fri, 8 Nov 2024 21:28:16 +0900 Subject: [PATCH 29/42] ethclient/gethclient: testcase for createAccessList, make tabledriven (#30194) Adds testcase for createAccessList when user requested gasPrice is less than baseFee, also makes the tests tabledriven --------- Co-authored-by: Martin Holst Swende --- ethclient/gethclient/gethclient_test.go | 129 +++++++++++++++--------- 1 file changed, 80 insertions(+), 49 deletions(-) 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) + } } } From 0fc9cca9949b70a5028e63e7af01f3fe9032b10e Mon Sep 17 00:00:00 2001 From: jwasinger Date: Fri, 8 Nov 2024 21:33:43 +0900 Subject: [PATCH 30/42] internal/ethapi: Set basefee for `AccessList` based on given block, not chain tip (#30538) --- internal/ethapi/api.go | 11 ++++++++++- internal/ethapi/transaction_args.go | 5 ++--- internal/ethapi/transaction_args_test.go | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index bea615bf44..a508b0ca5b 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1287,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/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) From a6037d027fd77dc135af2f512ae3265c7f74632a Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Fri, 8 Nov 2024 19:27:29 +0530 Subject: [PATCH 31/42] accounts/usbwallet: support dynamic tx (#30180) Adds support non-legacy transaction-signing using ledger --------- Co-authored-by: Martin Holst Swende --- accounts/usbwallet/ledger.go | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) 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 { From 5b78aef00995a2199bb628c7b5e000222b4e103d Mon Sep 17 00:00:00 2001 From: Naveen <116692862+naveen-imtb@users.noreply.github.com> Date: Sat, 9 Nov 2024 01:04:17 +1100 Subject: [PATCH 32/42] signer/core: extended support for EIP-712 array types (#30620) This change updates the EIP-712 implementation to resolve [#30619](https://github.com/ethereum/go-ethereum/issues/30619). The test cases have been repurposed from the ethers.js [repository](https://github.com/ethers-io/ethers.js/blob/main/testcases/typed-data.json.gz), but have been updated to remove tests that don't have a valid domain separator; EIP-712 messages without a domain separator are not supported by geth. --------- Co-authored-by: Martin Holst Swende --- .../apitypes/signed_data_internal_test.go | 71 +- signer/core/apitypes/testdata/typed-data.json | 6089 +++++++++++++++++ signer/core/apitypes/types.go | 87 +- signer/core/apitypes/types_test.go | 96 +- 4 files changed, 6272 insertions(+), 71 deletions(-) create mode 100644 signer/core/apitypes/testdata/typed-data.json 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) + } + } +} From d42d45046ce074d0575cdaceac965720032b03af Mon Sep 17 00:00:00 2001 From: jwasinger Date: Fri, 8 Nov 2024 23:18:42 +0900 Subject: [PATCH 33/42] cmd/evm: benchmarking via `statetest` command + filter by name, index and fork (#30442) When `evm statetest --bench` is specified, benchmark the execution similarly to `evm run`. Also adds the ability to filter tests by name, index and fork. --------- Co-authored-by: Martin Holst Swende --- cmd/evm/runner.go | 64 +++++++++++++------- cmd/evm/staterunner.go | 125 +++++++++++++++++++++++++++++---------- tests/state_test_util.go | 16 ++--- 3 files changed, 144 insertions(+), 61 deletions(-) diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 3f82deaf70..8c382e6257 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -76,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 { @@ -265,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) @@ -300,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/tests/state_test_util.go b/tests/state_test_util.go index e9a58694ed..31f4224a8b 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 } } @@ -322,7 +322,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, err } func (t *StateTest) gasLimit(subtest StateSubtest) uint64 { From 7cbce8ed583a195eda8bac99c0cf604ac0bb7743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Fri, 8 Nov 2024 15:21:00 +0100 Subject: [PATCH 34/42] beacon/blsync: remove cli dependencies (#30720) This PR moves chain config related code (config file processing, fork logic, network defaults) from `beacon/types` and `beacon/blsync` into `beacon/params` while the command line flag logic of the chain config is moved into `cmd/utils`, thereby removing the cli dependencies from package `beacon` and its sub-packages. --- beacon/blsync/client.go | 39 ++----- beacon/blsync/config.go | 129 --------------------- beacon/blsync/engineclient.go | 5 +- beacon/light/committee_chain.go | 10 +- beacon/light/committee_chain_test.go | 28 ++--- beacon/light/test_helpers.go | 6 +- beacon/{types => params}/config.go | 161 ++++++++++++++------------- beacon/params/networks.go | 56 ++++++++++ cmd/blsync/main.go | 2 +- cmd/geth/config.go | 2 +- cmd/utils/flags.go | 76 +++++++++++++ 11 files changed, 254 insertions(+), 260 deletions(-) delete mode 100644 beacon/blsync/config.go rename beacon/{types => params}/config.go (94%) create mode 100644 beacon/params/networks.go 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 828c14f898..0000000000 --- a/beacon/blsync/config.go +++ /dev/null @@ -1,129 +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("0x6509b691f4de4f7b083f2784938fd52f0e131675432b3fd85ea549af9aebd3d0"), - } - - 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("0x456e85f5608afab3465a0580bff8572255f6d97af0c5f939e3f7536b5edb2d3f"), - } - - HoleskyConfig = lightClientConfig{ - ChainConfig: (&types.ChainConfig{ - GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"), - GenesisTime: 1695902400, - }). - 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}), - Checkpoint: common.HexToHash("0x6456a1317f54d4b4f2cb5bc9d153b5af0988fe767ef0609f0236cf29030bcff7"), - } -) - -func makeChainConfig(ctx *cli.Context) lightClientConfig { - var config lightClientConfig - customConfig := ctx.IsSet(utils.BeaconConfigFlag.Name) - utils.CheckExclusive(ctx, utils.MainnetFlag, utils.SepoliaFlag, utils.HoleskyFlag, utils.BeaconConfigFlag) - switch { - case ctx.Bool(utils.MainnetFlag.Name): - config = MainnetConfig - case ctx.Bool(utils.SepoliaFlag.Name): - config = SepoliaConfig - case ctx.Bool(utils.HoleskyFlag.Name): - config = HoleskyConfig - 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 778cd3028f..4fa87785c0 100644 --- a/beacon/light/committee_chain.go +++ b/beacon/light/committee_chain.go @@ -76,24 +76,24 @@ type CommitteeChain struct { unixNano func() int64 // system clock (simulated clock in tests) sigVerifier committeeSigVerifier // BLS sig verifier (dummy verifier in tests) - config *types.ChainConfig + 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, @@ -505,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/cmd/blsync/main.go b/cmd/blsync/main.go index 6a35e9d16a..d74e1496cd 100644 --- a/cmd/blsync/main.go +++ b/cmd/blsync/main.go @@ -70,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/geth/config.go b/cmd/geth/config.go index 842c1c2347..17ed9fb606 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -240,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/utils/flags.go b/cmd/utils/flags.go index c788b85089..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" @@ -1889,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) { From 3c7336b0e9cb88a633eeae3b219407786b520414 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Fri, 8 Nov 2024 15:25:30 +0100 Subject: [PATCH 35/42] core/state: invoke OnCodeChange-hook on selfdestruct (#30686) This change invokes the OnCodeChange hook when selfdestruct operation is performed, and a contract is removed. This is an event which can be consumed by tracers. --- core/state/statedb_hooked.go | 44 ++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 3abb0fa65f..26d0217099 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -198,22 +198,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 } From 896fc51379593c75e9beda2232e12eadb60cdc1b Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Fri, 8 Nov 2024 22:28:42 +0800 Subject: [PATCH 36/42] trie/utils: remove unneeded initialization (#30472) --- trie/utils/verkle.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/trie/utils/verkle.go b/trie/utils/verkle.go index 054fbcf150..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++ { @@ -297,8 +293,6 @@ func evaluateAddressPoint(address []byte) *verkle.Point { } var poly [3]fr.Element - poly[0].SetZero() - // 32-byte address, interpreted as two little endian // 16-byte numbers. verkle.FromLEBytes(&poly[1], address[:16]) From 55fdbb7e7b4a5dd38b9f406a6a3dce9d5be5898b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 8 Nov 2024 18:20:48 +0200 Subject: [PATCH 37/42] travis: build and upload RISC-V docker images too (#30739) Requested by @barnabasbusa --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 74ef47462f2a9daea04e81687c4d0b4598826ca2 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Sat, 9 Nov 2024 08:08:06 +0800 Subject: [PATCH 38/42] core/state, triedb/database: refactor state reader (#30712) Co-authored-by: Martin HS --- core/state/database.go | 6 +++--- core/state/reader.go | 41 ++++++++++++++++--------------------- triedb/database/database.go | 29 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 26 deletions(-) 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/triedb/database/database.go b/triedb/database/database.go index cde8390756..cd7ec1d931 100644 --- a/triedb/database/database.go +++ b/triedb/database/database.go @@ -18,6 +18,7 @@ package database import ( "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" ) // NodeReader wraps the Node method of a backing trie reader. @@ -37,3 +38,31 @@ type NodeDatabase interface { // An error will be returned if the specified state is not available. NodeReader(stateRoot common.Hash) (NodeReader, error) } + +// StateReader wraps the Account and Storage method of a backing state reader. +type StateReader interface { + // Account directly retrieves the account associated with a particular hash in + // the slim data format. An error will be returned if the read operation exits + // abnormally. Specifically, if the layer is already stale. + // + // Note: + // - the returned account object is safe to modify + // - no error will be returned if the requested account is not found in database + Account(hash common.Hash) (*types.SlimAccount, error) + + // Storage directly retrieves the storage data associated with a particular hash, + // within a particular account. An error will be returned if the read operation + // exits abnormally. + // + // Note: + // - the returned storage data is not a copy, please don't modify it + // - no error will be returned if the requested slot is not found in database + Storage(accountHash, storageHash common.Hash) ([]byte, error) +} + +// StateDatabase wraps the methods of a backing state store. +type StateDatabase interface { + // StateReader returns a state reader associated with the specific state. + // An error will be returned if the specified state is not available. + StateReader(stateRoot common.Hash) (StateReader, error) +} From 3f5f2efccb23fa0bc05a0104e2f582f0e7a1b943 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Sat, 9 Nov 2024 16:07:17 +0100 Subject: [PATCH 39/42] eth/protocols/eth: add ETH68 protocol handler fuzzers (#30417) Adds a protocol handler fuzzer to fuzz the ETH68 protocol handlers --- eth/protocols/eth/handler_test.go | 82 ++++++++++++++++++++++++++++++- oss-fuzz.sh | 4 ++ 2 files changed, 84 insertions(+), 2 deletions(-) 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/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 From 77f3ef3714afa280add3654ebceda2dd1856d65f Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Sun, 10 Nov 2024 17:57:05 +0800 Subject: [PATCH 40/42] tests: fix test panic (#30741) Fix panic in tests --- tests/state_test_util.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 31f4224a8b..af2cb63d94 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -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, vmRet.UsedGas, err + return st, root, vmRet.UsedGas, nil } func (t *StateTest) gasLimit(subtest StateSubtest) uint64 { From ae83912841ac997d5ceac12949b5eb7a674ea6fe Mon Sep 17 00:00:00 2001 From: tianyeyouyou Date: Mon, 11 Nov 2024 18:43:22 +0800 Subject: [PATCH 41/42] p2p/netutil: unittests for addrutil (#30439) add unit tests for `p2p/addrutil` --------- Co-authored-by: Martin HS --- p2p/netutil/addrutil_test.go | 140 +++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 p2p/netutil/addrutil_test.go 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) + } + }) + } +} From df182a742cec68adcc034d4747afa5182fc75ca3 Mon Sep 17 00:00:00 2001 From: witty <131909329+0xwitty@users.noreply.github.com> Date: Mon, 11 Nov 2024 14:14:18 +0300 Subject: [PATCH 42/42] docs: fix typo (#30740) fixes a typo on one of the postmortems --- docs/postmortems/2021-08-22-split-postmortem.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: