Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
693 changes: 357 additions & 336 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 = "pkhry/external_transient_storage", 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 = "pkhry/external_transient_storage"}
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 = "pkhry/external_transient_storage", default-features = false }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "pkhry/external_transient_storage", default-features = false, features = [
"sc-allocator",
"sc-basic-authorship",
"sc-block-builder",
Expand Down
67 changes: 64 additions & 3 deletions crates/anvil-polkadot/src/api_server/revive_conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use alloy_primitives::{Address, B256};
use alloy_rpc_types::{
AccessList, FilterBlockOption, FilterSet, SignedAuthorization, Topic, TransactionRequest,
trace::geth::{
AccountState, CallFrame, CallLogFrame, DiffMode, GethDebugBuiltInTracerType,
AccountState, CallFrame, CallLogFrame, DefaultFrame, DiffMode, GethDebugBuiltInTracerType,
GethDebugTracerType, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace,
PreStateFrame, PreStateMode,
PreStateFrame, PreStateMode, StructLog,
},
};
use polkadot_sdk::{
Expand All @@ -17,6 +17,7 @@ use polkadot_sdk::{
},
sp_core,
};
use revm::bytecode::OpCode;
use serde::{Deserialize, Serialize};
use subxt::utils::{H160, H256};

Expand All @@ -30,7 +31,11 @@ impl From<polkadot_sdk::sp_core::U256> for AlloyU256 {
Self(alloy_primitives::U256::from_be_bytes(bytes))
}
}

