Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
785 changes: 446 additions & 339 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ revive-strategy = { path = "crates/revive-strategy" }
revive-utils = { path = "crates/revive-utils" }

# polkadot-sdk
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "master", features = [
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "alindima/add-eip3607-bypass-option", features = [
"experimental",
"runtime",
"polkadot-runtime-common",
Expand Down
6 changes: 3 additions & 3 deletions crates/anvil-polkadot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ path = "bin/main.rs"
# foundry internal
codec = { version = "3.7.5", default-features = true, package = "parity-scale-codec" }
substrate-runtime = { path = "substrate-runtime" }
pallet-revive-eth-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "master" }
pallet-revive-eth-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "alindima/add-eip3607-bypass-option" }
secp256k1 = { version = "0.28.0", default-features = false }
libsecp256k1 = { version = "0.7.0", default-features = false }
sp-runtime-interface = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "master", default-features = false }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "master", default-features = false, features = [
sp-runtime-interface = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "alindima/add-eip3607-bypass-option", default-features = false }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "alindima/add-eip3607-bypass-option", default-features = false, features = [
"sc-allocator",
"sc-basic-authorship",
"sc-block-builder",
Expand Down
4 changes: 4 additions & 0 deletions crates/anvil-polkadot/src/substrate_node/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ impl GenesisConfig {
json!({
"revive": {
"accounts": revive_genesis_accounts,
"debugSettings": {
"allow_unlimited_contract_size": true,
"bypass_eip_3607": true
}
},
"transactionPayment": {
"multiplier": self.base_fee_per_gas.into_inner().to_string(),
Expand Down
14 changes: 9 additions & 5 deletions crates/anvil-polkadot/src/substrate_node/service/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use polkadot_sdk::{
use std::{collections::HashMap, num::NonZeroUsize, sync::Arc};
use substrate_runtime::Balance;

const DEFAULT_LRU_CAP: NonZeroUsize = NonZeroUsize::new(256).expect("256 is non-zero");

#[derive(Debug, thiserror::Error)]
pub enum BackendError {
#[error("Inner client error: {0}")]
Expand Down Expand Up @@ -249,13 +251,15 @@ pub struct StorageOverrides {
per_block: LruCache<Hash, BlockOverrides>,
}

impl Default for StorageOverrides {
fn default() -> Self {
Self { per_block: LruCache::new(NonZeroUsize::new(10).expect("10 is greater than 0")) }
impl StorageOverrides {
pub fn new(lru_capacity: Option<usize>) -> Self {
Self {
per_block: LruCache::new(
lru_capacity.and_then(|cap| NonZeroUsize::new(cap)).unwrap_or(DEFAULT_LRU_CAP),
),
}
}
}

impl StorageOverrides {
pub fn get(&mut self, block: &Hash) -> Option<BlockOverrides> {
self.per_block.get(block).cloned()
}
Expand Down
3 changes: 2 additions & 1 deletion crates/anvil-polkadot/src/substrate_node/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ pub fn new(
anvil_config: &AnvilNodeConfig,
config: Configuration,
) -> Result<(Service, TaskManager), ServiceError> {
let storage_overrides = Arc::new(Mutex::new(StorageOverrides::default()));
let storage_overrides =
Arc::new(Mutex::new(StorageOverrides::new(anvil_config.revive_rpc_block_limit)));

let (client, backend, keystore, mut task_manager) = client::new_client(
anvil_config.get_genesis_number(),
Expand Down
4 changes: 2 additions & 2 deletions crates/anvil-polkadot/substrate-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ license.workspace = true
[dependencies]
array-bytes = { version = "6.2.2", default-features = false }
codec = { version = "3.7.5", default-features = false, package = "parity-scale-codec" }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "master", default-features = false, features = [
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "alindima/add-eip3607-bypass-option", default-features = false, features = [
Comment thread
alindima marked this conversation as resolved.
Outdated
"pallet-aura",
"pallet-balances",
"pallet-revive",
Expand All @@ -30,7 +30,7 @@ scale-info = { version = "2.11.6", default-features = false }
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }

[build-dependencies]
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "master", default-features = false, optional = true, features = ["substrate-wasm-builder"] }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "alindima/add-eip3607-bypass-option", default-features = false, optional = true, features = ["substrate-wasm-builder"] }

[features]
default = ["std"]
Expand Down
1 change: 1 addition & 0 deletions crates/anvil-polkadot/substrate-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ impl pallet_revive::Config for Runtime {
type InstantiateOrigin = EnsureSigned<Self::AccountId>;
type Time = Timestamp;
type FeeInfo = FeeInfo<Address, Signature, EthExtraImpl>;
type DebugEnabled = ConstBool<true>;
}

pallet_revive::impl_runtime_apis_plus_revive_traits!(
Expand Down
124 changes: 124 additions & 0 deletions crates/anvil-polkadot/tests/it/state_injector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,130 @@ async fn test_set_balance() {
assert_eq!(node.get_balance(random_addr, None).await, new_balance);
}

#[tokio::test(flavor = "multi_thread")]
async fn test_set_and_spend_balance_for_contract() {
let anvil_node_config = AnvilNodeConfig::test_config();
let substrate_node_config = SubstrateNodeConfig::new(&anvil_node_config);
let mut node = TestNode::new(anvil_node_config, substrate_node_config).await.unwrap();

let alith =
Address::from(ReviveAddress::new(Account::from(subxt_signer::eth::dev::alith()).address()));

let ContractCode { init: bytecode, .. } = get_contract_code("SimpleStorage");

let tx_hash = node
.deploy_contract(&bytecode, Account::from(subxt_signer::eth::dev::alith()).address())
.await;

unwrap_response::<()>(node.eth_rpc(EthRequest::Mine(None, None)).await.unwrap()).unwrap();

let receipt = node.get_transaction_receipt(tx_hash).await;
let contract_address = Address::from(ReviveAddress::new(receipt.contract_address.unwrap()));

let set_value_data = SimpleStorage::setValueCall::new((U256::from(5),)).abi_encode();
let tx = TransactionRequest::default()
.from(alith)
.to(contract_address)
.input(TransactionInput::both(set_value_data.into()));

let tx_hash = node.send_transaction(tx).await.unwrap();

unwrap_response::<()>(node.eth_rpc(EthRequest::Mine(None, None)).await.unwrap()).unwrap();

let _receipt = node.get_transaction_receipt(tx_hash).await;

// assert new value
let tx = TransactionRequest::default()
.from(alith)
.to(contract_address)
.input(TransactionInput::both(SimpleStorage::getValueCall.abi_encode().into()));

let value = unwrap_response::<Bytes>(
node.eth_rpc(EthRequest::EthCall(tx.into(), None, None, None)).await.unwrap(),
)
.unwrap();

let value = SimpleStorage::getValueCall::abi_decode_returns(&value.0).unwrap();

assert_eq!(value, U256::from(5));

// Get balance
assert_eq!(
node.get_balance(ReviveAddress::from(contract_address).inner(), None).await,
U256::from(0)
);

// Set a new balance
let contract_balance = U256::from_str_radix("200000000000000000000", 10).unwrap();
unwrap_response::<()>(
node.eth_rpc(EthRequest::SetBalance(contract_address, contract_balance)).await.unwrap(),
)
.unwrap();

// Check balance
assert_eq!(
node.get_balance(ReviveAddress::from(contract_address).inner(), None).await,
contract_balance
);

// Try spending the balance, need to impersonate first.
unwrap_response::<()>(
node.eth_rpc(EthRequest::ImpersonateAccount(contract_address)).await.unwrap(),
)
.unwrap();

let charleth = Account::from(subxt_signer::eth::dev::charleth());
let tx = TransactionRequest::default()
.value(U256::from(2e18))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: capture 2e18 in a variable, and use it when asserting on the expected balance

.from(contract_address)
.to(Address::from(ReviveAddress::new(charleth.address())));

let tx_hash = node.send_transaction(tx).await.unwrap();

unwrap_response::<()>(node.eth_rpc(EthRequest::Mine(None, None)).await.unwrap()).unwrap();

let transaction_receipt = node.get_transaction_receipt(tx_hash).await;
assert_eq!(transaction_receipt.transaction_hash, tx_hash);

let new_balance = contract_balance
- AlloyU256::from(transaction_receipt.effective_gas_price * transaction_receipt.gas_used)
.inner()
- U256::from(2e18);
assert_eq!(
node.get_balance(ReviveAddress::from(contract_address).inner(), None).await,
new_balance
);
assert_eq!(node.get_balance(charleth.address(), None).await, U256::from(2e18));

// Now try interacting with the contract again to check that it still works.
let set_value_data = SimpleStorage::setValueCall::new((U256::from(10),)).abi_encode();
let tx = TransactionRequest::default()
.from(alith)
.to(contract_address)
.input(TransactionInput::both(set_value_data.into()));

let tx_hash = node.send_transaction(tx).await.unwrap();

unwrap_response::<()>(node.eth_rpc(EthRequest::Mine(None, None)).await.unwrap()).unwrap();

let _receipt = node.get_transaction_receipt(tx_hash).await;

// assert new value.
let tx = TransactionRequest::default()
.from(alith)
.to(contract_address)
.input(TransactionInput::both(SimpleStorage::getValueCall.abi_encode().into()));

let value = unwrap_response::<Bytes>(
node.eth_rpc(EthRequest::EthCall(tx.into(), None, None, None)).await.unwrap(),
)
.unwrap();

let value = SimpleStorage::getValueCall::abi_decode_returns(&value.0).unwrap();

assert_eq!(value, U256::from(10));
}

#[tokio::test(flavor = "multi_thread")]
// Test setting the code of an existing contract.
async fn test_set_code_existing_contract() {
Expand Down
4 changes: 0 additions & 4 deletions crates/revive-strategy/src/cheatcodes/mock_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,6 @@ impl MockHandler<Runtime> for MockHandlerImpl {
None
}

fn mock_origin(&self) -> Option<&ExecOrigin<Runtime>> {
Comment thread
alindima marked this conversation as resolved.
Some(&self.origin)
}

fn mock_delegated_caller(
&self,
dest: H160,
Expand Down
4 changes: 2 additions & 2 deletions crates/revive-strategy/src/cheatcodes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ impl foundry_cheatcodes::CheatcodeInspectorStrategyExt for PvmCheatcodeInspector
if ecx.cfg.limit_contract_code_size == Some(usize::MAX)
|| ecx.cfg.limit_contract_initcode_size == Some(usize::MAX)
{
let debug_settings = DebugSettings::new(true);
let debug_settings = DebugSettings::new(true, true);
debug_settings.write_to_storage::<Runtime>();
}

Expand Down Expand Up @@ -1127,7 +1127,7 @@ impl foundry_cheatcodes::CheatcodeInspectorStrategyExt for PvmCheatcodeInspector
if ecx.cfg.limit_contract_code_size == Some(usize::MAX)
|| ecx.cfg.limit_contract_initcode_size == Some(usize::MAX)
{
let debug_settings = DebugSettings::new(true);
let debug_settings = DebugSettings::new(true, true);
debug_settings.write_to_storage::<Runtime>();
}
Pallet::<Runtime>::bare_call(
Expand Down
Loading