Skip to content

Commit

Permalink
feat(cheatcodes): access broadcast artifacts (#9107)
Browse files Browse the repository at this point in the history
* refac(`script`): extract script sequence and related types to new crate

* replace MultiChainSequence in script crate

* replace TransactionWithMetadata and AdditionalContract

* replace ScriptSequence

* replace all underlying ScriptSequence and related types

* doc nits

* add `ScriptTransactionBuilder`

* remove `TxWithMetadata`

* mv verify fns and use `ScriptSequence` directly

* clippy

* feat(`cheatcodes`): vm.getDeployment

* cargo cheats

* getBroadcast by txType

* get all broadcast txs

* nits

* fix

* feat: getBroadcasts by txType

* nit

* fix

* mv `BroadcastReader` to script-sequence

* fix: search all broadcast files and then apply filters

* fix: ignore run-latest to avoid duplicating entries

* nit

* sort by descending block number

* tests

* feat(`CheatsConfig`): add `broadcast` dir path

* feat: read multichain sequences

* nit

* minify json

* use walkdir

* fix

* fix path

* feat: getDeployment cheatcodes

* feat: read broadcasts with multiple tx types

* test: getDeployment

* nit

* fmt

* fix

* nit

* cli test

* nit

* remove solidity test

* nit
  • Loading branch information
yash-atreya authored Oct 30, 2024
1 parent 748af79 commit 2bb446e
Show file tree
Hide file tree
Showing 12 changed files with 802 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/cheatcodes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ foundry-config.workspace = true
foundry-evm-core.workspace = true
foundry-evm-traces.workspace = true
foundry-wallets.workspace = true
forge-script-sequence.workspace = true

alloy-dyn-abi.workspace = true
alloy-json-abi.workspace = true
Expand Down
169 changes: 169 additions & 0 deletions crates/cheatcodes/assets/cheatcodes.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/cheatcodes/spec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@ impl Cheatcodes<'static> {
Vm::StorageAccess::STRUCT.clone(),
Vm::Gas::STRUCT.clone(),
Vm::DebugStep::STRUCT.clone(),
Vm::BroadcastTxSummary::STRUCT.clone(),
]),
enums: Cow::Owned(vec![
Vm::CallerMode::ENUM.clone(),
Vm::AccountAccessKind::ENUM.clone(),
Vm::ForgeContext::ENUM.clone(),
Vm::BroadcastTxType::ENUM.clone(),
]),
errors: Vm::VM_ERRORS.iter().copied().cloned().collect(),
events: Cow::Borrowed(&[]),
Expand Down
63 changes: 63 additions & 0 deletions crates/cheatcodes/spec/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,31 @@ interface Vm {
address contractAddr;
}

/// The transaction type (`txType`) of the broadcast.
enum BroadcastTxType {
/// Represents a CALL broadcast tx.
Call,
/// Represents a CREATE broadcast tx.
Create,
/// Represents a CREATE2 broadcast tx.
Create2
}

/// Represents a transaction's broadcast details.
struct BroadcastTxSummary {
/// The hash of the transaction that was broadcasted
bytes32 txHash;
/// Represent the type of transaction among CALL, CREATE, CREATE2
BroadcastTxType txType;
/// The address of the contract that was called or created.
/// This is address of the contract that is created if the txType is CREATE or CREATE2.
address contractAddress;
/// The block number the transaction landed in.
uint64 blockNumber;
/// Status of the transaction, retrieved from the transaction receipt.
bool success;
}

// ======== EVM ========

/// Gets the address for a given private key.
Expand Down Expand Up @@ -1670,6 +1695,44 @@ interface Vm {
#[cheatcode(group = Filesystem)]
function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode);

/// Returns the most recent broadcast for the given contract on `chainId` matching `txType`.
///
/// For example:
///
/// The most recent deployment can be fetched by passing `txType` as `CREATE` or `CREATE2`.
///
/// The most recent call can be fetched by passing `txType` as `CALL`.
#[cheatcode(group = Filesystem)]
function getBroadcast(string memory contractName, uint64 chainId, BroadcastTxType txType) external returns (BroadcastTxSummary memory);

/// Returns all broadcasts for the given contract on `chainId` with the specified `txType`.
///
/// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber.
#[cheatcode(group = Filesystem)]
function getBroadcasts(string memory contractName, uint64 chainId, BroadcastTxType txType) external returns (BroadcastTxSummary[] memory);

/// Returns all broadcasts for the given contract on `chainId`.
///
/// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber.
#[cheatcode(group = Filesystem)]
function getBroadcasts(string memory contractName, uint64 chainId) external returns (BroadcastTxSummary[] memory);

/// Returns the most recent deployment for the current `chainId`.
#[cheatcode(group = Filesystem)]
function getDeployment(string memory contractName) external returns (address deployedAddress);

/// Returns the most recent deployment for the given contract on `chainId`
#[cheatcode(group = Filesystem)]
function getDeployment(string memory contractName, uint64 chainId) external returns (address deployedAddress);

/// Returns all deployments for the given contract on `chainId`
///
/// Sorted in descending order of deployment time i.e descending order of BroadcastTxSummary.blockNumber.
///
/// The most recent deployment is the first element, and the oldest is the last.
#[cheatcode(group = Filesystem)]
function getDeployments(string memory contractName, uint64 chainId) external returns (address[] memory deployedAddresses);

// -------- Foreign Function Interface --------

/// Performs a foreign function call via the terminal.
Expand Down
4 changes: 4 additions & 0 deletions crates/cheatcodes/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub struct CheatsConfig {
pub fs_permissions: FsPermissions,
/// Project root
pub root: PathBuf,
/// Absolute Path to broadcast dir i.e project_root/broadcast
pub broadcast: PathBuf,
/// Paths (directories) where file reading/writing is allowed
pub allowed_paths: Vec<PathBuf>,
/// How the evm was configured by the user
Expand Down Expand Up @@ -87,6 +89,7 @@ impl CheatsConfig {
paths: config.project_paths(),
fs_permissions: config.fs_permissions.clone().joined(config.root.as_ref()),
root: config.root.0.clone(),
broadcast: config.root.0.clone().join(&config.broadcast),
allowed_paths,
evm_opts,
labels: config.labels.clone(),
Expand Down Expand Up @@ -216,6 +219,7 @@ impl Default for CheatsConfig {
paths: ProjectPathsConfig::builder().build_with_root("./"),
fs_permissions: Default::default(),
root: Default::default(),
broadcast: Default::default(),
allowed_paths: vec![],
evm_opts: Default::default(),
labels: Default::default(),
Expand Down
Loading

0 comments on commit 2bb446e

Please sign in to comment.