You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.9 KiB
131 lines
3.9 KiB
3 years ago
|
import { ethers, abacus } from 'hardhat';
|
||
3 years ago
|
import { expect } from 'chai';
|
||
3 years ago
|
import { AbacusState, Validator } from './lib/core';
|
||
3 years ago
|
import { Signer } from './lib/types';
|
||
3 years ago
|
|
||
3 years ago
|
import { TestOutbox, TestOutbox__factory } from '../typechain';
|
||
3 years ago
|
|
||
3 years ago
|
const destinationNonceTestCases = require('../../../vectors/destinationNonce.json');
|
||
4 years ago
|
|
||
4 years ago
|
const localDomain = 1000;
|
||
4 years ago
|
const destDomain = 2000;
|
||
3 years ago
|
const nullAddress: string = '0x' + '00'.repeat(32);
|
||
4 years ago
|
|
||
3 years ago
|
describe('Outbox', async () => {
|
||
|
let outbox: TestOutbox, signer: Signer, recipient: Signer;
|
||
4 years ago
|
|
||
|
before(async () => {
|
||
3 years ago
|
[signer, recipient] = await ethers.getSigners();
|
||
4 years ago
|
});
|
||
|
|
||
|
beforeEach(async () => {
|
||
3 years ago
|
// redeploy the outbox before each test run
|
||
|
const outboxFactory = new TestOutbox__factory(signer);
|
||
|
outbox = await outboxFactory.deploy(localDomain);
|
||
3 years ago
|
// The ValidatorManager is unused in these tests *but* needs to be a
|
||
|
// contract.
|
||
3 years ago
|
await outbox.initialize(outbox.address);
|
||
4 years ago
|
});
|
||
|
|
||
4 years ago
|
it('Cannot be initialized twice', async () => {
|
||
3 years ago
|
await expect(outbox.initialize(outbox.address)).to.be.revertedWith(
|
||
3 years ago
|
'Initializable: contract is already initialized',
|
||
|
);
|
||
4 years ago
|
});
|
||
|
|
||
3 years ago
|
it('ValidatorManager can fail', async () => {
|
||
3 years ago
|
await outbox.testSetValidatorManager(signer.address);
|
||
|
await outbox.fail();
|
||
|
expect(await outbox.state()).to.equal(AbacusState.FAILED);
|
||
4 years ago
|
|
||
|
const message = ethers.utils.formatBytes32String('message');
|
||
|
await expect(
|
||
3 years ago
|
outbox.dispatch(
|
||
4 years ago
|
destDomain,
|
||
3 years ago
|
abacus.ethersAddressToBytes32(recipient.address),
|
||
4 years ago
|
message,
|
||
|
),
|
||
4 years ago
|
).to.be.revertedWith('failed state');
|
||
|
});
|
||
|
|
||
3 years ago
|
it('Non ValidatorManager cannot fail', async () => {
|
||
3 years ago
|
await expect(outbox.connect(recipient).fail()).to.be.revertedWith(
|
||
3 years ago
|
'!validatorManager',
|
||
|
);
|
||
4 years ago
|
});
|
||
|
|
||
3 years ago
|
it('Does not dispatch too large messages', async () => {
|
||
4 years ago
|
const message = `0x${Buffer.alloc(3000).toString('hex')}`;
|
||
|
await expect(
|
||
3 years ago
|
outbox.dispatch(
|
||
3 years ago
|
destDomain,
|
||
|
abacus.ethersAddressToBytes32(recipient.address),
|
||
|
message,
|
||
|
),
|
||
3 years ago
|
).to.be.revertedWith('msg too long');
|
||
4 years ago
|
});
|
||
|
|
||
3 years ago
|
it('Dispatches a message', async () => {
|
||
4 years ago
|
const message = ethers.utils.formatBytes32String('message');
|
||
3 years ago
|
const nonce = await outbox.nonces(localDomain);
|
||
4 years ago
|
|
||
|
// Format data that will be emitted from Dispatch event
|
||
3 years ago
|
const destinationAndNonce = abacus.destinationAndNonce(destDomain, nonce);
|
||
4 years ago
|
|
||
3 years ago
|
const abacusMessage = abacus.formatMessage(
|
||
4 years ago
|
localDomain,
|
||
4 years ago
|
signer.address,
|
||
3 years ago
|
nonce,
|
||
4 years ago
|
destDomain,
|
||
|
recipient.address,
|
||
|
message,
|
||
|
);
|
||
3 years ago
|
const messageHash = abacus.messageHash(abacusMessage);
|
||
3 years ago
|
const leafIndex = await outbox.tree();
|
||
|
const [checkpointedRoot] = await outbox.latestCheckpoint();
|
||
4 years ago
|
|
||
|
// Send message with signer address as msg.sender
|
||
|
await expect(
|
||
3 years ago
|
outbox
|
||
4 years ago
|
.connect(signer)
|
||
3 years ago
|
.dispatch(
|
||
4 years ago
|
destDomain,
|
||
3 years ago
|
abacus.ethersAddressToBytes32(recipient.address),
|
||
4 years ago
|
message,
|
||
|
),
|
||
|
)
|
||
3 years ago
|
.to.emit(outbox, 'Dispatch')
|
||
3 years ago
|
.withArgs(
|
||
3 years ago
|
messageHash,
|
||
3 years ago
|
leafIndex,
|
||
3 years ago
|
destinationAndNonce,
|
||
3 years ago
|
checkpointedRoot,
|
||
3 years ago
|
abacusMessage,
|
||
3 years ago
|
);
|
||
4 years ago
|
});
|
||
|
|
||
3 years ago
|
it('Checkpoints the latest root', async () => {
|
||
4 years ago
|
const message = ethers.utils.formatBytes32String('message');
|
||
3 years ago
|
await outbox.dispatch(
|
||
4 years ago
|
destDomain,
|
||
3 years ago
|
abacus.ethersAddressToBytes32(recipient.address),
|
||
4 years ago
|
message,
|
||
|
);
|
||
3 years ago
|
await outbox.checkpoint();
|
||
|
const [root, index] = await outbox.latestCheckpoint();
|
||
3 years ago
|
expect(root).to.not.equal(nullAddress);
|
||
|
expect(index).to.equal(1);
|
||
4 years ago
|
});
|
||
4 years ago
|
|
||
3 years ago
|
it('Correctly calculates destinationAndNonce', async () => {
|
||
|
for (let testCase of destinationNonceTestCases) {
|
||
|
let { destination, nonce, expectedDestinationAndNonce } = testCase;
|
||
3 years ago
|
const solidityDestinationAndNonce = await outbox.destinationAndNonce(
|
||
3 years ago
|
destination,
|
||
|
nonce,
|
||
4 years ago
|
);
|
||
3 years ago
|
expect(solidityDestinationAndNonce).to.equal(expectedDestinationAndNonce);
|
||
4 years ago
|
}
|
||
|
});
|
||
4 years ago
|
});
|