Skip to content

Commit

Permalink
more refactor, remote evm crate
Browse files Browse the repository at this point in the history
  • Loading branch information
gitofdeepanshu committed Aug 6, 2023
1 parent f0b7b69 commit 22bd42d
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 26 deletions.
6 changes: 6 additions & 0 deletions precompiles/batch/Batch.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,10 @@ interface Batch {
uint64[] memory gasLimit
) external;

/// Emitted when a subcall succeeds.
event SubcallSucceeded(uint256 index);

/// Emitted when a subcall fails.
event SubcallFailed(uint256 index);

}
13 changes: 3 additions & 10 deletions precompiles/batch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,7 @@ use frame_support::{
traits::ConstU32,
};
use pallet_evm::{Precompile, PrecompileOutput};
use precompile_utils::{
bytes::BoundedBytes,
data::BoundedVec,
evm::{costs::call_cost, logs::log1},
*,
};
use precompile_utils::{bytes::BoundedBytes, data::BoundedVec, *};
use sp_core::{H160, U256};
use sp_std::{iter::repeat, marker::PhantomData, vec, vec::Vec};

Expand All @@ -56,16 +51,14 @@ type GetCallDataLimit = ConstU32<CALL_DATA_LIMIT>;
type GetArrayLimit = ConstU32<ARRAY_LIMIT>;

