Skip to content

Commit

Permalink
feat: charge gas for each Transferred Asset
Browse files Browse the repository at this point in the history
  • Loading branch information
IaroslavMazur committed Jan 1, 2024
1 parent df22148 commit 692791b
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 13 deletions.
9 changes: 7 additions & 2 deletions crates/interpreter/src/gas/calc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::constants::*;
use crate::primitives::{Address, Spec, SpecId::*, U256};
use crate::primitives::{Address, Spec, SpecId::*, TransferredAsset, U256};
use alloc::vec::Vec;

#[allow(clippy::collapsible_else_if)]
Expand Down Expand Up @@ -312,11 +312,12 @@ pub fn mint_cost<SPEC: Spec>(_is_cold: bool) -> Option<u64> {
}

/// Initial gas that is deducted for transaction to be included.
/// Initial gas contains initial stipend gas, gas for access list and input data.
/// Initial gas contains initial stipend gas, gas for access list and input data, and gas for transferred MNAs.
pub fn initial_tx_gas<SPEC: Spec>(
input: &[u8],
is_create: bool,
access_list: &[(Address, Vec<U256>)],
transferred_assets: &Option<Vec<TransferredAsset>>,
) -> u64 {
let mut initial_gas = 0;
let zero_data_len = input.iter().filter(|v| **v == 0).count() as u64;
Expand Down Expand Up @@ -354,5 +355,9 @@ pub fn initial_tx_gas<SPEC: Spec>(
initial_gas += initcode_cost(input.len() as u64)
}

if let Some(assets) = transferred_assets {
initial_gas += assets.len() as u64 * TRANSFERRED_ASSET;
}

initial_gas
}
2 changes: 2 additions & 0 deletions crates/interpreter/src/gas/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ pub const WARM_STORAGE_READ_COST: u64 = 100;
pub const INITCODE_WORD_COST: u64 = 2;

pub const CALL_STIPEND: u64 = 2300;

pub const TRANSFERRED_ASSET: u64 = 50;
9 changes: 6 additions & 3 deletions crates/revm/benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use revm::{
db::BenchmarkDB,
interpreter::{analysis::to_analysed, BytecodeLocked, Contract, DummyHost, Interpreter},
primitives::{
address, bytes, hex, BerlinSpec, Bytecode, BytecodeState, Bytes, TransactTo, B256,
BASE_ASSET_ID, U256,
address, bytes, hex, BerlinSpec, Bytecode, BytecodeState, Bytes, TransactTo,
TransferredAsset, B256, BASE_ASSET_ID, U256,
},
};
use revm_interpreter::{opcode::make_instruction_table, SharedMemory, EMPTY_SHARED_MEMORY};
Expand Down Expand Up @@ -69,7 +69,10 @@ fn transfer(c: &mut Criterion) {

evm.env.tx.caller = address!("0000000000000000000000000000000000000001");
evm.env.tx.transact_to = TransactTo::Call(address!("0000000000000000000000000000000000000000"));
evm.env.tx.transferred_assets = Some(vec![(B256::from(BASE_ASSET_ID), U256::from(10))]);
evm.env.tx.transferred_assets = Some(vec![TransferredAsset {
id: B256::from(BASE_ASSET_ID),
amount: U256::from(10),
}]);

let mut g = c.benchmark_group("transfer");
g.noise_threshold(0.03).warm_up_time(Duration::from_secs(1));
Expand Down
2 changes: 2 additions & 0 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ impl<'a, SPEC: Spec + 'static, DB: Database> EVMImpl<'a, SPEC, DB> {
&env.tx.data,
env.tx.transact_to.is_create(),
&env.tx.access_list,
&env.tx.transferred_assets,
);

// Additional check to see if limit is big enough to cover initial gas.
Expand Down Expand Up @@ -415,6 +416,7 @@ impl<'a, SPEC: Spec + 'static, DB: Database> EVMImpl<'a, SPEC, DB> {
&tx_data,
env.tx.transact_to.is_create(),
&env.tx.access_list,
&env.tx.transferred_assets,
);

// load coinbase
Expand Down
12 changes: 6 additions & 6 deletions crates/revm/src/handler/optimism.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ mod tests {

let gas = handle_call_return::<BedrockSpec>(&env, InstructionResult::Revert, Gas::new(90));
assert_eq!(gas.remaining(), 90);
assert_eq!(gas.spend(), 10);
assert_eq!(gas.spent(), 10);
assert_eq!(gas.refunded(), 0);
}

Expand All @@ -268,7 +268,7 @@ mod tests {
let gas = handle_call_return::<BedrockSpec>(&env, InstructionResult::Revert, Gas::new(90));
// else branch takes all gas.
assert_eq!(gas.remaining(), 0);
assert_eq!(gas.spend(), 100);
assert_eq!(gas.spent(), 100);
assert_eq!(gas.refunded(), 0);
}

Expand All @@ -281,7 +281,7 @@ mod tests {

let gas = handle_call_return::<RegolithSpec>(&env, InstructionResult::Stop, Gas::new(90));
assert_eq!(gas.remaining(), 90);
assert_eq!(gas.spend(), 10);
assert_eq!(gas.spent(), 10);
assert_eq!(gas.refunded(), 0);
}

Expand All @@ -297,12 +297,12 @@ mod tests {

let gas = handle_call_return::<RegolithSpec>(&env, InstructionResult::Stop, ret_gas);
assert_eq!(gas.remaining(), 90);
assert_eq!(gas.spend(), 10);
assert_eq!(gas.spent(), 10);
assert_eq!(gas.refunded(), 20);

let gas = handle_call_return::<RegolithSpec>(&env, InstructionResult::Revert, ret_gas);
assert_eq!(gas.remaining(), 90);
assert_eq!(gas.spend(), 10);
assert_eq!(gas.spent(), 10);
assert_eq!(gas.refunded(), 0);
}

Expand All @@ -315,7 +315,7 @@ mod tests {

let gas = handle_call_return::<BedrockSpec>(&env, InstructionResult::Stop, Gas::new(90));
assert_eq!(gas.remaining(), 0);
assert_eq!(gas.spend(), 100);
assert_eq!(gas.spent(), 100);
assert_eq!(gas.refunded(), 0);
}
}
5 changes: 3 additions & 2 deletions crates/revm/src/inspector/customprinter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,12 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {

#[cfg(test)]
mod test {
use crate::primitives::TransferredAsset;
#[test]
#[cfg(not(feature = "optimism"))]
fn gas_calculation_underflow() {
use crate::primitives::{address, bytes, init_balances, B256, BASE_ASSET_ID, U256};
use crate::primitives::{
address, bytes, init_balances, TransferredAsset, B256, BASE_ASSET_ID, U256,
};

// https://github.com/bluealloy/revm/issues/277
// checks this use case
Expand Down

0 comments on commit 692791b

Please sign in to comment.