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

Commit

Permalink
FM-111: Hashed chain ID and --chain-name (#115)
Browse files Browse the repository at this point in the history
* FM-111: Add fendermint_vm_core with Timestamp

* FM-111: Hashed chain ID constructor

* FM-111: Chain ID in genesis, signature, RPC and CLI

* FM-111: Return known IDs for known names.

* FM-111: Notes about /root

* FM-111: Add --chain-name to smoke test

* FM-111: Add headers

* FM-111: Fixes

* FM-111: Fix genesis golden file.

* FM-111: Test chain ID in signature
  • Loading branch information
aakoshh authored May 24, 2023
1 parent 8718590 commit 40751fa
Show file tree
Hide file tree
Showing 34 changed files with 409 additions and 81 deletions.
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions docs/running.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ mkdir test-network
First, create a new `genesis.json` file devoid of accounts and validators. The `--base-fee` here is completely arbitrary.

```shell
cargo run -p fendermint_app -- genesis --genesis-file test-network/genesis.json new --network-name test --base-fee 1000 --timestamp 1680101412
cargo run -p fendermint_app -- genesis --genesis-file test-network/genesis.json new --chain-name test --base-fee 1000 --timestamp 1680101412
```

We can check what the contents look like:
Expand All @@ -40,7 +40,7 @@ We can check what the contents look like:
$ cat test-network/genesis.json
{
"timestamp": 1680101412,
"network_name": "test",
"chain_name": "test",
"network_version": 18,
"base_fee": "1000",
"validators": [],
Expand Down Expand Up @@ -241,7 +241,7 @@ $ cat ~/.cometbft/config/genesis.json
}
],
"base_fee": "1000",
"network_name": "test",
"chain_name": "test",
"network_version": 18,
"timestamp": 1680101412,
"validators": [
Expand Down Expand Up @@ -473,15 +473,15 @@ For example we can send 1000 tokens from Alice to Bob:

```shell
cargo run -p fendermint_app --release -- \
rpc transfer --secret-key test-network/keys/alice.sk --to $BOB_ADDR --sequence 0 --value 1000
rpc transfer --secret-key test-network/keys/alice.sk --to $BOB_ADDR --sequence 0 --value 1000 --chain-name test
```

Note that we are using `--sequence 0` because this is the first transaction we make using Alice's key.

The `transfer` command waits for the commit results of the transaction:

```console
$ cargo run -p fendermint_app --release -- rpc transfer --secret-key test-network/keys/alice.sk --to $BOB_ADDR --sequence 0 --value 1000
$ cargo run -p fendermint_app --release -- rpc transfer --secret-key test-network/keys/alice.sk --to $BOB_ADDR --sequence 0 --value 1000 --chain-name test
Finished dev [unoptimized + debuginfo] target(s) in 0.40s
Running `target/debug/fendermint rpc transfer --secret-key test-network/keys/alice.sk --to f1kgtzp5nuob3gdccagivcgns7e25be2c2rqozilq --sequence 0 --value 1000`
{
Expand Down Expand Up @@ -543,7 +543,7 @@ Say we want to deploy the `SimpleCoin` contract from that directory.
```shell
CONTRACT=../builtin-actors/actors/evm/tests/contracts/SimpleCoin.bin
cargo run -p fendermint_app --release -- \
rpc fevm --secret-key test-network/keys/alice.sk --sequence 1 \
rpc fevm --secret-key test-network/keys/alice.sk --sequence 1 --chain-name test \
create --contract $CONTRACT
```

Expand All @@ -554,7 +554,7 @@ which we can use to call the contract, namely by copying the `delegated_address`

```console
$ CREATE=$(cargo run -p fendermint_app --release -- \
rpc fevm --secret-key test-network/keys/alice.sk --sequence 1 \
rpc fevm --secret-key test-network/keys/alice.sk --sequence 1 --chain-name test \
create --contract $CONTRACT)

$ echo $CREATE | jq .return_data
Expand All @@ -576,7 +576,7 @@ Now that we have a contract deployed, we can call it. The arguments in the follo

```console
$ cargo run -p fendermint_app --release -- \
rpc fevm --secret-key test-network/keys/alice.sk --sequence 2 \
rpc fevm --secret-key test-network/keys/alice.sk --sequence 2 --chain-name test \
invoke --contract $DELEGATED_ADDR \
--method f8b2cb4f --method-args 000000000000000000000000ff00000000000000000000000000000000000064 \
| jq .return_data
Expand All @@ -590,7 +590,7 @@ To avoid having to come up with ABI encoded arguments in hexadecimal format, we
Here's an [example](../fendermint/rpc/examples/simplecoin.rs) of doing that with the [SimpleCoin](https://github.com/filecoin-project/builtin-actors/blob/v10.0.0/actors/evm/tests/contracts/simplecoin.sol) contract.

```console
$ cargo run -p fendermint_rpc --release --example simplecoin -- --secret-key test-network/keys/alice.sk --verbose
$ cargo run -p fendermint_rpc --release --example simplecoin -- --secret-key test-network/keys/alice.sk --chain-name test --verbose
2023-05-19T10:18:47.234878Z DEBUG fendermint_rpc::client: Using HTTP client to submit request to: http://127.0.0.1:26657/
...
2023-05-19T10:18:47.727563Z INFO simplecoin: contract deployed contract_address="f410fvbmxiqdn6svyo5oubfbzxsorkvydcb5ecmlbwma" actor_id=107
Expand Down
1 change: 1 addition & 0 deletions fendermint/app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ fendermint_storage = { path = "../storage" }
fendermint_rocksdb = { path = "../rocksdb" }
fendermint_rpc = { path = "../rpc" }
fendermint_vm_actor_interface = { path = "../vm/actor_interface" }
fendermint_vm_core = { path = "../vm/core" }
fendermint_vm_interpreter = { path = "../vm/interpreter", features = ["bundle"] }
fendermint_vm_message = { path = "../vm/message", features = ["secp256k1"] }
fendermint_vm_genesis = { path = "../vm/genesis" }
Expand Down
11 changes: 9 additions & 2 deletions fendermint/app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use fendermint_abci::{AbciResult, Application};
use fendermint_storage::{
Codec, Encode, KVCollection, KVRead, KVReadable, KVStore, KVWritable, KVWrite,
};
use fendermint_vm_genesis::Timestamp;
use fendermint_vm_core::Timestamp;
use fendermint_vm_interpreter::bytes::{
BytesMessageApplyRet, BytesMessageCheckRet, BytesMessageQuery, BytesMessageQueryRet,
};
Expand All @@ -26,6 +26,7 @@ use fendermint_vm_interpreter::{
};
use fvm::engine::MultiEngine;
use fvm_ipld_blockstore::Blockstore;
use fvm_shared::chainid::ChainID;
use fvm_shared::econ::TokenAmount;
use fvm_shared::version::NetworkVersion;
use num_traits::Zero;
Expand Down Expand Up @@ -70,6 +71,9 @@ impl AppState {
pub fn state_root(&self) -> Cid {
self.state_params.state_root
}
pub fn chain_id(&self) -> ChainID {
ChainID::from(self.state_params.chain_id)
}
pub fn app_hash(&self) -> tendermint::hash::AppHash {
tendermint::hash::AppHash::try_from(self.state_root().to_bytes())
.expect("hash can be wrapped")
Expand Down Expand Up @@ -189,6 +193,7 @@ where
network_version: NetworkVersion::MAX,
base_fee: TokenAmount::zero(),
circ_supply: TokenAmount::zero(),
chain_id: 0,
},
};
self.set_committed_state(state)?;
Expand Down Expand Up @@ -377,6 +382,7 @@ where
network_version: out.network_version,
base_fee: out.base_fee,
circ_supply: out.circ_supply,
chain_id: out.chain_id.into(),
},
};

