-
Notifications
You must be signed in to change notification settings - Fork 17
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
chore: additional changes to propose_update #729
Conversation
82fd209
to
2bd66dd
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.
@@ -0,0 +1,18 @@ | |||
use near_sdk::{env, near, PanicOnDefault}; | |||
|
|||
// use crate::FailureContractExt; |
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.
dead code
let execution = contract | ||
.call("propose_update") | ||
.args_json(serde_json::json!({ | ||
"contract": vec![1, 2, 3], | ||
"code": vec![1, 2, 3], |
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 test is called test_propose_update_config
but we are proposing a new code.
|
||
dbg!(&execution); | ||
let state: mpc_contract::ProtocolContractState = execution.json().unwrap(); | ||
dbg!(state); |
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.
Do we need to check the execution status here?
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.
nope, json().unwrap()
does it
// Try calling into state and see if it works after the contract updates with an invalid | ||
// contract. It will fail in `migrate` so a state rollback on the contract code should have | ||
// happened. | ||
let execution = accounts[0] |
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.
IMO the end goal in tests for update logic should be:
- To make sure that the user-facing API was not changed, make a sign, pk, and other calls. It should prevent us from accidentally breaking the API
- To make sure that the upgrade logic is still functioning after the update. It will allow us to fix it with new updates no matter what. The flow can be: deploy the contract, upgrade it, and upgrade it again to see if the upgrade logic is functioning.
// contract. It will fail in `migrate` so a state rollback on the contract code should have | ||
// happened. | ||
let execution = accounts[0] | ||
.call(contract.id(), "state") |
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 function does not exist on that contract. Is this intentional?
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.
because of the state rollback, the FailureContract
does not get deployed, so we end up back at our original contract which has the state
function
else { | ||
return Err(MpcContractError::VoteError(VoteError::UpdateNotFound)); | ||
let Some(_promise) = self.proposed_updates().do_update(&id, UPDATE_CONFIG_GAS) else { | ||
return Err(MpcContractError::from(VoteError::UpdateNotFound)); | ||
}; | ||
|
||
Ok(true) |
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.
theoretically do_update
can fail, but maybe convenient bool
result is more important
#[private] | ||
#[init(ignore_state)] | ||
#[handle_result] | ||
pub fn migrate() -> Result<Self, MpcContractError> { |
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.
We must keep the last deployed version somewhere to ensure migrations are successful.
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.
yeah, I think we should have a list of structs when we're making these breaking changes. We're supposed to be using the versioned contracts for this, but it hasn't been necessary since we haven't released yet
@@ -772,12 +794,27 @@ impl VersionedMpcContract { | |||
} | |||
} | |||
|
|||
fn threshold(&self) -> Result<usize, VoteError> { |
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.
VoteError looks strange here :/ We may need to reorg the error structure
votes: HashMap<UpdateId, HashSet<AccountId>>, | ||
next_id: u64, | ||
entries: HashMap<UpdateId, UpdateEntry>, | ||
id: UpdateId, |
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.
Isn't next_id a better name?
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.
It's just an id generator. Calling it next_id meant that it could be sequential when it just generates you an arbitrary id
Update::Contract(code) => promise = promise.deploy_contract(code), | ||
Update::Contract(code) => { | ||
// deploy contract then do a `migrate` call to migrate state. | ||
promise = promise.deploy_contract(code).function_call( |
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.
Does this work as a batched transaction? Will deployment fail if the function call fails?
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.
yeah, this ends up being a batch call where calling into migrate
will roll back the whole entire promise with the deployed contract
Terraform Feature Environment Destroy (dev-729)Terraform Initialization ⚙️
|
Follow up to #714
propose_update
where the uploaded config or contract bytes is used to determine how much. This amount currently cannot be withdrawn, so it'll be trapped there until we make more changes to the contract. For us, this just means that there's a cost of about 8N per contract update to mainnet and not more than 0.1N for config updatesProposedUpdates
now just uses one hashmap to save us the hassle of fetching both the votes and updates at the same timemigrate
function will be invoked after a deploy contractmigrate
function which effectively rolls back to the previous state. In this case the update fails and is evicted from being voted upon again