From 684376143f6a4230c44d07a20bb04a0cf069e65c Mon Sep 17 00:00:00 2001 From: Lucas MT Date: Tue, 7 Nov 2023 19:10:46 -0600 Subject: [PATCH 1/3] Add highly-branching MerkleProofTest --- .../integration/test-data/foundry-prove-all | 1 + .../integration/test-data/foundry-prove-skip | 1 + .../foundry/test/MerkleProofTest.t.sol | 69 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 src/tests/integration/test-data/foundry/test/MerkleProofTest.t.sol diff --git a/src/tests/integration/test-data/foundry-prove-all b/src/tests/integration/test-data/foundry-prove-all index ffae5dd35..38d9606bf 100644 --- a/src/tests/integration/test-data/foundry-prove-all +++ b/src/tests/integration/test-data/foundry-prove-all @@ -139,6 +139,7 @@ LoopsTest.test_sum_100() LoopsTest.test_sum_1000() LoopsTest.testSumToN(uint256) LoopsTest.testSumToNBroken(uint256) +MerkleProofTest.testValidateMerkleProof(bytes32,uint256,bytes32,bytes32,bytes32,bytes32) MethodDisambiguateTest.test_method_call() MockCallTest.testMockCall() MockCallTest.testMockCalls() diff --git a/src/tests/integration/test-data/foundry-prove-skip b/src/tests/integration/test-data/foundry-prove-skip index 23ae8e256..299210d12 100644 --- a/src/tests/integration/test-data/foundry-prove-skip +++ b/src/tests/integration/test-data/foundry-prove-skip @@ -84,6 +84,7 @@ LoopsTest.test_sum_100() LoopsTest.test_sum_1000() LoopsTest.testSumToN(uint256) LoopsTest.testSumToNBroken(uint256) +MerkleProofTest.testValidateMerkleProof(bytes32,uint256,bytes32,bytes32,bytes32,bytes32) MockCallTest.testMockCall() MockCallTest.testMockCalls() MockCallTest.testMockCallValue() diff --git a/src/tests/integration/test-data/foundry/test/MerkleProofTest.t.sol b/src/tests/integration/test-data/foundry/test/MerkleProofTest.t.sol new file mode 100644 index 000000000..39c39d4d7 --- /dev/null +++ b/src/tests/integration/test-data/foundry/test/MerkleProofTest.t.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity =0.8.13; + +import "forge-std/Test.sol"; + +contract MerkleProofTest is Test { + + /** + * The purpose of this test is to evaluate how well we handle branching. + * When we assume that _validateMerkleProof holds, the execution splits + * into 2 ** proof.length (in this case, 8) branches. We want to be able + * to handle this amount of branching without losing information, so we + * can still prove that it holds in the final assertTrue. + * + * Increase the length of the proof to evaluate scalability. + */ + function testValidateMerkleProof( + bytes32 leaf, + uint256 index, + bytes32 root, + bytes32 proofElement0, + bytes32 proofElement1, + bytes32 proofElement2 + ) external { + uint256 proofLength = 3; + + bytes32[] memory proof = new bytes32[](proofLength); + proof[0] = proofElement0; + proof[1] = proofElement1; + proof[2] = proofElement2; + + vm.assume(index < 2 ** proof.length); + + vm.assume(_validateMerkleProof(leaf, index, root, proof)); + + assertTrue(_validateMerkleProof(leaf, index, root, proof)); + } + + /** + * Checks that the proof is valid for a Merkle tree with the given root + * where the given leaf is at the given index. + */ + function _validateMerkleProof( + bytes32 leaf, + uint256 index, + bytes32 root, + bytes32[] memory proof + ) internal pure returns (bool) { + // Number of leaves is exponential on the tree depth + require(index < 2 ** proof.length); + + bytes32 hash = leaf; + + for (uint256 i; i < proof.length; i++) { + if (index % 2 == 0) { + // If index is even, proof element is to the right + hash = keccak256(abi.encodePacked(hash, proof[i])); + } else { + // If index is odd, proof element is to the left + hash = keccak256(abi.encodePacked(proof[i], hash)); + } + + // Go up one level in the tree + index = index / 2; + } + + return hash == root; + } +} From 4887c3f57332fec0bc0c94b2789f8c1fd6f9aa65 Mon Sep 17 00:00:00 2001 From: devops Date: Wed, 8 Nov 2023 17:02:16 +0000 Subject: [PATCH 2/3] Set Version: 0.1.55 --- package/version | 2 +- pyproject.toml | 2 +- src/kontrol/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package/version b/package/version index 7b300677b..8893a8e14 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.54 +0.1.55 diff --git a/pyproject.toml b/pyproject.toml index 1f3778d7a..b9dcf5a9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "kontrol" -version = "0.1.54" +version = "0.1.55" description = "Foundry integration for KEVM" authors = [ "Runtime Verification, Inc. ", diff --git a/src/kontrol/__init__.py b/src/kontrol/__init__.py index 70964acd7..d9c80697c 100644 --- a/src/kontrol/__init__.py +++ b/src/kontrol/__init__.py @@ -5,4 +5,4 @@ if TYPE_CHECKING: from typing import Final -VERSION: Final = '0.1.54' +VERSION: Final = '0.1.55' From b15ac7a90be59fe16109321d50cb2ee4ae3e45e9 Mon Sep 17 00:00:00 2001 From: devops Date: Tue, 5 Dec 2023 21:07:52 +0000 Subject: [PATCH 3/3] Set Version: 0.1.83 --- package/version | 2 +- pyproject.toml | 2 +- src/kontrol/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package/version b/package/version index 59e55c1f1..660b5ae0c 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.82 +0.1.83 diff --git a/pyproject.toml b/pyproject.toml index b2f785a6a..03f5fb218 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "kontrol" -version = "0.1.82" +version = "0.1.83" description = "Foundry integration for KEVM" authors = [ "Runtime Verification, Inc. ", diff --git a/src/kontrol/__init__.py b/src/kontrol/__init__.py index 50ad77bde..5c3289b28 100644 --- a/src/kontrol/__init__.py +++ b/src/kontrol/__init__.py @@ -6,4 +6,4 @@ from typing import Final -VERSION: Final = '0.1.82' +VERSION: Final = '0.1.83'