Skip to content

Commit

Permalink
feat: mint opcode (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulRBerg committed Sep 28, 2023
1 parent 0813fad commit f003a89
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 11 deletions.
6 changes: 6 additions & 0 deletions crates/interpreter/src/gas/calc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,12 @@ pub fn memory_gas(a: usize) -> u64 {
.saturating_add(a.saturating_mul(a) / 512)
}

/// TODO: implement
#[inline]
pub fn mint_cost<SPEC: Spec>(_is_cold: bool) -> Option<u64> {
Some(1)
}

/// Initial gas that is deducted for transaction to be included.
/// Initial gas contains initial stipend gas, gas for access list and input data.
pub fn initial_tx_gas<SPEC: Spec>(
Expand Down
4 changes: 2 additions & 2 deletions crates/interpreter/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub trait Host {
/// Get asset balance of address and if account is cold loaded.
fn balanceof(&mut self, asset_id: B256, address: B160) -> Option<(U256, bool)>;
/// Mint a native asset.
fn mint(&mut self, address: B160, value: U256) -> (InstructionResult, Gas);
fn mint(&mut self, address: B160, sub_id: B256, value: U256) -> Option<bool>;
/// Burn a native asset.
fn burn(&mut self, address: B160, value: U256) -> (InstructionResult, Gas);
fn burn(&mut self, address: B160, sub_id: B256, value: U256) -> Option<bool>;
}
4 changes: 2 additions & 2 deletions crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ impl Host for DummyHost {
}

#[inline]
fn mint(&mut self, _address: B160, _value: U256) -> (InstructionResult, Gas) {
fn mint(&mut self, _address: B160, _sub_id: B256, _value: U256) -> Option<bool> {
panic!("Mint is not supported for this host")
}

#[inline]
fn burn(&mut self, _address: B160, _value: U256) -> (InstructionResult, Gas) {
fn burn(&mut self, _address: B160, _sub_id: B256, _value: U256) -> Option<bool> {
panic!("Burn is not supported for this host")
}
}
12 changes: 11 additions & 1 deletion crates/interpreter/src/instructions/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,16 @@ pub fn balanceof<H: Host, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut
push!(interpreter, balance);
}

pub fn mint<H: Host, SPEC: Spec>(_interpreter: &mut Interpreter, _host: &mut H) {}
pub fn mint<H: Host, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
pop!(interpreter, sub_id, value);

let sub_id = B256::from(sub_id);

let Some(is_cold) = host.mint(interpreter.contract.address, sub_id, value) else {
interpreter.instruction_result = InstructionResult::FatalExternalError;
return;
};
gas_or_fail!(interpreter, { gas::mint_cost::<SPEC>(is_cold) });
}

pub fn burn<H: Host, SPEC: Spec>(_interpreter: &mut Interpreter, _host: &mut H) {}
4 changes: 2 additions & 2 deletions crates/interpreter/src/instructions/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ opcodes! {
// 0xBE
// 0xBF
0xC0 => BALANCEOF => host::balanceof::<H, SPEC>,
// 0xC1 => MINT => (),
0xC1 => MINT => host::mint::<H,SPEC>,
// 0xC2 => BURN => (),
// 0xC3
// 0xC4
Expand Down Expand Up @@ -753,7 +753,7 @@ const fn opcode_gas_info(opcode: u8, spec: SpecId) -> OpInfo {
0xBE => OpInfo::none(),
0xBF => OpInfo::none(),
BALANCEOF => OpInfo::dynamic_gas(),
0xC1 => OpInfo::none(),
MINT => OpInfo::none(),
0xC2 => OpInfo::none(),
0xC3 => OpInfo::none(),
0xC4 => OpInfo::none(),
Expand Down
8 changes: 8 additions & 0 deletions crates/primitives/src/utilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ pub fn keccak256(input: &[u8]) -> B256 {
B256(Keccak256::digest(input)[..].try_into().unwrap())
}

/// Returns the asset ID by hashing the address and sub ID.
pub fn asset_id_address(address: B160, sub_id: B256) -> B256 {
let mut hasher = Keccak256::new();
hasher.update(&address[..]);
hasher.update(&sub_id[..]);
B256(hasher.finalize().as_slice().try_into().unwrap())
}

/// Returns the address for the legacy `CREATE` scheme: [`crate::env::CreateScheme::Create`]
pub fn create_address(caller: B160, nonce: u64) -> B160 {
let mut stream = rlp::RlpStream::new_list(2);
Expand Down
16 changes: 13 additions & 3 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use alloc::boxed::Box;
use alloc::vec::Vec;
use core::{cmp::min, marker::PhantomData};
use revm_interpreter::gas::initial_tx_gas;
use revm_interpreter::primitives::asset_id_address;
use revm_interpreter::MAX_CODE_SIZE;
use revm_precompile::{Precompile, Precompiles};

Expand Down Expand Up @@ -933,9 +934,18 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host
.map(|(acc, is_cold)| (acc.info.get_balance(asset_id), is_cold))
}

/// TODO: implement
fn mint(&mut self, _address: B160, _value: U256) -> (InstructionResult, Gas) {
panic!("Mint is not supported for this host")
fn mint(&mut self, address: B160, sub_id: B160, value: U256) -> Option<bool> {
let asset_id = asset_id_address(address, sub_id);

let db = &mut self.data.db;
let journal = &mut self.data.journaled_state;
let error = &mut self.data.error;

self.data
.journaled_state
.mint(address, asset_id, value, self.data.db)
.map_err(|e| self.data.error = Some(e))
.ok()
}

/// TODO: implement
Expand Down
12 changes: 11 additions & 1 deletion crates/revm/src/journaled_state.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::interpreter::{inner_models::SelfDestructResult, InstructionResult};
use crate::primitives::{
db::Database, hash_map::Entry, Account, Bytecode, HashMap, Log, Spec, SpecId::*, State,
StorageSlot, TransientStorage, B160, KECCAK_EMPTY, PRECOMPILE3, U256,
StorageSlot, TransientStorage, B160, B256, KECCAK_EMPTY, PRECOMPILE3, U256,
};
use alloc::vec::Vec;
use core::mem;
Expand Down Expand Up @@ -770,6 +770,16 @@ impl JournaledState {
pub fn log(&mut self, log: Log) {
self.logs.push(log);
}

pub fn mint<DB: Database>(
&mut self,
_address: B160,
_asset_id: B256,
_value: U256,
_db: &mut DB,
) -> Result<(bool), DB::Error> {
Ok(true)
}
}

/// Check if address is precompile by having assumption
Expand Down

0 comments on commit f003a89

Please sign in to comment.