impl From<u64> for AlloyU256 {
fn from(value: u64) -> Self {
Self(alloy_primitives::U256::from(value))
}
}
impl AlloyU256 {
pub fn inner(&self) -> alloy_primitives::U256 {
self.0
Expand Down Expand Up @@ -484,6 +489,62 @@ impl ReviveTrace {
impl From<ReviveTrace> for GethTrace {
fn from(value: ReviveTrace) -> Self {
match value.inner() {
Trace::Execution(execution_trace) => Self::Default(DefaultFrame {
failed: execution_trace.failed,
gas: execution_trace.gas,
return_value: execution_trace.return_value.0.into(),
struct_logs: execution_trace
.struct_logs
.into_iter()
.filter_map(|struct_| match struct_.kind {
evm::ExecutionStepKind::EVMOpcode { pc, op, stack, memory, storage } => {
Some(StructLog {
pc: pc.into(),
op: OpCode::new(op).map(|x| x.as_str().into()).unwrap_or_default(),
gas: struct_.gas,
gas_cost: struct_.gas_cost,
depth: struct_.depth.into(),
error: struct_.error,
stack: if stack.is_empty() {
None
} else {
Some(
stack
.into_iter()
.map(|x| alloy_primitives::U256::from_be_slice(&x.0))
.collect(),
)
},
return_data: if struct_.return_data.is_empty() {
None
} else {
Some(struct_.return_data.0.into())
},
memory: if memory.is_empty() {
None
} else {
memory
.into_iter()
.map(|x| String::from_utf8(x.0))
.collect::<Result<Vec<String>, _>>()
.ok()
.or_else(|| None)
},
memory_size: None, // TODO: fixme
storage: storage.map(|x| {
x.into_iter()
.map(|(k, v)| {
(B256::from_slice(&k.0), B256::from_slice(&v.0))
})
.collect()
}),
refund_counter: None,
})
}
evm::ExecutionStepKind::PVMSyscall { op: _, args: _, returned: _ } => None,
})
.collect(),
}),
Trace::Call(call_trace) => Self::CallTracer(ReviveCallTrace::new(call_trace).into()),
Trace::Prestate(PrestateTrace::Prestate(prestate_map)) => {
Self::PreStateTracer(PreStateFrame::Default(PreStateMode(
Expand Down
2 changes: 1 addition & 1 deletion crates/anvil-polkadot/src/api_server/trace_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub fn parity_transaction_trace_builder(
) -> Result<Vec<LocalizedTransactionTrace>, Error> {
let call_trace = match trace {
Trace::Call(call_trace) => call_trace,
Trace::Prestate(_) => {
Trace::Prestate(_) | Trace::Execution(_) => {
return Err(Error::InternalError("Trace is not a call trace".to_string()));
}
};
Expand Down
8 changes: 7 additions & 1 deletion crates/anvil-polkadot/src/substrate_node/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,13 @@ impl GenesisConfig {
let genesis_nonce: u64 = account.nonce.unwrap_or_default();
let contract_data: Option<ContractData> = if account.code.is_some() {
Some(ContractData {
code: account.code.clone().map(|code| code.to_vec()).unwrap_or_default(),
code: account
.code
.clone()
.map(|code| {
polkadot_sdk::pallet_revive::evm::Bytes::from(code.to_vec())
})
.unwrap_or_default(),
storage: account
.storage
.clone()
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 = "pkhry/external_transient_storage", default-features = false, features = [
Copy link

Choose a reason for hiding this comment

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

Do you plan to use this ?

Copy link
Author

Choose a reason for hiding this comment

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

will use latest master as soon as the pr is merged

"pallet-aura",
"pallet-balances",
"pallet-revive",
Expand All @@ -29,7 +29,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 = "pkhry/external_transient_storage", default-features = false, optional = true, features = ["substrate-wasm-builder"] }

[features]
default = ["std"]
Expand Down
1 change: 1 addition & 0 deletions crates/forge/tests/it/revive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ pub mod cheats_individual;
pub mod fuzz_max_int;
pub mod migration;
pub mod record_accesses;
pub mod transient_storage;
pub mod tx_gas_price;
16 changes: 16 additions & 0 deletions crates/forge/tests/it/revive/transient_storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use crate::{config::*, test_helpers::TEST_DATA_REVIVE};
use foundry_test_utils::Filter;
use revive_strategy::ReviveRuntimeMode;
use revm::primitives::hardfork::SpecId;
use rstest::rstest;

#[rstest]
#[case::pvm(ReviveRuntimeMode::Pvm)]
#[case::evm(ReviveRuntimeMode::Evm)]
#[tokio::test(flavor = "multi_thread")]
async fn test_transient_storage(#[case] runtime_mode: ReviveRuntimeMode) {
let runner: forge::MultiContractRunner = TEST_DATA_REVIVE.runner_revive(runtime_mode);
let filter = Filter::new("testTransientStoragePersistence", "TransientStorage", ".*/revive/.*");

TestConfig::with_filter(runner, filter).spec_id(SpecId::PRAGUE).run().await;
}
2 changes: 1 addition & 1 deletion crates/revive-env/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ parameter_types! {
pub const UnstableInterface: bool = true;
pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0);
pub const NativeToEthRatio: u32 = 1_000_000;
pub const GasScale : u32 = 1_000_000;
pub const GasScale : u32 = 100_000_000;
Copy link
Collaborator

Choose a reason for hiding this comment

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

What does it fix?

Copy link
Author

Choose a reason for hiding this comment

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

OutOfGas errors with balancer v3


pub const DepositPerByte: Balance = 1;
pub const DepositPerItem: Balance = 2;
Expand Down
27 changes: 18 additions & 9 deletions crates/revive-strategy/src/cheatcodes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,12 @@ fn select_revive(
ctx.externalities.execute_with(||{
// Enable debug mode to bypass EIP-170 size checks during testing
if data.cfg.limit_contract_code_size == Some(usize::MAX) {
let debug_settings = DebugSettings::new(true, true, true);
let debug_settings = {
DebugSettings::default()
.set_allow_unlimited_contract_size(true)
.set_bypass_eip_3607(true)
.set_enable_pvm_logs(true)
};
debug_settings.write_to_storage::<Runtime>();
}
<revive_env::Runtime as polkadot_sdk::pallet_revive::Config>::ChainId::set(
Expand Down Expand Up @@ -1082,7 +1087,7 @@ impl foundry_cheatcodes::CheatcodeInspectorStrategyExt for PvmCheatcodeInspector
let caller_h160 = H160::from_slice(input.caller().as_slice());
let eth_deals = &state.eth_deals;

let res = ctx.externalities.execute_with(|| {
let res = ctx.externalities.execute_with_transient_storage(|transient_storage| {
tracer.watch_address(&caller_h160);

tracer.trace(|| {
Expand Down Expand Up @@ -1135,9 +1140,10 @@ impl foundry_cheatcodes::CheatcodeInspectorStrategyExt for PvmCheatcodeInspector
effective_gas_price: Some(gas_price_pvm),
mock_handler: Some(Box::new(mock_handler.clone())),
is_dry_run: None,
transient_storage: Some(transient_storage),
};

Pallet::<Runtime>::bare_instantiate(
let result = Pallet::<Runtime>::bare_instantiate(
origin,
evm_value,
pallet_revive::TransactionLimits::WeightAndDeposit {
Expand All @@ -1147,8 +1153,9 @@ impl foundry_cheatcodes::CheatcodeInspectorStrategyExt for PvmCheatcodeInspector
code,
data,
salt,
exec_config,
)
&exec_config,
);
(result, exec_config.transient_storage.expect("can't happen"))
})
});
let mut gas = Gas::new(input.gas_limit());
Expand Down Expand Up @@ -1292,7 +1299,7 @@ impl foundry_cheatcodes::CheatcodeInspectorStrategyExt for PvmCheatcodeInspector

let mut tracer = Tracer::new(state.expected_calls.clone(), state.expected_creates.clone());
let eth_deals = &state.eth_deals;
let res = ctx.externalities.execute_with(|| {
let res = ctx.externalities.execute_with_transient_storage(|transient_storage| {
// Watch the caller's address so its nonce changes get tracked in prestate trace
tracer.watch_address(&caller_h160);

Expand All @@ -1310,13 +1317,14 @@ impl foundry_cheatcodes::CheatcodeInspectorStrategyExt for PvmCheatcodeInspector
effective_gas_price: Some(gas_price_pvm),
mock_handler: Some(Box::new(mock_handler.clone())),
is_dry_run: None,
transient_storage: Some(transient_storage),
};
if should_bump_nonce {
System::inc_account_nonce(
AccountId32Mapper::<Runtime>::to_fallback_account_id(&caller_h160),
);
}
Pallet::<Runtime>::bare_call(
let result = Pallet::<Runtime>::bare_call(
origin,
target,
evm_value,
Expand All @@ -1325,8 +1333,9 @@ impl foundry_cheatcodes::CheatcodeInspectorStrategyExt for PvmCheatcodeInspector
deposit_limit: if call.is_static { 0 } else { 100_000_000_000_000 },
},
call.input.bytes(ecx).to_vec(),
exec_config,
)
&exec_config,
);
(result, exec_config.transient_storage.expect("can't happen"))
})
});
mock_handler.update_state_mocks(state);
Expand Down
16 changes: 7 additions & 9 deletions crates/revive-strategy/src/executor/runner.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use crate::{
backend::ReviveBackendStrategyBuilder, cheatcodes::PvmCheatcodeInspectorStrategyBuilder,
executor::context::ReviveExecutorStrategyContext, state::TestEnv,
};
use alloy_primitives::{Address, U256};
use foundry_cheatcodes::CheatcodeInspectorStrategy;
use foundry_compilers::{
Expand All @@ -11,14 +15,8 @@ use foundry_evm::{
strategy::ExecutorStrategyExt,
},
};
use polkadot_sdk::sp_externalities::Externalities;
use revm::context::result::ResultAndState;

use crate::{
backend::ReviveBackendStrategyBuilder, cheatcodes::PvmCheatcodeInspectorStrategyBuilder,
executor::context::ReviveExecutorStrategyContext,
};

/// Defines the [ExecutorStrategyRunner] strategy for Revive.
#[derive(Debug, Default, Clone)]
pub struct ReviveExecutorStrategyRunner;
Expand Down Expand Up @@ -156,13 +154,13 @@ impl ExecutorStrategyExt for ReviveExecutorStrategyRunner {
}
fn start_transaction(&self, ctx: &dyn ExecutorStrategyContext) {
let ctx = get_context_ref(ctx);
let mut externalities = ctx.externalties.0.lock().unwrap();
externalities.externalities.ext().storage_start_transaction();
let mut state = ctx.externalties.0.lock().unwrap();
TestEnv::start_transaction(&mut state);
}

fn rollback_transaction(&self, ctx: &dyn ExecutorStrategyContext) {
let ctx = get_context_ref(ctx);
let mut state = ctx.externalties.0.lock().unwrap();
let _ = state.externalities.ext().storage_rollback_transaction();
TestEnv::revert_transaction(&mut state);
}
}
Loading
Loading