Skip to content

Commit

Permalink
Rebased and using newest Casper code, still wip
Browse files Browse the repository at this point in the history
  • Loading branch information
kubaplas committed Oct 28, 2024
1 parent 33b943e commit 0b38f87
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 67 deletions.
14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ odra-casper-rpc-client = { path = "odra-casper/rpc-client", version = "2.0.0" }
odra-vm = { path = "odra-vm", version = "2.0.0" }
odra-casper-wasm-env = { path = "odra-casper/wasm-env", version = "2.0.0"}
odra-schema = { path = "odra-schema", version = "2.0.0" }
casper-contract = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0", default-features = false }
casper-contract = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0", default-features = false }
casper-contract-schema = { git = "https://github.com/odradev/casper-contract-schema.git", branch = "feature/casper-2.0" }
casper-types = "5.0.0"
casper-execution-engine = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0" }
casper-engine-test-support = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0" }
casper-storage = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0" }
casper-event-standard = { git = "https://github.com/odradev/casper-event-standard.git", branch = "rustSDK-feat-2.0" }
casper-client = { git = "https://github.com/casper-ecosystem/casper-client-rs.git", branch = "rustSDK-feat-2.0" }
casper-execution-engine = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" }
casper-engine-test-support = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" }
casper-storage = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" }
casper-event-standard = { path = "../../casper-event-standard/casper-event-standard" }
casper-client = { git = "https://github.com/casper-ecosystem/casper-client-rs.git", branch = "feat-track-node-2.0" }
blake2 = "0.10.6"
log = "0.4.20"
env_logger = "0.11.1"
Expand All @@ -61,7 +61,7 @@ convert_case = "0.6.0"
lazy_static = "1.5.0"

[patch.crates-io]
casper-types = { version = "5.0.0", git = "https://github.com/casper-network/casper-node", branch = "rustSDK-feat-2.0" }
casper-types = { version = "5.0.0", git = "https://github.com/casper-network/casper-node", branch = "feat-2.0" }

