Support local deploys for agent development (#234)

* Support local deploys for agent development

* Write out base db path

* PR review
nambrot/fix-contracts-metrics
Nam Chu Hoai 3 years ago committed by GitHub
parent 649001d179
commit f04959a57b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 68
      rust/config/local/alfajores_config.json
  2. 68
      rust/config/local/fuji_config.json
  3. 68
      rust/config/local/kovan_config.json
  4. 68
      rust/config/local/mumbai_config.json
  5. 17
      typescript/abacus-deploy/config/environments/local/agent.ts
  6. 4
      typescript/abacus-deploy/config/networks/testnets.ts
  7. 1
      typescript/abacus-deploy/hardhat.config.ts
  8. 14
      typescript/abacus-deploy/scripts/create-keys.ts
  9. 14
      typescript/abacus-deploy/scripts/delete-keys.ts
  10. 12
      typescript/abacus-deploy/scripts/dev/create-keys.ts
  11. 12
      typescript/abacus-deploy/scripts/dev/delete-keys.ts
  12. 59
      typescript/abacus-deploy/src/agents/index.ts
  13. 8
      typescript/abacus-deploy/src/config/agent.ts
  14. 2
      typescript/abacus-deploy/src/config/chain.ts
  15. 1
      typescript/abacus-deploy/src/config/environment.ts
  16. 6
      typescript/abacus-deploy/src/core/CoreDeploy.ts

@ -0,0 +1,68 @@
{
"environment": "local",
"signers": {
"alfajores": {
"key": "",
"type": "hexKey"
},
"kovan": {
"key": "",
"type": "hexKey"
},
"fuji": {
"key": "",
"type": "hexKey"
},
"mumbai": {
"key": "",
"type": "hexKey"
}
},
"replicas": {
"kovan": {
"address": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933",
"domain": "3000",
"name": "kovan",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"fuji": {
"address": "0x809d550fca64d94Bd9F66E60752A544199cfAC3D",
"domain": "43113",
"name": "fuji",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"mumbai": {
"address": "0xdbC43Ba45381e02825b14322cDdd15eC4B3164E6",
"domain": "80001",
"name": "mumbai",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
}
},
"home": {
"address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
"domain": "1000",
"name": "alfajores",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"tracing": {
"level": "debug",
"fmt": "json"
},
"db": "db_path"
}

@ -0,0 +1,68 @@
{
"environment": "local",
"signers": {
"fuji": {
"key": "",
"type": "hexKey"
},
"alfajores": {
"key": "",
"type": "hexKey"
},
"kovan": {
"key": "",
"type": "hexKey"
},
"mumbai": {
"key": "",
"type": "hexKey"
}
},
"replicas": {
"alfajores": {
"address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
"domain": "1000",
"name": "alfajores",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"kovan": {
"address": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
"domain": "3000",
"name": "kovan",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"mumbai": {
"address": "0xDC11f7E700A4c898AE5CAddB1082cFfa76512aDD",
"domain": "80001",
"name": "mumbai",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
}
},
"home": {
"address": "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF",
"domain": "43113",
"name": "fuji",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"tracing": {
"level": "debug",
"fmt": "json"
},
"db": "db_path"
}

@ -0,0 +1,68 @@
{
"environment": "local",
"signers": {
"kovan": {
"key": "",
"type": "hexKey"
},
"alfajores": {
"key": "",
"type": "hexKey"
},
"fuji": {
"key": "",
"type": "hexKey"
},
"mumbai": {
"key": "",
"type": "hexKey"
}
},
"replicas": {
"alfajores": {
"address": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
"domain": "1000",
"name": "alfajores",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"fuji": {
"address": "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154",
"domain": "43113",
"name": "fuji",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"mumbai": {
"address": "0x21dF544947ba3E8b3c32561399E88B52Dc8b2823",
"domain": "80001",
"name": "mumbai",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
}
},
"home": {
"address": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
"domain": "3000",
"name": "kovan",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"tracing": {
"level": "debug",
"fmt": "json"
},
"db": "db_path"
}

@ -0,0 +1,68 @@
{
"environment": "local",
"signers": {
"mumbai": {
"key": "",
"type": "hexKey"
},
"alfajores": {
"key": "",
"type": "hexKey"
},
"kovan": {
"key": "",
"type": "hexKey"
},
"fuji": {
"key": "",
"type": "hexKey"
}
},
"replicas": {
"alfajores": {
"address": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
"domain": "1000",
"name": "alfajores",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"kovan": {
"address": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8",
"domain": "3000",
"name": "kovan",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"fuji": {
"address": "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1",
"domain": "43113",
"name": "fuji",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
}
},
"home": {
"address": "0xB0D4afd8879eD9F52b28595d31B441D079B2Ca07",
"domain": "80001",
"name": "mumbai",
"rpcStyle": "ethereum",
"connection": {
"type": "http",
"url": ""
}
},
"tracing": {
"level": "debug",
"fmt": "json"
},
"db": "db_path"
}

@ -0,0 +1,17 @@
import { AgentConfig, DeployEnvironment } from '../../../src/config';
export const agentConfig: AgentConfig = {
environment: DeployEnvironment.local,
namespace: 'abacus-local',
runEnv: 'local',
docker: {
repo: 'gcr.io/abacus-labs/abacus-agent',
tag: 'e3c1b3bdcc8f92d506626785e4e7c058ba8d79be',
},
validator: {
interval: 5,
},
relayer: {
interval: 5,
},
};

@ -11,7 +11,7 @@ export const alfajores: ChainConfigWithoutSigner = {
export const fuji: ChainConfigWithoutSigner = {
name: ChainName.FUJI,
domain: 43113,
confirmations: 3,
confirmations: 1,
overrides: {},
};
@ -30,6 +30,7 @@ export const kovan: ChainConfigWithoutSigner = {
overrides: {
gasPrice: BigNumber.from(10_000_000_000),
},
confirmations: 3,
};
export const mumbai: ChainConfigWithoutSigner = {
@ -46,6 +47,7 @@ export const rinkarby: ChainConfigWithoutSigner = {
gasPrice: 0,
gasLimit: 600_000_000,
},
confirmations: 2,
};
export const rinkeby: ChainConfigWithoutSigner = {

@ -61,6 +61,7 @@ task('abacus', 'Deploys abacus on top of an already running Harthat Network')
// Write configs
deploy.writeOutput(getEnvironmentDirectory(environment));
deploy.writeRustConfigs(environment, getEnvironmentDirectory(environment));
});
task('kathy', 'Dispatches random abacus messages')

@ -0,0 +1,14 @@
import { createAgentGCPKeys } from '../src/agents/gcp';
import { getEnvironment, getChainConfigs } from './utils';
async function main() {
const environment = await getEnvironment();
const chains = await getChainConfigs(environment);
return createAgentGCPKeys(
environment,
Object.values(chains).map((c) => c.name),
);
}
main().then(console.log).catch(console.error);

@ -0,0 +1,14 @@
import { deleteAgentGCPKeys } from '../src/agents/gcp';
import { getEnvironment, getChainConfigsRecord } from './utils';
async function main() {
const environment = await getEnvironment();
const chains = await getChainConfigsRecord(environment);
return deleteAgentGCPKeys(
environment,
Object.values(chains).map((c) => c.name),
);
}
main().then(console.log).catch(console.error);

@ -1,12 +0,0 @@
import { createAgentGCPKeys } from '../../src/agents/gcp';
import { getChains } from '../../config/environments/dev/chains';
async function main() {
const chains = await getChains();
return createAgentGCPKeys(
'dev',
chains.map((c) => c.name),
);
}
main().then(console.log).catch(console.error);

@ -1,12 +0,0 @@
import { deleteAgentGCPKeys } from '../../src/agents/gcp';
import { getChains } from '../../config/environments/dev/chains';
async function main() {
const chains = await getChains();
return deleteAgentGCPKeys(
'dev',
chains.map((c) => c.name),
);
}
main().then(console.log).catch(console.error);

@ -10,17 +10,18 @@ import { AgentAwsKey } from './aws';
export enum KEY_ROLE_ENUM {
UpdaterAttestation = 'validator-attestation',
UpdaterSigner = 'validator-signer',
ProcessorSigner = 'processor-signer',
CheckpointerSigner = 'checkpointer-signer',
RelayerSigner = 'relayer-signer',
WatcherAttestation = 'watcher-attestation',
WatcherSigner = 'watcher-signer',
Deployer = 'deployer',
Bank = 'bank',
}
export const KEY_ROLES = [
'validator-attestation',
'validator-signer',
'processor-signer',
'checkpointer-signer',
'relayer-signer',
'watcher-attestation',
'watcher-signer',
@ -43,6 +44,8 @@ async function helmValuesForChain(
return undefined;
};
const chain = chains.find((_) => _.name === chainName)!;
return {
image: {
repository: agentConfig.docker.repo,
@ -71,11 +74,12 @@ async function helmValuesForChain(
attestationSigner: {
...credentials(KEY_ROLE_ENUM.UpdaterAttestation),
},
...include(!!agentConfig.validator!.interval, {
pollingInterval: agentConfig.validator!.interval || '',
reorg_period: chain.confirmations,
...include(!!agentConfig.validator?.interval, {
pollingInterval: agentConfig.validator?.interval || '',
}),
...include(!!agentConfig.validator!.pause, {
updatePause: agentConfig.validator!.pause || '',
...include(!!agentConfig.validator?.pause, {
updatePause: agentConfig.validator?.pause || '',
}),
},
relayer: {
@ -84,12 +88,15 @@ async function helmValuesForChain(
name: chain.name,
...credentials(KEY_ROLE_ENUM.RelayerSigner),
})),
...include(!!agentConfig.validator?.interval, {
pollingInterval: agentConfig.validator?.interval || '',
}),
},
processor: {
enabled: true,
transactionSigners: chains.map((chain) => ({
name: chain.name,
...credentials(KEY_ROLE_ENUM.ProcessorSigner),
...credentials(KEY_ROLE_ENUM.CheckpointerSigner),
})),
indexonly: agentConfig.processor?.indexOnly || [],
s3BucketName: agentConfig.processor?.s3Bucket || '',
@ -111,7 +118,7 @@ export async function getAgentEnvVars(
chains,
);
const envVars: string[] = [];
const chain = chains.find((_) => _.name === homeChainName)!;
const rpcEndpoints = await getSecretRpcEndpoints(agentConfig, chains);
envVars.push(`OPT_BASE_HOME_CONNECTION_URL=${rpcEndpoints[homeChainName]}`);
valueDict.optics.replicaChains.forEach((replicaChain: any) => {
@ -127,6 +134,9 @@ export async function getAgentEnvVars(
envVars.push(`RUN_ENV=${agentConfig.runEnv}`);
envVars.push(`OPT_BASE_METRICS=9090`);
envVars.push(`OPT_BASE_TRACING_LEVEL=info`);
envVars.push(
`OPT_BASE_DB=/tmp/${agentConfig.environment}-${role}-${homeChainName}-db`,
);
try {
const gcpKeys = await fetchAgentGCPKeys(
@ -145,13 +155,36 @@ export async function getAgentEnvVars(
// Updater attestation key
if (role.startsWith('validator')) {
envVars.push(
`OPT_BASE_UPDATER_KEY=${strip0x(
`OPT_BASE_VALIDATOR_KEY=${strip0x(
gcpKeys[homeChainName + '-' + KEY_ROLE_ENUM.UpdaterAttestation]
.privateKey,
)}`,
`OPT_BASE_VALIDATOR_TYPE=hexKey`,
);
// Throw an error if the chain config did not specify the reorg period
if (valueDict.optics.validator.confirmations === undefined) {
throw new Error(
`Panic: Chain config for ${homeChainName} did not specify a reorg period`,
);
}
envVars.push(
`OPT_VALIDATOR_REORGPERIOD=${chain.confirmations! - 1}`,
`OPT_VALIDATOR_INTERVAL=${valueDict.optics.validator.pollingInterval}`,
);
}
if (role.startsWith('relayer')) {
envVars.push(
`OPT_RELAYER_INTERVAL=${valueDict.optics.relayer.pollingInterval}`,
);
}
} catch (error) {
// This happens if you don't have a result type
if ((error as any).toString().includes('Panic')) {
throw error;
}
// Keys are in AWS
const awsKeys = await getSecretAwsCredentials(agentConfig);
@ -174,15 +207,15 @@ export async function getAgentEnvVars(
);
});
// Updater attestation key
// Validator attestation key
if (role.startsWith('validator')) {
const key = new AgentAwsKey(agentConfig, role, homeChainName);
envVars.push(`OPT_BASE_UPDATER_TYPE=aws`);
envVars.push(`OPT_BASE_VALIDATOR_TYPE=aws`);
envVars.push(
`OPT_BASE_UPDATER_ID=${key.credentialsAsHelmValue.aws.keyId}`,
`OPT_BASE_VALIDATOR_ID=${key.credentialsAsHelmValue.aws.keyId}`,
);
envVars.push(
`OPT_BASE_UPDATER_REGION=${key.credentialsAsHelmValue.aws.region}`,
`OPT_BASE_VALIDATOR_REGION=${key.credentialsAsHelmValue.aws.region}`,
);
}
}

@ -16,6 +16,11 @@ interface ProcessorConfig {
s3Bucket: string;
}
interface RelayerConfig {
// How often a relayer should check for new signed checkpoints
interval?: number;
}
interface ValidatorConfig {
// How often an validator should check for new updates
interval?: number;
@ -37,6 +42,7 @@ export interface AgentConfig {
aws?: AwsConfig;
processor?: ProcessorConfig;
validator?: ValidatorConfig;
relayer?: RelayerConfig;
}
export type RustSigner = {
@ -51,7 +57,7 @@ export type RustConnection = {
export type RustContractBlock = {
address: types.Address;
domain: types.Domain;
domain: string;
name: ChainName;
rpcStyle: string; // TODO
connection: RustConnection;

@ -29,7 +29,9 @@ export type ChainConfig = {
signer: ethers.Signer;
overrides: ethers.Overrides;
supports1559?: boolean;
// The number of confirmations considered reorg safe
confirmations?: number;
poll_interval?: number;
};
export type ChainConfigWithoutSigner = Omit<ChainConfig, 'signer'>;

@ -7,4 +7,5 @@ export enum DeployEnvironment {
test = 'test',
production = 'production',
stagingCommunity = 'staging-community',
local = 'local',
}

@ -55,12 +55,12 @@ export class CoreDeploy extends CommonDeploy<CoreInstance, CoreConfig> {
const filepath = path.join(
this.configDirectory(directory),
'rust',
`${this.name(domain)}.json`,
`${this.name(domain)}_config.json`,
);
const outbox = {
address: this.outbox(domain).address,
domain,
domain: domain.toString(),
name: this.name(domain),
rpcStyle: 'ethereum',
connection: {
@ -86,7 +86,7 @@ export class CoreDeploy extends CommonDeploy<CoreInstance, CoreConfig> {
for (const remote of this.remotes(domain)) {
const inbox = {
address: this.inbox(remote, domain).address,
domain: remote,
domain: remote.toString(),
name: this.name(remote),
rpcStyle: 'ethereum',
connection: {

Loading…
Cancel
Save