5
5
//! Types for methods found under the `== Rawtransactions ==` section of the API docs.
6
6
7
7
use std:: collections:: HashMap ;
8
+ use std:: str:: FromStr ;
8
9
9
10
use bitcoin:: { Amount , FeeRate , Txid , Wtxid } ;
10
11
use serde:: { Deserialize , Serialize } ;
11
12
12
- use crate :: model;
13
+ use crate :: model:: { self , SubmitPackageError } ;
13
14
14
15
/// Result of JSON-RPC method `submitpackage`.
15
16
//submitpackage ["rawtx",...] ( maxfeerate maxburnamount )
@@ -70,20 +71,33 @@ pub struct SubmitPackage {
70
71
pub package_msg : String ,
71
72
/// Transaction results keyed by [`Wtxid`].
72
73
#[ serde( rename = "tx-results" ) ]
73
- pub tx_results : HashMap < Wtxid , SubmitPackageTxResult > ,
74
+ pub tx_results : HashMap < String , SubmitPackageTxResult > ,
74
75
/// List of txids of replaced transactions.
75
76
#[ serde( rename = "replaced-transactions" ) ]
76
- pub replaced_transactions : Vec < Txid > ,
77
+ pub replaced_transactions : Vec < String > ,
77
78
}
78
79
79
80
impl SubmitPackage {
80
81
/// Converts version specific type to a version in-specific, more strongly typed type.
81
- pub fn into_model ( self ) -> model:: SubmitPackage {
82
- model:: SubmitPackage {
83
- package_msg : self . package_msg ,
84
- tx_results : self . tx_results . into_iter ( ) . map ( |( k, v) | ( k, v. into_model ( ) ) ) . collect ( ) ,
85
- replaced_transactions : self . replaced_transactions ,
82
+ pub fn into_model ( self ) -> Result < model:: SubmitPackage , model:: SubmitPackageError > {
83
+ let mut tx_results = HashMap :: with_capacity ( self . tx_results . len ( ) ) ;
84
+ for ( k, v) in self . tx_results {
85
+ let wtxid = Wtxid :: from_str ( & k) . map_err ( model:: SubmitPackageError :: Wtxid ) ?;
86
+ let result = v. into_model ( ) ?;
87
+ tx_results. insert ( wtxid, result) ;
88
+ }
89
+
90
+ let mut replaced_transactions = Vec :: with_capacity ( self . replaced_transactions . len ( ) ) ;
91
+ for t in self . replaced_transactions {
92
+ let txid = Txid :: from_str ( & t) . map_err ( model:: SubmitPackageError :: Txid ) ?;
93
+ replaced_transactions. push ( txid) ;
86
94
}
95
+
96
+ Ok ( model:: SubmitPackage {
97
+ package_msg : self . package_msg ,
98
+ tx_results,
99
+ replaced_transactions,
100
+ } )
87
101
}
88
102
}
89
103
@@ -96,9 +110,9 @@ pub struct SubmitPackageTxResult {
96
110
///
97
111
/// If set, this means the submitted transaction was ignored.
98
112
#[ serde( rename = "other-wtxid" ) ]
99
- pub other_wtxid : Option < Wtxid > ,
113
+ pub other_wtxid : Option < String > ,
100
114
/// Sigops-adjusted virtual transaction size.
101
- pub vsize : Option < usize > ,
115
+ pub vsize : Option < i64 > ,
102
116
/// Transaction fees.
103
117
pub fees : Option < SubmitPackageTxResultFees > ,
104
118
/// The transaction error string, if it was rejected by the mempool
@@ -107,14 +121,26 @@ pub struct SubmitPackageTxResult {
107
121
108
122
impl SubmitPackageTxResult {
109
123
/// Converts version specific type to a version in-specific, more strongly typed type.
110
- pub fn into_model ( self ) -> model:: SubmitPackageTxResult {
111
- model:: SubmitPackageTxResult {
124
+ pub fn into_model ( self ) -> Result < model:: SubmitPackageTxResult , model:: SubmitPackageError > {
125
+ let other_wtxid = if let Some ( other_wtxid) = self . other_wtxid {
126
+ Some ( Wtxid :: from_str ( & other_wtxid) . map_err ( SubmitPackageError :: Wtxid ) ?)
127
+ } else {
128
+ None
129
+ } ;
130
+
131
+ let vsize = if let Some ( vsize) = self . vsize {
132
+ Some ( vsize. try_into ( ) . map_err ( |_| SubmitPackageError :: Vsize ) ?)
133
+ } else {
134
+ None
135
+ } ;
136
+ let fees = if let Some ( fees) = self . fees { Some ( fees. into_model ( ) ?) } else { None } ;
137
+ Ok ( model:: SubmitPackageTxResult {
112
138
txid : self . txid ,
113
- other_wtxid : self . other_wtxid ,
114
- vsize : self . vsize ,
115
- fees : self . fees . map ( move |f| f . into_model ( ) ) ,
139
+ other_wtxid,
140
+ vsize,
141
+ fees,
116
142
error : self . error ,
117
- }
143
+ } )
118
144
}
119
145
}
120
146
@@ -123,27 +149,41 @@ impl SubmitPackageTxResult {
123
149
pub struct SubmitPackageTxResultFees {
124
150
/// Transaction fee.
125
151
#[ serde( rename = "base" ) ]
126
- pub base_fee : Amount ,
152
+ pub base_fee : f64 ,
127
153
/// The effective feerate.
128
154
///
129
155
/// Will be `None` if the transaction was already in the mempool.
130
156
///
131
157
/// For example, the package feerate and/or feerate with modified fees from the `prioritisetransaction` JSON-RPC method.
132
158
#[ serde( rename = "effective-feerate" ) ]
133
- pub effective_feerate : Option < FeeRate > ,
159
+ pub effective_feerate : Option < f64 > ,
134
160
/// If [`Self::effective_feerate`] is provided, this holds the [`Wtxid`]s of the transactions
135
161
/// whose fees and vsizes are included in effective-feerate.
136
162
#[ serde( rename = "effective-includes" ) ]
137
- pub effective_includes : Vec < Wtxid > ,
163
+ pub effective_includes : Vec < String > ,
138
164
}
139
165
140
166
impl SubmitPackageTxResultFees {
141
167
/// Converts version specific type to a version in-specific, more strongly typed type.
142
- pub fn into_model ( self ) -> model:: SubmitPackageTxResultFees {
143
- model :: SubmitPackageTxResultFees {
144
- base_fee : self . base_fee ,
145
- effective_feerate : self . effective_feerate ,
146
- effective_includes : self . effective_includes ,
168
+ pub fn into_model ( self ) -> Result < model:: SubmitPackageTxResultFees , model :: SubmitPackageError > {
169
+ let mut effective_includes = Vec :: with_capacity ( self . effective_includes . len ( ) ) ;
170
+ for include in self . effective_includes {
171
+ let wtxid = Wtxid :: from_str ( & include ) . map_err ( SubmitPackageError :: Wtxid ) ? ;
172
+ effective_includes. push ( wtxid ) ;
147
173
}
174
+
175
+ let effective_feerate = self . effective_feerate . map ( |rate_btc_kvb| {
176
+ // Bitcoin Core gives us a feerate in BTC/KvB.
177
+ // Thus, we multiply by 25_000_000 (10^8 / 4) to get satoshis/kwu.
178
+ let fee_rate_sat_per_kwu = ( rate_btc_kvb * 25_000_000.0 ) . round ( ) as u64 ;
179
+ FeeRate :: from_sat_per_kwu ( fee_rate_sat_per_kwu)
180
+ } ) ;
181
+
182
+ Ok ( model:: SubmitPackageTxResultFees {
183
+ base_fee : Amount :: from_btc ( self . base_fee )
184
+ . map_err ( model:: SubmitPackageError :: BaseFee ) ?,
185
+ effective_feerate,
186
+ effective_includes,
187
+ } )
148
188
}
149
189
}
0 commit comments