Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into fix/CAN-717
Browse files Browse the repository at this point in the history
  • Loading branch information
nicosampler committed Feb 26, 2025
2 parents f475543 + fbbf932 commit 92c9029
Show file tree
Hide file tree
Showing 19 changed files with 836 additions and 615 deletions.
9 changes: 7 additions & 2 deletions packages/cli/src/commands/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const commandsConfig: CommandsConfig = {
},
{
flags: '--impersonate <address>',
description: 'Impersonate all calls from the given signer instead of a real wallet. Only works with --fork',
description: 'Impersonate all calls from the given signer instead of a real wallet.',
defaultValue: ANVIL_FIRST_ADDRESS,
},
{
Expand Down Expand Up @@ -113,7 +113,12 @@ export const commandsConfig: CommandsConfig = {
},
{
flags: '--impersonate [addresses]',
description: 'Specify a comma separated list of signers to impersonate. Only works with --dry-run',
description:
'Specify a comma separated list of signers to impersonate. Useful to ensure only specified signers are required to complete a deployment. Only works with --dry-run Only works with --dry-run',
},
{
flags: '--impersonate-all',
description: 'Impersonate all calls from all required wallets. Only works with --dry-run',
},
{
flags: '--keep-alive',
Expand Down
5 changes: 5 additions & 0 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ applyCommandsConfig(program.command('build'), commandsConfig.build)
throw new Error('Cannot build on Cannon Network with --dry-run flag.');
}

// throw an error if `--dry-run`, and `--impersonate` or `--impersonate-all` is not declared
if (options.dryRun && !options.impersonate && !options.impersonateAll) {
throw new Error('Must specify one of `--impersonate` or `--impersonate-all`');
}

// throw an error if the chainId is not consistent with the provider's chainId
await ensureChainIdConsistency(cliSettings.rpcUrl, options.chainId);

Expand Down
63 changes: 45 additions & 18 deletions packages/cli/src/write-script/render-foundry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ import { Transform } from 'node:stream';
import { getAddress } from 'viem';

/**
* This script is used to deploy contracts using Foundry Cast.
* It outputs a bash script that can be used to deploy contracts and execute transactions.
* Note: Make sure you add `.sh` extension to the output file.
* This script is used to deploy contracts using Forge.
* It outputs a solidity script that can be used to deploy contracts and execute transactions.
* Note: Make sure you add `.sol` extension to the output file.
*/

const header = `
const footer = `
}
}
`;

export const createRenderer = (blockNumber: number) =>
new Transform({
objectMode: true,
construct(cb) {
const header = `
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
Expand All @@ -19,42 +28,54 @@ import {Script} from "forge-std/Script.sol";
* @notice The following script is automatically generated by https://usecannon.com
*/
contract CannonDeploy is Script {
mapping(bytes32 => address) public getAddress;
uint256 public deployBlockNumber = ${blockNumber};
mapping(bytes32 => address) public addresses;
mapping(bytes32 => string) public settings;
function run() external {
bytes memory data;
`;
function getAddress(string memory label) external returns (address) {
return addresses[keccak256(bytes(label))];
}
const footer = `
function getSetting(string memory label) external returns (string memory) {
return settings[keccak256(bytes(label))];
}
}
`;
export const createRenderer = () =>
new Transform({
objectMode: true,
construct(cb) {
function run() external {
bytes memory data;
`;

this.push(header); // Bash script header
return cb();
},
transform(line, _, cb) {
const title = `[${line.type}.${line.label}]`;
const indent = ' '.repeat(2);

this.push(`${indent}// ${title}${EOL}`);
if (!line.result) {
// Logging non-transaction steps
this.push(`${indent}// no on-chain transactions required`);
this.push(`${indent}// no on-chain transactions required\n`);
} else {
// Loggin txn types
for (const c in line.result.contracts) {
const fullContractPath = [...line.cloneNames, c].join('.');
this.push(`${indent}// > CONTRACT DEPLOYED: ${line.result.contracts[c].address}\n`);
this.push(`${indent}getAddress[keccak256("${c}")] = address(${getAddress(line.result.contracts[c].address)});\n`);
this.push(
`${indent}addresses[keccak256("${fullContractPath}")] = address(${getAddress(
line.result.contracts[c].address
)});\n`
);
this.push(`${indent}vm.label(${getAddress(line.result.contracts[c].address)}, "${fullContractPath}");\n`);
}

for (const t in line.result.txns) {
this.push(`${indent}// > TRANSACTION EXECUTED: ${Object.keys(line.result.txns[t].events).join(', ')}\n`);
}

for (const s in line.result.settings) {
this.push(
`${indent}settings[keccak256("${[...line.cloneNames, s].join('.')}")] = "${line.result.settings[s]}";\n`
);
}
}

for (const { to, from, input, value } of line.txns) {
Expand All @@ -77,6 +98,12 @@ export const createRenderer = () =>
//this.push(`${indent}${command}${EOL}${EOL}`);
}

this.push(`${indent}// ${line.phase === 'pre' ? 'START' : 'END'} ${title}${EOL}`);

if (line.phase === 'post') {
this.push(EOL);
}

return cb();
},
flush(cb) {
Expand Down
12 changes: 9 additions & 3 deletions packages/cli/src/write-script/stream-steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ class StepEventsStream extends Readable {
}

_construct(cb: (err?: Error | null | undefined) => void): void {
const cloneNames: string[] = [];
const handlePreStepExecute = (type: DumpLine['type'], label: string, step: DumpLine['step'], depth: number) => {
if (type === 'clone') {
this.push({ type, label, depth, step, txns: [] });
if (type === 'clone' || type === 'provision') {
this.push({ phase: 'pre', type, label, depth, step, txns: [], cloneNames });
cloneNames.push(label);
}
};

Expand All @@ -65,7 +67,11 @@ class StepEventsStream extends Readable {
result: ChainArtifacts,
depth: number
) => {
this.push({ type, label, depth, step, result, txns: [] });
if (type === 'clone' || type === 'provision') {
cloneNames.pop();
}

this.push({ phase: 'post', type, label, depth, step, result, txns: [], cloneNames });
};

this.runtime.on(Events.PreStepExecute, handlePreStepExecute);
Expand Down
10 changes: 9 additions & 1 deletion packages/cli/src/write-script/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ export type DumpLine =
| (BaseDumpLine & {
type: 'clone';
step: StepClone;
})
| (BaseDumpLine & {
type: 'import';
step: StepPull;
})
| (BaseDumpLine & {
type: 'provision';
step: StepClone;
});

export type DumpRenderer = () => any;
export type DumpRenderer = (forkBlockNumber: number) => any;
4 changes: 3 additions & 1 deletion packages/cli/src/write-script/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ export async function createWriteScript(

const events = createStepsStream(runtime);

const blockNumber = await runtime.provider.getBlockNumber();

const stream = events.stream // Listen for step execution events
.pipe(events.fetchTransactions) // asynchronically add the executed transactions
.pipe(createRenderer()) // render step lines into the desired format
.pipe(createRenderer(Number(blockNumber))) // render step lines into the desired format
.pipe(createWriteStream(targetFile)); // save to file

return {
Expand Down
Loading

0 comments on commit 92c9029

Please sign in to comment.