Skip to content

Commit 163f27c

Browse files
committed
Workaround stack too deep
1 parent 18540ef commit 163f27c

File tree

1 file changed

+37
-20
lines changed

1 file changed

+37
-20
lines changed

contracts/utils/TrieProof.sol

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -126,26 +126,7 @@ library TrieProof {
126126
uint8 branchKey = uint8(key[keyIndex]);
127127
(nodeId, keyIndex) = (_id(node.decoded[branchKey]), keyIndex + 1);
128128
} else if (nodeLength == LEAF_OR_EXTENSION_NODE_LENGTH) {
129-
bytes memory path = _path(node);
130-
uint8 prefix = uint8(path[0]);
131-
uint8 offset = 2 - (prefix % 2); // Calculate offset based on even/odd path length
132-
bytes memory pathRemainder = Bytes.slice(path, offset); // Path after the prefix
133-
bytes memory keyRemainder = Bytes.slice(key, keyIndex); // Remaining key to match
134-
uint256 sharedNibbleLength = _sharedNibbleLength(pathRemainder, keyRemainder);
135-
136-
// Path must match at least partially with our key
137-
if (sharedNibbleLength == 0) return ("", ProofError.INVALID_PATH_REMAINDER);
138-
if (prefix > uint8(type(Prefix).max)) return ("", ProofError.UNKNOWN_NODE_PREFIX);
139-
140-
// Leaf node (terminal) - return its value if key matches completely
141-
if (Prefix(prefix) == Prefix.LEAF_EVEN || Prefix(prefix) == Prefix.LEAF_ODD) {
142-
if (keyRemainder.length == 0) return ("", ProofError.INVALID_KEY_REMAINDER);
143-
return _validateLastItem(node.decoded[1], trieProof, i);
144-
}
145-
146-
// Extension node (non-terminal) - continue to next node
147-
// Increment keyIndex by the number of nibbles consumed
148-
(nodeId, keyIndex) = (_id(node.decoded[1]), keyIndex + sharedNibbleLength);
129+
return _processLeafOrExtension(node, trieProof, key, nodeId, keyIndex, i);
149130
}
150131
}
151132

@@ -166,6 +147,42 @@ library TrieProof {
166147
return ProofError.NO_ERROR; // No error
167148
}
168149

150+
/**
151+
* @dev Processes a leaf or extension node in the trie proof.
152+
*
153+
* For leaf nodes, validates that the key matches completely and returns the value.
154+
* For extension nodes, continues traversal by updating the node ID and key index.
155+
*/
156+
function _processLeafOrExtension(
157+
Node memory node,
158+
Node[] memory trieProof,
159+
bytes memory key,
160+
bytes memory nodeId,
161+
uint256 keyIndex,
162+
uint256 i
163+
) private pure returns (bytes memory value, ProofError err) {
164+
bytes memory path = _path(node);
165+
uint8 prefix = uint8(path[0]);
166+
uint8 offset = 2 - (prefix % 2); // Calculate offset based on even/odd path length
167+
bytes memory pathRemainder = Bytes.slice(path, offset); // Path after the prefix
168+
bytes memory keyRemainder = Bytes.slice(key, keyIndex); // Remaining key to match
169+
uint256 sharedNibbleLength = _sharedNibbleLength(pathRemainder, keyRemainder);
170+
171+
// Path must match at least partially with our key
172+
if (sharedNibbleLength == 0) return ("", ProofError.INVALID_PATH_REMAINDER);
173+
if (prefix > uint8(type(Prefix).max)) return ("", ProofError.UNKNOWN_NODE_PREFIX);
174+
175+
// Leaf node (terminal) - return its value if key matches completely
176+
if (Prefix(prefix) == Prefix.LEAF_EVEN || Prefix(prefix) == Prefix.LEAF_ODD) {
177+
if (keyRemainder.length == 0) return ("", ProofError.INVALID_KEY_REMAINDER);
178+
return _validateLastItem(node.decoded[1], trieProof, i);
179+
}
180+
181+
// Extension node (non-terminal) - continue to next node
182+
// Increment keyIndex by the number of nibbles consumed
183+
(nodeId, keyIndex) = (_id(node.decoded[1]), keyIndex + sharedNibbleLength);
184+
}
185+
169186
/**
170187
* @dev Validates that we've reached a valid leaf value and this is the last proof element.
171188
* Ensures the value is not empty and no extra proof elements exist.

0 commit comments

Comments
 (0)