Skip to content

Commit

Permalink
feat: native tokens
Browse files Browse the repository at this point in the history
Co-authored-by: Iaroslav Mazur <[email protected]>
  • Loading branch information
PaulRBerg and IaroslavMazur committed May 28, 2024
1 parent eb24a7f commit 5a7168f
Show file tree
Hide file tree
Showing 48 changed files with 1,541 additions and 297 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions bins/revm-test/src/bin/burntpix/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use regex::bytes::Regex;
use revm::{
db::{CacheDB, EmptyDB},
primitives::{
address, hex, keccak256, AccountInfo, Address, Bytecode, Bytes, ExecutionResult, Output,
TransactTo, B256, U256,
address, hex, keccak256, AccountInfo, Address, Balances, Bytecode, Bytes, ExecutionResult,
Output, TransactTo, B256, BASE_TOKEN_ID, U256,
},
Evm,
};
Expand Down Expand Up @@ -102,7 +102,7 @@ fn try_from_hex_to_u32(hex: &str) -> eyre::Result<u32> {
fn insert_account_info(cache_db: &mut CacheDB<EmptyDB>, addr: Address, code: Bytes) {
let code_hash = hex::encode(keccak256(code.clone()));
let account_info = AccountInfo::new(
U256::from(0),
Balances::from([(BASE_TOKEN_ID, U256::ZERO)]),
0,
B256::from_str(&code_hash).unwrap(),
Bytecode::new_raw(code),
Expand Down
8 changes: 6 additions & 2 deletions bins/revm-test/src/bin/transfer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use revm::{
db::BenchmarkDB,
primitives::{Bytecode, TransactTo, U256},
primitives::{Bytecode, TokenTransfer, TransactTo, BASE_TOKEN_ID, U256},
Evm,
};

Expand All @@ -15,7 +15,11 @@ fn main() {
tx.caller = "0x0000000000000000000000000000000000000001"
.parse()
.unwrap();
tx.value = U256::from(10);
let token_transfer = TokenTransfer {
id: BASE_TOKEN_ID,
amount: U256::from(10),
};
tx.transferred_tokens = vec![token_transfer];
tx.transact_to = TransactTo::Call(
"0x0000000000000000000000000000000000000000"
.parse()
Expand Down
3 changes: 2 additions & 1 deletion bins/revme/src/cmd/statetest/merkle_trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ impl TrieAccount {
fn new(acc: &PlainAccount) -> Self {
Self {
nonce: acc.info.nonce,
balance: acc.info.balance,
// TODO: keep track of all of the NT balances here, instead?
balance: acc.info.get_base_balance(),
root_hash: sec_trie_root::<KeccakHasher, _, _, _>(
acc.storage
.iter()
Expand Down
1 change: 1 addition & 0 deletions bins/revme/src/cmd/statetest/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub struct TxPartIndices {
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct AccountInfo {
/// Not a balances mapping because it has to remain compatible with the upstream Ethereum tests
pub balance: U256,
pub code: Bytes,
#[serde(deserialize_with = "deserialize_str_as_u64")]
Expand Down
12 changes: 8 additions & 4 deletions bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use revm::{
inspector_handle_register,
inspectors::TracerEip3155,
primitives::{
calc_excess_blob_gas, keccak256, Bytecode, Bytes, EVMResultGeneric, Env, ExecutionResult,
SpecId, TransactTo, B256, U256,
calc_excess_blob_gas, init_balances, keccak256, Bytecode, Bytes, EVMResultGeneric, Env,
ExecutionResult, SpecId, TokenTransfer, TransactTo, B256, BASE_TOKEN_ID, U256,
},
Evm, State,
};
Expand Down Expand Up @@ -258,7 +258,7 @@ pub fn execute_test_suite(
let mut cache_state = revm::CacheState::new(false);
for (address, info) in unit.pre {
let acc_info = revm::primitives::AccountInfo {
balance: info.balance,
balances: init_balances(info.balance),
code_hash: keccak256(&info.code),
code: Some(Bytecode::new_raw(info.code)),
nonce: info.nonce,
Expand Down Expand Up @@ -336,7 +336,11 @@ pub fn execute_test_suite(
.get(test.indexes.data)
.unwrap()
.clone();
env.tx.value = unit.transaction.value[test.indexes.value];
let token_transfer = TokenTransfer {
id: BASE_TOKEN_ID,
amount: U256::from(unit.transaction.value[test.indexes.value]),
};
env.tx.transferred_tokens = vec![token_transfer];

env.tx.access_list = unit
.transaction
Expand Down
1 change: 1 addition & 0 deletions crates/interpreter/src/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ impl Gas {
#[inline]
pub fn set_refund(&mut self, refund: i64) {
self.refunded = refund;
// TODO: how is it made sure that by the end of the tx, self.refunded is positive?
}

/// Records an explicit cost.
Expand Down
18 changes: 18 additions & 0 deletions crates/interpreter/src/gas/calc.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use revm_primitives::TokenTransfer;

use super::constants::*;
use crate::{
num_words,
Expand Down Expand Up @@ -358,6 +360,7 @@ pub fn validate_initial_tx_gas(
input: &[u8],
is_create: bool,
access_list: &[(Address, Vec<U256>)],
transferred_tokens: &[TokenTransfer],
) -> u64 {
let mut initial_gas = 0;
let zero_data_len = input.iter().filter(|v| **v == 0).count() as u64;
Expand Down Expand Up @@ -400,5 +403,20 @@ pub fn validate_initial_tx_gas(
initial_gas += initcode_cost(input.len() as u64)
}

// gas cost of transferring the Native Tokens
if !transferred_tokens.is_empty() {
initial_gas += transferred_tokens.len() as u64 * TRANSFERRED_TOKEN;
}

initial_gas
}

#[inline]
pub fn burn_cost() -> Option<u64> {
Some(BURN_TOKENS)
}

#[inline]
pub fn mint_cost() -> Option<u64> {
Some(MINT_TOKENS)
}
5 changes: 5 additions & 0 deletions crates/interpreter/src/gas/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,8 @@ pub const WARM_SSTORE_RESET: u64 = SSTORE_RESET - COLD_SLOAD_COST;
pub const INITCODE_WORD_COST: u64 = 2;

pub const CALL_STIPEND: u64 = 2300;

/// Sablier
pub const BURN_TOKENS: u64 = 10000;
pub const MINT_TOKENS: u64 = 10000;
pub const TRANSFERRED_TOKEN: u64 = 50;
27 changes: 24 additions & 3 deletions crates/interpreter/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::primitives::{Address, Bytecode, Env, Log, B256, U256};

mod dummy;
pub use dummy::DummyHost;
use revm_primitives::BASE_TOKEN_ID;

/// EVM context host.
pub trait Host {
Expand All @@ -19,9 +20,6 @@ pub trait Host {
/// Get the block hash of the given block `number`.
fn block_hash(&mut self, number: U256) -> Option<B256>;

/// Get balance of `address` and if the account is cold.
fn balance(&mut self, address: Address) -> Option<(U256, bool)>;

/// Get code of `address` and if the account is cold.
fn code(&mut self, address: Address) -> Option<(Bytecode, bool)>;

Expand All @@ -47,6 +45,29 @@ pub trait Host {

/// Mark `address` to be deleted, with funds transferred to `target`.
fn selfdestruct(&mut self, address: Address, target: Address) -> Option<SelfDestructResult>;

/// Get token balance of address and if account is cold loaded.
fn balance(&mut self, token_id: U256, address: Address) -> Option<(U256, bool)>;

/// Get the base token balance of `address` and if the account is cold.
fn base_balance(&mut self, address: Address) -> Option<(U256, bool)> {
self.balance(BASE_TOKEN_ID, address)
}

/// Burn a Native Token.
fn burn(&mut self, burner: Address, sub_id: U256, amount: U256) -> bool;

/// Check whether the sender of the current tx is an EOA.
fn is_tx_sender_eoa(&mut self) -> bool {
// TODO: tx.caller == tx.origin => it will always be an EOA
// at the same time, the address actually calling the MINT
// opcode will always be a contract
let caller = self.env().tx.caller;
self.code(caller).is_none()
}

/// Mint a Native Token.
fn mint(&mut self, minter: Address, recipient: Address, sub_id: U256, amount: U256) -> bool;
}

/// Represents the result of an `sstore` operation.
Expand Down
31 changes: 26 additions & 5 deletions crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,6 @@ impl Host for DummyHost {
Some(B256::ZERO)
}

#[inline]
fn balance(&mut self, _address: Address) -> Option<(U256, bool)> {
Some((U256::ZERO, false))
}

#[inline]
fn code(&mut self, _address: Address) -> Option<(Bytecode, bool)> {
Some((Bytecode::default(), false))
Expand Down Expand Up @@ -121,4 +116,30 @@ impl Host for DummyHost {
fn selfdestruct(&mut self, _address: Address, _target: Address) -> Option<SelfDestructResult> {
panic!("Selfdestruct is not supported for this host")
}

#[inline]
fn balance(&mut self, _token_id: U256, _address: Address) -> Option<(U256, bool)> {
Some((U256::ZERO, false))
}

#[inline]
fn burn(&mut self, _burner: Address, _sub_id: U256, _amount: U256) -> bool {
panic!("Burn is not supported for this host")
}

#[inline]
fn is_tx_sender_eoa(&mut self) -> bool {
false
}

#[inline]
fn mint(
&mut self,
_minter: Address,
_recipient: Address,
_sub_id: U256,
_amount: U256,
) -> bool {
panic!("Mint is not supported for this host")
}
}
4 changes: 4 additions & 0 deletions crates/interpreter/src/instruction_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub enum InstructionResult {
EOFOpcodeDisabledInLegacy,
/// EOF function stack overflow
EOFFunctionStackOverflow,
UnauthorizedCaller,
}

impl From<SuccessReason> for InstructionResult {
Expand Down Expand Up @@ -95,6 +96,7 @@ impl From<HaltReason> for InstructionResult {
HaltReason::CallTooDeep => Self::CallTooDeep,
#[cfg(feature = "optimism")]
HaltReason::FailedDeposit => Self::FatalExternalError,
HaltReason::UnauthorizedCaller => Self::UnauthorizedCaller,
}
}
}
Expand Down Expand Up @@ -272,6 +274,7 @@ impl From<InstructionResult> for SuccessOrHalt {
InstructionResult::ReturnContract => {
panic!("Unexpected EOF internal Return Contract")
}
InstructionResult::UnauthorizedCaller => Self::Halt(HaltReason::UnauthorizedCaller),
}
}
}
Expand All @@ -287,6 +290,7 @@ mod tests {
return_revert!() => {}
return_ok!() => {}
InstructionResult::CallOrCreate => {}
InstructionResult::UnauthorizedCaller => {}
}
}

Expand Down
Loading

0 comments on commit 5a7168f

Please sign in to comment.