Randomize Dandelion timer (#928)

This commit is contained in:
Quentin Le Sceller 2018-04-04 13:14:58 -04:00 committed by Ignotus Peverell
parent 40212942da
commit 68e2fa3915
2 changed files with 18 additions and 14 deletions

View file

@ -51,7 +51,6 @@ pub fn monitor_transactions<T>(
let time_transaction = time_stem_transactions.get(tx_hash).unwrap(); let time_transaction = time_stem_transactions.get(tx_hash).unwrap();
let interval = now_utc().to_timespec().sec - time_transaction; let interval = now_utc().to_timespec().sec - time_transaction;
// TODO Randomize between 30 and 60 seconds
if interval >= config.dandelion_embargo { if interval >= config.dandelion_embargo {
let source = TxSource { let source = TxSource {
debug_name: "dandelion-monitor".to_string(), debug_name: "dandelion-monitor".to_string(),

View file

@ -252,6 +252,11 @@ where
let stem_propagation = random <= self.config.dandelion_probability; let stem_propagation = random <= self.config.dandelion_probability;
let mut will_stem = stem && stem_propagation; let mut will_stem = stem && stem_propagation;
// Track the case where a parent of a transaction is in stempool
let mut parent_in_stempool = false;
// The timer attached to this transaction
let mut timer: i64 = 0;
// The next issue is to identify all unspent outputs that // The next issue is to identify all unspent outputs that
// this transaction will consume and make sure they exist in the set. // this transaction will consume and make sure they exist in the set.
let mut pool_refs: Vec<graph::Edge> = Vec::new(); let mut pool_refs: Vec<graph::Edge> = Vec::new();
@ -269,17 +274,13 @@ where
match self.search_for_best_output(&output) { match self.search_for_best_output(&output) {
Parent::PoolTransaction { tx_ref: x } => pool_refs.push(base.with_source(Some(x))), Parent::PoolTransaction { tx_ref: x } => pool_refs.push(base.with_source(Some(x))),
Parent::StemPoolTransaction { tx_ref: x } => { Parent::StemPoolTransaction { tx_ref: x } => {
if will_stem { will_stem = true;
// Going to stem this transaction if parent is in stempool it's ok. parent_in_stempool = true;
debug!(LOGGER, "Going in stempool"); debug!(LOGGER, "Parent is in stempool, going in stempool");
pool_refs.push(base.with_source(Some(x))); pool_refs.push(base.with_source(Some(x)));
} else { let temp_timer = self.time_stem_transactions.get(&x).unwrap().clone();
will_stem = true; if temp_timer > timer {
debug!( timer = temp_timer;
LOGGER,
"Parent is in stempool, force transaction to go in stempool"
);
pool_refs.push(base.with_source(Some(x)));
} }
} }
Parent::BlockTransaction => { Parent::BlockTransaction => {
@ -299,6 +300,11 @@ where
let is_orphan = orphan_refs.len() > 0; let is_orphan = orphan_refs.len() > 0;
// In the case the parent is not in stempool we randomize the timer
if !parent_in_stempool {
timer = time::now_utc().to_timespec().sec + rand::thread_rng().gen_range(0, 31);
}
// Next we examine the outputs this transaction creates and ensure // Next we examine the outputs this transaction creates and ensure
// that they do not already exist. // that they do not already exist.
// I believe its worth preventing duplicate outputs from being // I believe its worth preventing duplicate outputs from being
@ -344,8 +350,7 @@ where
self.adapter.stem_tx_accepted(&tx); self.adapter.stem_tx_accepted(&tx);
self.stem_transactions.insert(tx_hash, Box::new(tx)); self.stem_transactions.insert(tx_hash, Box::new(tx));
// Track this transaction // Track this transaction
self.time_stem_transactions self.time_stem_transactions.insert(tx_hash, timer);
.insert(tx_hash, time::now_utc().to_timespec().sec);
} else { } else {
// Fluff phase: transaction is added to memory pool and broadcasted normally // Fluff phase: transaction is added to memory pool and broadcasted normally
self.pool.add_pool_transaction( self.pool.add_pool_transaction(