Skip to content

Commit

Permalink
Merge branch 'main' into elmattic/optional-eth-mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
elmattic authored Feb 26, 2025
2 parents 23276a4 + c713838 commit 8f8969c
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 92 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@

- [#5319](https://github.com/ChainSafe/forest/pull/5319) Improve the ergonomics of the `forest-tool api generate-test-snapshot` subcommand.

- [#5342](https://github.com/ChainSafe/forest/pull/5342) Improved the ergonomics of handling addresses in the `Filecoin.EthGetLogs` and `Filecoin.EthNewFilter` to accept both single addresses and arrays of addresses. This conforms to the Ethereum RPC API.

### Changed

- [#5237](https://github.com/ChainSafe/forest/pull/5237) Stylistic changes to FIL pretty printing.
Expand All @@ -85,6 +87,8 @@

### Removed

- [#5344](https://github.com/ChainSafe/forest/pull/5344) Removed the last traces of the `forest-cli attach` command.

### Fixed

- [#5111](https://github.com/ChainSafe/forest/issues/5111) Make F3 work when the node Kademlia is disabled.
Expand Down
2 changes: 0 additions & 2 deletions src/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::cli_shared::logger;
use crate::daemon::get_actual_chain_name;
use crate::rpc::{self, prelude::*};
use crate::shim::address::{CurrentNetwork, Network};
use anyhow::bail;
use clap::Parser;
use std::ffi::OsString;

Expand Down Expand Up @@ -45,7 +44,6 @@ where
Subcommand::Send(cmd) => cmd.run(client).await,
Subcommand::Info(cmd) => cmd.run(client).await,
Subcommand::Snapshot(cmd) => cmd.run(client).await,
Subcommand::Attach { .. } => bail!("the `attach` subcommand has been removed. Please raise an issue if this breaks a workflow for you"),
Subcommand::Shutdown(cmd) => cmd.run(client).await,
Subcommand::Healthcheck(cmd) => cmd.run(client).await,
Subcommand::F3(cmd) => cmd.run(client).await,
Expand Down
3 changes: 0 additions & 3 deletions src/cli/subcommands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ pub enum Subcommand {
#[command(subcommand)]
Info(InfoCommand),

/// `[REMOVED]` Attach to daemon via a JavaScript console
Attach { _ignored: Vec<String> },

/// Shutdown Forest
Shutdown(ShutdownCommand),

Expand Down
93 changes: 26 additions & 67 deletions src/rpc/methods/eth/filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -739,9 +739,9 @@ mod tests {
to_block: Some("latest".into()),
address: vec![
EthAddress::from_str("0xff38c072f286e3b20b3954ca9f99c05fbecc64aa").unwrap(),
],
topics: None,
block_hash: None,
]
.into(),
..Default::default()
};

let chain_height = 50;
Expand All @@ -759,9 +759,9 @@ mod tests {
to_block: Some("invalid".into()),
address: vec![
EthAddress::from_str("0xff38c072f286e3b20b3954ca9f99c05fbecc64aa").unwrap(),
],
topics: None,
block_hash: None,
]
.into(),
..Default::default()
};

let chain_height = 50;
Expand Down Expand Up @@ -876,9 +876,9 @@ mod tests {
to_block: Some("latest".into()),
address: vec![
EthAddress::from_str("0xff38c072f286e3b20b3954ca9f99c05fbecc64aa").unwrap(),
],
topics: None,
block_hash: None,
]
.into(),
..Default::default()
};

let chain_height = 50;
Expand Down Expand Up @@ -911,13 +911,11 @@ mod tests {
let event_handler = EthEventHandler::new();
let mut filter_ids = Vec::new();
let filter_spec = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![
EthAddress::from_str("0xff38c072f286e3b20b3954ca9f99c05fbecc64aa").unwrap(),
],
topics: None,
block_hash: None,
]
.into(),
..Default::default()
};

let filter_id = event_handler.eth_new_filter(&filter_spec, 0).unwrap();
Expand All @@ -941,13 +939,7 @@ mod tests {

#[test]
fn test_do_match_address() {
let empty_spec = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: None,
block_hash: None,
};
let empty_spec = EthFilterSpec::default();

let addr0 = Address::from_str("t410f744ma4xsq3r3eczzktfj7goal67myzfkusna2hy").unwrap();
let eth_addr0 = EthAddress::from_str("0xff38c072f286e3b20b3954ca9f99c05fbecc64aa").unwrap();
Expand Down Expand Up @@ -993,11 +985,8 @@ mod tests {

// Matching the given address 0
let spec0 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![eth_addr0.clone()],
topics: None,
block_hash: None,
address: vec![eth_addr0.clone()].into(),
..Default::default()
};

assert!(spec0.matches(&addr0, &[]).unwrap());
Expand All @@ -1006,11 +995,8 @@ mod tests {

// Matching the given address 0 or 1
let spec1 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![eth_addr0.clone(), eth_addr1.clone()],
topics: None,
block_hash: None,
address: vec![eth_addr0.clone(), eth_addr1.clone()].into(),
..Default::default()
};

assert!(spec1.matches(&addr0, &[]).unwrap());
Expand Down Expand Up @@ -1070,111 +1056,84 @@ mod tests {
.unwrap();

let spec1 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: Some(EthTopicSpec(vec![EthHashList::Single(None)])),
block_hash: None,
..Default::default()
};

assert!(spec1.matches(&addr0, &entries0).unwrap());

let spec2 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: Some(EthTopicSpec(vec![
EthHashList::Single(None),
EthHashList::Single(None),
])),
block_hash: None,
..Default::default()
};

assert!(spec2.matches(&addr0, &entries0).unwrap());

let spec2 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: Some(EthTopicSpec(vec![EthHashList::Single(Some(
topic0.clone(),
))])),
block_hash: None,
..Default::default()
};

assert!(spec2.matches(&addr0, &entries0).unwrap());

let spec3 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: Some(EthTopicSpec(vec![EthHashList::List(vec![topic0.clone()])])),
block_hash: None,
..Default::default()
};

