rm validatorManager test, rm unused AbacusDeployment

pull/334/head
Trevor Porter 3 years ago
parent e1d5133ae6
commit ebadcefcd2
  1. 198
      solidity/core/test/lib/AbacusDeployment.ts
  2. 150
      solidity/core/test/validatorManager.test.ts

@ -1,198 +0,0 @@
import { assert } from 'chai';
import * as ethers from 'ethers';
import { types, Validator } from '@abacus-network/utils';
import {
TestOutbox,
TestOutbox__factory,
ValidatorManager,
ValidatorManager__factory,
UpgradeBeaconController,
UpgradeBeaconController__factory,
XAppConnectionManager,
XAppConnectionManager__factory,
TestInbox,
TestInbox__factory,
} from '../../types';
export interface AbacusInstance {
domain: types.Domain;
validator: Validator;
validatorManager: ValidatorManager;
outbox: TestOutbox;
connectionManager: XAppConnectionManager;
ubc: UpgradeBeaconController;
inboxs: Record<number, TestInbox>;
}
export class AbacusDeployment {
constructor(
public readonly domains: types.Domain[],
public readonly instances: Record<number, AbacusInstance>,
public readonly signer: ethers.Signer,
) {}
static async fromDomains(domains: types.Domain[], signer: ethers.Signer) {
const instances: Record<number, AbacusInstance> = {};
for (const local of domains) {
const instance = await AbacusDeployment.deployInstance(
local,
domains.filter((d) => d !== local),
signer,
);
instances[local] = instance;
}
return new AbacusDeployment(domains, instances, signer);
}
static async deployInstance(
local: types.Domain,
remotes: types.Domain[],
signer: ethers.Signer,
): Promise<AbacusInstance> {
const validatorManagerFactory = new ValidatorManager__factory(signer);
const validatorManager = await validatorManagerFactory.deploy();
await validatorManager.enrollValidator(local, await signer.getAddress());
await Promise.all(
remotes.map(async (remoteDomain) =>
validatorManager.enrollValidator(
remoteDomain,
await signer.getAddress(),
),
),
);
const ubcFactory = new UpgradeBeaconController__factory(signer);
const ubc = await ubcFactory.deploy();
const outboxFactory = new TestOutbox__factory(signer);
const outbox = await outboxFactory.deploy(local);
await outbox.initialize(validatorManager.address);
const connectionManagerFactory = new XAppConnectionManager__factory(signer);
const connectionManager = await connectionManagerFactory.deploy();
await connectionManager.setOutbox(outbox.address);
const inboxFactory = new TestInbox__factory(signer);
const inboxs: Record<number, TestInbox> = {};
const deploys = remotes.map(async (remoteDomain) => {
const inbox = await inboxFactory.deploy(local);
await inbox.initialize(
remoteDomain,
validatorManager.address,
ethers.constants.HashZero,
0,
);
await connectionManager.enrollInbox(remoteDomain, inbox.address);
inboxs[remoteDomain] = inbox;
});
await Promise.all(deploys);
return {
domain: local,
validator: await Validator.fromSigner(signer, local),
outbox,
connectionManager,
validatorManager,
inboxs,
ubc,
};
}
async transferOwnership(domain: types.Domain, address: types.Address) {
await this.outbox(domain).transferOwnership(address);
await this.ubc(domain).transferOwnership(address);
await this.connectionManager(domain).transferOwnership(address);
await this.validatorManager(domain).transferOwnership(address);
for (const remote of this.domains) {
if (remote !== domain) {
await this.inbox(domain, remote).transferOwnership(address);
}
}
}
outbox(domain: types.Domain): TestOutbox {
return this.instances[domain].outbox;
}
ubc(domain: types.Domain): UpgradeBeaconController {
return this.instances[domain].ubc;
}
validator(domain: types.Domain): Validator {
return this.instances[domain].validator;
}
inbox(local: types.Domain, remote: types.Domain): TestInbox {
return this.instances[local].inboxs[remote];
}
connectionManager(domain: types.Domain): XAppConnectionManager {
return this.instances[domain].connectionManager;
}
validatorManager(domain: types.Domain): ValidatorManager {
return this.instances[domain].validatorManager;
}
async processMessages() {
await Promise.all(
this.domains.map((d) => this.processMessagesFromDomain(d)),
);
}
async processMessagesFromDomain(local: types.Domain) {
const outbox = this.outbox(local);
const [checkpointedRoot, checkpointedIndex] =
await outbox.latestCheckpoint();
const latestIndex = await outbox.tree();
if (latestIndex.eq(checkpointedIndex)) return;
// Find the block number of the last checkpoint submitted on Outbox.
const checkpointFilter = outbox.filters.Checkpoint(checkpointedRoot);
const checkpoints = await outbox.queryFilter(checkpointFilter);
assert(checkpoints.length === 0 || checkpoints.length === 1);
const fromBlock = checkpoints.length === 0 ? 0 : checkpoints[0].blockNumber;
await outbox.checkpoint();
const [root, index] = await outbox.latestCheckpoint();
// If there have been no checkpoints since the last checkpoint, return.
if (
index.eq(0) ||
(checkpoints.length == 1 && index.eq(checkpoints[0].args.index))
) {
return;
}
// TODO come back to this!
// Update the Outbox and Inboxs to the latest roots.
// This is technically not necessary given that we are not proving against
// a root in the TestInbox.
// const validator = this.validator(local);
// const { signature } = await validator.signCheckpoint(
// root,
// index.toNumber(),
// );
for (const remote of this.domains) {
if (remote !== local) {
const inbox = this.inbox(remote, local);
await inbox.checkpoint(root, index); // TODO come back to this!
}
}
// Find all messages dispatched on the outbox since the previous checkpoint.
const dispatchFilter = outbox.filters.Dispatch();
const dispatches = await outbox.queryFilter(dispatchFilter, fromBlock);
for (const dispatch of dispatches) {
const destination = dispatch.args.destinationAndNonce.shr(32).toNumber();
if (destination !== local) {
const inbox = this.inbox(destination, local);
await inbox.setMessageProven(dispatch.args.message);
await inbox.testProcess(dispatch.args.message);
}
}
}
}
export const abacus: any = {
AbacusDeployment,
};

