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

Implement eth_getProof #1590

Merged
merged 23 commits into from
Dec 9, 2021
Merged

Implement eth_getProof #1590

merged 23 commits into from
Dec 9, 2021

Conversation

jochem-brouwer
Copy link
Member

@jochem-brouwer jochem-brouwer commented Nov 29, 2021

Closes #1078. Implements eth_getProof based on comparing results with Geth 1.10.8. Rebased version of #1180.

TODOs

  • Implement tests for StateManager
  • Implement RPC method in client
  • Add client tests
  • Figure out what to do when verifyProof from trie returns null (probably edge case; only happens on empty tries)

Note: if verifyProof returns null, it simply means that the key does not exist in the trie (a non-existing account, or an empty storage slot).

@jochem-brouwer
Copy link
Member Author

Dumping an example proof here for ropsten.

> eth.getBlock('latest')
{
  baseFeePerGas: 8,
  difficulty: 1216405549,
  extraData: "0xd883010a08846765746888676f312e31362e34856c696e7578",
  gasLimit: 8000000,
  gasUsed: 503298,
  hash: "0x1d9ea6981b8093a2b63f22f74426ceb6ba1acae3fddd7831442bbeba3fa4f146",
  logsBloom: "0x00000000000000010000000000000000000000000000040000000000000000000000000000000000000000000400040000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000010000000000000000000000000000000000000000080000000000000000000000000010000001000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000",
  miner: "0xc626553e7c821d0f8308c28d56c60e3c15f8d55a",
  mixHash: "0x3a67c07b69ad36dc1b1e6b3e4d6f4619fee3985f8b24b4c0ce99a08e3ea27817",
  nonce: "0xe891510fffd97226",
  number: 11098094,
  parentHash: "0x6777434f4b9f86c713cba1ea19eaf181a176f2c5555dc29cf91ad3c8fa9ebaf3",
  receiptsRoot: "0xa5a2cf3952c9187947cd802397ab1aa74133dcab31ec7b76a962f47ee6716ed9",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 1961,
  stateRoot: "0xd487ffaf2f2838d69417f81c9d2bfca5d2e0d024ddda433bba9b8f2099eb96e5",
  timestamp: 1632426743,
  totalDifficulty: 35057075981876873,
  transactions: ["0xc22ada3e380ae70769a31237367b691b19ed98c06501a508a0ccde772af68a8d", "0x3bbffd220a84e6debf9d548a16862712f281bd1d0a606370e3cdcf5130bcf521", "0x12084623eb26288289c1b02042ef2228544c18fe75c7e9002808af57055c7168", "0xf918ae7c8ee5caea62e9b61f9bc123e3e7c64badab044f7f6d6c9424adcccd74", "0x5a3e39e86eb9f1256bc853c83cffc685a8286e687b6204fed9ce575ac945ed6a", "0xb7ae1d52cafaa1344cb45d9e6767e06387a83603b638a1495bf528eaa7216622"],
  transactionsRoot: "0x9179958e4a3e9761d013ac103c1eeabde28bc20b8290b106871d888234e3111f",
  uncles: []
}
> eth.getProof("0xc626553e7c821d0f8308c28d56c60e3c15f8d55a", [], 'latest')
{
  accountProof: ["0xf90211a08b35ef8aaf1001ffe7dff4f6221f26b66e34dd968abcee85a8ac32091d06251ba05cafd14da795cdf8a394b35defa13a536fdfac14b6030af3c37f6493c74f900fa084d432a820fa6ac48249fe05cf14cb1c2d147b632e88c55b08b0453b855e78dda0728563ec9378f52f06b03c4e95844719936356b4f2a8499ba9125823d1acd8aba0f9c8c6d587de5a4beb8beab7c268f1843004378dba0d282e7bcd8c85e792d7eaa0e85343ecaeea1eaff936300ccde67f35c496fa94ef598155b710f7a623a57936a08ee22057f1ecf34963bc50ae61316946a624647c22175727fc9391a20e9fd228a065baa728267c680520b7fc43e1f9139f907122d5573d66470d89fcd053ea3140a0bbf921d19e38c35e214ebaaf6a870d0a0150ca82dbc6856c78a30c484f19e7a0a0dee8ba0a60377b394b888faf60952d79662d5a3d858e2ed0a905064ec894dbdfa009d51219b8b2485c903ac06a42493e3541e406ccf34f57850f1096222165aadaa05c708ed7f6a0d0d3aa13d6f973bcdfc7cf0f6d26f1d4485d820de2d2311b3ee1a042f84164e5d78135eb89917b395a3c635c2421a864aaeeb6c20492b7109cf57da090dbe8366a32a6e13ac284ee7755c607833198aa7b7d0c6e2cb5c879aac8d187a026ca02d08826865db5d5ccb312e0daad3d49a2b7bff32dbc817119fe36f1b3bba061c0982c847660740a3a240d8ee893db660a50afe88f1d0aa404c75954d9c50780", "0xf90211a0ce7a6755a8443c9fd0cc08f374556033a1e6ce60aa5979fe8df7146c6c1fdec4a04531ebafd19bc1fc4a523cc3cdae1a0aa9e4d0ebb9c967c04038cc7b32341de1a035dabb7ae61124027aa8c587703217401680d24d141a76ac2e3f8eec4024d8fca04d6af591b8050bb4ad2f37d7e4cffc443643917e5775199c383b1e772b1949d0a01bd02db2b2b80e98c03e3991eeaad519e6fd280f9b59214cc6f09a961d6c8d98a04af90b5fdc1c45420c30696bd0b5de4fb67e4ae6fb6ea5eee82cd34d484f9ab2a00d9eb4c1b6a1c3e2206c80b5d199de4d16c711bdc5d9421f377aa90c76d31da0a0d3466cf77c90edd1c996fc6132de73dfd5c0f7969939fd59b7acc5ad69fb353ba055d9c98f5c78471f4fbe5f692ea0f810da8c5225a7bfd7818a686c7646446b00a030852522d75897983eca2893388ff1c45b8de755472a3af1d8228f6e35770d61a0714d8230137c266b283f9dedda3f91afd0ffb06e3188d1592b51dbeb366725f0a0fafb282a71f6b66114bded6045e92b2ca6af245981c551df0461018e7f7c2057a00ba8d9e99596bdfc8276a2840e6bfd52f6ea1f3a7618452e14bb8fc908f82084a06b7159184ba75c6ba7785bafd1a541c335274db48418c72661ab1b248ee30076a00ae332520383587d2a5d9ed45cd934b4bf2625d7ac2bca2479210adca1cef6bba038cd99d11c174ddb97c6b175b75da8ff95061a419a538a7a94e87851f9fb67c680", "0xf90211a0c8e37dd9aacf55947b7fad9a03195b05e02a1df6779bb809ef7cf7e3d4c0103aa0897aef3ff6c7db1f412e87f4bb98b2ffede1f23a17ea63d4201c2913482e92e4a05c089263749e659ef8068fd3cc8461b703400b70b4fb3e0e685196a04e242fcea0491b802967c46150575fc36766a8e3cfa5da0be00fef5b6b39d870d2dbf88408a0466d8527d6613510f1a06864a409451d54c07f4031cbaea18c5383b2e9924842a03b701a4ce3fb065eb2ddff36ba4f1bb2ca997aa86cbbb493af4201588ff317b5a03eb54ed71abe6a3ebca0b5ff956ea05814029ffc85ff624ccd4e2b3120aa5f52a0aea074cbeff6c6e2790aa70ca280c8c9c832e8c8c3ed7e0a3ded48a5bb75ea71a0d2a7453c0a56fa6b8a10e4eeb9abbe833fb0e6bf3c8f3ac059f769b4b23482b6a097b7af459384cf53aa499f741de7f52404207523eae2bb73cd7b5f72528c0edea0c9e0c7fe11eff50eb7aa794961900935fdb98af0b0c493a7174b78e201d2bf5ca0c0e5edccaf22e3207c5e4a4880989da92491245ff314ad1b513cc75316f00249a0b97e872b44f81b37c93f7b964e6cdb9a0e3391988901f8ad4587ee5e5ceafcaca0ea9bca9ce0e48044f5635b17f1d05e2a24cd4d79bdb93812c5ef4d1b82e8d653a056542cc749f058326a35351fb036eb6973e4b1df6a5e3907af05209ed087bf38a0823dfc5b36a11e2fedf7dbb763206f378b71d84a4c9c16428e96b3b6f5de431380", "0xf90211a035202c8e4a28b2b360e50c812412dd1c81be0b25e15de11af8d167be083a4605a038c7bdae901b4c9bb75e1568174827e2f4690b4daa996a3bbacdcfac7651cd2aa030df4afb38e44e9a3e26f53fffbd00e7c373097580a14a348c3eb3bbdea4cebea09445e3d5c72e5149bc03d5ea7391957451f45711890d31c8dfad2d0605230fd7a09e48c03b090f5bbd304e3995fef75e774a50786f1acef63aac1e2993d55ed2e9a02fb3f9660c33b686484fef1a4cde7d717c48dd8f62b7138e96fdbec57fc2aee0a0af720636864c9adeee8cd0fbaedf2a8a60a5a1cf3749e20b0a469d4306312f4da078cb02067b8c7c2c562073a61632c4df75142d127afe4b7373211a213afbeb6fa0bbfde4af6bb830609dd172a293e036082f507f867fcb1d287587e4a02592b2a2a02e32951295e013e536d5f7c15875e34cfa1e1f3fa43a2b36876475e1f61e142aa0c8eb4b24d2eb20183a5c30d433f5d8993751706edbad7d1867c5d964af52cb97a046d6bd9e5246d10c34b36f28c0fbfa4be81e1815ae8dbbd7abd78df11d29c753a09cd2d9c811fddb32ba31902d9d2e091a970602fb2ed827648b75195a9cae8b1ca07e1c080ad7292e95afd4a4063f8411e3533ad8375885582acb4c8039175149cca0aa317a285400917f6b1e24234c7e8fdf64e6e326667664e61e8dce872789d6faa08f78ad2f58b27881381993c033749cd065944a586304fe8118695ccd2bb9ee9b80", "0xf90211a01b1aec789d90bc913f8162c53c9fcda2f9aa45c0999f7ade0ec0985c420a1c56a0f601cbd4213e4e81878cef66305380f706b5bc24facdc0a5ab97cca8c295a884a02e0a5612bf79363ff21157063c7115b56c3ef00edf68299c16f0673db6dcbaffa0ad2ed3f0757259cd6fe64ded5f0538d57576089a36d3015a60337d85c9de93e9a0dd5d143dfdc4e735b4fa6844972f3d946b641a2d28ef9584b8cd66188503d609a02b0ccc1c5bfa79bc88bd38aa33ea32561d2e94f71c7bae372a1aace745ac192da0fda4979a04e4b360620cc6678a27dfc448c8d51a564eefb9192837c4292906bea0ee0174a1d4c6492c970603958016b9ff003d7c10fca26b7f9ddd7622c89e5752a06eed4d9df81427c83112c65c1a2e11ca12d10b9db22501586027d643cbccb989a074eb0e051454404d7e36b84ebe3ad27dfcf04506cc59f5c3611c80afbf5d73fba03bc1e213b78ea2b1db4d2a23acade8e495796468a3a06bd82eecc32c478b4339a0950122838f7ccda0ee77748fa5bc747c795bc850e89e6837bd3b539479d386c2a0ea8aa9d7c3445a7c9367992b598c210b6a05cee4acc9042c78ff296ac6324f0aa0a8713d37d7b216a20ace107f1612af4d2477b3e2c02b3a27dc2fbc487db6cc5da012c9c4863f0fa618268de346b96671b7e1568d9a41295926d1bbe1a3552dfa86a026309e68d1a4c82bbae891ba689f3488be71b5f2dc8d466961697554668a031880", "0xf901d1a001cc3f0f8a6587690418355cc0d2bbb55e170221d16e12c0a538910d0a7356b7a072fc6e97a7914c63f79d5df4f052cee94227d5157d2ddf7e96a2d27a3fc643f380a09c6ed7ac3cbc93989e35c1a42227a08cebbd58306a7bde31d58c4601586f44c9a07151e5b77fbfc418a2e2ff920f2962925eb904166f1202a113d776bfe2a38dada0ff0e369b099c8d6b2946c219bd62364ff34df4f0846538fc3878df42f10fdc2aa01433c88065c239a26ff1152bfb21f00af7a7e0fa1dddb35494f2046ee9de8de3a0c0d7e1cbaa2b6e4e68797fd09a2e5173e08318a9e81a3050bb907f7a70e6000ca02727ef0d8ddc604f2f2a7c49f8a863a3ac42e06bc7e3ba5cfbd19f26efc3b03880a08ad2c34e584fc786f6bf59f3289cac4d684fb43029cb8a46d092471fac0b081da09cfaeb918831b0520bdf84a3a7451b926619b349646301b6e04fdfd22f618099a0957bcfb32c9f02d2eb0a599fb8f013f7fd08a93aa7a4a487713492ac245590aca0699fdb4f7820aaa430710adb626d3360e80a4e46e7c17cb2b85c3d0711c3896da083685a27a548ace44319b5e9a7d8ad0cc2655ee0c6b22b9a1cc9a803d7b70efda03ab16da1d2f81bc872aff69c2bb774313a74c4f8b0e5caecf9d142a8f0dfeef680", "0xf85180a06abbc406fba9a3fd5cea3732a250df379f9db45935e49ccf27c0d31c3c5ef497808080a0ad26dc113c2968bb2853036f34132fc00e95bb58e4940491234b8aea779670268080808080808080808080", "0xf86f9d347a234d6dc902b4ea893294e5494f9f61dbca75ab4834c2c747aa29d4b84ff84d80898cc8f68890288a3bf6a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"],
  address: "0xc626553e7c821d0f8308c28d56c60e3c15f8d55a",
  balance: "0x8cc8f68890288a3bf6",
  codeHash: "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
  nonce: "0x0",
  storageHash: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  storageProof: []
}