assert!(spec3.matches(&addr0, &entries0).unwrap());

let spec4 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: Some(EthTopicSpec(vec![EthHashList::List(vec![
topic1.clone(),
topic0.clone(),
])])),
block_hash: None,
..Default::default()
};

assert!(spec4.matches(&addr0, &entries0).unwrap());

let spec5 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: Some(EthTopicSpec(vec![EthHashList::Single(Some(
topic1.clone(),
))])),
block_hash: None,
..Default::default()
};

assert!(!spec5.matches(&addr0, &entries0).unwrap());

let spec6 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: Some(EthTopicSpec(vec![EthHashList::List(vec![
topic2.clone(),
topic3.clone(),
])])),
block_hash: None,
..Default::default()
};

assert!(!spec6.matches(&addr0, &entries0).unwrap());

let spec7 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: Some(EthTopicSpec(vec![
EthHashList::Single(Some(topic1.clone())),
EthHashList::Single(Some(topic1.clone())),
])),
block_hash: None,
..Default::default()
};

assert!(!spec7.matches(&addr0, &entries0).unwrap());

let spec8 = EthFilterSpec {
from_block: None,
to_block: None,
address: vec![],
topics: Some(EthTopicSpec(vec![
EthHashList::Single(Some(topic0.clone())),
EthHashList::Single(Some(topic1.clone())),
EthHashList::Single(Some(topic3.clone())),
])),
block_hash: None,
..Default::default()
};

assert!(!spec8.matches(&addr0, &entries0).unwrap());
Expand Down
42 changes: 40 additions & 2 deletions src/rpc/methods/eth/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use anyhow::ensure;
use ipld_core::serde::SerdeError;
use libsecp256k1::util::FULL_PUBLIC_KEY_SIZE;
use serde::de::{value::StringDeserializer, IntoDeserializer};
use std::hash::Hash;
use std::{hash::Hash, ops::Deref};
use uuid::Uuid;