@ -1,150 +0,0 @@
import { ethers } from 'hardhat';
import { expect } from 'chai';
import { types, utils, Validator } from '@abacus-network/utils';
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
import {
Outbox__factory,
Outbox,
ValidatorManager__factory,
ValidatorManager,
} from '../types';
const domainHashCases = require('../../../vectors/domainHash.json');
const localDomain = 1000;
describe('ValidatorManager', async () => {
let signer: SignerWithAddress,
fakeSigner: SignerWithAddress,
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.enrollValidator(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 domainHashCases) {
const { expectedDomainHash } = testCase;
const domainHash = await validatorManager.domainHash(
testCase.outboxDomain,
);
expect(domainHash).to.equal(expectedDomainHash);
}
});
describe('improper checkpoints', async () => {
let outbox: Outbox;
beforeEach(async () => {
const outboxFactory = new Outbox__factory(signer);
outbox = await outboxFactory.deploy(localDomain);
await outbox.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(
outbox.address,
root,
index,
signature,
),
)
.to.emit(validatorManager, 'ImproperCheckpoint')
.withArgs(
outbox.address,
localDomain,
validator.address,
root,
index,
signature,
);
expect(await outbox.state()).to.equal(types.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(
outbox.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 outbox.dispatch(
localDomain,
utils.addressToBytes32(signer.address),
message,
);
await outbox.checkpoint();
const [root, index] = await outbox.latestCheckpoint();
const { signature } = await validator.signCheckpoint(
root,
index.toNumber(),
);
// Send message with signer address as msg.sender
await expect(
validatorManager.improperCheckpoint(
outbox.address,
root,
index,
signature,
),
).to.be.revertedWith('!improper');
});
});
});
Loading…
Cancel
Save