Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
4fab033
Alow for machine reuse
bzawisto Dec 12, 2022
e6b9b9d
Merge pull request #1 from Zilliqa/ZIL-4652-SputnikVM-Execution-in-Co…
bzawisto Dec 12, 2022
f45da63
Extend machine interface
bzawisto Dec 15, 2022
02e6fd5
Merge pull request #2 from Zilliqa/make-machine-constructible-from-state
bzawisto Dec 15, 2022
8517d12
Extending machine interface (2)
bzawisto Dec 15, 2022
d11614c
Extending machine interface (3)
bzawisto Dec 15, 2022
300cdec
Remove Drop for Resolves
bzawisto Dec 30, 2022
2b6081f
Allow Stacksubstate to be reused
bzawisto Jan 2, 2023
28054a1
Some more required extensions
bzawisto Jan 2, 2023
f7f118d
Expose memory locations for call result
bzawisto Jan 9, 2023
de594fa
Make code compile
bzawisto Jan 9, 2023
868d660
Merge branch 'master' into make-machine-constructible-from-state-3
bzawisto Jan 11, 2023
541857a
Expose return data buffer
bzawisto Jan 12, 2023
3414969
Make Handle public
bzawisto Jan 13, 2023
287229e
Make a struct public
bzawisto Jan 13, 2023
eb988c5
Make fields public
bzawisto Jan 13, 2023
a21a329
Allow precompile to trap
bzawisto Feb 13, 2023
264c67c
Allow precompile to trap (2)
bzawisto Feb 13, 2023
1aa2757
add tracing extensions
n-hutton Feb 21, 2023
269d95f
cleanup
n-hutton Feb 21, 2023
73e8b0e
Merge pull request #3 from Zilliqa/make-machine-constructible-from-st…
bzawisto Feb 23, 2023
6876b5b
Merge pull request #4 from Zilliqa/tracing
n-hutton Feb 23, 2023
c64b566
Give precompile access to backend
bzawisto Mar 8, 2023
2845a69
Adding an option to return sc code as json
bzawisto Mar 10, 2023
b9fc869
Bug fix
bzawisto Mar 10, 2023
a514478
Fetch contract substate
bzawisto Mar 16, 2023
8938f64
Typo
bzawisto Mar 16, 2023
39b6bb0
Missing vname added
bzawisto Mar 16, 2023
bd1f6e7
Fetch substate
bzawisto Mar 27, 2023
53485a9
Typo fix
bzawisto Apr 6, 2023
3c1e9b7
add support for otter
n-hutton May 23, 2023
8014eb8
cleanup
n-hutton May 23, 2023
a36ee21
Merge pull request #7 from Zilliqa/precompile-access-backend
bzawisto Jun 7, 2023
2265ca3
Format
bzawisto Jun 7, 2023
4c193e9
Merge branch 'master' into ZIL-5269-Add-support-for-reading-init-data…
bzawisto Jun 7, 2023
dccbfc0
Adding option to fetch init data by backend
bzawisto Jun 7, 2023
8606e47
Merge pull request #8 from Zilliqa/ZIL-5269-Add-support-for-reading-i…
bzawisto Jun 7, 2023
d31060c
formatting
n-hutton Jun 8, 2023
ef7a9d1
Merge pull request #9 from Zilliqa/precompile-backend-plus-otter
n-hutton Jun 9, 2023
f3ffc62
shanghai eips 3651, 3855, 3860
saeed-zil Jul 25, 2023
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
4 changes: 4 additions & 0 deletions core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ pub enum ExitError {
/// Other normal errors.
#[cfg_attr(feature = "with-codec", codec(index = 13))]
Other(Cow<'static, str>),

/// Init code exceeds limit (runtime).
#[cfg_attr(feature = "with-codec", codec(index = 7))]
InitCodeLimit,
}

impl From<ExitError> for ExitReason {
Expand Down
5 changes: 5 additions & 0 deletions core/src/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ fn eval_jumpdest(_state: &mut Machine, _opcode: Opcode, _position: usize) -> Con
Control::Continue(1)
}

fn eval_push0(state: &mut Machine, _opcode: Opcode, position: usize) -> Control {
self::misc::push(state, 0, position)
}

fn eval_push1(state: &mut Machine, _opcode: Opcode, position: usize) -> Control {
self::misc::push(state, 1, position)
}
Expand Down Expand Up @@ -494,6 +498,7 @@ pub fn eval(state: &mut Machine, opcode: Opcode, position: usize) -> Control {
table[Opcode::MSIZE.as_usize()] = eval_msize as _;
table[Opcode::JUMPDEST.as_usize()] = eval_jumpdest as _;

table[Opcode::PUSH0.as_usize()] = eval_push0 as _;
table[Opcode::PUSH1.as_usize()] = eval_push1 as _;
table[Opcode::PUSH2.as_usize()] = eval_push2 as _;
table[Opcode::PUSH3.as_usize()] = eval_push3 as _;
Expand Down
37 changes: 37 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ impl Machine {
pub fn position(&self) -> &Result<usize, ExitReason> {
&self.position
}
/// Return a reference of the return range.
pub fn return_range(&self) -> &Range<U256> {
&self.return_range
}
/// Return a reference of the valids.
pub fn valids(&self) -> &Valids {
&self.valids
}
/// Return a reference of the return range.
pub fn code(&mut self) -> Vec<u8> {
self.code.to_vec()
}
/// Return a reference of the valids.
pub fn data(&self) -> Vec<u8> {
self.data.to_vec()
}

/// Create a new machine with given code and data.
pub fn new(
Expand All @@ -87,6 +103,27 @@ impl Machine {
}
}

/// Create a new machine with some previous state
pub fn create_from_state(
code: Rc<Vec<u8>>,
data: Rc<Vec<u8>>,
position: Result<usize, ExitReason>,
return_range: Range<U256>,
valids: Valids,
memory: Memory,
stack: Stack,
) -> Self {
Self {
data,
code,
position,
return_range,
valids,
memory,
stack,
}
}

/// Explicit exit of the machine. Further step will return error.
pub fn exit(&mut self, reason: ExitReason) {
self.position = Err(reason);
Expand Down
157 changes: 157 additions & 0 deletions core/src/opcode.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt;

/// Opcode enum. One-to-one corresponding to an `u8` value.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(
Expand Down Expand Up @@ -95,6 +97,7 @@ impl Opcode {
pub const JUMPDEST: Opcode = Opcode(0x5b);

/// `PUSHn`
pub const PUSH0: Opcode = Opcode(0x5f);
pub const PUSH1: Opcode = Opcode(0x60);
pub const PUSH2: Opcode = Opcode(0x61);
pub const PUSH3: Opcode = Opcode(0x62);
Expand Down Expand Up @@ -269,3 +272,157 @@ impl Opcode {
self.0 as usize
}
}

impl fmt::Display for Opcode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
//write!(f, "{}", "urgh...")
let op = match self {
&Opcode::STOP => "STOP",
&Opcode::ADD => "ADD",
&Opcode::MUL => "MUL",
&Opcode::SUB => "SUB",
&Opcode::DIV => "DIV",
&Opcode::SDIV => "SDIV",
&Opcode::MOD => "MOD",
&Opcode::SMOD => "SMOD",
&Opcode::ADDMOD => "ADDMOD",
&Opcode::MULMOD => "MULMOD",
&Opcode::EXP => "EXP",
&Opcode::SIGNEXTEND => "SIGNEXTEND",
&Opcode::LT => "LT",
&Opcode::GT => "GT",
&Opcode::SLT => "SLT",
&Opcode::SGT => "SGT",
&Opcode::EQ => "EQ",
&Opcode::ISZERO => "ISZERO",
&Opcode::AND => "AND",
&Opcode::OR => "OR",
&Opcode::XOR => "XOR",
&Opcode::NOT => "NOT",
&Opcode::BYTE => "BYTE",
&Opcode::CALLDATALOAD => "CALLDATALOAD",
&Opcode::CALLDATASIZE => "CALLDATASIZE",
&Opcode::CALLDATACOPY => "CALLDATACOPY",
&Opcode::CODESIZE => "CODESIZE",
&Opcode::CODECOPY => "CODECOPY",
&Opcode::SHL => "SHL",
&Opcode::SHR => "SHR",
&Opcode::SAR => "SAR",
&Opcode::POP => "POP",
&Opcode::MLOAD => "MLOAD",
&Opcode::MSTORE => "MSTORE",
&Opcode::MSTORE8 => "MSTORE8",
&Opcode::JUMP => "JUMP",
&Opcode::JUMPI => "JUMPI",
&Opcode::PC => "PC",
&Opcode::MSIZE => "MSIZE",
&Opcode::JUMPDEST => "JUMPDEST",
&Opcode::PUSH1 => "PUSH1",
&Opcode::PUSH2 => "PUSH2",
&Opcode::PUSH3 => "PUSH3",
&Opcode::PUSH4 => "PUSH4",
&Opcode::PUSH5 => "PUSH5",
&Opcode::PUSH6 => "PUSH6",
&Opcode::PUSH7 => "PUSH7",
&Opcode::PUSH8 => "PUSH8",
&Opcode::PUSH9 => "PUSH9",
&Opcode::PUSH10 => "PUSH10",
&Opcode::PUSH11 => "PUSH11",
&Opcode::PUSH12 => "PUSH12",
&Opcode::PUSH13 => "PUSH13",
&Opcode::PUSH14 => "PUSH14",
&Opcode::PUSH15 => "PUSH15",
&Opcode::PUSH16 => "PUSH16",
&Opcode::PUSH17 => "PUSH17",
&Opcode::PUSH18 => "PUSH18",
&Opcode::PUSH19 => "PUSH19",
&Opcode::PUSH20 => "PUSH20",
&Opcode::PUSH21 => "PUSH21",
&Opcode::PUSH22 => "PUSH22",
&Opcode::PUSH23 => "PUSH23",
&Opcode::PUSH24 => "PUSH24",
&Opcode::PUSH25 => "PUSH25",
&Opcode::PUSH26 => "PUSH26",
&Opcode::PUSH27 => "PUSH27",
&Opcode::PUSH28 => "PUSH28",
&Opcode::PUSH29 => "PUSH29",
&Opcode::PUSH30 => "PUSH30",
&Opcode::PUSH31 => "PUSH31",
&Opcode::PUSH32 => "PUSH32",
&Opcode::DUP1 => "DUP1",
&Opcode::DUP2 => "DUP2",
&Opcode::DUP3 => "DUP3",
&Opcode::DUP4 => "DUP4",
&Opcode::DUP5 => "DUP5",
&Opcode::DUP6 => "DUP6",
&Opcode::DUP7 => "DUP7",
&Opcode::DUP8 => "DUP8",
&Opcode::DUP9 => "DUP9",
&Opcode::DUP10 => "DUP10",
&Opcode::DUP11 => "DUP11",
&Opcode::DUP12 => "DUP12",
&Opcode::DUP13 => "DUP13",
&Opcode::DUP14 => "DUP14",
&Opcode::DUP15 => "DUP15",
&Opcode::DUP16 => "DUP16",
&Opcode::SWAP1 => "SWAP1",
&Opcode::SWAP2 => "SWAP2",
&Opcode::SWAP3 => "SWAP3",
&Opcode::SWAP4 => "SWAP4",
&Opcode::SWAP5 => "SWAP5",
&Opcode::SWAP6 => "SWAP6",
&Opcode::SWAP7 => "SWAP7",
&Opcode::SWAP8 => "SWAP8",
&Opcode::SWAP9 => "SWAP9",
&Opcode::SWAP10 => "SWAP10",
&Opcode::SWAP11 => "SWAP11",
&Opcode::SWAP12 => "SWAP12",
&Opcode::SWAP13 => "SWAP13",
&Opcode::SWAP14 => "SWAP14",
&Opcode::SWAP15 => "SWAP15",
&Opcode::SWAP16 => "SWAP16",
&Opcode::RETURN => "RETURN",
&Opcode::REVERT => "REVERT",
&Opcode::INVALID => "INVALID",
&Opcode::EOFMAGIC => "EOFMAGIC",
&Opcode::SHA3 => "SHA3",
&Opcode::ADDRESS => "ADDRESS",
&Opcode::BALANCE => "BALANCE",
&Opcode::SELFBALANCE => "SELFBALANCE",
&Opcode::BASEFEE => "BASEFEE",
&Opcode::ORIGIN => "ORIGIN",
&Opcode::CALLER => "CALLER",
&Opcode::CALLVALUE => "CALLVALUE",
&Opcode::GASPRICE => "GASPRICE",
&Opcode::EXTCODESIZE => "EXTCODESIZE",
&Opcode::EXTCODECOPY => "EXTCODECOPY",
&Opcode::EXTCODEHASH => "EXTCODEHASH",
&Opcode::RETURNDATASIZE => "RETURNDATASIZE",
&Opcode::RETURNDATACOPY => "RETURNDATACOPY",
&Opcode::BLOCKHASH => "BLOCKHASH",
&Opcode::COINBASE => "COINBASE",
&Opcode::TIMESTAMP => "TIMESTAMP",
&Opcode::NUMBER => "NUMBER",
&Opcode::DIFFICULTY => "DIFFICULTY",
&Opcode::GASLIMIT => "GASLIMIT",
&Opcode::SLOAD => "SLOAD",
&Opcode::SSTORE => "SSTORE",
&Opcode::GAS => "GAS",
&Opcode::LOG0 => "LOG0",
&Opcode::LOG1 => "LOG1",
&Opcode::LOG2 => "LOG2",
&Opcode::LOG3 => "LOG3",
&Opcode::LOG4 => "LOG4",
&Opcode::CREATE => "CREATE",
&Opcode::CREATE2 => "CREATE2",
&Opcode::CALL => "CALL",
&Opcode::CALLCODE => "CALLCODE",
&Opcode::DELEGATECALL => "DELEGATECALL",
&Opcode::STATICCALL => "STATICCALL",
&Opcode::SUICIDE => "SUICIDE",
&Opcode::CHAINID => "CHAINID",
_ => "UNKNOWNOP",
};
write!(f, "{}", op)
}
}
19 changes: 17 additions & 2 deletions gasometer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,17 @@ impl<'config> Gasometer<'config> {
non_zero_data_len,
access_list_address_len,
access_list_storage_len,
initcode_cost,
} => {
self.config.gas_transaction_create
let mut cost = self.config.gas_transaction_create
+ zero_data_len as u64 * self.config.gas_transaction_zero_data
+ non_zero_data_len as u64 * self.config.gas_transaction_non_zero_data
+ access_list_address_len as u64 * self.config.gas_access_list_address
+ access_list_storage_len as u64 * self.config.gas_access_list_storage_key
+ access_list_storage_len as u64 * self.config.gas_access_list_storage_key;
if self.config.max_initcode_size.is_some() {
cost += initcode_cost;
}
cost
}
};

Expand Down Expand Up @@ -293,15 +298,21 @@ pub fn create_transaction_cost(data: &[u8], access_list: &[(H160, Vec<H256>)]) -
let zero_data_len = data.iter().filter(|v| **v == 0).count();
let non_zero_data_len = data.len() - zero_data_len;
let (access_list_address_len, access_list_storage_len) = count_access_list(access_list);
let initcode_cost = init_code_cost(data);

TransactionCost::Create {
zero_data_len,
non_zero_data_len,
access_list_address_len,
access_list_storage_len,
initcode_cost,
}
}

