Always stem local txs if configured that way (unless explicitly fluffed) (#2876)

* always stem local txs if configured that way (unless explicitly fluff from wallet)
this overrides current epoch behavior for txs coming in via "push-api"
rename "local" to "our" txs

* TxSource is now an enum for type safety.
This commit is contained in:
Antioch Peverell
2019-07-04 11:56:42 +01:00
committed by GitHub
parent 82775164e8
commit f4eb3e3d4b
10 changed files with 86 additions and 75 deletions
+8 -11
View File
@@ -37,7 +37,6 @@ use crate::core::{core, global};
use crate::p2p;
use crate::p2p::types::PeerInfo;
use crate::pool;
use crate::pool::types::DandelionConfig;
use crate::util::OneTime;
use chrono::prelude::*;
use chrono::Duration;
@@ -97,10 +96,7 @@ impl p2p::ChainAdapter for NetToChainAdapter {
return Ok(true);
}
let source = pool::TxSource {
debug_name: "p2p".to_string(),
identifier: "?.?.?.?".to_string(),
};
let source = pool::TxSource::Broadcast;
let header = self.chain().head_header()?;
@@ -804,11 +800,11 @@ impl DandelionAdapter for PoolToNetAdapter {
}
impl pool::PoolAdapter for PoolToNetAdapter {
fn tx_accepted(&self, tx: &core::Transaction) {
self.peers().broadcast_transaction(tx);
fn tx_accepted(&self, entry: &pool::PoolEntry) {
self.peers().broadcast_transaction(&entry.tx);
}
fn stem_tx_accepted(&self, tx: &core::Transaction) -> Result<(), pool::PoolError> {
fn stem_tx_accepted(&self, entry: &pool::PoolEntry) -> Result<(), pool::PoolError> {
// Take write lock on the current epoch.
// We need to be able to update the current relay peer if not currently connected.
let mut epoch = self.dandelion_epoch.write();
@@ -816,9 +812,10 @@ impl pool::PoolAdapter for PoolToNetAdapter {
// If "stem" epoch attempt to relay the tx to the next Dandelion relay.
// Fallback to immediately fluffing the tx if we cannot stem for any reason.
// If "fluff" epoch then nothing to do right now (fluff via Dandelion monitor).
if epoch.is_stem() {
// If node is configured to always stem our (pushed via api) txs then do so.
if epoch.is_stem() || (entry.src.is_pushed() && epoch.always_stem_our_txs()) {
if let Some(peer) = epoch.relay_peer(&self.peers()) {
match peer.send_stem_transaction(tx) {
match peer.send_stem_transaction(&entry.tx) {
Ok(_) => {
info!("Stemming this epoch, relaying to next peer.");
Ok(())
@@ -841,7 +838,7 @@ impl pool::PoolAdapter for PoolToNetAdapter {
impl PoolToNetAdapter {
/// Create a new pool to net adapter
pub fn new(config: DandelionConfig) -> PoolToNetAdapter {
pub fn new(config: pool::DandelionConfig) -> PoolToNetAdapter {
PoolToNetAdapter {
peers: OneTime::new(),
dandelion_epoch: Arc::new(RwLock::new(DandelionEpoch::new(config))),
+8 -6
View File
@@ -496,8 +496,8 @@ impl DandelionEpoch {
match self.start_time {
None => true,
Some(start_time) => {
let epoch_secs = self.config.epoch_secs.expect("epoch_secs config missing") as i64;
Utc::now().timestamp().saturating_sub(start_time) > epoch_secs
let epoch_secs = self.config.epoch_secs;
Utc::now().timestamp().saturating_sub(start_time) > epoch_secs as i64
}
}
}
@@ -511,10 +511,7 @@ impl DandelionEpoch {
// If stem_probability == 90 then we stem 90% of the time.
let mut rng = rand::thread_rng();
let stem_probability = self
.config
.stem_probability
.expect("stem_probability config missing");
let stem_probability = self.config.stem_probability;
self.is_stem = rng.gen_range(0, 100) < stem_probability;
let addr = self.relay_peer.clone().map(|p| p.info.addr);
@@ -529,6 +526,11 @@ impl DandelionEpoch {
self.is_stem
}
/// Always stem our (pushed via api) txs regardless of stem/fluff epoch?
pub fn always_stem_our_txs(&self) -> bool {
self.config.always_stem_our_txs
}
/// What is our current relay peer?
/// If it is not connected then choose a new one.
pub fn relay_peer(&mut self, peers: &Arc<p2p::Peers>) -> Option<Arc<p2p::Peer>> {
+4 -19
View File
@@ -113,9 +113,7 @@ fn process_fluff_phase(
return Ok(());
}
let cutoff_secs = dandelion_config
.aggregation_secs
.expect("aggregation secs config missing");
let cutoff_secs = dandelion_config.aggregation_secs;
let cutoff_entries = select_txs_cutoff(&tx_pool.stempool, cutoff_secs);
// If epoch is expired, fluff *all* outstanding entries in stempool.
@@ -149,12 +147,7 @@ fn process_fluff_phase(
verifier_cache.clone(),
)?;
let src = TxSource {
debug_name: "fluff".to_string(),
identifier: "?.?.?.?".to_string(),
};
tx_pool.add_to_pool(src, agg_tx, false, &header)?;
tx_pool.add_to_pool(TxSource::Fluff, agg_tx, false, &header)?;
Ok(())
}
@@ -165,10 +158,7 @@ fn process_expired_entries(
// Take a write lock on the txpool for the duration of this processing.
let mut tx_pool = tx_pool.write();
let embargo_secs = dandelion_config
.embargo_secs
.expect("embargo_secs config missing")
+ thread_rng().gen_range(0, 31);
let embargo_secs = dandelion_config.embargo_secs + thread_rng().gen_range(0, 31);
let expired_entries = select_txs_cutoff(&tx_pool.stempool, embargo_secs);
if expired_entries.is_empty() {
@@ -179,14 +169,9 @@ fn process_expired_entries(
let header = tx_pool.chain_head()?;
let src = TxSource {
debug_name: "embargo_expired".to_string(),
identifier: "?.?.?.?".to_string(),
};
for entry in expired_entries {
let txhash = entry.tx.hash();
match tx_pool.add_to_pool(src.clone(), entry.tx, false, &header) {
match tx_pool.add_to_pool(TxSource::EmbargoExpired, entry.tx, false, &header) {
Ok(_) => info!(
"dand_mon: embargo expired for {}, fluffed successfully.",
txhash