mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Clean decoy selection code
This commit is contained in:
@@ -39,8 +39,6 @@ async fn select_n(
|
|||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let decoy_count = ring_len - 1;
|
|
||||||
|
|
||||||
// Get the distribution
|
// Get the distribution
|
||||||
let distribution = rpc.get_output_distribution(.. height).await?;
|
let distribution = rpc.get_output_distribution(.. height).await?;
|
||||||
let highest_output_exclusive_bound = distribution[distribution.len() - DEFAULT_LOCK_WINDOW];
|
let highest_output_exclusive_bound = distribution[distribution.len() - DEFAULT_LOCK_WINDOW];
|
||||||
@@ -48,7 +46,7 @@ async fn select_n(
|
|||||||
// outputs even when excluding them (due to their own timelock requirements)
|
// outputs even when excluding them (due to their own timelock requirements)
|
||||||
// Considering this a temporal error for very new chains, it's sufficiently sane to have
|
// Considering this a temporal error for very new chains, it's sufficiently sane to have
|
||||||
if highest_output_exclusive_bound.saturating_sub(u64::try_from(COINBASE_LOCK_WINDOW).unwrap()) <
|
if highest_output_exclusive_bound.saturating_sub(u64::try_from(COINBASE_LOCK_WINDOW).unwrap()) <
|
||||||
u64::try_from(decoy_count).unwrap()
|
u64::try_from(ring_len).unwrap()
|
||||||
{
|
{
|
||||||
Err(RpcError::InternalError("not enough decoy candidates".to_string()))?;
|
Err(RpcError::InternalError("not enough decoy candidates".to_string()))?;
|
||||||
}
|
}
|
||||||
@@ -75,23 +73,26 @@ async fn select_n(
|
|||||||
// to the RPC
|
// to the RPC
|
||||||
// The length of that remainder is expected to be minimal
|
// The length of that remainder is expected to be minimal
|
||||||
while res.len() != decoy_count {
|
while res.len() != decoy_count {
|
||||||
let remaining = decoy_count - res.len();
|
|
||||||
let mut candidates = Vec::with_capacity(remaining);
|
|
||||||
while candidates.len() != remaining {
|
|
||||||
// Ensure this isn't infinitely looping
|
|
||||||
iters += 1;
|
iters += 1;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
const MAX_ITERS: usize = 10;
|
const MAX_ITERS: usize = 10;
|
||||||
// When testing on fresh chains, increased iterations can be useful and we don't necessitate
|
// When testing on fresh chains, increased iterations can be useful and we don't necessitate
|
||||||
// reasonable performance
|
// reasonable performance
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
const MAX_ITERS: usize = 100;
|
const MAX_ITERS: usize = 100;
|
||||||
|
// Ensure this isn't infinitely looping
|
||||||
if iters == MAX_ITERS {
|
// We check both that we aren't at the maximum amount of iterations and that the not-yet
|
||||||
|
// selected candidates exceed the amount of candidates necessary to trigger the next iteration
|
||||||
|
if (iters == MAX_ITERS) ||
|
||||||
|
((highest_output_exclusive_bound - u64::try_from(do_not_select.len()).unwrap()) <
|
||||||
|
u64::try_from(ring_len).unwrap())
|
||||||
|
{
|
||||||
Err(RpcError::InternalError("hit decoy selection round limit".to_string()))?;
|
Err(RpcError::InternalError("hit decoy selection round limit".to_string()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let remaining = decoy_count - res.len();
|
||||||
|
let mut candidates = Vec::with_capacity(remaining);
|
||||||
|
while candidates.len() != remaining {
|
||||||
// Use a gamma distribution, as Monero does
|
// Use a gamma distribution, as Monero does
|
||||||
// TODO: Cite these constants
|
// TODO: Cite these constants
|
||||||
let mut age = Gamma::<f64>::new(19.28, 1.0 / 1.61).unwrap().sample(rng).exp();
|
let mut age = Gamma::<f64>::new(19.28, 1.0 / 1.61).unwrap().sample(rng).exp();
|
||||||
|
|||||||
Reference in New Issue
Block a user