feat: support contract upgrades in batches#3361
Conversation
|
@claude review |
|
@claude review |
Pull request overviewAdds a chunked-upload flow ( Changes:
Reviewed changesPer-file summary
FindingsBlocking (must fix before merge):
Non-blocking (nits, follow-ups, suggestions):
|
netrome
left a comment
There was a problem hiding this comment.
Mostly looks good to me. Nothing strictly blocking, but a few things I would like to change:
- I'd like to rename the existing
propose_updatemethod topropose_config_updateas it no longer is used for anything else than config updates. This should be fine since it's a method we call. - I don't see the point of emitting logs in the new methods. I suggest skipping it (YAGNI).
- There are some
asconversion. You know my preference on these.
There was a problem hiding this comment.
Thank you very much! Looks like it should work!
I have a few small blockers:
- contract size check (the bump seems no longer needed)
- the contract state migration assumes 3.10 (needs to be fixed by another PR)
- the lack of update_gas constants, which serve as an upper bound in tests.
I am also a bit concerned about the deposit logic, which does not seem trivial. Would be good to get that sorted out
I hoped we could do this change so that we could revert back to a single chunk easily when we get our contract size down, but the current implementation does not seem trivial to revert.
There was a problem hiding this comment.
small blocker: This file cannot be modified until #3473 lands
| uploader | ||
| .call(contract.id(), method_names::START_CONTRACT_UPLOAD) | ||
| .args_borsh(StartContractUploadArgs { | ||
| total_size: std::num::NonZeroU64::new(chunk.len() as u64).unwrap(), | ||
| }) | ||
| .max_gas() | ||
| .deposit(NearToken::from_yoctonear(1)) | ||
| .transact() | ||
| .await? | ||
| .into_result() | ||
| .map_err(|e| anyhow::anyhow!("start_contract_upload failed: {e}"))?; |
There was a problem hiding this comment.
we should probably measure and set a gas constant here instead of max_gas
| // This vote crosses the threshold and triggers deploy_contract + migrate | ||
| // on a multi-MiB binary; use max_gas so chunk reassembly + deploy fit. | ||
| let execution = mpc_signer_accounts[1] | ||
| .call(contract.id(), method_names::VOTE_UPDATE) | ||
| .args_json(serde_json::json!({ | ||
| "id": proposal_b, | ||
| })) | ||
| .gas(GAS_FOR_VOTE_UPDATE) | ||
| .max_gas() |
There was a problem hiding this comment.
as I said in some comments above, we should still track how much gas is that, by keeping the constant
| .await; | ||
|
|
||
| let code = current_contract(); | ||
| assert!(code.len() > 1024, "contract binary should be non-trivial"); |
There was a problem hiding this comment.
this is a strange restriction. Why would the test care about that?
|
|
||
| for (account, num_chunks, deposited) in orphaned { | ||
| for i in 0..num_chunks { | ||
| self.staged_chunks.remove(&(account.clone(), i)); | ||
| } | ||
| self.staged_uploads.remove(&account); | ||
| if deposited > NearToken::from_yoctonear(0) { | ||
| Promise::new(account).transfer(deposited).detach(); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
how are we ensuring that this does not consume more gas than we are paying for it?
| /// Cleans update votes from non-participants after resharing. | ||
| /// Can be called by any participant or triggered automatically via promise. | ||
| #[handle_result] | ||
| pub fn remove_non_participant_update_votes(&mut self) -> Result<(), Error> { | ||
| log!( | ||
| "remove_non_participant_update_votes: signer={}", | ||
| env::signer_account_id() | ||
| ); |
There was a problem hiding this comment.
isn't this comment a bit misleading? It mentions online participants can call it, but it seems anyone can actually call it
closes #2987