[profile.release]
codegen-units = 1
Expand Down
12 changes: 9 additions & 3 deletions core/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,13 @@ impl From<Caller> for Address {
fn from(value: Caller) -> Self {
match value {
Caller::Initiator { account_hash } => Address::from(account_hash),
Caller::Entity { package_hash, .. } => Address::from(package_hash)
Caller::Entity { package_hash, .. } => Address::from(package_hash),
Caller::SmartContract {
contract_hash,
contract_package_hash
} => {
todo!("CONTRACTPACKAGEWHAT!?")
}
}
}
}
Expand Down Expand Up @@ -293,7 +299,7 @@ const fn hex_char_to_value(c: u8) -> Result<u8, &'static str> {
mod tests {
use super::*;
use casper_types::system::Caller;
use casper_types::{AddressableEntityHash, EraId};
use casper_types::EraId;

// TODO: casper-types > 1.5.0 will have prefix fixed.
const PACKAGE_HASH: &str =
Expand Down Expand Up @@ -464,7 +470,7 @@ mod tests {
let address = Address::from(package_hash);
let caller = Caller::Entity {
package_hash,
entity_hash: AddressableEntityHash::new(package_hash.value())
entity_addr: EntityAddr::SmartContract(package_hash.value())
};
assert_eq!(address, caller.into());
}
Expand Down
17 changes: 11 additions & 6 deletions odra-casper/rpc-client/src/casper_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use casper_client::cli::{
use casper_client::rpcs::results::{GetDeployResult, PutDeployResult};
use casper_client::Verbosity;
use casper_types::bytesrepr::{deserialize_from_slice, Bytes, FromBytes, ToBytes};
use casper_types::contracts::ContractPackageHash;
use casper_types::execution::ExecutionResultV1::{Failure, Success};
use casper_types::StoredValue::CLValue;
use casper_types::{
Expand Down Expand Up @@ -533,12 +534,16 @@ impl CasperClient {
call_def.entry_point()
));
let session = ExecutableDeployItem::StoredVersionedContractByHash {
hash: *addr.as_package_hash().unwrap_or_else(|| {
panic!(
"Couldn't get package hash from address: {:?}",
addr.to_formatted_string()
)
}),
hash: ContractPackageHash::from(
addr.as_package_hash()
.unwrap_or_else(|| {
panic!(
"Couldn't get package hash from address: {:?}",
addr.to_formatted_string()
)
})
.value()
),
version: None,
entry_point: call_def.entry_point().to_string(),
args: call_def.args().clone()
Expand Down
33 changes: 22 additions & 11 deletions odra-casper/test-vm/resources/chainspec.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ hard_reset = false
# in contract-runtime for computing genesis post-state hash.
#
# If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era.
activation_point = "2024-09-17T09:51:21.872206621Z"
activation_point = '${TIMESTAMP}'

[network]
# Human readable name for convenience; the genesis_hash is the true identifier. The name influences the genesis hash by
Expand Down Expand Up @@ -76,6 +76,9 @@ max_runtime_call_stack_height = 12
minimum_delegation_amount = 500_000_000_000
# Maximum allowed delegation amount in motes
maximum_delegation_amount = 1_000_000_000_000_000_000
# Minimum bid amount allowed in motes. Withdrawing one's bid to an amount strictly less than
# the value specified will be treated as a full unbond of a validator and their associated delegators
minimum_bid_amount = 10_000_000_000_000
# Global state prune batch size (0 = this feature is off)
prune_batch_size = 0
# Enables strict arguments checking when calling a contract; i.e. that all non-optional args are provided and of the correct `CLType`.
Expand All @@ -96,7 +99,10 @@ signature_rewards_max_delay = 3
#
# Changing this option makes sense only for private chains which dont need auctioning new validator slots.
allow_auction_bids = true
# Allow peer to peer transfers between users. Setting this to false makes sense only on private chains.
# Allows transfers between accounts in the blockchain network.
#
# Setting this to false restricts normal accounts from sending tokens to other accounts, allowing transfers only to administrators.
# Changing this option makes sense only on private chains.
allow_unrestricted_transfers = true
# If set to false, then consensus doesn't compute rewards and always uses 0.
compute_rewards = true
Expand Down Expand Up @@ -157,6 +163,7 @@ gas_hold_interval = '24 hours'
# List of public keys of administrator accounts. Setting this option makes only on private chains which require
# administrator accounts for regulatory reasons.
administrators = []
enable_addressable_entity = false

[highway]
# Highway dynamically chooses its round length, between minimum_block_time and maximum_round_length.
Expand Down Expand Up @@ -193,29 +200,28 @@ max_timestamp_leeway = '5 seconds'
# [4] -> The maximum number of transactions the lane can contain
native_mint_lane = [0, 1024, 1024, 65_000_000_000, 650]
native_auction_lane = [1, 2048, 2048, 362_500_000_000, 145]
wasm_lanes = [[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]
install_upgrade_lane = [2, 1_048_576, 2048, 1_000_000_000_000, 1]
wasm_lanes = [[3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]

[transactions.deploy]
# The maximum number of Motes allowed to be spent during payment. 0 means unlimited.
max_payment_cost = '0'
# The maximum number of other deploys a deploy can depend on (require to have been executed before it can execute).
max_dependencies = 10
# The limit of length of serialized payment code arguments.
payment_args_max_length = 1024
# The limit of length of serialized session code arguments.
session_args_max_length = 1024

[wasm]
[wasm.v1]
# Amount of free memory (in 64kB pages) each contract can use for stack.
max_memory = 64
# Max stack height (native WebAssembly stack limiter).
max_stack_height = 500

[wasm.storage_costs]
[storage_costs]
# Gas charged per byte stored in the global state.
gas_per_byte = 1_117_587

[wasm.opcode_costs]
[wasm.v1.opcode_costs]
# Bit operations multiplier.
bit = 300
# Arithmetic add operations multiplier.
Expand Down Expand Up @@ -246,9 +252,11 @@ nop = 200
current_memory = 290
# Grow memory cost, per page (64kb).
grow_memory = 240_000
# Sign extension operations cost
sign = 300

# Control flow operations multiplier.
[wasm.opcode_costs.control_flow]
[wasm.v1.opcode_costs.control_flow]
block = 440
loop = 440
if = 440
Expand All @@ -262,17 +270,18 @@ call = 68_000
call_indirect = 68_000
drop = 440

[wasm.opcode_costs.control_flow.br_table]
[wasm.v1.opcode_costs.control_flow.br_table]
# Fixed cost per `br_table` opcode
cost = 35_000
# Size of target labels in the `br_table` opcode will be multiplied by `size_multiplier`
size_multiplier = 100

# Host function declarations are located in smart_contracts/contract/src/ext_ffi.rs
[wasm.host_function_costs]
[wasm.v1.host_function_costs]
add = { cost = 5_800, arguments = [0, 0, 0, 0] }
add_associated_key = { cost = 9_000, arguments = [0, 0, 0] }
add_contract_version = { cost = 200, arguments = [0, 0, 0, 0, 120_000, 0, 0, 0, 0, 0] }
add_contract_version_with_message_topics = { cost = 200, arguments = [0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0] }
add_package_version = { cost = 200, arguments = [0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0] }
blake2b = { cost = 200, arguments = [0, 0, 0, 0] }
call_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 420, 0] }
Expand Down Expand Up @@ -317,7 +326,9 @@ dictionary_put = { cost = 9_500, arguments = [0, 1_800, 0, 520] }
enable_contract_version = { cost = 200, arguments = [0, 0, 0, 0] }
manage_message_topic = { cost = 200, arguments = [0, 30_000, 0, 0] }
emit_message = { cost = 200, arguments = [0, 30_000, 0, 120_000] }
generic_hash = { cost = 300, arguments = [0, 0, 0, 0, 0] }
cost_increase_per_message = 50
get_block_info = { cost = 330, arguments = [0, 0] }

[wasm.messages_limits]
max_topic_name_size = 256
Expand Down
37 changes: 3 additions & 34 deletions odra-casper/test-vm/src/vm/casper_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,8 @@ impl CasperVm {
let messages = messages.messages();
messages.iter().for_each(|message| {
let payload = message.payload().clone();
let addressable_entity =
self.get_addressable_entity_from_entity_addr(message.entity_hash());
let address = Address::Contract(addressable_entity.package_hash());
let contract_hash = message.entity_hash().value();
let package_hash = PackageHash::from(*message.hash_addr());
let address = Address::from(package_hash);
self.messages.entry(address).or_default().push(payload);
});
}
Expand Down Expand Up @@ -318,25 +316,6 @@ impl CasperVm {
}
.unwrap()
}
fn get_messages(&self, address: &Address) {
let entity = self.get_addressable_entity(address);
let (topic_name, message_topic_hash) = entity
.message_topics()
.iter()
.next()
.expect("should have at least one topic");

let entity_hash = self.get_addressable_entity_hash(address).value();

let q = self
.context
.query(
None,
Key::message_topic(EntityAddr::SmartContract(entity_hash), *message_topic_hash),
&[]
)
.unwrap();
}

/// Creates a new contract with the specified name, initialization arguments, and entry points caller.
pub fn new_contract(
Expand Down Expand Up @@ -617,15 +596,7 @@ impl CasperVm {

impl CasperVm {
fn get_package(&self, package_hash: PackageHash) -> Package {
let stored_value = self
.context
.query(None, Key::Package(package_hash.value()), &[])
.unwrap();

match stored_value {
StoredValue::Package(package) => package,
_ => panic!("Expected Package")
}
self.context.get_package(package_hash).unwrap()
}

fn get_current_contract(&self, package_hash: PackageHash) -> EntityWithNamedKeys {
Expand Down Expand Up @@ -793,8 +764,6 @@ fn parse_error(err: engine_state::Error) -> OdraError {
}
_ => OdraError::VmError(VmError::Other(format!("Casper ExecError: {}", exec_err)))
}
} else if let engine_state::Error::InsufficientPayment = err {
OdraError::VmError(VmError::BalanceExceeded)
} else {
OdraError::VmError(VmError::Other(format!("Casper EngineStateError: {}", err)))
}
Expand Down
75 changes: 69 additions & 6 deletions odra-casper/wasm-env/src/host_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ use casper_contract::{
unwrap_or_revert::UnwrapOrRevert
};
use core::mem::MaybeUninit;
use odra_core::casper_types::account::AccountHash;
use odra_core::casper_types::addressable_entity::NamedKeys;
use odra_core::casper_types::bytesrepr::deserialize;
use odra_core::casper_types::contract_messages::{MessagePayload, MessageTopicOperation};
use odra_core::casper_types::contracts::ContractVersion;
use odra_core::casper_types::system::Caller;
use odra_core::casper_types::contracts::{ContractHash, ContractPackageHash, ContractVersion};
use odra_core::casper_types::system::{Caller, CallerInfo};
use odra_core::casper_types::{
api_error, bytesrepr,
bytesrepr::{Bytes, FromBytes, ToBytes},
ApiError, CLTyped, CLValue, EntryPoints, Key, PackageHash, RuntimeArgs, URef,
ApiError, CLTyped, CLValue, EntityAddr, EntryPoints, Key, PackageHash, RuntimeArgs, URef,
DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, UREF_SERIALIZED_LENGTH
};
use odra_core::consts::{ALLOW_KEY_OVERRIDE_ARG, IS_UPGRADABLE_ARG, PACKAGE_HASH_KEY_NAME_ARG};
Expand Down Expand Up @@ -369,7 +370,7 @@ pub fn emit_native_event(event: &Bytes) {
#[inline(always)]
pub fn caller() -> Address {
let second_elem = take_nth_caller_from_stack(1);
second_elem.into()
caller_info_to_caller(second_elem).into()
}

/// Calls a contract method by Address
Expand Down Expand Up @@ -401,7 +402,7 @@ pub fn call_contract(address: Address, call_def: CallDef) -> Bytes {
#[inline(always)]
pub fn self_address() -> Address {
let first_elem = take_nth_caller_from_stack(0);
first_elem.into()
caller_info_to_caller(first_elem).into()
}

/// Gets the balance of the current contract.
Expand Down Expand Up @@ -571,7 +572,7 @@ fn deserialize_contract_result(bytes_written: usize) -> Vec<u8> {
}
}

fn take_nth_caller_from_stack(n: usize) -> Caller {
fn take_nth_caller_from_stack(n: usize) -> CallerInfo {
runtime::get_call_stack()
.into_iter()
.nth_back(n)
Expand Down Expand Up @@ -699,3 +700,65 @@ fn get_named_arg_size(name: &str) -> Result<usize, ApiError> {
_ => Err(ApiError::from(ret as u32))
}
}

fn caller_info_to_caller(info: CallerInfo) -> Caller {
let kind = info.kind();
match kind {
0 => {
let account_hash = info
.get_field_by_index(0)
.map(|val| {
val.to_t::<Option<AccountHash>>()
.expect("must convert out of cl_value")
})
.expect("must have index 0 in fields")
.expect("account hash must be some");
Caller::Initiator { account_hash }
}
3 => {
let package_hash = info
.get_field_by_index(1)
.map(|val| {
val.to_t::<Option<PackageHash>>()
.expect("must convert out of cl_value")
})
.expect("must have index 1 in fields")
.expect("package hash must be some");
let entity_addr = info
.get_field_by_index(3)
.map(|val| {
val.to_t::<Option<EntityAddr>>()
.expect("must convert out of cl_value")
})
.expect("must have index 3 in fields")
.expect("entity addr must be some");
Caller::Entity {
package_hash,
entity_addr
}
}
4 => {
let contract_package_hash = info
.get_field_by_index(2)
.map(|val| {
val.to_t::<Option<ContractPackageHash>>()
.expect("must convert out of cl_value")
})
.expect("must have index 2 in fields")
.expect("contract package hash must be some");
let contract_hash = info
.get_field_by_index(4)
.map(|val| {
val.to_t::<Option<ContractHash>>()
.expect("must convert out of cl_value")
})
.expect("must have index 4 in fields")
.expect("contract hash must be some");
Caller::SmartContract {
contract_package_hash,
contract_hash
}
}
_ => panic!("unhandled kind")
}
}

0 comments on commit 0b38f87

Please sign in to comment.