-
Notifications
You must be signed in to change notification settings - Fork 12
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
Define Consumer Contracts #33
Conversation
c0ec886
to
14c29ae
Compare
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.
Some comments for current state.
|
||
fn handle_epoch( | ||
&self, | ||
deps: DepsMut<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.
Ouch, I am not sure if it is properly supported in Sylvia to use custom queries, it was postponed. I will double-check, and if not, we will push for delivering it asap.
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 looked and the following are all not supported:
- CustomQueries (Deps)
- Exposing sudo in multitests (and maybe making another Sylvia method like reply to enable that)
I tried returning custom messages in instantiate and it works (at least the compiler didn't complain once I updated the lib.rs bindings... good to check this works with the auto-generated entry points)
For Custom Queries, note it could vary between T and Empty between calls, but not T and U. I guess all execute variants need the same, as well as all query variants, but eg instantiate may be DepsMut while execute is DepsMut
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.
Good thing is sudo is outside of Sylvia so I can get this to compile and run for system level tests (uploading to a chain), even if I can't for multitest yet
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.
NB: I rebased on your vault branch to check new Sylvia and it errors on returning Response<CustomMsg>
from instantiate. (something about anyhow::Error
so I assume mt
related. One more thing to check then
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.
Created CosmWasm/sylvia#139 and CosmWasm/sylvia#140
CosmWasm/sylvia#16 is the oldest open issue... time to knock it out.
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.
Yea, both custom queries and custom messages are not supported. We will prioritize those.
Sudo is easy thing to do, for now we can do it in reply-wise and deprecate it when we properly implement them.
For Custom Queries, note it could vary between T and Empty between calls, but not T and U. I guess all execute variants need the same, as well as all query variants, but eg instantiate may be DepsMut while execute is DepsMut
I am aware, however it might happen we will enforce using T
through entire contract due to practical reasons (it should not be a problem - Querier<T>
can do everythin Querier<Empty>
can do). Simillarly as with error type (you use ContractError even if StdError would be sufficient).
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.
Not 100% sure how to approach it. This is too big PR to leave it not merged, but queries/responses would be in Sylvia this/next week (Jan is working on that right now). Sudo messages I can do in one day (not the way replies go, I have another approach for that which will stay relevant). On the other way, I assume it won't work properly so it is merging invalid code probably.
My take: change the reply to "default" for now, and where you query it just create a dummy default response, leaving todo: "Properly query when CosmWasm/sylvia#16 is merged". Then create issue on GH to fix it (to not forget).
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.
Ahh, ignore it - it is used only in sudo. So you just use sudo this way which is working for now, except not testable at this point. But we will deliver it soon and then change. Good (for now).
config: Item<'a, Config>, | ||
// Amount of tokens that have been requested to bond to a validator | ||
// (Sum of bond minus unbond requests). This will only update actual bond on epoch changes. | ||
bond_requests: Map<'a, &'a str, Uint128>, |
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 key should probably be an &Addr
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.
The key is a validator address (specifically valoper
), which due to some weird architectural decision of the SDK uses a different bech32 prefix than the normal accounts, although it actually works the same way 🤷♂️
We have to treat as String without validating.
let requests: Vec<(String, Uint128)> = self | ||
.bond_requests | ||
.range(deps.storage, None, None, cosmwasm_std::Order::Ascending) | ||
.collect::<Result<_, _>>()?; | ||
let total_request: Uint128 = requests.iter().map(|(_, v)| v).sum(); | ||
if total_request > bond.cap.amount { | ||
// TODO: normalize the list of requests to match the cap | ||
todo!(); | ||
} | ||
|
||
// TODO: Look at existing list and calculate differences for bond/unbond calls | ||
|
||
// Save the new values | ||
self.bonded.save(deps.storage, &requests)?; |
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.
Collecting all the requests, then summing them, then ignoring those out of range, and store after transformation seems waaaay off to me. I assume that normalizing requests is done to prevent wasting gas on transforming all the requests, but probably more gas is wasted by collecting all the requests, and always fetching/storing all the bonded items.
The algorithm should probably go ass follows:
The requests should never be collected, instead they should be transformed fold-like keeping the transformed items, and total request (both as Iterator::scan
items). The reason for using scan
instead of fold is, that fold
is eager, and scan
is lazy - after scan we can use take_while
, to stop transforming after the cap is reached.
I would go even deeper, and in the scan
I would just return an iterator over (request, total)
, then take_wile
to break when total
reaches cap
, then map
to transform items and update them immediately in bonded (which should be Map
for that.
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.
Happy for better design, but let me finish this, then improve. I need to:
- Get all bond requests
- Sum the total amount
- If the sum <= max_cap then use collected requests as is
- If the sum > max_cap,
a. calculate multiplier Decimal(max_cap / sum)
b. multiply every element of the collected requests in place. - Find diff between collected (normalized) requests and last bonding amounts (which go up, which down).
- Transform diff into unbond and bond requests, sorting so all unbond happen first
The largest optimization I can see is collecting (in 1) into a {Hash,BTree}Map as we will likely need that later.
We don't cut off at the cap, we multiply everyone down. We need to get it all.
The storage load is the most expensive. Highest V is 100-150, so even O(N^2) in memory, which I would like to avoid, may be cheaper than the storage reads
4b1f611
to
33e5cb7
Compare
The basic code is laid out. There are no tests. Simple Price Feed is simple enough to be tested, and a good place to learn how, but not really needed. However, this is a first step to getting something that @alpe could use in system tests (as the generated wasm should work) |
8ff516c
to
25b07cb
Compare
@hashedone I rebased on vault merge, can you review this (ideally run The only issue I have is a build warning. Code: use mesh_apis::local_staking_api::{self, LocalStakingApi, MaxSlashResponse};
#[contract]
#[messages(local_staking_api as LocalStakingApi)]
impl LocalStakingApi for NativeStakingContract<'_> {
// ...
} Error:
I guess the |
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.
Couple comments.
First of all - entry points can be generated with a single line from Sylvia - who commented on it twice, but there are more contracts and that apply to all of them.
The warning about unused modules is surprising, but it is not because #[messages(...)]
is not used - it is always used, but when mt
utils are not generated (so no mt
flag enabled on Sylvia), the macro does not use the provided path. Don't remove the #[messages(...)]
attribute; it will cause more problems in the future. For now, the best I can think of is adding #[allow(unused_imports)]
just before the import block which causes this one. We will fix this warning in Sylvia by artificially using the module even when not generating things using it.
I am leaving the approval as I don't see any serious problem so you can merge when you fix or ignore comments.
|
||
fn handle_epoch( | ||
&self, | ||
deps: DepsMut<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.
Not 100% sure how to approach it. This is too big PR to leave it not merged, but queries/responses would be in Sylvia this/next week (Jan is working on that right now). Sudo messages I can do in one day (not the way replies go, I have another approach for that which will stay relevant). On the other way, I assume it won't work properly so it is merging invalid code probably.
My take: change the reply to "default" for now, and where you query it just create a dummy default response, leaving todo: "Properly query when CosmWasm/sylvia#16 is merged". Then create issue on GH to fix it (to not forget).
|
||
fn handle_epoch( | ||
&self, | ||
deps: DepsMut<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.
Ahh, ignore it - it is used only in sudo. So you just use sudo this way which is working for now, except not testable at this point. But we will deliver it soon and then change. Good (for now).
25b07cb
to
53ac9e6
Compare
Made requested fixes and rebased on main. |
This will start some contract code from the consumer side. The intention is to clarify some interfaces in the documentation by means of sample code. But also, to work towards a minimal working virtual staking contract that can be used for system-level integrations with the virtual staking SDK module.