devex: area of improvements
Closed this issue · 4 comments
This keeps track of pain points in development of go-cosmwasm contracts.
-
- HandleMsg switch case - annoying keeping it up to date as messages that can be handled grow and change
-
- Query API needs to be improved as it requires a lot of machinery
-
- Avoid marshal/unmarshal as much as possible in code as it adds too much noise. We know we need marshal/unmarshal only when dealing with state and handling messages and eventually the aim should be to completely remove the codec layer from the contract logic.
Regarding 2.:
- smart contract query requires two rounds of marshalling:
if err != nil {
return nil, err
}
req := types.QueryRequest{
Wasm: &types.WasmQuery{
Smart: &types.SmartQuery{
ContractAddr: env.Contract.Address,
Msg: recurseBytes,
},
},
}
reqBytes, err := req.MarshalJSON()
if err != nil {
return nil, err
}
return deps.Querier.RawQuery(reqBytes)
Ideally we want the consumer just to signal the intention to query a smart contract and pass addr and message structure (not bytes)
Regarding 2 again:
I think we could eventually merge the API for module querying and smart contract querying.
Ex:
return &QueryRequest{ContractAddr: "cw20-contract", Msg: cw20.QueryBalance{}}
return &QueryRequest{ContractAddr: bank.ModuleAddress, Msg: bank.GetBalance{}}
They are fundamentally different types. We pretty much need to keep those same wire types to be compatible with both rust contract as well as the wasmd runtime.
What we can do (and did in rust) is add helpers. eg.
var req types.QueryRequest = types.SmartQuery{
ContractAddr: env.Contract.Address,
Msg: recurseBytes,
}.ToQuery()
or
```go
// here we require recurseMsg implements easyjson.Marshal and then serialise inside the function.
res, err := deps.Querier.SmartQuery(env.Contract.Address, recurseMsg)
point is we can hide all the complexity of building the wire types from the user.
See eg. https://github.com/CosmWasm/cosmwasm/blob/main/packages/std/src/traits.rs#L190-L283
HandleMsg switch case - annoying keeping it up to date as messages that can be handled grow and change
This is a hard one and generally an issue when using "enums" / "union types" in go. The compiler has no way to know the total set of possible types, so we always end up with default case to return error