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

Expose contract pinning #401

Closed
ethanfrey opened this issue Jan 29, 2021 · 3 comments · Fixed by #436
Closed

Expose contract pinning #401

ethanfrey opened this issue Jan 29, 2021 · 3 comments · Fixed by #436
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@ethanfrey
Copy link
Member

In current CosmWasm master, wasmvm 0.14-dev, they expose an API to pin/unpin contracts by Checksum. If a contract is pinned, it is guaranteed to be in memory cache and we can reduce the instantiation cost significantly:

  • Expose keeper API to pin/unpin contracts
  • Store pinned contracts in KVStore and re-pin on restart (can we just lazily pin everytime we run them, assuming that this is near zero cost if they are already pinned?)
  • Lower fix gas cost of calling a pinned contract from 40k to 1k (much faster on all machines)
  • Write some benchmarks that show calling pinned contracts is much faster (ensuring we are using APIs correctly). They can be Keeper level, and we can set the LRU cache size to 0 to ensure no other caching is going on.
@ethanfrey ethanfrey added this to the v0.16.0 milestone Jan 29, 2021
@alpe alpe added the enhancement New feature or request label Jan 29, 2021
@ethanfrey
Copy link
Member Author

ethanfrey commented Mar 4, 2021

Some thoughts:

  • We need to store a table to lookup contractAddr -> pinned (only set on true)
  • Add 2 governance messages to pin and unpin contract
  • Expose the Pin/Unpin functions on the WasmerEngine interface, and make them no-ops in the MockWasmerEngine implementation
  • On gov:pin, we just write to the kvstore. On gov:unpin, we remove from kvstore and call unpin on wasmer
  • Everytime we load a contract (where we charge the InstanceCost), we should do more or less the following.
if (contractPinned(ctx, contractAddr)) {
  k.wasmEngine.Pin(codeHash)
} else {
  gasMeter.charge(INSTANCE_COST)
}

Pinned contracts can have 0 instantation cost (the query to see if they are pinned will give 1k gas base fee). Pinning an already pinned contract is a rather cheap no-op on cosmwasm side

This is not the most optimized design, but simple enough and robust against restarts

@alpe alpe self-assigned this Mar 4, 2021
@alpe
Copy link
Contributor

alpe commented Mar 4, 2021

This approach makes sense and will work.
I was following some design from the capability module and would suggest some improvements (maybe as a new iteration).
My assumption is that we do not change the pinned set very often.

  • The "lookup" table is also copied into a memory store
  • On startup we load the "lookup" table from the persistent store and seed the cache and memory store with pinned contracts. A bonus can be code/contract meta data stored in the memory store

@ethanfrey
Copy link
Member Author

That is a good assumption and if you can do something on "startup", then that would be a great improvement. I wasn't sure it that was possible.

Also, if this is memory store, we must be sure not to write during simulated tx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants