Skip to content

Commit 2eb9552

Browse files
committed
Merge #345: Test and update getwalletinfo
e15aee7 Test and update getwalletinfo (Jamil Lambert, PhD) Pull request description: `getwalletinfo` was implemented for v17 only and untested. There are return changes in v18, v19, v21, v23 and v26. - Add the updated structs in all versions, update the model and add new `into_model()`. - Add a test with version specific sections to test the new sub-structs. - Update the types tables and reexports. ACKs for top commit: tcharding: ACK e15aee7 Tree-SHA512: f4dee1f7c60e82ea1eb7cef257a3198f4ac1dcadbbd74e2dabdfe4a8fb2695313c8ffb96b16ad23e7fcf3aaed48de1d5076e0b03860e21a4e97bb1251a156732
2 parents 22b1a75 + e15aee7 commit 2eb9552

File tree

29 files changed

+871
-170
lines changed

29 files changed

+871
-170
lines changed

integration_test/tests/wallet.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,31 @@ fn wallet__get_unconfirmed_balance__modelled() {
390390
model.unwrap();
391391
}
392392

393+
#[test]
394+
fn wallet__get_wallet_info__modelled() {
395+
let node = Node::with_wallet(Wallet::Default, &[]);
396+
node.mine_a_block();
397+
398+
let json: GetWalletInfo = node.client.get_wallet_info().expect("getwalletinfo");
399+
let model: Result<mtype::GetWalletInfo, GetWalletInfoError> = json.into_model();
400+
let wallet_info = model.unwrap();
401+
402+
assert!(!wallet_info.wallet_name.is_empty());
403+
404+
#[cfg(not(feature = "v18_and_below"))]
405+
{
406+
assert!(wallet_info.avoid_reuse.is_some());
407+
assert!(wallet_info.scanning.is_some());
408+
}
409+
410+
#[cfg(not(feature = "v25_and_below"))]
411+
{
412+
let last_processed = wallet_info.last_processed_block.as_ref().expect("last_processed_block");
413+
let best_hash = node.client.best_block_hash().expect("best_block_hash");
414+
assert_eq!(last_processed.hash, best_hash);
415+
}
416+
}
417+
393418
#[test]
394419
fn wallet__import_address() {
395420
let node = match () {

types/src/model/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ pub use self::{
5555
CreateWallet, DumpPrivKey, GetAddressInfo, GetAddressInfoEmbedded, GetAddressesByLabel,
5656
GetBalance, GetBalances, GetBalancesMine, GetBalancesWatchOnly, GetHdKeys, GetNewAddress,
5757
GetRawChangeAddress, GetReceivedByAddress, GetReceivedByLabel, GetTransaction,
58-
GetTransactionDetail, GetUnconfirmedBalance, GetWalletInfo, HdKey, HdKeyDescriptor,
59-
LastProcessedBlock, ListAddressGroupings, ListAddressGroupingsItem, ListLockUnspent,
60-
ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListReceivedByLabel,
61-
ListReceivedByLabelItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions,
62-
ListTransactionsItem, ListUnspent, ListUnspentItem, ListWallets, LoadWallet, PsbtBumpFee,
63-
RescanBlockchain, ScriptType, Send, SendAll, SendMany, SendManyVerbose, SendToAddress,
64-
SignMessage, SimulateRawTransaction, TransactionCategory, UnloadWallet,
65-
WalletCreateFundedPsbt, WalletDisplayAddress, WalletProcessPsbt,
58+
GetTransactionDetail, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoScanning, HdKey,
59+
HdKeyDescriptor, LastProcessedBlock, ListAddressGroupings, ListAddressGroupingsItem,
60+
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,
6666
},
6767
};

types/src/model/wallet.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,8 @@ pub struct GetWalletInfo {
455455
pub wallet_name: String,
456456
/// The wallet version.
457457
pub wallet_version: u32,
458+
/// Database format. v21 and later only.
459+
pub format: Option<String>,
458460
/// The total confirmed balance of the wallet in BTC.
459461
pub balance: Amount,
460462
/// The total unconfirmed balance of the wallet in BTC.
@@ -472,13 +474,40 @@ pub struct GetWalletInfo {
472474
pub keypool_size_hd_internal: u32,
473475
/// The timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked
474476
/// for transfers, or 0 if the wallet is locked.
475-
pub unlocked_until: u32,
477+
pub unlocked_until: Option<u32>,
476478
/// The transaction fee configuration.
477479
pub pay_tx_fee: Option<FeeRate>,
478480
/// The Hash160 of the HD seed (only present when HD is enabled).
479481
pub hd_seed_id: Option<hash160::Hash>,
480482
/// If privatekeys are disabled for this wallet (enforced watch-only wallet).
481483
pub private_keys_enabled: bool,
484+
/// Whether this wallet tracks clean/dirty coins in terms of reuse. v19 and later only.
485+
pub avoid_reuse: Option<bool>,
486+
/// Current scanning details, or false if no scan is in progress. v19 and later only.
487+
pub scanning: Option<GetWalletInfoScanning>,
488+
/// Whether wallet uses descriptors. v21 and later only.
489+
pub descriptors: Option<bool>,
490+
/// Whether this wallet is configured to use an external signer such as a hardware wallet. v23 and later only.
491+
pub external_signer: Option<bool>,
492+
/// Whether this wallet intentionally does not contain any keys, scripts, or descriptors. v26 and later only.
493+
pub blank: Option<bool>,
494+
/// The start time for blocks scanning. v26 and later only.
495+
pub birthtime: Option<u32>,
496+
/// Hash and height of the block this information was generated on. v26 and later only.
497+
pub last_processed_block: Option<LastProcessedBlock>,
498+
}
499+
500+
/// Models the `scanning` field of `getwalletinfo` (v19+). When not scanning Core returns `false`.
501+
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
502+
#[serde(untagged)]
503+
pub enum GetWalletInfoScanning {
504+
Details {
505+
/// Elapsed seconds since scan start.
506+
duration: u64,
507+
/// Scanning progress percentage [0.0, 1.0].
508+
progress: f64,
509+
},
510+
NotScanning(bool),
482511
}
483512

484513
/// Models the result of JSON-RPC method `listaddressgroupings`.

types/src/v17/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
//! | getreceivedbyaddress | version + model | |
172172
//! | gettransaction | version + model | |
173173
//! | getunconfirmedbalance | version + model | |
174-
//! | getwalletinfo | version + model | UNTESTED |
174+
//! | getwalletinfo | version + model | |
175175
//! | importaddress | returns nothing | |
176176
//! | importmulti | version | |
177177
//! | importprivkey | returns nothing | |

types/src/v17/wallet/into.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ impl GetWalletInfo {
437437
Ok(model::GetWalletInfo {
438438
wallet_name: self.wallet_name,
439439
wallet_version,
440+
format: None,
440441
balance,
441442
unconfirmed_balance,
442443
immature_balance,
@@ -448,6 +449,13 @@ impl GetWalletInfo {
448449
pay_tx_fee,
449450
hd_seed_id,
450451
private_keys_enabled: self.private_keys_enabled,
452+
avoid_reuse: None,
453+
scanning: None,
454+
descriptors: None,
455+
external_signer: None,
456+
blank: None,
457+
birthtime: None,
458+
last_processed_block: None,
451459
})
452460
}
453461
}

types/src/v17/wallet/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ pub struct GetWalletInfo {
549549
pub keypool_size_hd_internal: i64,
550550
/// The timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked
551551
/// for transfers, or 0 if the wallet is locked.
552-
pub unlocked_until: u32,
552+
pub unlocked_until: Option<u32>,
553553
/// The transaction fee configuration, set in BTC/kB.
554554
#[serde(rename = "paytxfee")]
555555
pub pay_tx_fee: f64,

types/src/v18/mod.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@
175175
//! | getreceivedbylabel | version + model | |
176176
//! | gettransaction | version + model | |
177177
//! | getunconfirmedbalance | version + model | |
178-
//! | getwalletinfo | version + model | UNTESTED |
178+
//! | getwalletinfo | version + model | |
179179
//! | importaddress | returns nothing | |
180180
//! | importmulti | version | |
181181
//! | importprivkey | returns nothing | |
@@ -246,7 +246,7 @@ pub use self::{
246246
util::{DeriveAddresses, GetDescriptorInfo},
247247
wallet::{
248248
GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoError, GetReceivedByLabel,
249-
ImportMulti, ImportMultiEntry, JsonRpcError, ListReceivedByAddress,
249+
GetWalletInfo, ImportMulti, ImportMultiEntry, JsonRpcError, ListReceivedByAddress,
250250
ListReceivedByAddressItem, ListReceivedByLabel, ListReceivedByLabelError, ListUnspent,
251251
ListUnspentItem, ListWalletDir, ListWalletDirWallet,
252252
},
@@ -272,19 +272,18 @@ pub use crate::v17::{
272272
GetRawMempoolVerbose, GetRawTransaction, GetRawTransactionVerbose,
273273
GetRawTransactionVerboseError, GetReceivedByAddress, GetTransaction, GetTransactionDetail,
274274
GetTransactionDetailError, GetTransactionError, GetTxOut, GetTxOutError, GetTxOutSetInfo,
275-
GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfo, GetWalletInfoError,
276-
ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListBanned,
277-
ListLabels, ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError,
278-
ListReceivedByAddressError, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction,
279-
ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem,
280-
ListTransactionsItemError, ListUnspentItemError, ListWallets, LoadWallet, LockUnspent, Locked,
281-
Logging, MapMempoolEntryError, MempoolAcceptance, MempoolEntryError, MempoolEntryFees,
282-
MempoolEntryFeesError, PruneBlockchain, PsbtInput, PsbtOutput, PsbtScript, RawTransaction,
283-
RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, ScriptType,
284-
SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SetTxFee, SignFail,
285-
SignFailError, SignMessage, SignMessageWithPrivKey, SignRawTransaction,
286-
SignRawTransactionError, Softfork, SoftforkReject, TestMempoolAccept, TransactionCategory,
287-
UploadTarget, ValidateAddress, ValidateAddressError, VerifyChain, VerifyMessage,
288-
VerifyTxOutProof, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, WalletProcessPsbt,
289-
WitnessUtxo,
275+
GetTxOutSetInfoError, GetUnconfirmedBalance, GetWalletInfoError, ListAddressGroupings,
276+
ListAddressGroupingsError, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent,
277+
ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddressError, ListSinceBlock,
278+
ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError,
279+
ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError,
280+
ListWallets, LoadWallet, LockUnspent, Locked, Logging, MapMempoolEntryError, MempoolAcceptance,
281+
MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PruneBlockchain, PsbtInput,
282+
PsbtOutput, PsbtScript, RawTransaction, RawTransactionError, RawTransactionInput,
283+
RawTransactionOutput, RescanBlockchain, ScriptType, SendMany, SendRawTransaction,
284+
SendToAddress, SetNetworkActive, SetTxFee, SignFail, SignFailError, SignMessage,
285+
SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, Softfork, SoftforkReject,
286+
TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, ValidateAddressError,
287+
VerifyChain, VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt,
288+
WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo,
290289
};

types/src/v18/wallet/into.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ use bitcoin::{
1010

1111
use super::{
1212
GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoEmbeddedError, GetAddressInfoError,
13-
GetReceivedByLabel, ListReceivedByAddress, ListReceivedByAddressError,
14-
ListReceivedByAddressItem, ListReceivedByLabel, ListReceivedByLabelError,
15-
ListReceivedByLabelItem, ListUnspent, ListUnspentItem, ListUnspentItemError,
13+
GetReceivedByLabel, GetWalletInfo, GetWalletInfoError, ListReceivedByAddress,
14+
ListReceivedByAddressError, ListReceivedByAddressItem, ListReceivedByLabel,
15+
ListReceivedByLabelError, ListReceivedByLabelItem, ListUnspent, ListUnspentItem,
16+
ListUnspentItemError,
1617
};
1718
use crate::model;
1819

@@ -166,6 +167,52 @@ impl GetReceivedByLabel {
166167
}
167168
}
168169

170+
impl GetWalletInfo {
171+
/// Converts version specific type to a version nonspecific, more strongly typed type.
172+
pub fn into_model(self) -> Result<model::GetWalletInfo, GetWalletInfoError> {
173+
use GetWalletInfoError as E;
174+
175+
let wallet_version = crate::to_u32(self.wallet_version, "wallet_version")?;
176+
let balance = Amount::from_btc(self.balance).map_err(E::Balance)?;
177+
let unconfirmed_balance =
178+
Amount::from_btc(self.unconfirmed_balance).map_err(E::UnconfirmedBalance)?;
179+
let immature_balance =
180+
Amount::from_btc(self.immature_balance).map_err(E::ImmatureBalance)?;
181+
let tx_count = crate::to_u32(self.tx_count, "tx_count")?;
182+
let keypool_oldest = crate::to_u32(self.keypool_oldest, "keypoo_oldest")?;
183+
let keypool_size = crate::to_u32(self.keypool_size, "keypoo_size")?;
184+
let keypool_size_hd_internal =
185+
crate::to_u32(self.keypool_size_hd_internal, "keypoo_size_hd_internal")?;
186+
let pay_tx_fee = crate::btc_per_kb(self.pay_tx_fee).map_err(E::PayTxFee)?;
187+
let hd_seed_id =
188+
self.hd_seed_id.map(|s| s.parse::<hash160::Hash>()).transpose().map_err(E::HdSeedId)?;
189+
190+
Ok(model::GetWalletInfo {
191+
wallet_name: self.wallet_name,
192+
wallet_version,
193+
format: None,
194+
balance,
195+
unconfirmed_balance,
196+
immature_balance,
197+
tx_count,
198+
keypool_oldest,
199+
keypool_size,
200+
keypool_size_hd_internal,
201+
unlocked_until: self.unlocked_until,
202+
pay_tx_fee,
203+
hd_seed_id,
204+
private_keys_enabled: self.private_keys_enabled,
205+
avoid_reuse: None,
206+
scanning: None,
207+
descriptors: None,
208+
external_signer: None,
209+
blank: None,
210+
birthtime: None,
211+
last_processed_block: None,
212+
})
213+
}
214+
}
215+
169216
impl ListReceivedByAddress {
170217
/// Converts version specific type to a version nonspecific, more strongly typed type.
171218
pub fn into_model(self) -> Result<model::ListReceivedByAddress, ListReceivedByAddressError> {

types/src/v18/wallet/mod.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize};
1111

1212
pub use self::error::{GetAddressInfoError, ListReceivedByLabelError};
1313
pub use super::{
14-
GetAddressInfoEmbeddedError, GetAddressInfoLabel, ListReceivedByAddressError,
15-
ListUnspentItemError, ScriptType,
14+
GetAddressInfoEmbeddedError, GetAddressInfoLabel, GetWalletInfoError,
15+
ListReceivedByAddressError, ListUnspentItemError, ScriptType,
1616
};
1717

1818
/// Result of the JSON-RPC method `getaddressinfo`.
@@ -152,6 +152,51 @@ pub struct GetAddressInfoEmbedded {
152152
#[serde(deny_unknown_fields)]
153153
pub struct GetReceivedByLabel(pub f64);
154154

155+
/// Result of the JSON-RPC method `getwalletinfo`.
156+
///
157+
/// > getwalletinfo
158+
/// > Returns an object containing various wallet state info.
159+
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
160+
#[serde(deny_unknown_fields)]
161+
pub struct GetWalletInfo {
162+
/// The wallet name.
163+
#[serde(rename = "walletname")]
164+
pub wallet_name: String,
165+
/// The wallet version.
166+
#[serde(rename = "walletversion")]
167+
pub wallet_version: i64,
168+
/// The total confirmed balance of the wallet in BTC.
169+
pub balance: f64,
170+
/// The total unconfirmed balance of the wallet in BTC.
171+
pub unconfirmed_balance: f64,
172+
/// The total immature balance of the wallet in BTC.
173+
pub immature_balance: f64,
174+
/// The total number of transactions in the wallet
175+
#[serde(rename = "txcount")]
176+
pub tx_count: i64,
177+
/// The timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool.
178+
#[serde(rename = "keypoololdest")]
179+
pub keypool_oldest: i64,
180+
/// How many new keys are pre-generated (only counts external keys).
181+
#[serde(rename = "keypoolsize")]
182+
pub keypool_size: i64,
183+
/// How many new keys are pre-generated for internal use (used for change outputs, only appears
184+
/// if the wallet is using this feature, otherwise external keys are used).
185+
#[serde(rename = "keypoolsize_hd_internal")]
186+
pub keypool_size_hd_internal: i64,
187+
/// The timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked
188+
/// for transfers, or 0 if the wallet is locked.
189+
pub unlocked_until: Option<u32>,
190+
/// The transaction fee configuration, set in BTC/kB.
191+
#[serde(rename = "paytxfee")]
192+
pub pay_tx_fee: f64,
193+
/// The Hash160 of the HD seed (only present when HD is enabled).
194+
#[serde(rename = "hdseedid")]
195+
pub hd_seed_id: Option<String>,
196+
/// If privatekeys are disabled for this wallet (enforced watch-only wallet).
197+
pub private_keys_enabled: bool,
198+
}
199+
155200
/// Result of JSON-RPC method `importmulti`.
156201
///
157202
/// > importmulti requests ( options )

0 commit comments

Comments
 (0)