fix(block producer): fill_tx_fee unable to cover tx fee
@@ -25,8 +25,7 @@ pub fn to_result<T: DeserializeOwned>(output: Output) -> Result<T> {
/// TODO accept fee rate args
fn calculate_required_tx_fee(tx_size: usize) -> u64 {
// tx_size * KB / MIN_FEE_RATE
- // TODO fix me
- tx_size as u64 + 1_00000000
+ tx_size as u64
}
/// Add fee cell to tx skeleton
@@ -39,17 +38,22 @@ pub async fn fill_tx_fee(
let tx_size = tx_skeleton.tx_in_block_size()?;
let paid_fee: u64 = tx_skeleton.calculate_fee()?;
- let taken_outpoints = tx_skeleton.taken_outpoints()?;
+ let mut required_fee = calculate_required_tx_fee(tx_size).saturating_sub(paid_fee);
+ if 0 == required_fee {
+ return Ok(());
+ }
+
// calculate required fee, we assume always need a change cell to simplify the code
- let required_fee =
- (calculate_required_tx_fee(tx_size) + CHANGE_CELL_CAPACITY).saturating_sub(paid_fee);
+ required_fee += CHANGE_CELL_CAPACITY;
+ // to filter used input cells
+ let taken_outpoints = tx_skeleton.taken_outpoints()?;
// get payment cells
- if required_fee > 0 {
let cells = rpc_client
.query_payment_cells(lock_script.clone(), required_fee, &taken_outpoints)
.await?;
assert!(!cells.is_empty(), "need cells to pay fee");
+
// put cells in tx skeleton
tx_skeleton
.inputs_mut()
@@ -59,17 +63,32 @@ pub async fn fill_tx_fee(
.build();
InputCellInfo { input, cell }
}));
- }
// Generate change cell
+ let estimate_tx_size_with_change = |tx_skeleton: &mut TransactionSkeleton| -> Result<usize> {
+ let change_cell = CellOutput::new_builder()
+ .lock(lock_script.clone())
+ .capacity(CHANGE_CELL_CAPACITY.pack())
+ .build();
+
+ tx_skeleton
+ .outputs_mut()
+ .push((change_cell, Default::default()));
+
+ let tx_size = tx_skeleton.tx_in_block_size()?;
+ tx_skeleton.outputs_mut().pop();
+
+ Ok(tx_size)
+ };
+
let change_capacity = {
let paid_fee: u64 = tx_skeleton.calculate_fee()?;
- let tx_size = tx_skeleton.tx_in_block_size()?;
+ let tx_size = estimate_tx_size_with_change(tx_skeleton)?;
// calculate required fee
let tx_fee = calculate_required_tx_fee(tx_size);
log::debug!(
- "paid fee {}, tx fee {}, result fee {}",
+ "paid fee {}, tx fee {}, result change {}",
paid_fee,
calculate_required_tx_fee(tx_size),
paid_fee - tx_fee,
