Skip to content

Commit 3bbc757

Browse files
authored
### Description - Fix in the stack trie `GetProof` method - Added description for `TestTransactions` ### Issue Link privacy-scaling-explorations#1752 ### Type of change - [x ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update - [ ] Refactor (no updates to logic) ### How Has This Been Tested? `TestTransactions` and `TestGetProof` in `zkevm-circuits/geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go`.
1 parent 8e2e74a commit 3bbc757

File tree

9 files changed

+144
-1071
lines changed

9 files changed

+144
-1071
lines changed

.github/workflows/geth-utils.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
- name: Set up Go
3131
uses: actions/setup-go@v4
3232
with:
33-
go-version: '1.20'
33+
go-version: '1.21'
3434

3535
- name: Format
3636
uses: Jerome1337/[email protected]

.github/workflows/integration.yml

+2-12
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,9 @@ jobs:
7070
with:
7171
override: false
7272
- name: Setup golang
73-
uses: actions/setup-go@v3
73+
uses: actions/setup-go@v4
7474
with:
75-
go-version: ~1.19
76-
# Go cache for building geth-utils
77-
- name: Go cache
78-
uses: actions/cache@v3
79-
with:
80-
path: |
81-
~/.cache/go-build
82-
~/go/pkg/mod
83-
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
84-
restore-keys: |
85-
${{ runner.os }}-go-
75+
go-version: ~1.21
8676
- name: Cargo cache
8777
uses: actions/cache@v3
8878
with:

.github/workflows/lints.yml