Expand Down Expand Up @@ -450,7 +456,8 @@ where
None => {
let db = self.state_store_clone();
let state = self.committed_state()?;
FvmCheckState::new(db, state.state_root()).context("error creating check state")?
FvmCheckState::new(db, state.state_root(), state.chain_id())
.context("error creating check state")?
}
};

Expand Down
8 changes: 4 additions & 4 deletions fendermint/app/src/cmd/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use fendermint_app::APP_VERSION;
use fvm_shared::address::Address;
use std::path::PathBuf;

use fendermint_vm_core::Timestamp;
use fendermint_vm_genesis::{
Account, Actor, ActorMeta, Genesis, Multisig, Power, SignerAddr, Timestamp, Validator,
ValidatorKey,
Account, Actor, ActorMeta, Genesis, Multisig, Power, SignerAddr, Validator, ValidatorKey,
};

use crate::cmd;
Expand Down Expand Up @@ -36,7 +36,7 @@ cmd! {
GenesisNewArgs(self, genesis_file: PathBuf) {
let genesis = Genesis {
timestamp: Timestamp(self.timestamp),
network_name: self.network_name.clone(),
chain_name: self.chain_name.clone(),
network_version: self.network_version,
base_fee: self.base_fee.clone(),
validators: Vec::new(),
Expand Down Expand Up @@ -171,7 +171,7 @@ fn into_tendermint(genesis_file: &PathBuf, args: &GenesisIntoTendermintArgs) ->
let genesis_json = serde_json::to_value(&genesis)?;
let tmg = tendermint::Genesis {
genesis_time: tendermint::time::Time::from_unix_timestamp(genesis.timestamp.as_secs(), 0)?,
chain_id: tendermint::chain::Id::try_from(genesis.network_name)?,
chain_id: tendermint::chain::Id::try_from(genesis.chain_name)?,
initial_height: 0,
// Values are based on the default produced by `tendermint init`
consensus_params: tendermint::consensus::Params {
Expand Down
4 changes: 3 additions & 1 deletion fendermint/app/src/cmd/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use fendermint_rpc::tx::{
AsyncResponse, BoundClient, CallClient, CommitResponse, SyncResponse, TxAsync, TxClient,
TxCommit, TxSync,
};
use fendermint_vm_core::chainid;
use fendermint_vm_message::chain::ChainMessage;
use fvm_ipld_encoding::RawBytes;
use fvm_shared::address::Address;
Expand Down Expand Up @@ -317,7 +318,8 @@ struct TransClient {
impl TransClient {
pub fn new(client: FendermintClient, args: &TransArgs) -> anyhow::Result<Self> {
let sk = read_secret_key(&args.secret_key)?;
let mf = MessageFactory::new(sk, args.sequence)?;
let chain_id = chainid::from_str_hashed(&args.chain_name)?;
let mf = MessageFactory::new(sk, args.sequence, chain_id)?;
let client = client.bind(mf);
let client = Self {
inner: client,
Expand Down
2 changes: 1 addition & 1 deletion fendermint/app/src/options/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub struct GenesisNewArgs {
pub timestamp: u64,
/// Name of the network and chain.
#[arg(long, short = 'n')]
pub network_name: String,
pub chain_name: String,
/// Network version, governs which set of built-in actors to use.
#[arg(long, short = 'v', default_value = "18", value_parser = parse_network_version)]
pub network_version: NetworkVersion,
Expand Down
3 changes: 3 additions & 0 deletions fendermint/app/src/options/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ pub struct FevmArgs {
/// Arguments common to transactions and transfers.
#[derive(Args, Debug, Clone)]
pub struct TransArgs {
/// Name of chain the for which the message will be signed.
#[arg(long, short, env = "FM_CHAIN_NAME")]
pub chain_name: String,
/// Amount of tokens to send, in atto.
#[arg(long, short, value_parser = parse_token_amount, default_value = "0")]
pub value: TokenAmount,
Expand Down
6 changes: 2 additions & 4 deletions fendermint/app/src/tmconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
// SPDX-License-Identifier: Apache-2.0, MIT
//! Conversions to Tendermint data types.
use anyhow::{anyhow, Context};
use fendermint_vm_core::Timestamp;
use fendermint_vm_genesis::Validator;
use fendermint_vm_interpreter::{
fvm::{FvmApplyRet, FvmCheckRet, FvmQueryRet},
Timestamp,
};
use fendermint_vm_interpreter::fvm::{FvmApplyRet, FvmCheckRet, FvmQueryRet};
use fvm_shared::{error::ExitCode, event::StampedEvent};
use prost::Message;
use std::num::NonZeroU32;
Expand Down
1 change: 1 addition & 0 deletions fendermint/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ fvm_ipld_encoding = { workspace = true }
fvm_shared = { workspace = true }

fendermint_vm_actor_interface = { path = "../vm/actor_interface" }
fendermint_vm_core = { path = "../vm/core" }
fendermint_vm_message = { path = "../vm/message", features = ["secp256k1"] }

[dev-dependencies]
Expand Down
9 changes: 8 additions & 1 deletion fendermint/rpc/examples/simplecoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use ethers::prelude::{abigen, decode_function_data};
use ethers::types::H160;
use fendermint_rpc::query::QueryClient;
use fendermint_vm_actor_interface::eam::{self, CreateReturn, EthAddress};
use fendermint_vm_core::chainid;
use fvm_shared::address::Address;
use lazy_static::lazy_static;
use libsecp256k1::{PublicKey, SecretKey};
Expand Down Expand Up @@ -85,6 +86,10 @@ pub struct Options {
/// Path to the secret key to deploy with, expected to be in Base64 format.
#[arg(long, short)]
pub secret_key: PathBuf,

/// The name of the chain we are connecting to, which becomes part of the message signature.
#[arg(long, short)]
pub chain_name: String,
}

impl Options {
Expand Down Expand Up @@ -114,7 +119,9 @@ async fn main() {
.await
.expect("error getting sequence");

let mf = MessageFactory::new(sk, sn).unwrap();
let chain_id = chainid::from_str_hashed(&opts.chain_name).expect("problematic chain name");

let mf = MessageFactory::new(sk, sn, chain_id).unwrap();

let mut client = client.bind(mf);

Expand Down
16 changes: 12 additions & 4 deletions fendermint/rpc/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use bytes::Bytes;
use fendermint_vm_actor_interface::{eam, evm};
use fendermint_vm_message::{chain::ChainMessage, signed::SignedMessage};
use fvm_ipld_encoding::{BytesSer, RawBytes};
use fvm_shared::{address::Address, econ::TokenAmount, message::Message, MethodNum, METHOD_SEND};
use fvm_shared::{
address::Address, chainid::ChainID, econ::TokenAmount, message::Message, MethodNum, METHOD_SEND,
};
use libsecp256k1::{PublicKey, SecretKey};

use crate::B64_ENGINE;
Expand All @@ -19,13 +21,19 @@ pub struct MessageFactory {
sk: SecretKey,
addr: Address,
sequence: u64,
chain_id: ChainID,
}

impl MessageFactory {
pub fn new(sk: SecretKey, sequence: u64) -> anyhow::Result<Self> {
pub fn new(sk: SecretKey, sequence: u64, chain_id: ChainID) -> anyhow::Result<Self> {
let pk = PublicKey::from_secret_key(&sk);
let addr = Address::new_secp256k1(&pk.serialize())?;
Ok(Self { sk, addr, sequence })
Ok(Self {
sk,
addr,
sequence,
chain_id,
})
}

/// Convenience method to read the secret key from a file, expected to be in Base64 format.
Expand Down Expand Up @@ -85,7 +93,7 @@ impl MessageFactory {
gas_premium: gas_params.gas_premium,
};
self.sequence += 1;
let signed = SignedMessage::new_secp256k1(message, &self.sk)?;
let signed = SignedMessage::new_secp256k1(message, &self.sk, &self.chain_id)?;
let chain = ChainMessage::Signed(Box::new(signed));
Ok(chain)
}
Expand Down
4 changes: 3 additions & 1 deletion fendermint/testing/smoke-test/Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ run_task = { name = [
script = """
cd ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}
cargo run -p fendermint_rpc --release --example simplecoin -- \
--secret-key fendermint/testing/smoke-test/test-data/fendermint/keys/alice.sk
--secret-key fendermint/testing/smoke-test/test-data/fendermint/keys/alice.sk \
--chain-name ${NETWORK_NAME}
"""


Expand Down Expand Up @@ -119,6 +120,7 @@ docker run \
--volume ${TEST_DATA_DIR}:/data \
--volume ${TEST_SCRIPTS_DIR}:/scripts \
--env FM_DATA_DIR=/data/fendermint/data \
--env FM_CHAIN_NAME=${NETWORK_NAME} \
--entrypoint ${ENTRY} \
${FM_DOCKER_IMAGE} \
${CMD}
Expand Down
2 changes: 1 addition & 1 deletion fendermint/testing/smoke-test/scripts/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ KEYS_DIR=$FM_DIR/keys
GENESIS_FILE=$FM_DIR/genesis.json

# Create a genesis file
fendermint genesis --genesis-file $GENESIS_FILE new --network-name smoke --base-fee 1000 --timestamp 1680101412
fendermint genesis --genesis-file $GENESIS_FILE new --chain-name $FM_CHAIN_NAME --base-fee 1000 --timestamp 1680101412

# Create test keys
mkdir -p $KEYS_DIR
Expand Down
Loading

0 comments on commit 40751fa

Please sign in to comment.