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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
- [#4463](https://github.com/ChainSafe/forest/issues/4463) Add support for the
`Filecoin.EthGetTransactionByHash` RPC method.

- [#4613](https://github.com/ChainSafe/forest/issues/4613) Add support for the
`Filecoin.EthCall` RPC method.

### Changed

- [#4583](https://github.com/ChainSafe/forest/pull/4583) Removed the expiration
Expand Down
29 changes: 29 additions & 0 deletions src/rpc/methods/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1870,6 +1870,35 @@ impl RpcMethod<1> for EthGetTransactionHashByCid {
}
}

pub enum EthCall {}
impl RpcMethod<2> for EthCall {
const NAME: &'static str = "Filecoin.EthCall";
const NAME_ALIAS: Option<&'static str> = Some("eth_call");
const N_REQUIRED_PARAMS: usize = 1;
const PARAM_NAMES: [&'static str; 2] = ["tx", "block_param"];
const API_PATHS: ApiPaths = ApiPaths::V1;
const PERMISSION: Permission = Permission::Read;
type Params = (EthCallMessage, BlockNumberOrHash);
type Ok = EthBytes;
async fn handle(
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
(tx, block_param): Self::Params,
) -> Result<Self::Ok, ServerError> {
let msg = tx.try_into()?;
let ts = tipset_by_block_number_or_hash(ctx.chain_store(), block_param)?;
let invoke_result = ctx.state_manager.call(&msg, Some(ts))?;

if msg.to() == FilecoinAddress::ETHEREUM_ACCOUNT_MANAGER_ACTOR {
Ok(EthBytes::default())
} else {
let msg_rct = invoke_result.msg_rct.context("no message receipt")?;

let bytes = decode_payload(&msg_rct.return_data(), CBOR)?;
Ok(bytes)
}
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
12 changes: 12 additions & 0 deletions src/rpc/methods/eth/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: Apache-2.0, MIT

use super::*;
use libipld::error::SerdeError;
use serde::de::{value::StringDeserializer, IntoDeserializer};

pub const METHOD_GET_BYTE_CODE: u64 = 3;
pub const METHOD_GET_STORAGE_AT: u64 = 5;
Expand Down Expand Up @@ -30,6 +32,16 @@ impl From<RawBytes> for EthBytes {
}
}

impl FromStr for EthBytes {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let deserializer: StringDeserializer<SerdeError> = String::from_str(s)?.into_deserializer();
let bytes = crate::lotus_json::hexify_vec_bytes::deserialize(deserializer)?;
Ok(Self(bytes))
}
}

#[derive(Debug, Deserialize, Serialize)]
pub struct GetBytecodeReturn(pub Option<Cid>);

Expand Down
1 change: 1 addition & 0 deletions src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ macro_rules! for_each_method {
$callback!(crate::rpc::eth::EthProtocolVersion);
$callback!(crate::rpc::eth::EthGetTransactionByHash);
$callback!(crate::rpc::eth::EthGetTransactionHashByCid);
$callback!(crate::rpc::eth::EthCall);

// gas vertical
$callback!(crate::rpc::gas::GasEstimateGasLimit);
Expand Down
17 changes: 17 additions & 0 deletions src/tool/subcommands/api_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,23 @@ fn eth_tests() -> Vec<RpcTest> {
tests.push(RpcTest::identity(
EthProtocolVersion::request_with_alias((), use_alias).unwrap(),
));
tests.push(RpcTest::identity(
EthCall::request_with_alias(
(
EthCallMessage {
to: Some(
EthAddress::from_str("0x0c1d86d34e469770339b53613f3a2343accd62cb")
.unwrap(),
),
data: "0xf8b2cb4f000000000000000000000000CbfF24DED1CE6B53712078759233Ac8f91ea71B6".parse().unwrap(),
..EthCallMessage::default()
},
BlockNumberOrHash::from_predefined(Predefined::Latest),
),
use_alias,
)
.unwrap(),
));
}
tests
}
Expand Down