فهرست منبع

runtime: removed slot related fns and added gas cost to util fns

skoupidi 2 سال پیش
والد
کامیت
2f5de8e999
4فایلهای تغییر یافته به همراه89 افزوده شده و 157 حذف شده
  1. 45 70
      src/runtime/import/util.rs
  2. 0 24
      src/runtime/vm_runtime.rs
  3. 39 18
      src/sdk/src/blockchain.rs
  4. 5 45
      src/sdk/src/util.rs

+ 45 - 70
src/runtime/import/util.rs

@@ -217,78 +217,53 @@ pub(crate) fn get_object_size(mut ctx: FunctionEnvMut<Env>, idx: u32) -> i64 {
     obj_len as i64
     obj_len as i64
 }
 }
 
 
-/// Will return current epoch number.
-pub(crate) fn get_current_epoch(ctx: FunctionEnvMut<Env>) -> u64 {
-    // TODO: Gas cost
-    ctx.data().time_keeper.current_epoch()
-}
+/// Will return current runtime configured verifying block height number
+pub(crate) fn get_verifying_block_height(mut ctx: FunctionEnvMut<Env>) -> u64 {
+    let (env, mut store) = ctx.data_and_store_mut();
 
 
-/// Will return current block height number, which is equivalent
-/// to current slot number.
-pub(crate) fn get_current_block_height(ctx: FunctionEnvMut<Env>) -> u64 {
-    // TODO: Gas cost
-    ctx.data().time_keeper.current_slot()
-}
+    // Subtract used gas. Here we count the size of the object.
+    // u64 is 8 bytes.
+    env.subtract_gas(&mut store, 8);
 
 
-/// Will return current slot number.
-pub(crate) fn get_current_slot(ctx: FunctionEnvMut<Env>) -> u64 {
-    // TODO: Gas cost
-    ctx.data().time_keeper.current_slot()
+    env.time_keeper.verifying_block_height
 }
 }
 
 
-/// 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<Env>) -> u64 {
-    // TODO: Gas cost
-    ctx.data().time_keeper.verifying_block_height
-}
+/// Will return current runtime configured verifying block height epoch number
+pub(crate) fn get_verifying_block_height_epoch(mut ctx: FunctionEnvMut<Env>) -> u64 {
+    let (env, mut store) = ctx.data_and_store_mut();
+
+    // Subtract used gas. Here we count the size of the object.
+    // u64 is 8 bytes.
+    env.subtract_gas(&mut store, 8);
 
 
-/// 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<Env>) -> u64 {
-    // TODO: Gas cost
-    ctx.data().time_keeper.verifying_block_height_epoch()
+    darkfi_sdk::blockchain::block_epoch(env.time_keeper.verifying_block_height)
 }
 }
 
 
