-
Notifications
You must be signed in to change notification settings - Fork 59
feat(client): add async and blocking clients to submit txs package #114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,13 +2,14 @@ | |
//! | ||
//! See: <https://github.com/Blockstream/esplora/blob/master/API.md> | ||
|
||
use std::collections::HashMap; | ||
|
||
pub use bitcoin::consensus::{deserialize, serialize}; | ||
pub use bitcoin::hex::FromHex; | ||
use bitcoin::Weight; | ||
pub use bitcoin::{ | ||
transaction, Amount, BlockHash, OutPoint, ScriptBuf, Transaction, TxIn, TxOut, Txid, Witness, | ||
}; | ||
|
||
use bitcoin::{FeeRate, Weight, Wtxid}; | ||
use serde::Deserialize; | ||
|
||
#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] | ||
|
@@ -123,6 +124,58 @@ pub struct AddressTxsSummary { | |
pub tx_count: u32, | ||
} | ||
|
||
#[derive(Deserialize, Debug)] | ||
pub struct SubmitPackageResult { | ||
/// The transaction package result message. "success" indicates all transactions were accepted | ||
/// into or are already in the mempool. | ||
pub package_msg: String, | ||
/// Transaction results keyed by [`Wtxid`]. | ||
#[serde(rename = "tx-results")] | ||
pub tx_results: HashMap<Wtxid, TxResult>, | ||
/// List of txids of replaced transactions. | ||
#[serde(rename = "replaced-transactions")] | ||
pub replaced_transactions: Option<Vec<Txid>>, | ||
Comment on lines
+132
to
+137
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason not to keep the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bitcoin Core's RPC API is inconsistent in that it mixes snake and dash-case. I assume Esplora just re-exposes the identical field names. |
||
} | ||
|
||
#[derive(Deserialize, Debug)] | ||
pub struct TxResult { | ||
/// The transaction id. | ||
pub txid: Txid, | ||
/// The [`Wtxid`] of a different transaction with the same [`Txid`] but different witness found | ||
/// in the mempool. | ||
/// | ||
/// If set, this means the submitted transaction was ignored. | ||
#[serde(rename = "other-wtxid")] | ||
pub other_wtxid: Option<Wtxid>, | ||
/// Sigops-adjusted virtual transaction size. | ||
pub vsize: Option<u32>, | ||
/// Transaction fees. | ||
pub fees: Option<MempoolFeesSubmitPackage>, | ||
/// The transaction error string, if it was rejected by the mempool | ||
pub error: Option<String>, | ||
} | ||
|
||
#[derive(Deserialize, Debug)] | ||
pub struct MempoolFeesSubmitPackage { | ||
/// Transaction fee. | ||
#[serde(with = "bitcoin::amount::serde::as_btc")] | ||
pub base: Amount, | ||
/// The effective feerate. | ||
/// | ||
/// Will be `None` if the transaction was already in the mempool. For example, the package | ||
/// feerate and/or feerate with modified fees from the `prioritisetransaction` JSON-RPC method. | ||
#[serde( | ||
rename = "effective-feerate", | ||
default, | ||
deserialize_with = "deserialize_feerate" | ||
)] | ||
pub effective_feerate: Option<FeeRate>, | ||
/// If [`Self::effective_fee_rate`] is provided, this holds the [`Wtxid`]s of the transactions | ||
/// whose fees and vsizes are included in effective-feerate. | ||
#[serde(rename = "effective-includes")] | ||
pub effective_includes: Option<Vec<Wtxid>>, | ||
} | ||
|
||
impl Tx { | ||
pub fn to_tx(&self) -> Transaction { | ||
Transaction { | ||
|
@@ -198,3 +251,20 @@ where | |
.collect::<Result<Vec<Vec<u8>>, _>>() | ||
.map_err(serde::de::Error::custom) | ||
} | ||
|
||
fn deserialize_feerate<'de, D>(d: D) -> Result<Option<FeeRate>, D::Error> | ||
where | ||
D: serde::de::Deserializer<'de>, | ||
{ | ||
use serde::de::Error; | ||
|
||
let btc_per_kvb = match Option::<f64>::deserialize(d)? { | ||
Some(v) => v, | ||
None => return Ok(None), | ||
}; | ||
let sat_per_kwu = btc_per_kvb * 25_000_000.0; | ||
if sat_per_kwu.is_infinite() { | ||
return Err(D::Error::custom("feerate overflow")); | ||
} | ||
Ok(Some(FeeRate::from_sat_per_kwu(sat_per_kwu as u64))) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know if the variants here are finite? Do we see a chance to parse this into an
enum
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, that'd be best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i agree that would be best, but as I can see here, there is no enum defined for that field. I'd be happy to update that part as soon as it is upgraded to one there