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.
150 lines
4.3 KiB
150 lines
4.3 KiB
3 years ago
|
import { ethers, abacus } from 'hardhat';
|
||
|
import { expect } from 'chai';
|
||
|
|
||
|
import { AbacusState, Validator } from './lib/core';
|
||
|
import { Signer } from './lib/types';
|
||
|
|
||
|
import {
|
||
|
Home__factory,
|
||
|
Home,
|
||
|
ValidatorManager__factory,
|
||
|
ValidatorManager,
|
||
|
} from '../typechain';
|
||
|
|
||
|
const homeDomainHashCases = require('../../../vectors/homeDomainHash.json');
|
||
|
const localDomain = 1000;
|
||
|
|
||
|
describe('ValidatorManager', async () => {
|
||
|
let signer: Signer,
|
||
|
fakeSigner: Signer,
|
||
|
validatorManager: ValidatorManager,
|
||
|
validator: Validator,
|
||
|
fakeValidator: Validator;
|
||
|
|
||
|
before(async () => {
|
||
|
[signer, fakeSigner] = await ethers.getSigners();
|
||
|
validator = await Validator.fromSigner(signer, localDomain);
|
||
|
fakeValidator = await Validator.fromSigner(fakeSigner, localDomain);
|
||
|
});
|
||
|
|
||
|
beforeEach(async () => {
|
||
|
const validatorManagerFactory = new ValidatorManager__factory(signer);
|
||
|
validatorManager = await validatorManagerFactory.deploy();
|
||
|
await validatorManager.setValidator(localDomain, validator.address);
|
||
|
});
|
||
|
|
||
|
it('Accepts validator signature', async () => {
|
||
|
const root = ethers.utils.formatBytes32String('root');
|
||
|
const index = 1;
|
||
|
|
||
|
const { signature } = await validator.signCheckpoint(root, index);
|
||
|
const isValid = await validatorManager.isValidatorSignature(
|
||
|
localDomain,
|
||
|
root,
|
||
|
index,
|
||
|
signature,
|
||
|
);
|
||
|
expect(isValid).to.be.true;
|
||
|
});
|
||
|
|
||
|
it('Rejects non-validator signature', async () => {
|
||
|
const root = ethers.utils.formatBytes32String('root');
|
||
|
const index = 1;
|
||
|
|
||
|
const { signature } = await fakeValidator.signCheckpoint(root, index);
|
||
|
const isValid = await validatorManager.isValidatorSignature(
|
||
|
localDomain,
|
||
|
root,
|
||
|
index,
|
||
|
signature,
|
||
|
);
|
||
|
expect(isValid).to.be.false;
|
||
|
});
|
||
|
|
||
|
it('Calculated domain hash matches Rust-produced domain hash', async () => {
|
||
|
// Compare Rust output in json file to solidity output (json file matches
|
||
|
// hash for local domain of 1000)
|
||
|
for (let testCase of homeDomainHashCases) {
|
||
|
const { expectedDomainHash } = testCase;
|
||
|
const domainHash = await validatorManager.domainHash(testCase.homeDomain);
|
||
|
expect(domainHash).to.equal(expectedDomainHash);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
describe('improper checkpoints', async () => {
|
||
|
let home: Home;
|
||
|
beforeEach(async () => {
|
||
|
const homeFactory = new Home__factory(signer);
|
||
|
home = await homeFactory.deploy(localDomain);
|
||
|
await home.initialize(validatorManager.address);
|
||
|
});
|
||
|
|
||
|
it('Accepts improper checkpoint from validator', async () => {
|
||
|
const root = ethers.utils.formatBytes32String('root');
|
||
|
const index = 1;
|
||
|
|
||
|
const { signature } = await validator.signCheckpoint(root, index);
|
||
|
// Send message with signer address as msg.sender
|
||
|
await expect(
|
||
|
validatorManager.improperCheckpoint(
|
||
|
home.address,
|
||
|
root,
|
||
|
index,
|
||
|
signature,
|
||
|
),
|
||
|
)
|
||
|
.to.emit(validatorManager, 'ImproperCheckpoint')
|
||
|
.withArgs(
|
||
|
home.address,
|
||
|
localDomain,
|
||
|
validator.address,
|
||
|
root,
|
||
|
index,
|
||
|
signature,
|
||
|
);
|
||
|
expect(await home.state()).to.equal(AbacusState.FAILED);
|
||
|
});
|
||
|
|
||
|
it('Rejects improper checkpoint from non-validator', async () => {
|
||
|
const root = ethers.utils.formatBytes32String('root');
|
||
|
const index = 1;
|
||
|
|
||
|
const { signature } = await fakeValidator.signCheckpoint(root, index);
|
||
|
// Send message with signer address as msg.sender
|
||
|
await expect(
|
||
|
validatorManager.improperCheckpoint(
|
||
|
home.address,
|
||
|
root,
|
||
|
index,
|
||
|
signature,
|
||
|
),
|
||
|
).to.be.revertedWith('!validator sig');
|
||
|
});
|
||
|
|
||
|
it('Rejects proper checkpoint from validator', async () => {
|
||
|
const message = `0x${Buffer.alloc(10).toString('hex')}`;
|
||
|
await home.dispatch(
|
||
|
localDomain,
|
||
|
abacus.ethersAddressToBytes32(signer.address),
|
||
|
message,
|
||
|
);
|
||
|
await home.checkpoint();
|
||
|
const [root, index] = await home.latestCheckpoint();
|
||
|
|
||
|
const { signature } = await validator.signCheckpoint(
|
||
|
root,
|
||
|
index.toNumber(),
|
||
|
);
|
||
|
// Send message with signer address as msg.sender
|
||
|
await expect(
|
||
|
validatorManager.improperCheckpoint(
|
||
|
home.address,
|
||
|
root,
|
||
|
index,
|
||
|
signature,
|
||
|
),
|
||
|
).to.be.revertedWith('!improper');
|
||
|
});
|
||
|
});
|
||
|
});
|