CosmWasm / wasmd

Basic cosmos-sdk app with web assembly smart contracts
Other
369 stars 402 forks source link

Query code by checksum #1145

Open webmaster128 opened 1 year ago

webmaster128 commented 1 year ago

It would be cool to have a query like this:

  // Code gets the binary code and metadata for a singe wasm code
  rpc Code(QueryCodeRequest) returns (QueryCodeResponse) {
    option (google.api.http).get = "/cosmwasm/wasm/v1/code/{code_id}";
  }

but with the checksum as an argument.

The use case for this is as follows: I want to instantiate a contract and upload it only when it does not yet exist. If the checksum exists already, I can use the existing one.

alpe commented 1 year ago

I can see that this is useful and may save gas and storage. This would be nice as part of the contract registry but we don't have this, yet. What would you expect in the response? QueryCodeResponse contains CodeInfoResponse and wasm code?

webmaster128 commented 1 year ago

The main motivation is to get the code ID, which is what we need for instantiation. For advanced cases the instantiation config makes sense too. We don't need the Wasm blob here since it can be queried on demand if we have the metadata. In the use existing or upload case we have the Wasm blob available locally anyways. So CodeInfoResponse queried using a different index is perfect.

Now there is one slight inconvenience: checksums are not unique as the same code can be uploaded multiple times with different creators and init configs. So we have to return a list with all codes for the checksum.

unl1k3ly commented 1 year ago

I think it's valid to note that, checksum would be different based on optimiser versions. I'm not too sure how effective this change could be simple because hash diff upon wasm prods. Please, correct if I'm wrong! That's my 2cents. Cheers!

alpe commented 1 year ago

@unl1k3ly thanks, this is a fair point! Neither we would be able to catch trivial modifications

I have looked at a Juno dump (block: 6171872) and it has ~20% (or 347 in total) of duplicate wasm contract checksums uploaded. (None of the uploads stands really out. Max was 10 duplicates ) It would still be nice to avoid the obvious duplications. First step is to track them.

I can imagine more based on this like warnings in the CLI, rejecting duplicates on chain or even migrations to deduplicate. But this should be new new issues.

webmaster128 commented 1 year ago

In the early days, uploading the same Wasm twice was disallowed. Then we allowed it because the Code entry holds meta information like creator and you might want to have your own metadata here. At the wasmvm level the Wasm blobs are identified by their hash such that they are deduplicated there by default. This affects storage of the Wasm blob to disk, the compiled module as well as caches of the module.

That being said, I don't claim this would reduce Wasm storage significantly in any production environment. I just think it's nice to be able to figure out if a Wasm has been uploaded yet and which code ID to use when I want to instantiate the existing one.

ethanfrey commented 1 year ago

In the early days, uploading the same Wasm twice was disallowed.

It was allowed because 80% or more of our support issues were someone uploading cw20_base for the 10th time and complaining they got an error. They all complained it was bad UX.

In the end, we only store the wasm on the filesystem once (if it has the same hash, it is the same, so no reason to multiplex there). And it made devs happy.

There is no canonically backwards mapping, but we could just take the lowest code_id and report that consistently. It wouldn't change, and would be correct.