@codecov
Copy link

codecov bot commented Nov 29, 2021

Codecov Report

Merging #1590 (ddfc8d5) into master (164989b) will increase coverage by 0.10%.
The diff coverage is 91.54%.

Impacted file tree graph

Flag Coverage Δ
block 84.96% <ø> (ø)
blockchain 85.08% <ø> (ø)
client 70.89% <53.84%> (-0.08%) ⬇️
common 100.00% <ø> (ø)
devp2p 82.89% <ø> (+0.13%) ⬆️
ethash ∅ <ø> (∅)
trie 86.09% <ø> (ø)
tx 88.62% <ø> (ø)
util 91.81% <ø> (ø)
vm 79.71% <100.00%> (+0.39%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

@jochem-brouwer
Copy link
Member Author

Some notes: the first item of this proof is the first node (somewhat expected), so keccak256(accountProof[0]) equals the block state root. The final node thus contains the data required to create an account.

It looks like something fishy is going on in our MPT getProof, it returns the empty array for the account proof (which is not correct). I am assuming it is because we do not include the first node in the path (it probably skips this when trying to findPath). If we add this then I think it should be fine. We should also check if we can create proofs for non-existing accounts (we probably already support this).

Non-existing account proof

> eth.getProof("0x68268f12253f69f66b188c95b8106b2f847859fc", [], 'latest')
{
  accountProof: ["0xf90211a08b35ef8aaf1001ffe7dff4f6221f26b66e34dd968abcee85a8ac32091d06251ba05cafd14da795cdf8a394b35defa13a536fdfac14b6030af3c37f6493c74f900fa084d432a820fa6ac48249fe05cf14cb1c2d147b632e88c55b08b0453b855e78dda0728563ec9378f52f06b03c4e95844719936356b4f2a8499ba9125823d1acd8aba0f9c8c6d587de5a4beb8beab7c268f1843004378dba0d282e7bcd8c85e792d7eaa0e85343ecaeea1eaff936300ccde67f35c496fa94ef598155b710f7a623a57936a08ee22057f1ecf34963bc50ae61316946a624647c22175727fc9391a20e9fd228a065baa728267c680520b7fc43e1f9139f907122d5573d66470d89fcd053ea3140a0bbf921d19e38c35e214ebaaf6a870d0a0150ca82dbc6856c78a30c484f19e7a0a0dee8ba0a60377b394b888faf60952d79662d5a3d858e2ed0a905064ec894dbdfa009d51219b8b2485c903ac06a42493e3541e406ccf34f57850f1096222165aadaa05c708ed7f6a0d0d3aa13d6f973bcdfc7cf0f6d26f1d4485d820de2d2311b3ee1a042f84164e5d78135eb89917b395a3c635c2421a864aaeeb6c20492b7109cf57da090dbe8366a32a6e13ac284ee7755c607833198aa7b7d0c6e2cb5c879aac8d187a026ca02d08826865db5d5ccb312e0daad3d49a2b7bff32dbc817119fe36f1b3bba061c0982c847660740a3a240d8ee893db660a50afe88f1d0aa404c75954d9c50780", "0xf90211a09b746fafbaec59bfe7531df4c3f7e90fccae2310b4a07244660180ebdae83740a00ca3a961e09eaa73937dd64b4cad6837ca8c0821a1916bdb88ae740d431f8224a025b14b34bb7bffb0569764ebae9fd9423e046c09e4fd23c5f4a3f98aae736865a08c67c635ed533f995a81d4f31e49657d6ee9a0c55908d83316bc02cc2b83ae36a048458384065d237f47bcdef04bf8b8e3da48b7b69918b2ad6140d531d917d8c9a02695404dbe42d4d236adb5bb9a0e8aa093f8dc852b43d6440e354cb1c60256d3a0695b968f22e3e0423faf0f40ccc3d2efff833d60cae01ee63ed9ee394b5b76a8a07ae0b7685ba88b1781e04cadeeb4c507b09cf697d1de7af3ee0f3e1b4a05b2ffa0210366b57186281985b8282d42a4f5a5a40dcf313d289b4eeb0e2daafad32f11a03ccafe0cf0444ded8aec013904c5eb769e6fd13e33b11d1987cf4b5b90ea1f71a09a1cb6c95fa9c023b69f99bfb349f8d42cc515670581dc4d89f59034d43e6f7ba00309f400a9bd16859ef8f05d66b7da5e352dcea7a8c78e0c80e313bc44e45e46a00b21a780fe8be342e1b174be47cb8f135bc1ffed6572b5e2a84898aed7ca5039a0cc9c1e379a9a07b241d69497feb4c1a11dcd7711e1cd5ed9000d7c06a14b56d1a02e12ef72e9479309bba56693075259ba16b344a67ba63b0b107e9ac21ee87935a09f09b7a10b78dfa3dd2a9056a68e5256fcf0aacc72a50d675903760e8f3873d580", "0xf90211a0c77f7f856b72389bb24bf62830a3d06970bb4f30434f5b30a8641b1f87dff3a9a0d5f62ad871afdf1cf9acbafe9dd59c8402d84f405210d29b64152d1d86c9f6f3a0b2ef592df3844f2658c985936fe25b36c5ccc20cfb5784cd0d6c5e48bd59a0fda05d5918d537707b8081857d49b41e46bfad4aa678b6e752fc1b6896c1a2b12037a053a2af0b50e5e7aebb906f594f9298c3021983b14d3658bddab310cae15ca04fa06632410e8baa78fd71b16ec9d51d393d5e235815f4098e1cb33fe59562c08cf2a07c4d680cf02d0335323bed8f68dddb7a1ea1f6b5ae8a073b86ea94725c7976efa064d41944b9d16a2a3874eccf6afddef309d49f817d4ac7ad157f580267dd98f5a0aea1cc543c6acfa6c791b2d10a2bc817bf8cc3bb4475c4b6643fc0c9edfc9636a097db9562b22b4df35b5657e486fefd4f37e61b5245bb01fcecce15fef354db34a03ed0dc09dbf21f2a34bbfd55c32763b73767c488b7ecd8438e612b1f1edafb15a03a68f87f03b402306513d84154268c8e47d9b4a82afdc166ed53ac68f45cb8c2a0125c451b9efc5652dfdbbcdcf4e510c8fb635c9ce6f38d4e1b0759e4148892d0a0f4890433b6e78937195db61187573a22929538d7568ca557a22a5481ce256896a0ca6e0cfe4b2bde21d0e19d84b76df64540bd8dba8f0520aedfb746e54a2110e4a096f0f6ef207acd392eeedeec3421d4c8209bba852c2794abed25ee0902b46a6980", "0xf90211a09328b9945087040f7239ab09f3ef8c37aac04ffe7ac9a5e26715df7d72e6cbd1a07bb098ea9c1c2209f0bae7b73813c72a85767e3537468aafa7347fb205d571cba02845790d87fd1ad9075fd73ecd1d189db5b5bb959e545f5a65450886e45a2692a03c9471e0f8c9b405f8050cfaa4ba012105a575052bd090f9364c59da6f8f73afa09d5f7bf6abb44400e271a6631686c1f0a3accf01337a6d45be3e02a6499c964aa0e4735aba6b2680dcbf311d4a91d41050928ec0a39ab21d8144883533b2681ee7a01b1544aba915c38085d2d1217cc9def8f227ff0e6ed9cbdb221de6d3972684efa0e42dc212adda224a2c4841437cecee740ed46b7663988524c89d9452936331baa0dd6438793fddc6097569f17c4da7260a8d7977ba491f9dc8865601dc407e8710a0210a0f858fdedbafbefe78fba9e79b1332d2f60c508f84b56f7374367dbc9528a0e061e2725c148fe2294075bf12c16cbd0c3b17cebb2762014fdf1852f3f7d69da02adec7fdf56143e4876ee8431172440a788e9c28ecfd96b47191615742203f89a0aead602208e4b64bc9db20f44aba1829ea3fba13435eb17472f16f123028b754a007f37c3fa6b6e59280b0abc26426486978e9e759b0419c31e1d26a5937580853a08de3670a41f86c916fbfc1232f27f7c714250006cd5d723f180480c6a778b294a0746c363bb9f2b65d27d8db4b9b65fb06b4d48543a342c84129205641148ce10e80", "0xf90211a0f9c18d36278289fe4db820f13f5a605506408e378eb053ffdc3002480ff4d96ca04ff083bc0c9b339b8b4996b0b2b486df5993999e5a77d9a3cc6cf28a67e7df9ca08f3ccbd74eb7e86029e407fd13ce97c7bfe59a1a4767557df4b3cecc0126e332a01260d2d4f4f47d7fa898eb2cc4d75ee522eda8cdde547d4570a93a0cac046283a088a4a891bdbcfae8339e3b8f5d8e46f927ef9c358253c7b97d199fa361457f03a0b00b53a7e81ae32247a187698b79ec5cb22acb0e367445cc3462df0c76d7ffe2a0cb9a847f5809b650cd7d6ad13a01077bde94b49272c3ea034de1497b19d4dca8a059d17a33e6a4160d637abaca94828162c38dbc847366463792e2bebde8abed8fa04b5b561e1ec26b9c12533443a309c01c7aa730d05669afc7fcc44a2e52474b63a08769244cf7e7b8f27c6ca04144535ea9a7ba78f303ee8bfed293c238fe9089faa0ec80e65ade132afdbe583f93bcce7d3c259de6091a8472d0727f53e17fa36aa5a075d650f6462355ce62e26d00eefc229c7ae7ef632e3bc30e1639513065d0c70ea073ad244d3638a66e709df7660c91f0f06a0eefcf3e187ca668cba5e506e14e53a08f8235b788373bb22e28bd8900a0c95c0deb805e79a6e5997a8c7535ed09d6dba0b19d4e1503d582f33e9706edb6dfa3d1d0bf9d80a75a980bc533a7c1f858d15da0dca273067882c2be8da00e75a8a98393b3343959591182e51d3805ad55f768ca80", "0xf901b1a0583a7d00c9bb314f3ee940090655de5e26777d4de3540786b8956f5c52e4bc6680a0829054045be406c1ad4261ed7d43f09a182ae78060af0fa7f840d4fe115e2fa2a03becf44de9957e41c3b33de2610fb6df58d5e4f8f3f13cdc0c078fbfdede638aa0c8062f45f4f9ba1ac9115a677edb3dbe0fa636f8100776ae672540cecf47271fa0ca4fe21d1d7fcf0c507105cdac4a650c0d64a635119bf0eb44395949b4741791a0180d174727317dae6b6cff12125fd35cfd1ce4ac9e6723b11f40930d7e46293ea0ff62b84d1c8daec04456279571ca023d8e267a9679ce2bd3fb8909b35b7b6565a0852dcaf6235f0f026165787f6a41efe25328236f2f02e41614c0302041a0a93ba00334192a13b3d391bafd35a753d791b92deba86fe7e925a4583d012e315fa8a6a011b478c60b475ac17e3f8af6843c70afdc0940bfa5492dcbcb74219887b33d5ca0b1d221035f1d25b6d3eb8630030da1d71e18b43484bd817fa50b3d42cb970681a00bbddbe47206773634d383e6ec10e0730f58ac0106b4850f32500cb40d17a72aa008c7b471b980fc999674830ce9d45372937663c55c4290d175194eff1b036c47808080"],
  address: "0x68268f12253f69f66b188c95b8106b2f847859fc",
  balance: "0x0",
  codeHash: "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
  nonce: "0x0",
  storageHash: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  storageProof: []
}

(Same block number / state root)

const value = Buffer.from('0000aabb00', 'hex')
const code = Buffer.from('6000', 'hex')
const stateManager = new DefaultStateManager()
await stateManager.checkpoint()
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: without checkpoint/commit the cache is not flushed which means that the MPT cannot find the right path for the requested account (this should be addressed, ensure that cache is flushed before trying to create a proof)

Copy link
Member

Choose a reason for hiding this comment

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

I guess you can just call into cache.flush() in the new proof functions? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah yes that should work and makes more sense.

Copy link
Contributor

Choose a reason for hiding this comment

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

in normal vm operation the stateManager should checkpoint and commit after every block, so we should never run into a scenario where this occurs, correct? moreso just a spec test setup particularity? just wanted to make sure before i resolved this conversation

@jochem-brouwer jochem-brouwer changed the title Implement EIP1186 (rebased) Implement eth_getProof Nov 30, 2021
@jochem-brouwer
Copy link
Member Author

Note: have renamed this from EIP 1186 to Implement eth_getProof. The EIP is stagnant and outdated.

I have included 3 tests taken from Geth 1.10.8 and ensured that the returned objects by us are equal.

There are 2 things which I noticed: (1) there is a field address in the returned field (which is thus the input to eth_getProof) which is not in the EIP. (2) If Geth finds an empty slot, it reports the value as 0x0 consistent with how Geth reports 0 nonces or 0 balance.

I also noticed that Geth does not enforce 32 bytes as keys, but just left-pads it with zeros if you dont input 32 bytes. You also can input a key like 0x1. In the returned proof this key is copied, so if you either request storage slot 0x1 or 0x01, the proof and the value fields are of course the same but the key field is not.

This PR is not entirely dedicated to create a full blown copy of Geths return values but it is good to be aware of these things.

@jochem-brouwer jochem-brouwer mentioned this pull request Nov 30, 2021
4 tasks
@jochem-brouwer
Copy link
Member Author

Note to self:

Trie verifyProof returns null in case the value does not exist (i.e. the storage slot is empty or the account is empty). Otherwise, it returns the value of the requested key (i.e. the RLP encoding of the account, or the value of the storage slot). So we can use that to verify inside state manager that the reported values in the returned JSON is indeed correct.

@jochem-brouwer
Copy link
Member Author

jochem-brouwer commented Nov 30, 2021

TODO: make verifyProof implicitly support non-full tries (fill the tries just as in the tests, and then use these incomplete tries to verify)

EDIT: this functionality already exists 😅

@jochem-brouwer
Copy link
Member Author

Hmm weird our Trie does not like the Geth proofs, throws invalid proof 🤔 We might have a bug in Trie's verifyProof

@jochem-brouwer
Copy link
Member Author

Great, account proofs, non-existing account proofs, storage proofs and non-existing storage proofs should now work.

@@ -42,4 +43,6 @@ export interface EIP2929StateManager extends StateManager {
isWarmedStorage(address: Buffer, slot: Buffer): boolean
clearWarmedAccounts(): void
generateAccessList?(addressesRemoved: Address[], addressesOnlyStorage: Address[]): AccessList
getProof?(address: Address, storageSlots: Buffer[]): Promise<Proof>
verifyProof?(proof: Proof): Promise<boolean>
Copy link
Member

Choose a reason for hiding this comment

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

Have thought about the API of this a bit. For now I would make a pledge to not add this to the StateManager interface at all but rather treat this as some custom functionality we add to our own StateManager implementation.

The functionality is not used in the VM at all and this will rather confuse people and make life harder for implementers who want to do custom state manager implementations, if we bloat the interface more and more.

Instead we should add a dev comment (so: no public code function comment but rather only visible within the code) to both functions like:

/*
 * This function is currently not used within the VM but exists as a utility function for people 
 * who want to use the StateManager out of the VM context. It is therefore not part of the 
 * StateManager interface.
 *
 * If at some point it gets necessary to use VM internally make sure add to the StateManager interface.
 */

Does this make sense?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this makes sense. We should also create a standalone StateManager package, see #1599.

Copy link
Member Author

Choose a reason for hiding this comment

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

Do you think we should create an extra "type" of StateManager which has these proof methods? Like we did with EIP2929 state manager - the state manager with proofs would inherit the EIP2929 functions.

@holgerd77
Copy link
Member

What's the status of this?

@jochem-brouwer
Copy link
Member Author

What is left here is implementing the RPC methods at the client side, which should be done by this week.

gabrocheleau
gabrocheleau previously approved these changes Dec 8, 2021
Copy link
Contributor

@gabrocheleau gabrocheleau left a comment

Choose a reason for hiding this comment

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

Looks good to me, left two small suggestions. I am not familiar enough with some of the stuff yet so it would be best if someone else could also review.

packages/client/lib/rpc/modules/eth.ts Show resolved Hide resolved
packages/client/lib/rpc/modules/eth.ts Outdated Show resolved Hide resolved
packages/client/test/rpc/eth/getProof.spec.ts Outdated Show resolved Hide resolved
  * bolster invalid proof error messages
  * extract ProofStateManager tests to own file
  * move testdata files to own folder and use import syntax for improved type info
  * already have array validator (usage: `validators.array(validators.hex)`)
  * add typedoc for getProof (thanks @gabrocheleau)
  * update getProof.spec.ts to match future test setup from PR #1598 (this slightly modifies the returned accountProof)
@ryanio
Copy link
Contributor

ryanio commented Dec 9, 2021

beautiful PR @jochem-brouwer! super clean, and easy to follow 🤩

changes from my review are noted in the two added commit descriptions.

will approve when ci passes, if everything looks good feel free to merge @jochem-brouwer!

Then I will update #1598 to include getProof.

Copy link
Contributor

@ryanio ryanio left a comment

Choose a reason for hiding this comment

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

LGTM!

@jochem-brouwer jochem-brouwer merged commit bffbc03 into master Dec 9, 2021
@jochem-brouwer
Copy link
Member Author

@ryanio Thanks for the updates :) @gabrocheleau Thanks for the review! :)

Merged! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Trie: Add support for EIP-1186 (eth_getProof)
4 participants