pub fn init_code_cost(data: &[u8]) -> u64 {
2 * (data.len() as u64 / 32)
}

/// Counts the number of addresses and storage keys in the access list
fn count_access_list(access_list: &[(H160, Vec<H256>)]) -> (usize, usize) {
let access_list_address_len = access_list.len();
Expand Down Expand Up @@ -610,6 +621,8 @@ pub fn dynamic_opcode_cost<H: Handler>(
}
}

Opcode::PUSH0 if config.has_push0 => GasCost::Base,

_ => GasCost::Invalid(opcode),
};

Expand Down Expand Up @@ -1021,6 +1034,8 @@ pub enum TransactionCost {
access_list_address_len: usize,
/// Total number of storage keys in transaction access list (see EIP-2930)
access_list_storage_len: usize,
/// Cost of initcode = 2 * ceil(len(initcode) / 32) (see EIP-3860)
initcode_cost: u64,
},
}

Expand Down
44 changes: 44 additions & 0 deletions runtime/src/eval/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ use core::cmp::min;
use primitive_types::{H256, U256};
use sha3::{Digest, Keccak256};

pub fn u8_vec_to_hex(to_convert: &Vec<u8>) -> String {
let mut hex_string = String::new();
for byte in to_convert {
hex_string.push_str(&format!("{:02x}", byte));
}
hex_string
}

