-
Notifications
You must be signed in to change notification settings - Fork 85
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
1706 improve versioning for the light client contract #1800
Merged
alysiahuggins
merged 15 commits into
main
from
1706-improve-versioning-for-the-light-client-contract
Aug 21, 2024
Merged
Changes from 9 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
910c0e8
switched to using contract inheritance for new versions of the LC con…
alysiahuggins ae91d22
Merge branch 'main' into 1706-improve-versioning-for-the-light-client…
alysiahuggins c0e2b16
Merge branch 'main' into 1706-improve-versioning-for-the-light-client…
alysiahuggins 60a6db4
Merge branch 'main' into 1706-improve-versioning-for-the-light-client…
alysiahuggins cdbe464
Merge branch 'main' into 1706-improve-versioning-for-the-light-client…
alysiahuggins 8021a52
Merge branch 'main' into 1706-improve-versioning-for-the-light-client…
alysiahuggins 35a6dd9
added initialize methods for each version and a third version of the …
alysiahuggins 4a0b8ca
added documentation about smart contract upgrades to read me and modi…
alysiahuggins d0bee37
Merge branch 'main' into 1706-improve-versioning-for-the-light-client…
alysiahuggins ec52e14
Merge branch 'main' into 1706-improve-versioning-for-the-light-client…
alysiahuggins 09f3732
adding more context to the docs with example that include the LC cont…
alysiahuggins 105e26a
add more deployment notes
alysiahuggins 50dec69
use the reinitializer modifier to safeguard against more that one re-…
alysiahuggins 7c3569c
improving comments
alysiahuggins b30b52d
Merge branch 'main' into 1706-improve-versioning-for-the-light-client…
alysiahuggins File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.0; | ||
pragma experimental ABIEncoderV2; | ||
|
||
import { Test } /*, console2*/ from "forge-std/Test.sol"; | ||
import { LightClient as LCV1 } from "../src/LightClient.sol"; | ||
import { LightClientV2 as LCV2 } from "../test/LightClientV2.sol"; | ||
import { LightClientV3 as LCV3 } from "../test/LightClientV3.sol"; | ||
import { DeployLightClientContractScript } from "../script/LightClient.s.sol"; | ||
import { UpgradeLightClientScript } from "./UpgradeLightClientToV2.s.sol"; | ||
import { UpgradeLightClientScript as ULCV3 } from "./UpgradeLightClientToV3.s.sol"; | ||
import { OwnableUpgradeable } from | ||
"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; | ||
|
||
contract LightClientUpgradeToVxTest is Test { | ||
LCV1 public lcV1Proxy; | ||
LCV2 public lcV2Proxy; | ||
LCV3 public lcV3Proxy; | ||
|
||
DeployLightClientContractScript public deployer = new DeployLightClientContractScript(); | ||
UpgradeLightClientScript public upgraderV2 = new UpgradeLightClientScript(); | ||
ULCV3 public upgraderV3 = new ULCV3(); | ||
|
||
LCV1.LightClientState public stateV1; | ||
|
||
address public admin; | ||
address public proxy; | ||
|
||
// deploy the first implementation with its proxy | ||
function setUp() public { | ||
(proxy, admin, stateV1) = deployer.run(10, 5); | ||
lcV1Proxy = LCV1(proxy); | ||
} | ||
|
||
function testCorrectInitialization() public view { | ||
assert(lcV1Proxy.blocksPerEpoch() == 10); | ||
assert(lcV1Proxy.currentEpoch() == 0); | ||
|
||
assertEq(abi.encode(lcV1Proxy.getGenesisState()), abi.encode(stateV1)); | ||
|
||
assertEq(abi.encode(lcV1Proxy.getFinalizedState()), abi.encode(stateV1)); | ||
|
||
bytes32 stakeTableComm = lcV1Proxy.computeStakeTableComm(stateV1); | ||
assertEq(lcV1Proxy.votingStakeTableCommitment(), stakeTableComm); | ||
assertEq(lcV1Proxy.frozenStakeTableCommitment(), stakeTableComm); | ||
assertEq(lcV1Proxy.votingThreshold(), stateV1.threshold); | ||
assertEq(lcV1Proxy.frozenThreshold(), stateV1.threshold); | ||
} | ||
|
||
// that the data remains the same after upgrading the implementation | ||
function testUpgradeSameDataV1ToV2() public { | ||
// Upgrade LightClient and check that the genesis state is not changed and that the new | ||
// field | ||
// of the upgraded contract is set to 0 | ||
uint256 myNewField = 123; | ||
lcV2Proxy = LCV2(upgraderV2.run(proxy, myNewField, admin)); | ||
|
||
assertEq(lcV2Proxy.newField(), myNewField); | ||
assertEq(lcV2Proxy.blocksPerEpoch(), 10); | ||
assertEq(lcV2Proxy.currentEpoch(), 0); | ||
|
||
LCV1.LightClientState memory expectedLightClientState = LCV1.LightClientState( | ||
stateV1.viewNum, | ||
stateV1.blockHeight, | ||
stateV1.blockCommRoot, | ||
stateV1.feeLedgerComm, | ||
stateV1.stakeTableBlsKeyComm, | ||
stateV1.stakeTableSchnorrKeyComm, | ||
stateV1.stakeTableAmountComm, | ||
stateV1.threshold | ||
); | ||
|
||
LCV2.ExtendedLightClientState memory expectedExtendedLightClientState = | ||
LCV2.ExtendedLightClientState(0); | ||
|
||
assertEq(abi.encode(lcV2Proxy.getFinalizedState()), abi.encode(expectedLightClientState)); | ||
assertEq( | ||
abi.encode(lcV2Proxy.getExtendedFinalizedState()), | ||
abi.encode(expectedExtendedLightClientState) | ||
); | ||
} | ||
|
||
// that the data remains the same after upgrading the implementation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorted here 7c3569c |
||
function testUpgradeSameDataV2ToV3() public { | ||
// Upgrade LightClient and check that the genesis state is not changed and that the new | ||
// field | ||
// of the upgraded contract is set to 0 | ||
uint256 myNewField = 123; | ||
uint256 myNewFieldV3 = 456; | ||
lcV2Proxy = LCV2(upgraderV2.run(proxy, myNewField, admin)); | ||
|
||
assertEq(lcV2Proxy.newField(), myNewField); | ||
assertEq(lcV2Proxy.blocksPerEpoch(), 10); | ||
assertEq(lcV2Proxy.currentEpoch(), 0); | ||
|
||
LCV1.LightClientState memory expectedLightClientState = LCV1.LightClientState( | ||
stateV1.viewNum, | ||
stateV1.blockHeight, | ||
stateV1.blockCommRoot, | ||
stateV1.feeLedgerComm, | ||
stateV1.stakeTableBlsKeyComm, | ||
stateV1.stakeTableSchnorrKeyComm, | ||
stateV1.stakeTableAmountComm, | ||
stateV1.threshold | ||
); | ||
|
||
LCV2.ExtendedLightClientState memory expectedExtendedLightClientState = | ||
LCV2.ExtendedLightClientState(0); | ||
|
||
assertEq(abi.encode(lcV2Proxy.getFinalizedState()), abi.encode(expectedLightClientState)); | ||
assertEq( | ||
abi.encode(lcV2Proxy.getExtendedFinalizedState()), | ||
abi.encode(expectedExtendedLightClientState) | ||
); | ||
|
||
// upgrade to v3 | ||
lcV3Proxy = LCV3(upgraderV3.run(proxy, myNewFieldV3, admin)); | ||
|
||
assertEq(lcV3Proxy.newField(), myNewField); | ||
assertEq(lcV3Proxy.anotherField(), myNewFieldV3); | ||
assertEq(lcV3Proxy.blocksPerEpoch(), 10); | ||
assertEq(lcV3Proxy.currentEpoch(), 0); | ||
|
||
assertEq(abi.encode(lcV3Proxy.getFinalizedState()), abi.encode(expectedLightClientState)); | ||
assertEq( | ||
abi.encode(lcV3Proxy.getExtendedFinalizedState()), | ||
abi.encode(expectedExtendedLightClientState) | ||
); | ||
} | ||
|
||
// check that the proxy address remains the same | ||
function testUpgradesSameProxyAddress() public { | ||
(uint8 major, uint8 minor, uint8 patch) = lcV1Proxy.getVersion(); | ||
assertEq(major, 1); | ||
assertEq(minor, 0); | ||
assertEq(patch, 0); | ||
|
||
//upgrade box | ||
lcV2Proxy = LCV2(upgraderV2.run(proxy, 123, admin)); | ||
assertEq(address(lcV2Proxy), address(lcV1Proxy)); | ||
(uint8 majorV2, uint8 minorV2, uint8 patchV2) = lcV2Proxy.getVersion(); | ||
assertEq(majorV2, 2); | ||
assertEq(minorV2, 0); | ||
assertEq(patchV2, 0); | ||
} | ||
|
||
function testMaliciousUpgradeToV2Fails() public { | ||
address attacker = makeAddr("attacker"); | ||
|
||
//attempted upgrade as attacker will revert | ||
vm.expectRevert( | ||
abi.encodeWithSelector(OwnableUpgradeable.OwnableUnauthorizedAccount.selector, attacker) | ||
); | ||
|
||
lcV2Proxy = LCV2(upgraderV2.run(address(proxy), 123, attacker)); | ||
} | ||
|
||
function testMaliciousUpgradeToV32Fails() public { | ||
address attacker = makeAddr("attacker"); | ||
|
||
//attempted upgrade as attacker will revert | ||
|
||
vm.expectRevert( | ||
abi.encodeWithSelector(OwnableUpgradeable.OwnableUnauthorizedAccount.selector, attacker) | ||
); | ||
lcV3Proxy = LCV3(upgraderV3.run(address(proxy), 456, attacker)); | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
nit:
test that the data remains the same after upgrading the 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.
sorted here 7c3569c