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

Commit

Permalink
FM-407: Insert 0x00..00 for system account (#409)
Browse files Browse the repository at this point in the history
* FM-407: Insert 0x00..00 for system account

* FM-407: Use implicit execution for 0x00..00

* FM-407: Try a read-only call
  • Loading branch information
aakoshh authored Nov 9, 2023
1 parent ecd2c9f commit 0169123
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 9 deletions.
10 changes: 10 additions & 0 deletions fendermint/eth/api/examples/ethers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ where
// Calling with 0 nonce so the node figures out the latest value.
let mut probe_tx = transfer.clone();
probe_tx.set_nonce(0);

let probe_height = BlockId::Number(BlockNumber::Number(bn));

request(
Expand Down Expand Up @@ -558,6 +559,15 @@ where
*coin_balance == U256::from(10000)
})?;

// Calling with 0x00..00 address so we see if it world work for calls by clients that set nothing.
let coin_balance = coin_balance.from(Address::default());

request(
"eth_call w/ 0x00..00",
coin_balance.call().await,
|coin_balance| *coin_balance == U256::from(10000),
)?;

// We could calculate the storage location of the balance of the owner of the contract,
// but let's just see what it returns with at slot 0. See an example at
// https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getstorageat
Expand Down
2 changes: 1 addition & 1 deletion fendermint/vm/actor_interface/src/eam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub enum Method {

// TODO: We could re-export `fil_evm_actor_shared::address::EvmAddress`.
#[derive(
serde::Deserialize, serde::Serialize, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord,
serde::Deserialize, serde::Serialize, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default,
)]
pub struct EthAddress(#[serde(with = "strict_bytes")] pub [u8; 20]);

Expand Down
11 changes: 10 additions & 1 deletion fendermint/vm/actor_interface/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use fvm_ipld_encoding::tuple::*;
use fvm_ipld_hamt::Hamt;
use fvm_shared::{address::Address, ActorID, HAMT_BIT_WIDTH};

use crate::eam::EthAddress;
use crate::{eam::EthAddress, system};

/// Defines first available ID address after builtin actors
pub const FIRST_NON_SINGLETON_ADDR: ActorID = 100;
Expand Down Expand Up @@ -113,6 +113,15 @@ impl State {
next_id += 1;
}

// Insert the null-Ethereum address to equal the system actor,
// so the system actor can be identified by 0xff00..00 as well as 0x00..00
address_map
.set(
system::SYSTEM_ACTOR_ETH_ADDR.to_bytes().into(),
system::SYSTEM_ACTOR_ID,
)
.context("cannot set ID of null eth address")?;

#[cfg(feature = "m2-native")]
let installed_actors = store.put_cbor(&Vec::<Cid>::new(), Code::Blake2b256)?;

Expand Down
14 changes: 14 additions & 0 deletions fendermint/vm/actor_interface/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,23 @@
// SPDX-License-Identifier: Apache-2.0, MIT
use cid::Cid;
use fvm_ipld_encoding::tuple::*;
use fvm_shared::address::Address;
use lazy_static::lazy_static;

use crate::eam::EthAddress;

define_singleton!(SYSTEM { id: 0, code_id: 1 });

lazy_static! {
/// The Ethereum null-address 0x00..00 can also be used to identify the system actor.
pub static ref SYSTEM_ACTOR_ETH_ADDR: Address = EthAddress::default().into();
}

/// Check whether the address is one of those identifying the system actor.
pub fn is_system_addr(addr: &Address) -> bool {
*addr == SYSTEM_ACTOR_ADDR || *addr == *SYSTEM_ACTOR_ETH_ADDR
}

/// System actor state.
#[derive(Default, Deserialize_tuple, Serialize_tuple, Debug, Clone)]
pub struct State {
Expand Down
4 changes: 2 additions & 2 deletions fendermint/vm/interpreter/src/fvm/state/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{cell::RefCell, sync::Arc};
use anyhow::{anyhow, Context};

use cid::Cid;
use fendermint_vm_actor_interface::system::SYSTEM_ACTOR_ADDR;
use fendermint_vm_actor_interface::system::is_system_addr;
use fendermint_vm_core::chainid::HasChainID;
use fendermint_vm_message::query::ActorState;
use fvm::engine::MultiEngine;
Expand Down Expand Up @@ -190,7 +190,7 @@ where
msg.gas_limit = fvm_shared::BLOCK_GAS_LIMIT;
}

if msg.from == SYSTEM_ACTOR_ADDR {
if is_system_addr(&msg.from) {
// Explicit execution requires `from` to be an account kind.
s.execute_implicit(msg)
} else {
Expand Down
10 changes: 5 additions & 5 deletions fendermint/vm/message/src/conv/from_eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use ethers_core::types::{Eip1559TransactionRequest, NameOrAddress, H160, U256};
use fendermint_vm_actor_interface::{
eam::{self, EthAddress},
evm, system,
evm,
};
use fvm_ipld_encoding::{BytesSer, RawBytes};
use fvm_shared::{
Expand Down Expand Up @@ -35,10 +35,10 @@ pub fn to_fvm_message(tx: &Eip1559TransactionRequest) -> anyhow::Result<Message>
};

// The `from` of the transaction is inferred from the signature.
// As long as the client and the server use the same hashing scheme,
// this should be usable as a delegated address.
// If none, use SYSTEM_ACTOR_ADDR. This is similar to https://github.com/filecoin-project/lotus/blob/master/node/impl/full/eth_utils.go#L124
let from = tx.from.map_or(system::SYSTEM_ACTOR_ADDR, to_fvm_address);
// As long as the client and the server use the same hashing scheme, this should be usable as a delegated address.
// If none, use the 0x00..00 null ethereum address, which in the node will be replaced with the SYSTEM_ACTOR_ADDR;
// This is similar to https://github.com/filecoin-project/lotus/blob/master/node/impl/full/eth_utils.go#L124
let from = to_fvm_address(tx.from.unwrap_or_default());

// Wrap calldata in IPLD byte format.
let calldata = tx.data.clone().unwrap_or_default().to_vec();
Expand Down

0 comments on commit 0169123

Please sign in to comment.