pub fn sha3<H: Handler>(runtime: &mut Runtime) -> Control<H> {
pop_u256!(runtime, from, len);

Expand Down Expand Up @@ -258,6 +266,12 @@ pub fn log<H: Handler>(runtime: &mut Runtime, n: u8, handler: &mut H) -> Control
pub fn suicide<H: Handler>(runtime: &mut Runtime, handler: &mut H) -> Control<H> {
pop!(runtime, target);

event!(TransactSuicide {
address: runtime.context.address,
target: target.into(),
balance: handler.balance(runtime.context.address),
});

match handler.mark_delete(runtime.context.address, target.into()) {
Ok(()) => (),
Err(e) => return Control::Exit(e.into()),
Expand Down Expand Up @@ -295,9 +309,23 @@ pub fn create<H: Handler>(runtime: &mut Runtime, is_create2: bool, handler: &mut
}
};

event!(TransactCreate {
call_type: &(if is_create2 {
"CREATE2".to_string()
} else {
"CREATE".to_string()
}),
address: runtime.context.address,
target: handler.get_create_address(scheme).into(),
balance: value,
is_create2: is_create2,
input: &format!("0x{:}", u8_vec_to_hex(&code)),
});

match handler.create(runtime.context.address, scheme, value, code, None) {
Capture::Exit((reason, address, return_data)) => {
runtime.return_data_buffer = return_data;

let create_address: H256 = address.map(|a| a.into()).unwrap_or_default();

match reason {
Expand Down Expand Up @@ -399,13 +427,29 @@ pub fn call<H: Handler>(runtime: &mut Runtime, scheme: CallScheme, handler: &mut
None
};

let target = if scheme == CallScheme::CallCode {
runtime.context.address
} else {
to.into()
};

event!(TransactTransfer {
call_type: &format!("{:?}", scheme).to_uppercase(),
address: runtime.context.address,
target: target.into(),
balance: value,
input: &format!("0x{:}", u8_vec_to_hex(&input)),
});

match handler.call(
to.into(),
transfer,
input,
gas,
scheme == CallScheme::StaticCall,
context,
out_offset,
out_len,
) {
Capture::Exit((reason, return_data)) => {
runtime.return_data_buffer = return_data;
Expand Down
Loading