Skip to content

Commit f09d975

Browse files
test: reboot fork test setup (#511)
* reboot fork setup * Fix: upgrade in reboot script * follow naming convention * fix: actual ethereum updater * functional reboot setup * feat: reload config * refactor: put reboot actions into single forge script * fix: only deploy accountant on ethereum * exclude fork tests from test:unit * changelog & readme * refactor: config stores path and reloads from it * refactor: rename update___ to write____Config * fix: don't attempt to initialize again if unneeded * fix: pushUpgrade checks if upgrade is unnecessary * feat: don't re-deploy accountant if already deployed * explicit import Script * rename: push__ for gov actions * console.log * feat: don't overwrite config * fix: safety on config loading Co-authored-by: James <[email protected]>
1 parent c3ce016 commit f09d975

18 files changed

+445
-179
lines changed

foundry.toml

+4
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,15 @@ src = 'packages/contracts-da-bridge/contracts'
7171
test = 'packages/contracts-da-bridge/contracts/test'
7272
out = 'packages/contracts-da-bridge/foundry_artifacts'
7373
ffi = true
74+
7475
[profile.da-bridge-ci.fuzz]
7576
runs = 10_000
77+
7678
[profile.ops]
7779
src = 'packages/contracts-ops/contracts'
7880
test = 'packages/contracts-ops/contracts/test'
7981
out = 'packages/contracts-ops/foundry_artifacts'
8082
ffi = true
8183
fs_permissions = [{ access = "read-write", path = "./actions" }]
84+
# same as above, + 5574 for contract size
85+
ignored_error_codes = [2462, 5878, 9302, 5574]

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"storage-inspect:generate": "yarn workspaces foreach -Apvi --include @nomad-xyz/contracts-core --include @nomad-xyz/contracts-bridge --include @nomad-xyz/contracts-router run storage-inspect:generate",
3333
"test:coverage": "yarn workspaces foreach -Apvi run test:coverage",
3434
"test:integration": "yarn local-environment test:integration",
35-
"test:unit": "yarn workspaces foreach -Apvt --exclude @nomad-xyz/deploy run test:unit"
35+
"test:unit": "yarn workspaces foreach -Apvt --exclude @nomad-xyz/deploy --exclude @nomad-xyz/contracts-ops run test:unit"
3636
},
3737
"packageManager": "[email protected]"
3838
}

