diff --git a/src/contract/dao/src/entrypoint/propose.rs b/src/contract/dao/src/entrypoint/propose.rs index 31e08d2f5..58d20176b 100644 --- a/src/contract/dao/src/entrypoint/propose.rs +++ b/src/contract/dao/src/entrypoint/propose.rs @@ -27,7 +27,7 @@ use darkfi_sdk::{ error::{ContractError, ContractResult}, msg, pasta::pallas, - util::get_verifying_slot, + util::get_verifying_block_height, ContractCall, }; use darkfi_serial::{deserialize, serialize, Encodable, WriteExt}; @@ -85,7 +85,7 @@ pub(crate) fn dao_propose_get_metadata( } // ANCHOR: dao-blockheight_to_day-example-usage - let current_day = blockheight_to_day(get_verifying_slot()); + let current_day = blockheight_to_day(get_verifying_block_height()); // ANCHOR_END: dao-blockheight_to_day-example-usage let total_funds_coords = total_funds_commit.to_affine().coordinates().unwrap(); diff --git a/src/contract/dao/src/entrypoint/vote.rs b/src/contract/dao/src/entrypoint/vote.rs index a21221d4a..8618060f7 100644 --- a/src/contract/dao/src/entrypoint/vote.rs +++ b/src/contract/dao/src/entrypoint/vote.rs @@ -24,7 +24,7 @@ use darkfi_sdk::{ error::{ContractError, ContractResult}, msg, pasta::pallas, - util::get_verifying_slot, + util::get_verifying_block_height, ContractCall, }; use darkfi_serial::{deserialize, serialize, Encodable, WriteExt}; @@ -81,7 +81,7 @@ pub(crate) fn dao_vote_get_metadata( )); } - let current_day = blockheight_to_day(get_verifying_slot()); + let current_day = blockheight_to_day(get_verifying_block_height()); let yes_vote_commit_coords = params.yes_vote_commit.to_affine().coordinates().unwrap(); let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap(); diff --git a/src/contract/money/src/entrypoint/genesis_mint_v1.rs b/src/contract/money/src/entrypoint/genesis_mint_v1.rs index d4e9810c9..df5d0014c 100644 --- a/src/contract/money/src/entrypoint/genesis_mint_v1.rs +++ b/src/contract/money/src/entrypoint/genesis_mint_v1.rs @@ -26,7 +26,7 @@ use darkfi_sdk::{ error::{ContractError, ContractResult}, merkle_add, msg, pasta::pallas, - util::get_verifying_slot, + util::get_verifying_block_height, ContractCall, }; use darkfi_serial::{deserialize, serialize, Encodable, WriteExt}; @@ -83,11 +83,14 @@ pub(crate) fn money_genesis_mint_process_instruction_v1( let self_ = &calls[call_idx as usize].data; let params: MoneyGenesisMintParamsV1 = deserialize(&self_.data[1..])?; - // Verify this contract call is verified against on genesis slot(0). - let verifying_slot = get_verifying_slot(); - if verifying_slot != 0 { - msg!("[GenesisMintV1] Error: Call is executed for slot {}, not genesis", verifying_slot); - return Err(MoneyError::GenesisCallNonGenesisSlot.into()) + // Verify this contract call is verified against genesis block(0). + let verifying_block_height = get_verifying_block_height(); + if verifying_block_height != 0 { + msg!( + "[GenesisMintV1] Error: Call is executed for slot {}, not genesis", + verifying_block_height + ); + return Err(MoneyError::GenesisCallNonGenesisBlock.into()) } // Only DARK_TOKEN_ID can be minted on genesis slot. diff --git a/src/contract/money/src/entrypoint/pow_reward_v1.rs b/src/contract/money/src/entrypoint/pow_reward_v1.rs index bf34189e4..bced79491 100644 --- a/src/contract/money/src/entrypoint/pow_reward_v1.rs +++ b/src/contract/money/src/entrypoint/pow_reward_v1.rs @@ -27,7 +27,7 @@ use darkfi_sdk::{ error::{ContractError, ContractResult}, merkle_add, msg, pasta::pallas, - util::{get_slot, get_verifying_slot}, + util::{get_slot, get_verifying_block_height}, ContractCall, }; use darkfi_serial::{deserialize, serialize, Encodable, WriteExt}; @@ -84,21 +84,21 @@ pub(crate) fn money_pow_reward_process_instruction_v1( let self_ = &calls[call_idx as usize].data; let params: MoneyPoWRewardParamsV1 = deserialize(&self_.data[1..])?; - // Verify this contract call is verified against a slot(block height) before PoS transition, + // Verify this contract call is verified against a block height(slot) before PoS transition, // excluding genesis. - let verifying_slot = get_verifying_slot(); - if verifying_slot == 0 || verifying_slot > POW_CUTOFF { + let verifying_block_height = get_verifying_block_height(); + if verifying_block_height == 0 || verifying_block_height > POW_CUTOFF { msg!( - "[PoWRewardV1] Error: Call is executed for slot {}(cutoff slot {})", - verifying_slot, + "[PoWRewardV1] Error: Call is executed for block height {}(cutoff block height {})", + verifying_block_height, POW_CUTOFF ); - return Err(MoneyError::PoWRewardCallAfterCutoffSlot.into()) + return Err(MoneyError::PoWRewardCallAfterCutoffBlockHeight.into()) } // Grab the slot to validate consensus params against - let Some(slot) = get_slot(verifying_slot)? else { - msg!("[PoWRewardV1] Error: Missing slot {} from db", verifying_slot); + let Some(slot) = get_slot(verifying_block_height)? else { + msg!("[PoWRewardV1] Error: Missing slot {} from db", verifying_block_height); return Err(MoneyError::PoWRewardMissingSlot.into()) }; let slot: Slot = deserialize(&slot)?; @@ -134,13 +134,13 @@ pub(crate) fn money_pow_reward_process_instruction_v1( return Err(MoneyError::TransferClearInputNonNativeToken.into()) } - // Verify reward value matches the expected one for this slot(block height) - let expected_reward = expected_reward(verifying_slot); + // Verify reward value matches the expected one for this block height(slot) + let expected_reward = expected_reward(verifying_block_height); if params.input.value != expected_reward { msg!( "[PoWRewardV1] Error: Reward value({}) is not the block height({}) expected one: {}", params.input.value, - verifying_slot, + verifying_block_height, expected_reward ); return Err(MoneyError::ValueMismatch.into()) diff --git a/src/contract/money/src/error.rs b/src/contract/money/src/error.rs index 26d65d9d2..e9fdc38a1 100644 --- a/src/contract/money/src/error.rs +++ b/src/contract/money/src/error.rs @@ -112,14 +112,14 @@ pub enum MoneyError { #[error("Child call input mismatch")] ChildCallInputMismatch, - #[error("Call is not executed on genesis slot")] - GenesisCallNonGenesisSlot, + #[error("Call is not executed on genesis block")] + GenesisCallNonGenesisBlock, #[error("Missing nullifier in set")] MissingNullifier, - #[error("Call is executed after cutoff slot")] - PoWRewardCallAfterCutoffSlot, + #[error("Call is executed after cutoff block height")] + PoWRewardCallAfterCutoffBlockHeight, #[error("Missing slot from db")] PoWRewardMissingSlot, @@ -171,9 +171,9 @@ impl From for ContractError { MoneyError::ParentCallInputMismatch => Self::Custom(28), MoneyError::ChildCallFunctionMismatch => Self::Custom(29), MoneyError::ChildCallInputMismatch => Self::Custom(30), - MoneyError::GenesisCallNonGenesisSlot => Self::Custom(31), + MoneyError::GenesisCallNonGenesisBlock => Self::Custom(31), MoneyError::MissingNullifier => Self::Custom(32), - MoneyError::PoWRewardCallAfterCutoffSlot => Self::Custom(33), + MoneyError::PoWRewardCallAfterCutoffBlockHeight => Self::Custom(33), MoneyError::PoWRewardMissingSlot => Self::Custom(34), MoneyError::PoWRewardExtendsUnknownFork => Self::Custom(35), MoneyError::PoWRewardErroneousVrfProof => Self::Custom(36), diff --git a/src/runtime/import/util.rs b/src/runtime/import/util.rs index 7f9ae94cc..ac3f0d3f1 100644 --- a/src/runtime/import/util.rs +++ b/src/runtime/import/util.rs @@ -199,16 +199,34 @@ pub(crate) fn get_current_epoch(ctx: FunctionEnvMut) -> u64 { ctx.data().time_keeper.current_epoch() } +/// Will return current block height number, which is equivalent +/// to current slot number. +pub(crate) fn get_current_block_height(ctx: FunctionEnvMut) -> u64 { + ctx.data().time_keeper.current_slot() +} + /// Will return current slot number. pub(crate) fn get_current_slot(ctx: FunctionEnvMut) -> u64 { ctx.data().time_keeper.current_slot() } +/// Will return current runtime configured verifying block height number, +/// which is equivalent to verifying slot number. +pub(crate) fn get_verifying_block_height(ctx: FunctionEnvMut) -> u64 { + ctx.data().time_keeper.verifying_slot +} + /// Will return current runtime configured verifying slot number. pub(crate) fn get_verifying_slot(ctx: FunctionEnvMut) -> u64 { ctx.data().time_keeper.verifying_slot } +/// Will return current runtime configured verifying block height epoch number, +/// which is equivalent to verifying slot epoch number. +pub(crate) fn get_verifying_block_height_epoch(ctx: FunctionEnvMut) -> u64 { + ctx.data().time_keeper.verifying_slot_epoch() +} + /// Will return current runtime configured verifying slot epoch number. pub(crate) fn get_verifying_slot_epoch(ctx: FunctionEnvMut) -> u64 { ctx.data().time_keeper.verifying_slot_epoch() diff --git a/src/runtime/vm_runtime.rs b/src/runtime/vm_runtime.rs index d4b95fb17..7d006ff2b 100644 --- a/src/runtime/vm_runtime.rs +++ b/src/runtime/vm_runtime.rs @@ -264,18 +264,36 @@ impl Runtime { import::util::get_current_epoch, ), + "get_current_block_height_" => Function::new_typed_with_env( + &mut store, + &ctx, + import::util::get_current_block_height, + ), + "get_current_slot_" => Function::new_typed_with_env( &mut store, &ctx, import::util::get_current_slot, ), + "get_verifying_block_height_" => Function::new_typed_with_env( + &mut store, + &ctx, + import::util::get_verifying_block_height, + ), + "get_verifying_slot_" => Function::new_typed_with_env( &mut store, &ctx, import::util::get_verifying_slot, ), + "get_verifying_block_height_epoch_" => Function::new_typed_with_env( + &mut store, + &ctx, + import::util::get_verifying_block_height_epoch, + ), + "get_verifying_slot_epoch_" => Function::new_typed_with_env( &mut store, &ctx, diff --git a/src/sdk/src/util.rs b/src/sdk/src/util.rs index 69371c767..ec107730c 100644 --- a/src/sdk/src/util.rs +++ b/src/sdk/src/util.rs @@ -86,6 +86,15 @@ pub fn get_current_epoch() -> u64 { unsafe { get_current_epoch_() } } +/// Everyone can call this. Will return current block height. +/// +/// ``` +/// block_height = get_current_block_height(); +/// ``` +pub fn get_current_block_height() -> u64 { + unsafe { get_current_block_height_() } +} + /// Everyone can call this. Will return current slot. /// /// ``` @@ -95,6 +104,16 @@ pub fn get_current_slot() -> u64 { unsafe { get_current_slot_() } } +/// Everyone can call this. Will return runtime configured +/// verifying block height. +/// +/// ``` +/// block_height = get_verifying_block_height(); +/// ``` +pub fn get_verifying_block_height() -> u64 { + unsafe { get_verifying_block_height_() } +} + /// Everyone can call this. Will return runtime configured /// verifying slot. /// @@ -105,11 +124,21 @@ pub fn get_verifying_slot() -> u64 { unsafe { get_verifying_slot_() } } +/// Everyone can call this. Will return runtime configured +/// verifying block height epoch. +/// +/// ``` +/// epoch = get_verifying_block_height_epoch(); +/// ``` +pub fn get_verifying_block_height_epoch() -> u64 { + unsafe { get_verifying_block_height_epoch_() } +} + /// Everyone can call this. Will return runtime configured /// verifying slot epoch. /// /// ``` -/// slot = get_verifying_slot_epoch(); +/// epoch = get_verifying_slot_epoch(); /// ``` pub fn get_verifying_slot_epoch() -> u64 { unsafe { get_verifying_slot_epoch_() } @@ -141,8 +170,11 @@ extern "C" { fn get_object_size_(len: u32) -> i64; fn get_current_epoch_() -> u64; + fn get_current_block_height_() -> u64; fn get_current_slot_() -> u64; + fn get_verifying_block_height_() -> u64; fn get_verifying_slot_() -> u64; + fn get_verifying_block_height_epoch_() -> u64; fn get_verifying_slot_epoch_() -> u64; fn get_slot_(slot: u64) -> i64; fn get_blockchain_time_() -> u64;