Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Commit a5b0b2e

Browse files
committed
Merge branch 'extension-into-branch' (only .go files) into feat/#1752-fix-witness-generation-json-export
2 parents a4ef7e1 + 1dd4008 commit a5b0b2e

File tree

10 files changed

+228
-97
lines changed

10 files changed

+228
-97
lines changed

geth-utils/gethutil/mpt/oracle/prefetch.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ var RemoteUrl = "https://mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161"
8181
var LocalUrl = "http://localhost:8545"
8282

8383
// For generating special tests for MPT circuit:
84-
var PreventHashingInSecureTrie = false
84+
var PreventHashingInSecureTrie = false // storage
85+
var AccountPreventHashingInSecureTrie = false
8586

8687
func toFilename(key string) string {
8788
return fmt.Sprintf("/tmp/eth/json_%s", key)

geth-utils/gethutil/mpt/state/database.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (db *Database) CopyTrie(t Trie) Trie {
5252

5353
// OpenTrie opens the main account trie at a specific root hash.
5454
func (db *Database) OpenTrie(root common.Hash) (Trie, error) {
55-
tr, err := trie.NewSecure(root, db.db)
55+
tr, err := trie.NewSecure(root, db.db, false)
5656
if err != nil {
5757
return nil, err
5858
}
@@ -62,7 +62,7 @@ func (db *Database) OpenTrie(root common.Hash) (Trie, error) {
6262
// OpenStorageTrie opens the storage trie of an account.
6363
func (db *Database) OpenStorageTrie(addrHash, root common.Hash) (Trie, error) {
6464
//return SimpleTrie{db.BlockNumber, root, true, addrHash}, nil
65-
tr, err := trie.NewSecure(root, db.db)
65+
tr, err := trie.NewSecure(root, db.db, true)
6666
if err != nil {
6767
return nil, err
6868
}

geth-utils/gethutil/mpt/state/statedb.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,12 @@ func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
298298

299299
// GetProof returns the Merkle proof for a given account.
300300
func (s *StateDB) GetProof(addr common.Address) ([][]byte, []byte, [][]byte, bool, bool, error) {
301-
return s.GetProofByHash(crypto.Keccak256Hash(addr.Bytes()))
301+
newAddr := crypto.Keccak256Hash(addr.Bytes())
302+
if oracle.AccountPreventHashingInSecureTrie {
303+
bytes := append(addr.Bytes(), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}...)
304+
newAddr = common.BytesToHash(bytes)
305+
}
306+
return s.GetProofByHash(newAddr)
302307
}
303308

304309
// GetProofByHash returns the Merkle proof for a given account.
@@ -311,7 +316,13 @@ func (s *StateDB) GetProofByHash(addrHash common.Hash) ([][]byte, []byte, [][]by
311316
// GetStorageProof returns the Merkle proof for given storage slot.
312317
func (s *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte, []byte, [][]byte, bool, bool, error) {
313318
var proof proofList
314-
trie := s.StorageTrie(a)
319+
newAddr := a
320+
if oracle.AccountPreventHashingInSecureTrie {
321+
bytes := append(a.Bytes(), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}...)
322+
newAddr = common.BytesToAddress(bytes)
323+
}
324+
325+
trie := s.StorageTrie(newAddr)
315326
if trie == nil {
316327
return proof, nil, nil, false, false, errors.New("storage trie for requested address does not exist")
317328
}
@@ -457,7 +468,7 @@ func (s *StateDB) SetStateObjectIfExists(addr common.Address) {
457468
}
458469

459470
/*
460-
When an account that does not exist is tried to be fetched by PrefetchAccount and when the some other account
471+
When an account that does not exist is being fetched by PrefetchAccount and when some other account
461472
exist at the overlapping address (the beginning of it), this (wrong) account is obtained by PrefetchAccount
462473
and needs to be ignored.
463474
*/
@@ -533,8 +544,15 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
533544
if err != nil {
534545
panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
535546
}
536-
if err = s.trie.TryUpdateAlwaysHash(addr[:], data); err != nil {
537-
s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err))
547+
548+
if !oracle.AccountPreventHashingInSecureTrie {
549+
if err = s.trie.TryUpdateAlwaysHash(addr[:], data); err != nil {
550+
s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err))
551+
}
552+
} else {
553+
if err = s.trie.TryUpdate(addr[:], data); err != nil {
554+
s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err))
555+
}
538556
}
539557