+3-9
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,10 @@ jobs:
3838
with:
3939
components: rustfmt, clippy
4040
override: false
41-
# Go cache for building geth-utils
42-
- name: Go cache
43-
uses: actions/cache@v3
41+
- name: Setup golang
42+
uses: actions/setup-go@v4
4443
with:
45-
path: |
46-
~/.cache/go-build
47-
~/go/pkg/mod
48-
key: lint-${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
49-
restore-keys: |
50-
${{ runner.os }}-go-
44+
go-version: ~1.21
5145
- name: Cargo cache
5246
uses: actions/cache@v3
5347
with:

.github/workflows/main-tests.yml

+7-33
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,9 @@ jobs:
4646
with:
4747
override: false
4848
- name: Setup golang
49-
uses: actions/setup-go@v3
49+
uses: actions/setup-go@v4
5050
with:
51-
go-version: ~1.19
52-
# Go cache for building geth-utils
53-
- name: Go cache
54-
uses: actions/cache@v3
55-
with:
56-
path: |
57-
~/.cache/go-build
58-
~/go/pkg/mod
59-
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
60-
restore-keys: |
61-
${{ runner.os }}-go-
51+
go-version: ~1.21
6252
- name: Cargo cache
6353
uses: actions/cache@v3
6454
with:
@@ -104,19 +94,9 @@ jobs:
10494
with:
10595
override: false
10696
- name: Setup golang
107-
uses: actions/setup-go@v3
108-
with:
109-
go-version: ~1.19
110-
# Go cache for building geth-utils
111-
- name: Go cache
112-
uses: actions/cache@v3
97+
uses: actions/setup-go@v4
11398
with:
114-
path: |
115-
~/.cache/go-build
116-
~/go/pkg/mod
117-
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
118-
restore-keys: |
119-
${{ runner.os }}-go-
99+
go-version: ~1.21
120100
- name: Cargo cache
121101
uses: actions/cache@v3
122102
with:
@@ -155,16 +135,10 @@ jobs:
155135
override: false
156136
- name: Add target
157137
run: rustup target add x86_64-unknown-linux-gnu
158-
# Go cache for building geth-utils
159-
- name: Go cache
160-
uses: actions/cache@v3
138+
- name: Setup golang
139+
uses: actions/setup-go@v4
161140
with:
162-
path: |
163-
~/.cache/go-build
164-
~/go/pkg/mod
165-
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
166-
restore-keys: |
167-
${{ runner.os }}-go-
141+
go-version: ~1.21
168142
- name: Cargo cache
169143
uses: actions/cache@v3
170144
with:

.github/workflows/test-features.yml

+3-9
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,10 @@ jobs:
3636
- uses: actions-rs/toolchain@v1
3737
with:
3838
override: false
39-
40-
# Go cache for building geth-utils
41-
- name: Go cache
42-
uses: actions/cache@v3
39+
- name: Setup golang
40+
uses: actions/setup-go@v4
4341
with:
44-
path: |
45-
~/.cache/go-build
46-
~/go/pkg/mod
47-
key: ${{ github.workflow }}-${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
48-
42+
go-version: ~1.21
4943
- name: Cargo cache
5044
uses: actions/cache@v3
5145
with:

geth-utils/gethutil/mpt/trie/stacktrie.go

+12-34
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"fmt"
2525
"io"
2626
"main/gethutil/mpt/types"
27+
"slices"
2728
"sync"
2829

2930
"github.com/ethereum/go-ethereum/common"
@@ -230,9 +231,6 @@ func (st *StackTrie) getDiffIndex(key []byte) int {
230231
// Helper function to that inserts a (key, value) pair into
231232
// the trie.
232233
func (st *StackTrie) insert(key, value []byte) {
233-
if key[0] == 1 && key[1] == 0 {
234-
fmt.Println("d")
235-
}
236234
switch st.nodeType {
237235
case branchNode: /* Branch */
238236
idx := int(key[st.keyOffset])
@@ -659,7 +657,6 @@ func (st *StackTrie) UpdateAndGetProofs(db ethdb.KeyValueReader, list types.Deri
659657

660658
func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, error) {
661659
k := KeybytesToHex(key)
662-
i := 0
663660

664661
if st.nodeType == emptyNode {
665662
return [][]byte{}, nil
@@ -678,13 +675,11 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, er
678675
}
679676

680677
var proof [][]byte
681-
682678
var nodes []*StackTrie
683-
684679
c := st
685680
isHashed := false
686681

687-
for i < len(k) {
682+
for i := 0; i < len(k); i++ {
688683
if c.nodeType == extNode {
689684
nodes = append(nodes, c)
690685
c = st.children[0]
@@ -701,33 +696,19 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, er
701696
isHashed = true
702697
c_rlp, error := db.Get(c.val)
703698
if error != nil {
704-
fmt.Println(error)
705699
panic(error)
706700
}
707-
fmt.Println(c_rlp)
708701

709702
proof = append(proof, c_rlp)
703+
branchChild := st.getNodeFromBranchRLP(c_rlp, k[i])
710704

711-
for i < len(k)-1 {
712-
node := st.getNodeFromBranchRLP(c_rlp, k[i])
713-
i += 1
714-
fmt.Println(node)
715-
716-
if len(node) == 1 && node[0] == 128 { // no child at this position
717-
break
718-
}
719-
720-
c_rlp, error = db.Get(node)
721-
if error != nil {
722-
fmt.Println(error)
723-
panic(error)
724-
}
725-
fmt.Println(c_rlp)
726-
727-
proof = append(proof, c_rlp)
705+
// branchChild is of length 1 when there is no child at this position in the branch
706+
// (`branchChild = [128]` in this case), but it is also of length 1 when `c_rlp` is a leaf.
707+
if len(branchChild) == 1 {
708+
// no child at this position - 128 is RLP encoding for nil object
709+
break
728710
}
729-
730-
break
711+
c.val = branchChild
731712
}
732713
}
733714

@@ -740,7 +721,6 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, er
740721
lNodes := len(nodes)
741722
for i := lNodes - 1; i >= 0; i-- {
742723
node := nodes[i]
743-
fmt.Println(node)
744724

745725
if node.nodeType == leafNode {
746726
rlp, error := db.Get(node.val)
@@ -760,11 +740,9 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, er
760740
}
761741

762742
}
763-
}
764-
765-
fmt.Println("----------")
766-
for i := 0; i < len(proof); i++ {
767-
fmt.Println(proof[i])
743+
// The proof is now reversed (only for non-hashed),
744+
// let's reverse it back to have the leaf at the bottom:
745+
slices.Reverse(proof)
768746
}
769747

770748
return proof, nil

geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go

+61-5
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,54 @@ import (
1515
"github.com/ethereum/go-ethereum/rlp"
1616
)
1717

18-
func TestTransactions(t *testing.T) {
19-
t.Skip("failing test")
18+
/*
19+
TestNonHashedTransactionsStackTrieGetProof inserts 70 transactions into a stacktrie.
20+
For each of the 70 modifications of the trie it asks for a proof - GetProof is called before
21+
and after the modification. The transactions in the trie are not hashed and thus GetProof
22+
does not require to query a database to get the preimages.
23+
24+
When the first transaction is added, a leaf is added to the trie
25+
(it has index 1 which is used as a key when inserting into a trie, the key is changed by
26+
calling KeybytesToHex(key) in TryUpdate to [0, 1, 16]).
27+
28+
When the second transaction is added (it has index 2, when inserting into a trie,
29+
it gets changed to [0, 2, 16]), the extension node E is created with nibble 0 (note that
30+
both leaves/transactions have the first nibble 0) and the underlying branch B with children
31+
at positions 1 and 2 (second nibble of the two leaves).
32+
33+
At this point, the proof for the second transaction is (proofC when index = 2):
34+
[226 16 160 212 52 159 164 192 63 244 122 229 5 208 58 20 16 54 62 169 98 62 238 163 88 174 155 252 118 132 91 148 62 122 23]
35+
[248 81 128 160 32 244 75 78 180 11 251 73 229 254 70 16 254 170 54 254 200 97 231 24 180 34 220 244 153 76 1 194 23 63 64 224 160 46 141 2 37 188 204 110 232 46 31 230 82 226 213 98 71 18 241 37 90 213 167 221 58 33 36 249 248 180 207 235 47 128 128 128 128 128 128 128 128 128 128 128 128 128 128]
36+
[248 200 2 131 4 147 224 131 1 226 65 148 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 184 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37 160 163 65 77 46 20 3 175 162 34 86 182 41 225 43 90 92 158 249 153 67 193 148 178 63 8 81 26 169 176 56 242 78 160 21 37 82 209 254 5 113 171 235 198 244 52 17 233 162 51 76 151 85 224 28 101 146 160 197 216 253 237 240 187 19 184]
37+
38+
Note that the first proof element is an extension node with nibble 0 = 16 - 16 (see
39+
the second byte). The third byte (32 = 160 - 128) denotes the length of the subsequent stream
40+
which represents the hash of the underlying branch.
41+
The second proof element is the underlying branch. The second byte (81) denotes the length
42+
of the subsequent RLP stream. The third byte (128) denotes the nil element at position 0.
43+
Then there are two children at positions 1 (32 244 75...) and 2 (46 141 2...). Note that
44+
these two 32-long value are the hashes of the two leaves/transactions in the branch.
45+
The bytes 128 at the end of the branch RLP represents nil objects at positions 3 - 15.
46+
The last proof element is the second transaction, for example the third nibble (2)
47+
represents the index of the transaction.
48+
49+
When further 13 transactions are added, the branch B gets populated at positions 3 - 15
50+
(the position 0 remains nil).
51+
52+
When the 16-th transaction is added (it has index 16, it gets changed to [1, 0, 16]),
53+
the extension node E is turned into branch B1 which has children at positions 0 and 1.
54+
At position 0 it has a branch B (which used to be the underlying branch of E1) and
55+
at position 1 it has a leaf that represents the 16-transaction.
56+
57+
At this point, the proof for the second transaction is (proofC when index = 16):
58+
[248 81 160 204 44 112 166 132 56 23 211 247 164 233 113 161 247 117 64 34 142 106 19 106 151 213 163 170 185 19 10 144 231 85 229 160 23 243 146 56 210 93 132 177 170 102 160 150 91 57 192 254 50 122 118 157 138 67 46 2 247 8 89 216 105 197 213 36 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128]
59+
[248 203 16 131 4 147 224 131 1 226 65 148 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 131 1 0 0 184 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 38 160 4 18 182 163 225 56 150 243 120 135 140 57 183 97 55 103 25 62 11 37 106 178 135 7 12 58 133 148 112 183 105 66 160 106 208 180 0 175 152 228 224 143 226 84 16 188 253 79 140 234 80 104 143 32 229 83 105 24 251 62 24 122 66 11 59]
60+
61+
The first proof element is a branch with children at position 0 (branch B) and 1 (newly added leaf).
62+
The second element is the 16-th transaction. For example, the third byte (16) represents
63+
the transaction index.
64+
*/
65+
func TestNonHashedTransactionsStackTrieGetProof(t *testing.T) {
2066
txs := make([]*types.Transaction, 70)
2167
key, _ := crypto.GenerateKey()
2268
signer := types.LatestSigner(params.TestChainConfig)
@@ -41,16 +87,26 @@ func TestTransactions(t *testing.T) {
4187
fmt.Println("===")
4288
}
4389

44-
// No update for each step, just final proof.
45-
func TestGetProof(t *testing.T) {
46-
txs := make([]*types.Transaction, 70)
90+
/*
91+
TestHashedTransactionsStackTrieGetProof inserts 2 transactions into a stacktrie,
92+
the trie is then hashed (DeriveSha call).
93+
The proof is asked for one of the two transactions. The transactions in the trie are hashed and thus
94+
GetProof requires to query a database to get the preimages.
95+
*/
96+
func TestHashedTransactionsStackTrieGetProof(t *testing.T) {
97+
txs := make([]*types.Transaction, 2)
4798
key, _ := crypto.GenerateKey()
4899
signer := types.LatestSigner(params.TestChainConfig)
49100

50101
for i := range txs {
51102
amount := math.BigPow(2, int64(i))
52103
price := big.NewInt(300000)
53104
data := make([]byte, 100)
105+
data[3] = 3
106+
data[4] = 3
107+
data[5] = 3
108+
data[6] = 3
109+
data[7] = 3
54110
tx := types.NewTransaction(uint64(i), common.Address{}, amount, 123457, price, data)
55111
signedTx, err := types.SignTx(tx, signer, key)
56112
if err != nil {

geth-utils/go.mod

+47-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,56 @@
11
module main
22

3-
go 1.16
3+
go 1.21
44

55
require github.com/ethereum/go-ethereum v1.11.5
66

77
require golang.org/x/crypto v0.1.0
88

9+
require (
10+
github.com/DataDog/zstd v1.5.2 // indirect
11+
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
12+
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
13+
github.com/beorn7/perks v1.0.1 // indirect
14+
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
15+
github.com/cespare/xxhash/v2 v2.2.0 // indirect
16+
github.com/cockroachdb/errors v1.9.1 // indirect
17+
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
18+
github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 // indirect
19+
github.com/cockroachdb/redact v1.1.3 // indirect
20+
github.com/deckarep/golang-set/v2 v2.1.0 // indirect
21+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
22+
github.com/getsentry/sentry-go v0.18.0 // indirect
23+
github.com/go-ole/go-ole v1.2.1 // indirect
24+
github.com/go-stack/stack v1.8.1 // indirect
25+
github.com/gofrs/flock v0.8.1 // indirect
26+
github.com/gogo/protobuf v1.3.2 // indirect
27+
github.com/golang/protobuf v1.5.2 // indirect
28+
github.com/golang/snappy v0.0.4 // indirect
29+
github.com/gorilla/websocket v1.4.2 // indirect
30+
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
31+
github.com/holiman/uint256 v1.2.0 // indirect
32+
github.com/klauspost/compress v1.15.15 // indirect
33+
github.com/kr/pretty v0.3.1 // indirect
34+
github.com/kr/text v0.2.0 // indirect
35+
github.com/mattn/go-runewidth v0.0.9 // indirect
36+
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
37+
github.com/olekukonko/tablewriter v0.0.5 // indirect
38+
github.com/pkg/errors v0.9.1 // indirect
39+
github.com/prometheus/client_golang v1.14.0 // indirect
40+
github.com/prometheus/client_model v0.3.0 // indirect
41+
github.com/prometheus/common v0.39.0 // indirect
42+
github.com/prometheus/procfs v0.9.0 // indirect
43+
github.com/rogpeppe/go-internal v1.9.0 // indirect
44+
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
45+
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
46+
github.com/tklauser/go-sysconf v0.3.5 // indirect
47+
github.com/tklauser/numcpus v0.2.2 // indirect
48+
golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect
49+
golang.org/x/sys v0.5.0 // indirect
50+
golang.org/x/text v0.7.0 // indirect
51+
google.golang.org/protobuf v1.28.1 // indirect
52+
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
53+
)
54+
955
// Uncomment for debugging
1056
// replace github.com/ethereum/go-ethereum => ../../go-ethereum

0 commit comments

Comments
 (0)