mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 04:09:23 +00:00
Remove Plan ID non-determinism leading Monero to have distinct TX fees
Monero would select decoys with a new RNG seed, which may have used more bytes, increasing the fee. There's a few comments here. 1) Non-determinism wasn't removed via distinguishing the edits. It was done by removing part of the transcript. A TODO exists to improve this. 2) Distinct TX fees is a test failure, not an issue in prod *unless* the distinct fee is greater. So long as the distinct fee is lesser, it's fine. 3) Removing outputs is expected to only decrease fees.
This commit is contained in:
@@ -358,7 +358,7 @@ pub trait Network: 'static + Send + Sync + Clone + PartialEq + Eq + Debug {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Amortize a fee over the plan's payments
|
// Amortize the fee over the plan's payments
|
||||||
let (post_fee_branches, mut operating_costs) = (|| {
|
let (post_fee_branches, mut operating_costs) = (|| {
|
||||||
// If we're creating a change output, letting us recoup coins, amortize the operating costs
|
// If we're creating a change output, letting us recoup coins, amortize the operating costs
|
||||||
// as well
|
// as well
|
||||||
@@ -417,9 +417,21 @@ pub trait Network: 'static + Send + Sync + Clone + PartialEq + Eq + Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Drop payments now worth 0
|
// Drop payments now worth 0
|
||||||
plan.payments = plan.payments.drain(..).filter(|payment| payment.amount != 0).collect();
|
let plan_id = plan.id();
|
||||||
|
plan.payments = plan
|
||||||
|
.payments
|
||||||
|
.drain(..)
|
||||||
|
.filter(|payment| {
|
||||||
|
if payment.amount != 0 {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
log::debug!("dropping dust payment from plan {}", hex::encode(&plan_id));
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Sanity check the fee wa successfully amortized
|
// Sanity check the fee was successfully amortized
|
||||||
let new_outputs = plan.payments.iter().map(|payment| payment.amount).sum::<u64>();
|
let new_outputs = plan.payments.iter().map(|payment| payment.amount).sum::<u64>();
|
||||||
assert!((new_outputs + total_fee) <= original_outputs);
|
assert!((new_outputs + total_fee) <= original_outputs);
|
||||||
|
|
||||||
|
|||||||
@@ -113,10 +113,16 @@ impl<N: Network> Plan<N> {
|
|||||||
transcript.append_message(b"input", input.id());
|
transcript.append_message(b"input", input.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't transcript the payments as these will change between the intended Plan and the actual
|
||||||
|
// Plan, once various fee logics have executed
|
||||||
|
// TODO: Distinguish IntendedPlan and ActualPlan, or make actual payments a distinct field,
|
||||||
|
// letting us transcript this
|
||||||
|
/*
|
||||||
transcript.domain_separate(b"payments");
|
transcript.domain_separate(b"payments");
|
||||||
for payment in &self.payments {
|
for payment in &self.payments {
|
||||||
payment.transcript(&mut transcript);
|
payment.transcript(&mut transcript);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if let Some(change) = &self.change {
|
if let Some(change) = &self.change {
|
||||||
transcript.append_message(b"change", change.to_string());
|
transcript.append_message(b"change", change.to_string());
|
||||||
|
|||||||
Reference in New Issue
Block a user