-/// Grabs last block from the `Blockchain` overlay and then copies its
-/// height, nonce and previous block hash into the VM, by appending the data
-/// to the VM's object store.
-///
-/// On success, returns the index of the new object in the object store.
-/// Otherwise, returns an error code.
-pub(crate) fn get_last_block_info(mut ctx: FunctionEnvMut<Env>) -> i64 {
+/// Will return current blockchain timestamp,
+/// defined as the last block's timestamp.
+pub(crate) fn get_blockchain_time(mut ctx: FunctionEnvMut<Env>) -> i64 {
     let (env, mut store) = ctx.data_and_store_mut();
     let (env, mut store) = ctx.data_and_store_mut();
     let cid = &env.contract_id;
     let cid = &env.contract_id;
 
 
-    // Enforce function ACL
-    if let Err(e) = acl_allow(env, &[ContractSection::Exec]) {
-        error!(
-            target: "runtime::db::get_last_block_info",
-            "[WASM] [{}] get_last_block_info(): Called in unauthorized section: {}", cid, e,
-        );
-        return darkfi_sdk::error::CALLER_ACCESS_DENIED
-    }
-
     // Grab current last block
     // Grab current last block
     let block = match env.blockchain.lock().unwrap().last_block() {
     let block = match env.blockchain.lock().unwrap().last_block() {
         Ok(b) => b,
         Ok(b) => b,
         Err(e) => {
         Err(e) => {
             error!(
             error!(
-                target: "runtime::db::get_last_block_info",
-                "[WASM] [{}] get_last_block_info(): Internal error getting from blocks tree: {}", cid, e,
+                target: "runtime::db::get_blockchain_time",
+                "[WASM] [{}] get_blockchain_time(): Internal error getting from blocks tree: {}", cid, e,
             );
             );
             return darkfi_sdk::error::DB_GET_FAILED
             return darkfi_sdk::error::DB_GET_FAILED
         }
         }
     };
     };
 
 
-    // Create the return object
-    let mut ret = Vec::with_capacity(8 + 32 + blake3::OUT_LEN);
-    ret.extend_from_slice(&block.header.height.to_be_bytes());
-    ret.extend_from_slice(&block.header.nonce.to_repr());
-    ret.extend_from_slice(block.header.previous.as_bytes());
-
     // Subtract used gas. Here we count the size of the object.
     // Subtract used gas. Here we count the size of the object.
-    env.subtract_gas(&mut store, ret.len() as u64);
+    // u64 is 8 bytes.
+    env.subtract_gas(&mut store, 8);
+
+    // Create the return object
+    let mut ret = Vec::with_capacity(8);
+    ret.extend_from_slice(&block.header.timestamp.0.to_be_bytes());
 
 
     // Copy Vec<u8> to the VM
     // Copy Vec<u8> to the VM
     let mut objects = env.objects.borrow_mut();
     let mut objects = env.objects.borrow_mut();
@@ -300,39 +275,45 @@ pub(crate) fn get_last_block_info(mut ctx: FunctionEnvMut<Env>) -> i64 {
     (objects.len() - 1) as i64
     (objects.len() - 1) as i64
 }
 }
 
 
-/// Copies the data of requested slot from `SlotStore` into the VM by appending
-/// the data to the VM's object store.
+/// Grabs last block from the `Blockchain` overlay and then copies its
+/// height, nonce and previous block hash into the VM, by appending the data
+/// to the VM's object store.
 ///
 ///
 /// On success, returns the index of the new object in the object store.
 /// On success, returns the index of the new object in the object store.
 /// Otherwise, returns an error code.
 /// Otherwise, returns an error code.
-pub(crate) fn get_slot(mut ctx: FunctionEnvMut<Env>, slot: u64) -> i64 {
+pub(crate) fn get_last_block_info(mut ctx: FunctionEnvMut<Env>) -> i64 {
     let (env, mut store) = ctx.data_and_store_mut();
     let (env, mut store) = ctx.data_and_store_mut();
     let cid = &env.contract_id;
     let cid = &env.contract_id;
 
 
     // Enforce function ACL
     // Enforce function ACL
-    if let Err(e) =
-        acl_allow(env, &[ContractSection::Deploy, ContractSection::Metadata, ContractSection::Exec])
-    {
+    if let Err(e) = acl_allow(env, &[ContractSection::Exec]) {
         error!(
         error!(
-            target: "runtime::db::db_get_slot",
-            "[WASM] [{}] get_slot({}): Called in unauthorized section: {}", cid, slot, e,
+            target: "runtime::db::get_last_block_info",
+            "[WASM] [{}] get_last_block_info(): Called in unauthorized section: {}", cid, e,
         );
         );
         return darkfi_sdk::error::CALLER_ACCESS_DENIED
         return darkfi_sdk::error::CALLER_ACCESS_DENIED
     }
     }
 
 
-    let ret = match env.blockchain.lock().unwrap().slots.get_by_id(slot) {
-        Ok(v) => v,
+    // Grab current last block
+    let block = match env.blockchain.lock().unwrap().last_block() {
+        Ok(b) => b,
         Err(e) => {
         Err(e) => {
             error!(
             error!(
-                target: "runtime::db::db_get_slot",
-                "[WASM] [{}] db_get_slot(): Internal error getting from slots tree: {}", cid, e,
+                target: "runtime::db::get_last_block_info",
+                "[WASM] [{}] get_last_block_info(): Internal error getting from blocks tree: {}", cid, e,
             );
             );
             return darkfi_sdk::error::DB_GET_FAILED
             return darkfi_sdk::error::DB_GET_FAILED
         }
         }
     };
     };
 
 
     // Subtract used gas. Here we count the size of the object.
     // Subtract used gas. Here we count the size of the object.
-    env.subtract_gas(&mut store, ret.len() as u64);
+    env.subtract_gas(&mut store, (8 + 32 + blake3::OUT_LEN) as u64);
+
+    // Create the return object
+    let mut ret = Vec::with_capacity(8 + 32 + blake3::OUT_LEN);
+    ret.extend_from_slice(&block.header.height.to_be_bytes());
+    ret.extend_from_slice(&block.header.nonce.to_repr());
+    ret.extend_from_slice(block.header.previous.as_bytes());
 
 
     // Copy Vec<u8> to the VM
     // Copy Vec<u8> to the VM
     let mut objects = env.objects.borrow_mut();
     let mut objects = env.objects.borrow_mut();
@@ -343,9 +324,3 @@ pub(crate) fn get_slot(mut ctx: FunctionEnvMut<Env>, slot: u64) -> i64 {
 
 
     (objects.len() - 1) as i64
     (objects.len() - 1) as i64
 }
 }
-
-/// Will return current blockchain timestamp.
-pub(crate) fn get_blockchain_time(ctx: FunctionEnvMut<Env>) -> u64 {
-    // TODO: Gas cost
-    ctx.data().time_keeper.blockchain_timestamp()
-}

+ 0 - 24
src/runtime/vm_runtime.rs

@@ -277,24 +277,6 @@ impl Runtime {
                     import::merkle::merkle_add,
                     import::merkle::merkle_add,
                 ),
                 ),
 
 
-                "get_current_epoch_" => Function::new_typed_with_env(
-                    &mut store,
-                    &ctx,
-                    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(
                 "get_verifying_block_height_" => Function::new_typed_with_env(
                     &mut store,
                     &mut store,
                     &ctx,
                     &ctx,
@@ -307,12 +289,6 @@ impl Runtime {
                     import::util::get_verifying_block_height_epoch,
                     import::util::get_verifying_block_height_epoch,
                 ),
                 ),
 
 
-                "get_slot_" => Function::new_typed_with_env(
-                    &mut store,
-                    &ctx,
-                    import::util::get_slot,
-                ),
-
                 "get_blockchain_time_" => Function::new_typed_with_env(
                 "get_blockchain_time_" => Function::new_typed_with_env(
                     &mut store,
                     &mut store,
                     &ctx,
                     &ctx,

+ 39 - 18
src/sdk/src/blockchain.rs

@@ -131,26 +131,47 @@ pub fn block_version(height: u64) -> u8 {
     }
     }
 }
 }
 
 
-/// Auxiliary function to calculate provided block height(slot) expected reward value.
-/// Genesis slot(0) always returns reward value 0.
-/// We use PoW bootstrap, configured to reduce rewards at fixed height numbers, until a cutoff.
-/// Once cut-off is reached, signalling PoS start, reward value is based on DARK token-economics.
+/// Auxiliary function to calculate provided block height epoch.
+/// Each epoch is defined by the fixed intervals rewards change.
+/// Genesis block is on epoch 0.
+pub fn block_epoch(height: u64) -> u64 {
+    match height {
+        0 => 0,
+        1..=1000 => 1,
+        1001..=2000 => 2,
+        2001..=3000 => 3,
+        3001..=4000 => 4,
+        4001..=5000 => 5,
+        5001..=6000 => 6,
+        6001..=7000 => 7,
+        7001..=8000 => 8,
+        8001..=9000 => 9,
+        9001..=10000 => 10,
+        10001.. => 11,
+    }
+}
+
+/// Auxiliary function to calculate provided block height expected reward value.
+/// Genesis block always returns reward value 0. Rewards are halfed at fixed intervals,
+/// called epochs. After last epoch has started, reward value is based on DARK token-economics.
 pub fn expected_reward(height: u64) -> u64 {
 pub fn expected_reward(height: u64) -> u64 {
+    // Grab block height epoch
+    let epoch = block_epoch(height);
+
+    // TODO (res) implement reward mechanism with accord to DRK, DARK token-economics.
     // Configured block rewards (1 DRK == 1 * 10^8)
     // Configured block rewards (1 DRK == 1 * 10^8)
-    match height {
+    match epoch {
         0 => 0,
         0 => 0,
-        1..=1000 => 2_000_000_000,         // 20 DRK
-        1001..=2000 => 1_800_000_000,      // 18 DRK
-        2001..=3000 => 1_600_000_000,      // 16 DRK
-        3001..=4000 => 1_400_000_000,      // 14 DRK
-        4001..=5000 => 1_200_000_000,      // 12 DRK
-        5001..=6000 => 1_000_000_000,      // 10 DRK
-        6001..=7000 => 800_000_000,        // 8 DRK
-        7001..=8000 => 600_000_000,        // 6 DRK
-        8001..=9000 => 400_000_000,        // 4 DRK
-        9001..=10000 => 200_000_000,       // 2 DRK
-        10001..=POW_CUTOFF => 100_000_000, // 1 DRK
-        // TODO (res) implement reward mechanism with accord to DRK, DARK token-economics.
-        POS_START.. => 100_000_000, // 1 DRK
+        1 => 2_000_000_000, // 20 DRK
+        2 => 1_800_000_000, // 18 DRK
+        3 => 1_600_000_000, // 16 DRK
+        4 => 1_400_000_000, // 14 DRK
+        5 => 1_200_000_000, // 12 DRK
+        6 => 1_000_000_000, // 10 DRK
+        7 => 800_000_000,   // 8 DRK
+        8 => 600_000_000,   // 6 DRK
+        9 => 400_000_000,   // 4 DRK
+        10 => 200_000_000,  // 2 DRK
+        _ => 100_000_000,   // 1 DRK
     }
     }
 }
 }

+ 5 - 45
src/sdk/src/util.rs

@@ -49,7 +49,7 @@ pub fn get_object_size(object_index: u32) -> i64 {
     unsafe { get_object_size_(object_index) }
     unsafe { get_object_size_(object_index) }
 }
 }
 
 
-/// Auxiliary function to parse db_get and get_slot return value.
+/// Auxiliary function to parse db_get return value.
 /// If either of these functions returns a negative integer error code,
 /// If either of these functions returns a negative integer error code,
 /// convert it into a [`ContractError`].
 /// convert it into a [`ContractError`].
 pub(crate) fn parse_ret(ret: i64) -> GenericResult<Option<Vec<u8>>> {
 pub(crate) fn parse_ret(ret: i64) -> GenericResult<Option<Vec<u8>>> {
@@ -77,33 +77,6 @@ pub(crate) fn parse_ret(ret: i64) -> GenericResult<Option<Vec<u8>>> {
     Ok(Some(buf))
     Ok(Some(buf))
 }
 }
 
 
-/// Everyone can call this. Will return current epoch.
-///
-/// ```
-/// epoch = get_current_epoch();
-/// ```
-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.
-///
-/// ```
-/// slot = get_current_slot();
-/// ```
-pub fn get_current_slot() -> u64 {
-    unsafe { get_current_slot_() }
-}
-
 /// Everyone can call this. Will return runtime configured
 /// Everyone can call this. Will return runtime configured
 /// verifying block height.
 /// verifying block height.
 ///
 ///
@@ -124,23 +97,14 @@ pub fn get_verifying_block_height_epoch() -> u64 {
     unsafe { get_verifying_block_height_epoch_() }
     unsafe { get_verifying_block_height_epoch_() }
 }
 }
 
 
-/// Everyone can call this. Will return requested slot from `SlotStore`.
-///
-/// ```
-/// slot = get_slot(slot);
-/// ```
-pub fn get_slot(slot: u64) -> GenericResult<Option<Vec<u8>>> {
-    let ret = unsafe { get_slot_(slot) };
-    parse_ret(ret)
-}
-
 /// Everyone can call this. Will return current blockchain timestamp.
 /// Everyone can call this. Will return current blockchain timestamp.
 ///
 ///
 /// ```
 /// ```
 /// timestamp = get_blockchain_time();
 /// timestamp = get_blockchain_time();
 /// ```
 /// ```
-pub fn get_blockchain_time() -> u64 {
-    unsafe { get_blockchain_time_() }
+pub fn get_blockchain_time() -> GenericResult<Option<Vec<u8>>> {
+    let ret = unsafe { get_blockchain_time_() };
+    parse_ret(ret)
 }
 }
 
 
 /// Only exec() can call this. Will return last block information.
 /// Only exec() can call this. Will return last block information.
@@ -159,12 +123,8 @@ extern "C" {
     fn get_object_bytes_(ptr: *const u8, len: u32) -> i64;
     fn get_object_bytes_(ptr: *const u8, len: u32) -> i64;
     fn get_object_size_(len: u32) -> i64;
     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_block_height_() -> u64;
     fn get_verifying_block_height_epoch_() -> u64;
     fn get_verifying_block_height_epoch_() -> u64;
-    fn get_slot_(slot: u64) -> i64;
-    fn get_blockchain_time_() -> u64;
+    fn get_blockchain_time_() -> i64;
     fn get_last_block_info_() -> i64;
     fn get_last_block_info_() -> i64;
 }
 }