Skip to content

Commit

Permalink
Isolated CROO tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bvrooman committed Feb 16, 2024
1 parent 0165aea commit 2c7446f
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 101 deletions.
4 changes: 2 additions & 2 deletions fuel-tx/src/transaction/consensus_parameters/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,15 +658,15 @@ impl DependentCost {
match self {
DependentCost::LightOperation { units_per_gas, .. } => {
// Apply the linear transformation:
// f(x) = 1/m * x = x/m
// f(x) = 1/m * x = x/m
// where:
// x is the number of units
// 1/m is the gas_per_unit
units.saturating_div(*units_per_gas)
}
DependentCost::HeavyOperation { gas_per_unit, .. } => {
// Apply the linear transformation:
// f(x) = mx
// f(x) = mx
// where:
// x is the number of units
// m is the gas per unit
Expand Down
2 changes: 2 additions & 0 deletions fuel-vm/src/interpreter/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ use fuel_types::{
#[cfg(test)]
mod code_tests;
#[cfg(test)]
mod croo_tests;
#[cfg(test)]
mod other_tests;
#[cfg(test)]
mod smo_tests;
Expand Down
203 changes: 203 additions & 0 deletions fuel-vm/src/interpreter/blockchain/croo_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
use super::*;
use crate::{
interpreter::{
memory::Memory,
PanicContext,
},
storage::MemoryStorage,
};
use fuel_tx::{
Contract,
GasCosts,
};

use std::convert::TryInto;

const CONTRACT_LEN: usize = 512;
const INITIAL_GAS: Word = 1_000_000;

struct SystemRegisters {
pc: Word,
is: Word,
cgas: Word,
ggas: Word,
}

fn initialize_system_registers() -> SystemRegisters {
SystemRegisters {
pc: 4,
is: 0,
cgas: INITIAL_GAS,
ggas: INITIAL_GAS,
}
}

fn initialize_ownership_registers() -> OwnershipRegisters {
OwnershipRegisters {
sp: 1000,
ssp: 1,
hp: 2000,
prev_hp: 3000,
context: Context::Script {
block_height: Default::default(),
},
}
}

fn new_contract_id() -> ContractId {
ContractId::new([3u8; ContractId::LEN])
}

#[test]
fn test_code_root() {
// Given
let contract_id = new_contract_id();

let mut storage = MemoryStorage::new(Default::default(), Default::default());
let mut memory: Memory<MEM_SIZE> = vec![1u8; MEM_SIZE].try_into().unwrap();
memory[0..ContractId::LEN].copy_from_slice(contract_id.as_slice());

let data = alloc::vec![0xffu8; CONTRACT_LEN];
let contract: Contract = data.into();
let root = contract.root();
storage
.storage_contract_insert(&contract_id, &contract)
.expect("Failed to insert contract");

let gas_cost = GasCosts::default().contract_root;
let ownership_registers = initialize_ownership_registers();
let SystemRegisters {
mut pc,
is,
mut cgas,
mut ggas,
} = initialize_system_registers();
let croo_address = 0xFF as Word;
let croo_range = croo_address as usize..croo_address as usize + 32;

let input_contracts = [contract_id];
let mut panic_context = PanicContext::None;

// When
CodeRootCtx {
memory: &mut memory,
storage: &storage,
gas_cost,
profiler: &mut Default::default(),
input_contracts: InputContracts::new(input_contracts.iter(), &mut panic_context),
current_contract: None,
cgas: RegMut::new(&mut cgas),
ggas: RegMut::new(&mut ggas),
owner: ownership_registers,
pc: RegMut::new(&mut pc),
is: Reg::new(&is),
}
.code_root(croo_address, 0)
.unwrap();

// Then
assert_eq!(pc, 8);
assert_eq!(memory[croo_range], *root.as_slice());
assert_eq!(
cgas,
INITIAL_GAS - gas_cost.resolve_without_base(CONTRACT_LEN as Word)
);
assert_eq!(
ggas,
INITIAL_GAS - gas_cost.resolve_without_base(CONTRACT_LEN as Word)
);
}

#[test]
fn test_code_root_contract_not_found() {
// Given
let contract_id = new_contract_id();

let storage = MemoryStorage::new(Default::default(), Default::default());
let mut memory: Memory<MEM_SIZE> = vec![1u8; MEM_SIZE].try_into().unwrap();
memory[0..ContractId::LEN].copy_from_slice(contract_id.as_slice());

let gas_cost = GasCosts::default().contract_root;
let ownership_registers = initialize_ownership_registers();
let SystemRegisters {
mut pc,
is,
mut cgas,
mut ggas,
} = initialize_system_registers();
let croo_address = 0xFFu64;
let croo_range = croo_address as usize..croo_address as usize + 32;

let input_contracts = [contract_id];
let mut panic_context = PanicContext::None;

// When
let _ = CodeRootCtx {
memory: &mut memory,
storage: &storage,
gas_cost,
profiler: &mut Default::default(),
input_contracts: InputContracts::new(input_contracts.iter(), &mut panic_context),
current_contract: None,
cgas: RegMut::new(&mut cgas),
ggas: RegMut::new(&mut ggas),
owner: ownership_registers,
pc: RegMut::new(&mut pc),
is: Reg::new(&is),
}
.code_root(croo_address, 0)
.expect_err("Contract is not found");

// Then
assert_eq!(pc, 4);
assert_eq!(memory[croo_range], [1u8; 32]);
assert_eq!(cgas, INITIAL_GAS);
assert_eq!(ggas, INITIAL_GAS);
}

#[test]
fn test_code_root_contract_not_in_inputs() {
// Given
let contract_id = new_contract_id();

let storage = MemoryStorage::new(Default::default(), Default::default());
let mut memory: Memory<MEM_SIZE> = vec![1u8; MEM_SIZE].try_into().unwrap();
memory[0..ContractId::LEN].copy_from_slice(contract_id.as_slice());

let gas_cost = GasCosts::default().contract_root;
let ownership_registers = initialize_ownership_registers();
let SystemRegisters {
mut pc,
is,
mut cgas,
mut ggas,
} = initialize_system_registers();
let croo_address = 0xFFu64;
let croo_range = croo_address as usize..croo_address as usize + 32;

let input_contracts = [];
let mut panic_context = PanicContext::None;

// When
let _ = CodeRootCtx {
memory: &mut memory,
storage: &storage,
gas_cost,
profiler: &mut Default::default(),
input_contracts: InputContracts::new(input_contracts.iter(), &mut panic_context),
current_contract: None,
cgas: RegMut::new(&mut cgas),
ggas: RegMut::new(&mut ggas),
owner: ownership_registers,
pc: RegMut::new(&mut pc),
is: Reg::new(&is),
}
.code_root(croo_address as Word, 0)
.expect_err("Contract is not in inputs");

// Then
assert_eq!(pc, 4);
assert_eq!(memory[croo_range], [1u8; 32]);
assert_eq!(cgas, INITIAL_GAS);
assert_eq!(ggas, INITIAL_GAS);
}
99 changes: 0 additions & 99 deletions fuel-vm/src/interpreter/blockchain/other_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use core::{
use super::*;
use crate::interpreter::PanicContext;
use fuel_storage::StorageAsMut;
use fuel_tx::Contract;
use test_case::test_case;

#[test_case(false, 0, None, 0, [0; 32] => Ok(()); "Burn nothing")]
Expand Down Expand Up @@ -235,104 +234,6 @@ fn test_coinbase() {
assert_eq!(memory[20..20 + 32], [0u8; 32]);
}

#[test]
fn test_code_root() {
let contract_id = ContractId::new([3u8; ContractId::LEN]);
let mut storage = MemoryStorage::new(Default::default(), Default::default());
let mut memory: Memory<MEM_SIZE> = vec![1u8; MEM_SIZE].try_into().unwrap();
memory[0..ContractId::LEN].copy_from_slice(contract_id.as_slice());
let owner = OwnershipRegisters {
sp: 1000,
ssp: 1,
hp: 2000,
prev_hp: 3000,
context: Context::Script {
block_height: Default::default(),
},
};
let mut pc = 4;
let is = 0;
let mut cgas = 0;
let mut ggas = 0;
let input_contracts = [contract_id];
let mut panic_context = PanicContext::None;
let _ = CodeRootCtx {
memory: &mut memory,
storage: &storage,
gas_cost: DependentCost::free(),
profiler: &mut Default::default(),
input_contracts: InputContracts::new(input_contracts.iter(), &mut panic_context),
current_contract: None,
cgas: RegMut::new(&mut cgas),
ggas: RegMut::new(&mut ggas),
owner,
pc: RegMut::new(&mut pc),
is: Reg::new(&is),
}
.code_root(20, 0)
.expect_err("Contract is not found");
assert_eq!(pc, 4);

let data = alloc::vec![0xffu8; 512];
let contract: Contract = data.into();
let root = contract.root();
storage
.storage_contract_insert(&contract_id, &contract)
.expect("Failed to insert contract");

let owner = OwnershipRegisters {
sp: 1000,
ssp: 1,
hp: 2000,
prev_hp: 3000,
context: Context::Script {
block_height: Default::default(),
},
};
CodeRootCtx {
memory: &mut memory,
storage: &storage,
gas_cost: DependentCost::free(),
profiler: &mut Default::default(),
input_contracts: InputContracts::new(input_contracts.iter(), &mut panic_context),
current_contract: None,
cgas: RegMut::new(&mut cgas),
ggas: RegMut::new(&mut ggas),
owner,
pc: RegMut::new(&mut pc),
is: Reg::new(&is),
}
.code_root(20, 0)
.unwrap();
assert_eq!(pc, 8);
assert_eq!(memory[20..20 + 32], *root.as_slice());

let owner = OwnershipRegisters {
sp: 1000,
ssp: 1,
hp: 2000,
prev_hp: 3000,
context: Context::Script {
block_height: Default::default(),
},
};
let _ = CodeRootCtx {
memory: &mut memory,
storage: &storage,
gas_cost: DependentCost::free(),
profiler: &mut Default::default(),
input_contracts: InputContracts::new(iter::empty(), &mut panic_context),
current_contract: None,
cgas: RegMut::new(&mut cgas),
ggas: RegMut::new(&mut ggas),
owner,
pc: RegMut::new(&mut pc),
is: Reg::new(&is),
}
.code_root(20, 0)
.expect_err("Contract is not in inputs");
}

#[test]
fn test_code_size() {
let contract_id = ContractId::new([3u8; ContractId::LEN]);
Expand Down

0 comments on commit 2c7446f

Please sign in to comment.