Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/script/descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,12 +819,12 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
auto expr = Expr(sp);
bool sorted_multi = false;
if (Func("pk", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2SH, out, error);
auto pubkey = ParsePubkey(key_exp_index, expr, true, out, error);
if (!pubkey) return nullptr;
return std::make_unique<PKDescriptor>(std::move(pubkey));
}
if (Func("pkh", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2SH, out, error);
auto pubkey = ParsePubkey(key_exp_index, expr, true, out, error);
if (!pubkey) return nullptr;
return std::make_unique<PKHDescriptor>(std::move(pubkey));
}
Expand All @@ -851,7 +851,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
return nullptr;
}
auto arg = Expr(expr);
auto pk = ParsePubkey(key_exp_index, arg, ctx != ParseScriptContext::P2SH, out, error);
auto pk = ParsePubkey(key_exp_index, arg, true, out, error);
if (!pk) return nullptr;
script_size += pk->GetSize() + 1;
providers.emplace_back(std::move(pk));
Expand Down
10 changes: 10 additions & 0 deletions src/script/signingprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,13 @@ bool FillableSigningProvider::GetCScript(const CScriptID &hash, CScript& redeemS
}
return false;
}

CKeyID GetKeyForDestination(const SigningProvider& store, const CTxDestination& dest)
{
// Only supports destinations which map to single public keys, i.e. P2PKH
const PKHash *pkhash = std::get_if<PKHash>(&dest);

if (pkhash != nullptr) return ToKeyID(*pkhash);

return CKeyID();
}
3 changes: 3 additions & 0 deletions src/script/signingprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,7 @@ class FillableSigningProvider : public SigningProvider
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const override;
};

/** Return the CKeyID of the key involved in a script (if there is a unique one). */
CKeyID GetKeyForDestination(const SigningProvider& store, const CTxDestination& dest);

#endif // BITCOIN_SCRIPT_SIGNINGPROVIDER_H
2 changes: 1 addition & 1 deletion src/test/fuzz/key_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ FUZZ_TARGET_INIT(key_io, initialize_key_io)

const CTxDestination tx_destination = DecodeDestination(random_string);
(void)DescribeAddress(tx_destination);
// (void)GetKeyForDestination(/* store */ {}, tx_destination);
(void)GetKeyForDestination(/* store */ {}, tx_destination);
(void)GetScriptForDestination(tx_destination);
(void)IsValidDestination(tx_destination);

Expand Down
6 changes: 6 additions & 0 deletions src/test/script_standard_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

BOOST_FIXTURE_TEST_SUITE(script_standard_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(dest_default_is_no_dest)
{
CTxDestination dest;
BOOST_CHECK(!IsValidDestination(dest));
}

BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
{
CKey keys[3];
Expand Down
35 changes: 19 additions & 16 deletions src/wallet/rpcdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,6 @@ UniValue importprunedfunds(const JSONRPCRequest& request)
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
}
uint256 hashTx = tx.GetHash();
CWalletTx wtx(pwallet, MakeTransactionRef(std::move(tx)));

CDataStream ssMB(ParseHexV(request.params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION);
CMerkleBlock merkleBlock;
Expand All @@ -329,10 +328,10 @@ UniValue importprunedfunds(const JSONRPCRequest& request)
unsigned int txnIndex = vIndex[it - vMatch.begin()];

CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, height, merkleBlock.header.GetHash(), txnIndex);
wtx.m_confirm = confirm;

if (pwallet->IsMine(*wtx.tx)) {
pwallet->AddToWallet(wtx, false);
CTransactionRef tx_ref = MakeTransactionRef(tx);
if (pwallet->IsMine(*tx_ref)) {
pwallet->AddToWallet(std::move(tx_ref), confirm);
return NullUniValue;
}

Expand Down Expand Up @@ -908,15 +907,19 @@ UniValue dumpwallet(const JSONRPCRequest& request)
},
}.Check(request);

std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
if (!wallet) return NullUniValue;
const CWallet* const pwallet = wallet.get();
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
if (!pwallet) return NullUniValue;

LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*wallet);
CWallet& wallet = *pwallet;
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(wallet);

LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
wallet.BlockUntilSyncedToCurrentChain();

