Skip to content

Commit

Permalink
feat: migration and noNetwork fix
Browse files Browse the repository at this point in the history
  • Loading branch information
MishaShWoof committed Dec 12, 2024
1 parent be4c3ed commit 16d8736
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,7 @@ export default migration('1733443598_configurate_and_ens', {
},
PufETH: {
supplyCap: exp(1_000, 18)
},
baseTrackingSupplySpeed: 0,
baseTrackingBorrowSpeed: 0,
}
});

// 3.
Expand Down
2 changes: 1 addition & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export const networkConfigs: NetworkConfig[] = [
{
network: 'mainnet',
chainId: 1,
url: `http://normally-up-yeti.n0des.xyz`
url: `https://rpc.ankr.com/eth/${ANKR_KEY}`,
},
{
network: 'sepolia',
Expand Down
31 changes: 1 addition & 30 deletions plugins/deployment_manager/Spider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,33 +50,6 @@ function maybeStore(alias: Alias, address: Address, into: Aliases): boolean {
return true;
}
}
async function retry(fn: () => Promise<any>, retries: number = 10, timeLimit?: number, wait: number = 500) {
try {
return await asyncCallWithTimeout(fn(), timeLimit);
} catch (e) {
if (retries === 0) throw e;

console.warn(`Retrying in ${wait}ms...`);

await new Promise(ok => setTimeout(ok, wait));
return retry(fn, retries - 1, timeLimit, wait >= 10000 ? 10000 : wait * 2);
}
}
async function asyncCallWithTimeout(asyncPromise: Promise<any>, timeLimit: number = 120_000) {
let timeoutHandle: string | number | NodeJS.Timeout;

const timeoutPromise = new Promise((_resolve, reject) => {
timeoutHandle = setTimeout(
() => reject(new Error('Async call timeout limit reached')),
timeLimit
);
});

return Promise.race([asyncPromise, timeoutPromise]).then(result => {
clearTimeout(timeoutHandle);
return result;
});
}

async function discoverNodes(
path: Contract[],
Expand All @@ -85,9 +58,7 @@ async function discoverNodes(
config: RelationInnerConfig,
defaultKeyAndTemplate: string
): Promise<DiscoverNode[]> {
const addresses = await retry(() => {
return readField(contract, getFieldKey(config, defaultKeyAndTemplate), context);
});
const addresses = await readField(contract, getFieldKey(config, defaultKeyAndTemplate), context);
const templates = config.alias ? asArray(config.alias) : [defaultKeyAndTemplate];
return addresses.map((address, i) => ({
address,
Expand Down
55 changes: 45 additions & 10 deletions plugins/scenario/Runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,37 @@ export class Runner<T, U, R> {
}
}


async function retry(fn: () => Promise<any>, retries: number = 10, timeLimit?: number, wait: number = 100) {
try {
return await asyncCallWithTimeout(fn(), timeLimit);
} catch (e) {
if (retries === 0) throw e;
if(e.reason !== 'could not detect network')
throw e;

console.warn(`Retrying in ${wait}ms...`);

await new Promise(ok => setTimeout(ok, wait));
return retry(fn, retries - 1, timeLimit, wait >= 10000 ? 10000 : wait * 2);
}
}
async function asyncCallWithTimeout(asyncPromise: Promise<any>, timeLimit: number = 5000_000) {
let timeoutHandle: string | number | NodeJS.Timeout;

const timeoutPromise = new Promise((_resolve, reject) => {
timeoutHandle = setTimeout(
() => reject(new Error('Async call timeout limit reached')),
timeLimit
);
});

return Promise.race([asyncPromise, timeoutPromise]).then(result => {
clearTimeout(timeoutHandle);
return result;
});
}

export async function runScenarios(bases: ForkSpec[]) {
const loader = await Loader.load();
const [runningScenarios, skippedScenarios] = loader.splitScenarios();
Expand All @@ -161,16 +192,20 @@ export async function runScenarios(bases: ForkSpec[]) {
const results: Result[] = [];

for (const base of bases) {
const world = new World(base), dm = world.deploymentManager;
const delta = await dm.runDeployScript({ allMissing: true });
console.log(`[${base.name}] Deployed ${dm.counter} contracts, spent ${dm.spent} to initialize world 🗺`);
console.log(`[${base.name}]\n${dm.diffDelta(delta)}`);

if (world.auxiliaryDeploymentManager) {
await world.auxiliaryDeploymentManager.spider();
}

const runner = new Runner(base, world);
let runner: Runner<unknown, unknown, unknown>;
await retry(async () => {
const world = new World(base);
await world.initialize(base);
const dm = world.deploymentManager;
const delta = await dm.runDeployScript({ allMissing: true });
console.log(`[${base.name}] Deployed ${dm.counter} contracts, spent ${dm.spent} to initialize world 🗺`);
console.log(`[${base.name}]\n${dm.diffDelta(delta)}`);

if (world.auxiliaryDeploymentManager) {
await world.auxiliaryDeploymentManager.spider();
}
runner = new Runner(base, world);
});

// NB: contexts are (still) a bit awkward
// they prob dont even really need to get passed through here currently
Expand Down
10 changes: 6 additions & 4 deletions plugins/scenario/World.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,17 @@ export class World {
snapshotAuxiliaryDeploymentManager?: DeploymentManager;

constructor(base: ForkSpec) {
// Q: should we really need to fork/snapshot the deployment manager?
const hre = hreForBase(base);
this.base = base;
}

async initialize(base: ForkSpec) {
const hre = await hreForBase(base);
this.deploymentManager = new DeploymentManager(base.network, base.deployment, hre);
// Q: should we really need to fork/snapshot the deployment manager?
this.snapshotDeploymentManager = this.deploymentManager;

if (this.base.auxiliaryBase) {
const auxiliaryBase = hre.config.scenario.bases.find(b => b.name === this.base.auxiliaryBase);
this.auxiliaryDeploymentManager = new DeploymentManager(auxiliaryBase.network, auxiliaryBase.deployment, hreForBase(auxiliaryBase));
this.auxiliaryDeploymentManager = new DeploymentManager(auxiliaryBase.network, auxiliaryBase.deployment, await hreForBase(auxiliaryBase));
this.snapshotAuxiliaryDeploymentManager = this.auxiliaryDeploymentManager;
}
}
Expand Down
17 changes: 12 additions & 5 deletions plugins/scenario/utils/hreForBase.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ethers } from 'ethers';
import { ethers } from 'ethers';
import type { HardhatEthersHelpers } from '@nomiclabs/hardhat-ethers/types';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { HardhatContext } from 'hardhat/internal/context';
Expand Down Expand Up @@ -36,7 +36,7 @@ declare module 'hardhat/internal/core/runtime-environment' {
}
}

export function nonForkedHreForBase(base: ForkSpec): HardhatRuntimeEnvironment {
export async function nonForkedHreForBase(base: ForkSpec): Promise<HardhatRuntimeEnvironment> {
const ctx: HardhatContext = HardhatContext.getHardhatContext();

const hardhatArguments = getEnvHardhatArguments(
Expand All @@ -61,7 +61,7 @@ export function nonForkedHreForBase(base: ForkSpec): HardhatRuntimeEnvironment {
);
}

export function forkedHreForBase(base: ForkSpec): HardhatRuntimeEnvironment {
export async function forkedHreForBase(base: ForkSpec): Promise<HardhatRuntimeEnvironment> {
const ctx: HardhatContext = HardhatContext.getHardhatContext();

const hardhatArguments = getEnvHardhatArguments(HARDHAT_PARAM_DEFINITIONS, process.env);
Expand All @@ -73,6 +73,13 @@ export function forkedHreForBase(base: ForkSpec): HardhatRuntimeEnvironment {

const baseNetwork = networks[base.network] as HttpNetworkUserConfig;

const provider = new ethers.providers.JsonRpcProvider(baseNetwork.url);

// noNetwork otherwise
if(!base.blockNumber)
// base.blockNumber = 17480000;
base.blockNumber = await provider.getBlockNumber() - 210;

if (!baseNetwork) {
throw new Error(`cannot find network config for network: ${base.network}`);
}
Expand All @@ -96,7 +103,7 @@ export function forkedHreForBase(base: ForkSpec): HardhatRuntimeEnvironment {
defaultNetwork: 'hardhat',
networks: {
hardhat: forkedNetwork,
localhost
localhost: localhost
},
},
};
Expand All @@ -111,7 +118,7 @@ export function forkedHreForBase(base: ForkSpec): HardhatRuntimeEnvironment {
);
}

export default function hreForBase(base: ForkSpec, fork = true): HardhatRuntimeEnvironment {
export default async function hreForBase(base: ForkSpec, fork = true): Promise<HardhatRuntimeEnvironment> {
if (fork) {
return forkedHreForBase(base);
} else {
Expand Down
14 changes: 7 additions & 7 deletions tasks/deployment_manager/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { impersonateAddress } from '../../plugins/scenario/utils';
import hreForBase from '../../plugins/scenario/utils/hreForBase';

// TODO: Don't depend on scenario's hreForBase
function getForkEnv(env: HardhatRuntimeEnvironment, deployment: string): HardhatRuntimeEnvironment {
async function getForkEnv(env: HardhatRuntimeEnvironment, deployment: string): Promise<HardhatRuntimeEnvironment> {
const base = env.config.scenario.bases.find(b => b.network == env.network.name && b.deployment == deployment);
if (!base) {
throw new Error(`No fork spec for ${env.network.name}`);
}
return hreForBase(base);
return await hreForBase(base);
}

function getDefaultDeployment(config: HardhatConfig, network: string): string {
Expand Down Expand Up @@ -65,7 +65,7 @@ task('deploy', 'Deploys market')
.addFlag('overwrite', 'overwrites cache')
.addParam('deployment', 'The deployment to deploy')
.setAction(async ({ simulate, noDeploy, noVerify, noVerifyImpl, overwrite, deployment }, env) => {
const maybeForkEnv = simulate ? getForkEnv(env, deployment) : env;
const maybeForkEnv = simulate ? await getForkEnv(env, deployment) : env;
const network = env.network.name;
const tag = `${network}/${deployment}`;
const dm = new DeploymentManager(
Expand Down Expand Up @@ -174,7 +174,7 @@ task('migrate', 'Runs migration')
.addFlag('overwrite', 'overwrites artifact if exists, fails otherwise')
.setAction(
async ({ migration: migrationName, prepare, enact, noEnacted, simulate, overwrite, deployment, impersonate }, env) => {
const maybeForkEnv = simulate ? getForkEnv(env, deployment) : env;
const maybeForkEnv = simulate ? await getForkEnv(env, deployment) : env;
const network = env.network.name;
const dm = new DeploymentManager(
network,
Expand All @@ -193,7 +193,7 @@ task('migrate', 'Runs migration')
const governanceBase = isBridgedDeployment ? env.config.scenario.bases.find(b => b.name === base.auxiliaryBase) : undefined;

if (governanceBase) {
const governanceEnv = hreForBase(governanceBase, simulate);
const governanceEnv = await hreForBase(governanceBase, simulate);
governanceDm = new DeploymentManager(
governanceBase.network,
governanceBase.deployment,
Expand Down Expand Up @@ -246,7 +246,7 @@ task('deploy_and_migrate', 'Runs deploy and migration')
.addParam('deployment', 'The deployment to deploy')
.setAction(
async ({ migration: migrationName, prepare, enact, noEnacted, simulate, overwrite, deployment, impersonate, noDeploy, noVerify, noVerifyImpl }, env) => {
const maybeForkEnv = simulate ? getForkEnv(env, deployment) : env;
const maybeForkEnv = simulate ? await getForkEnv(env, deployment) : env;
const network = env.network.name;
const tag = `${network}/${deployment}`;
const dm = new DeploymentManager(
Expand Down Expand Up @@ -314,7 +314,7 @@ task('deploy_and_migrate', 'Runs deploy and migration')
const governanceBase = isBridgedDeployment ? env.config.scenario.bases.find(b => b.name === base.auxiliaryBase) : undefined;

if (governanceBase) {
const governanceEnv = hreForBase(governanceBase, simulate);
const governanceEnv = await hreForBase(governanceBase, simulate);
governanceDm = new DeploymentManager(
governanceBase.network,
governanceBase.deployment,
Expand Down
2 changes: 1 addition & 1 deletion tasks/scenario/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ task('scenario:spider', 'Runs spider in preparation for scenarios')
const bases: ForkSpec[] = getBasesFromTaskArgs(taskArgs.bases, env);
await Promise.all(bases.map(async (base) => {
if (base.network !== 'hardhat') {
let hre = hreForBase(base);
let hre = await hreForBase(base);
let dm = new DeploymentManager(
base.name,
base.deployment,
Expand Down

0 comments on commit 16d8736

Please sign in to comment.