Restore mined block heights when restoring decrypted notes.

This commit is contained in:
Kris Nuttycombe 2022-03-09 13:59:05 -07:00
parent ca34a97a37
commit e63d52896a
4 changed files with 39 additions and 5 deletions

View File

@ -117,9 +117,13 @@ void orchard_wallet_add_notes_from_bundle(
*
* The provided bundle must be a component of the transaction from which
* `txid` was derived.
*
* The value the `blockHeight` pointer points to be set to the height at which the
* transaction was mined, or `nullptr` if the transaction is not in the main chain.
*/
bool orchard_wallet_restore_notes(
OrchardWalletPtr* wallet,
const uint32_t* blockHeight,
const unsigned char txid[32],
const OrchardBundlePtr* bundle,
const RawOrchardActionIVK* actionIvks,

View File

@ -341,7 +341,15 @@ impl Wallet {
let mut result = BTreeMap::new();
for (action_idx, ivk, note, recipient, memo) in bundle.decrypt_outputs_for_keys(&keys) {
assert!(self.add_decrypted_note(txid, action_idx, ivk.clone(), note, recipient, memo));
assert!(self.add_decrypted_note(
None,
txid,
action_idx,
ivk.clone(),
note,
recipient,
memo
));
result.insert(action_idx, ivk);
}
@ -353,13 +361,22 @@ impl Wallet {
/// key to the vector of action indices that that key decrypts.
pub fn add_notes_from_bundle_with_hints(
&mut self,
tx_height: Option<BlockHeight>,
txid: &TxId,
bundle: &Bundle<Authorized, Amount>,
hints: BTreeMap<usize, &IncomingViewingKey>,
) -> Result<(), BundleDecryptionError> {
for (action_idx, ivk) in hints.into_iter() {
if let Some((note, recipient, memo)) = bundle.decrypt_output_with_key(action_idx, ivk) {
if !self.add_decrypted_note(txid, action_idx, ivk.clone(), note, recipient, memo) {
if !self.add_decrypted_note(
tx_height,
txid,
action_idx,
ivk.clone(),
note,
recipient,
memo,
) {
return Err(BundleDecryptionError::FvkNotFound(ivk.clone()));
}
} else {
@ -369,8 +386,10 @@ impl Wallet {
Ok(())
}
#[allow(clippy::too_many_arguments)]
fn add_decrypted_note(
&mut self,
tx_height: Option<BlockHeight>,
txid: &TxId,
action_idx: usize,
ivk: IncomingViewingKey,
@ -396,7 +415,7 @@ impl Wallet {
self.wallet_received_notes
.entry(*txid)
.or_insert_with(|| TxNotes {
tx_height: None,
tx_height,
decrypted_notes: BTreeMap::new(),
})
.decrypted_notes
@ -639,12 +658,14 @@ pub extern "C" fn orchard_wallet_add_notes_from_bundle(
#[no_mangle]
pub extern "C" fn orchard_wallet_restore_notes(
wallet: *mut Wallet,
block_height: *const u32,
txid: *const [c_uchar; 32],
bundle: *const Bundle<Authorized, Amount>,
hints: *const FFIActionIvk,
hints_len: usize,
) -> bool {
let wallet = unsafe { wallet.as_mut() }.expect("Wallet pointer may not be null");
let block_height = unsafe { block_height.as_ref() }.map(|h| BlockHeight::from(*h));
let txid = TxId::from_bytes(*unsafe { txid.as_ref() }.expect("txid may not be null."));
let bundle = unsafe { bundle.as_ref() }.expect("bundle pointer may not be null.");
@ -658,7 +679,7 @@ pub extern "C" fn orchard_wallet_restore_notes(
);
}
match wallet.add_notes_from_bundle_with_hints(&txid, bundle, hints) {
match wallet.add_notes_from_bundle_with_hints(block_height, &txid, bundle, hints) {
Ok(_) => true,
Err(e) => {
error!("Failed to restore decrypted notes to wallet: {:?}", e);

View File

@ -133,6 +133,7 @@ public:
* notes to the wallet.
*/
bool RestoreDecryptedNotes(
const std::optional<int> nBlockHeight,
const CTransaction& tx,
std::map<uint32_t, libzcash::OrchardIncomingViewingKey> hints
) {
@ -140,8 +141,10 @@ public:
for (const auto& [action_idx, ivk] : hints) {
rawHints.push_back({ action_idx, ivk.inner.get() });
}
uint32_t blockHeight = nBlockHeight.has_value() ? (uint32_t) nBlockHeight.value() : 0;
return orchard_wallet_restore_notes(
inner.get(),
nBlockHeight.has_value() ? &blockHeight : nullptr,
tx.GetHash().begin(),
tx.GetOrchardBundle().inner.get(),
rawHints.data(),
@ -156,6 +159,7 @@ public:
* Returns `false` if the caller attempts to insert a block out-of-order.
*/
bool AppendNoteCommitments(const int nBlockHeight, const CBlock& block) {
assert(nBlockHeight >= 0);
for (int txidx = 0; txidx < block.vtx.size(); txidx++) {
const CTransaction& tx = block.vtx[txidx];
if (!orchard_wallet_append_bundle_commitments(

View File

@ -947,7 +947,12 @@ bool CWallet::LoadUnifiedCaches()
// Restore decrypted Orchard notes.
for (const auto& [_, walletTx] : mapWallet) {
if (!walletTx.mapOrchardActionData.empty()) {
if (!orchardWallet.RestoreDecryptedNotes(walletTx, walletTx.mapOrchardActionData)) {
const CBlockIndex* pTxIndex;
std::optional<int> blockHeight;
if (walletTx.GetDepthInMainChain(pTxIndex) > 0) {
blockHeight = pTxIndex->nHeight;
}
if (!orchardWallet.RestoreDecryptedNotes(blockHeight, walletTx, walletTx.mapOrchardActionData)) {
return false;
}
}