540558
// If state snapshotting is active, cache the data til commit. Note, this

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -102,33 +102,27 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) (
102102
fromLevel--
103103
continue
104104
}
105-
// var hn Node
106105

107106
// We need nibbles in witness for extension keys.
108107
// copy n.Key before it gets changed in ProofHash
109108
var nCopy []byte
110109
if short, ok := n.(*ShortNode); ok {
111-
if !hasTerm(short.Key) { // only for extension keys
110+
if !hasTerm(short.Key) { // extension keys
112111
nCopy = make([]byte, len(short.Key))
113112
copy(nCopy, short.Key)
114113
extNibbles = append(extNibbles, nCopy)
114+
} else {
115+
extNibbles = append(extNibbles, []byte{})
115116
}
117+
} else {
118+
extNibbles = append(extNibbles, []byte{})
116119
}
117120

118-
// n, hn = hasher.ProofHash(n)
119121
n, _ = hasher.ProofHash(n)
120-
// if hash, ok := hn.(HashNode); ok || i == 0 {
121122
// If the node's database encoding is a hash (or is the
122123
// root node), it becomes a proof element.
123124
enc, _ := rlp.EncodeToBytes(n)
124-
/*
125-
if !ok {
126-
hash = hasher.HashData(enc)
127-
}
128-
*/
129-
// proofDb.Put(hash, enc)
130125
proofDb.Put([]byte{1, 1, 1}, enc)
131-
// }
132126
}
133127

134128
isNeighbourNodeHashed := false

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type SecureTrie struct {
4040
hashKeyBuf [common.HashLength]byte
4141
secKeyCache map[string][]byte
4242
secKeyCacheOwner *SecureTrie // Pointer to self, replace the key cache on mismatch
43+
isStorageTrie bool
4344
}
4445

