Move CoreDeployer to deploy pkg (#428)

pull/434/head
Yorke Rhodes 3 years ago committed by GitHub
parent 233d0aa14d
commit 0ac724aa7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 271
      typescript/deploy/src/core/deploy.ts
  2. 5
      typescript/deploy/src/index.ts
  3. 3
      typescript/infra/config/environments/dev/core.ts
  4. 3
      typescript/infra/config/environments/test/core.ts
  5. 3
      typescript/infra/config/environments/testnet/core.ts
  6. 4
      typescript/infra/hardhat.config.ts
  7. 7
      typescript/infra/scripts/core.ts
  8. 2
      typescript/infra/scripts/governance.ts
  9. 3
      typescript/infra/src/config/environment.ts
  10. 8
      typescript/infra/src/core/check.ts
  11. 259
      typescript/infra/src/core/deploy.ts
  12. 2
      typescript/infra/src/core/govern.ts
  13. 2
      typescript/infra/src/core/index.ts
  14. 10
      typescript/infra/src/core/types.ts
  15. 8
      typescript/infra/test/core.test.ts

@ -0,0 +1,271 @@
import { ethers } from 'ethers';
import {
AbacusConnectionManager__factory,
InboxValidatorManager,
InboxValidatorManager__factory,
Inbox__factory,
InterchainGasPaymaster__factory,
OutboxValidatorManager__factory,
Outbox__factory,
UpgradeBeaconController__factory,
} from '@abacus-network/core';
import { AbacusAppDeployer, ProxiedContract } from '@abacus-network/deploy';
import {
AbacusCore,
ChainMap,
ChainName,
CoreContractAddresses,
CoreContracts,
DomainConnection,
InboxContracts,
MailboxAddresses,
MultiProvider,
RemoteChainMap,
Remotes,
domains,
objMap,
promiseObjAll,
} from '@abacus-network/sdk';
import { types } from '@abacus-network/utils';
export type ValidatorManagerConfig = {
validators: Array<types.Address>;
threshold: number;
};
export type CoreConfig = {
validatorManager: ValidatorManagerConfig;
};
type FactoryBuilder = (signer: ethers.Signer) => ethers.ContractFactory;
export class AbacusCoreDeployer<
Networks extends ChainName,
> extends AbacusAppDeployer<
Networks,
CoreConfig,
CoreContractAddresses<Networks, any>
> {
inboxFactoryBuilder: FactoryBuilder = (signer: ethers.Signer) =>
new Inbox__factory(signer);
outboxFactoryBuilder: FactoryBuilder = (signer: ethers.Signer) =>
new Outbox__factory(signer);
startingBlockNumbers: ChainMap<Networks, number | undefined>;
constructor(
multiProvider: MultiProvider<Networks>,
configMap: ChainMap<Networks, CoreConfig>,
) {
super(multiProvider, configMap);
this.startingBlockNumbers = objMap(configMap, () => undefined);
}
async deployContracts<Local extends Networks>(
network: Local,
config: CoreConfig,
): Promise<CoreContractAddresses<Networks, Local>> {
const dc = this.multiProvider.getDomainConnection(network);
const signer = dc.signer!;
const provider = dc.provider!;
const startingBlockNumber = await provider.getBlockNumber();
this.startingBlockNumbers[network] = startingBlockNumber;
const upgradeBeaconController = await this.deployContract(
network,
'UpgradeBeaconController',
new UpgradeBeaconController__factory(signer),
[],
);
const outboxValidatorManagerConfig = config.validatorManager;
const domain = domains[network].id;
const outboxValidatorManager = await this.deployContract(
network,
'OutboxValidatorManager',
new OutboxValidatorManager__factory(signer),
[
domain,
outboxValidatorManagerConfig.validators,
outboxValidatorManagerConfig.threshold,
],
);
const outbox = await this.deployProxiedContract(
network,
'Outbox',
this.outboxFactoryBuilder(signer),
[domain],
upgradeBeaconController.address,
[outboxValidatorManager.address],
);
const interchainGasPaymaster = await this.deployContract(
network,
'InterchainGasPaymaster',
new InterchainGasPaymaster__factory(signer),
[],
);
const abacusConnectionManager = await this.deployContract(
network,
'AbacusConnectionManager',
new AbacusConnectionManager__factory(signer),
[],
);
await abacusConnectionManager.setOutbox(
outbox.contract.address,
dc.overrides,
);
await abacusConnectionManager.setInterchainGasPaymaster(
interchainGasPaymaster.address,
dc.overrides,
);
const remotes = Object.keys(this.configMap).filter(
(k) => k !== network,
) as Remotes<Networks, Local>[];
const deployValidatorManager = async (
remote: Remotes<Networks, Local>,
): Promise<InboxValidatorManager> => {
const remoteConfig = this.configMap[remote].validatorManager;
return this.deployContract(
network,
'InboxValidatorManager',
new InboxValidatorManager__factory(signer),
[domains[remote].id, remoteConfig.validators, remoteConfig.threshold],
);
};
const [firstRemote, ...trailingRemotes] = remotes;
const firstValidatorManager = await deployValidatorManager(firstRemote);
const firstInbox = await this.deployProxiedContract(
network,
'Inbox',
this.inboxFactoryBuilder(signer),
[domain],
upgradeBeaconController.address,
[
domains[firstRemote].id,
firstValidatorManager.address,
ethers.constants.HashZero,
0,
],
);
const getMailbox = (
validatorManager: ethers.Contract,
box: ProxiedContract<ethers.Contract>,
): MailboxAddresses => ({
...box.addresses,
validatorManager: validatorManager.address,
});
type RemoteMailboxEntry = [Remotes<Networks, Local>, MailboxAddresses];
const firstInboxAddresses: RemoteMailboxEntry = [
firstRemote,
getMailbox(firstValidatorManager, firstInbox),
];
const trailingInboxAddresses = await Promise.all(
trailingRemotes.map(async (remote): Promise<RemoteMailboxEntry> => {
const validatorManager = await deployValidatorManager(remote);
const inbox = await this.duplicateProxiedContract(
network,
'Inbox',
firstInbox,
[
domains[remote].id,
validatorManager.address,
ethers.constants.HashZero,
0,
],
);
return [remote, getMailbox(validatorManager, inbox)];
}),
);
const inboxAddresses = [firstInboxAddresses, ...trailingInboxAddresses];
await Promise.all(
inboxAddresses.map(([remote, mailbox]) =>
abacusConnectionManager.enrollInbox(domains[remote].id, mailbox.proxy),
),
);
return {
upgradeBeaconController: upgradeBeaconController.address,
abacusConnectionManager: abacusConnectionManager.address,
interchainGasPaymaster: interchainGasPaymaster.address,
outbox: getMailbox(outboxValidatorManager, outbox),
inboxes: Object.fromEntries(inboxAddresses) as RemoteChainMap<
Networks,
Local,
MailboxAddresses
>,
};
}
static async transferOwnership<CoreNetworks extends ChainName>(
core: AbacusCore<CoreNetworks>,
owners: ChainMap<CoreNetworks, types.Address>,
multiProvider: MultiProvider<CoreNetworks>,
) {
return promiseObjAll(
objMap(core.contractsMap, async (network, coreContracts) => {
const owner = owners[network];
const domainConnection = multiProvider.getDomainConnection(network);
return AbacusCoreDeployer.transferOwnershipOfDomain(
coreContracts,
owner,
domainConnection,
);
}),
);
}
static async transferOwnershipOfDomain<
CoreNetworks extends ChainName,
Local extends CoreNetworks,
>(
core: CoreContracts<CoreNetworks, Local>,
owner: types.Address,
domainConnection: DomainConnection,
): Promise<ethers.ContractReceipt> {
await core.contracts.outbox.validatorManager.transferOwnership(
owner,
domainConnection.overrides,
);
await core.contracts.abacusConnectionManager.transferOwnership(
owner,
domainConnection.overrides,
);
await core.contracts.upgradeBeaconController.transferOwnership(
owner,
domainConnection.overrides,
);
const inboxContracts: InboxContracts[] = Object.values(
core.contracts.inboxes,
);
await Promise.all(
inboxContracts.map(async (inbox) => {
await inbox.validatorManager.transferOwnership(
owner,
domainConnection.overrides,
);
await inbox.inbox.transferOwnership(owner, domainConnection.overrides);
}),
);
const tx = await core.contracts.outbox.outbox.transferOwnership(
owner,
domainConnection.overrides,
);
return tx.wait(domainConnection.confirmations);
}
}

@ -4,6 +4,11 @@ export {
EnvironmentConfig,
TransactionConfig,
} from './config';
export {
AbacusCoreDeployer,
CoreConfig,
ValidatorManagerConfig,
} from './core/deploy';
export { AbacusAppDeployer } from './deploy';
export {
ProxiedContract,

@ -1,7 +1,6 @@
import { CoreConfig } from '@abacus-network/deploy';
import { ChainMap } from '@abacus-network/sdk';
import { CoreConfig } from '../../../src/core';
import { DevNetworks } from './domains';
export const core: ChainMap<DevNetworks, CoreConfig> = {

@ -1,7 +1,6 @@
import { CoreConfig } from '@abacus-network/deploy';
import { ChainMap } from '@abacus-network/sdk';
import { CoreConfig } from '../../../src/core';
import { TestNetworks } from './domains';
export const core: ChainMap<TestNetworks, CoreConfig> = {

@ -1,7 +1,6 @@
import { CoreConfig } from '@abacus-network/deploy';
import { ChainMap } from '@abacus-network/sdk';
import { CoreConfig } from '../../../src/core';
import { TestnetNetworks } from './domains';
export const core: ChainMap<TestnetNetworks, CoreConfig> = {

@ -18,7 +18,7 @@ import {
getCoreRustDirectory,
getCoreVerificationDirectory,
} from './scripts/utils';
import { AbacusCoreDeployer } from './src/core';
import { AbacusCoreInfraDeployer } from './src/core/deploy';
import { sleep } from './src/utils/utils';
import { AbacusContractVerifier } from './src/verify';
@ -78,7 +78,7 @@ task('abacus', 'Deploys abacus on top of an already running Hardhat Network')
signer,
);
const deployer = new AbacusCoreDeployer(multiProvider, config.core);
const deployer = new AbacusCoreInfraDeployer(multiProvider, config.core);
const addresses = await deployer.deploy();
// Write configs

@ -1,4 +1,4 @@
import { AbacusCoreDeployer } from '../src/core';
import { AbacusCoreInfraDeployer } from '../src/core/deploy';
import {
getCoreContractsSdkFilepath,
@ -12,7 +12,10 @@ async function main() {
const environment = await getEnvironment();
const config = getCoreEnvironmentConfig(environment) as any;
const multiProvider = await config.getMultiProvider();
const deployer = new AbacusCoreDeployer(multiProvider, config.core);
const deployer = new AbacusCoreInfraDeployer(
multiProvider,
config.core.validatorManagers,
);
const addresses = await deployer.deploy();

@ -1,6 +1,6 @@
import { AbacusCoreDeployer } from '@abacus-network/deploy';
import { AbacusCore, objMap } from '@abacus-network/sdk';
import { AbacusCoreDeployer } from '../src/core';
import { AbacusGovernanceDeployer } from '../src/governance';
import {

@ -1,8 +1,7 @@
import { EnvironmentConfig } from '@abacus-network/deploy';
import { CoreConfig, EnvironmentConfig } from '@abacus-network/deploy';
import { ChainMap, ChainName, MultiProvider } from '@abacus-network/sdk';
import { environments } from '../../config/environments';
import { CoreConfig } from '../core';
import { GovernanceConfig } from '../governance';
import { AgentConfig } from './agent';

@ -1,7 +1,11 @@
import { expect } from 'chai';
import { MultisigValidatorManager } from '@abacus-network/core';
import { AbacusAppChecker, CheckerViolation } from '@abacus-network/deploy';
import {
AbacusAppChecker,
CheckerViolation,
CoreConfig,
} from '@abacus-network/deploy';
import {
AbacusCore,
ChainName,
@ -14,8 +18,6 @@ import { types } from '@abacus-network/utils';
import { setDifference } from '../utils/utils';
import { CoreConfig } from './types';
export enum CoreViolationType {
ValidatorManager = 'ValidatorManager',
Validator = 'Validator',

@ -1,206 +1,13 @@
import { ethers } from 'ethers';
import path from 'path';
import {
AbacusConnectionManager__factory,
InboxValidatorManager,
InboxValidatorManager__factory,
Inbox__factory,
InterchainGasPaymaster__factory,
OutboxValidatorManager__factory,
Outbox__factory,
UpgradeBeaconController__factory,
} from '@abacus-network/core';
import { AbacusAppDeployer, ProxiedContract } from '@abacus-network/deploy';
import {
AbacusCore,
ChainMap,
ChainName,
CoreContractAddresses,
CoreContracts,
DomainConnection,
InboxContracts,
MailboxAddresses,
MultiProvider,
RemoteChainMap,
Remotes,
domains,
objMap,
promiseObjAll,
} from '@abacus-network/sdk';
import { types } from '@abacus-network/utils';
import { AbacusAppDeployer, AbacusCoreDeployer } from '@abacus-network/deploy';
import { ChainName, domains, objMap } from '@abacus-network/sdk';
import { DeployEnvironment, RustConfig } from '../config';
import { CoreConfig } from './types';
export class AbacusCoreDeployer<
export class AbacusCoreInfraDeployer<
Networks extends ChainName,
> extends AbacusAppDeployer<
Networks,
CoreConfig,
CoreContractAddresses<Networks, any>
> {
// Tracks the block number per network from which contract deployment started
startingBlockNumbers: ChainMap<Networks, number | undefined>;
constructor(
multiProvider: MultiProvider<Networks>,
configMap: ChainMap<Networks, CoreConfig>,
) {
super(multiProvider, configMap);
this.startingBlockNumbers = objMap(configMap, () => undefined);
}
async deployContracts<Local extends Networks>(
network: Local,
config: CoreConfig,
): Promise<CoreContractAddresses<Networks, Local>> {
const dc = this.multiProvider.getDomainConnection(network);
const provider = dc.provider!;
const signer = dc.signer!;
const startingBlockNumber = await provider.getBlockNumber();
this.startingBlockNumbers[network] = startingBlockNumber;
const upgradeBeaconController = await this.deployContract(
network,
'UpgradeBeaconController',
new UpgradeBeaconController__factory(signer),
[],
);
const outboxValidatorManagerConfig = config.validatorManager;
const domain = domains[network].id;
const outboxValidatorManager = await this.deployContract(
network,
'OutboxValidatorManager',
new OutboxValidatorManager__factory(signer),
[
domain,
outboxValidatorManagerConfig.validators,
outboxValidatorManagerConfig.threshold,
],
);
const outbox = await this.deployProxiedContract(
network,
'Outbox',
new Outbox__factory(signer),
[domain],
upgradeBeaconController.address,
[outboxValidatorManager.address],
);
const interchainGasPaymaster = await this.deployContract(
network,
'InterchainGasPaymaster',
new InterchainGasPaymaster__factory(signer),
[],
);
const abacusConnectionManager = await this.deployContract(
network,
'AbacusConnectionManager',
new AbacusConnectionManager__factory(signer),
[],
);
await abacusConnectionManager.setOutbox(
outbox.contract.address,
dc.overrides,
);
await abacusConnectionManager.setInterchainGasPaymaster(
interchainGasPaymaster.address,
dc.overrides,
);
const remotes = Object.keys(this.configMap).filter(
(k) => k !== network,
) as Remotes<Networks, Local>[];
const deployValidatorManager = async (
remote: Remotes<Networks, Local>,
): Promise<InboxValidatorManager> => {
const remoteConfig = this.configMap[remote].validatorManager;
return this.deployContract(
network,
'InboxValidatorManager',
new InboxValidatorManager__factory(signer),
[domains[remote].id, remoteConfig.validators, remoteConfig.threshold],
);
};
const [firstRemote, ...trailingRemotes] = remotes;
const firstValidatorManager = await deployValidatorManager(firstRemote);
const firstInbox = await this.deployProxiedContract(
network,
'Inbox',
new Inbox__factory(dc.signer!),
[domain],
upgradeBeaconController.address,
[
domains[firstRemote].id,
firstValidatorManager.address,
ethers.constants.HashZero,
0,
],
);
const getMailbox = (
validatorManager: ethers.Contract,
box: ProxiedContract<ethers.Contract>,
): MailboxAddresses => ({
...box.addresses,
validatorManager: validatorManager.address,
});
type RemoteMailboxEntry = [Remotes<Networks, Local>, MailboxAddresses];
const firstInboxAddresses: RemoteMailboxEntry = [
firstRemote,
getMailbox(firstValidatorManager, firstInbox),
];
const trailingInboxAddresses = await Promise.all(
trailingRemotes.map(async (remote): Promise<RemoteMailboxEntry> => {
const validatorManager = await deployValidatorManager(remote);
const inbox = await this.duplicateProxiedContract(
network,
'Inbox',
firstInbox,
[
domains[remote].id,
validatorManager.address,
ethers.constants.HashZero,
0,
],
);
return [remote, getMailbox(validatorManager, inbox)];
}),
);
const inboxAddresses = [firstInboxAddresses, ...trailingInboxAddresses];
await Promise.all(
inboxAddresses.map(([remote, mailbox]) =>
abacusConnectionManager.enrollInbox(domains[remote].id, mailbox.proxy),
),
);
return {
upgradeBeaconController: upgradeBeaconController.address,
abacusConnectionManager: abacusConnectionManager.address,
interchainGasPaymaster: interchainGasPaymaster.address,
outbox: getMailbox(outboxValidatorManager, outbox),
inboxes: Object.fromEntries(inboxAddresses) as RemoteChainMap<
Networks,
Local,
MailboxAddresses
>,
};
}
> extends AbacusCoreDeployer<Networks> {
writeRustConfigs(
environment: DeployEnvironment,
directory: string,
@ -265,62 +72,4 @@ export class AbacusCoreDeployer<
AbacusAppDeployer.writeJson(filepath, rustConfig);
});
}
static async transferOwnership<CoreNetworks extends ChainName>(
core: AbacusCore<CoreNetworks>,
owners: ChainMap<CoreNetworks, types.Address>,
multiProvider: MultiProvider<CoreNetworks>,
) {
return promiseObjAll(
objMap(core.contractsMap, async (network, coreContracts) => {
const owner = owners[network];
const domainConnection = multiProvider.getDomainConnection(network);
return AbacusCoreDeployer.transferOwnershipOfDomain(
coreContracts,
owner,
domainConnection,
);
}),
);
}
static async transferOwnershipOfDomain<
CoreNetworks extends ChainName,
Local extends CoreNetworks,
>(
core: CoreContracts<CoreNetworks, Local>,
owner: types.Address,
domainConnection: DomainConnection,
): Promise<ethers.ContractReceipt> {
await core.contracts.outbox.validatorManager.transferOwnership(
owner,
domainConnection.overrides,
);
await core.contracts.abacusConnectionManager.transferOwnership(
owner,
domainConnection.overrides,
);
await core.contracts.upgradeBeaconController.transferOwnership(
owner,
domainConnection.overrides,
);
const inboxContracts: InboxContracts[] = Object.values(
core.contracts.inboxes,
);
await Promise.all(
inboxContracts.map(async (inbox) => {
await inbox.validatorManager.transferOwnership(
owner,
domainConnection.overrides,
);
await inbox.inbox.transferOwnership(owner, domainConnection.overrides);
}),
);
const tx = await core.contracts.outbox.outbox.transferOwnership(
owner,
domainConnection.overrides,
);
return tx.wait(domainConnection.confirmations);
}
}

@ -4,6 +4,7 @@ import { PopulatedTransaction } from 'ethers';
import { MultisigValidatorManager__factory } from '@abacus-network/core';
import {
CheckerViolation,
CoreConfig,
ProxyViolationType,
UpgradeBeaconViolation,
} from '@abacus-network/deploy';
@ -23,7 +24,6 @@ import {
ValidatorViolation,
ValidatorViolationType,
} from './check';
import { CoreConfig } from './types';
interface DomainedCall {
network: ChainName;

@ -1,4 +1,2 @@
export { AbacusCoreDeployer } from './deploy';
export { AbacusCoreChecker, CoreViolationType } from './check';
export { AbacusCoreGovernor } from './govern';
export { CoreConfig } from './types';

@ -1,10 +0,0 @@
import { types } from '@abacus-network/utils';
export type ValidatorManagerConfig = {
validators: Array<types.Address>;
threshold: number;
};
export type CoreConfig = {
validatorManager: ValidatorManagerConfig;
};

@ -2,6 +2,7 @@ import '@nomiclabs/hardhat-waffle';
import { ethers } from 'hardhat';
import path from 'path';
import { AbacusCoreDeployer, CoreConfig } from '@abacus-network/deploy';
import {
AbacusCore,
ChainMap,
@ -12,13 +13,14 @@ import {
import { TestNetworks } from '../config/environments/test/domains';
import { getCoreEnvironmentConfig } from '../scripts/utils';
import { AbacusCoreChecker, AbacusCoreDeployer, CoreConfig } from '../src/core';
import { AbacusCoreChecker } from '../src/core';
import { AbacusCoreInfraDeployer } from '../src/core/deploy';
describe('core', async () => {
const environment = 'test';
let multiProvider: MultiProvider<TestNetworks>;
let deployer: AbacusCoreDeployer<TestNetworks>;
let deployer: AbacusCoreInfraDeployer<TestNetworks>;
let core: AbacusCore<TestNetworks>;
let addresses: ChainMap<
TestNetworks,
@ -31,7 +33,7 @@ describe('core', async () => {
const config = getCoreEnvironmentConfig(environment);
multiProvider = await config.getMultiProvider();
coreConfig = config.core;
deployer = new AbacusCoreDeployer(multiProvider, coreConfig);
deployer = new AbacusCoreInfraDeployer(multiProvider, coreConfig);
const [, owner] = await ethers.getSigners();
owners = objMap(config.transactionConfigs, () => owner.address);
});

Loading…
Cancel
Save