Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Commit

Permalink
FM-406: Return empty bytes from eth_call if it's a deploy (#410)
Browse files Browse the repository at this point in the history
* FM-406: Return created contract address from eth_call if it's a deploy

* FM-406: Return empty from call on deploy, like Lotus

* FM-406: Try eth_call with deploy
  • Loading branch information
aakoshh authored Nov 27, 2023
1 parent eb0a30b commit 37e20de
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
12 changes: 9 additions & 3 deletions fendermint/eth/api/examples/ethers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,9 +563,15 @@ where

tracing::info!(sighash = ?deployer.tx.sighash(), "deployment tx");

// NOTE: This will call eth_estimateGas to figure out how much gas to use, because we don't set it,
// unlike in the case of the example transfer. What the [Provider::fill_transaction] will _also_ do
// is estimate the fees using eth_feeHistory, here:
// Try with a call just because Remix does.
request(
"eth_call w/ deploy",
provider.call(&deployer.tx, None).await,
|_| true,
)?;

// NOTE: This would call eth_estimateGas to figure out how much gas to use, if we didn't set it.
// What the [Provider::fill_transaction] will _also_ do is estimate the fees using eth_feeHistory, here:
// https://github.com/gakonst/ethers-rs/blob/df165b84229cdc1c65e8522e0c1aeead3746d9a8/ethers-providers/src/rpc/provider.rs#LL300C30-L300C51
// These were set to zero in the earlier example transfer, ie. it was basically paid for by the miner (which is not at the moment charged),
// so the test passed. Here, however, there will be a non-zero cost to pay by the deployer, and therefore those balances
Expand Down
15 changes: 12 additions & 3 deletions fendermint/eth/api/src/apis/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use ethers_core::utils::rlp;
use fendermint_rpc::message::MessageFactory;
use fendermint_rpc::query::QueryClient;
use fendermint_rpc::response::{decode_fevm_invoke, decode_fevm_return_data};
use fendermint_vm_actor_interface::eam::EthAddress;
use fendermint_vm_actor_interface::eam::{EthAddress, EAM_ACTOR_ADDR};
use fendermint_vm_actor_interface::evm;
use fendermint_vm_message::chain::ChainMessage;
use fendermint_vm_message::query::FvmQueryHeight;
Expand Down Expand Up @@ -634,6 +634,7 @@ where
C: Client + Sync + Send,
{
let msg = to_fvm_message(tx.into(), true)?;
let is_create = msg.to == EAM_ACTOR_ADDR;
let height = data.query_height(block_id).await?;
let response = data.client.call(msg, height).await?;
let deliver_tx = response.value;
Expand All @@ -649,11 +650,19 @@ where
),
};
error_with_data(ExitCode::new(deliver_tx.code.value()), msg, data)
} else if is_create {
// It's not clear why some tools like Remix call this with deployment transaction, but they do.
// We could parse the deployed contract address, but it would be of very limited use;
// the call effect isn't persisted, so one would have to send an actual transaction
// and then run a call on `pending` state with this address to have a chance to hit
// that contract before the transaction is included in a block, assuming address
// creation is deterministic.
// Lotus returns empty: https://github.com/filecoin-project/lotus/blob/v1.23.1-rc2/node/impl/full/eth.go#L1091-L1094
Ok(Default::default())
} else {
let return_data = decode_fevm_invoke(&deliver_tx)
.context("error decoding data from deliver_tx in query")?;

Ok(et::Bytes::from(return_data))
Ok(return_data.into())
}
}

Expand Down
2 changes: 1 addition & 1 deletion fendermint/rpc/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ pub fn decode_fevm_return_data(data: RawBytes) -> anyhow::Result<Vec<u8>> {
// that is, it's as if it was returning `CreateReturn`, it's returning `RawBytes` encoded as IPLD.
fvm_ipld_encoding::from_slice::<BytesDe>(&data)
.map(|bz| bz.0)
.map_err(|e| anyhow!("failed to deserialize bytes returned by FEVM: {e}"))
.map_err(|e| anyhow!("failed to deserialize bytes returned by FEVM method invocation: {e}"))
}

0 comments on commit 37e20de

Please sign in to comment.