From 5987bcde196fad78ebf956099339aa23852e2086 Mon Sep 17 00:00:00 2001 From: Gary Yu Date: Tue, 12 Feb 2019 21:39:43 +0800 Subject: [PATCH] add repost method into wallet owner api (#2553) * add repost method into wallet owner api * rustfmt --- doc/api/wallet_owner_api.md | 45 +++++++++++++++++++ wallet/src/controller.rs | 86 +++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) diff --git a/doc/api/wallet_owner_api.md b/doc/api/wallet_owner_api.md index ab0d92b07..70562de08 100644 --- a/doc/api/wallet_owner_api.md +++ b/doc/api/wallet_owner_api.md @@ -12,6 +12,7 @@ 1. [POST Finalize Tx](#post-finalize-tx) 1. [POST Cancel Tx](#post-cancel-tx) 1. [POST Post Tx](#post-post-tx) + 1. [POST Repost Tx](#post-repost-tx) 1. [POST Issue Burn Tx](#post-issue-burn-tx) 1. [Adding Foreign API Endpoints](#add-foreign-api-endpoints) @@ -641,6 +642,50 @@ Push new transaction to the connected node transaction pool. Add `?fluff` at the }, }); ``` +### POST Repost Tx + +Repost a `sending` transaction to the connected node transaction pool with a given transaction id. Add `?fluff` at the end of the URL to bypass Dandelion relay . This could be used for retry posting when a `sending` transaction is created but somehow failed on posting. + +* **URL** + + * /v1/wallet/owner/repost?id=x + * /v1/wallet/owner/repost?tx_id=x + * /v1/wallet/owner/repost?fluff&tx_id=x + +* **Method:** + + `POST` + +* **URL Params** + + **Required:** + * `id=[number]` the transaction id + * `tx_id=[string]`the transaction slate id + +* **Data Params** + + None + +* **Success Response:** + + * **Code:** 200 + +* **Error Response:** + + * **Code:** 400 + +* **Sample Call:** + + ```javascript + $.ajax({ + url: "/v1/wallet/owner/repost?id=3", + dataType: "json", + type : "POST", + success : function(r) { + console.log(r); + } + }); + ``` ### POST Issue Burn Tx diff --git a/wallet/src/controller.rs b/wallet/src/controller.rs index 1bbf1a268..94cb82614 100644 --- a/wallet/src/controller.rs +++ b/wallet/src/controller.rs @@ -40,6 +40,7 @@ use std::marker::PhantomData; use std::net::SocketAddr; use std::sync::Arc; use url::form_urlencoded; +use uuid::Uuid; /// Instantiate wallet Owner API for a single-use (command line) call /// Return a function containing a loaded API context to call @@ -467,6 +468,87 @@ where )) } + pub fn repost( + &self, + req: Request, + api: APIOwner, + ) -> Box + Send> { + let params = parse_params(&req); + let mut id_int: Option = None; + let mut tx_uuid: Option = None; + + if let Some(id_string) = params.get("id") { + match id_string[0].parse() { + Ok(id) => id_int = Some(id), + Err(e) => { + error!("repost: could not parse id: {}", e); + return Box::new(err(ErrorKind::GenericError( + "repost: cannot repost transaction. Could not parse id in request." + .to_owned(), + ) + .into())); + } + } + } else if let Some(tx_id_string) = params.get("tx_id") { + match tx_id_string[0].parse() { + Ok(tx_id) => tx_uuid = Some(tx_id), + Err(e) => { + error!("repost: could not parse tx_id: {}", e); + return Box::new(err(ErrorKind::GenericError( + "repost: cannot repost transaction. Could not parse tx_id in request." + .to_owned(), + ) + .into())); + } + } + } else { + return Box::new(err(ErrorKind::GenericError( + "repost: Cannot repost transaction. Missing id or tx_id param in request." + .to_owned(), + ) + .into())); + } + + let res = api.retrieve_txs(true, id_int, tx_uuid); + if let Err(e) = res { + return Box::new(err(ErrorKind::GenericError(format!( + "repost: cannot repost transaction. retrieve_txs failed, err: {:?}", + e + )) + .into())); + } + let (_, txs) = res.unwrap(); + let res = api.get_stored_tx(&txs[0]); + if let Err(e) = res { + return Box::new(err(ErrorKind::GenericError(format!( + "repost: cannot repost transaction. get_stored_tx failed, err: {:?}", + e + )) + .into())); + } + let stored_tx = res.unwrap(); + if stored_tx.is_none() { + error!( + "Transaction with id {:?}/{:?} does not have transaction data. Not reposting.", + id_int, tx_uuid, + ); + return Box::new(err(ErrorKind::GenericError( + "repost: Cannot repost transaction. Missing id or tx_id param in request." + .to_owned(), + ) + .into())); + } + + let fluff = params.get("fluff").is_some(); + Box::new(match api.post_tx(&stored_tx.unwrap(), fluff) { + Ok(_) => ok(()), + Err(e) => { + error!("repost: failed with error: {}", e); + err(e) + } + }) + } + fn handle_post_request(&self, req: Request) -> WalletResponseFuture { let api = APIOwner::new(self.wallet.clone()); match req @@ -493,6 +575,10 @@ where self.post_tx(req, api) .and_then(|_| ok(response(StatusCode::OK, "{}"))), ), + "repost" => Box::new( + self.repost(req, api) + .and_then(|_| ok(response(StatusCode::OK, ""))), + ), _ => Box::new(err(ErrorKind::GenericError( "Unknown error handling post request".to_owned(), )