Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions crates/cast/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,17 +338,16 @@ pub async fn run_command(args: CastArgs) -> Result<()> {
Cast::new(provider).base_fee(block.unwrap_or(BlockId::Number(Latest))).await?
)?
}
CastSubcommand::Block { block, full, field, raw, rpc } => {
CastSubcommand::Block { block, full, fields, raw, rpc } => {
let config = rpc.load_config()?;
let provider = utils::get_provider(&config)?;

// Can use either --raw or specify raw as a field
let raw = raw || field.as_ref().is_some_and(|f| f == "raw");
let raw = raw || fields.contains(&"raw".into());

sh_println!(
"{}",
Cast::new(provider)
.block(block.unwrap_or(BlockId::Number(Latest)), full, field, raw)
.block(block.unwrap_or(BlockId::Number(Latest)), full, fields, raw)
.await?
)?
}
Expand Down
32 changes: 19 additions & 13 deletions crates/cast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ impl<P: Provider<AnyNetwork>> Cast<P> {
/// let provider =
/// ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
/// let cast = Cast::new(provider);
/// let block = cast.block(5, true, None, false).await?;
/// let block = cast.block(5, true, vec![], false).await?;
/// println!("{}", block);
/// # Ok(())
/// # }
Expand All @@ -348,14 +348,11 @@ impl<P: Provider<AnyNetwork>> Cast<P> {
&self,
block: B,
full: bool,
field: Option<String>,
fields: Vec<String>,
raw: bool,
) -> Result<String> {
let block = block.into();
if let Some(ref field) = field
&& field == "transactions"
&& !full
{
if fields.contains(&"transactions".into()) && !full {
eyre::bail!("use --full to view transactions")
}

Expand All @@ -369,9 +366,17 @@ impl<P: Provider<AnyNetwork>> Cast<P> {
Ok(if raw {
let header: Header = block.into_inner().header.inner.try_into_header()?;
format!("0x{}", hex::encode(alloy_rlp::encode(&header)))
} else if let Some(ref field) = field {
get_pretty_block_attr(&block, field)
.unwrap_or_else(|| format!("{field} is not a valid block field"))
} else if !fields.is_empty() {
let mut result = String::new();
for field in fields {
result.push_str(
&get_pretty_block_attr(&block, &field)
.unwrap_or_else(|| format!("{field} is not a valid block field")),
);

result.push('\n');
}
result.trim_end().to_string()
} else if shell::is_json() {
serde_json::to_value(&block).unwrap().to_string()
} else {
Expand All @@ -385,7 +390,7 @@ impl<P: Provider<AnyNetwork>> Cast<P> {
block.into(),
false,
// Select only select field
Some(field),
vec![field],
false,
)
.await?
Expand Down Expand Up @@ -414,14 +419,15 @@ impl<P: Provider<AnyNetwork>> Cast<P> {
0,
false,
// Select only block hash
Some(String::from("hash")),
vec![String::from("hash")],
false,
)
.await?;

Ok(match &genesis_hash[..] {
"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" => {
match &(Self::block(self, 1920000, false, Some("hash".to_string()), false).await?)[..]
match &(Self::block(self, 1920000, false, vec![String::from("hash")], false)
.await?)[..]
{
"0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f" => {
"etclive"
Expand Down Expand Up @@ -464,7 +470,7 @@ impl<P: Provider<AnyNetwork>> Cast<P> {
"0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34" => "bsctest",
"0x0d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5b" => "bsc",
"0x31ced5b9beb7f8782b014660da0cb18cc409f121f408186886e1ca3e8eeca96b" => {
match &(Self::block(self, 1, false, Some(String::from("hash")), false).await?)[..] {
match &(Self::block(self, 1, false, vec![String::from("hash")], false).await?)[..] {
"0x738639479dc82d199365626f90caa82f7eafcfe9ed354b456fb3d294597ceb53" => {
"avalanche-fuji"
}
Expand Down
9 changes: 4 additions & 5 deletions crates/cast/src/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ use crate::cmd::{
use alloy_ens::NameOrAddress;
use alloy_primitives::{Address, B256, Selector, U256};
use alloy_rpc_types::BlockId;
use clap::{Parser, Subcommand, ValueHint};
use clap::{ArgAction, Parser, Subcommand, ValueHint};
use eyre::Result;
use foundry_cli::opts::{EtherscanOpts, GlobalArgs, RpcOpts};
use foundry_common::version::{LONG_VERSION, SHORT_VERSION};
use std::{path::PathBuf, str::FromStr};

/// A Swiss Army knife for interacting with Ethereum applications from the command line.
#[derive(Parser)]
#[command(
Expand Down Expand Up @@ -379,11 +378,11 @@ pub enum CastSubcommand {
block: Option<BlockId>,

/// If specified, only get the given field of the block.
#[arg(long, short)]
field: Option<String>,
#[arg(short, long = "field", aliases = ["fields"], num_args = 0.., action = ArgAction::Append, value_delimiter = ',')]
fields: Vec<String>,

/// Print the raw RLP encoded block header.
#[arg(long, conflicts_with = "field")]
#[arg(long, conflicts_with = "fields")]
raw: bool,

#[arg(long, env = "CAST_FULL_BLOCK")]
Expand Down
54 changes: 28 additions & 26 deletions crates/cast/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,17 @@ transactions: [
"#]]);

// <https://etherscan.io/block/15007840>
cmd.cast_fuse().args(["block", "15007840", "-f", "hash", "--rpc-url", eth_rpc_url.as_str()]);
cmd.cast_fuse().args([
"block",
"15007840",
"-f",
"hash,timestamp",
"--rpc-url",
eth_rpc_url.as_str(),
]);
cmd.assert_success().stdout_eq(str![[r#"
0x950091817a57e22b6c1f3b951a15f52d41ac89b299cc8f9c89bb6d185f80c415
1655904485

"#]]);
});
Expand Down Expand Up @@ -1312,6 +1320,7 @@ casttest!(to_base, |_prj, cmd| {
});

// tests that revert reason is only present if transaction has reverted.

casttest!(receipt_revert_reason, |_prj, cmd| {
let rpc = next_http_archive_rpc_url();

Expand All @@ -1323,27 +1332,25 @@ casttest!(receipt_revert_reason, |_prj, cmd| {
rpc.as_str(),
])
.assert_success()
.stdout_eq(str![[r#"

.stdout_eq(format!(r#"
blockHash 0x2cfe65be49863676b6dbc04d58176a14f39b123f1e2f4fea0383a2d82c2c50d0
blockNumber 16239315
contractAddress
contractAddress {}
cumulativeGasUsed 10743428
effectiveGasPrice 10539984136
from 0x199D5ED7F45F4eE35960cF22EAde2076e95B253F
gasUsed 21000
logs []
logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
root
root {}
status 1 (success)
transactionHash 0x44f2aaa351460c074f2cb1e5a9e28cbc7d83f33e425101d2de14331c7b7ec31e
transactionIndex 116
type 0
blobGasPrice
blobGasUsed
blobGasPrice {}
blobGasUsed {}
to 0x91da5bf3F8Eb72724E6f50Ec6C3D199C6355c59c

"#]]);
"#,"", "", "", ""));

let rpc = next_http_archive_rpc_url();

Expand All @@ -1356,30 +1363,27 @@ to 0x91da5bf3F8Eb72724E6f50Ec6C3D199C6355c59c
rpc.as_str(),
])
.assert_success()
.stdout_eq(str![[r#"

.stdout_eq(format!(r#"
blockHash 0x883f974b17ca7b28cb970798d1c80f4d4bb427473dc6d39b2a7fe24edc02902d
blockNumber 14839405
contractAddress
contractAddress {}
cumulativeGasUsed 20273649
effectiveGasPrice 21491736378
from 0x3cF412d970474804623bb4e3a42dE13F9bCa5436
gasUsed 24952
logs []
logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
root
root {}
status 0 (failed)
transactionHash 0x0e07d8b53ed3d91314c80e53cf25bcde02084939395845cbb625b029d568135c
transactionIndex 173
type 2
blobGasPrice
blobGasUsed
blobGasPrice {}
blobGasUsed {}
to 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
revertReason [..]Transaction too old, data: "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000135472616e73616374696f6e20746f6f206f6c6400000000000000000000000000"

"#]]);
"#,"","","",""));
});

// tests that the revert reason is loaded using the correct `from` address.
casttest!(revert_reason_from, |_prj, cmd| {
let rpc = next_rpc_endpoint(NamedChain::Sepolia);
Expand All @@ -1391,28 +1395,26 @@ casttest!(revert_reason_from, |_prj, cmd| {
rpc.as_str(),
])
.assert_success()
.stdout_eq(str![[r#"

.stdout_eq(format!(r#"
blockHash 0x32663d7730c9ea8e1de6d99854483e25fcc05bb56c91c0cc82f9f04944fbffc1
blockNumber 7823353
contractAddress
contractAddress {}
cumulativeGasUsed 7500797
effectiveGasPrice 14296851013
from 0x3583fF95f96b356d716881C871aF7Eb55ea34a93
gasUsed 25815
logs []
logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
root
root {}
status 0 (failed)
transactionHash 0x10ee70cf9f5ced5c515e8d53bfab5ea9f5c72cd61b25fba455c8355ee286c4e4
transactionIndex 96
type 0
blobGasPrice
blobGasUsed
blobGasPrice {}
blobGasUsed {}
to 0x91b5d4111a4C038153b24e31F75ccdC47123595d
revertReason Counter is too large, data: "0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000014436f756e74657220697320746f6f206c61726765000000000000000000000000"

"#]]);
"#, "", "", "", ""));
});

// tests that `cast --parse-bytes32-address` command is working correctly.
Expand Down
Loading