The home for Hyperlane core contracts, sdk packages, and other infrastructure
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.
 
 
 
 
 
 
hyperlane-monorepo/solidity/abacus-core/test/common.test.ts

136 lines
4.3 KiB

import { ethers } from 'hardhat';
import { expect } from 'chai';
import { AbacusState, Updater } from './lib/core';
import { Signer } from './lib/types';
import { TestCommon__factory, TestCommon } from '../typechain';
const signedUpdateTestCases = require('../../../vectors/signedUpdate.json');
const localDomain = 1000;
describe('Common', async () => {
let signer: Signer,
fakeSigner: Signer,
common: TestCommon,
updater: Updater,
fakeUpdater: Updater;
before(async () => {
[signer, fakeSigner] = await ethers.getSigners();
updater = await Updater.fromSigner(signer, localDomain);
fakeUpdater = await Updater.fromSigner(fakeSigner, localDomain);
});
beforeEach(async () => {
const commonFactory = new TestCommon__factory(signer);
common = await commonFactory.deploy(localDomain, updater.address);
});
it('Accepts updater signature', async () => {
const oldRoot = ethers.utils.formatBytes32String('old root');
const newRoot = ethers.utils.formatBytes32String('new root');
const { signature } = await updater.signUpdate(oldRoot, newRoot);
const isValid = await common.testIsUpdaterSignature(
oldRoot,
newRoot,
signature,
);
expect(isValid).to.be.true;
});
it('Rejects non-updater signature', async () => {
const oldRoot = ethers.utils.formatBytes32String('old root');
const newRoot = ethers.utils.formatBytes32String('new root');
const { signature: fakeSignature } = await fakeUpdater.signUpdate(
oldRoot,
newRoot,
);
expect(await common.testIsUpdaterSignature(oldRoot, newRoot, fakeSignature))
.to.be.false;
});
it('Fails on valid double update proof', async () => {
const oldRoot = ethers.utils.formatBytes32String('old root');
const newRoot = ethers.utils.formatBytes32String('new root 1');
const newRoot2 = ethers.utils.formatBytes32String('new root 2');
const { signature } = await updater.signUpdate(oldRoot, newRoot);
const { signature: signature2 } = await updater.signUpdate(
oldRoot,
newRoot2,
);
await expect(
common.doubleUpdate(oldRoot, [newRoot, newRoot2], signature, signature2),
).to.emit(common, 'DoubleUpdate');
expect(await common.state()).to.equal(AbacusState.FAILED);
});
it('Does not fail contract on invalid double update proof', async () => {
const oldRoot = ethers.utils.formatBytes32String('old root');
const newRoot = ethers.utils.formatBytes32String('new root');
const { signature } = await updater.signUpdate(oldRoot, newRoot);
// Double update proof uses same roots and signatures
await common.doubleUpdate(
oldRoot,
[newRoot, newRoot],
signature,
signature,
);
// State should not be failed because double update proof does not
// demonstrate fraud
const state = await common.state();
expect(state).not.to.equal(AbacusState.FAILED);
expect(state).to.equal(AbacusState.ACTIVE);
});
it('Does not fail on double update after updater rotation', async () => {
const oldRoot = ethers.utils.formatBytes32String('old root');
const newRoot = ethers.utils.formatBytes32String('new root 1');
const newRoot2 = ethers.utils.formatBytes32String('new root 2');
const { signature } = await updater.signUpdate(oldRoot, newRoot);
const { signature: signature2 } = await updater.signUpdate(
oldRoot,
newRoot2,
);
await common.setUpdater(fakeUpdater.address);
await common.doubleUpdate(
oldRoot,
[newRoot, newRoot2],
signature,
signature2,
);
// State should not be failed because double update proof does not
// use current updater.
const state = await common.state();
expect(state).not.to.equal(AbacusState.FAILED);
expect(state).to.equal(AbacusState.ACTIVE);
});
it('Checks Rust-produced SignedUpdate', async () => {
// Compare Rust output in json file to solidity output
for (let testCase of signedUpdateTestCases) {
const { oldRoot, newRoot, signature, signer } = testCase;
const signerAddress = ethers.utils.getAddress(signer);
await common.setUpdater(signerAddress);
expect(
await common.testIsUpdaterSignature(
oldRoot,
newRoot,
ethers.utils.joinSignature(signature),
),
).to.be.true;
}
});
});