packages/contracts-core/contracts/test/Home.t.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ contract HomeTest is NomadTestWithUpdaterManager {
6161

6262
function test_onlyUpdaterManagerSetUpdater() public {
6363
address newUpdater = vm.addr(420);
64-
address oldUpdater = updater;
65-
assertEq(home.updater(), updater);
66-
assertEq(updaterManager.updater(), updater);
64+
address oldUpdater = updaterAddr;
65+
assertEq(home.updater(), updaterAddr);
66+
assertEq(updaterManager.updater(), updaterAddr);
6767
vm.expectEmit(false, false, false, true);
6868
emit NewUpdater(oldUpdater, newUpdater);
6969
vm.prank(address(updaterManager));

packages/contracts-core/contracts/test/NomadBase.t.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ contract NomadBaseTest is NomadTest {
1818
super.setUp();
1919
nbh = new NomadBaseHarness(homeDomain);
2020
vm.expectEmit(false, false, false, true);
21-
emit NewUpdater(address(0), updater);
22-
nbh.initialize(updater);
21+
emit NewUpdater(address(0), updaterAddr);
22+
nbh.initialize(updaterAddr);
2323
vm.label(address(nbh), "Nomad Base Harness");
2424
}
2525

2626
function test_failInitializeTwice() public {
2727
vm.expectRevert(
2828
bytes("Initializable: contract is already initialized")
2929
);
30-
nbh.initialize(updater);
30+
nbh.initialize(updaterAddr);
3131
}
3232

3333
function test_ownerIsContractCreator() public {

packages/contracts-core/contracts/test/Replica.t.sol

+8-8
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ contract ReplicaTest is ReplicaHandlers {
1616

1717
ReplicaHarness replica;
1818

19-
uint256 optimisticSeconds;
19+
uint256 optimisticTimeout;
2020
bytes32 committedRoot;
2121

2222
bytes32 exampleRoot;
2323
bytes32 exampleLeaf;
2424
uint256 exampleLeafIndex;
2525
bytes32[32] exampleProof;
2626

27-
function setUp() public override {
27+
function setUp() public virtual override {
2828
super.setUp();
2929
committedRoot = "commited root";
3030

@@ -137,17 +137,17 @@ contract ReplicaTest is ReplicaHandlers {
137137
}
138138

139139
function initializeReplica() public {
140-
optimisticSeconds = 10;
140+
optimisticTimeout = 10;
141141

142142
replica.initialize(
143143
remoteDomain,
144-
updater,
144+
updaterAddr,
145145
committedRoot,
146-
optimisticSeconds
146+
optimisticTimeout
147147
);
148148
assertEq(uint256(replica.remoteDomain()), uint256(remoteDomain));
149149
assertEq(replica.committedRoot(), committedRoot);
150-
assertEq(replica.optimisticSeconds(), optimisticSeconds);
150+
assertEq(replica.optimisticSeconds(), optimisticTimeout);
151151
assertEq(replica.confirmAt(committedRoot), 1);
152152
}
153153

@@ -168,7 +168,7 @@ contract ReplicaTest is ReplicaHandlers {
168168

169169
assertEq(
170170
replica.confirmAt(newRoot),
171-
block.timestamp + optimisticSeconds
171+
block.timestamp + optimisticTimeout
172172
);
173173
assertEq(replica.committedRoot(), newRoot);
174174
}
@@ -465,7 +465,7 @@ contract ReplicaTest is ReplicaHandlers {
465465

466466
function test_setUpdaterOnlyOwner() public {
467467
vm.expectEmit(false, false, false, true);
468-
emit NewUpdater(updater, vm.addr(10));
468+
emit NewUpdater(updaterAddr, vm.addr(10));
469469
vm.prank(replica.owner());
470470
replica.setUpdater(vm.addr(10));
471471
vm.prank(vm.addr(1453));

packages/contracts-core/contracts/test/utils/NomadTest.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {MerkleTest} from "./MerkleTest.sol";
1111
contract NomadTest is Test {
1212
uint256 updaterPK = 1;
1313
uint256 fakeUpdaterPK = 2;
14-
address updater = vm.addr(updaterPK);
14+
address updaterAddr = vm.addr(updaterPK);
1515
address fakeUpdater = vm.addr(fakeUpdaterPK);
1616
address signer = vm.addr(3);
1717
address fakeSigner = vm.addr(4);
@@ -22,7 +22,7 @@ contract NomadTest is Test {
2222
MerkleTest merkleTest;
2323

2424
function setUp() public virtual {
25-
vm.label(updater, "updater");
25+
vm.label(updaterAddr, "updater");
2626
vm.label(fakeUpdater, "fake updater");
2727
vm.label(signer, "signer");
2828
vm.label(fakeSigner, "fake signer");
@@ -91,7 +91,7 @@ contract NomadTestWithUpdaterManager is NomadTest {
9191

9292
function setUp() public virtual override {
9393
super.setUp();
94-
updaterManager = new UpdaterManager(updater);
94+
updaterManager = new UpdaterManager(updaterAddr);
9595
}
9696
}
9797

packages/contracts-ops/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
- feature: callbatch contract
1010
- feature: Config.sol exposes configuration to foundry scripts
1111
- feature: Produce callbatches required to perform an Upgrade
12+
- feature: Reboot script & Reboot fork test setup

packages/contracts-ops/README.md

+17-2
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,27 @@ Contains forge scripts for Nomad system maintenance
3838
- uses `CallBatch` and `Config`
3939
- Entrypoint:
4040
- `printCallBatches(string,string[],string,bool)`:
41-
- config path (e.g `actions/production.json`)
41+
- name of config JSON file in `./actions` folder (e.g `production.json` for `./actions/production.json`)
4242
- list of domains for which batches should be built (e.g `[evmos,ethereum,moonbeam]`)
4343
- name of the domain that should be considered as local (e.g `ethereum`)
4444
- `true` if scripts should run for recovery mode, `false` otherwise
4545
- Example:
46-
- `FOUNDRY_PROFILE=ops forge script UpgradeCallBatches --sig "printCallBatches(string,string[],string,bool)" "actions/production.json" "[evmos,avalanche,xdai,milkomedaC1,moonbeam,ethereum]" "ethereum" true`
46+
- `FOUNDRY_PROFILE=ops forge script UpgradeCallBatches --sig "printCallBatches(string,string[],string,bool)" "production.json" "[evmos,avalanche,xdai,milkomedaC1,moonbeam,ethereum]" "ethereum" true`
47+
- `Reboot.s.sol`
48+
- Performs all steps necessary to reboot the protocol
49+
- Deploy fresh implementations
50+
- Push calls to upgrade to fresh implementations
51+
- Rotate the Updater key
52+
- Re-enroll the Replicas in the xAppConnectionManager
53+
- uses `CallBatch` and `Config`
54+
- Entrypoint:
55+
- `runReboot(string,string,string,bool)`:
56+
- name of config JSON file in `./actions` folder (e.g `production.json` for `./actions/production.json`)
57+
- domain to run the script on (e.g `ethereum`)
58+
- name of JSON file to output callBatch (e.g `rebootActions.json` for `./actions/rebootActions.json`)
59+
- `true` to overwrite existing contents of output file, `false` otherwise
60+
- Example:
61+
- `FOUNDRY_PROFILE=ops forge script Reboot --sig "runReboot(string,string,string,bool)" "production.json" "ethereum" "rebootActions.json" true`
4762

4863
## Usage
4964

packages/contracts-ops/contracts/CallBatch.sol

+15-11
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,36 @@ import {TypeCasts} from "@nomad-xyz/contracts-core/contracts/XAppConnectionManag
1111
import {JsonWriter} from "./JsonWriter.sol";
1212

1313
import "forge-std/Script.sol";
14+
import "forge-std/Vm.sol";
1415

15-
abstract contract CallBatch is Script {
16+
abstract contract CallBatch {
1617
using JsonWriter for JsonWriter.Buffer;
1718
using JsonWriter for string;
1819

20+
Vm private constant vm =
21+
Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
22+
1923
string localDomainName;
2024
uint32 public localDomain;
2125
GovernanceMessage.Call[] public localCalls;
2226
uint32[] public remoteDomains;
2327
mapping(uint32 => GovernanceMessage.Call[]) public remoteCalls;
2428

2529
bool public written;
26-
JsonWriter.File outputFile;
30+
JsonWriter.File batchOutput;
2731

2832
function __CallBatch_initialize(
2933
string memory _localDomainName,
3034
uint32 _localDomain,
31-
string memory _outputFilePath,
35+
string memory _batchOutput,
3236
bool _overwrite
3337
) public {
3438
require(localDomain == 0, "already initialized");
3539
require(_localDomain != 0, "can't pass zero domain");
3640
localDomainName = _localDomainName;
3741
localDomain = _localDomain;
38-
outputFile.overwrite = _overwrite;
39-
outputFile.path = string(
40-
abi.encodePacked("./actions/", _outputFilePath)
41-
);
42+
batchOutput.overwrite = _overwrite;
43+
batchOutput.path = string(abi.encodePacked("./actions/", _batchOutput));
4244
}
4345

4446
function pushRemote(
@@ -112,7 +114,7 @@ abstract contract CallBatch is Script {
112114
string memory indent,
113115
GovernanceMessage.Call storage call,
114116
bool terminal
115-
) private {
117+
) private view {
116118
buffer.writeObjectOpen(indent);
117119
string memory inner = indent.nextIndent();
118120
buffer.writeKv(
@@ -129,7 +131,7 @@ abstract contract CallBatch is Script {
129131
JsonWriter.Buffer memory buffer,
130132
string memory indent,
131133
GovernanceMessage.Call[] storage calls
132-
) private {
134+
) private view {
133135
for (uint32 i = 0; i < calls.length; i++) {
134136
writeCall(
135137
buffer,
@@ -142,6 +144,7 @@ abstract contract CallBatch is Script {
142144

143145
function writeLocal(JsonWriter.Buffer memory buffer, string memory indent)
144146
private
147+
view
145148
{
146149
buffer.writeArrayOpen(indent, "local");
147150
writeCallList(buffer, indent, localCalls);
@@ -150,6 +153,7 @@ abstract contract CallBatch is Script {
150153

151154
function writeRemotes(JsonWriter.Buffer memory buffer, string memory indent)
152155
private
156+
view
153157
{
154158
if (remoteDomains.length == 0) return;
155159
buffer.writeObjectOpen(indent, "remote");
@@ -172,7 +176,7 @@ abstract contract CallBatch is Script {
172176
uint32 domain,
173177
GovernanceMessage.Call[] memory calls,
174178
bool isLastDomain
175-
) private {
179+
) private pure {
176180
buffer.writeObjectOpen(indent, vm.toString(uint256(domain)));
177181
bytes memory data = abi.encodeWithSelector(
178182
GovernanceRouter.executeGovernanceActions.selector,
@@ -260,7 +264,7 @@ abstract contract CallBatch is Script {
260264
writeRemotes(buffer, inner);
261265
writeBuilt(buffer, inner, recovery);
262266
buffer.writeObjectClose(indent, true);
263-
buffer.flushTo(outputFile);
267+
buffer.flushTo(batchOutput);
264268
// finish
265269
written = true;
266270
}

0 commit comments

Comments
 (0)