Basic Dandelion transaction routing (#719)

* Initial Dandelion Commit
* Changed stem_tx_pool to tx_stempool
* Introduction of stem memory pool and stem pool config
* Pool push now send to stem memory pool
* Add stem transaction functions
* Add stem transaction pool
* Drastically simplified code structure
* Add monitor transactions
* Add Dandelion monitor and remove transactions from stempool
* Add peer relay monitor
* Reconcile block with stempool
* Fix total size bug
* Add fluff option for pool push
* Added details on dandelion monitor
* Fix issue with missing parent
* Child transaction with stempool parent are now forced stem
* Update Dandelion Relay from outgoing peers
* Fix missing pool reconciliation
* Add the ability to fluff a transaction directly
* Fix tests for Dandelion
* Missing send_stem_transaction method...
* Add fluff handler for wallet
* Add logger when successfully updated Dandelion relay
* Launch transaction monitor last
* Fix dandelion relay misplaced
* Add logging and updating for stempool
* Additionnal check for stem transaction
* Fix 2 Locks in a row
This commit is contained in:
Quentin Le Sceller
2018-03-19 22:18:54 -05:00
committed by Ignotus Peverell
parent 7816f35238
commit fcfe7bc6a4
24 changed files with 962 additions and 83 deletions
+60 -1
View File
@@ -28,7 +28,7 @@ use core::consensus;
use core::core::{block, hash, transaction};
use core::core::transaction::{Input, OutputIdentifier};
/// Tranasction pool configuration
/// Transaction pool configuration
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PoolConfig {
/// Base fee for a transaction to be accepted by the pool. The transaction
@@ -40,6 +40,14 @@ pub struct PoolConfig {
/// Maximum capacity of the pool in number of transactions
#[serde = "default_max_pool_size"]
pub max_pool_size: usize,
/// Maximum capacity of the pool in number of transactions
#[serde = "default_dandelion_probability"]
pub dandelion_probability: usize,
/// Default embargo for Dandelion transaction
#[serde = "default_dandelion_embargo"]
pub dandelion_embargo: i64,
}
impl Default for PoolConfig {
@@ -47,6 +55,8 @@ impl Default for PoolConfig {
PoolConfig {
accept_fee_base: default_accept_fee_base(),
max_pool_size: default_max_pool_size(),
dandelion_probability: default_dandelion_probability(),
dandelion_embargo: default_dandelion_embargo(),
}
}
}
@@ -57,6 +67,12 @@ fn default_accept_fee_base() -> u64 {
fn default_max_pool_size() -> usize {
50_000
}
fn default_dandelion_probability() -> usize {
90
}
fn default_dandelion_embargo() -> i64 {
30
}
/// Placeholder: the data representing where we heard about a tx from.
///
@@ -79,6 +95,7 @@ pub enum Parent {
Unknown,
BlockTransaction,
PoolTransaction { tx_ref: hash::Hash },
StemPoolTransaction { tx_ref: hash::Hash },
AlreadySpent { other_tx: hash::Hash },
}
@@ -90,6 +107,9 @@ impl fmt::Debug for Parent {
&Parent::PoolTransaction { tx_ref: x } => {
write!(f, "Parent: Pool Transaction ({:?})", x)
}
&Parent::StemPoolTransaction { tx_ref: x } => {
write!(f, "Parent: Stempool Transaction ({:?})", x)
}
&Parent::AlreadySpent { other_tx: x } => write!(f, "Parent: Already Spent By {:?}", x),
}
}
@@ -103,6 +123,8 @@ pub enum PoolError {
InvalidTx(transaction::Error),
/// An entry already in the pool
AlreadyInPool,
/// An entry already in the stempool
AlreadyInStempool,
/// A duplicate output
DuplicateOutput {
/// The other transaction
@@ -166,6 +188,9 @@ pub trait PoolAdapter: Send + Sync {
/// The transaction pool has accepted this transactions as valid and added
/// it to its internal cache.
fn tx_accepted(&self, tx: &transaction::Transaction);
/// The stem transaction pool has accepted this transactions as valid and added
/// it to its internal cache.
fn stem_tx_accepted(&self, tx: &transaction::Transaction);
}
/// Dummy adapter used as a placeholder for real implementations
@@ -174,6 +199,7 @@ pub trait PoolAdapter: Send + Sync {
pub struct NoopAdapter {}
impl PoolAdapter for NoopAdapter {
fn tx_accepted(&self, _: &transaction::Transaction) {}
fn stem_tx_accepted(&self, _: &transaction::Transaction) {}
}
/// Pool contains the elements of the graph that are connected, in full, to
@@ -265,6 +291,39 @@ impl Pool {
}
}
// More relax way for stempool transaction in order to accept scenario such as:
// Parent is in mempool, child is allowed in stempool
//
pub fn add_stempool_transaction(
&mut self,
pool_entry: graph::PoolEntry,
mut blockchain_refs: Vec<graph::Edge>,
pool_refs: Vec<graph::Edge>,
mut new_unspents: Vec<graph::Edge>,
) {
// Removing consumed available_outputs
for new_edge in &pool_refs {
// All of these *can* correspond to an existing unspent
self.available_outputs.remove(&new_edge.output_commitment());
}
// Accounting for consumed blockchain outputs
for new_blockchain_edge in blockchain_refs.drain(..) {
self.consumed_blockchain_outputs
.insert(new_blockchain_edge.output_commitment(), new_blockchain_edge);
}
// Adding the transaction to the vertices list along with internal
// pool edges
self.graph.add_entry(pool_entry, pool_refs);
// Adding the new unspents to the unspent map
for unspent_output in new_unspents.drain(..) {
self.available_outputs
.insert(unspent_output.output_commitment(), unspent_output);
}
}
pub fn update_roots(&mut self) {
self.graph.update_roots()
}