From 0c76ff300873671fede7b149a60721a8c8df2078 Mon Sep 17 00:00:00 2001 From: Akosh Farkash Date: Thu, 14 Dec 2023 21:25:34 +0000 Subject: [PATCH] TEST: Check the deployed bytecode (#466) * TEST: Rename Makefile dir to scripts * TEST: Check in SimpleCoin for testing * TEST: Use the checked in SimpleCoin artifacts and test deployed bytecode --- Makefile | 13 ++----- fendermint/eth/api/examples/ethers.rs | 34 ++++++------------- fendermint/rpc/examples/simplecoin.rs | 17 ++++------ fendermint/testing/Makefile | 25 ++++++++++++++ fendermint/testing/contracts/SimpleCoin.abi | 1 + fendermint/testing/contracts/SimpleCoin.bin | 1 + .../testing/contracts/SimpleCoin.bin-runtime | 1 + .../testing/contracts/SimpleCoin.signatures | 3 ++ fendermint/testing/contracts/SimpleCoin.sol | 31 +++++++++++++++++ .../testing/contracts/SimpleCoin_storage.json | 1 + .../testing/{Makefile => scripts}/ci.env | 0 .../testing/{Makefile => scripts}/common.env | 0 .../testing/{Makefile => scripts}/common.toml | 0 .../{Makefile => scripts}/fendermint.toml | 0 fendermint/testing/smoke-test/Makefile.toml | 6 ++-- .../testing/snapshot-test/Makefile.toml | 6 ++-- 16 files changed, 88 insertions(+), 51 deletions(-) create mode 100644 fendermint/testing/Makefile create mode 100644 fendermint/testing/contracts/SimpleCoin.abi create mode 100644 fendermint/testing/contracts/SimpleCoin.bin create mode 100644 fendermint/testing/contracts/SimpleCoin.bin-runtime create mode 100644 fendermint/testing/contracts/SimpleCoin.signatures create mode 100644 fendermint/testing/contracts/SimpleCoin.sol create mode 100644 fendermint/testing/contracts/SimpleCoin_storage.json rename fendermint/testing/{Makefile => scripts}/ci.env (100%) rename fendermint/testing/{Makefile => scripts}/common.env (100%) rename fendermint/testing/{Makefile => scripts}/common.toml (100%) rename fendermint/testing/{Makefile => scripts}/fendermint.toml (100%) diff --git a/Makefile b/Makefile index 3ec16c9a..34260984 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ BUILTIN_ACTORS_TAG ?= v11.0.0 BUILTIN_ACTORS_BUNDLE := $(PWD)/builtin-actors/output/bundle.car -BUILTIN_ACTORS_DIR := ../builtin-actors # Make sure this tag matches the one in Cargo.toml IPC_ACTORS_TAG ?= origin/dev @@ -37,12 +36,12 @@ install: cargo install --locked --path fendermint/app # Using --release for testing because wasm can otherwise be slow. -test: $(IPC_ACTORS_ABI) $(BUILTIN_ACTORS_BUNDLE) $(BUILTIN_ACTORS_DIR) +test: $(IPC_ACTORS_ABI) $(BUILTIN_ACTORS_BUNDLE) FM_BUILTIN_ACTORS_BUNDLE=$(BUILTIN_ACTORS_BUNDLE) \ FM_CONTRACTS_DIR=$(IPC_ACTORS_OUT) \ cargo test --release --workspace --exclude smoke-test -e2e: docker-build $(BUILTIN_ACTORS_DIR) +e2e: docker-build cd fendermint/testing/smoke-test && cargo make --profile $(PROFILE) cd fendermint/testing/snapshot-test && cargo make --profile $(PROFILE) @@ -103,14 +102,6 @@ $(BUILTIN_ACTORS_BUNDLE): mkdir -p $(dir $@) curl -L -o $@ https://github.com/filecoin-project/builtin-actors/releases/download/$(BUILTIN_ACTORS_TAG)/builtin-actors-mainnet.car -# Some test expect the builtin-actors repo to be checked out where they can find test contracts. -$(BUILTIN_ACTORS_DIR): - mkdir -p $(BUILTIN_ACTORS_DIR) && \ - cd $(BUILTIN_ACTORS_DIR) && \ - git clone https://github.com/filecoin-project/builtin-actors.git . && \ - git checkout $(BUILTIN_ACTORS_TAG) - - # Compile the ABI artifacts of the IPC Solidity actors. ipc-actors-abi: $(IPC_ACTORS_ABI) diff --git a/fendermint/eth/api/examples/ethers.rs b/fendermint/eth/api/examples/ethers.rs index 7043962f..40e497fa 100644 --- a/fendermint/eth/api/examples/ethers.rs +++ b/fendermint/eth/api/examples/ethers.rs @@ -58,14 +58,6 @@ use tracing::Level; type TestMiddleware = SignerMiddleware, Wallet>; type TestContractCall = ContractCall, T>; -// This assumes that https://github.com/filecoin-project/builtin-actors is checked out next to this project, -// which the Makefile in the root takes care of with `make actor-bundle`, a dependency of creating docker images. -const SIMPLECOIN_HEX: &'static str = - include_str!("../../../../../builtin-actors/actors/evm/tests/contracts/SimpleCoin.bin"); - -// const SIMPLECOIN_ABI: &'static str = -// include_str!("../../../../../builtin-actors/actors/evm/tests/contracts/SimpleCoin.abi"); - /// Gas limit to set for transactions. const ENOUGH_GAS: u64 = 10_000_000_000u64; @@ -74,10 +66,11 @@ const FILTERS_ENABLED: bool = true; // Generate a statically typed interface for the contract. // An example of what it looks like is at https://github.com/filecoin-project/ref-fvm/blob/evm-integration-tests/testing/integration/tests/evm/src/simple_coin/simple_coin.rs -abigen!( - SimpleCoin, - "../../../../builtin-actors/actors/evm/tests/contracts/SimpleCoin.abi" -); +abigen!(SimpleCoin, "../../testing/contracts/SimpleCoin.abi"); + +const SIMPLECOIN_HEX: &'static str = include_str!("../../../testing/contracts/SimpleCoin.bin"); +const SIMPLECOIN_RUNTIME_HEX: &'static str = + include_str!("../../../testing/contracts/SimpleCoin.bin-runtime"); #[derive(Parser, Debug)] pub struct Options { @@ -549,6 +542,10 @@ where let bytecode = Bytes::from(hex::decode(SIMPLECOIN_HEX).context("failed to decode contract hex")?); + let deployed_bytecode = Bytes::from( + hex::decode(SIMPLECOIN_RUNTIME_HEX).context("failed to decode contract runtime hex")?, + ); + // let abi = serde_json::from_str::(SIMPLECOIN_ABI)?; let abi: Abi = SIMPLECOIN_ABI.clone(); @@ -622,18 +619,7 @@ where request( "eth_code", mw.get_code(contract.address(), None).await, - |bz| { - // It's not exactly the same as the bytecode above. - // The initcode is stripped, only the runtime bytecode is returned. - // But the two seem to start and end the same way. - let a = bz.iter(); - let b = bytecode.iter(); - let ar = bz.iter().rev(); - let br = bytecode.iter().rev(); - !bz.is_empty() - && a.zip(b).take_while(|(a, b)| a == b).count() > 0 - && ar.zip(br).take_while(|(a, b)| a == b).count() > 0 - }, + |bz| *bz == deployed_bytecode, )?; request("eth_syncing", mw.syncing().await, |s| { diff --git a/fendermint/rpc/examples/simplecoin.rs b/fendermint/rpc/examples/simplecoin.rs index 4e0ae5f2..6e08802c 100644 --- a/fendermint/rpc/examples/simplecoin.rs +++ b/fendermint/rpc/examples/simplecoin.rs @@ -39,8 +39,13 @@ use fendermint_rpc::tx::{CallClient, TxClient, TxCommit}; type MockProvider = ethers::providers::Provider; type MockContractCall = ethers::prelude::ContractCall; -const CONTRACT_HEX: &'static str = - include_str!("../../../../builtin-actors/actors/evm/tests/contracts/SimpleCoin.bin"); +// Generate a statically typed interface for the contract. +// This assumes the `builtin-actors` repo is checked in next to Fendermint, +// which the `make actor-bundle` command takes care of if it wasn't. +// This path starts from the root of this project, not this file. +abigen!(SimpleCoin, "../testing/contracts/SimpleCoin.abi"); + +const CONTRACT_HEX: &'static str = include_str!("../../testing/contracts/SimpleCoin.bin"); lazy_static! { /// Default gas params based on the testkit. @@ -51,14 +56,6 @@ lazy_static! { }; } -// Generate a statically typed interface for the contract. -// This assumes the `builtin-actors` repo is checked in next to Fendermint, -// which the `make actor-bundle` command takes care of if it wasn't. -abigen!( - SimpleCoin, - "../../../builtin-actors/actors/evm/tests/contracts/SimpleCoin.abi" -); - // Alternatively we can generate the ABI code as follows: // ``` // ethers::prelude::Abigen::new("SimpleCoin", ) diff --git a/fendermint/testing/Makefile b/fendermint/testing/Makefile new file mode 100644 index 00000000..2f0b211e --- /dev/null +++ b/fendermint/testing/Makefile @@ -0,0 +1,25 @@ +TEST_CONTRACTS_DIR = contracts +TEST_CONTRACTS_SOL = $(shell find $(TEST_CONTRACTS_DIR) -type f -name "*.sol") +TEST_CONTRACTS_BIN = $(TEST_CONTRACTS_SOL:.sol=.bin) + +.PHONY: all +all: \ + test-contracts + +# Compile all Solidity test contracts. +# This could also be achieved with https://docs.rs/ethers/latest/ethers/solc/ +.PHONY: test-contracts +test-contracts: $(TEST_CONTRACTS_BIN) + +# Compile a Solidity test contract +$(TEST_CONTRACTS_DIR)/%.bin: $(TEST_CONTRACTS_DIR)/%.sol | solc + solc --bin --bin-runtime --abi --storage-layout --hashes --overwrite $< -o $(TEST_CONTRACTS_DIR) + +# Requirements checks. + +.PHONY: solc +solc: + @if [ -z "$(shell which solc)" ]; then \ + echo "Please install solc, the Solidity compiler. See https://github.com/crytic/solc-select"; \ + exit 1; \ + fi diff --git a/fendermint/testing/contracts/SimpleCoin.abi b/fendermint/testing/contracts/SimpleCoin.abi new file mode 100644 index 00000000..19482937 --- /dev/null +++ b/fendermint/testing/contracts/SimpleCoin.abi @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getBalanceInEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendCoin","outputs":[{"internalType":"bool","name":"sufficient","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/fendermint/testing/contracts/SimpleCoin.bin b/fendermint/testing/contracts/SimpleCoin.bin new file mode 100644 index 00000000..dd452b7b --- /dev/null +++ b/fendermint/testing/contracts/SimpleCoin.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506127106000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610549806100656000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80637bd703e81461004657806390b98a1114610076578063f8b2cb4f146100a6575b600080fd5b610060600480360381019061005b91906102d1565b6100d6565b60405161006d919061036f565b60405180910390f35b610090600480360381019061008b91906102fa565b6100f4565b60405161009d9190610354565b60405180910390f35b6100c060048036038101906100bb91906102d1565b61025f565b6040516100cd919061036f565b60405180910390f35b600060026100e38361025f565b6100ed91906103e0565b9050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156101455760009050610259565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610193919061043a565b92505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101e8919061038a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161024c919061036f565b60405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000813590506102b6816104e5565b92915050565b6000813590506102cb816104fc565b92915050565b6000602082840312156102e357600080fd5b60006102f1848285016102a7565b91505092915050565b6000806040838503121561030d57600080fd5b600061031b858286016102a7565b925050602061032c858286016102bc565b9150509250929050565b61033f81610480565b82525050565b61034e816104ac565b82525050565b60006020820190506103696000830184610336565b92915050565b60006020820190506103846000830184610345565b92915050565b6000610395826104ac565b91506103a0836104ac565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156103d5576103d46104b6565b5b828201905092915050565b60006103eb826104ac565b91506103f6836104ac565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561042f5761042e6104b6565b5b828202905092915050565b6000610445826104ac565b9150610450836104ac565b925082821015610463576104626104b6565b5b828203905092915050565b60006104798261048c565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6104ee8161046e565b81146104f957600080fd5b50565b610505816104ac565b811461051057600080fd5b5056fea2646970667358221220d11fa32f457b8122876db665f066909bc482ee02a7ea3972d5a2de406fecf85b64736f6c63430008020033 \ No newline at end of file diff --git a/fendermint/testing/contracts/SimpleCoin.bin-runtime b/fendermint/testing/contracts/SimpleCoin.bin-runtime new file mode 100644 index 00000000..4cd6d523 --- /dev/null +++ b/fendermint/testing/contracts/SimpleCoin.bin-runtime @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50600436106100415760003560e01c80637bd703e81461004657806390b98a1114610076578063f8b2cb4f146100a6575b600080fd5b610060600480360381019061005b91906102d1565b6100d6565b60405161006d919061036f565b60405180910390f35b610090600480360381019061008b91906102fa565b6100f4565b60405161009d9190610354565b60405180910390f35b6100c060048036038101906100bb91906102d1565b61025f565b6040516100cd919061036f565b60405180910390f35b600060026100e38361025f565b6100ed91906103e0565b9050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156101455760009050610259565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610193919061043a565b92505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101e8919061038a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161024c919061036f565b60405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000813590506102b6816104e5565b92915050565b6000813590506102cb816104fc565b92915050565b6000602082840312156102e357600080fd5b60006102f1848285016102a7565b91505092915050565b6000806040838503121561030d57600080fd5b600061031b858286016102a7565b925050602061032c858286016102bc565b9150509250929050565b61033f81610480565b82525050565b61034e816104ac565b82525050565b60006020820190506103696000830184610336565b92915050565b60006020820190506103846000830184610345565b92915050565b6000610395826104ac565b91506103a0836104ac565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156103d5576103d46104b6565b5b828201905092915050565b60006103eb826104ac565b91506103f6836104ac565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561042f5761042e6104b6565b5b828202905092915050565b6000610445826104ac565b9150610450836104ac565b925082821015610463576104626104b6565b5b828203905092915050565b60006104798261048c565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6104ee8161046e565b81146104f957600080fd5b50565b610505816104ac565b811461051057600080fd5b5056fea2646970667358221220d11fa32f457b8122876db665f066909bc482ee02a7ea3972d5a2de406fecf85b64736f6c63430008020033 \ No newline at end of file diff --git a/fendermint/testing/contracts/SimpleCoin.signatures b/fendermint/testing/contracts/SimpleCoin.signatures new file mode 100644 index 00000000..965c82af --- /dev/null +++ b/fendermint/testing/contracts/SimpleCoin.signatures @@ -0,0 +1,3 @@ +f8b2cb4f: getBalance(address) +7bd703e8: getBalanceInEth(address) +90b98a11: sendCoin(address,uint256) diff --git a/fendermint/testing/contracts/SimpleCoin.sol b/fendermint/testing/contracts/SimpleCoin.sol new file mode 100644 index 00000000..79e12475 --- /dev/null +++ b/fendermint/testing/contracts/SimpleCoin.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.2; + +contract SimpleCoin { + mapping(address => uint256) balances; + + event Transfer(address indexed _from, address indexed _to, uint256 _value); + + constructor() { + balances[tx.origin] = 10000; + } + + function sendCoin( + address receiver, + uint256 amount + ) public returns (bool sufficient) { + if (balances[msg.sender] < amount) return false; + balances[msg.sender] -= amount; + balances[receiver] += amount; + emit Transfer(msg.sender, receiver, amount); + return true; + } + + function getBalanceInEth(address addr) public view returns (uint256) { + return getBalance(addr) * 2; + } + + function getBalance(address addr) public view returns (uint256) { + return balances[addr]; + } +} diff --git a/fendermint/testing/contracts/SimpleCoin_storage.json b/fendermint/testing/contracts/SimpleCoin_storage.json new file mode 100644 index 00000000..8d8f4660 --- /dev/null +++ b/fendermint/testing/contracts/SimpleCoin_storage.json @@ -0,0 +1 @@ +{"storage":[{"astId":5,"contract":"contracts/SimpleCoin.sol:SimpleCoin","label":"balances","offset":0,"slot":"0","type":"t_mapping(t_address,t_uint256)"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_mapping(t_address,t_uint256)":{"encoding":"mapping","key":"t_address","label":"mapping(address => uint256)","numberOfBytes":"32","value":"t_uint256"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}} \ No newline at end of file diff --git a/fendermint/testing/Makefile/ci.env b/fendermint/testing/scripts/ci.env similarity index 100% rename from fendermint/testing/Makefile/ci.env rename to fendermint/testing/scripts/ci.env diff --git a/fendermint/testing/Makefile/common.env b/fendermint/testing/scripts/common.env similarity index 100% rename from fendermint/testing/Makefile/common.env rename to fendermint/testing/scripts/common.env diff --git a/fendermint/testing/Makefile/common.toml b/fendermint/testing/scripts/common.toml similarity index 100% rename from fendermint/testing/Makefile/common.toml rename to fendermint/testing/scripts/common.toml diff --git a/fendermint/testing/Makefile/fendermint.toml b/fendermint/testing/scripts/fendermint.toml similarity index 100% rename from fendermint/testing/Makefile/fendermint.toml rename to fendermint/testing/scripts/fendermint.toml diff --git a/fendermint/testing/smoke-test/Makefile.toml b/fendermint/testing/smoke-test/Makefile.toml index 236d0690..97a2d982 100644 --- a/fendermint/testing/smoke-test/Makefile.toml +++ b/fendermint/testing/smoke-test/Makefile.toml @@ -11,13 +11,13 @@ # cargo make teardown extend = [ - { path = "../Makefile/common.toml" }, + { path = "../scripts/common.toml" }, ] env_files = [ { path = "./scripts/smoke.env" }, - { path = "../Makefile/common.env" }, - { path = "../Makefile/ci.env", profile = "ci" }, + { path = "../scripts/common.env" }, + { path = "../scripts/ci.env", profile = "ci" }, ] [tasks.test] diff --git a/fendermint/testing/snapshot-test/Makefile.toml b/fendermint/testing/snapshot-test/Makefile.toml index 3acb916c..320a3e9c 100644 --- a/fendermint/testing/snapshot-test/Makefile.toml +++ b/fendermint/testing/snapshot-test/Makefile.toml @@ -1,14 +1,14 @@ # See fendermint/testing/snapshot-test/src/lib.rs for description. extend = [ - { path = "../Makefile/common.toml" }, + { path = "../scripts/common.toml" }, ] env_files = [ # `snapshot.env` is the environment for `cargo make`. { path = "./scripts/snapshot.env" }, - { path = "../Makefile/common.env" }, - { path = "../Makefile/ci.env", profile = "ci" }, + { path = "../scripts/common.env" }, + { path = "../scripts/ci.env", profile = "ci" }, ] # Overriding the env file to enable snapshotting.