Skip to content
This repository has been archived by the owner on Jan 9, 2025. It is now read-only.

Commit

Permalink
update ssj
Browse files Browse the repository at this point in the history
  • Loading branch information
obatirou committed Oct 2, 2024
1 parent 6902cfc commit daa04ae
Show file tree
Hide file tree
Showing 27 changed files with 377 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub trait IHelpers<T> {
/// * The recovered Ethereum address.
fn recover_eth_address(self: @T, msg_hash: u256, signature: Signature) -> (bool, EthAddress);

/// Performs signature verification in the secp256r1 ellipitic curve.
/// Performs signature verification in the secp256r1 elliptic curve.
///
/// # Arguments
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ pub impl EthRPC<
fn eth_get_transaction_count(self: @TContractState, address: EthAddress) -> u64 {
let kakarot_state = KakarotState::get_state();
let starknet_address = kakarot_state.get_starknet_address(address);
println!("starknet_address: {:?}", starknet_address);
let account = IAccountDispatcher { contract_address: starknet_address };
let nonce = account.get_nonce();
nonce
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub trait IKakarotCore<TContractState> {
/// Gets the native token used by the Kakarot smart contract
fn get_native_token(self: @TContractState) -> ContractAddress;

/// Deterministically computes a Starknet address for an given EVM address
/// Deterministically computes a Starknet address for a given EVM address
/// The address is computed as the Starknet address corresponding to the deployment of an EOA,
/// Using its EVM address as salt, and KakarotCore as deployer.
fn compute_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress;
Expand Down Expand Up @@ -59,7 +59,7 @@ pub trait IExtendedKakarotCore<TContractState> {
/// Gets the native token used by the Kakarot smart contract
fn get_native_token(self: @TContractState) -> ContractAddress;

/// Deterministically computes a Starknet address for an given EVM address
/// Deterministically computes a Starknet address for a given EVM address
/// The address is computed as the Starknet address corresponding to the deployment of an EOA,
/// Using its EVM address as salt, and KakarotCore as deployer.
fn compute_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress;
Expand Down
2 changes: 1 addition & 1 deletion cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub impl CallHelpersImpl of CallHelpers {
self.stack.push(0)?;
},
ExecutionResultStatus::Exception => {
// If the call has halted exceptionnaly,
// If the call has halted exceptionally,
// the return_data is emptied, and nothing is stored in memory
self.return_data = [].span();
self.stack.push(0)?;
Expand Down
2 changes: 1 addition & 1 deletion cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub impl CreateHelpersImpl of CreateHelpers {
fn prepare_create(ref self: VM, create_type: CreateType) -> Result<CreateArgs, EVMError> {
let value = self.stack.pop()?;
let offset = self.stack.pop_saturating_usize()?;
let size = self.stack.pop_usize()?;
let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?;
self.memory.ensure_length(memory_expansion.new_size);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Block Information.

use core::num::traits::SaturatingAdd;
use core::starknet::SyscallResultTrait;
use core::starknet::syscalls::get_block_hash_syscall;

Expand All @@ -20,7 +21,9 @@ pub impl BlockInformation of BlockInformationTrait {
fn exec_blockhash(ref self: VM) -> Result<(), EVMError> {
self.charge_gas(gas::BLOCKHASH)?;

let block_number = self.stack.pop_u64()?;
// Saturate to MAX_U64 to avoid a revert when the hash requested is too big. It should just
// push 0.
let block_number = self.stack.pop_saturating_u64()?;
let current_block = self.env.block_number;

// If input block number is lower than current_block - 256, return 0
Expand All @@ -31,7 +34,8 @@ pub impl BlockInformation of BlockInformationTrait {
// TODO: monitor the changes in the `get_block_hash_syscall` syscall.
// source:
// https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-calls-cairo1/#get_block_hash
if block_number + 10 > current_block || block_number + 256 < current_block {
if block_number.saturating_add(10) > current_block
|| block_number.saturating_add(256) < current_block {
return self.stack.push(0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ pub impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait {
if i > 31 {
return self.stack.push(0);
}
let i: usize = i.try_into().unwrap(); // Safe because i <= 31

// Right shift value by offset bits and then take the least significant byte.
let result = x.shr((31 - i) * 8) & 0xFF;
Expand All @@ -150,7 +151,7 @@ pub impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait {
if shift > 255 {
return self.stack.push(0);
}

let shift: usize = shift.try_into().unwrap(); // Safe because shift <= 255
let result = val.wrapping_shl(shift);
self.stack.push(result)
}
Expand All @@ -163,6 +164,11 @@ pub impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait {
let shift = *popped[0];
let value = *popped[1];

// if shift is bigger than 255 return 0
if shift > 255 {
return self.stack.push(0);
}
let shift: usize = shift.try_into().unwrap(); // Safe because shift <= 255
let result = value.wrapping_shr(shift);
self.stack.push(result)
}
Expand All @@ -187,6 +193,7 @@ pub impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait {
if (shift >= 256) {
self.stack.push(sign)
} else {
let shift: usize = shift.try_into().unwrap(); // Safe because shift <= 256
// XORing with sign before and after the shift propagates the sign bit of the operation
let result = (sign ^ value.value).shr(shift) ^ sign;
self.stack.push(result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait {
fn exec_calldataload(ref self: VM) -> Result<(), EVMError> {
self.charge_gas(gas::VERYLOW)?;

let offset: usize = self.stack.pop_usize()?;
// Don't error out if the offset is too big. It should just push 0.
let offset: usize = self.stack.pop_saturating_usize()?;

let calldata = self.message().data;
let calldata_len = calldata.len();
Expand Down Expand Up @@ -113,7 +114,7 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait {
fn exec_calldatacopy(ref self: VM) -> Result<(), EVMError> {
let dest_offset = self.stack.pop_saturating_usize()?;
let offset = self.stack.pop_saturating_usize()?;
let size = self.stack.pop_usize()?;
let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

let words_size = bytes_32_words_size(size).into();
let copy_gas_cost = gas::COPY * words_size;
Expand Down Expand Up @@ -143,7 +144,7 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait {
fn exec_codecopy(ref self: VM) -> Result<(), EVMError> {
let dest_offset = self.stack.pop_saturating_usize()?;
let offset = self.stack.pop_saturating_usize()?;
let size = self.stack.pop_usize()?;
let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

let words_size = bytes_32_words_size(size).into();
let copy_gas_cost = gas::COPY * words_size;
Expand Down Expand Up @@ -192,7 +193,7 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait {
let evm_address = self.stack.pop_eth_address()?;
let dest_offset = self.stack.pop_saturating_usize()?;
let offset = self.stack.pop_saturating_usize()?;
let size = self.stack.pop_usize()?;
let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

// GAS
let words_size = bytes_32_words_size(size).into();
Expand Down Expand Up @@ -229,7 +230,7 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait {
fn exec_returndatacopy(ref self: VM) -> Result<(), EVMError> {
let dest_offset = self.stack.pop_saturating_usize()?;
let offset = self.stack.pop_saturating_usize()?;
let size = self.stack.pop_usize()?;
let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.
let return_data: Span<u8> = self.return_data();

let (last_returndata_index, overflow) = offset.overflowing_add(size);
Expand Down Expand Up @@ -549,7 +550,7 @@ mod tests {


#[test]
fn test_calldataload_with_offset_conversion_error() {
fn test_calldataload_with_offset_bigger_usize_succeeds() {
// Given
let calldata = u256_to_bytes_array(
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Expand All @@ -562,8 +563,8 @@ mod tests {
let result = vm.exec_calldataload();

// Then
assert!(result.is_err());
assert_eq!(result.unwrap_err(), EVMError::TypeConversionError(TYPE_CONVERSION_ERROR));
assert!(result.is_ok());
assert_eq!(vm.stack.pop().unwrap(), 0);
}

// *************************************************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ fn exec_log_i(ref self: VM, topics_len: u8) -> Result<(), EVMError> {

// TODO(optimization): check benefits of n `pop` instead of `pop_n`
let offset = self.stack.pop_saturating_usize()?;
let size = self.stack.pop_usize()?;
let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.
let topics: Array<u256> = self.stack.pop_n(topics_len.into())?;

let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?;
self.memory.ensure_length(memory_expansion.new_size);

// TODO: avoid addition overflows here. We should use checked arithmetic.
self
.charge_gas(
gas::LOG
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ pub impl MemoryOperation of MemoryOperationTrait {
/// MLOAD operation.
/// Load word from memory and push to stack.
fn exec_mload(ref self: VM) -> Result<(), EVMError> {
let offset: usize = self.stack.pop_usize()?;
let offset: usize = self
.stack
.pop_usize()?; // Any offset bigger than a usize would MemoryOOG.

let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 32)].span())?;
self.memory.ensure_length(memory_expansion.new_size);
Expand All @@ -50,7 +52,9 @@ pub impl MemoryOperation of MemoryOperationTrait {
/// Save word to memory.
/// # Specification: https://www.evm.codes/#52?fork=shanghai
fn exec_mstore(ref self: VM) -> Result<(), EVMError> {
let offset: usize = self.stack.pop_usize()?;
let offset: usize = self
.stack
.pop_usize()?; // Any offset bigger than a usize would MemoryOOG.
let value: u256 = self.stack.pop()?;
let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 32)].span())?;
self.memory.ensure_length(memory_expansion.new_size);
Expand All @@ -64,7 +68,7 @@ pub impl MemoryOperation of MemoryOperationTrait {
/// Save single byte to memory
/// # Specification: https://www.evm.codes/#53?fork=shanghai
fn exec_mstore8(ref self: VM) -> Result<(), EVMError> {
let offset = self.stack.pop_saturating_usize()?;
let offset = self.stack.pop_usize()?; // Any offset bigger than a usize would MemoryOOG.
let value = self.stack.pop()?;
let value: u8 = (value.low & 0xFF).try_into().unwrap();

Expand Down Expand Up @@ -188,7 +192,9 @@ pub impl MemoryOperation of MemoryOperationTrait {
/// The new pc target has to be a JUMPDEST opcode.
/// # Specification: https://www.evm.codes/#57?fork=shanghai
fn exec_jumpi(ref self: VM) -> Result<(), EVMError> {
let index = self.stack.pop_usize()?;
let index = self
.stack
.pop_saturating_usize()?; // Saturate because if b is 0, we skip the jump but don't want to fail here.
let b = self.stack.pop()?;

self.charge_gas(gas::HIGH)?;
Expand Down Expand Up @@ -280,14 +286,15 @@ pub impl MemoryOperation of MemoryOperationTrait {
fn exec_mcopy(ref self: VM) -> Result<(), EVMError> {
let dest_offset = self.stack.pop_saturating_usize()?;
let source_offset = self.stack.pop_saturating_usize()?;
let size = self.stack.pop_usize()?;
let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

let words_size = bytes_32_words_size(size).into();
let copy_gas_cost = gas::COPY * words_size;
let memory_expansion = gas::memory_expansion(
self.memory.size(), [(max(dest_offset, source_offset), size)].span()
)?;
self.memory.ensure_length(memory_expansion.new_size);
//TODO: handle add overflows
self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?;

if size == 0 {
Expand Down
6 changes: 4 additions & 2 deletions cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ pub impl Sha3Impl of Sha3Trait {
///
/// # Specification: https://www.evm.codes/#20?fork=shanghai
fn exec_sha3(ref self: VM) -> Result<(), EVMError> {
let offset: usize = self.stack.pop_usize()?;
let mut size: usize = self.stack.pop_usize()?;
let offset: usize = self.stack.pop_saturating_usize()?;
let mut size: usize = self
.stack
.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

let words_size = bytes_32_words_size(size).into();
let word_gas_cost = gas::KECCAK256WORD * words_size;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ pub impl SystemOperations of SystemOperationsTrait {
let to = self.stack.pop_eth_address()?;
let value = self.stack.pop()?;
let args_offset = self.stack.pop_saturating_usize()?;
let args_size = self.stack.pop_usize()?;
let args_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.
let ret_offset = self.stack.pop_saturating_usize()?;
let ret_size = self.stack.pop_usize()?;
let ret_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

// GAS
let memory_expansion = gas::memory_expansion(
Expand Down Expand Up @@ -109,9 +109,9 @@ pub impl SystemOperations of SystemOperationsTrait {
let code_address = self.stack.pop_eth_address()?;
let value = self.stack.pop()?;
let args_offset = self.stack.pop_saturating_usize()?;
let args_size = self.stack.pop_usize()?;
let args_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.
let ret_offset = self.stack.pop_saturating_usize()?;
let ret_size = self.stack.pop_usize()?;
let ret_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

let to = self.message().target.evm;

Expand Down Expand Up @@ -193,9 +193,9 @@ pub impl SystemOperations of SystemOperationsTrait {
let gas = self.stack.pop_saturating_u64()?;
let code_address = self.stack.pop_eth_address()?;
let args_offset = self.stack.pop_saturating_usize()?;
let args_size = self.stack.pop_usize()?;
let args_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.
let ret_offset = self.stack.pop_saturating_usize()?;
let ret_size = self.stack.pop_usize()?;
let ret_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

// GAS
let memory_expansion = gas::memory_expansion(
Expand Down Expand Up @@ -246,9 +246,9 @@ pub impl SystemOperations of SystemOperationsTrait {
let gas = self.stack.pop_saturating_u64()?;
let to = self.stack.pop_eth_address()?;
let args_offset = self.stack.pop_saturating_usize()?;
let args_size = self.stack.pop_usize()?;
let args_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.
let ret_offset = self.stack.pop_saturating_usize()?;
let ret_size = self.stack.pop_usize()?;
let ret_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

// GAS
let memory_expansion = gas::memory_expansion(
Expand Down Expand Up @@ -293,7 +293,7 @@ pub impl SystemOperations of SystemOperationsTrait {
/// # Specification: https://www.evm.codes/#fd?fork=shanghai
fn exec_revert(ref self: VM) -> Result<(), EVMError> {
let offset = self.stack.pop_saturating_usize()?;
let size = self.stack.pop_usize()?;
let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG.

let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?;
self.memory.ensure_length(memory_expansion.new_size);
Expand Down
4 changes: 2 additions & 2 deletions cairo/kakarot-ssj/crates/evm/src/interpreter.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::model::account::{Account, AccountTrait};
use crate::model::vm::{VM, VMTrait};
use crate::model::{
Message, Environment, Transfer, ExecutionSummary, ExecutionResult, ExecutionResultTrait,
ExecutionResultStatus, AddressTrait, TransactionResult, TransactionResultTrait, Address
ExecutionResultStatus, AddressTrait, TransactionResult, Address
};
use crate::precompiles::Precompiles;
use crate::precompiles::eth_precompile_addresses;
Expand Down Expand Up @@ -108,7 +108,7 @@ pub impl EVMImpl of EVMTrait {
let mut sender_account = env.state.get_account(origin.evm);

// Charge the intrinsic gas to the sender so that it's not available for the execution
// of the transaction but don't trigger any actual transfer, as only the actual consumde
// of the transaction but don't trigger any actual transfer, as only the actual consumed
// gas is charged at the end of the transaction
sender_account.set_balance(sender_account.balance() - max_fee.into());

Expand Down
2 changes: 1 addition & 1 deletion cairo/kakarot-ssj/crates/evm/src/memory.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl MemoryImpl of MemoryTrait {

// First erase byte value at offset, then set the new value using bitwise ops
let word: u128 = self.items.get(chunk_index.into());
let new_word = (word & ~mask) | (value.into().shl(right_offset.into() * 8));
let new_word = (word & ~mask) | (value.into().shl(right_offset * 8));
self.items.insert(chunk_index.into(), new_word);
}

Expand Down
3 changes: 2 additions & 1 deletion cairo/kakarot-ssj/crates/evm/src/stack.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ impl StackImpl of StackTrait {
Result::Ok(item.low)
}

/// Calls `Stack::pop` and converts it to usize
/// Calls `Stack::pop` and converts it to an EthAddress
/// If the value is bigger than an EthAddress, it will be truncated to keep the lower 160 bits.
///
/// # Errors
///
Expand Down
Loading

0 comments on commit daa04ae

Please sign in to comment.