Skip to content

Commit 648d812

Browse files
authored
Merge pull request #347 from jamillambert/0828-listsinceblock
Test and update `listsinceblock` and `listtransactions`
2 parents 2eb9552 + a07b91c commit 648d812

File tree

33 files changed

+1488
-390
lines changed

33 files changed

+1488
-390
lines changed

integration_test/tests/wallet.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,41 @@ fn wallet__list_received_by_address__modelled() {
593593
assert!(model.0.iter().any(|item| &item.address == unchecked_addr));
594594
}
595595

596+
#[test]
597+
fn wallet__list_since_block__modelled() {
598+
let node = Node::with_wallet(Wallet::Default, &[]);
599+
node.fund_wallet();
600+
let addr = node.client.new_address().expect("newaddress");
601+
let amount = Amount::from_sat(5_000);
602+
node.client.send_to_address(&addr, amount).expect("sendtoaddress");
603+
node.mine_a_block();
604+
605+
let json: ListSinceBlock = node.client.list_since_block().expect("listsinceblock");
606+
let model: Result<mtype::ListSinceBlock, ListSinceBlockError> = json.into_model();
607+
let model = model.unwrap();
608+
609+
let first_tx: mtype::TransactionItem = model.transactions[0].clone();
610+
assert_eq!(first_tx.txid.unwrap().to_string().len(), 64);
611+
}
612+
613+
#[test]
614+
fn wallet__list_transactions__modelled() {
615+
let node = Node::with_wallet(Wallet::Default, &[]);
616+
617+
node.fund_wallet();
618+
let addr = node.client.new_address().expect("newaddress");
619+
let amount = Amount::from_sat(5_000);
620+
node.client.send_to_address(&addr, amount).expect("sendtoaddress");
621+
node.mine_a_block();
622+
623+
let json: ListTransactions = node.client.list_transactions().expect("listtransactions");
624+
let model: Result<mtype::ListTransactions, TransactionItemError> = json.into_model();
625+
let model = model.unwrap();
626+
627+
let first_tx: mtype::TransactionItem = model.0[0].clone();
628+
assert_eq!(first_tx.txid.unwrap().to_string().len(), 64);
629+
}
630+
596631
#[test]
597632
fn wallet__import_multi() {
598633
let node = match () {

types/src/model/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ pub use self::{
5858
GetTransactionDetail, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoScanning, HdKey,
5959
HdKeyDescriptor, LastProcessedBlock, ListAddressGroupings, ListAddressGroupingsItem,
6060
ListLockUnspent, ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem,
61-
ListReceivedByLabel, ListReceivedByLabelItem, ListSinceBlock, ListSinceBlockTransaction,
62-
ListTransactions, ListTransactionsItem, ListUnspent, ListUnspentItem, ListWallets,
63-
LoadWallet, PsbtBumpFee, RescanBlockchain, ScriptType, Send, SendAll, SendMany,
64-
SendManyVerbose, SendToAddress, SignMessage, SimulateRawTransaction, TransactionCategory,
65-
UnloadWallet, WalletCreateFundedPsbt, WalletDisplayAddress, WalletProcessPsbt,
61+
ListReceivedByLabel, ListReceivedByLabelItem, ListSinceBlock, ListTransactions,
62+
ListUnspent, ListUnspentItem, ListWallets, LoadWallet, PsbtBumpFee, RescanBlockchain,
63+
ScriptType, Send, SendAll, SendMany, SendManyVerbose, SendToAddress, SignMessage,
64+
SimulateRawTransaction, TransactionCategory, TransactionItem, UnloadWallet,
65+
WalletCreateFundedPsbt, WalletDisplayAddress, WalletProcessPsbt,
6666
},
6767
};

types/src/model/wallet.rs

Lines changed: 33 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -590,12 +590,12 @@ pub struct ListReceivedByLabelItem {
590590
#[serde(deny_unknown_fields)]
591591
pub struct ListSinceBlock {
592592
/// All the transactions.
593-
pub transactions: Vec<ListSinceBlockTransaction>,
593+
pub transactions: Vec<TransactionItem>,
594594
/// Only present if `include_removed=true`.
595595
///
596596
/// Note: transactions that were re-added in the active chain will appear as-is in this array,
597597
/// and may thus have a positive confirmation count.
598-
pub removed: Vec<ListSinceBlockTransaction>,
598+
pub removed: Vec<TransactionItem>,
599599
/// The hash of the block (target_confirmations-1) from the best block on the main chain.
600600
///
601601
/// This is typically used to feed back into listsinceblock the next time you call it. So you
@@ -604,11 +604,12 @@ pub struct ListSinceBlock {
604604
pub last_block: BlockHash,
605605
}
606606

607-
/// Transaction list item, part of `ListSinceBlock`.
608-
// https://github.com/rust-bitcoin/rust-bitcoin/issues/3516
607+
/// Transaction item, part of `listsinceblock` and `listtransactions`.
609608
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
610609
#[serde(deny_unknown_fields)]
611-
pub struct ListSinceBlockTransaction {
610+
pub struct TransactionItem {
611+
/// Only returns true if imported addresses were involved in transaction.
612+
pub involves_watch_only: Option<bool>,
612613
/// The bitcoin address of the transaction.
613614
pub address: Option<Address<NetworkUnchecked>>,
614615
/// The transaction category.
@@ -631,96 +632,64 @@ pub struct ListSinceBlockTransaction {
631632
/// Available for 'send' and 'receive' category of transactions. When it's < 0, it means the
632633
/// transaction conflicted that many blocks ago.
633634
pub confirmations: i64,
635+
/// Only present if the transaction's only input is a coinbase one. Only documented from v0.20 and later.
636+
pub generated: Option<bool>,
637+
/// Whether we consider the transaction to be trusted and safe to spend from. Only present
638+
/// when the transaction has 0 confirmations (or negative confirmations, if conflicted). v0.20 and later only.
639+
pub trusted: Option<bool>,
634640
/// The block hash containing the transaction.
635641
///
636642
/// Available for 'send' and 'receive' category of transactions.
637-
pub block_hash: BlockHash,
643+
pub block_hash: Option<BlockHash>,
644+
/// The block height containing the transaction. v20 and later only.
645+
pub block_height: Option<u32>,
638646
/// The index of the transaction in the block that includes it.
639647
///
640648
/// Available for 'send' and 'receive' category of transactions.
641-
pub block_index: u32,
649+
pub block_index: Option<u32>,
642650
/// The block time in seconds since epoch (1 Jan 1970 GMT).
643-
pub block_time: u32,
651+
pub block_time: Option<u32>,
644652
/// The transaction id.
645653
///
646654
/// Available for 'send' and 'receive' category of transactions.
647655
pub txid: Option<Txid>,
656+
/// The hash of serialized transaction, including witness data. v24 and later only.
657+
pub wtxid: Option<Txid>,
658+
/// Conflicting transaction ids. Only documented from v0.20 and later.
659+
pub wallet_conflicts: Option<Vec<Txid>>,
660+
/// The txid if this tx was replaced. v23 and later only.
661+
pub replaced_by_txid: Option<Txid>,
662+
/// The txid if this tx replaces one. v23 and later only.
663+
pub replaces_txid: Option<Txid>,
664+
/// Transactions in the mempool that directly conflict with either this transaction or an ancestor transaction. v28 and later only.
665+
pub mempool_conflicts: Option<Vec<Txid>>,
666+
/// If a comment to is associated with the transaction.
667+
pub to: Option<String>,
648668
/// The transaction time in seconds since epoch (Jan 1 1970 GMT).
649669
pub time: u32,
650670
/// The time received in seconds since epoch (Jan 1 1970 GMT).
651671
///
652672
/// Available for 'send' and 'receive' category of transactions.
653673
pub time_received: u32,
674+
/// If a comment is associated with the transaction.
675+
pub comment: Option<String>,
654676
/// Whether this transaction could be replaced due to BIP125 (replace-by-fee);
655677
/// may be unknown for unconfirmed transactions not in the mempool
656678
pub bip125_replaceable: Bip125Replaceable,
679+
/// Only if 'category' is 'received'. List of parent descriptors for the scriptPubKey of this coin. v24 and later only.
680+
pub parent_descriptors: Option<Vec<String>>,
657681
/// If the transaction has been abandoned (inputs are respendable).
658682
///
659683
/// Only available for the 'send' category of transactions.
660684
pub abandoned: Option<bool>,
661-
/// If a comment is associated with the transaction.
662-
pub comment: Option<String>,
663685
/// A comment for the address/transaction, if any.
664686
pub label: Option<String>,
665-
/// If a comment to is associated with the transaction.
666-
pub to: Option<String>,
667687
}
668688

669689
/// Models the result of JSON-RPC method `listtransactions`.
670690
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
671691
#[serde(deny_unknown_fields)]
672-
pub struct ListTransactions(pub Vec<ListTransactionsItem>);
673-
674-
/// Transaction list item, part of `ListTransactions`.
675-
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
676-
#[serde(deny_unknown_fields)]
677-
pub struct ListTransactionsItem {
678-
/// The bitcoin address of the transaction.
679-
pub address: Address<NetworkUnchecked>,
680-
/// The transaction category.
681-
pub category: TransactionCategory,
682-
/// The amount.
683-
///
684-
/// This is negative for the 'send' category, and is positive for the 'receive' category.
685-
#[serde(default, with = "bitcoin::amount::serde::as_btc")]
686-
pub amount: SignedAmount,
687-
/// A comment for the address/transaction, if any.
688-
pub label: Option<String>,
689-
/// The vout value.
690-
pub vout: u32,
691-
/// The amount of the fee in BTC.
692-
///
693-
/// This is negative and only available for the 'send' category of transactions.
694-
#[serde(default, with = "bitcoin::amount::serde::as_btc")]
695-
pub fee: SignedAmount,
696-
/// The number of confirmations for the transaction.
697-
///
698-
/// Negative confirmations indicate the transaction conflicts with the block chain.
699-
pub confirmations: i64,
700-
/// Whether we consider the outputs of this unconfirmed transaction safe to spend.
701-
pub trusted: bool,
702-
/// The block hash containing the transaction.
703-
pub block_hash: BlockHash,
704-
/// The index of the transaction in the block that includes it.
705-
pub block_index: u32,
706-
/// The block time in seconds since epoch (1 Jan 1970 GMT).
707-
pub block_time: u32,
708-
/// The transaction id.
709-
pub txid: Txid,
710-
/// The transaction time in seconds since epoch (Jan 1 1970 GMT).
711-
pub time: u32,
712-
/// The time received in seconds since epoch (Jan 1 1970 GMT).
713-
pub time_received: u32,
714-
/// If a comment is associated with the transaction.
715-
pub comment: Option<String>,
716-
/// Whether this transaction could be replaced due to BIP125 (replace-by-fee);
717-
/// may be unknown for unconfirmed transactions not in the mempool
718-
pub bip125_replaceable: Bip125Replaceable,
719-
/// If the transaction has been abandoned (inputs are respendable).
720-
///
721-
/// Only available for the 'send' category of transactions.
722-
pub abandoned: Option<bool>,
723-
}
692+
pub struct ListTransactions(pub Vec<TransactionItem>);
724693

725694
/// Models the result of JSON-RPC method `listunspent`.
726695
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]

types/src/v17/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@
185185
//! | listlockunspent | version + model | |
186186
//! | listreceivedbyaccount | returns nothing | |
187187
//! | listreceivedbyaddress | version + model | |
188-
//! | listsinceblock | version + model | UNTESTED |
189-
//! | listtransactions | version + model | UNTESTED |
188+
//! | listsinceblock | version + model | |
189+
//! | listtransactions | version + model | |
190190
//! | listunspent | version + model | |
191191
//! | listwallets | version + model | |
192192
//! | loadwallet | version + model | |
@@ -281,10 +281,9 @@ pub use self::{
281281
ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, ListLockUnspent,
282282
ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddress,
283283
ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError,
284-
ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions,
285-
ListTransactionsItem, ListTransactionsItemError, ListUnspent, ListUnspentItem,
286-
ListUnspentItemError, ListWallets, LoadWallet, LockUnspent, RescanBlockchain, ScriptType,
287-
SendMany, SendToAddress, SetTxFee, SignMessage, TransactionCategory,
284+
ListTransactions, ListUnspent, ListUnspentItem, ListUnspentItemError, ListWallets,
285+
LoadWallet, LockUnspent, RescanBlockchain, ScriptType, SendMany, SendToAddress, SetTxFee,
286+
SignMessage, TransactionCategory, TransactionItem, TransactionItemError,
288287
WalletCreateFundedPsbt, WalletCreateFundedPsbtError, WalletProcessPsbt,
289288
},
290289
zmq::GetZmqNotifications,

types/src/v17/wallet/error.rs

Lines changed: 9 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -496,9 +496,9 @@ impl std::error::Error for ListReceivedByAddressError {
496496
#[derive(Debug)]
497497
pub enum ListSinceBlockError {
498498
/// Conversion of item in `transactions` list failed.
499-
Transactions(ListSinceBlockTransactionError),
499+
Transactions(TransactionItemError),
500500
/// Conversion of item in `removed` list failed.
501-
Removed(ListSinceBlockTransactionError),
501+
Removed(TransactionItemError),
502502
/// Conversion of the `last_block` field failed.
503503
LastBlock(hex::HexToArrayError),
504504
}
@@ -529,9 +529,9 @@ impl std::error::Error for ListSinceBlockError {
529529
}
530530
}
531531

532-
/// Error when converting a `ListSinceBlockTransaction` type into the model type.
532+
/// Error when converting a `TransactionItem` type into the model type.
533533
#[derive(Debug)]
534-
pub enum ListSinceBlockTransactionError {
534+
pub enum TransactionItemError {
535535
/// Conversion of numeric type to expected type failed.
536536
Numeric(NumericError),
537537
/// Conversion of the `address` field failed.
@@ -546,9 +546,9 @@ pub enum ListSinceBlockTransactionError {
546546
Txid(hex::HexToArrayError),
547547
}
548548

549-
impl fmt::Display for ListSinceBlockTransactionError {
549+
impl fmt::Display for TransactionItemError {
550550
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
551-
use ListSinceBlockTransactionError as E;
551+
use TransactionItemError as E;
552552

553553
match *self {
554554
E::Numeric(ref e) => write_err!(f, "numeric"; e),
@@ -562,9 +562,9 @@ impl fmt::Display for ListSinceBlockTransactionError {
562562
}
563563

564564
#[cfg(feature = "std")]
565-
impl std::error::Error for ListSinceBlockTransactionError {
565+
impl std::error::Error for TransactionItemError {
566566
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
567-
use ListSinceBlockTransactionError as E;
567+
use TransactionItemError as E;
568568

569569
match *self {
570570
E::Numeric(ref e) => Some(e),
@@ -577,59 +577,7 @@ impl std::error::Error for ListSinceBlockTransactionError {
577577
}
578578
}
579579

580-
impl From<NumericError> for ListSinceBlockTransactionError {
581-
fn from(e: NumericError) -> Self { Self::Numeric(e) }
582-
}
583-
584-
/// Error when converting a `ListTransactionsItem` type into the model type.
585-
#[derive(Debug)]
586-
pub enum ListTransactionsItemError {
587-
/// Conversion of numeric type to expected type failed.
588-
Numeric(NumericError),
589-
/// Conversion of the `address` field failed.
590-
Address(address::ParseError),
591-
/// Conversion of the `amount` field failed.
592-
Amount(ParseAmountError),
593-
/// Conversion of the `fee` field failed.
594-
Fee(ParseAmountError),
595-
/// Conversion of the `block_hash` field failed.
596-
BlockHash(hex::HexToArrayError),
597-
/// Conversion of the `txid` field failed.
598-
Txid(hex::HexToArrayError),
599-
}
600-
601-
impl fmt::Display for ListTransactionsItemError {
602-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
603-
use ListTransactionsItemError as E;
604-
605-
match *self {
606-
E::Numeric(ref e) => write_err!(f, "numeric"; e),
607-
E::Address(ref e) => write_err!(f, "conversion of the `address` field failed"; e),
608-
E::Amount(ref e) => write_err!(f, "conversion of the `amount` field failed"; e),
609-
E::Fee(ref e) => write_err!(f, "conversion of the `fee` field failed"; e),
610-
E::BlockHash(ref e) => write_err!(f, "conversion of the `block_hash` field failed"; e),
611-
E::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e),
612-
}
613-
}
614-
}
615-
616-
#[cfg(feature = "std")]
617-
impl std::error::Error for ListTransactionsItemError {
618-
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
619-
use ListTransactionsItemError as E;
620-
621-
match *self {
622-
E::Numeric(ref e) => Some(e),
623-
E::Address(ref e) => Some(e),
624-
E::Amount(ref e) => Some(e),
625-
E::Fee(ref e) => Some(e),
626-
E::BlockHash(ref e) => Some(e),
627-
E::Txid(ref e) => Some(e),
628-
}
629-
}
630-
}
631-
632-
impl From<NumericError> for ListTransactionsItemError {
580+
impl From<NumericError> for TransactionItemError {
633581
fn from(e: NumericError) -> Self { Self::Numeric(e) }
634582
}
635583

0 commit comments

Comments
 (0)