CosmWasm / wasmd

Basic cosmos-sdk app with web assembly smart contracts

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't wasm's module query before block commit

JoowonYun opened this issue · comments

Requirements

Upgrade modules have become a standard, and many DApp operators have a requirement to query the wasm state of the block before the upgrade. For example, re-index DApp data.

Cause

  • (Assuming that the chain was launched using the previous binary alone to collect the state of the wasm module before the upgrade.)
  • When NewEnv for querying, a panic occurs because there is no block header information other than height in the context.
    https://github.com/CosmWasm/wasmd/blob/main/x/wasm/keeper/keeper.go#L756
  • Context's BlockHeader is assigned only at commit time(Block produce or block sync etc. This makes it impossible to query past data.)

Question

  • Is there a good way to get state data before upgrade node?

There is no support to query historic data for the contract, only for an external client.
If you need old state in the contract, then it is the best to store a copy by the contract so that you can make use of this in your logic.

Nevertheless you can do a smart query from your client to an archive node for historic data with a --height parameter. See wasmd query wasm contract-state smart -h

It would help if you can elaborate a bit more on your concrete use case. I don't fully understand the motivation for the re-indexing as the contract state should be unrelated to an upgrade.

There is no support to query historic data for the contract, only for an external client. If you need old state in the contract, then it is the best to store a copy by the contract so that you can make use of this in your logic.

Nevertheless you can do a smart query from your client to an archive node for historic data with a --height parameter. See wasmd query wasm contract-state smart -h

It would help if you can elaborate a bit more on your concrete use case. I don't fully understand the motivation for the re-indexing as the contract state should be unrelated to an upgrade.

It was a problem when I used wasmd query wasm contract-state smart -h

For example, let's say a chain upgrades from v1 to v2. If I query the height state of v1 from the latest node, which is v2, I will get an error saying that the iavl version does not match. So, take a snapshot of the last height of v1 and run the v1 version of the node. However, in a NewEnv, a panic occurs because there is no block header information in the context. It looks assigned only at commit time(block sync or block produce). So, it cannot be brought to this state in the last block of previous versions.

Thank you for the additional information. I am not sure if I fully got it but I will try to answer.
You should be able to execute the smart query with the --height=<v1> param (on a node with height>v1) so that the smart contract query is executed with the store state at height v1. This is built into the SDK. It can fail though if the server has pruning activated (default) and moved ahead so that this state was deleted. Some chains provide an "Archive" node for this use case that has pruning disabled.
A smart query on uncommitted state could lead to a dirty read.
Can you elaborate on the "why" you need to do this? Maybe there are other options

@JoowonYun You referenced an IAVL query issue. Is your chain by chance on SDK v0.45.12+? If so you need to use an SDK fork to fix that.

See my releases here to fix that:

(This is patched in SDK v47+ chains, but broken in mainline v0.45.12+ forever)

Thank you for the additional information. I am not sure if I fully got it but I will try to answer. You should be able to execute the smart query with the --height=<v1> param (on a node with height>v1) so that the smart contract query is executed with the store state at height v1. This is built into the SDK. It can fail though if the server has pruning activated (default) and moved ahead so that this state was deleted. Some chains provide an "Archive" node for this use case that has pruning disabled. A smart query on uncommitted state could lead to a dirty read. Can you elaborate on the "why" you need to do this? Maybe there are other options

@alpe Thank you for quick response.

Of course, I am using archive node.

First, I have a question about your answer. What you mean is that when querying the state of v1's height from v2's node, it should work normally? The types will be different because the binaries are different, so I have doubts about whether this is possible.

Second, I explain a little more about why commits are necessary.
In my case, let's assume that v2 is running on the network, and that the v1 archive node has been run to re-index v1's data. When a smart query in the node, a panic occurs at the point. The reason this part of the panic occurs is because there is no Blocktime data in the Blockheader in the current context. This means that in its current status, all SmartQuery will panics. To avoid this, I looked for the point at when BlockHeader is assigned, and it was Commit point.

@JoowonYun You referenced an IAVL query issue. Is your chain by chance on SDK v0.45.12+? If so you need to use an SDK fork to fix that.

See my releases here to fix that:

(This is patched in SDK v47+ chains, but broken in mainline v0.45.12+ forever)

@Reecepbcups I checked that the state of the previous version can be successfully queried using the current version.
Thanks a lot.