diff --git a/geth-utils/gethutil/mpt/trie/stacktrie.go b/geth-utils/gethutil/mpt/trie/stacktrie.go index adec28e2641..115eb80a6a5 100644 --- a/geth-utils/gethutil/mpt/trie/stacktrie.go +++ b/geth-utils/gethutil/mpt/trie/stacktrie.go @@ -664,7 +664,7 @@ func printProof(ps [][]byte) { } func (st *StackTrie) UpdateAndGetProof(db ethdb.KeyValueReader, indexBuf, value []byte) (StackProof, error) { - fmt.Println("====") + fmt.Println(" ====") proofS, nibblesS, err := st.GetProof(db, indexBuf) if err != nil { return StackProof{}, err @@ -679,7 +679,6 @@ func (st *StackTrie) UpdateAndGetProof(db ethdb.KeyValueReader, indexBuf, value return StackProof{}, err } len2 := len(proofC) - fmt.Println(" Proof S C ", len1, len2) printProof(proofC) // fmt.Println(len1, len2) @@ -703,6 +702,7 @@ func (st *StackTrie) UpdateAndGetProofs(db ethdb.KeyValueReader, list types.Deri // order is correct. var indexBuf []byte for i := 1; i < list.Len() && i <= 0x7f; i++ { + fmt.Print(i) indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) value := types.EncodeForDerive(list, i, valueBuf) proof, err := st.UpdateAndGetProof(db, indexBuf, value) @@ -715,6 +715,7 @@ func (st *StackTrie) UpdateAndGetProofs(db ethdb.KeyValueReader, list types.Deri // special case when index is 0 // rlp.AppendUint64() encodes index 0 to [128] if list.Len() > 0 { + fmt.Print("0") indexBuf = rlp.AppendUint64(indexBuf[:0], 0) value := types.EncodeForDerive(list, 0, valueBuf) proof, err := st.UpdateAndGetProof(db, indexBuf, value) @@ -725,6 +726,7 @@ func (st *StackTrie) UpdateAndGetProofs(db ethdb.KeyValueReader, list types.Deri } for i := 0x80; i < list.Len(); i++ { + fmt.Print(i) indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) value := types.EncodeForDerive(list, i, valueBuf) proof, err := st.UpdateAndGetProof(db, indexBuf, value) @@ -740,7 +742,7 @@ func (st *StackTrie) UpdateAndGetProofs(db ethdb.KeyValueReader, list types.Deri func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, [][]byte, error) { k := KeybytesToHex(key) - fmt.Println("k", k) + // fmt.Println("k", k) if st.nodeType == emptyNode { return [][]byte{}, nil, nil } @@ -832,8 +834,8 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, [] // fmt.Println("** ", element) // FIXME only one nibble case - nibble := element[0] - // fmt.Println(" Ext nibble:", nibble) + nibble := element[0] - 16 + // fmt.Println(" Ext nibble:", element) nibbles = append(nibbles, []byte{nibble}) } } @@ -844,9 +846,5 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, [] slices.Reverse(proof) } - // given a default value - if len(nibbles) == 0 { - nibbles = append(nibbles, []byte{0}) - } return proof, nibbles, nil } diff --git a/geth-utils/gethutil/mpt/witness/branch.go b/geth-utils/gethutil/mpt/witness/branch.go index e3066712104..fe72b2cc354 100644 --- a/geth-utils/gethutil/mpt/witness/branch.go +++ b/geth-utils/gethutil/mpt/witness/branch.go @@ -31,9 +31,12 @@ func isTxLeaf(proofEl []byte) bool { check(err) c, err1 := rlp.CountValues(elems) check(err1) - fmt.Println("ISLEAF:", c) + isHashedNode := false + if proofEl[0] == 226 && proofEl[1] == 32 && proofEl[2] == 160 { + isHashedNode = true + } // 9: for tx (Nonce, Gas, GasPrice, Value, To, Data, r, s, v) - return c == 9 + return c == 9 || isHashedNode } // prepareBranchWitness takes the rows that are to be filled with branch data and it takes @@ -84,8 +87,11 @@ func prepareBranchWitness(rows [][]byte, branch []byte, branchStart int, branchR } } -func prepareBranchNode(branch1, branch2, extNode1, extNode2, extListRlpBytes []byte, extValues [][]byte, key, driftedInd byte, +func prepareBranchNode( + branch1, branch2, extNode1, extNode2, extListRlpBytes []byte, + extValues [][]byte, key, driftedInd byte, isBranchSPlaceholder, isBranchCPlaceholder, isExtension bool) Node { + extensionNode := ExtensionNode{ ListRlpBytes: extListRlpBytes, } @@ -244,7 +250,10 @@ func addBranchAndPlaceholder(proof1, proof2, extNibblesS, extNibblesC [][]byte, // For stack trie // if 1 st node of proof2 is a branch node and 1st node of Proof1 is an ext node need_placeholder_ext := isBranch(proof2[0]) && (!isTxLeaf(proof1[0]) && !isBranch(proof1[0])) - + if need_placeholder_ext { + fmt.Println("need_placeholder_ext", isTxLeaf(proof1[0]), isBranch(proof1[0]), proof1[0]) + fmt.Println("need_placeholder_ext", isBranch(proof2[0]), proof2[0]) + } isExtension := (len1 == len2+2) || (len2 == len1+2) if isExtension || need_placeholder_ext { var numNibbles byte @@ -301,6 +310,8 @@ func addBranchAndPlaceholder(proof1, proof2, extNibblesS, extNibblesC [][]byte, var extNode []byte if need_placeholder_ext { extNode = proof1[0] + // FIXME should move to above and need to avoid above [len-3] operation + isExtension = need_placeholder_ext } else { if isExtension { if len1 > len2 { @@ -311,9 +322,6 @@ func addBranchAndPlaceholder(proof1, proof2, extNibblesS, extNibblesC [][]byte, } } - // FIXME should move to above and need to avoid above [len-3] operation - isExtension = need_placeholder_ext - // Note that isModifiedExtNode happens also when we have a branch instead of shortExtNode isModifiedExtNode := (!isBranch(longExtNode) && !isShorterProofLastLeaf) || need_placeholder_ext @@ -324,7 +332,6 @@ func addBranchAndPlaceholder(proof1, proof2, extNibblesS, extNibblesC [][]byte, if len1 > len2 { node = prepareBranchNode(proof1[len1-2], proof1[len1-2], extNode, extNode, extListRlpBytes, extValues, key[keyIndex+numberOfNibbles], driftedInd, false, true, isExtension) - } else { node = prepareBranchNode(proof2[len2-2], proof2[len2-2], extNode, extNode, extListRlpBytes, extValues, key[keyIndex+numberOfNibbles], driftedInd, true, false, isExtension) diff --git a/geth-utils/gethutil/mpt/witness/gen_witness_from_local_blockchain_test.go b/geth-utils/gethutil/mpt/witness/gen_witness_from_local_blockchain_test.go index 8471fb63534..e769031e829 100644 --- a/geth-utils/gethutil/mpt/witness/gen_witness_from_local_blockchain_test.go +++ b/geth-utils/gethutil/mpt/witness/gen_witness_from_local_blockchain_test.go @@ -922,3 +922,20 @@ func TestExtNodeDeletedExtShortIsBranchFirstLevel(t *testing.T) { ExtNodeDeleted(key1, key2, key3, "ExtNodeDeletedExtShortIsBranchFirstLevel") } + +func TestSimulateStackTrieUnder128Txs(t *testing.T) { + SkipIfNoGeth(t) + // The trie is empty before we add key1, key2, key3. + key1 := common.HexToHash("0x2345610000000000000000000000000000000000000000000000000000000000") + // After inserting key1, there is only one leaf in the trie. + + key2 := common.HexToHash("0x2345630000000000000000000000000000000000000000000000000000000000") + // After inserting key2, we have an extension node E in the trie with the following nibbles: 2 3 4 5 6. + // The branch of the extension node has two leaves - key1 at position 1 and key2 at position 3. + + key3 := common.HexToHash("0x2345800000000000000000000000000000000000000000000000000000000000") + // After inserting key3, we have an extension node E1 with nibbles: 2 3 4 5. + // The branch of E1 has two nodes: the branch at position 6 and the leaf at position 8. + + ExtNodeInserted(key1, key2, key3, "ExtNodeInsertedExtShortIsBranchSecondLevel") +} diff --git a/geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go b/geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go index b754bf0d340..a2f1ab0ad32 100644 --- a/geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go +++ b/geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go @@ -121,7 +121,7 @@ func transactionsStackTrieInsertionTemplate(t *testing.T, n int) { } func TestTransactionInsertion(t *testing.T) { - txs := makeTransactions(4) + txs := makeTransactions(256) prepareStackTrieWitness("TransactionInsertion", types.Transactions(txs)) } diff --git a/geth-utils/gethutil/mpt/witness/leaf.go b/geth-utils/gethutil/mpt/witness/leaf.go index c301253445e..ac27d4d2b11 100644 --- a/geth-utils/gethutil/mpt/witness/leaf.go +++ b/geth-utils/gethutil/mpt/witness/leaf.go @@ -163,7 +163,7 @@ func prepareAccountLeafNode(addr common.Address, addrh []byte, leafS, leafC, nei driftedRlpBytes := []byte{0} keyDrifted := make([]byte, valueLen) if neighbourNode != nil { - keyDrifted, _, driftedRlpBytes, _ = prepareStorageLeafInfo(neighbourNode, false, false) + keyDrifted, _, driftedRlpBytes, _ = prepareStorageLeafInfo(neighbourNode, false, false, false) } wrongValue := make([]byte, valueLen) @@ -349,12 +349,12 @@ func prepareLeafAndPlaceholderNode(addr common.Address, addrh []byte, proof1, pr func prepareTxLeafNode(idx uint, leafS, leafC, key, neighborNode []byte, isSPlaceholder, isSModExtension, isCModExtension bool) Node { var rows [][]byte - keyS, valueS, listRlpBytes1, valueRlpBytes1 := prepareStorageLeafInfo(leafS, false, isSPlaceholder) + keyS, valueS, listRlpBytes1, valueRlpBytes1 := prepareStorageLeafInfo(leafS, false, isSPlaceholder, true) rows = append(rows, keyS) rows = append(rows, valueS) - keyC, valueC, listRlpBytes2, valueRlpBytes2 := prepareStorageLeafInfo(leafC, false, false) + keyC, valueC, listRlpBytes2, valueRlpBytes2 := prepareStorageLeafInfo(leafC, false, false, true) rows = append(rows, keyC) rows = append(rows, valueC) @@ -370,15 +370,10 @@ func prepareTxLeafNode(idx uint, leafS, leafC, key, neighborNode []byte, isSPlac driftedRlpBytes := []byte{0} keyDrifted := make([]byte, valueLen) if neighborNode != nil { - keyDrifted, _, driftedRlpBytes, _ = prepareStorageLeafInfo(neighborNode, false, false) + keyDrifted, _, driftedRlpBytes, _ = prepareStorageLeafInfo(neighborNode, false, false, true) } rows = append(rows, keyDrifted) - // var nonExistingStorageRow []byte - // var wrongRlpBytes []byte - // nonExistingStorageRow = prepareEmptyNonExistingStorageRow() - // rows = append(rows, nonExistingStorageRow) - // These rows are only used in the case of a modified extension node. // These rows are actually set in equipLeafWithModExtensionNode function. for i := 0; i < modifiedExtensionNodeRowLen; i++ { @@ -489,7 +484,7 @@ func prepareStorageLeafPlaceholderNode(storage_key common.Hash, key []byte, keyI return prepareStorageLeafNode(leaf, leaf, nil, storage_key, key, false, true, true, false, false) } -func prepareStorageLeafInfo(row []byte, valueIsZero, isPlaceholder bool) ([]byte, []byte, []byte, []byte) { +func prepareStorageLeafInfo(row []byte, valueIsZero, isPlaceholder, isTxLeaf bool) ([]byte, []byte, []byte, []byte) { var keyRlp []byte var valueRlp []byte var keyRlpLen byte @@ -520,51 +515,62 @@ func prepareStorageLeafInfo(row []byte, valueIsZero, isPlaceholder bool) ([]byte keyLen := byte(0) offset := byte(1) - if len(row) < 32 { // the node doesn't get hashed in this case + if isTxLeaf { keyRlpLen = 1 keyRlp = make([]uint8, keyRlpLen) copy(keyRlp, row[:keyRlpLen]) - - // 192 + 32 = 224 - if row[1] < 128 { - // last level: [194,32,1] - // or - // only one nibble in a leaf (as soon as the leaf has two nibbles, row[1] will have 128 + length) - // [194,48,1] - this one contains nibble 0 = 48 - 48 - keyLen = byte(1) - copy(key, row[keyRlpLen:keyLen+1]) - offset = byte(1) - } else { - // [196,130,32,0,1] - keyLen = row[1] - 128 - copy(key, row[keyRlpLen:keyLen+2]) - offset = byte(2) - } - } else if row[0] == 248 { - // [248,67,160,59,138,106,70,105,186,37,13,38,205,122,69,158,202,157,33,95,131,7,227,58,235,229,3,121,188,90,54,23,236,52,68,161,160,... - keyRlpLen = 2 - keyLen = row[2] - 128 - keyRlp = row[:keyRlpLen] - copy(key, row[keyRlpLen:keyLen+3]) - offset = byte(3) + // [248 200 129 128 131 4 147 224 98 148 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 130 5 9 184 100 0 0 0 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 ...] + key[0] = row[0] + key[1] = row[1] + keyLen = byte(2) + offset = byte(0) } else { - keyRlpLen = 1 - keyRlp = make([]uint8, keyRlpLen) - copy(keyRlp, row[:keyRlpLen]) - if row[1] < 128 { - // last level: - // [227,32,161,160,187,239,170,18,88,1,56,188,38,60,149,117,120,38,223,78,36,235,129,201,170,170,170,170,170,170,170,170,170,170,170,170] - // one nibble: - // [227,48,161,160,187,239,170,18,88,1,56,188,38,60,149,117,120,38,223,78,36,235,129,201,170,170,170,170,170,170,170,170,170,170,170,170] - key[0] = row[0] - key[1] = row[1] - keyLen = byte(2) - offset = byte(0) + if len(row) < 32 { // the node doesn't get hashed in this case + keyRlpLen = 1 + keyRlp = make([]uint8, keyRlpLen) + copy(keyRlp, row[:keyRlpLen]) + + // 192 + 32 = 224 + if row[1] < 128 { + // last level: [194,32,1] + // or + // only one nibble in a leaf (as soon as the leaf has two nibbles, row[1] will have 128 + length) + // [194,48,1] - this one contains nibble 0 = 48 - 48 + keyLen = byte(1) + copy(key, row[keyRlpLen:keyLen+1]) + offset = byte(1) + } else { + // [196,130,32,0,1] + keyLen = row[1] - 128 + copy(key, row[keyRlpLen:keyLen+2]) + offset = byte(2) + } + } else if row[0] == 248 { + // [248,67,160,59,138,106,70,105,186,37,13,38,205,122,69,158,202,157,33,95,131,7,227,58,235,229,3,121,188,90,54,23,236,52,68,161,160,... + keyRlpLen = 2 + keyLen = row[2] - 128 + keyRlp = row[:keyRlpLen] + copy(key, row[keyRlpLen:keyLen+3]) + offset = byte(3) } else { - // [226,160,59,138,106,70,105,186,37,13,38[227,32,161,160,187,239,170,18,88,1,56,188,38,60,149,117,120,38,223,78,36,235,129,201,170,170,170,170,170,170,170,170,170,170,170,170] - keyLen = row[1] - 128 - copy(key, row[keyRlpLen:keyLen+2]) - offset = byte(2) + keyRlpLen = 1 + keyRlp = make([]uint8, keyRlpLen) + copy(keyRlp, row[:keyRlpLen]) + if row[1] < 128 { + // last level: + // [227,32,161,160,187,239,170,18,88,1,56,188,38,60,149,117,120,38,223,78,36,235,129,201,170,170,170,170,170,170,170,170,170,170,170,170] + // one nibble: + // [227,48,161,160,187,239,170,18,88,1,56,188,38,60,149,117,120,38,223,78,36,235,129,201,170,170,170,170,170,170,170,170,170,170,170,170] + key[0] = row[0] + key[1] = row[1] + keyLen = byte(2) + offset = byte(0) + } else { + // [226,160,59,138,106,70,105,186,37,13,38[227,32,161,160,187,239,170,18,88,1,56,188,38,60,149,117,120,38,223,78,36,235,129,201,170,170,170,170,170,170,170,170,170,170,170,170] + keyLen = row[1] - 128 + copy(key, row[keyRlpLen:keyLen+2]) + offset = byte(2) + } } } setKeyValue(keyLen, offset) @@ -575,12 +581,12 @@ func prepareStorageLeafInfo(row []byte, valueIsZero, isPlaceholder bool) ([]byte func prepareStorageLeafNode(leafS, leafC, neighbourNode []byte, storage_key common.Hash, key []byte, nonExistingStorageProof, isSPlaceholder, isCPlaceholder, isSModExtension, isCModExtension bool) Node { var rows [][]byte - keyS, valueS, listRlpBytes1, valueRlpBytes1 := prepareStorageLeafInfo(leafS, false, isSPlaceholder) + keyS, valueS, listRlpBytes1, valueRlpBytes1 := prepareStorageLeafInfo(leafS, false, isSPlaceholder, false) rows = append(rows, keyS) rows = append(rows, valueS) - keyC, valueC, listRlpBytes2, valueRlpBytes2 := prepareStorageLeafInfo(leafC, false, isCPlaceholder) + keyC, valueC, listRlpBytes2, valueRlpBytes2 := prepareStorageLeafInfo(leafC, false, isCPlaceholder, false) fmt.Println("-", key) fmt.Println("-", keyS, leafS) @@ -600,7 +606,7 @@ func prepareStorageLeafNode(leafS, leafC, neighbourNode []byte, storage_key comm driftedRlpBytes := []byte{0} keyDrifted := make([]byte, valueLen) if neighbourNode != nil { - keyDrifted, _, driftedRlpBytes, _ = prepareStorageLeafInfo(neighbourNode, false, false) + keyDrifted, _, driftedRlpBytes, _ = prepareStorageLeafInfo(neighbourNode, false, false, false) } rows = append(rows, keyDrifted) diff --git a/geth-utils/gethutil/mpt/witness/prepare_witness.go b/geth-utils/gethutil/mpt/witness/prepare_witness.go index 6ddbd6d95b6..2d9adb0f352 100644 --- a/geth-utils/gethutil/mpt/witness/prepare_witness.go +++ b/geth-utils/gethutil/mpt/witness/prepare_witness.go @@ -301,10 +301,19 @@ func prepareStackTrieWitness(testName string, list types.DerivableList) { var key []byte var nodes []Node for i, proof := range proofs { - // fmt.Println("* PROOF", i) + // i := len(proofs) - 1 + // proof := proofs[i] + idx := i + 1 + fmt.Println("* PROOF", idx) nodes = append(nodes, GetStartNode(testName, common.Hash{}, root, 0)) - key = rlp.AppendUint64(key[:0], uint64(i)) - node := GenerateWitness(uint(i), key, key, &proof) + var node []Node + if (i <= 0x7f && len(proofs)-1 == i) || i == 127 { + // key = rlp.AppendUint64(key[:0], uint64(0)) + // node = GenerateWitness(uint(0), key, key, &proof) + } else { + key = rlp.AppendUint64(key[:0], uint64(idx)) + node = GenerateWitness(uint(idx), key, key, &proof) + } nodes = append(nodes, node...) nodes = append(nodes, GetEndNode()) } @@ -332,8 +341,10 @@ func prepareWitnessSpecial(testName string, trieModifications []TrieModification func GenerateWitness(txIdx uint, key, value []byte, proof *trie.StackProof) []Node { k := trie.KeybytesToHex(key) k = k[:len(k)-1] + // padding k to 32 bytes kk := make([]byte, 32-len(k)) k = append(k, kk...) + fmt.Println("txIdx", txIdx) toBeHashed := make([][]byte, 0) proofS := proof.GetProofS() @@ -347,20 +358,24 @@ func GenerateWitness(txIdx uint, key, value []byte, proof *trie.StackProof) []No len1 := len(proofS) len2 := len(proofC) - is_end_of_leaf := true + is_end_with_leaf := true if len1 > 0 { // len = 0 when trie trie is empty - is_end_of_leaf = isTxLeaf(proofS[len1-1]) + is_end_with_leaf = isTxLeaf(proofS[len1-1]) + } + + isStartWithExt := false + if len1 > 0 && (!isBranch(proofS[0]) && !isTxLeaf(proofS[0])) { + isStartWithExt = true } upTo := minLen additionalBranch := false - // In stack trie, proofC is always end up with a leaf node - // If proofS is not end up with a leaf, we need to make their length equal by setting additionalBranch to true - // For example, when the num of txs is less than 128, the last proof will be the first tx (aka. tx id is 0) - // and the first tx will be inserted at the position 8. - // The proof will be like this proofS: [ext - branch] and proofC: [branch - leaf] - if !is_end_of_leaf || (len1 < len2 && len1 > 0) { + // In stack trie, proofC is always end up with a leaf node, but it's not the case for proofS. + // So, basically additionalBranch is always true, even when len1 == len2 + if len1 > 0 { additionalBranch = true + } + if len1 == len2 { upTo = minLen - 1 } @@ -376,25 +391,21 @@ func GenerateWitness(txIdx uint, key, value []byte, proof *trie.StackProof) []No var nodes []Node for i := 0; i < upTo; i++ { if !isBranch(proofS[i]) { - // areThereNibbles := len(extNibblesS) != 0 || len(extNibblesC) != 0 - // If i < upTo-1, it means it's not a leaf, so it's an extension node. - // There is no any special relation between isNonExistingProof and isExtension, - // except that in the non-existing proof the extension node can appear in `i == upTo-1`. - // For non-existing proof, the last node in the proof could be an extension node (we have - // nil in the underlying branch). For the non-existing proof with the wrong leaf - // (non-existing proofs can be with a nil leaf or with a wrong leaf), - // we don't need to worry because it appears in i = upTo-1). - // if (i != upTo-1) || areThereNibbles { // extension node - // var numberOfNibbles byte - // isExtension = true + fmt.Println("extNibbleS/C", extNibblesS, extNibblesC) + areThereNibbles := len(extNibblesS) != 0 + if areThereNibbles { // extension node + var numberOfNibbles byte + isExtension = true - // // FIXME: handle the case of proofS(ext), proofC(branch), and it needs to add a branch placeholder at proofS? - // numberOfNibbles, extListRlpBytes, extValues = prepareExtensions(extNibblesS, extensionNodeInd, proofS[i], proofC[i]) + // FIXME: handle the case of proofS(ext), proofC(branch), and it needs to add a branch placeholder at proofS? + numberOfNibbles, extListRlpBytes, extValues = + prepareExtensions(extNibblesS, extensionNodeInd, proofS[i], proofC[i]) - // keyIndex += int(numberOfNibbles) - // extensionNodeInd++ - // continue - // } + keyIndex += int(numberOfNibbles) + // extensionNodeInd++ + fmt.Println("Increase keyIdx", keyIndex) + continue + } l := len(proofS) node := prepareTxLeafNode(uint(i), proofS[l-1], proofC[l-1], k, nil, false, false, false) @@ -407,10 +418,10 @@ func GenerateWitness(txIdx uint, key, value []byte, proof *trie.StackProof) []No extNode2 = proofC[i-1] } - fmt.Println(" s:", proofS[i]) - fmt.Println(" c:", proofC[i]) - bNode := prepareBranchNode(proofS[i], proofC[i], extNode1, extNode2, extListRlpBytes, extValues, - k[keyIndex], k[keyIndex], false, false, isExtension) + bNode := prepareBranchNode( + proofS[i], proofC[i], extNode1, extNode2, extListRlpBytes, + extValues, k[keyIndex], k[keyIndex], + false, false, isExtension) nodes = append(nodes, bNode) keyIndex += 1 @@ -418,56 +429,48 @@ func GenerateWitness(txIdx uint, key, value []byte, proof *trie.StackProof) []No isExtension = false } } - // fmt.Println("len", len1, len2) - fmt.Println("*** ", nodes) // To address the length of proofS and proofC is not equal or the order of the type is matched. if additionalBranch { leafRow0 := proofS[0] // To compute the drifted position. + isModifiedExtNode, _, _, bNode := + addBranchAndPlaceholder( + proofS, proofC, extNibblesS, extNibblesC, + leafRow0, k, nil, + keyIndex, extensionNodeInd, additionalBranch, + false, false, is_end_with_leaf, &toBeHashed) - // There are two kinds of situations needed to add an additional branch - // A. when the number of txs is less than or equals 128 - // The last proof (which is the first tx) looks like this, - // proofS: EXT - BRANCH - // proofC: BRANCH - LEAF - // B. when the 129th tx inserted, the last proof looks like, - // proofS: BRANCH - LEAF - // proofC: BRANCH - BRANCH - LEAF - isModifiedExtNode, _, numberOfNibbles, bNode := addBranchAndPlaceholder(proofS, proofC, extNibblesS, extNibblesC, - leafRow0, k, nil, - keyIndex, extensionNodeInd, additionalBranch, - false, false, is_end_of_leaf, &toBeHashed) - - nodes = append(nodes, bNode) + if !isStartWithExt { + nodes = append(nodes, bNode) + } var leafNode Node // Add a tx leaf after branch placeholder if !isModifiedExtNode { - leafNode = prepareTxLeafNode(txIdx, proofS[len1-1], proofC[len2-1], k, nil, false, false, false) + leafNode = prepareTxLeafNode(txIdx, proofS[len1-1], proofC[len2-1], k, nil, isBranch(proofS[len1-1]), false, false) } else { - isSModExtension := false - // isCModExtension := false - // FIXME might not fit our case bcs we have [EXT - BRANCH] --> [BRANCH - LEAF] - if len2 > len1 { - isSModExtension = true - } - leafNode = prepareTxLeafAndPlaceholderNode(txIdx, proofC[len2-1], k, isSModExtension) + fmt.Println("SHOULD NOT GET INTO THIS!!") + // TODO might not fit our case bcs we have [EXT - BRANCH] --> [BRANCH - LEAF] + // isSModExtension := false + // if len2 > len1 { + // isSModExtension = true + // } + // leafNode = prepareTxLeafAndPlaceholderNode(txIdx, proofC[len2-1], k, isSModExtension) } // When a proof element is a modified extension node (new extension node appears at the position // of the existing extension node), additional rows are added (extension node before and after // modification). if isModifiedExtNode { - // FIXME neighbor is for drifted node and what is drifted node: - // the leaf being moved from one branch to a newly created branch - leafNode = equipLeafWithModExtensionNode(nil, leafNode, common.Address{0}, proofS, proofC, proofC, - extNibblesS, extNibblesC, k, nil, - keyIndex, extensionNodeInd, numberOfNibbles, false, &toBeHashed) + fmt.Println("SHOULD NOT GET INTO THIS 2!!") + // TODO + // leafNode = equipLeafWithModExtensionNode(nil, leafNode, common.Address{0}, proofS, proofC, proofC, + // extNibblesS, extNibblesC, k, nil, + // keyIndex, extensionNodeInd, numberOfNibbles, false, &toBeHashed) } nodes = append(nodes, leafNode) } - fmt.Println("*** FINAL", nodes) - // return []Node{} + return nodes }