Skip to content

Commit 88db7fe

Browse files
author
+Sharon
committed
Add DecodeScriptSegwit struct, conversions, and model support
- Add `DecodeScriptSegwit` struct to both versioned and model representations. - Implement `into_model()` for `DecodeScriptSegwit` and update `DecodeScript` accordingly. - Use `ScriptBuf` instead of `String` for `hex` to strongly type the field. - Replace `String` with `Address<NetworkUnchecked>` for `p2sh_segwit` and other fields. - Normalize and correct field comments to match Core `decodescript` RPC output. - Clean up formatting errors
1 parent 9a10ba4 commit 88db7fe

File tree

11 files changed

+73
-82
lines changed

11 files changed

+73
-82
lines changed

types/src/model/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ pub use self::{
4141
raw_transactions::{
4242
AnalyzePsbt, AnalyzePsbtInput, AnalyzePsbtInputMissing, CombinePsbt, CombineRawTransaction,
4343
ConvertToPsbt, CreatePsbt, CreateRawTransaction, DecodePsbt, DecodeRawTransaction,
44-
DecodeScript,DecodeScriptSegwit, DescriptorProcessPsbt, FinalizePsbt, FundRawTransaction, GetRawTransaction,
45-
GetRawTransactionVerbose, JoinPsbts, MempoolAcceptance, SendRawTransaction, SignFail,
46-
SignRawTransaction, SubmitPackage, SubmitPackageTxResult, SubmitPackageTxResultFees,
47-
TestMempoolAccept, UtxoUpdatePsbt,
44+
DecodeScript, DecodeScriptSegwit, DescriptorProcessPsbt, FinalizePsbt, FundRawTransaction,
45+
GetRawTransaction, GetRawTransactionVerbose, JoinPsbts, MempoolAcceptance,
46+
SendRawTransaction, SignFail, SignRawTransaction, SubmitPackage, SubmitPackageTxResult,
47+
SubmitPackageTxResultFees, TestMempoolAccept, UtxoUpdatePsbt,
4848
},
4949
util::{
5050
CreateMultisig, DeriveAddresses, EstimateSmartFee, SignMessageWithPrivKey, ValidateAddress,

types/src/model/raw_transactions.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,30 +116,31 @@ pub struct DecodeScript {
116116
pub addresses: Vec<Address<NetworkUnchecked>>,
117117
/// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).
118118
pub p2sh: Option<Address<NetworkUnchecked>>,
119-
/// Segwit data (see `DecodeScriptSegwit` for explanation).
119+
/// Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped).
120120
pub segwit: Option<DecodeScriptSegwit>,
121-
/// Address of the P2SH script wrapping this witness redeem script
122-
pub p2sh_segwit: Option<String>,
123-
121+
/// Address of the P2SH script wrapping this witness redeem script.
122+
pub p2sh_segwit: Option<Address<NetworkUnchecked>>,
124123
}
125124
/// Models the `segwit` field returned by the `decodescript` RPC.
126125
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
127126
#[serde(deny_unknown_fields)]
128127
pub struct DecodeScriptSegwit {
129-
/// The witness program.
128+
/// Disassembly of the script.
130129
pub asm: String,
131-
/// Hex-encoded script.
132-
pub hex: String,
133-
/// The output type.
130+
/// The raw output script bytes, hex-encoded.
131+
pub hex: ScriptBuf,
132+
/// Inferred descriptor for the script. v23 and later only.
133+
pub descriptor: Option<String>,
134+
/// The output type (e.g. nonstandard, anchor, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_scripthash, witness_v0_keyhash, witness_v1_taproot, witness_unknown).
134135
pub type_: String,
135-
/// Bitcoin address (only if a well-defined address exists).
136+
/// Bitcoin address (only if a well-defined address exists)v22 and later only.
136137
pub address: Option<Address<NetworkUnchecked>>,
137138
/// The required signatures.
138139
pub required_signatures: Option<u64>,
139140
/// List of bitcoin addresses.
140141
pub addresses: Vec<Address<NetworkUnchecked>>,
141142
/// Address of the P2SH script wrapping this witness redeem script.
142-
pub p2sh_segwit: Option<String>,
143+
pub p2sh_segwit: Option<Address<NetworkUnchecked>>,
143144
}
144145

145146
/// Models the result of JSON-RPC method `descriptorprocesspsbt`.

types/src/v17/raw_transactions/mod.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ mod into;
99

1010
use std::collections::HashMap;
1111

12+
use bitcoin::address::{Address, NetworkUnchecked};
13+
use bitcoin::ScriptBuf;
1214
use serde::{Deserialize, Serialize};
1315

1416
use crate::ScriptSig;
@@ -213,11 +215,11 @@ pub struct DecodeRawTransaction(pub RawTransaction);
213215
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
214216
#[serde(deny_unknown_fields)]
215217
pub struct DecodeScript {
216-
/// Script public key.
218+
/// Disassembly of the script.
217219
pub asm: String,
218-
/// Hex encoded public key.
220+
/// The raw output script bytes, hex-encoded.
219221
pub hex: Option<String>,
220-
/// The output type.
222+
/// The type of the output script (e.g. witness_v0_keyhash or witness_v0_scripthash).
221223
#[serde(rename = "type")]
222224
pub type_: String,
223225
/// The required signatures.
@@ -227,33 +229,33 @@ pub struct DecodeScript {
227229
pub addresses: Option<Vec<String>>,
228230
/// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).
229231
pub p2sh: Option<String>,
230-
/// Segwit data (see `DecodeScriptSegwit` for explanation).
232+
/// Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped).
231233
pub segwit: Option<DecodeScriptSegwit>,
232234
/// Address of the P2SH script wrapping this witness redeem script
233235
#[serde(rename = "p2sh-segwit")]
234-
pub p2sh_segwit: Option<String>,
236+
pub p2sh_segwit: Option<Address<NetworkUnchecked>>,
235237
}
236238

237239
/// Seemingly undocumented data returned in the `segwit` field of `DecodeScript`.
238240
// This seems to be the same as `DecodeScript` except the `p2sh` field is called `p2sh-segwit`.
239241
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
240242
#[serde(deny_unknown_fields)]
241243
pub struct DecodeScriptSegwit {
242-
/// Script public key.
244+
/// Disassembly of the script.
243245
pub asm: String,
244-
/// Hex encoded public key.
245-
pub hex: String,
246-
/// The output type.
246+
/// The raw output script bytes, hex-encoded.
247+
pub hex: ScriptBuf,
248+
/// The type of the output script (e.g. witness_v0_keyhash or witness_v0_scripthash).
247249
#[serde(rename = "type")]
248250
pub type_: String,
249251
/// The required signatures.
250252
#[serde(rename = "reqSigs")]
251253
pub required_signatures: Option<u64>,
252254
/// List of bitcoin addresses.
253255
pub addresses: Option<Vec<String>>,
254-
/// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).
256+
/// Address of the P2SH script wrapping this witness redeem script.
255257
#[serde(rename = "p2sh-segwit")]
256-
pub p2sh_segtwit: Option<String>,
258+
pub p2sh_segtwit: Option<Address<NetworkUnchecked>>,
257259
}
258260

259261
/// Result of JSON-RPC method `finalizepsbt`.

types/src/v22/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,9 @@ pub use self::{
253253
blockchain::GetMempoolInfo,
254254
control::Logging,
255255
network::{Banned, GetPeerInfo, ListBanned},
256-
raw_transactions::{DecodeScript, DecodeScriptError,DecodeScriptSegwit,DecodeScriptSegwitError},
256+
raw_transactions::{
257+
DecodeScript, DecodeScriptError, DecodeScriptSegwit, DecodeScriptSegwitError,
258+
},
257259
};
258260
#[doc(inline)]
259261
pub use crate::{

types/src/v22/raw_transactions/error.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ pub enum DecodeScriptError {
1919
Segwit(DecodeScriptSegwitError),
2020
/// Conversion of the transaction `p2sh` field failed.
2121
P2sh(address::ParseError),
22-
2322
}
2423

2524
impl fmt::Display for DecodeScriptError {
@@ -54,8 +53,6 @@ impl std::error::Error for DecodeScriptError {
5453
/// Error when converting a `DecodeScriptSegwit` type into the model type.
5554
#[derive(Debug)]
5655
pub enum DecodeScriptSegwitError {
57-
/// An invalid or missing field in the `DecodeScriptSegwit` data.
58-
InvalidField(&'static str),
5956
/// Conversion of the transaction `address` field failed.
6057
Address(address::ParseError),
6158
/// Conversion of the transaction `addresses` field failed.
@@ -65,10 +62,7 @@ pub enum DecodeScriptSegwitError {
6562
impl fmt::Display for DecodeScriptSegwitError {
6663
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6764
use DecodeScriptSegwitError as E;
68-
6965
match *self {
70-
E::InvalidField(name) =>
71-
write!(f, "conversion of the `segwit` field failed: invalid or missing field `{}`", name),
7266
E::Address(ref e) =>
7367
write_err!(f, "conversion of the `address` field in `segwit` failed"; e),
7468
E::Addresses(ref e) =>
@@ -81,13 +75,9 @@ impl fmt::Display for DecodeScriptSegwitError {
8175
impl std::error::Error for DecodeScriptSegwitError {
8276
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
8377
use DecodeScriptSegwitError as E;
84-
8578
match *self {
86-
E::InvalidField(_) => None,
8779
E::Address(ref e) => Some(e),
8880
E::Addresses(ref e) => Some(e),
8981
}
9082
}
9183
}
92-
93-

types/src/v22/raw_transactions/into.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
use bitcoin::Address;
44

5-
use super::{DecodeScript, DecodeScriptError, DecodeScriptSegwit, DecodeScriptSegwitError};
6-
5+
use super::{DecodeScript, DecodeScriptError, DecodeScriptSegwit, DecodeScriptSegwitError};
76
use crate::model;
87

98
impl DecodeScript {
@@ -24,7 +23,7 @@ impl DecodeScript {
2423
None => vec![],
2524
};
2625
let p2sh = self.p2sh.map(|s| s.parse::<Address<_>>()).transpose().map_err(E::P2sh)?;
27-
26+
2827
Ok(model::DecodeScript {
2928
script_pubkey: None,
3029
type_: self.type_,
@@ -35,7 +34,6 @@ impl DecodeScript {
3534
p2sh,
3635
segwit: self.segwit.map(|s| s.into_model()).transpose().map_err(E::Segwit)?,
3736
p2sh_segwit: self.p2sh_segwit,
38-
3937
})
4038
}
4139
}
@@ -65,12 +63,12 @@ impl DecodeScriptSegwit {
6563
Ok(model::DecodeScriptSegwit {
6664
asm: self.asm,
6765
hex: self.hex,
66+
descriptor: None,
6867
type_: self.type_,
6968
address,
7069
required_signatures,
7170
addresses,
7271
p2sh_segwit,
7372
})
74-
7573
}
7674
}

types/src/v22/raw_transactions/mod.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
mod error;
88
mod into;
99

10+
use bitcoin::address::{Address, NetworkUnchecked};
11+
use bitcoin::ScriptBuf;
1012
use serde::{Deserialize, Serialize};
1113

12-
pub use self::error::{DecodeScriptError,DecodeScriptSegwitError};
14+
pub use self::error::{DecodeScriptError, DecodeScriptSegwitError};
1315

1416
/// Result of JSON-RPC method `decodescript`.
1517
///
@@ -23,9 +25,9 @@ pub use self::error::{DecodeScriptError,DecodeScriptSegwitError};
2325
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
2426
#[serde(deny_unknown_fields)]
2527
pub struct DecodeScript {
26-
/// Script public key.
28+
/// Disassembly of the script.
2729
pub asm: String,
28-
/// The output type.
30+
/// The output type (e.g. nonstandard, anchor, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_scripthash, witness_v0_keyhash, witness_v1_taproot, witness_unknown).
2931
#[serde(rename = "type")]
3032
pub type_: String,
3133
/// Bitcoin address (only if a well-defined address exists). v22 and later only.
@@ -37,22 +39,22 @@ pub struct DecodeScript {
3739
pub addresses: Option<Vec<String>>,
3840
/// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).
3941
pub p2sh: Option<String>,
40-
/// Segwit data (see `DecodeScriptSegwit` for explanation).
42+
/// Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped).
4143
pub segwit: Option<DecodeScriptSegwit>,
4244
/// Address of the P2SH script wrapping this witness redeem script
4345
#[serde(rename = "p2sh-segwit")]
44-
pub p2sh_segwit: Option<String>,
46+
pub p2sh_segwit: Option<Address<NetworkUnchecked>>,
4547
}
4648

4749
/// `segwit` item returned as part of `decodescript`.
4850
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
4951
#[serde(deny_unknown_fields)]
5052
pub struct DecodeScriptSegwit {
51-
/// Script public key.
53+
/// Disassembly of the script.
5254
pub asm: String,
53-
/// Hex encoded public key.
54-
pub hex: String,
55-
/// The output type.
55+
/// The raw output script bytes, hex-encoded.
56+
pub hex: ScriptBuf,
57+
/// The output type (e.g. nonstandard, anchor, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_scripthash, witness_v0_keyhash, witness_v1_taproot, witness_unknown).
5658
#[serde(rename = "type")]
5759
pub type_: String,
5860
/// Bitcoin address (only if a well-defined address exists). v22 and later only.
@@ -62,7 +64,7 @@ pub struct DecodeScriptSegwit {
6264
pub required_signatures: Option<u64>,
6365
/// List of bitcoin addresses.
6466
pub addresses: Option<Vec<String>>,
65-
/// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).
67+
/// Address of the P2SH script wrapping this witness redeem script.
6668
#[serde(rename = "p2sh-segwit")]
67-
pub p2sh_segwit: Option<String>,
69+
pub p2sh_segwit: Option<Address<NetworkUnchecked>>,
6870
}

types/src/v23/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,8 @@ pub use self::{
249249
control::Logging,
250250
network::GetPeerInfo,
251251
raw_transactions::{
252-
DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, GlobalXpub, Proprietary,
253-
PsbtInput, PsbtOutput,DecodeScriptSegwit,DecodeScriptSegwitError
252+
DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, DecodeScriptSegwit,
253+
DecodeScriptSegwitError, GlobalXpub, Proprietary, PsbtInput, PsbtOutput,
254254
},
255255
util::CreateMultisig,
256256
wallet::{GetTransaction, GetTransactionError},

types/src/v23/raw_transactions/error.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ pub enum DecodeScriptSegwitError {
312312
impl fmt::Display for DecodeScriptSegwitError {
313313
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
314314
use DecodeScriptSegwitError as E;
315-
316315
match *self {
317316
E::Address(ref e) =>
318317
write_err!(f, "conversion of the `address` field in `segwit` failed"; e),
@@ -326,7 +325,6 @@ impl fmt::Display for DecodeScriptSegwitError {
326325
impl std::error::Error for DecodeScriptSegwitError {
327326
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
328327
use DecodeScriptSegwitError as E;
329-
330328
match *self {
331329
E::Address(ref e) => Some(e),
332330
E::Addresses(ref e) => Some(e),

types/src/v23/raw_transactions/into.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ use bitcoin::psbt::{self, raw, PsbtSighashType};
99
use bitcoin::{Address, Amount};
1010

1111
use super::{
12-
DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, GlobalXpub, GlobalXpubError,
13-
Proprietary, PsbtInput, PsbtInputError, PsbtOutput, PsbtOutputError,DecodeScriptSegwit,
14-
DecodeScriptSegwitError,
12+
DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, DecodeScriptSegwit,
13+
DecodeScriptSegwitError, GlobalXpub, GlobalXpubError, Proprietary, PsbtInput, PsbtInputError,
14+
PsbtOutput, PsbtOutputError,
1515
};
16-
1716
use crate::model;
1817

1918
impl DecodePsbt {
@@ -326,10 +325,8 @@ impl DecodeScript {
326325
.map_err(E::Addresses)?,
327326
None => vec![],
328327
};
329-
330-
331328
let p2sh = self.p2sh.map(|s| s.parse::<Address<_>>()).transpose().map_err(E::P2sh)?;
332-
329+
333330
Ok(model::DecodeScript {
334331
script_pubkey: None,
335332
type_: self.type_,
@@ -340,7 +337,6 @@ impl DecodeScript {
340337
p2sh,
341338
segwit: self.segwit.map(|s| s.into_model()).transpose().map_err(E::Segwit)?,
342339
p2sh_segwit: self.p2sh_segwit,
343-
344340
})
345341
}
346342
}
@@ -353,7 +349,6 @@ impl DecodeScriptSegwit {
353349
Some(addr) => Some(addr.parse::<Address<_>>().map_err(E::Address)?),
354350
None => None,
355351
};
356-
357352
let addresses = match self.addresses {
358353
Some(addrs) => addrs
359354
.into_iter()
@@ -362,16 +357,18 @@ impl DecodeScriptSegwit {
362357
.map_err(E::Addresses)?,
363358
None => vec![],
364359
};
360+
let required_signatures = self.required_signatures;
361+
let p2sh_segwit = self.p2sh_segwit;
365362

366363
Ok(model::DecodeScriptSegwit {
367364
asm: self.asm,
368365
hex: self.hex,
366+
descriptor: self.descriptor,
369367
type_: self.type_,
370368
address,
371-
required_signatures: self.required_signatures,
369+
required_signatures,
372370
addresses,
373-
p2sh_segwit: self.p2sh_segwit,
371+
p2sh_segwit,
374372
})
375373
}
376374
}
377-

0 commit comments

Comments
 (0)