diff --git a/core/src/host.rs b/core/src/host.rs index 9819b314..4874efba 100644 --- a/core/src/host.rs +++ b/core/src/host.rs @@ -254,8 +254,8 @@ pub trait HostContext { /// Advances the block time by the specified time difference and processes auctions. fn advance_with_auctions(&self, time_diff: u64); - /// Era length in milliseconds. - fn era_length(&self) -> u64; + /// Time between auctions in milliseconds. + fn auction_delay(&self) -> u64; /// Returns the current block time. fn block_time(&self) -> u64; @@ -371,16 +371,15 @@ impl HostEnv { } /// Advances the block time by the specified time difference and processes auctions. - pub fn advance_with_rewards(&self, time_diff: u64) { + pub fn advance_with_auctions(&self, time_diff: u64) { let backend = self.backend.borrow(); backend.advance_with_auctions(time_diff); - backend.advance_block_time(time_diff); } /// Returns the era length in milliseconds. - pub fn era_length(&self) -> u64 { + pub fn auction_delay(&self) -> u64 { let backend = self.backend.borrow(); - backend.era_length() + backend.auction_delay() } /// Returns the current block time. diff --git a/examples/src/features/validators.rs b/examples/src/features/validators.rs index 857352ce..8a6f5027 100644 --- a/examples/src/features/validators.rs +++ b/examples/src/features/validators.rs @@ -57,67 +57,68 @@ pub enum ValError { InsufficientBalance = 1 } -#[cfg(test)] -mod tests { - - // Validators are now supported only on casper target - #[cfg(target_arch = "wasm32")] - #[test] - fn test_validators() { - use crate::features::validators::{ValidatorsContract, ValidatorsContractInitArgs}; - use odra::casper_types::U512; - use odra::host::Deployer; - use odra::host::HostRef; - - /// Time in milliseconds for one era. On livenet it's 120 minutes. On local, by default it's 41 seconds. - pub const ERA_DURATION: u64 = 41 * 1000; - let test_env = odra_test::env(); - test_env.set_caller(test_env.get_account(0)); - let mut staking = ValidatorsContract::deploy( - &test_env, - ValidatorsContractInitArgs { - validator: test_env.get_validator() - } - ); - - // Setup validators in vm - let inital_account_balance = test_env.balance_of(&test_env.get_account(0)); - - // Stake some amount - let staking_amount = U512::from(1_000_000_000_000u64); - staking.with_tokens(staking_amount).stake(); - assert_eq!(staking.currently_delegated_amount(), staking_amount); - assert_eq!( - test_env.balance_of(&test_env.get_account(0)), - inital_account_balance - staking_amount - ); - - // Advance time, run auctions and give off rewards - test_env.advance_with_rewards(ERA_DURATION * 10); - - // Check that the amount is greater than the staking amount - let staking_with_reward = staking.currently_delegated_amount(); - assert!(staking_with_reward > staking_amount); - - // Unstake - staking.unstake(staking_with_reward); - assert_eq!(staking.currently_delegated_amount(), U512::from(0)); - - // Withdraw should first fail, as we need to wait 7 eras - staking.try_withdraw(staking_with_reward).unwrap_err(); - // To confirm, the contract balance should be 0 - assert_eq!(staking.current_casper_balance(), U512::from(0)); - - // Advance time, run auctions and give off rewards - test_env.advance_with_rewards(ERA_DURATION * 8); - assert_eq!(staking.current_casper_balance(), staking_with_reward); - staking.withdraw(staking_with_reward); - assert_eq!(staking.current_casper_balance(), U512::from(0)); - - // The user now should have the tokens - assert_eq!( - test_env.balance_of(&test_env.get_account(0)), - staking_with_reward + inital_account_balance - staking_amount - ); - } +// Validators are now supported only on casper target +#[cfg(target_arch = "wasm32")] +#[test] +fn test_validators() { + use crate::features::validators::{ValidatorsContract, ValidatorsContractInitArgs}; + use odra::casper_types::U512; + use odra::host::Deployer; + use odra::host::HostRef; + + let test_env = odra_test::env(); + let auction_delay = test_env.auction_delay(); + // Should we put it into host method? + let unbonding_delay = auction_delay * 8; + + test_env.set_caller(test_env.get_account(0)); + let mut staking = ValidatorsContract::deploy( + &test_env, + ValidatorsContractInitArgs { + validator: test_env.get_validator() + } + ); + + // Setup validators in vm + let inital_account_balance = test_env.balance_of(&test_env.get_account(0)); + + // Stake some amount + let staking_amount = U512::from(1_000_000_000_000u64); + staking.with_tokens(staking_amount).stake(); + assert_eq!(staking.currently_delegated_amount(), staking_amount); + assert_eq!( + test_env.balance_of(&test_env.get_account(0)), + inital_account_balance - staking_amount + ); + + // Advance time, run auctions and give off rewards + // TODO: Why it works with auction delay * 2 and not with auction delay? + test_env.advance_with_auctions(auction_delay * 2); + + // Check that the amount is greater than the staking amount + let staking_with_reward = staking.currently_delegated_amount(); + assert!(staking_with_reward > staking_amount); + + // Unstake + staking.unstake(staking_with_reward); + assert_eq!(staking.currently_delegated_amount(), U512::from(0)); + + // Withdraw should first fail, as we need to wait for auction delay + staking.try_withdraw(staking_with_reward).unwrap_err(); + // To confirm, the contract balance should be 0 + assert_eq!(staking.current_casper_balance(), U512::from(0)); + + // Advance time, run auctions and give off rewards + test_env.advance_with_auctions(unbonding_delay); + assert_eq!(staking.current_casper_balance(), staking_with_reward); + staking.withdraw(staking_with_reward); + assert_eq!(staking.current_casper_balance(), U512::from(0)); + + // The user now should have the tokens + assert_eq!( + test_env.balance_of(&test_env.get_account(0)), + staking_with_reward + inital_account_balance - staking_amount + ); } +#[cfg(test)] +mod tests {} diff --git a/odra-casper/livenet-env/src/livenet_host.rs b/odra-casper/livenet-env/src/livenet_host.rs index fe8b5795..dc542d4e 100644 --- a/odra-casper/livenet-env/src/livenet_host.rs +++ b/odra-casper/livenet-env/src/livenet_host.rs @@ -265,7 +265,7 @@ impl HostContext for LivenetHost { panic!("advance_with_auctions not supported for LivenetHost") } - fn era_length(&self) -> u64 { + fn auction_delay(&self) -> u64 { panic!("era_length not yet implemented for LivenetHost") } } diff --git a/odra-casper/rpc-client/src/casper_client.rs b/odra-casper/rpc-client/src/casper_client.rs index 96fb8636..fe76757c 100644 --- a/odra-casper/rpc-client/src/casper_client.rs +++ b/odra-casper/rpc-client/src/casper_client.rs @@ -19,7 +19,7 @@ use casper_client::{ get_balance, get_deploy, get_transaction, put_transaction, query_global_state, JsonRpcId, Verbosity }; -use casper_types::bytesrepr::{deserialize_from_slice, Bytes, FromBytes, ToBytes}; +use casper_types::bytesrepr::{deserialize_from_slice, Bytes, ToBytes}; use casper_types::contracts::ContractPackageHash; use casper_types::execution::ExecutionResultV1::{Failure, Success}; use casper_types::StoredValue::CLValue; @@ -27,7 +27,7 @@ use casper_types::{ execution::ExecutionResult, runtime_args, sign, CLTyped, Digest, EntityAddr, Key, PublicKey, RuntimeArgs, SecretKey, Transaction, TransactionHash, URef, U512 }; -use casper_types::{ Deploy, DeployHash, ExecutableDeployItem, StoredValue, TimeDiff, Timestamp}; +use casper_types::{Deploy, DeployHash, ExecutableDeployItem, StoredValue, TimeDiff, Timestamp}; use odra_core::casper_event_standard::EVENTS_LENGTH; use odra_core::consts::{ AMOUNT_ARG, ARGS_ARG, ATTACHED_VALUE_ARG, ENTRY_POINT_ARG, EVENTS, PACKAGE_HASH_ARG, @@ -344,7 +344,7 @@ impl CasperClient { let result = r.map_err(|_| LivenetToDo)?; let stored_value = result.result.stored_value; let cl_value = stored_value.into_cl_value().ok_or(LivenetToDo)?; - + // Note: this is for compatibility with CEP18 named keys. if cl_value.cl_type() == &Vec::::cl_type() { let bytes = cl_value.into_t().map_err(|_| LivenetToDo)?; @@ -465,7 +465,7 @@ impl CasperClient { StoredValue::ContractPackage(package) => { let last_version = package.current_contract_hash().unwrap(); EntityAddr::SmartContract(last_version.value()) - }, + } _ => { panic!( "Couldn't get entity addr for address: {:?}", diff --git a/odra-casper/test-vm/src/casper_host.rs b/odra-casper/test-vm/src/casper_host.rs index b3aa7043..28e579b6 100644 --- a/odra-casper/test-vm/src/casper_host.rs +++ b/odra-casper/test-vm/src/casper_host.rs @@ -174,8 +174,9 @@ impl HostContext for CasperHost { self.vm.borrow_mut().transfer(to, amount) } - fn era_length(&self) -> u64 { - self.vm.borrow().era_length() + fn auction_delay(&self) -> u64 { + let mut backend = self.vm.borrow_mut(); + backend.auction_delay() } } diff --git a/odra-casper/test-vm/src/vm/casper_vm.rs b/odra-casper/test-vm/src/vm/casper_vm.rs index c875a320..362cd61a 100644 --- a/odra-casper/test-vm/src/vm/casper_vm.rs +++ b/odra-casper/test-vm/src/vm/casper_vm.rs @@ -110,16 +110,14 @@ impl CasperVm { /// Advances the block time by the specified time difference and processes auctions /// Giving the rewards to the validators pub fn advance_with_auctions(&mut self, time_diff: u64) { - let time_between_auctions = self - .context - .get_auction_delay() - .saturating_mul(self.context.chainspec().core_config.era_duration.millis()); + let time_between_auctions = self.auction_delay(); // Calculate how many auctions we can run based on time_diff let num_auctions = time_diff / time_between_auctions; // Run auctions for each complete delay period for _ in 0..num_auctions { self.context.run_auction(0u64, vec![]); + self.advance_block_time(time_between_auctions); } // Distribute rewards @@ -147,11 +145,14 @@ impl CasperVm { // Run remaining auctions with the leftover time let remaining_time = time_diff % time_between_auctions; + self.advance_block_time(remaining_time); } - /// Gets the era length in milliseconds. - pub fn era_length(&self) -> u64 { - self.context.chainspec().core_config.era_duration.millis() + /// Gets the time between auctions. + pub fn auction_delay(&mut self) -> u64 { + self.context + .get_auction_delay() + .saturating_mul(self.context.chainspec().core_config.era_duration.millis()) } /// Gets the current block time. @@ -624,7 +625,7 @@ impl CasperVm { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("resources/chainspec.toml"); let mut builder = LmdbWasmTestBuilder::new_temporary_with_chainspec(chainspec_path); // let mut builder = LmdbWasmTestBuilder::default(); - + builder.run_genesis(genesis_request).commit(); // crank the auction diff --git a/odra-vm/src/odra_vm_host.rs b/odra-vm/src/odra_vm_host.rs index 321c023a..ea4f352a 100644 --- a/odra-vm/src/odra_vm_host.rs +++ b/odra-vm/src/odra_vm_host.rs @@ -157,7 +157,7 @@ impl HostContext for OdraVmHost { .checked_transfer_tokens(&caller, &to, &amount) } - fn era_length(&self) -> u64 { + fn auction_delay(&self) -> u64 { 1_000u64 } }