diff --git a/go.mod b/go.mod index 2107f76fe1fc..b8952709c5e7 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/cespare/cp v0.1.0 github.com/cloudflare/cloudflare-go v0.14.0 github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f - github.com/crate-crypto/go-ipa v0.0.0-20221111143132-9aa5d42120bc + github.com/crate-crypto/go-ipa v0.0.0-20230112133036-98736f2f2808 github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v1.8.0 github.com/docker/docker v1.6.2 @@ -23,7 +23,7 @@ require ( github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff - github.com/gballet/go-verkle v0.0.0-20221129125207-513116151b28 + github.com/gballet/go-verkle v0.0.0-20230112140635-3e8bae599d5c github.com/go-stack/stack v1.8.0 github.com/golang-jwt/jwt/v4 v4.3.0 github.com/golang/protobuf v1.5.2 @@ -106,3 +106,5 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/gballet/go-verkle => github.com/gballet/go-verkle v0.0.0-20230112140635-3e8bae599d5c diff --git a/go.sum b/go.sum index 68a0ee1d1933..1a9367ca60ca 100644 --- a/go.sum +++ b/go.sum @@ -86,8 +86,8 @@ github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20221111143132-9aa5d42120bc h1:mtR7MuscVeP/s0/ERWA2uSr5QOrRYy1pdvZqG1USfXI= -github.com/crate-crypto/go-ipa v0.0.0-20221111143132-9aa5d42120bc/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI= +github.com/crate-crypto/go-ipa v0.0.0-20230112133036-98736f2f2808 h1:zzhDwbi4il5p8+g4WjfX4nWaIo9A61bBS6Ltj8AkExg= +github.com/crate-crypto/go-ipa v0.0.0-20230112133036-98736f2f2808/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= @@ -135,10 +135,8 @@ github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgx github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-verkle v0.0.0-20221122140954-75ceda26b7db h1:YvtZfE11QEYWPjsQCyZLoZCGMsxJs9mTEbhF3MnM32Q= -github.com/gballet/go-verkle v0.0.0-20221122140954-75ceda26b7db/go.mod h1:DMDd04jjQgdynaAwbEgiRERIGpC8fDjx0+y06an7Psg= -github.com/gballet/go-verkle v0.0.0-20221129125207-513116151b28 h1:UbB7D2R1OQCkNFX+LYoo2pHZ0u5LhwR9ldUsY4ZbZqI= -github.com/gballet/go-verkle v0.0.0-20221129125207-513116151b28/go.mod h1:DMDd04jjQgdynaAwbEgiRERIGpC8fDjx0+y06an7Psg= +github.com/gballet/go-verkle v0.0.0-20230112140635-3e8bae599d5c h1:ROHmmjPpri0ApcrUhpXZBsWaeFuyuVEDhrPK1dIsAqA= +github.com/gballet/go-verkle v0.0.0-20230112140635-3e8bae599d5c/go.mod h1:hspihFYcpgSaKoVnQV+97jkJREFZdH/kiPTcBwIHCyM= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -554,7 +552,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc= golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/tests/tries_test.go b/tests/tries_test.go new file mode 100644 index 000000000000..caf2e8aee126 --- /dev/null +++ b/tests/tries_test.go @@ -0,0 +1,76 @@ +package tests + +import ( + "fmt" + "math/big" + "math/rand" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ethereum/go-ethereum/trie" + "github.com/gballet/go-verkle" +) + +func BenchmarkTriesRandom(b *testing.B) { + numAccounts := []int{1_000, 5_000, 10_000} + + for _, numAccounts := range numAccounts { + rs := rand.New(rand.NewSource(42)) + accounts := getRandomStateAccounts(rs, numAccounts) + + b.Run(fmt.Sprintf("MPT/%d accounts", numAccounts), func(b *testing.B) { + trie, _ := trie.NewStateTrie(trie.TrieID(common.Hash{}), trie.NewDatabase(memorydb.New())) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + for k := 0; k < len(accounts); k++ { + trie.TryUpdateAccount(accounts[k].address[:], &accounts[k].stateAccount) + } + trie.Commit(true) + } + }) + b.Run(fmt.Sprintf("VKT/%d accounts", numAccounts), func(b *testing.B) { + // Warmup VKT configuration + trie.NewVerkleTrie(verkle.New(), trie.NewDatabase(memorydb.New())).TryUpdate([]byte("00000000000000000000000000000012"), []byte("B")) + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + trie := trie.NewVerkleTrie(verkle.New(), trie.NewDatabase(memorydb.New())) + for k := 0; k < len(accounts); k++ { + trie.TryUpdateAccount(accounts[k].address[:], &accounts[k].stateAccount) + } + trie.Commit(false) + } + }) + } +} + +type randomAccount struct { + address common.Address + stateAccount types.StateAccount +} + +func getRandomStateAccounts(rand *rand.Rand, count int) []randomAccount { + randomBytes := func(size int) []byte { + ret := make([]byte, size) + rand.Read(ret) + return ret + } + + accounts := make([]randomAccount, count) + for i := range accounts { + accounts[i] = randomAccount{ + address: common.BytesToAddress(randomBytes(common.AddressLength)), + stateAccount: types.StateAccount{ + Nonce: rand.Uint64(), + Balance: big.NewInt(int64(rand.Uint64())), + Root: common.Hash{}, + CodeHash: nil, + }, + } + } + return accounts +} diff --git a/trie/utils/verkle.go b/trie/utils/verkle.go index a0f4fac0a4e2..7757c234d572 100644 --- a/trie/utils/verkle.go +++ b/trie/utils/verkle.go @@ -82,9 +82,11 @@ func GetTreeKey(address []byte, treeIndex *uint256.Int, subIndex byte) []byte { // 32-byte aligned big-endian representation (BE({00,...,AA,BB,CC})). // - poly[4]'s byte representation is the same as the *low* 16 bytes (trieIndexBytes[:16]) of // the 32-byte aligned big-endian representation (BE({00,00,...}). - trieIndexBytes := treeIndex.Bytes32() - verkle.FromBytes(&poly[3], trieIndexBytes[16:]) - verkle.FromBytes(&poly[4], trieIndexBytes[:16]) + if !treeIndex.IsZero() { + trieIndexBytes := treeIndex.Bytes32() + verkle.FromBytes(&poly[3], trieIndexBytes[16:]) + verkle.FromBytes(&poly[4], trieIndexBytes[:16]) + } cfg := verkle.GetConfig() ret := cfg.CommitToPoly(poly[:], 0) diff --git a/trie/verkle.go b/trie/verkle.go index 6c2202596a70..0fda23171465 100644 --- a/trie/verkle.go +++ b/trie/verkle.go @@ -119,7 +119,7 @@ func (t *VerkleTrie) TryUpdateAccount(key []byte, acc *types.StateAccount) error var ( err error nonce, balance [32]byte - values = make([][]byte, verkle.NodeWidth) + values = make([][]byte, 256) stem = utils.GetTreeKeyVersion(key[:]) ) @@ -156,10 +156,9 @@ func (t *VerkleTrie) TryUpdateAccount(key []byte, acc *types.StateAccount) error } func (trie *VerkleTrie) TryUpdateStem(key []byte, values [][]byte) { - resolver := - func(h []byte) ([]byte, error) { - return trie.db.diskdb.Get(h) - } + resolver := func(h []byte) ([]byte, error) { + return trie.db.diskdb.Get(h) + } switch root := trie.root.(type) { case *verkle.InternalNode: root.InsertStem(key, values, resolver) @@ -239,9 +238,23 @@ func nodeToDBKey(n verkle.VerkleNode) []byte { // Commit writes all nodes to the trie's memory database, tracking the internal // and external (for account tries) references. func (trie *VerkleTrie) Commit(_ bool) (common.Hash, *NodeSet, error) { - flush := make(chan verkle.VerkleNode) + type vnflush struct { + n verkle.VerkleNode + value []byte + dbKey []byte + } + flush := make(chan vnflush, 1024) resolver := func(n verkle.VerkleNode) { - flush <- n + value, err := n.Serialize() + if err != nil { + panic(err) + } + dbKey := nodeToDBKey(n) + flush <- vnflush{ + n: n, + value: value, + dbKey: dbKey, + } } go func() { switch root := trie.root.(type) { @@ -255,12 +268,8 @@ func (trie *VerkleTrie) Commit(_ bool) (common.Hash, *NodeSet, error) { var commitCount int for n := range flush { commitCount += 1 - value, err := n.Serialize() - if err != nil { - panic(err) - } - if err := trie.db.diskdb.Put(nodeToDBKey(n), value); err != nil { + if err := trie.db.diskdb.Put(n.dbKey, n.value); err != nil { return common.Hash{}, NewNodeSet(common.Hash{}), err } }