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

Contract state should provide proofs from state root #2076

Closed
ilblackdragon opened this issue Feb 3, 2020 · 13 comments · Fixed by #7593
Closed

Contract state should provide proofs from state root #2076

ilblackdragon opened this issue Feb 3, 2020 · 13 comments · Fixed by #7593
Labels
A-chain Area: Chain, client & related A-RPC Area: rpc C-enhancement Category: An issue proposing an enhancement or a PR with one. P-low Priority: low
Milestone

Comments

@ilblackdragon
Copy link
Member

Given contract state queried from the node, we need also to provide a proof from this state (or part of the state) to the root of the state root that's in the block header.

@ilblackdragon ilblackdragon self-assigned this Feb 3, 2020
@MaksymZavershynskyi MaksymZavershynskyi added the A-RPC Area: rpc label Feb 4, 2020
@ilblackdragon
Copy link
Member Author

@MaksymZavershynskyi
Copy link
Contributor

Since we decided to use events differently (see Near-One/rainbow-bridge#12) this is no longer a blocker for EthDenver.

@frol frol added C-enhancement Category: An issue proposing an enhancement or a PR with one. P-low Priority: low labels Mar 14, 2020
@ilblackdragon ilblackdragon removed their assignment Mar 18, 2020
@ilblackdragon ilblackdragon added this to the Post MainNet milestone Mar 18, 2020
@ilblackdragon
Copy link
Member Author

One important point that people need is also proof of state non existence of some data.
E.g. if specific key is been queried from the state - it would be good to have a proof that key is not in the state.

@bowenwang1996
Copy link
Collaborator

One important point that people need is also proof of state non existence of some data.

@ilblackdragon could you provide a use case?

@stale
Copy link

stale bot commented Aug 31, 2021

This issue has been automatically marked as stale because it has not had recent activity in the last 2 months.
It will be closed in 7 days if no further activity occurs.
Thank you for your contributions.

@stale stale bot added the S-stale label Aug 31, 2021
@ilblackdragon
Copy link
Member Author

ilblackdragon commented Sep 2, 2021 via email

@stale
Copy link

stale bot commented Dec 1, 2021

This issue has been automatically marked as stale because it has not had recent activity in the last 2 months.
It will be closed in 7 days if no further activity occurs.
Thank you for your contributions.

@stale stale bot added the S-stale label Dec 1, 2021
@bowenwang1996 bowenwang1996 added A-chain Area: Chain, client & related and removed S-stale labels Dec 2, 2021
@stale
Copy link

stale bot commented Mar 2, 2022

This issue has been automatically marked as stale because it has not had recent activity in the last 2 months.
It will be closed in 7 days if no further activity occurs.
Thank you for your contributions.

@stale stale bot added the S-stale label Mar 2, 2022
@bhc8521
Copy link

bhc8521 commented May 23, 2022

how can i verify a contract's state provided by rpc? if it is specified to a single key-value pair, that would be helpful, thanks.

@blasrodri
Copy link
Contributor

Hi! As per (2) in https://gov.near.org/t/near-polkadot-using-ibc-trustless-bridging-requests/22807 we are in need of having this. I'd like to get some mentoring/tutoring and take the issue in my hands

@mfornet
Copy link
Member

mfornet commented Jun 20, 2022

how can i verify a contract's state provided by rpc? if it is specified to a single key-value pair, that would be helpful, thanks.

@bhc8521 you can get specific values on the state by calling an RPC method. Check it in the documentation: https://docs.near.org/docs/api/rpc/contracts#view-contract-state

near-bulldozer bot pushed a commit that referenced this issue Sep 9, 2022
Replace TrieIterator::seek method with TrieIterator::seek_prefix
which, as name suggests, limits the traversal to keys which match
given prefix.  That is, where seek used to return all keys no less
than the query, seek_prefix will now further limit that set to keys
which start with the query.

Issue: #2076
near-bulldozer bot pushed a commit that referenced this issue Sep 19, 2022
Add include_proof to QueryRequest::ViewState requests and view_state
runtime function.  If set to true the proof of the response will be
populated with nodes which can be used to verify the
values. Otherwise, the proof won’t be included.  For JSON RPC, the
default is for the parameter to be set to false.

Furthermore, deprecate empty proof fields in the query response.
Those were historically always sent and it’s possible that clients
exist which expects them to exist even though they were always empty
in the past.  Plan for the future is to include the `proof` field only
when proof was requested.

Issue: #2076
nikurt pushed a commit that referenced this issue Nov 9, 2022
Replace TrieIterator::seek method with TrieIterator::seek_prefix
which, as name suggests, limits the traversal to keys which match
given prefix.  That is, where seek used to return all keys no less
than the query, seek_prefix will now further limit that set to keys
which start with the query.

Issue: #2076
nikurt pushed a commit that referenced this issue Nov 9, 2022
Introduce visited_nodes to TrieIterator which records raw bytes of all
the nodes the iterator visits.  Those are then returned as proof in
response to ViewState request.  Since the exact nodes the iterator
visited are included in the proof, it is therefore possible to verify
all the values returned in the state.

At the moment the proof is always included.

Fixes: #2076
nikurt pushed a commit that referenced this issue Nov 9, 2022
Add include_proof to QueryRequest::ViewState requests and view_state
runtime function.  If set to true the proof of the response will be
populated with nodes which can be used to verify the
values. Otherwise, the proof won’t be included.  For JSON RPC, the
default is for the parameter to be set to false.

Furthermore, deprecate empty proof fields in the query response.
Those were historically always sent and it’s possible that clients
exist which expects them to exist even though they were always empty
in the past.  Plan for the future is to include the `proof` field only
when proof was requested.

Issue: #2076
@folex
Copy link

folex commented Jan 19, 2023

how can i verify a contract's state provided by rpc? if it is specified to a single key-value pair, that would be helpful, thanks.

@bhc8521 you can get specific values on the state by calling an RPC method. Check it in the documentation: https://docs.near.org/docs/api/rpc/contracts#view-contract-state

@mfornet view_state does not return proofs, it returns empty vec instead. Or am I missing something?

for example, some random contract on testnet:

% curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{
          "jsonrpc": "2.0",
          "id": "dontcare",
          "method": "query",
          "params": {
            "request_type": "view_state",
            "finality": "final",
            "account_id": "dev-1673415696476-75551828987522",
            "prefix_base64": ""
          }
        }' \
     https://rpc.testnet.near.org
{"jsonrpc":"2.0","result":{"block_hash":"4V6Wi5nbgukprRR4NkaqK5pd6tA3xzE2mwRcM7dUuQns","block_height":113511599,"proof":[],"values":[{"key":"U1RBVEU=","proof":[],"value":"AQAAAGEAQGNSv8YBAAAAAAAAAAAAfQAAAAAAAAABAAAAbQ=="},{"key":"YQwAAAB5b2NuLnRlc3RuZXQ=","proof":[],"value":"AAAAAAAAAAAAAAAAAAAAAA=="},{"key":"YREAAABrdW1hcjIxOTEudGVzdG5ldA==","proof":[],"value":"AF7QsgAAAAAAAAAAAAAAAA=="},{"key":"YRQAAABmYXJtc3Rha2V5b2MudGVzdG5ldA==","proof":[],"value":"AOKSn77GAQAAAAAAAAAAAA=="},{"key":"bQ==","proof":[],"value":"CAAAAGZ0LTEuMC4wBAAAAFlPQ04EAAAAWU9DTgAAAAg="}]},"id":"dontcare"}

UPD:

If I pass include_proof: true, then it does generate proofs! Yaay ^__^

curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{
          "jsonrpc": "2.0",
          "id": "dontcare",
          "method": "query",
          "params": {
            "request_type": "view_state",
            "finality": "final",
            "account_id": "dev-1673415696476-75551828987522",
            "prefix_base64": "",
            "include_proof": true
          }
        }' \
     https://rpc.testnet.near.org/
{"jsonrpc":"2.0","result":{"block_hash":"H8ggMmhSsQSX2UQsvKLpgEXswbMyqzdKQ1KCSajCf4XV","block_height":113513560,"proof":[[3,1,0,0,0,16,250,128,112,205,72,201,163,77,108,143,120,65,12,251,202,98,202,239,22,78,78,117,31,128,134,166,189,6,151,26,9,200,236,11,99,91,15,0,0,0],[1,135,2,172,25,44,187,213,198,212,214,210,120,117,113,112,227,4,235,115,149,107,99,171,13,95,232,249,167,222,134,72,184,76,246,93,10,160,129,101,71,169,211,30,161,106,37,233,47,36,207,206,5,94,72,5,253,129,10,208,108,27,212,18,121,1...

@folex
Copy link

folex commented Jan 19, 2023

Another question is: how to work around error State of contract aurora is too large to be viewed?

 % curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{
          "jsonrpc": "2.0",
          "id": "dontcare",
          "method": "query",
          "params": {
            "request_type": "view_state",
            "finality": "final",
            "account_id": "aurora",
            "prefix_base64": "U1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUK"
          }
        }' \
     https://rpc.testnet.near.org
{"jsonrpc":"2.0","error":{"name":"HANDLER_ERROR","cause":{"info":{"block_hash":"AuGK66R3CaS9WrvXHJJqscqFTQMihaXb6EYLSrWTpN7J","block_height":113511537,"contract_account_id":"aurora"},"name":"TOO_LARGE_CONTRACT_STATE"},"code":-32000,"message":"Server error","data":"State of contract aurora is too large to be viewed"},"id":"dontcare"}

You see, i've used U1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUKU1RBVEUK as a prefix in the hope that if it's a long enough prefix, then zero key would satisfy and empty result would be returned.

But it seems that prefix_base64 doesn't affect the limitation on the size of contract state. Is it at all possible to view a small piece of state of a big contract?

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-chain Area: Chain, client & related A-RPC Area: rpc C-enhancement Category: An issue proposing an enhancement or a PR with one. P-low Priority: low
Projects
None yet
8 participants