@hyperlane-xyz/deploy-sdk 3.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/core-artifact-reader.d.ts +19 -1
- package/dist/core/core-artifact-reader.d.ts.map +1 -1
- package/dist/core/core-artifact-reader.js +23 -3
- package/dist/core/core-artifact-reader.js.map +1 -1
- package/dist/core/core-artifact-reader.test.d.ts +2 -0
- package/dist/core/core-artifact-reader.test.d.ts.map +1 -0
- package/dist/core/core-artifact-reader.test.js +300 -0
- package/dist/core/core-artifact-reader.test.js.map +1 -0
- package/dist/core/core-writer.d.ts +42 -0
- package/dist/core/core-writer.d.ts.map +1 -0
- package/dist/core/core-writer.js +230 -0
- package/dist/core/core-writer.js.map +1 -0
- package/dist/core/core-writer.test.d.ts +2 -0
- package/dist/core/core-writer.test.d.ts.map +1 -0
- package/dist/core/core-writer.test.js +980 -0
- package/dist/core/core-writer.test.js.map +1 -0
- package/dist/hook/hook-writer.d.ts.map +1 -1
- package/dist/hook/hook-writer.js +2 -1
- package/dist/hook/hook-writer.js.map +1 -1
- package/dist/index.d.ts +7 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -9
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
- package/dist/AltVMCoreModule.d.ts +0 -94
- package/dist/AltVMCoreModule.d.ts.map +0 -1
- package/dist/AltVMCoreModule.js +0 -368
- package/dist/AltVMCoreModule.js.map +0 -1
- package/dist/AltVMCoreReader.d.ts +0 -16
- package/dist/AltVMCoreReader.d.ts.map +0 -1
- package/dist/AltVMCoreReader.js +0 -36
- package/dist/AltVMCoreReader.js.map +0 -1
- package/dist/core-module.d.ts +0 -5
- package/dist/core-module.d.ts.map +0 -1
- package/dist/core-module.js +0 -28
- package/dist/core-module.js.map +0 -1
|
@@ -0,0 +1,980 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import sinon from 'sinon';
|
|
3
|
+
import { MockSigner, hasProtocol, registerProtocol, } from '@hyperlane-xyz/provider-sdk';
|
|
4
|
+
import { ArtifactState, } from '@hyperlane-xyz/provider-sdk/artifact';
|
|
5
|
+
import { ZERO_ADDRESS_HEX_32 } from '@hyperlane-xyz/utils';
|
|
6
|
+
import { CoreWriter } from './core-writer.js';
|
|
7
|
+
// Test protocol
|
|
8
|
+
const TestProtocol = 'test-core-writer';
|
|
9
|
+
let mockIsmArtifactManager;
|
|
10
|
+
let mockHookArtifactManager;
|
|
11
|
+
let mockProtocolProvider;
|
|
12
|
+
if (!hasProtocol(TestProtocol)) {
|
|
13
|
+
registerProtocol(TestProtocol, () => mockProtocolProvider);
|
|
14
|
+
}
|
|
15
|
+
describe('CoreWriter', () => {
|
|
16
|
+
const mockMailboxAddress = '0xMAILBOX';
|
|
17
|
+
const mockIsmAddress = '0xISM';
|
|
18
|
+
const mockNewIsmAddress = '0xNEWISM';
|
|
19
|
+
const mockDefaultHookAddress = '0xDEFAULTHOOK';
|
|
20
|
+
const mockRequiredHookAddress = '0xREQUIREDHOOK';
|
|
21
|
+
const mockValidatorAnnounceAddress = '0xVA';
|
|
22
|
+
const mockOwner = '0xOWNER';
|
|
23
|
+
const mockSignerAddress = '0xSIGNER';
|
|
24
|
+
const mockDomainId = 1;
|
|
25
|
+
const chainName = 'test-chain';
|
|
26
|
+
let createMailboxWriterStub;
|
|
27
|
+
let createVAWriterStub;
|
|
28
|
+
let getSignerAddressStub;
|
|
29
|
+
let sendAndConfirmTxStub;
|
|
30
|
+
let mailboxArtifactManager;
|
|
31
|
+
let validatorAnnounceArtifactManager;
|
|
32
|
+
let signer;
|
|
33
|
+
let chainLookup;
|
|
34
|
+
let chainMetadata;
|
|
35
|
+
let coreWriter;
|
|
36
|
+
const mockReceipt = {
|
|
37
|
+
transactionHash: '0xHASH',
|
|
38
|
+
blockNumber: 123,
|
|
39
|
+
};
|
|
40
|
+
const mockIsm = {
|
|
41
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
42
|
+
config: {
|
|
43
|
+
type: 'merkleRootMultisigIsm',
|
|
44
|
+
validators: ['0xVALIDATOR1'],
|
|
45
|
+
threshold: 1,
|
|
46
|
+
},
|
|
47
|
+
deployed: { address: mockIsmAddress },
|
|
48
|
+
};
|
|
49
|
+
const mockDefaultHook = {
|
|
50
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
51
|
+
config: {
|
|
52
|
+
type: 'merkleTreeHook',
|
|
53
|
+
},
|
|
54
|
+
deployed: { address: mockDefaultHookAddress },
|
|
55
|
+
};
|
|
56
|
+
const mockRequiredHook = {
|
|
57
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
58
|
+
config: {
|
|
59
|
+
type: 'interchainGasPaymaster',
|
|
60
|
+
owner: mockOwner,
|
|
61
|
+
beneficiary: '0xBENEFICIARY',
|
|
62
|
+
oracleKey: '0xORACLE',
|
|
63
|
+
overhead: {},
|
|
64
|
+
oracleConfig: {},
|
|
65
|
+
},
|
|
66
|
+
deployed: { address: mockRequiredHookAddress },
|
|
67
|
+
};
|
|
68
|
+
beforeEach(async () => {
|
|
69
|
+
mockIsmArtifactManager = {
|
|
70
|
+
readIsm: sinon.stub(),
|
|
71
|
+
createReader: sinon.stub().returns({ read: sinon.stub() }),
|
|
72
|
+
createWriter: sinon.stub().returns({
|
|
73
|
+
create: sinon.stub(),
|
|
74
|
+
update: sinon.stub(),
|
|
75
|
+
read: sinon.stub(),
|
|
76
|
+
}),
|
|
77
|
+
};
|
|
78
|
+
mockHookArtifactManager = {
|
|
79
|
+
readHook: sinon.stub(),
|
|
80
|
+
createReader: sinon.stub().returns({ read: sinon.stub() }),
|
|
81
|
+
createWriter: sinon.stub().returns({
|
|
82
|
+
create: sinon.stub(),
|
|
83
|
+
update: sinon.stub(),
|
|
84
|
+
read: sinon.stub(),
|
|
85
|
+
}),
|
|
86
|
+
};
|
|
87
|
+
mockProtocolProvider = {
|
|
88
|
+
createProvider: sinon.stub(),
|
|
89
|
+
createSigner: sinon.stub(),
|
|
90
|
+
createSubmitter: sinon.stub(),
|
|
91
|
+
createIsmArtifactManager: sinon.stub(),
|
|
92
|
+
createHookArtifactManager: sinon.stub().returns(mockHookArtifactManager),
|
|
93
|
+
createMailboxArtifactManager: sinon.stub(),
|
|
94
|
+
createValidatorAnnounceArtifactManager: sinon.stub(),
|
|
95
|
+
getMinGas: sinon.stub(),
|
|
96
|
+
createWarpArtifactManager: sinon.stub(),
|
|
97
|
+
};
|
|
98
|
+
mockProtocolProvider.createIsmArtifactManager = sinon
|
|
99
|
+
.stub()
|
|
100
|
+
.returns(mockIsmArtifactManager);
|
|
101
|
+
signer = await MockSigner.connectWithSigner();
|
|
102
|
+
getSignerAddressStub = sinon.stub().returns(mockSignerAddress);
|
|
103
|
+
sinon.stub(signer, 'getSignerAddress').callsFake(getSignerAddressStub);
|
|
104
|
+
sendAndConfirmTxStub = sinon
|
|
105
|
+
.stub()
|
|
106
|
+
.resolves(mockReceipt);
|
|
107
|
+
sinon
|
|
108
|
+
.stub(signer, 'sendAndConfirmTransaction')
|
|
109
|
+
.callsFake(sendAndConfirmTxStub);
|
|
110
|
+
const mailboxCreateStub = sinon
|
|
111
|
+
.stub()
|
|
112
|
+
.resolves([
|
|
113
|
+
{
|
|
114
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
115
|
+
config: {
|
|
116
|
+
owner: mockSignerAddress,
|
|
117
|
+
defaultIsm: {
|
|
118
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
119
|
+
config: mockIsm.config,
|
|
120
|
+
deployed: mockIsm.deployed,
|
|
121
|
+
},
|
|
122
|
+
defaultHook: {
|
|
123
|
+
artifactState: ArtifactState.UNDERIVED,
|
|
124
|
+
deployed: { address: ZERO_ADDRESS_HEX_32 },
|
|
125
|
+
},
|
|
126
|
+
requiredHook: {
|
|
127
|
+
artifactState: ArtifactState.UNDERIVED,
|
|
128
|
+
deployed: { address: ZERO_ADDRESS_HEX_32 },
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
132
|
+
},
|
|
133
|
+
[mockReceipt],
|
|
134
|
+
]);
|
|
135
|
+
const mailboxUpdateStub = sinon
|
|
136
|
+
.stub()
|
|
137
|
+
.resolves([]);
|
|
138
|
+
const mockMailboxWriter = {
|
|
139
|
+
create: mailboxCreateStub,
|
|
140
|
+
update: mailboxUpdateStub,
|
|
141
|
+
read: sinon.stub(),
|
|
142
|
+
};
|
|
143
|
+
createMailboxWriterStub = sinon.stub().returns(mockMailboxWriter);
|
|
144
|
+
mailboxArtifactManager = {
|
|
145
|
+
readMailbox: sinon.stub(),
|
|
146
|
+
createReader: sinon.stub(),
|
|
147
|
+
createWriter: createMailboxWriterStub,
|
|
148
|
+
};
|
|
149
|
+
const vaCreateStub = sinon
|
|
150
|
+
.stub()
|
|
151
|
+
.resolves([
|
|
152
|
+
{
|
|
153
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
154
|
+
config: { mailboxAddress: mockMailboxAddress },
|
|
155
|
+
deployed: { address: mockValidatorAnnounceAddress },
|
|
156
|
+
},
|
|
157
|
+
[mockReceipt],
|
|
158
|
+
]);
|
|
159
|
+
const mockVAWriter = {
|
|
160
|
+
create: vaCreateStub,
|
|
161
|
+
update: sinon.stub(),
|
|
162
|
+
read: sinon.stub(),
|
|
163
|
+
};
|
|
164
|
+
createVAWriterStub = sinon.stub().returns(mockVAWriter);
|
|
165
|
+
validatorAnnounceArtifactManager = {
|
|
166
|
+
readValidatorAnnounce: sinon.stub(),
|
|
167
|
+
createReader: sinon.stub(),
|
|
168
|
+
createWriter: createVAWriterStub,
|
|
169
|
+
};
|
|
170
|
+
chainMetadata = {
|
|
171
|
+
name: chainName,
|
|
172
|
+
domainId: mockDomainId,
|
|
173
|
+
protocol: TestProtocol,
|
|
174
|
+
chainId: mockDomainId,
|
|
175
|
+
};
|
|
176
|
+
chainLookup = {
|
|
177
|
+
getChainMetadata: sinon
|
|
178
|
+
.stub()
|
|
179
|
+
.returns(chainMetadata),
|
|
180
|
+
getChainName: sinon.stub().returns(chainName),
|
|
181
|
+
getDomainId: sinon
|
|
182
|
+
.stub()
|
|
183
|
+
.returns(mockDomainId),
|
|
184
|
+
getKnownChainNames: sinon.stub().returns([chainName]),
|
|
185
|
+
};
|
|
186
|
+
coreWriter = new CoreWriter(mailboxArtifactManager, validatorAnnounceArtifactManager, chainMetadata, chainLookup, signer);
|
|
187
|
+
});
|
|
188
|
+
afterEach(() => {
|
|
189
|
+
sinon.restore();
|
|
190
|
+
});
|
|
191
|
+
describe('create', () => {
|
|
192
|
+
it('should deploy mailbox with NEW ISM and NEW hooks', async () => {
|
|
193
|
+
// ARRANGE
|
|
194
|
+
const artifact = {
|
|
195
|
+
artifactState: ArtifactState.NEW,
|
|
196
|
+
config: {
|
|
197
|
+
owner: mockOwner,
|
|
198
|
+
defaultIsm: {
|
|
199
|
+
artifactState: ArtifactState.NEW,
|
|
200
|
+
config: mockIsm.config,
|
|
201
|
+
},
|
|
202
|
+
defaultHook: {
|
|
203
|
+
artifactState: ArtifactState.NEW,
|
|
204
|
+
config: mockDefaultHook.config,
|
|
205
|
+
},
|
|
206
|
+
requiredHook: {
|
|
207
|
+
artifactState: ArtifactState.NEW,
|
|
208
|
+
config: mockRequiredHook.config,
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
const ismCreateStub = sinon
|
|
213
|
+
.stub()
|
|
214
|
+
.callsFake(async () => [mockIsm, [mockReceipt]]);
|
|
215
|
+
const mockIsmWriter = {
|
|
216
|
+
create: ismCreateStub,
|
|
217
|
+
update: sinon.stub(),
|
|
218
|
+
read: sinon.stub(),
|
|
219
|
+
};
|
|
220
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
221
|
+
value: mockIsmWriter,
|
|
222
|
+
writable: true,
|
|
223
|
+
});
|
|
224
|
+
const hookCreateStub = sinon
|
|
225
|
+
.stub()
|
|
226
|
+
.onFirstCall()
|
|
227
|
+
.callsFake(async () => [mockDefaultHook, [mockReceipt]])
|
|
228
|
+
.onSecondCall()
|
|
229
|
+
.callsFake(async () => [mockRequiredHook, [mockReceipt]]);
|
|
230
|
+
const mockHookWriter = {
|
|
231
|
+
create: hookCreateStub,
|
|
232
|
+
update: sinon.stub(),
|
|
233
|
+
read: sinon.stub(),
|
|
234
|
+
};
|
|
235
|
+
mockHookArtifactManager.createWriter = sinon
|
|
236
|
+
.stub()
|
|
237
|
+
.returns(mockHookWriter);
|
|
238
|
+
// ACT
|
|
239
|
+
const [result, receipts] = await coreWriter.create(artifact);
|
|
240
|
+
// ASSERT
|
|
241
|
+
expect(result.mailbox.deployed.address).to.equal(mockMailboxAddress);
|
|
242
|
+
expect(result.mailbox.config.owner).to.equal(mockOwner);
|
|
243
|
+
expect(result.validatorAnnounce).to.not.be.null;
|
|
244
|
+
expect(result.validatorAnnounce?.deployed.address).to.equal(mockValidatorAnnounceAddress);
|
|
245
|
+
expect(receipts.length).to.be.greaterThan(0);
|
|
246
|
+
sinon.assert.calledOnce(ismCreateStub);
|
|
247
|
+
sinon.assert.calledTwice(hookCreateStub);
|
|
248
|
+
sinon.assert.calledWith(createMailboxWriterStub, 'mailbox', signer);
|
|
249
|
+
sinon.assert.calledWith(createVAWriterStub, 'validatorAnnounce', signer);
|
|
250
|
+
});
|
|
251
|
+
it('should use existing ISM when DEPLOYED', async () => {
|
|
252
|
+
// ARRANGE
|
|
253
|
+
const artifact = {
|
|
254
|
+
artifactState: ArtifactState.NEW,
|
|
255
|
+
config: {
|
|
256
|
+
owner: mockOwner,
|
|
257
|
+
defaultIsm: mockIsm,
|
|
258
|
+
defaultHook: mockDefaultHook,
|
|
259
|
+
requiredHook: mockRequiredHook,
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
const ismCreateStub = sinon.stub();
|
|
263
|
+
const mockIsmWriter = {
|
|
264
|
+
create: ismCreateStub,
|
|
265
|
+
update: sinon.stub(),
|
|
266
|
+
read: sinon.stub(),
|
|
267
|
+
};
|
|
268
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
269
|
+
value: mockIsmWriter,
|
|
270
|
+
writable: true,
|
|
271
|
+
});
|
|
272
|
+
// ACT
|
|
273
|
+
await coreWriter.create(artifact);
|
|
274
|
+
// ASSERT
|
|
275
|
+
sinon.assert.notCalled(ismCreateStub);
|
|
276
|
+
});
|
|
277
|
+
it('should handle protocol without validator announce support', async () => {
|
|
278
|
+
// ARRANGE
|
|
279
|
+
const coreWriterNoVA = new CoreWriter(mailboxArtifactManager, null, chainMetadata, chainLookup, signer);
|
|
280
|
+
const artifact = {
|
|
281
|
+
artifactState: ArtifactState.NEW,
|
|
282
|
+
config: {
|
|
283
|
+
owner: mockOwner,
|
|
284
|
+
defaultIsm: mockIsm,
|
|
285
|
+
defaultHook: mockDefaultHook,
|
|
286
|
+
requiredHook: mockRequiredHook,
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
const mockIsmWriter = {
|
|
290
|
+
create: sinon.stub(),
|
|
291
|
+
update: sinon.stub(),
|
|
292
|
+
read: sinon.stub(),
|
|
293
|
+
};
|
|
294
|
+
Object.defineProperty(coreWriterNoVA, 'ismWriter', {
|
|
295
|
+
value: mockIsmWriter,
|
|
296
|
+
writable: true,
|
|
297
|
+
});
|
|
298
|
+
// ACT
|
|
299
|
+
const [result] = await coreWriterNoVA.create(artifact);
|
|
300
|
+
// ASSERT
|
|
301
|
+
expect(result.validatorAnnounce).to.be.null;
|
|
302
|
+
});
|
|
303
|
+
it('should create mailbox with signer as initial owner', async () => {
|
|
304
|
+
// ARRANGE
|
|
305
|
+
const artifact = {
|
|
306
|
+
artifactState: ArtifactState.NEW,
|
|
307
|
+
config: {
|
|
308
|
+
owner: mockOwner,
|
|
309
|
+
defaultIsm: mockIsm,
|
|
310
|
+
defaultHook: mockDefaultHook,
|
|
311
|
+
requiredHook: mockRequiredHook,
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
const mockIsmWriter = {
|
|
315
|
+
create: sinon.stub(),
|
|
316
|
+
update: sinon.stub(),
|
|
317
|
+
read: sinon.stub(),
|
|
318
|
+
};
|
|
319
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
320
|
+
value: mockIsmWriter,
|
|
321
|
+
writable: true,
|
|
322
|
+
});
|
|
323
|
+
// ACT
|
|
324
|
+
await coreWriter.create(artifact);
|
|
325
|
+
// ASSERT
|
|
326
|
+
const mailboxWriter = createMailboxWriterStub.returnValues[0];
|
|
327
|
+
const mailboxCreateStub = mailboxWriter.create;
|
|
328
|
+
const initialConfig = mailboxCreateStub.firstCall.args[0].config;
|
|
329
|
+
expect(initialConfig.owner).to.equal(mockSignerAddress);
|
|
330
|
+
expect(initialConfig.owner).to.not.equal(mockOwner);
|
|
331
|
+
});
|
|
332
|
+
it('should create mailbox with zero-address hooks initially', async () => {
|
|
333
|
+
// ARRANGE
|
|
334
|
+
const artifact = {
|
|
335
|
+
artifactState: ArtifactState.NEW,
|
|
336
|
+
config: {
|
|
337
|
+
owner: mockOwner,
|
|
338
|
+
defaultIsm: mockIsm,
|
|
339
|
+
defaultHook: {
|
|
340
|
+
artifactState: ArtifactState.NEW,
|
|
341
|
+
config: mockDefaultHook.config,
|
|
342
|
+
},
|
|
343
|
+
requiredHook: {
|
|
344
|
+
artifactState: ArtifactState.NEW,
|
|
345
|
+
config: mockRequiredHook.config,
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
const mockIsmWriter = {
|
|
350
|
+
create: sinon.stub(),
|
|
351
|
+
update: sinon.stub(),
|
|
352
|
+
read: sinon.stub(),
|
|
353
|
+
};
|
|
354
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
355
|
+
value: mockIsmWriter,
|
|
356
|
+
writable: true,
|
|
357
|
+
});
|
|
358
|
+
const mockHookWriter = {
|
|
359
|
+
create: sinon
|
|
360
|
+
.stub()
|
|
361
|
+
.onFirstCall()
|
|
362
|
+
.callsFake(async () => [mockDefaultHook, [mockReceipt]])
|
|
363
|
+
.onSecondCall()
|
|
364
|
+
.callsFake(async () => [mockRequiredHook, [mockReceipt]]),
|
|
365
|
+
update: sinon.stub(),
|
|
366
|
+
read: sinon.stub(),
|
|
367
|
+
};
|
|
368
|
+
mockHookArtifactManager.createWriter = sinon
|
|
369
|
+
.stub()
|
|
370
|
+
.returns(mockHookWriter);
|
|
371
|
+
// ACT
|
|
372
|
+
await coreWriter.create(artifact);
|
|
373
|
+
// ASSERT
|
|
374
|
+
const mailboxWriter = createMailboxWriterStub.returnValues[0];
|
|
375
|
+
const mailboxCreateStub = mailboxWriter.create;
|
|
376
|
+
const initialConfig = mailboxCreateStub.firstCall.args[0].config;
|
|
377
|
+
expect(initialConfig.defaultHook.deployed.address).to.equal(ZERO_ADDRESS_HEX_32);
|
|
378
|
+
expect(initialConfig.requiredHook.deployed.address).to.equal(ZERO_ADDRESS_HEX_32);
|
|
379
|
+
expect(initialConfig.defaultHook.artifactState).to.equal(ArtifactState.UNDERIVED);
|
|
380
|
+
});
|
|
381
|
+
it('should update mailbox with hooks and owner after deployment', async () => {
|
|
382
|
+
// ARRANGE
|
|
383
|
+
const artifact = {
|
|
384
|
+
artifactState: ArtifactState.NEW,
|
|
385
|
+
config: {
|
|
386
|
+
owner: mockOwner,
|
|
387
|
+
defaultIsm: mockIsm,
|
|
388
|
+
defaultHook: mockDefaultHook,
|
|
389
|
+
requiredHook: mockRequiredHook,
|
|
390
|
+
},
|
|
391
|
+
};
|
|
392
|
+
const mockIsmWriter = {
|
|
393
|
+
create: sinon.stub(),
|
|
394
|
+
update: sinon.stub(),
|
|
395
|
+
read: sinon.stub(),
|
|
396
|
+
};
|
|
397
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
398
|
+
value: mockIsmWriter,
|
|
399
|
+
writable: true,
|
|
400
|
+
});
|
|
401
|
+
// ACT
|
|
402
|
+
await coreWriter.create(artifact);
|
|
403
|
+
// ASSERT
|
|
404
|
+
const mailboxWriter = createMailboxWriterStub.returnValues[0];
|
|
405
|
+
const mailboxUpdateStub = mailboxWriter.update;
|
|
406
|
+
sinon.assert.calledOnce(mailboxUpdateStub);
|
|
407
|
+
const updatedArtifact = mailboxUpdateStub.firstCall.args[0];
|
|
408
|
+
expect(updatedArtifact.config.owner).to.equal(mockOwner);
|
|
409
|
+
expect(updatedArtifact.config.defaultHook.deployed.address).to.equal(mockDefaultHookAddress);
|
|
410
|
+
expect(updatedArtifact.config.requiredHook.deployed.address).to.equal(mockRequiredHookAddress);
|
|
411
|
+
});
|
|
412
|
+
it('should execute update transactions via signer', async () => {
|
|
413
|
+
// ARRANGE
|
|
414
|
+
const mockUpdateTx = {
|
|
415
|
+
to: mockMailboxAddress,
|
|
416
|
+
data: '0xUPDATE',
|
|
417
|
+
annotation: 'Update hooks',
|
|
418
|
+
};
|
|
419
|
+
const mailboxCreateStub = sinon.stub().resolves([
|
|
420
|
+
{
|
|
421
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
422
|
+
config: {
|
|
423
|
+
owner: mockSignerAddress,
|
|
424
|
+
defaultIsm: {
|
|
425
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
426
|
+
config: mockIsm.config,
|
|
427
|
+
deployed: mockIsm.deployed,
|
|
428
|
+
},
|
|
429
|
+
defaultHook: {
|
|
430
|
+
artifactState: ArtifactState.UNDERIVED,
|
|
431
|
+
deployed: { address: ZERO_ADDRESS_HEX_32 },
|
|
432
|
+
},
|
|
433
|
+
requiredHook: {
|
|
434
|
+
artifactState: ArtifactState.UNDERIVED,
|
|
435
|
+
deployed: { address: ZERO_ADDRESS_HEX_32 },
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
439
|
+
},
|
|
440
|
+
[mockReceipt],
|
|
441
|
+
]);
|
|
442
|
+
const mailboxUpdateStub = sinon.stub().resolves([mockUpdateTx]);
|
|
443
|
+
const mockMailboxWriter = {
|
|
444
|
+
create: mailboxCreateStub,
|
|
445
|
+
update: mailboxUpdateStub,
|
|
446
|
+
read: sinon.stub(),
|
|
447
|
+
};
|
|
448
|
+
mailboxArtifactManager.createWriter = sinon
|
|
449
|
+
.stub()
|
|
450
|
+
.returns(mockMailboxWriter);
|
|
451
|
+
const artifact = {
|
|
452
|
+
artifactState: ArtifactState.NEW,
|
|
453
|
+
config: {
|
|
454
|
+
owner: mockOwner,
|
|
455
|
+
defaultIsm: mockIsm,
|
|
456
|
+
defaultHook: mockDefaultHook,
|
|
457
|
+
requiredHook: mockRequiredHook,
|
|
458
|
+
},
|
|
459
|
+
};
|
|
460
|
+
const mockIsmWriter = {
|
|
461
|
+
create: sinon.stub(),
|
|
462
|
+
update: sinon.stub(),
|
|
463
|
+
read: sinon.stub(),
|
|
464
|
+
};
|
|
465
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
466
|
+
value: mockIsmWriter,
|
|
467
|
+
writable: true,
|
|
468
|
+
});
|
|
469
|
+
// ACT
|
|
470
|
+
await coreWriter.create(artifact);
|
|
471
|
+
// ASSERT
|
|
472
|
+
sinon.assert.calledWith(sendAndConfirmTxStub, mockUpdateTx);
|
|
473
|
+
});
|
|
474
|
+
it('should collect receipts from all steps', async () => {
|
|
475
|
+
// ARRANGE
|
|
476
|
+
const artifact = {
|
|
477
|
+
artifactState: ArtifactState.NEW,
|
|
478
|
+
config: {
|
|
479
|
+
owner: mockOwner,
|
|
480
|
+
defaultIsm: {
|
|
481
|
+
artifactState: ArtifactState.NEW,
|
|
482
|
+
config: mockIsm.config,
|
|
483
|
+
},
|
|
484
|
+
defaultHook: mockDefaultHook,
|
|
485
|
+
requiredHook: mockRequiredHook,
|
|
486
|
+
},
|
|
487
|
+
};
|
|
488
|
+
const mockIsmWriter = {
|
|
489
|
+
create: sinon
|
|
490
|
+
.stub()
|
|
491
|
+
.callsFake(async () => [mockIsm, [mockReceipt, mockReceipt]]),
|
|
492
|
+
update: sinon.stub(),
|
|
493
|
+
read: sinon.stub(),
|
|
494
|
+
};
|
|
495
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
496
|
+
value: mockIsmWriter,
|
|
497
|
+
writable: true,
|
|
498
|
+
});
|
|
499
|
+
// ACT
|
|
500
|
+
const [, receipts] = await coreWriter.create(artifact);
|
|
501
|
+
// ASSERT
|
|
502
|
+
expect(receipts.length).to.be.greaterThan(0);
|
|
503
|
+
expect(receipts.length).to.be.at.least(4);
|
|
504
|
+
});
|
|
505
|
+
it('should propagate ISM deployment errors', async () => {
|
|
506
|
+
// ARRANGE
|
|
507
|
+
const error = new Error('ISM deployment failed');
|
|
508
|
+
const artifact = {
|
|
509
|
+
artifactState: ArtifactState.NEW,
|
|
510
|
+
config: {
|
|
511
|
+
owner: mockOwner,
|
|
512
|
+
defaultIsm: {
|
|
513
|
+
artifactState: ArtifactState.NEW,
|
|
514
|
+
config: mockIsm.config,
|
|
515
|
+
},
|
|
516
|
+
defaultHook: mockDefaultHook,
|
|
517
|
+
requiredHook: mockRequiredHook,
|
|
518
|
+
},
|
|
519
|
+
};
|
|
520
|
+
const mockIsmWriter = {
|
|
521
|
+
create: sinon.stub().rejects(error),
|
|
522
|
+
update: sinon.stub(),
|
|
523
|
+
read: sinon.stub(),
|
|
524
|
+
};
|
|
525
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
526
|
+
value: mockIsmWriter,
|
|
527
|
+
writable: true,
|
|
528
|
+
});
|
|
529
|
+
// ACT & ASSERT
|
|
530
|
+
await expect(coreWriter.create(artifact)).to.be.rejectedWith('ISM deployment failed');
|
|
531
|
+
});
|
|
532
|
+
it('should propagate mailbox creation errors', async () => {
|
|
533
|
+
// ARRANGE
|
|
534
|
+
const error = new Error('Mailbox creation failed');
|
|
535
|
+
const mockMailboxWriter = {
|
|
536
|
+
create: sinon.stub().rejects(error),
|
|
537
|
+
update: sinon.stub(),
|
|
538
|
+
read: sinon.stub(),
|
|
539
|
+
};
|
|
540
|
+
mailboxArtifactManager.createWriter = sinon
|
|
541
|
+
.stub()
|
|
542
|
+
.returns(mockMailboxWriter);
|
|
543
|
+
const artifact = {
|
|
544
|
+
artifactState: ArtifactState.NEW,
|
|
545
|
+
config: {
|
|
546
|
+
owner: mockOwner,
|
|
547
|
+
defaultIsm: mockIsm,
|
|
548
|
+
defaultHook: mockDefaultHook,
|
|
549
|
+
requiredHook: mockRequiredHook,
|
|
550
|
+
},
|
|
551
|
+
};
|
|
552
|
+
const mockIsmWriter = {
|
|
553
|
+
create: sinon.stub(),
|
|
554
|
+
update: sinon.stub(),
|
|
555
|
+
read: sinon.stub(),
|
|
556
|
+
};
|
|
557
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
558
|
+
value: mockIsmWriter,
|
|
559
|
+
writable: true,
|
|
560
|
+
});
|
|
561
|
+
// ACT & ASSERT
|
|
562
|
+
await expect(coreWriter.create(artifact)).to.be.rejectedWith('Mailbox creation failed');
|
|
563
|
+
});
|
|
564
|
+
});
|
|
565
|
+
describe('update', () => {
|
|
566
|
+
it('should handle ISM type change by deploying new ISM', async () => {
|
|
567
|
+
// ARRANGE
|
|
568
|
+
const currentMailbox = {
|
|
569
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
570
|
+
config: {
|
|
571
|
+
owner: mockOwner,
|
|
572
|
+
defaultIsm: mockIsm,
|
|
573
|
+
defaultHook: mockDefaultHook,
|
|
574
|
+
requiredHook: mockRequiredHook,
|
|
575
|
+
},
|
|
576
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
577
|
+
};
|
|
578
|
+
sinon.stub(coreWriter, 'read').resolves(currentMailbox);
|
|
579
|
+
const newIsm = {
|
|
580
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
581
|
+
config: {
|
|
582
|
+
type: 'messageIdMultisigIsm',
|
|
583
|
+
validators: ['0xVALIDATOR2'],
|
|
584
|
+
threshold: 1,
|
|
585
|
+
},
|
|
586
|
+
deployed: { address: mockNewIsmAddress },
|
|
587
|
+
};
|
|
588
|
+
const expectedArtifact = {
|
|
589
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
590
|
+
config: {
|
|
591
|
+
owner: mockOwner,
|
|
592
|
+
defaultIsm: {
|
|
593
|
+
artifactState: ArtifactState.NEW,
|
|
594
|
+
config: newIsm.config,
|
|
595
|
+
},
|
|
596
|
+
defaultHook: mockDefaultHook,
|
|
597
|
+
requiredHook: mockRequiredHook,
|
|
598
|
+
},
|
|
599
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
600
|
+
};
|
|
601
|
+
const ismCreateStub = sinon
|
|
602
|
+
.stub()
|
|
603
|
+
.callsFake(async () => [newIsm, [mockReceipt]]);
|
|
604
|
+
const mockIsmWriter = {
|
|
605
|
+
create: ismCreateStub,
|
|
606
|
+
update: sinon.stub(),
|
|
607
|
+
read: sinon.stub(),
|
|
608
|
+
};
|
|
609
|
+
mockIsmArtifactManager.createWriter = sinon.stub().returns(mockIsmWriter);
|
|
610
|
+
const mockHookWriter = {
|
|
611
|
+
create: sinon.stub(),
|
|
612
|
+
update: sinon.stub().resolves([]),
|
|
613
|
+
read: sinon.stub(),
|
|
614
|
+
};
|
|
615
|
+
mockHookArtifactManager.createWriter = sinon
|
|
616
|
+
.stub()
|
|
617
|
+
.returns(mockHookWriter);
|
|
618
|
+
// ACT
|
|
619
|
+
await coreWriter.update(expectedArtifact);
|
|
620
|
+
// ASSERT
|
|
621
|
+
sinon.assert.calledOnce(ismCreateStub);
|
|
622
|
+
const createArg = ismCreateStub.firstCall.args[0];
|
|
623
|
+
expect(createArg.artifactState).to.equal(ArtifactState.NEW);
|
|
624
|
+
expect(createArg.config.type).to.equal('messageIdMultisigIsm');
|
|
625
|
+
});
|
|
626
|
+
it('should handle UNDERIVED ISM by using address as-is', async () => {
|
|
627
|
+
// ARRANGE
|
|
628
|
+
const currentMailbox = {
|
|
629
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
630
|
+
config: {
|
|
631
|
+
owner: mockOwner,
|
|
632
|
+
defaultIsm: mockIsm,
|
|
633
|
+
defaultHook: mockDefaultHook,
|
|
634
|
+
requiredHook: mockRequiredHook,
|
|
635
|
+
},
|
|
636
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
637
|
+
};
|
|
638
|
+
sinon.stub(coreWriter, 'read').resolves(currentMailbox);
|
|
639
|
+
const expectedArtifact = {
|
|
640
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
641
|
+
config: {
|
|
642
|
+
owner: mockOwner,
|
|
643
|
+
defaultIsm: {
|
|
644
|
+
artifactState: ArtifactState.UNDERIVED,
|
|
645
|
+
deployed: { address: mockIsmAddress },
|
|
646
|
+
},
|
|
647
|
+
defaultHook: mockDefaultHook,
|
|
648
|
+
requiredHook: mockRequiredHook,
|
|
649
|
+
},
|
|
650
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
651
|
+
};
|
|
652
|
+
const ismCreateStub = sinon.stub();
|
|
653
|
+
const ismUpdateStub = sinon.stub();
|
|
654
|
+
const mockIsmWriter = {
|
|
655
|
+
create: ismCreateStub,
|
|
656
|
+
update: ismUpdateStub,
|
|
657
|
+
read: sinon.stub(),
|
|
658
|
+
};
|
|
659
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
660
|
+
value: mockIsmWriter,
|
|
661
|
+
writable: true,
|
|
662
|
+
});
|
|
663
|
+
const mockHookWriter = {
|
|
664
|
+
create: sinon.stub(),
|
|
665
|
+
update: sinon.stub().resolves([]),
|
|
666
|
+
read: sinon.stub(),
|
|
667
|
+
};
|
|
668
|
+
mockHookArtifactManager.createWriter = sinon
|
|
669
|
+
.stub()
|
|
670
|
+
.returns(mockHookWriter);
|
|
671
|
+
// ACT
|
|
672
|
+
await coreWriter.update(expectedArtifact);
|
|
673
|
+
// ASSERT
|
|
674
|
+
sinon.assert.notCalled(ismCreateStub);
|
|
675
|
+
sinon.assert.notCalled(ismUpdateStub);
|
|
676
|
+
});
|
|
677
|
+
it('should return empty array when no updates needed', async () => {
|
|
678
|
+
// ARRANGE
|
|
679
|
+
const currentMailbox = {
|
|
680
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
681
|
+
config: {
|
|
682
|
+
owner: mockOwner,
|
|
683
|
+
defaultIsm: mockIsm,
|
|
684
|
+
defaultHook: mockDefaultHook,
|
|
685
|
+
requiredHook: mockRequiredHook,
|
|
686
|
+
},
|
|
687
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
688
|
+
};
|
|
689
|
+
sinon.stub(coreWriter, 'read').resolves(currentMailbox);
|
|
690
|
+
const expectedArtifact = {
|
|
691
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
692
|
+
config: currentMailbox.config,
|
|
693
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
694
|
+
};
|
|
695
|
+
const mockIsmWriter = {
|
|
696
|
+
create: sinon.stub(),
|
|
697
|
+
update: sinon.stub().resolves([]),
|
|
698
|
+
read: sinon.stub(),
|
|
699
|
+
};
|
|
700
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
701
|
+
value: mockIsmWriter,
|
|
702
|
+
writable: true,
|
|
703
|
+
});
|
|
704
|
+
const mockHookWriter = {
|
|
705
|
+
create: sinon.stub(),
|
|
706
|
+
update: sinon.stub().resolves([]),
|
|
707
|
+
read: sinon.stub(),
|
|
708
|
+
};
|
|
709
|
+
mockHookArtifactManager.createWriter = sinon
|
|
710
|
+
.stub()
|
|
711
|
+
.returns(mockHookWriter);
|
|
712
|
+
// ACT
|
|
713
|
+
const result = await coreWriter.update(expectedArtifact);
|
|
714
|
+
// ASSERT
|
|
715
|
+
expect(result).to.be.an('array').with.lengthOf(0);
|
|
716
|
+
});
|
|
717
|
+
it('should deploy NEW ISM when current is zero-address UNDERIVED', async () => {
|
|
718
|
+
// ARRANGE
|
|
719
|
+
const currentMailbox = {
|
|
720
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
721
|
+
config: {
|
|
722
|
+
owner: mockOwner,
|
|
723
|
+
defaultIsm: {
|
|
724
|
+
artifactState: ArtifactState.UNDERIVED,
|
|
725
|
+
deployed: { address: ZERO_ADDRESS_HEX_32 },
|
|
726
|
+
},
|
|
727
|
+
defaultHook: mockDefaultHook,
|
|
728
|
+
requiredHook: mockRequiredHook,
|
|
729
|
+
},
|
|
730
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
731
|
+
};
|
|
732
|
+
sinon.stub(coreWriter, 'read').resolves(currentMailbox);
|
|
733
|
+
const newIsm = {
|
|
734
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
735
|
+
config: {
|
|
736
|
+
type: 'merkleRootMultisigIsm',
|
|
737
|
+
validators: ['0xVALIDATOR1'],
|
|
738
|
+
threshold: 1,
|
|
739
|
+
},
|
|
740
|
+
deployed: { address: mockNewIsmAddress },
|
|
741
|
+
};
|
|
742
|
+
const expectedArtifact = {
|
|
743
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
744
|
+
config: {
|
|
745
|
+
owner: mockOwner,
|
|
746
|
+
defaultIsm: {
|
|
747
|
+
artifactState: ArtifactState.NEW,
|
|
748
|
+
config: newIsm.config,
|
|
749
|
+
},
|
|
750
|
+
defaultHook: mockDefaultHook,
|
|
751
|
+
requiredHook: mockRequiredHook,
|
|
752
|
+
},
|
|
753
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
754
|
+
};
|
|
755
|
+
const ismCreateStub = sinon
|
|
756
|
+
.stub()
|
|
757
|
+
.callsFake(async () => [newIsm, [mockReceipt]]);
|
|
758
|
+
const mockIsmWriter = {
|
|
759
|
+
create: ismCreateStub,
|
|
760
|
+
update: sinon.stub(),
|
|
761
|
+
read: sinon.stub(),
|
|
762
|
+
};
|
|
763
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
764
|
+
value: mockIsmWriter,
|
|
765
|
+
writable: true,
|
|
766
|
+
});
|
|
767
|
+
const mockHookWriter = {
|
|
768
|
+
create: sinon.stub(),
|
|
769
|
+
update: sinon.stub().resolves([]),
|
|
770
|
+
read: sinon.stub(),
|
|
771
|
+
};
|
|
772
|
+
mockHookArtifactManager.createWriter = sinon
|
|
773
|
+
.stub()
|
|
774
|
+
.returns(mockHookWriter);
|
|
775
|
+
// ACT
|
|
776
|
+
const result = await coreWriter.update(expectedArtifact);
|
|
777
|
+
// ASSERT
|
|
778
|
+
sinon.assert.calledOnce(ismCreateStub);
|
|
779
|
+
expect(result).to.be.an('array');
|
|
780
|
+
});
|
|
781
|
+
it('should assert artifacts are expanded before updating', async () => {
|
|
782
|
+
// ARRANGE
|
|
783
|
+
const currentMailbox = {
|
|
784
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
785
|
+
config: {
|
|
786
|
+
owner: mockOwner,
|
|
787
|
+
defaultIsm: {
|
|
788
|
+
artifactState: ArtifactState.UNDERIVED,
|
|
789
|
+
deployed: { address: mockIsmAddress },
|
|
790
|
+
},
|
|
791
|
+
defaultHook: mockDefaultHook,
|
|
792
|
+
requiredHook: mockRequiredHook,
|
|
793
|
+
},
|
|
794
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
795
|
+
};
|
|
796
|
+
sinon.stub(coreWriter, 'read').resolves(currentMailbox);
|
|
797
|
+
const expectedArtifact = {
|
|
798
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
799
|
+
config: {
|
|
800
|
+
owner: mockOwner,
|
|
801
|
+
defaultIsm: mockIsm,
|
|
802
|
+
defaultHook: mockDefaultHook,
|
|
803
|
+
requiredHook: mockRequiredHook,
|
|
804
|
+
},
|
|
805
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
806
|
+
};
|
|
807
|
+
// ACT & ASSERT
|
|
808
|
+
await expect(coreWriter.update(expectedArtifact)).to.be.rejectedWith('Expected defaultIsm to be DEPLOYED or UNDERIVED with zero address');
|
|
809
|
+
});
|
|
810
|
+
it('should deploy NEW hook during update', async () => {
|
|
811
|
+
// ARRANGE
|
|
812
|
+
const currentMailbox = {
|
|
813
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
814
|
+
config: {
|
|
815
|
+
owner: mockOwner,
|
|
816
|
+
defaultIsm: mockIsm,
|
|
817
|
+
defaultHook: {
|
|
818
|
+
artifactState: ArtifactState.UNDERIVED,
|
|
819
|
+
deployed: { address: ZERO_ADDRESS_HEX_32 },
|
|
820
|
+
},
|
|
821
|
+
requiredHook: mockRequiredHook,
|
|
822
|
+
},
|
|
823
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
824
|
+
};
|
|
825
|
+
sinon.stub(coreWriter, 'read').resolves(currentMailbox);
|
|
826
|
+
const newDefaultHook = {
|
|
827
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
828
|
+
config: { type: 'merkleTreeHook' },
|
|
829
|
+
deployed: { address: mockDefaultHookAddress },
|
|
830
|
+
};
|
|
831
|
+
const expectedArtifact = {
|
|
832
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
833
|
+
config: {
|
|
834
|
+
owner: mockOwner,
|
|
835
|
+
defaultIsm: mockIsm,
|
|
836
|
+
defaultHook: {
|
|
837
|
+
artifactState: ArtifactState.NEW,
|
|
838
|
+
config: newDefaultHook.config,
|
|
839
|
+
},
|
|
840
|
+
requiredHook: mockRequiredHook,
|
|
841
|
+
},
|
|
842
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
843
|
+
};
|
|
844
|
+
const mockIsmWriter = {
|
|
845
|
+
create: sinon.stub(),
|
|
846
|
+
update: sinon.stub().resolves([]),
|
|
847
|
+
read: sinon.stub(),
|
|
848
|
+
};
|
|
849
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
850
|
+
value: mockIsmWriter,
|
|
851
|
+
writable: true,
|
|
852
|
+
});
|
|
853
|
+
const hookCreateStub = sinon
|
|
854
|
+
.stub()
|
|
855
|
+
.callsFake(async () => [newDefaultHook, [mockReceipt]]);
|
|
856
|
+
const mockHookWriter = {
|
|
857
|
+
create: hookCreateStub,
|
|
858
|
+
update: sinon.stub().resolves([]),
|
|
859
|
+
read: sinon.stub(),
|
|
860
|
+
};
|
|
861
|
+
mockHookArtifactManager.createWriter = sinon
|
|
862
|
+
.stub()
|
|
863
|
+
.returns(mockHookWriter);
|
|
864
|
+
// ACT
|
|
865
|
+
await coreWriter.update(expectedArtifact);
|
|
866
|
+
// ASSERT
|
|
867
|
+
sinon.assert.calledOnce(hookCreateStub);
|
|
868
|
+
});
|
|
869
|
+
it('should handle owner change', async () => {
|
|
870
|
+
// ARRANGE
|
|
871
|
+
const newOwner = '0xNEWOWNER';
|
|
872
|
+
const currentMailbox = {
|
|
873
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
874
|
+
config: {
|
|
875
|
+
owner: mockOwner,
|
|
876
|
+
defaultIsm: mockIsm,
|
|
877
|
+
defaultHook: mockDefaultHook,
|
|
878
|
+
requiredHook: mockRequiredHook,
|
|
879
|
+
},
|
|
880
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
881
|
+
};
|
|
882
|
+
sinon.stub(coreWriter, 'read').resolves(currentMailbox);
|
|
883
|
+
const expectedArtifact = {
|
|
884
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
885
|
+
config: {
|
|
886
|
+
owner: newOwner,
|
|
887
|
+
defaultIsm: mockIsm,
|
|
888
|
+
defaultHook: mockDefaultHook,
|
|
889
|
+
requiredHook: mockRequiredHook,
|
|
890
|
+
},
|
|
891
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
892
|
+
};
|
|
893
|
+
const mockIsmWriter = {
|
|
894
|
+
create: sinon.stub(),
|
|
895
|
+
update: sinon.stub().resolves([]),
|
|
896
|
+
read: sinon.stub(),
|
|
897
|
+
};
|
|
898
|
+
Object.defineProperty(coreWriter, 'ismWriter', {
|
|
899
|
+
value: mockIsmWriter,
|
|
900
|
+
writable: true,
|
|
901
|
+
});
|
|
902
|
+
const mockHookWriter = {
|
|
903
|
+
create: sinon.stub(),
|
|
904
|
+
update: sinon.stub().resolves([]),
|
|
905
|
+
read: sinon.stub(),
|
|
906
|
+
};
|
|
907
|
+
mockHookArtifactManager.createWriter = sinon
|
|
908
|
+
.stub()
|
|
909
|
+
.returns(mockHookWriter);
|
|
910
|
+
// ACT
|
|
911
|
+
await coreWriter.update(expectedArtifact);
|
|
912
|
+
// ASSERT
|
|
913
|
+
const mailboxWriter = createMailboxWriterStub.returnValues[0];
|
|
914
|
+
const updatedArtifact = mailboxWriter.update.firstCall.args[0];
|
|
915
|
+
expect(updatedArtifact.config.owner).to.equal(newOwner);
|
|
916
|
+
});
|
|
917
|
+
it('should wire correct addresses into mailbox update', async () => {
|
|
918
|
+
// ARRANGE
|
|
919
|
+
const newIsm = {
|
|
920
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
921
|
+
config: {
|
|
922
|
+
type: 'messageIdMultisigIsm',
|
|
923
|
+
validators: ['0xVALIDATOR2'],
|
|
924
|
+
threshold: 1,
|
|
925
|
+
},
|
|
926
|
+
deployed: { address: mockNewIsmAddress },
|
|
927
|
+
};
|
|
928
|
+
const currentMailbox = {
|
|
929
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
930
|
+
config: {
|
|
931
|
+
owner: mockOwner,
|
|
932
|
+
defaultIsm: mockIsm,
|
|
933
|
+
defaultHook: mockDefaultHook,
|
|
934
|
+
requiredHook: mockRequiredHook,
|
|
935
|
+
},
|
|
936
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
937
|
+
};
|
|
938
|
+
sinon.stub(coreWriter, 'read').resolves(currentMailbox);
|
|
939
|
+
const expectedArtifact = {
|
|
940
|
+
artifactState: ArtifactState.DEPLOYED,
|
|
941
|
+
config: {
|
|
942
|
+
owner: mockOwner,
|
|
943
|
+
defaultIsm: {
|
|
944
|
+
artifactState: ArtifactState.NEW,
|
|
945
|
+
config: newIsm.config,
|
|
946
|
+
},
|
|
947
|
+
defaultHook: mockDefaultHook,
|
|
948
|
+
requiredHook: mockRequiredHook,
|
|
949
|
+
},
|
|
950
|
+
deployed: { address: mockMailboxAddress, domainId: mockDomainId },
|
|
951
|
+
};
|
|
952
|
+
const ismCreateStub = sinon
|
|
953
|
+
.stub()
|
|
954
|
+
.callsFake(async () => [newIsm, [mockReceipt]]);
|
|
955
|
+
const mockIsmWriter = {
|
|
956
|
+
create: ismCreateStub,
|
|
957
|
+
update: sinon.stub(),
|
|
958
|
+
read: sinon.stub(),
|
|
959
|
+
};
|
|
960
|
+
mockIsmArtifactManager.createWriter = sinon.stub().returns(mockIsmWriter);
|
|
961
|
+
const mockHookWriter = {
|
|
962
|
+
create: sinon.stub(),
|
|
963
|
+
update: sinon.stub().resolves([]),
|
|
964
|
+
read: sinon.stub(),
|
|
965
|
+
};
|
|
966
|
+
mockHookArtifactManager.createWriter = sinon
|
|
967
|
+
.stub()
|
|
968
|
+
.returns(mockHookWriter);
|
|
969
|
+
// ACT
|
|
970
|
+
await coreWriter.update(expectedArtifact);
|
|
971
|
+
// ASSERT
|
|
972
|
+
const mailboxWriter = createMailboxWriterStub.returnValues[0];
|
|
973
|
+
const updatedArtifact = mailboxWriter.update.firstCall.args[0];
|
|
974
|
+
expect(updatedArtifact.config.defaultIsm.deployed.address).to.equal(mockNewIsmAddress);
|
|
975
|
+
expect(updatedArtifact.config.defaultHook.deployed.address).to.equal(mockDefaultHookAddress);
|
|
976
|
+
expect(updatedArtifact.config.requiredHook.deployed.address).to.equal(mockRequiredHookAddress);
|
|
977
|
+
});
|
|
978
|
+
});
|
|
979
|
+
});
|
|
980
|
+
//# sourceMappingURL=core-writer.test.js.map
|