-
Notifications
You must be signed in to change notification settings - Fork 9
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
Sylvia upgrade #188
Sylvia upgrade #188
Conversation
// FIXME not sure how to get this to compile with latest sylvia | ||
// get the price value (usage is a bit clunky, need to use trait and cannot chain Remote::new() with .querier()) | ||
// also see https://github.com/CosmWasm/sylvia/issues/181 to just store Remote in state | ||
use price_feed_api::Querier; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hashedone not sure what's changed here, but this part is very broken. Struggling to find examples for this Querier
/ Remote
stuff...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since 0.9.0
Sylvia
generates all the code in the sv
module. We decided not to populate the scope with all the stuff it generates and rather keep it in this module.
Currently both interface
and contract
generates the code like this.
pub mod sv {
// messages
// qoc code
pub mod mt {
}
}
So for your code you have to:
+ use price_feed_api::sv::Querier;
- use price_feed_api::Querier;
You can read about the changes regarding 0.10.0
in the release article https://medium.com/confio/sylvia-1-0-0-45094b6ad8ba
And about the 0.9.0
in https://medium.com/confio/sylvia-0-9-0-78f50984a75f
I noticed that the https://github.com/CosmWasm/sylvia/blob/main/MIGRATING.md is not fully updated with the changes. I will update it today. Sorry for inconvenience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that the https://github.com/CosmWasm/sylvia/blob/main/MIGRATING.md is not fully updated with the changes. I will update it today. Sorry for inconvenience.
This would be super helpful.
How do I derive the Remote
? Read the issue here and not sure what to make of it: CosmWasm/sylvia#181
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both Remote
and BoundQuerier
were moved to the sylvia::types
module as they were always generated in the same way.
Here is example usage of Remote
/Querier
. If you find them insufficient and/or have some suggestions what is missing we will appreciate the feedback.
https://github.com/CosmWasm/sylvia/blob/main/sylvia/tests/querier.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those missing derives
were implemented in CosmWasm/sylvia#194 and are still present.
https://docs.rs/sylvia/0.10.1/sylvia/types/struct.Remote.html
Which traits are missing for your use case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jawoznia I'm coding again on mesh and jumping in this PR.
I made the above changes, but then need a concrete type for remote (when I really just want to pass in an interface). This fixes some of the changes you said:
use price_feed_api::sv::Querier;
use sylvia::types::Remote;
let remote = Remote::new(config.price_feed);
let price = remote.querier(&deps.querier).price()?.native_per_foreign;
I get the following two errors:
error[E0282]: type annotations needed for `Remote<'_, Contract>`
--> contracts/consumer/converter/src/contract.rs:280:13
|
280 | let remote = Remote::new(config.price_feed);
| ^^^^^^ ------------------------------ type must be known at this point
|
help: consider giving `remote` an explicit type, where the type for type parameter `Contract` is specified
|
280 | let remote: Remote<'_, Contract> = Remote::new(config.price_feed);
| ++++++++++++++++++++++
Problem here is it wants a concrete contract type, and made an error when I tried to pass in Remote::<PriceFeedApi>
. One of the main poitns of the APIs was to be able to call them without knowing the implementation. Is there an example how to use remote to call an API not a concrete contract?
error[E0283]: type annotations needed
--> contracts/consumer/converter/src/contract.rs:281:51
|
281 | let price = remote.querier(&deps.querier).price()?.native_per_foreign;
| ^^^^^
|
= note: multiple `impl`s satisfying `BoundQuerier<'_, cosmwasm_std::Empty, _>: mesh_apis::price_feed_api::sv::Querier` found in the `mesh_apis` crate:
- impl<'a, C, Contract> mesh_apis::price_feed_api::sv::Querier for BoundQuerier<'a, C, Contract>
where C: cosmwasm_std::CustomQuery, Contract: PriceFeedApi;
- impl<'a, C, Error> mesh_apis::price_feed_api::sv::Querier for BoundQuerier<'a, C, &dyn PriceFeedApi<Error = Error>>
where C: cosmwasm_std::CustomQuery;
help: try using a fully qualified path to specify the expected types
|
281 | let price = <BoundQuerier<'_, cosmwasm_std::Empty, Contract> as mesh_apis::price_feed_api::sv::Querier>::price(&remote.querier(&deps.querier))?.native_per_foreign;
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Okay, it is a little uglier to pass the querier as an argument to price, but no big deal there. The bigger issue is do I really need to make that complex type BoundQuerier<'_, cosmwasm_std::Empty, Contract> as mesh_apis::price_feed_api::sv::Querier>
in my code? Surely there is a shorter way.
(Looking at your example it does seem we need the verbose way, but there are some shortcuts there for types)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, please look at 71dffdf and let me know if that was the proper way to deal with it. I feel I am just forcing the type system rather then understanding anything
*/ | ||
fn handle_epoch( | ||
&self, | ||
ctx: SudoCtx<VirtualStakeCustomQuery>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two sudo methods (handle_epoch
and valset_update
) require custom queries and messages. Any guidance or suggestions on how to handle this would be greatly appreciated. 🙏
Examples or commits would be 🍰 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked the branch and found out that some Ctx
types miss the <VirtualStakeCustomQuery>
parameter and same for CustomMsg
for Response
.
From Rust POV Response<Empty>
and Response<VirtualStakeCustomMsg>
are different types and you have to make all the methods in the dispatch flow use the same types.
struct SetupResponse<'a> { | ||
price_feed: | ||
mesh_simple_price_feed::contract::multitest_utils::SimplePriceFeedContractProxy<'a, MtApp>, | ||
converter: mesh_converter::contract::multitest_utils::ConverterContractProxy<'a, MtApp>, | ||
virtual_staking: contract::multitest_utils::VirtualStakingContractProxy<'a, MtApp>, | ||
price_feed: mesh_simple_price_feed::contract::sv::mt::SimplePriceFeedContractProxy<'a, MtApp>, | ||
converter: mesh_converter::contract::sv::mt::ConverterContractProxy<'a, MtApp>, | ||
virtual_staking: contract::sv::mt::VirtualStakingContractProxy<'a, MtApp>, | ||
} | ||
|
||
fn setup<'a>(app: &'a App<MtApp>, args: SetupArgs<'a>) -> SetupResponse<'a> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm having a hard time with these setup functions... and not just in this file. It's generic and trait hell.
Getting tones of errors like this:
error[E0107]: trait takes 9 generic arguments but 1 generic argument was supplied
--> contracts/provider/native-staking-proxy/src/multitest.rs:59:16
|
59 | ) -> AnyResult<VaultContractProxy<'app, MtApp>> {
| ^^^^^^^^^^^^^^^^^^ ----- supplied 1 generic argument
| |
| expected 9 generic arguments
|
note: trait defined here, with 9 generic parameters: `BankT`, `ApiT`, `StorageT`, `CustomT`, `WasmT`, `StakingT`, `DistrT`, `IbcT`, `GovT`
--> /Users/meow/Dev/Mesh/mesh-security/contracts/provider/vault/src/contract.rs:69:6
|
66 | #[contract]
| -----------
...
69 | impl VaultContract<'_> {
| ^^^^^^^^^^^^^
help: add missing generic arguments
|
59 | ) -> AnyResult<VaultContractProxy<'app, MtApp, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT>> {
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
error[E0782]: trait objects must include the `dyn` keyword
--> contracts/provider/native-staking-proxy/src/multitest.rs:59:16
|
59 | ) -> AnyResult<VaultContractProxy<'app, MtApp>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: add `dyn` keyword before this trait
|
59 | ) -> AnyResult<dyn VaultContractProxy<'app, MtApp>> {
| +++
Too tired to figure it out right now, but any help would be appreciated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expected 9 generic arguments
🥲
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proxy
trait generated by Sylvia
is generic over cw_multi_test
modules while it would be much more user friendly to be generic over cw_multi_test::App
.
I see the missing use case in our tests. I will inspect possibility to make it generic over the cw_multi_test::App
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now to make it work you can provide the types used in the cw_multi_test::App
that I see you are trying to use here
https://github.com/CosmWasm/cw-multi-test/blob/main/src/app.rs#L51
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even better. You are returning here the trait. Change it to https://docs.rs/sylvia/0.10.1/sylvia/multitest/struct.Proxy.html.
You will be able to provide the MtApp
here as first parameter and your contract as a second generic parameter.
#[error(ContractError)] | ||
#[messages(converter_api as ConverterApi)] | ||
#[sv::error(ContractError)] | ||
#[sv::messages(converter_api as ConverterApi)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since 0.10.0
below is possible since we can deduce the interface name by converting the path to camel case
#[sv::messages(converter_api as ConverterApi)] | |
#[sv::messages(converter_api)] |
@@ -69,7 +71,7 @@ impl VirtualStakingContract<'_> { | |||
} | |||
|
|||
/// The caller of the instantiation will be the converter contract | |||
#[msg(instantiate)] | |||
#[sv::msg(instantiate)] | |||
pub fn instantiate(&self, ctx: InstantiateCtx) -> Result<Response, ContractError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the contract is now using some custom message and query you have to use them in the methods signatures. Otherwise you get this errors with conversion from DepsMut<'_, Empty>
to DepsMut<'_, VirtualStakeCustomQuery>
pub fn instantiate(&self, ctx: InstantiateCtx) -> Result<Response, ContractError> { | |
pub fn instantiate(&self, ctx: InstantiateCtx<VirtualStakeCustomQuery>) -> Result<Response<VirtualStakeCustomMsg>, ContractError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check 528c6e1 with the update of consumer/converter
. Tests are building and passing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the help @jawoznia
Left a few comments and one big question
mesh_simple_price_feed::contract::multitest_utils::SimplePriceFeedContractProxy<'a, MtApp>, | ||
converter: contract::multitest_utils::ConverterContractProxy<'a, MtApp>, | ||
virtual_staking: virtual_staking_mock::multitest_utils::VirtualStakingMockProxy<'a, MtApp>, | ||
price_feed: Proxy<'a, MtApp, SimplePriceFeedContract<'a>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, this is a lot of non-intuitive changes, but happy to use this as an example to fix others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is because we moved out of generating Proxy
type per contract
macro.
Instead we have a sylvia::multitest::Proxy
type that is generic over MtApp
on which the SimplePriceFeedContract
is deployed. So the idea was to link via proxy some contract to the chain.
mesh_simple_price_feed::contract::multitest_utils::CodeId::store_code(app); | ||
let virtual_staking_code = virtual_staking_mock::multitest_utils::CodeId::store_code(app); | ||
let converter_code = contract::multitest_utils::CodeId::store_code(app); | ||
let price_feed_code = PriceFeedCodeId::store_code(app); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usage actually looks simpler
use sylvia::types::Remote; | ||
// NOTE: Jan, this feels hacky... I'm not sure if this is the right way to do it | ||
// Also, I am sticking in a random error type here, not what I will get (which is unknown) | ||
let remote = Remote::<&dyn price_feed_api::PriceFeedApi<Error=StdError>>::new(config.price_feed); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this line correct? I feel I am faking the Remote generic type so it compiles... is this the right way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is correct, as sylvia::types::Remote
being representation of some external Contract is generic over it.
Unfortunately Rust requires us to state the associated types defined on the PriceFeedApi
trait which is not ideal, but we went with it as this way we were able to simplify support for generics and overall make the API less clunky (not without sacrifices as we can see).
In current state and in this usage you are using the Remote
to instantiate BoundQuerier
and query on contract.
It's fine to set Error
as StdError
as underneath it calls query_wasm_smart
which returns the StdResult
so although it looks hacky it's all fine.
The problem however is with storing Remote
as a field, which we didn't cover for the Remote
generic over some type implementing the interface and we have to fix it.
@jawoznia I managed to fix a lot with your example. All code and tests compile properly - expect The biggest issue is
|
block.time = block.time.plus_seconds(61); | ||
block.height += 13; | ||
}); | ||
// This is deprecated as unneeded, but tests fail if it isn't here. What's up??? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jawoznia another one as possible bug in the cosmwasm frameworks...
This is marked deprecated, saying I should just call update_block. But if I comment these lines out the tests fail.
I even tried to update the block with some huge diff (610.000.000 seconds) and it doesn't trigger the process queue.
Can you investigate? I know it is cw-multi-test, but still...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is not yet an issue in cw-multi-test
please consider making this an issue there. Darek should definitely check it.
Workaround to enable communication between `Empty` and `Custom` contracts in mt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks @ethanfrey and @jawoznia for helping get this updated!
Attempts to upgrade to Sylvia
v0.10
, following roughly what's in this article: https://medium.com/confio/sylvia-1-0-0-45094b6ad8baThe rational for
v0.10
over1.0
is that the Starship testing infra chains don't yet support CW2.0
I believe.Doesn't fully work yet... would appreciate some help.
Builds off of #187, but separate for easier review.