فهرست منبع

fee: replace legacy fee calculation

brid 1 هفته پیش
والد
کامیت
a444e8737c

+ 4 - 2
bin/drk/src/money.rs

@@ -45,7 +45,6 @@ use darkfi_money_contract::{
     MoneyFunction, MONEY_CONTRACT_ZKAS_FEE_NS_V1,
 };
 use darkfi_sdk::{
-    blockchain::compute_fee,
     bridgetree::Position,
     crypto::{
         keypair::{Address, Keypair, PublicKey, SecretKey, StandardAddress},
@@ -54,6 +53,7 @@ use darkfi_sdk::{
         BaseBlind, FuncId, MerkleNode, MerkleTree, ScalarBlind, MONEY_CONTRACT_ID,
     },
     dark_tree::DarkLeaf,
+    fee::minimum_fee,
     pasta::pallas,
     ContractCall,
 };
@@ -1291,7 +1291,9 @@ impl Drk {
     ) -> Result<(ContractCall, Vec<Proof>, Vec<SecretKey>)> {
         // First we verify the fee-less transaction to see how much fee it requires for execution
         // and verification.
-        let required_fee = compute_fee(&FEE_CALL_GAS) + self.get_tx_fee(tx, false).await?;
+        let fee_call_fee = minimum_fee(FEE_CALL_GAS)?;
+        let tx_fee = self.get_tx_fee(tx, false).await?;
+        let required_fee = fee_call_fee.checked_add(tx_fee).ok_or(Error::AdditionOverflow)?;
 
         // Knowing the total gas, we can now find an OwnCoin of enough value
         // so that we can create a valid Money::Fee call.

+ 4 - 4
script/research/tx-replayer/src/main.rs

@@ -35,10 +35,10 @@ use darkfi::{
     zk::VerifyingKey,
 };
 use darkfi_sdk::{
-    blockchain::compute_fee,
     crypto::{ContractId, MerkleTree, PublicKey},
     dark_tree::dark_forest_leaf_vec_integrity_check,
     deploy::DeployParamsV1,
+    fee::minimum_fee,
     pasta::pallas,
     tx::TransactionHash,
 };
@@ -308,7 +308,7 @@ async fn verify_transaction_wasm(
         };
 
         // Compute the required fee for this transaction
-        let required_fee = compute_fee(&total_gas_used);
+        let required_fee = minimum_fee(total_gas_used)?;
 
         // Check that enough fee has been paid for the used gas in this transaction
         if required_fee > fee {
@@ -483,7 +483,7 @@ async fn verify_transaction_zkps(
         };
 
         // Compute the required fee for this transaction
-        let required_fee = compute_fee(&total_gas_used);
+        let required_fee = minimum_fee(total_gas_used)?;
 
         // Check that enough fee has been paid for the used gas in this transaction
         if required_fee > fee {
@@ -637,7 +637,7 @@ async fn verify_transaction_signatures(
         };
 
         // Compute the required fee for this transaction
-        let required_fee = compute_fee(&total_gas_used);
+        let required_fee = minimum_fee(total_gas_used)?;
 
         // Check that enough fee has been paid for the used gas in this transaction
         if required_fee > fee {

+ 4 - 2
src/contract/money/tests/dep8.rs

@@ -34,11 +34,12 @@ use darkfi_money_contract::{
     MONEY_CONTRACT_ZKAS_MINT_NS_V1,
 };
 use darkfi_sdk::{
-    blockchain::{compute_fee, expected_reward},
+    blockchain::expected_reward,
     crypto::{
         contract_id::MONEY_CONTRACT_ID, note::AeadEncryptedNote, BaseBlind, FuncId, MerkleNode,
         MerkleTree, ScalarBlind, SecretKey,
     },
+    fee::minimum_fee,
     pasta::pallas,
     ContractCall,
 };
@@ -180,7 +181,8 @@ fn dep8() -> Result<()> {
         drop(validator);
 
         // Compute the required fee
-        let required_fee = compute_fee(&(gas_used + FEE_CALL_GAS));
+        let fee_gas = gas_used.checked_add(FEE_CALL_GAS).ok_or(darkfi::Error::AdditionOverflow)?;
+        let required_fee = minimum_fee(fee_gas)?;
         let change_value = output_coin.note.value - required_fee;
 
         // Input and output setup.

+ 4 - 3
src/contract/test-harness/src/money_fee.rs

@@ -33,11 +33,11 @@ use darkfi_money_contract::{
     MoneyFunction, MONEY_CONTRACT_ZKAS_FEE_NS_V1,
 };
 use darkfi_sdk::{
-    blockchain::compute_fee,
     crypto::{
         contract_id::MONEY_CONTRACT_ID, note::AeadEncryptedNote, BaseBlind, Blind, FuncId,
         ScalarBlind, SecretKey,
     },
+    fee::minimum_fee,
     pasta::pallas,
     ContractCall,
 };
@@ -58,7 +58,7 @@ impl TestHarness {
         let wallet = self.wallet(holder);
 
         // Compute fee call required fee
-        let required_fee = compute_fee(&FEE_CALL_GAS);
+        let required_fee = minimum_fee(FEE_CALL_GAS)?;
 
         // Find a compatible OwnCoin
         let coin = wallet
@@ -201,7 +201,8 @@ impl TestHarness {
             .0;
 
         // Compute the required fee
-        let required_fee = compute_fee(&(gas_used + FEE_CALL_GAS));
+        let fee_gas = gas_used.checked_add(FEE_CALL_GAS).ok_or(darkfi::Error::AdditionOverflow)?;
+        let required_fee = minimum_fee(fee_gas)?;
 
         // Knowing the total gas, we can now find an OwnCoin of enough
         // value so that we can create a valid Money::Fee call.

+ 11 - 0
src/error.rs

@@ -453,6 +453,10 @@ pub enum Error {
     #[error("Invalid DarkTree: {0}")]
     DarkTreeError(darkfi_sdk::error::DarkTreeError),
 
+    #[cfg(feature = "darkfi-sdk")]
+    #[error("Fee error: {0}")]
+    FeeError(darkfi_sdk::error::FeeError),
+
     #[cfg(feature = "blockchain")]
     #[error("contract wasm bincode not found")]
     WasmBincodeNotFound,
@@ -836,6 +840,13 @@ impl From<darkfi_sdk::error::DarkTreeError> for Error {
     }
 }
 
+#[cfg(feature = "darkfi-sdk")]
+impl From<darkfi_sdk::error::FeeError> for Error {
+    fn from(err: darkfi_sdk::error::FeeError) -> Self {
+        Self::FeeError(err)
+    }
+}
+
 #[cfg(feature = "util")]
 impl From<tracing_subscriber::util::TryInitError> for Error {
     fn from(err: tracing_subscriber::util::TryInitError) -> Self {

+ 0 - 8
src/sdk/src/blockchain.rs

@@ -67,11 +67,3 @@ pub fn expected_reward(height: u32) -> u64 {
         _ => 100_000_000,   // 1 DRK
     }
 }
-
-/// Auxiliary function to compute the corresponding fee value
-/// for the provided gas.
-///
-/// Currently we simply divide the gas value by 100.
-pub fn compute_fee(gas: &u64) -> u64 {
-    gas / 100
-}

+ 2 - 2
src/validator/mod.rs

@@ -18,7 +18,7 @@
 
 use std::{collections::HashMap, sync::Arc};
 
-use darkfi_sdk::{blockchain::compute_fee, crypto::MerkleTree};
+use darkfi_sdk::{crypto::MerkleTree, fee::minimum_fee};
 use kvdb_overlay::Database;
 use num_bigint::BigUint;
 use smol::lock::RwLock;
@@ -177,7 +177,7 @@ impl Validator {
         )
         .await?;
 
-        Ok(compute_fee(&verify_result.total_gas_used()))
+        Ok(minimum_fee(verify_result.total_gas_used())?)
     }
 
     /// The node retrieves a transaction, validates its state

+ 12 - 2
src/validator/verification.rs

@@ -19,13 +19,14 @@
 use std::{collections::HashMap, sync::Arc};
 
 use darkfi_sdk::{
-    blockchain::{block_version, compute_fee},
+    blockchain::block_version,
     crypto::{
         schnorr::{SchnorrPublic, Signature},
         ContractId, MerkleTree, PublicKey,
     },
     dark_tree::dark_forest_leaf_vec_integrity_check,
     deploy::DeployParamsV1,
+    fee::minimum_fee,
     pasta::pallas,
 };
 use darkfi_serial::{deserialize_async, serialize_async, AsyncDecodable, AsyncEncodable};
@@ -901,7 +902,16 @@ pub async fn verify_transaction(
         };
 
         // Compute the required fee for this transaction
-        let required_fee = compute_fee(&total_gas_used);
+        let required_fee = match minimum_fee(total_gas_used) {
+            Ok(fee) => fee,
+            Err(e) => {
+                error!(
+                    target: "validator::verification::verify_transaction",
+                    "[VALIDATOR] Failed calculating tx {tx_hash} fee: {e}"
+                );
+                return Err(TxVerifyFailed::InvalidFee.into())
+            }
+        };
 
         // Check that enough fee has been paid for the used gas in this
         // transaction.