|
@@ -28,6 +28,7 @@ use darkfi_sdk::{
|
|
|
},
|
|
},
|
|
|
dark_tree::DarkLeaf,
|
|
dark_tree::DarkLeaf,
|
|
|
error::{ContractError, ContractResult},
|
|
error::{ContractError, ContractResult},
|
|
|
|
|
+ fee::MONEY_FEE_CALLDATA_PREFIX_LEN,
|
|
|
msg,
|
|
msg,
|
|
|
pasta::pallas,
|
|
pasta::pallas,
|
|
|
wasm::{
|
|
wasm::{
|
|
@@ -50,18 +51,17 @@ use crate::{
|
|
|
MONEY_CONTRACT_NULLIFIER_ROOTS_TREE, MONEY_CONTRACT_ZKAS_FEE_NS_V1,
|
|
MONEY_CONTRACT_NULLIFIER_ROOTS_TREE, MONEY_CONTRACT_ZKAS_FEE_NS_V1,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const MONEY_FEE_PREFIX_LEN: usize = 9;
|
|
|
|
|
-
|
|
|
|
|
-fn parse_fee_call_data(data: &[u8]) -> Result<(u64, MoneyFeeParamsV1), ContractError> {
|
|
|
|
|
- if data.len() < MONEY_FEE_PREFIX_LEN {
|
|
|
|
|
|
|
+fn parse_fee_call_data(data: &[u8]) -> Result<(u64, u64, MoneyFeeParamsV1), ContractError> {
|
|
|
|
|
+ if data.len() < MONEY_FEE_CALLDATA_PREFIX_LEN {
|
|
|
msg!("[FeeV1] Error: Fee call data is too short");
|
|
msg!("[FeeV1] Error: Fee call data is too short");
|
|
|
return Err(MoneyError::InvalidFeeCall.into())
|
|
return Err(MoneyError::InvalidFeeCall.into())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let fee = deserialize(&data[1..MONEY_FEE_PREFIX_LEN])?;
|
|
|
|
|
- let params = deserialize(&data[MONEY_FEE_PREFIX_LEN..])?;
|
|
|
|
|
|
|
+ let fee = deserialize(&data[1..9])?;
|
|
|
|
|
+ let burned_fee = deserialize(&data[9..MONEY_FEE_CALLDATA_PREFIX_LEN])?;
|
|
|
|
|
+ let params = deserialize(&data[MONEY_FEE_CALLDATA_PREFIX_LEN..])?;
|
|
|
|
|
|
|
|
- Ok((fee, params))
|
|
|
|
|
|
|
+ Ok((fee, burned_fee, params))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// `get_metadata` function for `Money::FeeV1`
|
|
/// `get_metadata` function for `Money::FeeV1`
|
|
@@ -71,7 +71,7 @@ pub(crate) fn money_fee_get_metadata_v1(
|
|
|
calls: Vec<DarkLeaf<ContractCall>>,
|
|
calls: Vec<DarkLeaf<ContractCall>>,
|
|
|
) -> Result<Vec<u8>, ContractError> {
|
|
) -> Result<Vec<u8>, ContractError> {
|
|
|
let self_ = &calls[call_idx].data;
|
|
let self_ = &calls[call_idx].data;
|
|
|
- let (_, params) = parse_fee_call_data(&self_.data)?;
|
|
|
|
|
|
|
+ let (_, _, params) = parse_fee_call_data(&self_.data)?;
|
|
|
|
|
|
|
|
// Public inputs for the ZK proofs we have to verify
|
|
// Public inputs for the ZK proofs we have to verify
|
|
|
let mut zk_public_inputs: Vec<(String, Vec<pallas::Base>)> = vec![];
|
|
let mut zk_public_inputs: Vec<(String, Vec<pallas::Base>)> = vec![];
|
|
@@ -115,14 +115,19 @@ pub(crate) fn money_fee_process_instruction_v1(
|
|
|
calls: Vec<DarkLeaf<ContractCall>>,
|
|
calls: Vec<DarkLeaf<ContractCall>>,
|
|
|
) -> Result<Vec<u8>, ContractError> {
|
|
) -> Result<Vec<u8>, ContractError> {
|
|
|
let self_ = &calls[call_idx];
|
|
let self_ = &calls[call_idx];
|
|
|
- let (fee, params) = parse_fee_call_data(&self_.data.data)?;
|
|
|
|
|
|
|
+ let (paid_fee, burned_fee, params) = parse_fee_call_data(&self_.data.data)?;
|
|
|
|
|
|
|
|
// We should have _some_ fee paid...
|
|
// We should have _some_ fee paid...
|
|
|
- if fee == 0 {
|
|
|
|
|
|
|
+ if paid_fee == 0 {
|
|
|
msg!("[FeeV1] Error: Paid fee is 0");
|
|
msg!("[FeeV1] Error: Paid fee is 0");
|
|
|
return Err(MoneyError::InsufficientFee.into())
|
|
return Err(MoneyError::InsufficientFee.into())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ let Some(miner_claimable_fee) = paid_fee.checked_sub(burned_fee) else {
|
|
|
|
|
+ msg!("[FeeV1] Error: Burned fee exceeds paid fee");
|
|
|
|
|
+ return Err(MoneyError::InvalidFeeCall.into())
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
// Access the necessary databases where there is information to
|
|
// Access the necessary databases where there is information to
|
|
|
// validate this state transition.
|
|
// validate this state transition.
|
|
|
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
|
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
|
@@ -195,8 +200,8 @@ pub(crate) fn money_fee_process_instruction_v1(
|
|
|
// Subtract the output value commitment
|
|
// Subtract the output value commitment
|
|
|
valcom_total -= params.output.value_commit;
|
|
valcom_total -= params.output.value_commit;
|
|
|
|
|
|
|
|
- // Now subtract the fee from the accumulator
|
|
|
|
|
- valcom_total -= pedersen_commitment_u64(fee, params.fee_value_blind);
|
|
|
|
|
|
|
+ // Now subtract the paid fee from the accumulator.
|
|
|
|
|
+ valcom_total -= pedersen_commitment_u64(paid_fee, params.fee_value_blind);
|
|
|
|
|
|
|
|
// If the accumulator is not back in its initial; state, that means there
|
|
// If the accumulator is not back in its initial; state, that means there
|
|
|
// is a value mismatch betweeen inputs and outputs.
|
|
// is a value mismatch betweeen inputs and outputs.
|
|
@@ -205,15 +210,15 @@ pub(crate) fn money_fee_process_instruction_v1(
|
|
|
return Err(MoneyError::ValueMismatch.into())
|
|
return Err(MoneyError::ValueMismatch.into())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Accumulate the height paid fee
|
|
|
|
|
|
|
+ // Accumulate the height miner-claimable fee.
|
|
|
let verifying_block_height = wasm::util::get_verifying_block_height()?;
|
|
let verifying_block_height = wasm::util::get_verifying_block_height()?;
|
|
|
- let Some(paid_fee) = db_get(fees_db, &serialize(&verifying_block_height))? else {
|
|
|
|
|
|
|
+ let Some(accumulated_fees) = db_get(fees_db, &serialize(&verifying_block_height))? else {
|
|
|
msg!("[FeeV1] Error: Block height fees accumulator not found");
|
|
msg!("[FeeV1] Error: Block height fees accumulator not found");
|
|
|
return Err(MoneyError::PoWRewardCallMissingFeesAccumulator.into())
|
|
return Err(MoneyError::PoWRewardCallMissingFeesAccumulator.into())
|
|
|
};
|
|
};
|
|
|
- let paid_fee: u64 = deserialize(&paid_fee)?;
|
|
|
|
|
- let Some(paid_fee) = paid_fee.checked_add(fee) else {
|
|
|
|
|
- msg!("[FeeV1] Error: Could not compute paid fee");
|
|
|
|
|
|
|
+ let accumulated_fees: u64 = deserialize(&accumulated_fees)?;
|
|
|
|
|
+ let Some(accumulated_fees) = accumulated_fees.checked_add(miner_claimable_fee) else {
|
|
|
|
|
+ msg!("[FeeV1] Error: Could not compute accumulated miner-claimable fee");
|
|
|
return Err(MoneyError::ValueMismatch.into())
|
|
return Err(MoneyError::ValueMismatch.into())
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -223,7 +228,7 @@ pub(crate) fn money_fee_process_instruction_v1(
|
|
|
coin: params.output.coin,
|
|
coin: params.output.coin,
|
|
|
tx_local: params.output.tx_local,
|
|
tx_local: params.output.tx_local,
|
|
|
height: verifying_block_height,
|
|
height: verifying_block_height,
|
|
|
- fee: paid_fee,
|
|
|
|
|
|
|
+ fee: accumulated_fees,
|
|
|
};
|
|
};
|
|
|
// and return it
|
|
// and return it
|
|
|
Ok(serialize(&update))
|
|
Ok(serialize(&update))
|