4546
// NewSecure creates a trie with an existing root node from a backing database
@@ -53,15 +54,15 @@ type SecureTrie struct {
5354
// Loaded nodes are kept around until their 'cache generation' expires.
5455
// A new cache generation is created by each call to Commit.
5556
// cachelimit sets the number of past cache generations to keep.
56-
func NewSecure(root common.Hash, db *Database) (*SecureTrie, error) {
57+
func NewSecure(root common.Hash, db *Database, isStorageTrie bool) (*SecureTrie, error) {
5758
if db == nil {
5859
panic("trie.NewSecure called without a database")
5960
}
6061
trie, err := New(root, db)
6162
if err != nil {
6263
return nil, err
6364
}
64-
return &SecureTrie{trie: *trie}, nil
65+
return &SecureTrie{trie: *trie, isStorageTrie: isStorageTrie}, nil
6566
}
6667

6768
// Get returns the value for key stored in the trie.
@@ -202,7 +203,8 @@ func (t *SecureTrie) NodeIterator(start []byte) NodeIterator {
202203
// The caller must not hold onto the return value because it will become
203204
// invalid on the next call to hashKey or secKey.
204205
func (t *SecureTrie) hashKey(key []byte) []byte {
205-
if !oracle.PreventHashingInSecureTrie {
206+
preventHashing := (oracle.PreventHashingInSecureTrie && t.isStorageTrie) || (oracle.AccountPreventHashingInSecureTrie && !t.isStorageTrie)
207+
if !preventHashing {
206208
h := NewHasher(false)
207209
h.sha.Reset()
208210
h.sha.Write(key)
@@ -211,6 +213,9 @@ func (t *SecureTrie) hashKey(key []byte) []byte {
211213
return t.hashKeyBuf[:]
212214
} else {
213215
// For generating special tests for MPT circuit.
216+
if len(key) < 32 { // accounts
217+
key = append(key, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}...)
218+
}
214219
return key
215220
}
216221
}

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ func prepareBranchWitness(rows [][]byte, branch []byte, branchStart int, branchR
7070
func prepareBranchNode(
7171
branch1, branch2, extNode1, extNode2, extListRlpBytes []byte,
7272
extValues [][]byte, key, driftedInd byte,
73-
isBranchSPlaceholder, isBranchCPlaceholder, isExtension bool) Node {
74-
73+
isBranchSPlaceholder, isBranchCPlaceholder, isExtension, isLastLevel bool) Node {
7574
extensionNode := ExtensionNode{
7675
ListRlpBytes: extListRlpBytes,
7776
}
@@ -118,10 +117,11 @@ func prepareBranchNode(
118117
}
119118

120119
extensionBranch := ExtensionBranchNode{
121-
IsExtension: isExtension,
122-
IsPlaceholder: [2]bool{isBranchSPlaceholder, isBranchCPlaceholder},
123-
Extension: extensionNode,
124-
Branch: branchNode,
120+
IsExtension: isExtension,
121+
IsPlaceholder: [2]bool{isBranchSPlaceholder, isBranchCPlaceholder},
122+
IsLastLevelAndWrongExtCase: isLastLevel,
123+
Extension: extensionNode,
124+
Branch: branchNode,
125125
}
126126

127127
values := make([][]byte, 17)
@@ -311,10 +311,14 @@ func addBranchAndPlaceholder(
311311
driftedInd := getDriftedPosition(leafRow0, numberOfNibbles)
312312
if len1 > len2 {
313313
node = prepareBranchNode(proof1[len1-2], proof1[len1-2], extNode, extNode, extListRlpBytes, extValues,
314-
key[keyIndex+numberOfNibbles], driftedInd, false, true, isExtension)
314+
key[keyIndex+numberOfNibbles], driftedInd, false, true, isExtension, false)
315+
316+
// We now get the first nibble of the leaf that was turned into branch.
317+
// This first nibble presents the position of the leaf once it moved
318+
// into the new branch.
315319
} else {
316320
node = prepareBranchNode(proof2[len2-2], proof2[len2-2], extNode, extNode, extListRlpBytes, extValues,
317-
key[keyIndex+numberOfNibbles], driftedInd, true, false, isExtension)
321+
key[keyIndex+numberOfNibbles], driftedInd, true, false, isExtension, false)
318322
}
319323

320324
return isModifiedExtNode, isExtension, numberOfNibbles, node

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

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func getStorageRootCodeHashValue(leaf []byte, storageStart int) ([]byte, []byte)
122122
return storageRootValue, codeHashValue
123123
}
124124

125-
func prepareAccountLeafNode(addr common.Address, addrh []byte, leafS, leafC, neighbourNode, addressNibbles []byte, isPlaceholder, isSModExtension, isCModExtension bool) Node {
125+
func prepareAccountLeafNode(addr common.Address, addrh []byte, leafS, leafC, constructedLeaf, neighbourNode, addressNibbles []byte, isPlaceholder, isSModExtension, isCModExtension bool) Node {
126126
// For non existing account proof there are two cases:
127127
// 1. A leaf is returned that is not at the required address (wrong leaf).
128128
// 2. A branch is returned as the last element of getProof and
@@ -174,12 +174,19 @@ func prepareAccountLeafNode(addr common.Address, addrh []byte, leafS, leafC, nei
174174

175175
// wrongValue is used only for proof that account doesn't exist
176176

177+
wrongLeaf := leafC
178+
wrongLen := keyLenC
179+
if constructedLeaf != nil {
180+
wrongLeaf = constructedLeaf
181+
wrongLen = int(constructedLeaf[2]) - 128
182+
}
183+
177184
offset := 0
178-
nibblesNum := (keyLenC - 1) * 2
179-
wrongRlpBytes[0] = leafC[0]
180-
wrongRlpBytes[1] = leafC[1]
181-
wrongValue[0] = leafC[2] // length
182-
if leafC[3] != 32 { // odd number of nibbles
185+
nibblesNum := (wrongLen - 1) * 2
186+
wrongRlpBytes[0] = wrongLeaf[0]
187+
wrongRlpBytes[1] = wrongLeaf[1]
188+
wrongValue[0] = wrongLeaf[2] // length
189+
if wrongLeaf[3] != 32 { // odd number of nibbles
183190
nibblesNum = nibblesNum + 1
184191
wrongValue[1] = addressNibbles[64-nibblesNum] + 48
185192
offset = 1
@@ -327,7 +334,7 @@ func prepareLeafAndPlaceholderNode(addr common.Address, addrh []byte, proof1, pr
327334

328335
// When generating a proof that account doesn't exist, the length of both proofs is the same (doesn't reach
329336
// this code).
330-
return prepareAccountLeafNode(addr, addrh, leafS, leafC, nil, key, false, isSModExtension, isCModExtension)
337+
return prepareAccountLeafNode(addr, addrh, leafS, leafC, nil, nil, key, false, isSModExtension, isCModExtension)
331338
} else {
332339
var leaf []byte
333340
isSPlaceholder := false
@@ -341,7 +348,7 @@ func prepareLeafAndPlaceholderNode(addr common.Address, addrh []byte, proof1, pr
341348
isSPlaceholder = true
342349
}
343350

344-
return prepareStorageLeafNode(leaf, leaf, nil, storage_key, key, false, isSPlaceholder, isCPlaceholder, isSModExtension, isCModExtension)
351+
return prepareStorageLeafNode(leaf, leaf, nil, nil, storage_key, key, false, isSPlaceholder, isCPlaceholder, isSModExtension, isCModExtension)
345352
}
346353
}
347354

@@ -451,7 +458,7 @@ func prepareAccountLeafPlaceholderNode(addr common.Address, addrh, key []byte, k
451458
leaf[4+i] = remainingNibbles[2*i+offset]*16 + remainingNibbles[2*i+1+offset]
452459
}
453460

454-
node := prepareAccountLeafNode(addr, addrh, leaf, leaf, nil, key, true, false, false)
461+
node := prepareAccountLeafNode(addr, addrh, leaf, leaf, nil, nil, key, true, false, false)
455462

456463
node.Account.ValueRlpBytes[0][0] = 184
457464
node.Account.ValueRlpBytes[0][1] = 70
@@ -480,7 +487,7 @@ func prepareStorageLeafPlaceholderNode(storage_key common.Hash, key []byte, keyI
480487
keyLen := getLeafKeyLen(keyIndex)
481488
leaf[0] = 192 + 1 + byte(keyLen) + 1
482489

483-
return prepareStorageLeafNode(leaf, leaf, nil, storage_key, key, false, true, true, false, false)
490+
return prepareStorageLeafNode(leaf, leaf, nil, nil, storage_key, key, false, true, true, false, false)
484491
}
485492

486493
func setKeyValue(row, keyRlp []byte, keyLen, offset byte, valueIsZero, isPlaceholder bool) ([]byte, []byte, []byte) {
@@ -592,7 +599,7 @@ func prepareStorageLeafInfo(row []byte, valueIsZero, isPlaceholder bool) ([]byte
592599
return key, value, keyRlp, valueRlp
593600
}
594601

595-
func prepareStorageLeafNode(leafS, leafC, neighbourNode []byte, storage_key common.Hash, key []byte, nonExistingStorageProof, isSPlaceholder, isCPlaceholder, isSModExtension, isCModExtension bool) Node {
602+
func prepareStorageLeafNode(leafS, leafC, constructedLeaf, neighbourNode []byte, storage_key common.Hash, key []byte, nonExistingStorageProof, isSPlaceholder, isCPlaceholder, isSModExtension, isCModExtension bool) Node {
596603
var rows [][]byte
597604

598605
keyS, valueS, listRlpBytes1, valueRlpBytes1 := prepareStorageLeafInfo(leafS, false, isSPlaceholder)
@@ -623,7 +630,11 @@ func prepareStorageLeafNode(leafS, leafC, neighbourNode []byte, storage_key comm
623630
var nonExistingStorageRow []byte
624631
var wrongRlpBytes []byte
625632
if nonExistingStorageProof {
626-
wrongRlpBytes, nonExistingStorageRow = prepareNonExistingStorageRow(leafC, key)
633+
if constructedLeaf != nil {
634+
wrongRlpBytes, nonExistingStorageRow = prepareNonExistingStorageRow(constructedLeaf, key)
635+
} else {
636+
wrongRlpBytes, nonExistingStorageRow = prepareNonExistingStorageRow(leafC, key)
637+
}
627638
} else {
628639
nonExistingStorageRow = prepareEmptyNonExistingStorageRow()
629640
}
@@ -645,6 +656,7 @@ func prepareStorageLeafNode(leafS, leafC, neighbourNode []byte, storage_key comm
645656
ValueRlpBytes: valueRlpBytes,
646657
IsModExtension: [2]bool{isSModExtension, isCModExtension},
647658
}
659+
648660
keccakData := [][]byte{leafS, leafC, storage_key.Bytes()}
649661
if neighbourNode != nil {
650662
keccakData = append(keccakData, neighbourNode)
@@ -657,3 +669,38 @@ func prepareStorageLeafNode(leafS, leafC, neighbourNode []byte, storage_key comm
657669

658670
return node
659671
}
672+
673+
func equipLeafWithWrongExtension(leafNode Node, keyMiddle, keyAfter, nibblesMiddle, nibblesAfter []byte) Node {
674+
l := len(leafNode.Values)
675+
leafNode.Values[l-modifiedExtensionNodeRowLen] = keyMiddle
676+
startNibblePos := 2 // we don't need any nibbles for case keyLen = 1
677+
if len(keyMiddle) > 1 {
678+
if len(nibblesMiddle)%2 == 0 {
679+
startNibblePos = 1
680+
} else {
681+
startNibblePos = 2
682+
}
683+
}
684+
ind := 0
685+
for j := startNibblePos; j < len(nibblesMiddle); j += 2 {
686+
leafNode.Values[l-modifiedExtensionNodeRowLen+1][2+ind] = nibblesMiddle[j]
687+
ind++
688+
}
689+
690+
leafNode.Values[l-modifiedExtensionNodeRowLen+3] = keyAfter
691+
startNibblePos = 2 // we don't need any nibbles for case keyLen = 1
692+
if len(keyAfter) > 1 {
693+
if len(nibblesAfter)%2 == 0 {
694+
startNibblePos = 1
695+
} else {
696+
startNibblePos = 2
697+
}
698+
}
699+
ind = 0
700+
for j := startNibblePos; j < len(nibblesAfter); j += 2 {
701+
leafNode.Values[l-modifiedExtensionNodeRowLen+4][2+ind] = nibblesAfter[j]
702+
ind++
703+
}
704+
705+
return leafNode
706+
}

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,6 @@ func equipLeafWithModExtensionNode(
5656
longExtNodeKey[j] = longNibbles[j-byte(keyIndex)]
5757
}
5858

59-
k := trie.HexToKeybytes(longExtNodeKey)
60-
ky := common.BytesToHash(k)
61-
var proof [][]byte
62-
var err error
63-
if !isTxProof {
64-
if isAccountProof {
65-
proof, _, _, _, _, err = statedb.GetProof(addr)
66-
} else {
67-
proof, _, _, _, _, err = statedb.GetStorageProof(addr, ky)
68-
}
69-
check(err)
70-
}
71-
7259
// There is no short extension node when `len(longNibbles) - numberOfNibbles = 1`, in this case there
7360
// is simply a branch instead.
7461
// stack trie is always a short ext node.
@@ -79,6 +66,19 @@ func equipLeafWithModExtensionNode(
7966
var extValuesC [][]byte
8067

8168
if !shortExtNodeIsBranch {
69+
k := trie.HexToKeybytes(longExtNodeKey)
70+
ky := common.BytesToHash(k)
71+
var proof [][]byte
72+
var err error
73+
if !isTxProof {
74+
if isAccountProof {
75+
proof, _, _, _, _, err = statedb.GetProof(addr)
76+
} else {
77+
proof, _, _, _, _, err = statedb.GetStorageProof(addr, ky)
78+
}
79+
}
80+
check(err)
81+
8282
if len2 > len1 {
8383
isItBranch := isBranch(proof[len(proof)-1])
8484

0 commit comments

Comments
 (0)