feat: CosmWasm modules
summary
Allow a contract to be uploaded through governance access to begin & end blockers.
logic flow
- user uploads contract via a gov prop
- on pass, add address to a list of cw-modules
- every begin/end blocker, call said entrypoint within be contract. Only this module (cwmodule authority addr) can call it. (Standard execute? or somehow call directly with bindings for every contract. Look into 008-WASM light client)
considerations
- Limit the execution gas per contract within reason (ex: 500bn) to ensure no infinite loops occur (may not be needed)
- Fork of wasmd for a new entrypoint? begin_block, end_block
- Upload has a human name linked to address? (ex: croncatsv1 -> juno1contractaddr)
- Remove a contract (GOV & maybe other addresses, such as a security DAO)
- The contract may need endpoints for this logic to be set (It’s not really an entry point though, maybe can just be a matched func signature to call)
hacky (but simple) solution
- Contract adds a JunoEndBlocker SudoMsg.
- every end blocker, execute on contracts
- ensures this contract also works on other CW networks without custom bindings
future v2
- More access to underlying keepers (ex: mint, staking). Usecase: Mesh security QOL contract which instant unstakes and mints new tokens in the contract
issues
- if major featured contracts are added, this needs to be easy to setup in interchaintest / local-interchain
- migrateable? (admin, no admin?) require gov migrate?
Nice! Kind of like the way twasm does it with the concept of privileges.
There are two new messages able to be called by governance:
- PromoteToPrivilegedContractProposal: allows a contract to register special privileges.
- DemotePrivilegedContractProposal: removes a contract from special privileges.
Example usage in a contract: https://github.com/confio/poe-contracts/blob/main/contracts/tgrade-validator-voting/src/contract.rs#L260-L283
The nice thing about this approach is that it can easily be extended for functionality beyond BeginBlocker and EndBlocker. Here is the full list of privileges supported by twasm.
See the tg-bindings package for more inspiration: https://github.com/confio/poe-contracts/blob/main/packages/bindings/src/msg.rs
Most twasm logic lives in the privileges keeper: https://github.com/confio/tgrade/blob/main/x/twasm/keeper/privileged.go#L21C1-L21C1
Another nice thing about this approach is that the contract can be uploaded prior to the gov prop, as well as being able to do additional setup (or cleanup) upon being given privileges or having them removed.
Really think we should give twasm a good review as there is a lot of great prior art in there. Would be a great thing to upstream at some point too. Moreover, the design is robust enough to support more complex CW modules. Even if we don't support everything initially, would be good to have a pattern that can support more complexity in the future.
Here's another great example of a Tgrade smart contract utilizing BeginBlocker: https://github.com/confio/poe-contracts/blob/b7a8dbafd89cd70401dced518366f520b7089ff6/contracts/tgrade-valset/src/contract.rs#L679
Gas limits is a good call.