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
+14 -4
View File
@@ -64,17 +64,27 @@ where
Ok(res)
}
pub fn send_partial_tx(url: &str, partial_tx: &PartialTx) -> Result<PartialTx, Error> {
single_send_partial_tx(url, partial_tx)
pub fn send_partial_tx(url: &str, partial_tx: &PartialTx, fluff: bool) -> Result<PartialTx, Error> {
single_send_partial_tx(url, partial_tx, fluff)
}
fn single_send_partial_tx(url: &str, partial_tx: &PartialTx) -> Result<PartialTx, Error> {
fn single_send_partial_tx(
url: &str,
partial_tx: &PartialTx,
fluff: bool,
) -> Result<PartialTx, Error> {
let mut core = reactor::Core::new().context(ErrorKind::Hyper)?;
let client = hyper::Client::new(&core.handle());
// In case we want to do an express send
let mut url_pool = url.to_owned();
if fluff {
url_pool = format!("{}{}", url, "?fluff");
}
let mut req = Request::new(
Method::Post,
url.parse::<hyper::Uri>().context(ErrorKind::Hyper)?,
url_pool.parse::<hyper::Uri>().context(ErrorKind::Hyper)?,
);
req.headers_mut().set(ContentType::json());
let json = serde_json::to_string(&partial_tx).context(ErrorKind::Hyper)?;
+1
View File
@@ -26,6 +26,7 @@ extern crate serde_json;
#[macro_use]
extern crate slog;
extern crate term;
extern crate urlencoded;
extern crate uuid;
extern crate bodyparser;
+19 -1
View File
@@ -30,6 +30,7 @@ use core::{global, ser};
use keychain::{BlindingFactor, Identifier, Keychain};
use types::*;
use util::{secp, to_hex, LOGGER};
use urlencoded::UrlEncodedQuery;
use failure::ResultExt;
/// Dummy wrapper for the hex-encoded serialized transaction.
@@ -158,6 +159,7 @@ fn handle_sender_confirmation(
config: &WalletConfig,
keychain: &Keychain,
partial_tx: &PartialTx,
fluff: bool,
) -> Result<PartialTx, Error> {
let (amount, sender_pub_blinding, sender_pub_nonce, kernel_offset, sender_sig_part, tx) =
read_partial_tx(keychain, partial_tx)?;
@@ -226,7 +228,15 @@ fn handle_sender_confirmation(
let tx_hex = to_hex(ser::ser_vec(&final_tx).unwrap());
let url = format!("{}/v1/pool/push", config.check_node_api_http_addr.as_str());
let url;
if fluff {
url = format!(
"{}/v1/pool/push?fluff",
config.check_node_api_http_addr.as_str()
);
} else {
url = format!("{}/v1/pool/push", config.check_node_api_http_addr.as_str());
}
api::client::post(url.as_str(), &TxWrapper { tx_hex: tx_hex }).context(ErrorKind::Node)?;
// Return what we've actually posted
@@ -255,6 +265,13 @@ impl Handler for WalletReceiver {
fn handle(&self, req: &mut Request) -> IronResult<Response> {
let struct_body = req.get::<bodyparser::Struct<PartialTx>>();
let mut fluff = false;
if let Ok(params) = req.get_ref::<UrlEncodedQuery>() {
if let Some(_) = params.get("fluff") {
fluff = true;
}
}
if let Ok(Some(partial_tx)) = struct_body {
match partial_tx.phase {
PartialTxPhase::SenderInitiation => {
@@ -278,6 +295,7 @@ impl Handler for WalletReceiver {
&self.config,
&self.keychain,
&partial_tx,
fluff,
).map_err(|e| {
error!(LOGGER, "Phase 3 Sender Confirmation -> Problematic partial tx, looks like this: {:?}", partial_tx);
api::Error::Internal(format!(
+3 -2
View File
@@ -40,6 +40,7 @@ pub fn issue_send_tx(
dest: String,
max_outputs: usize,
selection_strategy_is_use_all: bool,
fluff: bool,
) -> Result<(), Error> {
checker::refresh_outputs(config, keychain)?;
@@ -126,7 +127,7 @@ pub fn issue_send_tx(
let url = format!("{}/v1/receive/transaction", &dest);
debug!(LOGGER, "Posting partial transaction to {}", url);
let res = client::send_partial_tx(&url, &partial_tx);
let res = client::send_partial_tx(&url, &partial_tx, fluff);
if let Err(e) = res {
match e.kind() {
ErrorKind::FeeExceedsAmount {
@@ -186,7 +187,7 @@ pub fn issue_send_tx(
partial_tx.phase = PartialTxPhase::SenderConfirmation;
// And send again
let res = client::send_partial_tx(&url, &partial_tx);
let res = client::send_partial_tx(&url, &partial_tx, fluff);
if let Err(e) = res {
match e.kind() {
ErrorKind::FeeExceedsAmount {sender_amount, recipient_fee} =>