Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

verifyMultiNamespaced #326

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
19 changes: 19 additions & 0 deletions src/lib/tree/binary/BinaryMerkleTree.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "../Utils.sol";
import "./TreeHasher.sol";
import "./BinaryMerkleProof.sol";
import "./BinaryMerkleMultiproof.sol";
import "../namespace/NamespaceNode.sol";

/// @title Binary Merkle Tree.
library BinaryMerkleTree {
Expand Down Expand Up @@ -91,6 +92,24 @@ library BinaryMerkleTree {
return verifyMultiHashes(root, proof, nodes);
}

/*
This helps with gas efficiency so we can avoid unnecessary copying and looping through the NamespaceNodes
when we go to verify the row inclusion multiproof
*/
function verifyMultiNamespaced(bytes32 root, BinaryMerkleMultiproof memory proof, NamespaceNode[] memory data)
internal
pure
returns (bool)
{
bytes32[] memory nodes = new bytes32[](data.length);
for (uint256 i = 0; i < data.length; i++) {
// the bytes.concat(...) converts a bytes32 into a bytes
nodes[i] = leafDigest(bytes.concat(data[i].digest));
}

return verifyMultiHashes(root, proof, nodes);
}
Comment on lines +99 to +111
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for empty data arrays.

The function verifyMultiNamespaced does not handle the case where the data array is empty, which could lead to unexpected behavior.

+        require(data.length > 0, "Data array cannot be empty");
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function verifyMultiNamespaced(bytes32 root, BinaryMerkleMultiproof memory proof, NamespaceNode[] memory data)
internal
pure
returns (bool)
{
bytes32[] memory nodes = new bytes32[](data.length);
for (uint256 i = 0; i < data.length; i++) {
// the bytes.concat(...) converts a bytes32 into a bytes
nodes[i] = leafDigest(bytes.concat(data[i].digest));
}
return verifyMultiHashes(root, proof, nodes);
}
function verifyMultiNamespaced(bytes32 root, BinaryMerkleMultiproof memory proof, NamespaceNode[] memory data)
internal
pure
returns (bool)
{
require(data.length > 0, "Data array cannot be empty");
bytes32[] memory nodes = new bytes32[](data.length);
for (uint256 i = 0; i < data.length; i++) {
// the bytes.concat(...) converts a bytes32 into a bytes
nodes[i] = leafDigest(bytes.concat(data[i].digest));
}
return verifyMultiHashes(root, proof, nodes);
}


function verifyMultiHashes(bytes32 root, BinaryMerkleMultiproof memory proof, bytes32[] memory leafNodes)
internal
pure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ contract NamespaceMerkleMultiproofTest is DSTest {
}

function testLoadFromBytes() external {
// the bytes were generated here https://github.com/S1nus/hyperchain-da/blob/main/src/clients/celestia/evm_types.rs#L132
// this is a Namespace merkle multiproof, corresponding to the first row of the blob
// the bytes were generated with this Rust code
// https://github.com/S1nus/hyperchain-da/blob/main/src/clients/celestia/evm_types.rs#L235
// the JSON test vector is located at ../../test/proofs.json
bytes memory proofData =
hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000e2c251c19c0cd38681c6263a7bbbb27bfe727fb71bebe4b68f75c275dade4550ff00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000039af53e89275fe860e67ef0cc55ad18a936a7f623c8897e541f20bcce166491f";
NamespaceMerkleMultiproof memory proof = abi.decode(proofData, (NamespaceMerkleMultiproof));
Expand Down
Loading