EnsureWalletIsUnlocked(pwallet);
LOCK2(wallet.cs_wallet, spk_man.cs_KeyStore);

EnsureWalletIsUnlocked(&wallet);

fs::path filepath = request.params[0].get_str();
filepath = fs::absolute(filepath);
Expand All @@ -937,7 +940,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)

std::map<CKeyID, int64_t> mapKeyBirth;
const std::map<CKeyID, int64_t>& mapKeyPool = spk_man.GetAllReserveKeys();
pwallet->GetKeyBirthTimes(mapKeyBirth);
wallet.GetKeyBirthTimes(mapKeyBirth);

std::set<CScriptID> scripts = spk_man.GetCScripts();

Expand All @@ -952,16 +955,16 @@ UniValue dumpwallet(const JSONRPCRequest& request)
// produce output
file << strprintf("# Wallet dump created by Dash Core %s\n", CLIENT_BUILD);
file << strprintf("# * Created on %s\n", FormatISO8601DateTime(GetTime()));
file << strprintf("# * Best block at time of backup was %i (%s),\n", pwallet->GetLastBlockHeight(), pwallet->GetLastBlockHash().ToString());
file << strprintf("# * Best block at time of backup was %i (%s),\n", wallet.GetLastBlockHeight(), wallet.GetLastBlockHash().ToString());
int64_t block_time = 0;
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetLastBlockHash(), FoundBlock().time(block_time)));
CHECK_NONFATAL(wallet.chain().findBlock(wallet.GetLastBlockHash(), FoundBlock().time(block_time)));
file << strprintf("# mined on %s\n", FormatISO8601DateTime(block_time));
file << "\n";

UniValue obj(UniValue::VOBJ);
obj.pushKV("dashcoreversion", CLIENT_BUILD);
obj.pushKV("lastblockheight", pwallet->GetLastBlockHeight());
obj.pushKV("lastblockhash", pwallet->GetLastBlockHash().ToString());
obj.pushKV("lastblockheight", wallet.GetLastBlockHeight());
obj.pushKV("lastblockhash", wallet.GetLastBlockHash().ToString());
obj.pushKV("lastblocktime", block_time);

// add the base58check encoded extended master if the wallet uses HD
Expand Down Expand Up @@ -1012,7 +1015,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
CKey key;
if (spk_man.GetKey(keyid, key)) {
file << strprintf("%s %s ", EncodeSecret(key), strTime);
const auto* address_book_entry = pwallet->FindAddressBookEntry(pkhash);
const auto* address_book_entry = wallet.FindAddressBookEntry(pkhash);
if (address_book_entry) {
file << strprintf("label=%s", EncodeDumpString(address_book_entry->GetLabel()));
} else if (mapKeyPool.count(keyid)) {
Expand Down
12 changes: 4 additions & 8 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,6 @@ UniValue getnewaddress(const JSONRPCRequest& request)
if (!wallet) return NullUniValue;
CWallet* const pwallet = wallet.get();

LegacyScriptPubKeyMan* spk_man = pwallet->GetLegacyScriptPubKeyMan();
if (!spk_man) {
throw JSONRPCError(RPC_WALLET_ERROR, "This type of wallet does not support this command");
}
LOCK(pwallet->cs_wallet);

if (!pwallet->CanGetAddresses()) {
Expand Down Expand Up @@ -1632,7 +1628,7 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
UniValue transactions(UniValue::VARR);

for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
CWalletTx tx = pairWtx.second;
const CWalletTx& tx = pairWtx.second;

if (depth == -1 || abs(tx.GetDepthInMainChain()) < depth) {
ListTransactions(pwallet, tx, 0, true, transactions, filter, nullptr /* filter_label */);
Expand Down Expand Up @@ -2560,9 +2556,9 @@ static UniValue getwalletinfo(const JSONRPCRequest& request)
if (spk_man) {
obj.pushKV("timefirstkey", spk_man->GetTimeFirstKey());
obj.pushKV("keypoololdest", spk_man->GetOldestKeyPoolTime());
obj.pushKV("keypoolsize", (int64_t)spk_man->KeypoolCountExternalKeys());
obj.pushKV("keypoolsize_hd_internal", (int64_t)(spk_man->KeypoolCountInternalKeys()));
}
obj.pushKV("keypoolsize", (int64_t)pwallet->KeypoolCountExternalKeys());
obj.pushKV("keypoolsize_hd_internal", (int64_t)(pwallet->KeypoolCountInternalKeys()));
obj.pushKV("keys_left", pwallet->nKeysLeftSinceAutoBackup);
if (pwallet->IsCrypted())
obj.pushKV("unlocked_until", pwallet->nRelockTime);
Expand Down Expand Up @@ -3833,12 +3829,12 @@ UniValue getaddressinfo(const JSONRPCRequest& request)

ScriptPubKeyMan* spk_man = pwallet->GetScriptPubKeyMan(scriptPubKey);
if (spk_man) {
const PKHash *pkhash = std::get_if<PKHash>(&dest);
if (const CKeyMetadata* meta = spk_man->GetMetadata(dest)) {
ret.pushKV("timestamp", meta->nCreateTime);
CHDChain hdChainCurrent;
LegacyScriptPubKeyMan* legacy_spk_man = pwallet->GetLegacyScriptPubKeyMan();
if (legacy_spk_man != nullptr) {
const PKHash *pkhash = std::get_if<PKHash>(&dest);
if (pkhash && legacy_spk_man->HaveHDKey(ToKeyID(*pkhash), hdChainCurrent)) {
ret.pushKV("hdchainid", hdChainCurrent.GetID().GetHex());
}
Expand Down
8 changes: 4 additions & 4 deletions src/wallet/scriptpubkeyman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ bool LegacyScriptPubKeyMan::GetNewDestination(CTxDestination& dest, std::string&
// Generate a new key that is added to wallet
CPubKey new_key;
if (!GetKeyFromPool(new_key, false)) {
error = "Error: Keypool ran out, please call keypoolrefill first";
error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
return false;
}
//LearnRelatedScripts(new_key);
Expand Down Expand Up @@ -749,9 +749,9 @@ const CKeyMetadata* LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& des
{
LOCK(cs_KeyStore);

const PKHash *pkhash = std::get_if<PKHash>(&dest);
if (pkhash != nullptr && !ToKeyID(*pkhash).IsNull()) {
auto it = mapKeyMetadata.find(ToKeyID(*pkhash));
CKeyID key_id = GetKeyForDestination(*this, dest);
if (!key_id.IsNull()) {
auto it = mapKeyMetadata.find(key_id);
if (it != mapKeyMetadata.end()) {
return &it->second;
}
Expand Down
9 changes: 2 additions & 7 deletions src/wallet/test/coinselector_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ BOOST_FIXTURE_TEST_SUITE(coinselector_tests, WalletTestingSetup)
// we repeat those tests this many times and only complain if all iterations of the test fail
#define RANDOM_REPEATS 5

std::vector<std::unique_ptr<CWalletTx>> wtxn;

typedef std::set<CInputCoin> CoinSet;

static std::vector<COutput> vCoins;
Expand Down Expand Up @@ -76,16 +74,14 @@ static void add_coin(CWallet& wallet, const CAmount& nValue, int nAge = 6*24, bo
// so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe()
tx.vin.resize(1);
}
std::unique_ptr<CWalletTx> wtx = std::make_unique<CWalletTx>(&wallet, MakeTransactionRef(std::move(tx)));
CWalletTx* wtx = wallet.AddToWallet(MakeTransactionRef(std::move(tx)), /* confirm= */ {});
if (fIsFromMe)
{
wtx->m_amounts[CWalletTx::DEBIT].Set(ISMINE_SPENDABLE, 1);
wtx->m_is_cache_empty = false;
}
COutput output(wtx.get(), nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */);
COutput output(wtx, nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */);
vCoins.push_back(output);
wallet.AddToWallet(*wtx.get());
wtxn.emplace_back(std::move(wtx));
}
static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0, bool spendable = false)
{
Expand All @@ -95,7 +91,6 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa
static void empty_wallet(void)
{
vCoins.clear();
wtxn.clear();
balance = 0;
}

Expand Down
6 changes: 2 additions & 4 deletions src/wallet/test/psbt_wallet_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ BOOST_AUTO_TEST_CASE(psbt_updater_test)
CDataStream s_prev_tx1(ParseHex("0200000000010158e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7501000000171600145f275f436b09a8cc9a2eb2a2f528485c68a56323feffffff02d8231f1b0100000017a914aed962d6654f9a2b36608eb9d64d2b260db4f1118700c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88702483045022100a22edcc6e5bc511af4cc4ae0de0fcd75c7e04d8c1c3a8aa9d820ed4b967384ec02200642963597b9b1bc22c75e9f3e117284a962188bf5e8a74c895089046a20ad770121035509a48eb623e10aace8bfd0212fdb8a8e5af3c94b0b133b95e114cab89e4f7965000000"), SER_NETWORK, PROTOCOL_VERSION);
CTransactionRef prev_tx1;
s_prev_tx1 >> prev_tx1;
CWalletTx prev_wtx1(&m_wallet, prev_tx1);
m_wallet.mapWallet.emplace(prev_wtx1.GetHash(), std::move(prev_wtx1));
m_wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(prev_tx1->GetHash()), std::forward_as_tuple(&m_wallet, prev_tx1));

CDataStream s_prev_tx2(ParseHex("0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000"), SER_NETWORK, PROTOCOL_VERSION);
CTransactionRef prev_tx2;
s_prev_tx2 >> prev_tx2;
CWalletTx prev_wtx2(&m_wallet, prev_tx2);
m_wallet.mapWallet.emplace(prev_wtx2.GetHash(), std::move(prev_wtx2));
m_wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(prev_tx2->GetHash()), std::forward_as_tuple(&m_wallet, prev_tx2));

// Add scripts
CScript rs1;
Expand Down
33 changes: 15 additions & 18 deletions src/wallet/test/wallet_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,17 +264,21 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
// Import key into wallet and call dumpwallet to create backup file.
{
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(m_node.chain.get(), "", CreateDummyWalletDatabase());
auto spk_man = wallet->GetOrCreateLegacyScriptPubKeyMan();
LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
spk_man->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME;
spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
{
auto spk_man = wallet->GetOrCreateLegacyScriptPubKeyMan();
LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
spk_man->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME;
spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());

AddWallet(wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
}
CoreContext context{m_node};
JSONRPCRequest request(context);

request.params.setArray();
request.params.push_back(backup_file);
AddWallet(wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());

::dumpwallet(request);
RemoveWallet(wallet, std::nullopt);
}
Expand Down Expand Up @@ -415,6 +419,7 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
static int64_t AddTx(ChainstateManager& chainman, CWallet& wallet, uint32_t lockTime, int64_t mockTime, int64_t blockTime)
{
CMutableTransaction tx;
CWalletTx::Confirmation confirm;
tx.nLockTime = lockTime;
SetMockTime(mockTime);
CBlockIndex* block = nullptr;
Expand All @@ -426,23 +431,15 @@ static int64_t AddTx(ChainstateManager& chainman, CWallet& wallet, uint32_t lock
block = inserted.first->second;
block->nTime = blockTime;
block->phashBlock = &hash;
confirm = {CWalletTx::Status::CONFIRMED, block->nHeight, hash, 0};
}

CWalletTx wtx(&wallet, MakeTransactionRef(tx));
LOCK(wallet.cs_wallet);
// If transaction is already in map, to avoid inconsistencies, unconfirmation
// is needed before confirm again with different block.
std::map<uint256, CWalletTx>::iterator it = wallet.mapWallet.find(wtx.GetHash());
if (it != wallet.mapWallet.end()) {
return wallet.AddToWallet(MakeTransactionRef(tx), confirm, [&](CWalletTx& wtx, bool /* new_tx */) {
wtx.setUnconfirmed();
wallet.AddToWallet(wtx);
}
if (block) {
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, block->nHeight, block->GetBlockHash(), 0);
wtx.m_confirm = confirm;
}
wallet.AddToWallet(wtx);
return wallet.mapWallet.at(wtx.GetHash()).nTimeSmart;
return true;
})->nTimeSmart;
}

// Simple test to verify assignment of CWalletTx::nSmartTime value. Could be
Expand Down
Loading