refactor(block producer): remove fill_tx_fee change assertion
@@ -43,9 +43,27 @@ pub async fn fill_tx_fee(
return Ok(());
}
+ 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)
+ };
+
// calculate required fee, we assume always need a change cell to simplify the code
required_fee += CHANGE_CELL_CAPACITY;
+ let mut change_capacity = 0;
+ while required_fee > 0 {
// to filter used input cells
let taken_outpoints = tx_skeleton.taken_outpoints()?;
// get payment cells
@@ -64,43 +82,15 @@ pub async fn fill_tx_fee(
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 = estimate_tx_size_with_change(tx_skeleton)?;
- // calculate required fee
let tx_fee = calculate_required_tx_fee(tx_size);
+ let max_paid_fee = tx_skeleton
+ .calculate_fee()?
+ .saturating_sub(CHANGE_CELL_CAPACITY);
- log::debug!(
- "paid fee {}, tx fee {}, result change {}",
- paid_fee,
- calculate_required_tx_fee(tx_size),
- paid_fee - tx_fee,
- );
-
- paid_fee - tx_fee
- };
-
- assert!(
- change_capacity > CHANGE_CELL_CAPACITY,
- "change capacity must cover the change cell"
- );
+ required_fee = tx_fee.saturating_sub(max_paid_fee);
+ change_capacity = max_paid_fee + CHANGE_CELL_CAPACITY - tx_fee;
+ }
let change_cell = CellOutput::new_builder()
.lock(lock_script)
@@ -110,6 +100,7 @@ pub async fn fill_tx_fee(
tx_skeleton
.outputs_mut()
.push((change_cell, Default::default()));
+
Ok(())
}
