mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-26 19:23:26 -03:00
Merge bitcoin/bitcoin#22156: Allow tr() import only when Taproot is active
fbf485c9b2
Allow tr() import only when Taproot is active (Andrew Chow) Pull request description: To avoid issues around fund loss, only allow descriptor wallets to import `tr()` descriptors after taproot has activated. ACKs for top commit: sipa: utACKfbf485c9b2
fjahr: Code review ACKfbf485c9b2
laanwj: Code review ACKfbf485c9b2
prayank23: utACKfbf485c9b2
Tree-SHA512: 83c43376515eea523dbc89bc5a0fde53e54aec492e49a40c2a33d80fc94aac459e232ae07b024b4bd75b58078c8d090bc7a2d69541c5d3d4834d2f4cfc9c8208
This commit is contained in:
commit
b0e5fbf6fa
4 changed files with 45 additions and 2 deletions
|
@ -277,6 +277,9 @@ public:
|
||||||
//! to be prepared to handle this by ignoring notifications about unknown
|
//! to be prepared to handle this by ignoring notifications about unknown
|
||||||
//! removed transactions and already added new transactions.
|
//! removed transactions and already added new transactions.
|
||||||
virtual void requestMempoolTransactions(Notifications& notifications) = 0;
|
virtual void requestMempoolTransactions(Notifications& notifications) = 0;
|
||||||
|
|
||||||
|
//! Check if Taproot has activated
|
||||||
|
virtual bool isTaprootActive() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Interface to let node manage chain clients (wallets, or maybe tools for
|
//! Interface to let node manage chain clients (wallets, or maybe tools for
|
||||||
|
|
|
@ -679,6 +679,12 @@ public:
|
||||||
notifications.transactionAddedToMempool(entry.GetSharedTx(), 0 /* mempool_sequence */);
|
notifications.transactionAddedToMempool(entry.GetSharedTx(), 0 /* mempool_sequence */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool isTaprootActive() const override
|
||||||
|
{
|
||||||
|
LOCK(::cs_main);
|
||||||
|
const CBlockIndex* tip = Assert(m_node.chainman)->ActiveChain().Tip();
|
||||||
|
return VersionBitsState(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_TAPROOT, versionbitscache) == ThresholdState::ACTIVE;
|
||||||
|
}
|
||||||
NodeContext& m_node;
|
NodeContext& m_node;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -1530,6 +1530,18 @@ static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Taproot descriptors cannot be imported if Taproot is not yet active.
|
||||||
|
// Check if this is a Taproot descriptor
|
||||||
|
CTxDestination dest;
|
||||||
|
ExtractDestination(scripts[0], dest);
|
||||||
|
if (std::holds_alternative<WitnessV1Taproot>(dest)) {
|
||||||
|
// Check if Taproot is active
|
||||||
|
if (!wallet.chain().isTaprootActive()) {
|
||||||
|
// Taproot is not active, raise an error
|
||||||
|
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot import tr() descriptor when Taproot is not active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If private keys are enabled, check some things.
|
// If private keys are enabled, check some things.
|
||||||
if (!wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
if (!wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||||
if (keys.keys.empty()) {
|
if (keys.keys.empty()) {
|
||||||
|
|
|
@ -172,9 +172,9 @@ class WalletTaprootTest(BitcoinTestFramework):
|
||||||
"""Test generation and spending of P2TR address outputs."""
|
"""Test generation and spending of P2TR address outputs."""
|
||||||
|
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
self.num_nodes = 2
|
self.num_nodes = 3
|
||||||
self.setup_clean_chain = True
|
self.setup_clean_chain = True
|
||||||
self.extra_args = [['-keypool=100'], ['-keypool=100']]
|
self.extra_args = [['-keypool=100'], ['-keypool=100'], ["-vbparams=taproot:1:1"]]
|
||||||
self.supports_cli = False
|
self.supports_cli = False
|
||||||
|
|
||||||
def skip_test_if_missing_module(self):
|
def skip_test_if_missing_module(self):
|
||||||
|
@ -230,12 +230,34 @@ class WalletTaprootTest(BitcoinTestFramework):
|
||||||
addr_r = self.make_addr(treefn, keys, i)
|
addr_r = self.make_addr(treefn, keys, i)
|
||||||
assert_equal(addr_g, addr_r)
|
assert_equal(addr_g, addr_r)
|
||||||
|
|
||||||
|
# tr descriptors cannot be imported when Taproot is not active
|
||||||
|
result = self.privs_tr_enabled.importdescriptors([{"desc": desc, "timestamp": "now"}])
|
||||||
|
assert(result[0]["success"])
|
||||||
|
result = self.privs_tr_disabled.importdescriptors([{"desc": desc, "timestamp": "now"}])
|
||||||
|
assert(not result[0]["success"])
|
||||||
|
assert_equal(result[0]["error"]["code"], -4)
|
||||||
|
assert_equal(result[0]["error"]["message"], "Cannot import tr() descriptor when Taproot is not active")
|
||||||
|
result = self.pubs_tr_enabled.importdescriptors([{"desc": desc_pub, "timestamp": "now"}])
|
||||||
|
assert(result[0]["success"])
|
||||||
|
result = self.pubs_tr_disabled.importdescriptors([{"desc": desc_pub, "timestamp": "now"}])
|
||||||
|
assert(not result[0]["success"])
|
||||||
|
assert_equal(result[0]["error"]["code"], -4)
|
||||||
|
assert_equal(result[0]["error"]["message"], "Cannot import tr() descriptor when Taproot is not active")
|
||||||
|
|
||||||
def do_test(self, comment, pattern, privmap, treefn, nkeys):
|
def do_test(self, comment, pattern, privmap, treefn, nkeys):
|
||||||
keys = self.rand_keys(nkeys)
|
keys = self.rand_keys(nkeys)
|
||||||
self.do_test_addr(comment, pattern, privmap, treefn, keys)
|
self.do_test_addr(comment, pattern, privmap, treefn, keys)
|
||||||
|
|
||||||
def run_test(self):
|
def run_test(self):
|
||||||
self.log.info("Creating wallets...")
|
self.log.info("Creating wallets...")
|
||||||
|
self.nodes[0].createwallet(wallet_name="privs_tr_enabled", descriptors=True, blank=True)
|
||||||
|
self.privs_tr_enabled = self.nodes[0].get_wallet_rpc("privs_tr_enabled")
|
||||||
|
self.nodes[2].createwallet(wallet_name="privs_tr_disabled", descriptors=True, blank=True)
|
||||||
|
self.privs_tr_disabled=self.nodes[2].get_wallet_rpc("privs_tr_disabled")
|
||||||
|
self.nodes[0].createwallet(wallet_name="pubs_tr_enabled", descriptors=True, blank=True, disable_private_keys=True)
|
||||||
|
self.pubs_tr_enabled = self.nodes[0].get_wallet_rpc("pubs_tr_enabled")
|
||||||
|
self.nodes[2].createwallet(wallet_name="pubs_tr_disabled", descriptors=True, blank=True, disable_private_keys=True)
|
||||||
|
self.pubs_tr_disabled=self.nodes[2].get_wallet_rpc("pubs_tr_disabled")
|
||||||
self.nodes[0].createwallet(wallet_name="addr_gen", descriptors=True, disable_private_keys=True, blank=True)
|
self.nodes[0].createwallet(wallet_name="addr_gen", descriptors=True, disable_private_keys=True, blank=True)
|
||||||
self.addr_gen = self.nodes[0].get_wallet_rpc("addr_gen")
|
self.addr_gen = self.nodes[0].get_wallet_rpc("addr_gen")
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue