Skip to content

Commit

Permalink
wallet: deactivate descriptor
Browse files Browse the repository at this point in the history
  • Loading branch information
S3RK committed Jun 28, 2021
1 parent 6737d96 commit 3efaf83
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/wallet/rpcdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1584,6 +1584,10 @@ static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, c
} else {
wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), internal);
}
} else {
if (w_desc.descriptor->GetOutputType()) {
wallet.DeactivateScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), internal);
}
}

result.pushKV("success", UniValue(true));
Expand Down
17 changes: 17 additions & 0 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3171,6 +3171,23 @@ void CWallet::LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool intern
NotifyCanGetAddressesChanged();
}

void CWallet::DeactivateScriptPubKeyMan(uint256 id, OutputType type, bool internal)
{
auto spk_man = GetScriptPubKeyMan(type, internal);
if (spk_man != nullptr && spk_man->GetID() == id) {
WalletLogPrintf("Deactivate spkMan: id = %s, type = %d, internal = %d\n", id.ToString(), static_cast<int>(type), static_cast<int>(internal));
WalletBatch batch(GetDatabase());
if (!batch.EraseActiveScriptPubKeyMan(static_cast<uint8_t>(type), internal)) {
throw std::runtime_error(std::string(__func__) + ": erasing active ScriptPubKeyMan id failed");
}

auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
spk_mans[type] = nullptr;
}

NotifyCanGetAddressesChanged();
}

bool CWallet::IsLegacy() const
{
if (m_internal_spk_managers.count(OutputType::LEGACY) == 0) {
Expand Down
6 changes: 6 additions & 0 deletions src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,12 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
//! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal);

//! Remove specified ScriptPubKeyMan from set of active SPK managers. Writes the change to the wallet file.
//! @param[in] id The unique id for the ScriptPubKeyMan
//! @param[in] type The OutputType this ScriptPubKeyMan provides addresses for
//! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
void DeactivateScriptPubKeyMan(uint256 id, OutputType type, bool internal);

//! Create new DescriptorScriptPubKeyMans and add them to the wallet
void SetupDescriptorScriptPubKeyMans() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);

Expand Down
6 changes: 6 additions & 0 deletions src/wallet/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ bool WalletBatch::WriteActiveScriptPubKeyMan(uint8_t type, const uint256& id, bo
return WriteIC(make_pair(key, type), id);
}

bool WalletBatch::EraseActiveScriptPubKeyMan(uint8_t type, bool internal)
{
const std::string key{internal ? DBKeys::ACTIVEINTERNALSPK : DBKeys::ACTIVEEXTERNALSPK};
return EraseIC(make_pair(key, type));
}

bool WalletBatch::WriteDescriptorKey(const uint256& desc_id, const CPubKey& pubkey, const CPrivKey& privkey)
{
// hash pubkey/privkey to accelerate wallet load
Expand Down
1 change: 1 addition & 0 deletions src/wallet/walletdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ class WalletBatch
bool EraseDestData(const std::string &address, const std::string &key);

bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256& id, bool internal);
bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal);

DBErrors LoadWallet(CWallet* pwallet);
DBErrors FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWalletTx>& vWtx);
Expand Down
15 changes: 15 additions & 0 deletions test/functional/wallet_importdescriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,21 @@ def run_test(self):
address = w1.getrawchangeaddress('legacy')
assert_equal(address, "mpA2Wh9dvZT7yfELq1UnrUmAoc5qCkMetg")

self.log.info('Check can deactivate active descriptor')
self.test_importdesc({'desc': descsum_create('pkh([12345678]' + xpub + '/*)'),
'range': [0, 5],
'active': False,
'timestamp': 'now',
'internal': True
},
success=True)
assert_raises_rpc_error(-4, 'This wallet has no available keys', w1.getrawchangeaddress, 'legacy')

self.log.info('Verify activation state is persistent')
w1.unloadwallet()
self.nodes[1].loadwallet('w1')
assert_raises_rpc_error(-4, 'This wallet has no available keys', w1.getrawchangeaddress, 'legacy')

# # Test importing a descriptor containing a WIF private key
wif_priv = "cTe1f5rdT8A8DFgVWTjyPwACsDPJM9ff4QngFxUixCSvvbg1x6sh"
address = "2MuhcG52uHPknxDgmGPsV18jSHFBnnRgjPg"
Expand Down

0 comments on commit 3efaf83

Please sign in to comment.