pub fn log_subcall_succeeded(address: impl Into<H160>, index: usize) -> Log {
log1(
address,
LogsBuilder::new(address.into()).log1(
LOG_SUBCALL_SUCCEEDED,
data::encode_event_data(U256::from(index)),
)
}

pub fn log_subcall_failed(address: impl Into<H160>, index: usize) -> Log {
log1(
address,
LogsBuilder::new(address.into()).log1(
LOG_SUBCALL_FAILED,
data::encode_event_data(U256::from(index)),
)
Expand Down
36 changes: 22 additions & 14 deletions precompiles/batch/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use crate::mock::{precompile_address, BatchPrecompileMock, ExtBuilder, PrecompilesValue, Runtime};
use crate::{log_subcall_failed, log_subcall_succeeded, Mode, *};
use fp_evm::ExitError;
use precompile_utils::{evm::costs::call_cost, testing::*};
use precompile_utils::{call_cost, testing::*, LogsBuilder};
use sp_core::{H256, U256};

fn precompiles() -> BatchPrecompileMock<Runtime> {
Expand Down Expand Up @@ -155,7 +155,9 @@ fn batch_returns(

SubcallOutput {
cost: 13,
logs: vec![log1(Bob, H256::repeat_byte(0x11), vec![])],
logs: vec![
LogsBuilder::new(Bob.into()).log1(H256::repeat_byte(0x11), vec![])
],
..SubcallOutput::succeed()
}
}
Expand All @@ -180,7 +182,9 @@ fn batch_returns(

SubcallOutput {
cost: 17,
logs: vec![log1(Charlie, H256::repeat_byte(0x22), vec![])],
logs: vec![
LogsBuilder::new(Charlie.into()).log1(H256::repeat_byte(0x22), vec![])
],
..SubcallOutput::succeed()
}
}
Expand All @@ -194,9 +198,9 @@ fn batch_returns(
fn batch_some_returns() {
ExtBuilder::default().build().execute_with(|| {
batch_returns(&precompiles(), Mode::BatchSome)
.expect_log(log1(Bob, H256::repeat_byte(0x11), vec![]))
.expect_log(LogsBuilder::new(Bob.into()).log1(H256::repeat_byte(0x11), vec![]))
.expect_log(log_subcall_succeeded(precompile_address(), 0))
.expect_log(log1(Charlie, H256::repeat_byte(0x22), vec![]))
.expect_log(LogsBuilder::new(Charlie.into()).log1(H256::repeat_byte(0x22), vec![]))
.expect_log(log_subcall_succeeded(precompile_address(), 1))
.execute_returns(EvmDataWriter::new().write(true).build())
})
Expand All @@ -206,9 +210,9 @@ fn batch_some_returns() {
fn batch_some_until_failure_returns() {
ExtBuilder::default().build().execute_with(|| {
batch_returns(&precompiles(), Mode::BatchSomeUntilFailure)
.expect_log(log1(Bob, H256::repeat_byte(0x11), vec![]))
.expect_log(LogsBuilder::new(Bob.into()).log1(H256::repeat_byte(0x11), vec![]))
.expect_log(log_subcall_succeeded(precompile_address(), 0))
.expect_log(log1(Charlie, H256::repeat_byte(0x22), vec![]))
.expect_log(LogsBuilder::new(Charlie.into()).log1(H256::repeat_byte(0x22), vec![]))
.expect_log(log_subcall_succeeded(precompile_address(), 1))
.execute_returns(EvmDataWriter::new().write(true).build())
})
Expand All @@ -218,9 +222,9 @@ fn batch_some_until_failure_returns() {
fn batch_all_returns() {
ExtBuilder::default().build().execute_with(|| {
batch_returns(&precompiles(), Mode::BatchAll)
.expect_log(log1(Bob, H256::repeat_byte(0x11), vec![]))
.expect_log(LogsBuilder::new(Bob.into()).log1(H256::repeat_byte(0x11), vec![]))
.expect_log(log_subcall_succeeded(precompile_address(), 0))
.expect_log(log1(Charlie, H256::repeat_byte(0x22), vec![]))
.expect_log(LogsBuilder::new(Charlie.into()).log1(H256::repeat_byte(0x22), vec![]))
.expect_log(log_subcall_succeeded(precompile_address(), 1))
.execute_returns(EvmDataWriter::new().write(true).build())
})
Expand Down Expand Up @@ -371,7 +375,9 @@ fn batch_incomplete(

SubcallOutput {
cost: 13,
logs: vec![log1(Bob, H256::repeat_byte(0x11), vec![])],
logs: vec![
LogsBuilder::new(Bob.into()).log1(H256::repeat_byte(0x11), vec![])
],
..SubcallOutput::succeed()
}
}
Expand Down Expand Up @@ -421,7 +427,9 @@ fn batch_incomplete(

SubcallOutput {
cost: 19,
logs: vec![log1(Alice, H256::repeat_byte(0x33), vec![])],
logs: vec![
LogsBuilder::new(Alice.into()).log1(H256::repeat_byte(0x33), vec![])
],
..SubcallOutput::succeed()
}
}
Expand All @@ -436,10 +444,10 @@ fn batch_some_incomplete() {
let (_, total_call_cost) = costs();

batch_incomplete(&precompiles(), Mode::BatchSome)
.expect_log(log1(Bob, H256::repeat_byte(0x11), vec![]))
.expect_log(LogsBuilder::new(Bob.into()).log1(H256::repeat_byte(0x11), vec![]))
.expect_log(log_subcall_succeeded(precompile_address(), 0))
.expect_log(log_subcall_failed(precompile_address(), 1))
.expect_log(log1(Alice, H256::repeat_byte(0x33), vec![]))
.expect_log(LogsBuilder::new(Alice.into()).log1(H256::repeat_byte(0x33), vec![]))
.expect_log(log_subcall_succeeded(precompile_address(), 2))
.expect_cost(13 + 17 + 19 + total_call_cost * 3)
.execute_returns(EvmDataWriter::new().write(true).build())
Expand All @@ -452,7 +460,7 @@ fn batch_some_until_failure_incomplete() {
let (_, total_call_cost) = costs();

batch_incomplete(&precompiles(), Mode::BatchSomeUntilFailure)
.expect_log(log1(Bob, H256::repeat_byte(0x11), vec![]))
.expect_log(LogsBuilder::new(Bob.into()).log1(H256::repeat_byte(0x11), vec![]))
.expect_log(log_subcall_succeeded(precompile_address(), 0))
.expect_log(log_subcall_failed(precompile_address(), 1))
.expect_cost(13 + 17 + total_call_cost * 2)
Expand Down
64 changes: 63 additions & 1 deletion precompiles/utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use sp_std::{marker::PhantomData, vec, vec::Vec};

pub mod bytes;
pub mod data;
pub mod evm;
// pub mod evm;

pub use data::{Address, Bytes, EvmData, EvmDataReader, EvmDataWriter};
pub use precompile_utils_macro::{generate_function_selector, keccak256};
Expand Down Expand Up @@ -304,6 +304,68 @@ pub fn log_costs(topics: usize, data_len: usize) -> EvmResult<u64> {
})
}

// Compute the cost of doing a subcall.
// Some parameters cannot be known in advance, so we estimate the worst possible cost.
pub fn call_cost(value: U256, config: &evm::Config) -> u64 {
// Copied from EVM code since not public.
pub const G_CALLVALUE: u64 = 9000;
pub const G_NEWACCOUNT: u64 = 25000;

fn address_access_cost(is_cold: bool, regular_value: u64, config: &evm::Config) -> u64 {
if config.increase_state_access_gas {
if is_cold {
config.gas_account_access_cold
} else {
config.gas_storage_read_warm
}
} else {
regular_value
}
}

fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 {
if is_call_or_callcode && transfers_value {
G_CALLVALUE
} else {
0
}
}

fn new_cost(
is_call_or_staticcall: bool,
new_account: bool,
transfers_value: bool,
config: &evm::Config,
) -> u64 {
let eip161 = !config.empty_considered_exists;
if is_call_or_staticcall {
if eip161 {
if transfers_value && new_account {
G_NEWACCOUNT
} else {
0
}
} else if new_account {
G_NEWACCOUNT
} else {
0
}
} else {
0
}
}

let transfers_value = value != U256::default();
let is_cold = true;
let is_call_or_callcode = true;
let is_call_or_staticcall = true;
let new_account = true;

address_access_cost(is_cold, config.gas_call, config)
+ xfer_cost(is_call_or_callcode, transfers_value)
+ new_cost(is_call_or_staticcall, new_account, transfers_value, config)
}

impl<T: PrecompileHandle> PrecompileHandleExt for T {
#[must_use]
/// Record cost of a log manualy.
Expand Down
2 changes: 1 addition & 1 deletion precompiles/utils/src/testing/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl PrecompileHandle for MockHandle {
context: &Context,
) -> (ExitReason, Vec<u8>) {
if self
.record_cost(crate::evm::costs::call_cost(
.record_cost(crate::call_cost(
context.apparent_value,
&evm::Config::london(),
))
Expand Down

0 comments on commit 22bd42d

Please sign in to comment.