pub const METHOD_GET_BYTE_CODE: u64 = 3;
Expand Down Expand Up @@ -401,6 +401,44 @@ pub enum EthHashList {
#[derive(Default, Serialize, Deserialize, Debug, Clone, JsonSchema)]
pub struct EthTopicSpec(pub Vec<EthHashList>);

/// Represents an [`EthAddress`] or a collection of thereof. This allows the caller to either use,
/// e.g., `0x1234...` or `["0x1234...", "0x5678..."]` as the address parameter.
#[derive(PartialEq, Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[serde(untagged)]
pub enum EthAddressList {
List(Vec<EthAddress>),
Single(EthAddress),
}

impl Default for EthAddressList {
fn default() -> Self {
EthAddressList::List(Vec::new())
}
}

impl From<EthAddress> for EthAddressList {
fn from(addr: EthAddress) -> Self {
EthAddressList::Single(addr)
}
}

impl From<Vec<EthAddress>> for EthAddressList {
fn from(addrs: Vec<EthAddress>) -> Self {
EthAddressList::List(addrs)
}
}

impl Deref for EthAddressList {
type Target = [EthAddress];

fn deref(&self) -> &Self::Target {
match self {
EthAddressList::List(addrs) => addrs,
EthAddressList::Single(addr) => std::slice::from_ref(addr),
}
}
}

/// Represents a filter specification for querying Ethereum event logs.
/// This struct can be used to specify criteria for filtering Ethereum event logs based on block range,
/// address, topics, and block hash. It is useful for making requests to Ethereum nodes to fetch logs
Expand Down Expand Up @@ -440,7 +478,7 @@ pub struct EthFilterSpec {
pub from_block: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub to_block: Option<String>,
pub address: Vec<EthAddress>,
pub address: EthAddressList,
pub topics: Option<EthTopicSpec>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub block_hash: Option<EthHash>,
Expand Down
44 changes: 26 additions & 18 deletions src/tool/subcommands/api_cmd/api_compare_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1232,22 +1232,30 @@ fn eth_tests() -> Vec<RpcTest> {
.unwrap(),
));
}
tests.push(RpcTest::basic(
EthNewFilter::request_with_alias(
(EthFilterSpec {
from_block: None,
to_block: None,
address: vec![EthAddress::from_str(
"0xff38c072f286e3b20b3954ca9f99c05fbecc64aa",
)
.unwrap()],
topics: None,
block_hash: None,
},),
use_alias,
)
.unwrap(),
));

let cases = [
EthAddressList::List(vec![]),
EthAddressList::List(vec![
EthAddress::from_str("0x0c1d86d34e469770339b53613f3a2343accd62cb").unwrap(),
EthAddress::from_str("0x89beb26addec4bc7e9f475aacfd084300d6de719").unwrap(),
]),
EthAddressList::Single(
EthAddress::from_str("0x0c1d86d34e469770339b53613f3a2343accd62cb").unwrap(),
),
];

for address in cases {
tests.push(RpcTest::basic(
EthNewFilter::request_with_alias(
(EthFilterSpec {
address,
..Default::default()
},),
use_alias,
)
.unwrap(),
));
}
tests.push(RpcTest::basic(
EthNewPendingTransactionFilter::request_with_alias((), use_alias).unwrap(),
));
Expand Down Expand Up @@ -1576,7 +1584,7 @@ fn eth_tests_with_tipset<DB: Blockstore>(store: &Arc<DB>, shared_tipset: &Tipset
EthGetLogs::request((EthFilterSpec {
from_block: Some(format!("0x{:x}", shared_tipset.epoch())),
to_block: Some(format!("0x{:x}", shared_tipset.epoch())),
address: vec![],
address: Default::default(),
topics: None,
block_hash: None,
},))
Expand All @@ -1587,7 +1595,7 @@ fn eth_tests_with_tipset<DB: Blockstore>(store: &Arc<DB>, shared_tipset: &Tipset
EthGetLogs::request((EthFilterSpec {
from_block: Some(format!("0x{:x}", shared_tipset.epoch() - 100)),
to_block: Some(format!("0x{:x}", shared_tipset.epoch())),
address: vec![],
address: Default::default(),
topics: None,
block_hash: None,
},))
Expand Down

0 comments on commit 8f8969c

Please sign in to comment.