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

fix: patricia trie decoding #41

Merged
merged 1 commit into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/MerklePatricia.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,9 @@ library MerklePatricia {
Extension memory extension = EthereumTrieDB.decodeExtension(node);
if (NibbleSliceOps.startsWith(keyNibbles, extension.key)) {
// Let's cut the key passed as input
uint256 cutNibble = keyNibbles.offset + NibbleSliceOps.len(extension.key);
keyNibbles = NibbleSlice(
NibbleSliceOps.bytesSlice(keyNibbles.data, NibbleSliceOps.len(extension.key)), 0
NibbleSliceOps.bytesSlice(keyNibbles.data, cutNibble / 2), cutNibble % 2
);
nextNode = extension.node;
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/trie/ethereum/EthereumTrieDB.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ library EthereumTrieDB {
Extension memory extension;
RLPReader.RLPItem[] memory decoded = node.data.data.toRlpItem().toList();
bytes memory data = decoded[1].toBytes();
uint8 isOdd = uint8(decoded[0].toBytes()[0] >> 4) & 0x01;
//Remove the first byte, which is the prefix and not present in the user provided key
extension.key = NibbleSlice(Bytes.substr(decoded[0].toBytes(), 1), 0);
extension.key = NibbleSlice(Bytes.substr(decoded[0].toBytes(), (isOdd + 1) % 2), isOdd);
extension.node = NodeHandle(true, Bytes.toBytes32(data), false, new bytes(0));
return extension;
}
Expand Down
28 changes: 28 additions & 0 deletions test/MerklePatricia.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,34 @@ contract MerklePatriciaTest is Test {
assertEq(ScaleCodec.decodeUintCompact(ByteSlice(value, 4)), 1679661054045);
}

function testEthereumMerklePatricia() public {
bytes[] memory keys = new bytes[](1);
// slot at 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
keys[0] = hex"75b20eef8615de99c108b05f0dbda081c91897128caa336d75dffb97c4132b4d";

// proof from account 0xbEb5Fc579115071764c7423A4f12eDde41f106Ed on Ethreum mainnet at block 19458609
bytes[] memory proof = new bytes[](7);
proof[0] =
hex"f90211a0e36cd4c05239f5c535a7840f9f14b74bf287328e3fb87d09f02355e644f4378fa0fa16c734775c7d81b5d459addf9cf6ef8c8e20b71a4df4754c6be3895cf20977a0ec900883398b84efcb12fee51e991e878fac4ce09c6cc07c8d0c0941398a3664a01de14c6cc89ac9ba2e5294a300c5497bb6817f7481e68febf3975a8b017e5c15a010765286a0f030df2b4e13c82eb2c95fb2f865e1e5ae67fb19fbadc4c554771da0f5cac85a41291eb814b14706fa3d27c6f8890ce2fed6f92ef03b6e8d22e093f8a0ff187925da588f90250b7680887c3d8d155b51f58112a0cfdc6356884c60d4eaa06b82977e5bb3457a89b79f252f3f448817761c03e14fdd99988d0d71a914fb96a0d0ed46c3bf3a217660177d3c0f3744aa40d3a67ed4dabe5371dcd101ebcb71d7a02d642b6a1035a17fca9ea16138d6ede364da0af4b2c5c362360e3b3669e96a7da0768a6012c6be41406374fa24604b803906c2dc3421d6aa9752fddcd7042ddb94a09c139cf4bbd79b32c255928ff267ee22948d06976efbc0ac869cb5a674857917a06e617a3e1bc92d939a0b6feff4c8d688f74315af5cecfb9a2869267b326a8ba6a078368124e1131b2743d0fbdda3b1b0c0a8adedb1b8839bb99fd31e34d50d1922a0dccc4ddd77c9580f1443dfd64c2d6a22014ba2dccd81281e6663f488c3447e21a0dfaeb0b02df962296d9e0645c2ae2961e15d0d1d92392164624a502cad96fd9480";
proof[1] =
hex"f90211a0486fcee760e354cec03ba3a431a9f035417f63c957ea05b33cf49e3afaef8741a08ef7adc166a1423cb4f035d5a83583726cd5803405a4b8684ad0c023203ce6a7a098d08b44d840f34fa68397f2a5453c4eb89e86195f96ccadfe14de7925664561a0817d070ecb8e3451a505c6f9d008db91763c68f186346dd4555962bbba4abe03a0115d9190622849e9205a96f863707032e29621447c34506145efc434dac91321a0298e4f7519bea373ceb5f94cb34d78383c4664e2f5beac262b01b428c3b2a280a0c0ff7e3638c51912db91d92a6d637a2c8bbcae73fe33bf3738db40369763e5aba0fde04f5dc892f5156e5b1fd7985e90d9c64330d439645b80311561a370338ef9a09bd1e2ef9548cacf1ce0057f13c93344300849fbca2638f3055bdf638d59948ea078a2c1a862906b603291741138bee56444fd3f34e6a4f3ca1f0e318429a94862a08ecc44cc4a06c9a7ac2e21860942750ada47e14e2f2efd561d03104525ba27aaa08d407dec2d5527e80d6d73e8ee8c1ef8cd8819bd82628faf93abe454f48b8a7ca0bf759b30dbbf0e5e6a3c5bc258a91b7c6778e6f0b474e7fdb4117c1659ea5774a06b30bcd113d0d3ea46f1134654f7172ccf7253d17397ed0e57847cb14f1a4a64a0c2b47985c05a2eb85463fc687d7e09bb8aafddf1c57a323652b04a9b791d76c9a0d65a53fe9963a9086bc3c7796aa30286f029b01814f561ff98f1f4b898ad264380";
proof[2] =
hex"f90211a0496f94fb20f86b96949c1e8ff21646543893848e9ba0fc88c29989993d6f4733a0346f2b92631b4ccec787638be96dce0f9082650f6839f951b4003282f0ea2934a0ddd5e6839f84a978019b8e076dc6057c579e3951ef766dcfb3342b251c424ee4a04feb7109266fd467e79012fada3159bad47d478612b15c812d853b5bbfb038cea083181482a9c3349b408b2cb957b78dd71aa9faf842d727e889afbf8d2e8f5fe2a0d417081e6c2f8b46bfa50ada78eb44bd87d620e834d5107055567f383ef04427a001d74013d6ab118109e0b4f6d3be65dbf5d16857cdd7e7f2698ef28a06177b9aa075bb8b6d0cffe800afd4dc0df14cffe73140cce5c716e75fb56bb65db4b403f4a055db1b1c8e3760650d578218fb0787d80b56295ce5e302515d5c300217f5179ba0c338b90051d671575d53c2cee1bd88fc422e7b84d7fa7fb8e0ae9c414382b1e0a03c2f2bb41a5f16e318785c263dc7811b17f4efaee0c6ca2645364259cbcb8487a0bdb8ff1b3ab9c0ef2cb6d22eb12cb0883a040b5a331cb3e178310bf052753552a00d8dcb4eab5db9a22b7a31d5cdf9a67c02b959f4f4ae49d325a6597622586859a0db07ac1cc177e0b96f40fda37b035e3954f0890942d6286fb18b6a9ca9e0a7dda033db3178750e7f06f808461292ddf275697492a5df3a13f25e7e6afb6d31ca70a0a81061197b9e888f84b6e647eebddee898f41c7056e8f878e9a4cd1c27c65e5980";
proof[3] =
hex"f8f1a0b9bbfd6ce22f4ae072ef3d74361ee4264c93d20f2db91820d80e7241a2fad769a021681b13bd0228de9fc4094fe565dfe7edd4904bac9aad26ed2a7f2bf8acea0fa00944ff72f3186a894ecbd5e4990ae7cf28d3014cfa2dfebb42a703218c5b5e808080808080a05500178fdbdbd39144f93e0bb3c5b1304337ed6b72a0898e4e951c4f2565637d808080a0e7b6274092da49eb53015db452d82ba172bd098ef90653d812dbcc32df8afb72a08a93d8b68d7ec95d2fe990bb6503309cc116a435f05ee710a24fc82f68c2c00f80a076be6f941a705872dfb43bca24baaa291663ad1332f60b9f28a7c111c941592c80";
proof[4] =
hex"e210a0b798089c35eabfa9992866d0ff2d19040e85326547b79dad85be810b5482bfb2";
proof[5] =
hex"f851808080808080808080a03b00a9adfccdbcb4252a987ba894a37829d4d2d5bf4f30740ac23f93a22510ab80808080a07904f9b847c710858697e144376dab844c380807ecf4b6b7364c57fc22a86ed18080";
proof[6] =
hex"f59e20ef8615de99c108b05f0dbda081c91897128caa336d75dffb97c4132b4d9594ababe63514ddd6277356f8cc3d6518aa8bdeb4de";

bytes32 root = hex"c162613853b0d814a7aaaf9869f44cad1aab4cb151321da5c60ff3a2ddc14daf";
bytes memory value = VerifyEthereum(root, proof, keys)[0].value;
bytes memory expectedOutput = hex"94ababe63514ddd6277356f8cc3d6518aa8bdeb4de";
assertEq(value, expectedOutput);
}

function VerifyKeys(bytes32 root, bytes[] memory proof, bytes[] memory keys)
public
pure
Expand Down
Loading