-
Notifications
You must be signed in to change notification settings - Fork 14
feat: announcePlannedUpgrade #260
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
Conversation
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} | ||
function announcePlannedUpgrade(PlannedUpgrade calldata plannedUpgrade) external onlyOwner { | ||
require(plannedUpgrade.nextImplementation.code.length > 3000); | ||
require(plannedUpgrade.afterEpoch > block.number); |
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 could also require a minimum delay, but in the event of an emergency we might want a shorter delay. I can add it if someone else wants it. Mainly if we discovered a problem right after a deployment a mandatory delay would become mandatory downtime.
Such a minimum delay would help facilitate security by allowing time to check, for example, that the bytecode matches the source code. It would enforce transparency by mandating a notice period for service providers, who can watch for the UpgradeAnnounced
event log.
However such a delay could also just be enforced off-chain by best-practices. This is why I don't enforce it in the code.
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.
sgtm
* @param _viewContract Address of the view contract (optional, can be address(0)) | ||
*/ | ||
function migrate(address _viewContract) public onlyProxy reinitializer(4) { | ||
require(msg.sender == address(this), Errors.OnlySelf(address(this), msg.sender)); |
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 the fix for #259
After validating that this is a good design, I can replicate it for the other proxies in separate PRs. |
} | ||
|
||
// Event declaration for testing (must match the contract's event) | ||
event ContractUpgraded(string version, address implementation); |
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 unused, and you can match the contract more easily by referring to the original, eg FilecoinWarmStorageService.ContractUpgraded
.
export EXPECTED_IMPL=$(echo $NEW_WARM_STORAGE_IMPLEMENTATION_ADDRESS | tr '[:upper:]' '[:lower:]') | ||
|
||
if [ "$NEW_IMPL" = "$EXPECTED_IMPL" ]; then | ||
echo "✅ Upgrade successful! Proxy now points to: $NEW_WARM_STORAGE_IMPLEMENTATION_ADDRESS" |
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.
output when I ran this locally:
Warning: NEW_WARM_STORAGE_VIEW_ADDRESS is not set. Keeping previous view contract.
Using owner address: 0x3B559cf662fdFe485eC216C036D4Cee91FBd1D39
Upgrade plan matches (0x9D4af62664A69db9c21eFCdf9fb43029D43A7f68)
Upgrade ready (3074256 > 3074254)
Keeping previous view contract address (0x85DB31F04dE9625b94b80bA20F1041f1A301D024)
Upgrading proxy and calling migrate...
Upgrade transaction sent: 0xbfb790ed434d1a1be7cc85fdab9cba40f00f1fbd9a4c0c10a39886cba74c70cc
Waiting for confirmation...
Verifying upgrade...
✅ Upgrade successful! Proxy now points to: 0x9D4af62664A69db9c21eFCdf9fb43029D43A7f68
echo "Error: Failed to send announcePlannedUpgrade transaction" | ||
fi | ||
|
||
echo "announcePlannedUpgrade transaction sent: $TX_HASH" |
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.
successful output log
Announcing planned upgrade after 4 epochs
Sending announcement from owner address: 0x3B559cf662fdFe485eC216C036D4Cee91FBd1D39
announcePlannedUpgrade transaction sent: 0xee4f2cb731c4102454a57356d86df2cd4bc3ab3a8c8bc229d8126fdb279fe70c
} | ||
|
||
function _authorizeUpgrade(address newImplementation) internal override onlyOwner { | ||
// zero address already checked by ERC1967Utils._setImplementation |
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 also test for this case in testUpgrade
.
(address nextImplementation, uint96 afterEpoch) = viewContract.nextUpgrade();
assertEq(nextImplementation, address(0));
assertEq(afterEpoch, uint96(0));
// Do not allow upgrade to zero address even if it's the nextImplementation
vm.expectRevert();
service.upgradeToAndCall(nextImplementation, migrateData);
Co-authored-by: Rod Vagg <[email protected]>
Co-authored-by: Rod Vagg <[email protected]>
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.
script names could be more consistent and have warm-storage
in them, but that's a weakly held opinion and I hope that problem mostly goes away with #229
weird that 351cc6e caused the size check to fail |
I reproduce this after merging with the main branch but not on the tip commit. Maybe it was testing a merged PR? I'll look for ways to cut codesize. |
Probably worth cutting codesize more than the minimum but will do it in a separate PR |
docs: add #260 to the changelog after rebase
Reviewer @rvagg Per a discussion with @jennijuju, we want to make the upgrade process more transparent. This changes upgrades to a two step process. First, we announce the planned upgrade. Then, after the designated time, we can complete the upgrade. The delay gives us time to check the pending implementation address. It also gives users notice even if we are not in communication with them. I also fix FilOzone#259 in this change, because I was already adding tests for `upgradeToAndCall`. I can fix it separately if this change is rejected. After validating that this is a good design that the team likes, I can replicate it for the other proxies in separate PRs. #### Test Plan I tested the new deployment scripts by running them on calibnet. * [announcePlannedUpgrade](https://calibration.filfox.info/en/message/bafy2bzaceb6vpcsy563vhpwig5g6jy7gb6fr2ssxhjgwiagj7k3vbjrg3dg56?t=3) * [upgradeToAndCall](https://calibration.filfox.info/en/message/bafy2bzaceadjmlemjyrv7nmwh5lzavdbntjmywvblrzmtuh3wsyldqlvxbcyo?t=3) #### Changes * announcePlannedUpgrade * update _authorizeUpgrade * new view method for pending upgrade * make gen * add and fix tests covering upgradeToAndCall with migrate * separate announce and upgrade scripts * update implementation-only script --------- Co-authored-by: Rod Vagg <[email protected]>
Reviewer @rvagg
Per a discussion with @jennijuju, we want to make the upgrade process more transparent.
This changes upgrades to a two step process.
First, we announce the planned upgrade.
Then, after the designated time, we can complete the upgrade.
The delay gives us time to check the pending implementation address. It also gives users notice even if we are not in communication with them.
I also fix #259 in this change, because I was already adding tests for
upgradeToAndCall
. I can fix it separately if this change is rejected.After validating that this is a good design that the team likes, I can replicate it for the other proxies in separate PRs.
Test Plan
I tested the new deployment scripts by running them on calibnet.
Changes