diff --git a/core/trie/key.go b/core/trie/key.go index 3dd55d3749..208f9fcd89 100644 --- a/core/trie/key.go +++ b/core/trie/key.go @@ -40,14 +40,14 @@ func (k *Key) MostSignificantBits(n uint8) (*Key, error) { bytesToCopy := (n + 7) / 8 if bytesToCopy > 0 { // Copy the required bytes from the original key - startPos := len(k.bitset) - int((k.len+7)/8) + startPos := len(k.bitset) - int((k.len+7)/8) //nolint:mnd copy(newKey.bitset[len(newKey.bitset)-int(bytesToCopy):], k.bitset[startPos:]) } // Clear any extra bits in the last byte if necessary if n%8 != 0 && bytesToCopy > 0 { lastBytePos := len(newKey.bitset) - int(bytesToCopy) - mask := byte(0xFF >> (8 - (n % 8))) + mask := byte(0xFF >> (8 - (n % 8))) //nolint:mnd newKey.bitset[lastBytePos] &= mask } diff --git a/core/trie/proof.go b/core/trie/proof.go index 73d9d20816..ea32a02007 100644 --- a/core/trie/proof.go +++ b/core/trie/proof.go @@ -165,67 +165,6 @@ func transformNode(tri *Trie, parentKey *Key, sNode StorageNode) (*Edge, *Binary return edge, binary, nil } -// pathSplitOccurredCheck checks if there happens at most one split in the merged path -// loops through the merged paths if left and right hashes of a node exist in the nodeHashes -// then a split happened in case of multiple splits it returns an error -func pathSplitOccurredCheck(mergedPath []ProofNode, nodeHashes map[felt.Felt]ProofNode) error { - splitHappened := false - for _, node := range mergedPath { - switch node := node.(type) { - case *Edge: - continue - case *Binary: - _, leftExists := nodeHashes[*node.LeftHash] - _, rightExists := nodeHashes[*node.RightHash] - if leftExists && rightExists { - if splitHappened { - return errors.New("split happened more than once") - } - splitHappened = true - } - default: - return fmt.Errorf("%w: %T", ErrUnknownProofNode, node) - } - } - return nil -} - -func rootNodeExistsCheck(rootHash *felt.Felt, nodeHashes map[felt.Felt]ProofNode) (ProofNode, error) { - currNode, rootExists := nodeHashes[*rootHash] - if !rootExists { - return currNode, errors.New("root hash not found in the merged path") - } - - return currNode, nil -} - -// traverseNodes traverses the merged proof path starting at `currNode` -// and adds nodes to `path` slice. It stops when the split node is added -// or the path is exhausted, and `currNode` children are not included -// in the path (nodeHashes) -func traverseNodes(currNode ProofNode, path *[]ProofNode, nodeHashes map[felt.Felt]ProofNode) { - *path = append(*path, currNode) - - switch currNode := currNode.(type) { - case *Binary: - nodeLeft, leftExist := nodeHashes[*currNode.LeftHash] - nodeRight, rightExist := nodeHashes[*currNode.RightHash] - - if leftExist && rightExist { - return - } else if leftExist { - traverseNodes(nodeLeft, path, nodeHashes) - } else if rightExist { - traverseNodes(nodeRight, path, nodeHashes) - } - case *Edge: - edgeNode, exist := nodeHashes[*currNode.Child] - if exist { - traverseNodes(edgeNode, path, nodeHashes) - } - } -} - // https://github.com/eqlabs/pathfinder/blob/main/crates/merkle-tree/src/tree.rs#L514 // GetProof generates a set of proof nodes from the root to the leaf. // The proof never contains the leaf node if it is set, as we already know it's hash. @@ -341,7 +280,9 @@ func VerifyProof(root *felt.Felt, key *Key, proofSet *ProofSet, hash HashFunc) ( // If the trie is constructed incorrectly then the root will have an incorrect key(len,path), and value, // and therefore its hash won't match the expected root. // ref: https://github.com/ethereum/go-ethereum/blob/v1.14.3/trie/proof.go#L484 -func VerifyRangeProof(root *felt.Felt, firstKey *felt.Felt, keys, values []*felt.Felt, proofSet *ProofSet, hash HashFunc) (bool, error) { +// +//nolint:gocyclo +func VerifyRangeProof(root, firstKey *felt.Felt, keys, values []*felt.Felt, proofSet *ProofSet, hash HashFunc) (bool, error) { // Ensure the number of keys and values are the same if len(keys) != len(values) { return false, fmt.Errorf("inconsistent proof data, number of keys: %d, number of values: %d", len(keys), len(values)) diff --git a/core/trie/proof_test.go b/core/trie/proof_test.go index f4133bbf97..56f0f402df 100644 --- a/core/trie/proof_test.go +++ b/core/trie/proof_test.go @@ -184,120 +184,12 @@ func build3KeyTrie(t *testing.T) *trie.Trie { return tempTrie } -func build4KeyTrie(t *testing.T) *trie.Trie { - // Juno - // 248 - // / \ - // 249 \ - // / \ \ - // 250 \ \ - // / \ /\ /\ - // 0 1 2 4 - - // Juno - should be able to reconstruct this from proofs - // 248 - // / \ - // 249 // Note we cant derive the right key, but need to store it's hash - // / \ - // 250 \ - // / \ / (Left hash set, no key) - // 0 - - // Pathfinder (???) - // 0 Edge - // | - // 248 Binary - // / \ - // 249 \ Binary Edge ?? - // / \ \ - // 250 250 250 Binary Edge ?? - // / \ / / - // 0 1 2 4 - - // Build trie - memdb := pebble.NewMemTest(t) - txn, err := memdb.NewTransaction(true) - require.NoError(t, err) - - tempTrie, err := trie.NewTriePedersen(trie.NewStorage(txn, []byte{0}), 251) - require.NoError(t, err) - - // Update trie - key1 := new(felt.Felt).SetUint64(0) - key2 := new(felt.Felt).SetUint64(1) - key3 := new(felt.Felt).SetUint64(2) - key5 := new(felt.Felt).SetUint64(4) - value1 := new(felt.Felt).SetUint64(4) - value2 := new(felt.Felt).SetUint64(5) - value3 := new(felt.Felt).SetUint64(6) - value5 := new(felt.Felt).SetUint64(7) - - _, err = tempTrie.Put(key1, value1) - require.NoError(t, err) - - _, err = tempTrie.Put(key3, value3) - require.NoError(t, err) - _, err = tempTrie.Put(key2, value2) - require.NoError(t, err) - _, err = tempTrie.Put(key5, value5) - require.NoError(t, err) - - require.NoError(t, tempTrie.Commit()) - - return tempTrie -} - -func noDuplicates(proofNodes []trie.ProofNode) bool { - seen := make(map[felt.Felt]bool) - for _, pNode := range proofNodes { - if _, ok := seen[*pNode.Hash(crypto.Pedersen)]; ok { - return false - } - seen[*pNode.Hash(crypto.Pedersen)] = true - } - return true -} - -// containsAll checks that subsetProofNodes is a subset of proofNodes -func containsAll(proofNodes, subsetProofNodes []trie.ProofNode) bool { - for _, pNode := range subsetProofNodes { - found := false - for _, p := range proofNodes { - if p.Hash(crypto.Pedersen).Equal(pNode.Hash(crypto.Pedersen)) { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -func isSameProofPath(proofNodes, expectedProofNodes []trie.ProofNode) bool { - if len(proofNodes) != len(expectedProofNodes) { - return false - } - for i := range proofNodes { - if !proofNodes[i].Hash(crypto.Pedersen).Equal(expectedProofNodes[i].Hash(crypto.Pedersen)) { - return false - } - } - return true -} - -func newBinaryProofNode() *trie.Binary { - return &trie.Binary{ - LeftHash: new(felt.Felt).SetUint64(1), - RightHash: new(felt.Felt).SetUint64(2), - } -} - func TestProve(t *testing.T) { t.Parallel() t.Run("simple binary", func(t *testing.T) { + t.Parallel() + tempTrie := buildSimpleTrie(t) zero := trie.NewKey(250, []byte{0}) @@ -330,6 +222,8 @@ func TestProve(t *testing.T) { }) t.Run("simple double binary", func(t *testing.T) { + t.Parallel() + tempTrie, expectedProofNodes := buildSimpleDoubleBinaryTrie(t) expectedProofNodes[2] = &trie.Binary{ @@ -355,6 +249,8 @@ func TestProve(t *testing.T) { }) t.Run("simple double binary edge", func(t *testing.T) { + t.Parallel() + tempTrie, expectedProofNodes := buildSimpleDoubleBinaryTrie(t) leafFelt := new(felt.Felt).SetUint64(3) leafKey := tempTrie.FeltToKey(leafFelt) @@ -373,6 +269,8 @@ func TestProve(t *testing.T) { }) t.Run("simple binary root", func(t *testing.T) { + t.Parallel() + tempTrie := buildSimpleBinaryRootTrie(t) key1Bytes := new(felt.Felt).SetUint64(0).Bytes() @@ -405,6 +303,8 @@ func TestProve(t *testing.T) { }) t.Run("left-right edge", func(t *testing.T) { + t.Parallel() + // (251,0xff,0xaa) // / // \ @@ -449,6 +349,8 @@ func TestProve(t *testing.T) { }) t.Run("three key trie", func(t *testing.T) { + t.Parallel() + tempTrie := build3KeyTrie(t) zero := trie.NewKey(249, []byte{0}) felt2 := new(felt.Felt).SetUint64(0).Bytes() @@ -487,6 +389,8 @@ func TestProve(t *testing.T) { }) t.Run("non existent key - less than root edge", func(t *testing.T) { + t.Parallel() + tempTrie, _ := buildSimpleDoubleBinaryTrie(t) nonExistentFelt := new(felt.Felt).SetUint64(123) @@ -504,6 +408,8 @@ func TestProve(t *testing.T) { }) t.Run("non existent leaf key", func(t *testing.T) { + t.Parallel() + tempTrie, _ := buildSimpleDoubleBinaryTrie(t) nonExistentFelt := new(felt.Felt).SetUint64(2) diff --git a/rpc/storage_test.go b/rpc/storage_test.go index 0182413719..a778b8108c 100644 --- a/rpc/storage_test.go +++ b/rpc/storage_test.go @@ -247,12 +247,8 @@ func TestStorageProof(t *testing.T) { require.Len(t, rootNodes, 1) // verify we can still prove any of the keys in query - // Hack: by a trie construction, we know that the first two nodes are common for both keys - // and the last two nodes are edges corresponding to both values - commonNodes := proof.ClassesProof[:2] - - verifyIf(t, trieRoot, key, value, append(commonNodes, proof.ClassesProof[2]), tempTrie.HashFunc()) - verifyIf(t, trieRoot, key2, value2, append(commonNodes, proof.ClassesProof[3]), tempTrie.HashFunc()) + verifyIf(t, trieRoot, key, value, proof.ClassesProof, tempTrie.HashFunc()) + verifyIf(t, trieRoot, key2, value2, proof.ClassesProof, tempTrie.HashFunc()) }) t.Run("storage trie address does not exist in a trie", func(t *testing.T) { t.Parallel()