github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/test/libraries/trie/MerkleTrie.t.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { Test } from "forge-std/Test.sol";
     5  import { MerkleTrie } from "src/libraries/trie/MerkleTrie.sol";
     6  import { FFIInterface } from "test/setup/FFIInterface.sol";
     7  
     8  contract MerkleTrie_get_Test is Test {
     9      FFIInterface constant ffi = FFIInterface(address(uint160(uint256(keccak256(abi.encode("optimism.ffi"))))));
    10  
    11      function setUp() public {
    12          vm.etch(address(ffi), vm.getDeployedCode("FFIInterface.sol:FFIInterface"));
    13          vm.label(address(ffi), "FFIInterface");
    14      }
    15  
    16      function test_get_validProof1_succeeds() external {
    17          bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
    18          bytes memory key = hex"6b6579326262";
    19          bytes memory val = hex"6176616c32";
    20          bytes[] memory proof = new bytes[](3);
    21          proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
    22          proof[1] =
    23              hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
    24          proof[2] = hex"ca83206262856176616c32";
    25  
    26          assertEq(val, MerkleTrie.get(key, proof, root));
    27      }
    28  
    29      function test_get_validProof2_succeeds() external {
    30          bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
    31          bytes memory key = hex"6b6579316161";
    32          bytes memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
    33          bytes[] memory proof = new bytes[](3);
    34          proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
    35          proof[1] =
    36              hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
    37          proof[2] = hex"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
    38  
    39          assertEq(val, MerkleTrie.get(key, proof, root));
    40      }
    41  
    42      function test_get_validProof3_succeeds() external {
    43          bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;
    44          bytes memory key = hex"6b6579316161";
    45          bytes memory val = hex"303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
    46          bytes[] memory proof = new bytes[](1);
    47          proof[0] =
    48              hex"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878";
    49  
    50          assertEq(val, MerkleTrie.get(key, proof, root));
    51      }
    52  
    53      function test_get_validProof4_succeeds() external {
    54          bytes32 root = 0x37956bab6bba472308146808d5311ac19cb4a7daae5df7efcc0f32badc97f55e;
    55          bytes memory key = hex"6b6579316161";
    56          bytes memory val = hex"3031323334";
    57          bytes[] memory proof = new bytes[](1);
    58          proof[0] = hex"ce87206b6579316161853031323334";
    59  
    60          assertEq(val, MerkleTrie.get(key, proof, root));
    61      }
    62  
    63      function test_get_validProof5_succeeds() external {
    64          bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;
    65          bytes memory key = hex"6b657931";
    66          bytes memory val =
    67              hex"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67";
    68          bytes[] memory proof = new bytes[](3);
    69          proof[0] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
    70          proof[1] =
    71              hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
    72          proof[2] =
    73              hex"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67";
    74  
    75          assertEq(val, MerkleTrie.get(key, proof, root));
    76      }
    77  
    78      function test_get_validProof6_succeeds() external {
    79          bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;
    80          bytes memory key = hex"6b657932";
    81          bytes memory val = hex"73686f7274";
    82          bytes[] memory proof = new bytes[](3);
    83          proof[0] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
    84          proof[1] =
    85              hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
    86          proof[2] = hex"df808080808080c9823262856176616c338080808080808080808573686f7274";
    87  
    88          assertEq(val, MerkleTrie.get(key, proof, root));
    89      }
    90  
    91      function test_get_validProof7_succeeds() external {
    92          bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;
    93          bytes memory key = hex"6b657933";
    94          bytes memory val = hex"31323334353637383930313233343536373839303132333435363738393031";
    95          bytes[] memory proof = new bytes[](3);
    96          proof[0] = hex"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779";
    97          proof[1] =
    98              hex"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080";
    99          proof[2] =
   100              hex"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031";
   101  
   102          assertEq(val, MerkleTrie.get(key, proof, root));
   103      }
   104  
   105      function test_get_validProof8_succeeds() external {
   106          bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;
   107          bytes memory key = hex"61";
   108          bytes memory val = hex"61";
   109          bytes[] memory proof = new bytes[](3);
   110          proof[0] = hex"d916d780c22061c22062c2206380808080808080808080808080";
   111          proof[1] = hex"d780c22061c22062c2206380808080808080808080808080";
   112          proof[2] = hex"c22061";
   113  
   114          assertEq(val, MerkleTrie.get(key, proof, root));
   115      }
   116  
   117      function test_get_validProof9_succeeds() external {
   118          bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;
   119          bytes memory key = hex"62";
   120          bytes memory val = hex"62";
   121          bytes[] memory proof = new bytes[](3);
   122          proof[0] = hex"d916d780c22061c22062c2206380808080808080808080808080";
   123          proof[1] = hex"d780c22061c22062c2206380808080808080808080808080";
   124          proof[2] = hex"c22062";
   125  
   126          assertEq(val, MerkleTrie.get(key, proof, root));
   127      }
   128  
   129      function test_get_validProof10_succeeds() external {
   130          bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;
   131          bytes memory key = hex"63";
   132          bytes memory val = hex"63";
   133          bytes[] memory proof = new bytes[](3);
   134          proof[0] = hex"d916d780c22061c22062c2206380808080808080808080808080";
   135          proof[1] = hex"d780c22061c22062c2206380808080808080808080808080";
   136          proof[2] = hex"c22063";
   137  
   138          assertEq(val, MerkleTrie.get(key, proof, root));
   139      }
   140  
   141      function test_get_nonexistentKey1_reverts() external {
   142          bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
   143          bytes memory key = hex"6b657932";
   144          bytes[] memory proof = new bytes[](3);
   145          proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
   146          proof[1] =
   147              hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
   148          proof[2] = hex"ca83206262856176616c32";
   149  
   150          vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
   151          MerkleTrie.get(key, proof, root);
   152      }
   153  
   154      function test_get_nonexistentKey2_reverts() external {
   155          bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;
   156          bytes memory key = hex"616e7972616e646f6d6b6579";
   157          bytes[] memory proof = new bytes[](1);
   158          proof[0] = hex"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
   159  
   160          vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
   161          MerkleTrie.get(key, proof, root);
   162      }
   163  
   164      function test_get_wrongKeyProof_reverts() external {
   165          bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;
   166          bytes memory key = hex"6b6579316161";
   167          bytes[] memory proof = new bytes[](3);
   168          proof[0] = hex"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f";
   169          proof[1] =
   170              hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080";
   171          proof[2] = hex"d687206e6f746865728d33343938683472697568677765";
   172  
   173          vm.expectRevert("MerkleTrie: invalid internal node hash");
   174          MerkleTrie.get(key, proof, root);
   175      }
   176  
   177      function test_get_corruptedProof_reverts() external {
   178          bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;
   179          bytes memory key = hex"6b6579326262";
   180          bytes[] memory proof = new bytes[](5);
   181          proof[0] = hex"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2";
   182          proof[1] =
   183              hex"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080";
   184          proof[2] = hex"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386";
   185          proof[3] =
   186              hex"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080";
   187          proof[4] = hex"ca83206262856176616c32";
   188  
   189          vm.expectRevert("RLPReader: decoded item type for list is not a list item");
   190          MerkleTrie.get(key, proof, root);
   191      }
   192  
   193      function test_get_invalidDataRemainder_reverts() external {
   194          bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;
   195          bytes memory key = hex"aa";
   196          bytes[] memory proof = new bytes[](3);
   197          proof[0] = hex"d91ad780808080808080808080c32081aac32081ab8080808080";
   198          proof[1] = hex"d780808080808080808080c32081aac32081ab8080808080";
   199          proof[2] = hex"c32081aa000000000000000000000000000000";
   200  
   201          vm.expectRevert("RLPReader: list item has an invalid data remainder");
   202          MerkleTrie.get(key, proof, root);
   203      }
   204  
   205      function test_get_invalidInternalNodeHash_reverts() external {
   206          bytes32 root = 0xa827dff1a657bb9bb9a1c3abe9db173e2f1359f15eb06f1647ea21ac7c95d8fa;
   207          bytes memory key = hex"aa";
   208          bytes[] memory proof = new bytes[](3);
   209          proof[0] = hex"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157";
   210          proof[1] =
   211              hex"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080";
   212          proof[2] = hex"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f";
   213  
   214          vm.expectRevert("MerkleTrie: invalid internal node hash");
   215          MerkleTrie.get(key, proof, root);
   216      }
   217  
   218      function test_get_zeroBranchValueLength_reverts() external {
   219          bytes32 root = 0xe04b3589eef96b237cd49ccb5dcf6e654a47682bfa0961d563ab843f7ad1e035;
   220          bytes memory key = hex"aa";
   221          bytes[] memory proof = new bytes[](2);
   222          proof[0] = hex"dd8200aad98080808080808080808080c43b82aabbc43c82aacc80808080";
   223          proof[1] = hex"d98080808080808080808080c43b82aabbc43c82aacc80808080";
   224  
   225          vm.expectRevert("MerkleTrie: value length must be greater than zero (branch)");
   226          MerkleTrie.get(key, proof, root);
   227      }
   228  
   229      function test_get_zeroLengthKey_reverts() external {
   230          bytes32 root = 0x54157fd62cdf2f474e7bfec2d3cd581e807bee38488c9590cb887add98936b73;
   231          bytes memory key = hex"";
   232          bytes[] memory proof = new bytes[](1);
   233          proof[0] = hex"c78320f00082b443";
   234  
   235          vm.expectRevert("MerkleTrie: empty key");
   236          MerkleTrie.get(key, proof, root);
   237      }
   238  
   239      function test_get_smallerPathThanKey1_reverts() external {
   240          bytes32 root = 0xa513ba530659356fb7588a2c831944e80fd8aedaa5a4dc36f918152be2be0605;
   241          bytes memory key = hex"01";
   242          bytes[] memory proof = new bytes[](3);
   243          proof[0] = hex"db10d9c32081bbc582202381aa808080808080808080808080808080";
   244          proof[1] = hex"d9c32081bbc582202381aa808080808080808080808080808080";
   245          proof[2] = hex"c582202381aa";
   246  
   247          vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
   248          MerkleTrie.get(key, proof, root);
   249      }
   250  
   251      function test_get_smallerPathThanKey2_reverts() external {
   252          bytes32 root = 0xa06abffaec4ebe8ccde595f4547b864b4421b21c1fc699973f94710c9bc17979;
   253          bytes memory key = hex"aa";
   254          bytes[] memory proof = new bytes[](3);
   255          proof[0] = hex"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905";
   256          proof[1] =
   257              hex"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080";
   258          proof[2] = hex"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af";
   259  
   260          vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
   261          MerkleTrie.get(key, proof, root);
   262      }
   263  
   264      function test_get_extraProofElements_reverts() external {
   265          bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;
   266          bytes memory key = hex"aa";
   267          bytes[] memory proof = new bytes[](4);
   268          proof[0] = hex"d91ad780808080808080808080c32081aac32081ab8080808080";
   269          proof[1] = hex"d780808080808080808080c32081aac32081ab8080808080";
   270          proof[2] = hex"c32081aa";
   271          proof[3] = hex"c32081aa";
   272  
   273          vm.expectRevert("MerkleTrie: value node must be last node in proof (leaf)");
   274          MerkleTrie.get(key, proof, root);
   275      }
   276  
   277      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   278      function testFuzz_get_validProofs_succeeds(bytes4) external {
   279          // Generate a test case with a valid proof of inclusion for the k/v pair in the trie.
   280          (bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("valid");
   281  
   282          // Assert that our expected value is equal to our actual value.
   283          assertEq(val, MerkleTrie.get(key, proof, root));
   284      }
   285  
   286      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   287      function testFuzz_get_invalidRoot_reverts(bytes4) external {
   288          // Get a random test case with a valid trie / proof
   289          (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("valid");
   290  
   291          bytes32 rootHash = keccak256(abi.encodePacked(root));
   292          vm.expectRevert("MerkleTrie: invalid root hash");
   293          MerkleTrie.get(key, proof, rootHash);
   294      }
   295  
   296      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   297      function testFuzz_get_extraProofElements_reverts(bytes4) external {
   298          // Generate an invalid test case with an extra proof element attached to an otherwise
   299          // valid proof of inclusion for the passed k/v.
   300          (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("extra_proof_elems");
   301  
   302          vm.expectRevert("MerkleTrie: value node must be last node in proof (leaf)");
   303          MerkleTrie.get(key, proof, root);
   304      }
   305  
   306      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   307      function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {
   308          // Generate an invalid test case where a long proof element is incorrect for the root.
   309          (bytes32 root, bytes memory key,, bytes[] memory proof) =
   310              ffi.getMerkleTrieFuzzCase("invalid_large_internal_hash");
   311  
   312          vm.expectRevert("MerkleTrie: invalid large internal hash");
   313          MerkleTrie.get(key, proof, root);
   314      }
   315  
   316      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   317      function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {
   318          // Generate an invalid test case where a small proof element is incorrect for the root.
   319          (bytes32 root, bytes memory key,, bytes[] memory proof) =
   320              ffi.getMerkleTrieFuzzCase("invalid_internal_node_hash");
   321  
   322          vm.expectRevert("MerkleTrie: invalid internal node hash");
   323          MerkleTrie.get(key, proof, root);
   324      }
   325  
   326      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   327      function testFuzz_get_corruptedProof_reverts(bytes4) external {
   328          // Generate an invalid test case where the proof is malformed.
   329          (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("corrupted_proof");
   330  
   331          vm.expectRevert("RLPReader: decoded item type for list is not a list item");
   332          MerkleTrie.get(key, proof, root);
   333      }
   334  
   335      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   336      function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {
   337          // Generate an invalid test case where a random element of the proof has more bytes than the
   338          // length designates within the RLP list encoding.
   339          (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("invalid_data_remainder");
   340  
   341          vm.expectRevert("RLPReader: list item has an invalid data remainder");
   342          MerkleTrie.get(key, proof, root);
   343      }
   344  
   345      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   346      function testFuzz_get_prefixedValidKey_reverts(bytes4) external {
   347          // Get a random test case with a valid trie / proof and a valid key that is prefixed
   348          // with random bytes
   349          (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("prefixed_valid_key");
   350  
   351          // Ambiguous revert check- all that we care is that it *does* fail. This case may
   352          // fail within different branches.
   353          vm.expectRevert();
   354          MerkleTrie.get(key, proof, root);
   355      }
   356  
   357      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   358      function testFuzz_get_emptyKey_reverts(bytes4) external {
   359          // Get a random test case with a valid trie / proof and an empty key
   360          (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("empty_key");
   361  
   362          vm.expectRevert("MerkleTrie: empty key");
   363          MerkleTrie.get(key, proof, root);
   364      }
   365  
   366      /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.
   367      function testFuzz_get_partialProof_reverts(bytes4) external {
   368          // Get a random test case with a valid trie / partially correct proof
   369          (bytes32 root, bytes memory key,, bytes[] memory proof) = ffi.getMerkleTrieFuzzCase("partial_proof");
   370  
   371          vm.expectRevert("MerkleTrie: ran out of proof elements");
   372          MerkleTrie.get(key, proof, root);
   373      }
   374  }