Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wallet: Ensure best block matches wallet scan state #30221

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
scripted-diff: Rename LastBlock to BestBlock
-BEGIN VERIFY SCRIPT-
sed -i "s/SetLastBlockProcessed/SetBestBlock/" $(git grep -l "SetLastBlockProcessed")
sed -i "s/GetLastBlock/GetBestBlock/g" $(git grep -l "GetLastBlock")
-END VERIFY SCRIPT-
  • Loading branch information
achow101 committed Nov 19, 2024
commit 39bfbc1628cb485d9aa86f4c47f78fe92b182a23
4 changes: 2 additions & 2 deletions src/qt/test/wallettests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ std::shared_ptr<CWallet> SetupLegacyWatchOnlyWallet(interfaces::Node& node, Test
CPubKey pubKey = test.coinbaseKey.GetPubKey();
bool import_keys = wallet->ImportPubKeys({{pubKey.GetID(), false}}, {{pubKey.GetID(), pubKey}} , /*key_origins=*/{}, /*add_keypool=*/false, /*timestamp=*/1);
assert(import_keys);
wallet->SetLastBlockProcessed(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
wallet->SetBestBlock(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
}
SyncUpWallet(wallet, node);
return wallet;
Expand All @@ -226,7 +226,7 @@ std::shared_ptr<CWallet> SetupDescriptorsWallet(interfaces::Node& node, TestChai
if (!wallet->AddWalletDescriptor(w_desc, provider, "", false)) assert(false);
CTxDestination dest = GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type);
wallet->SetAddressBook(dest, "", wallet::AddressPurpose::RECEIVE);
wallet->SetLastBlockProcessed(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
wallet->SetBestBlock(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
SyncUpWallet(wallet, node);
wallet->SetBroadcastTransactions(true);
return wallet;
Expand Down
2 changes: 1 addition & 1 deletion src/test/fuzz/util/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct FuzzedWallet {
LOCK(wallet->cs_wallet);
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
auto height{*Assert(chain.getHeight())};
wallet->SetLastBlockProcessed(height, chain.getBlockHash(height));
wallet->SetBestBlock(height, chain.getBlockHash(height));
}
wallet->m_keypool_size = 1; // Avoid timeout in TopUp()
assert(wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
Expand Down
8 changes: 4 additions & 4 deletions src/wallet/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,9 @@ class WalletImpl : public Wallet
if (mi == m_wallet->mapWallet.end()) {
return false;
}
num_blocks = m_wallet->GetLastBlockHeight();
num_blocks = m_wallet->GetBestBlockHeight();
block_time = -1;
CHECK_NONFATAL(m_wallet->chain().findBlock(m_wallet->GetLastBlockHash(), FoundBlock().time(block_time)));
CHECK_NONFATAL(m_wallet->chain().findBlock(m_wallet->GetBestBlockHash(), FoundBlock().time(block_time)));
tx_status = MakeWalletTxStatus(*m_wallet, mi->second);
return true;
}
Expand All @@ -383,7 +383,7 @@ class WalletImpl : public Wallet
LOCK(m_wallet->cs_wallet);
auto mi = m_wallet->mapWallet.find(txid);
if (mi != m_wallet->mapWallet.end()) {
num_blocks = m_wallet->GetLastBlockHeight();
num_blocks = m_wallet->GetBestBlockHeight();
in_mempool = mi->second.InMempool();
order_form = mi->second.vOrderForm;
tx_status = MakeWalletTxStatus(*m_wallet, mi->second);
Expand Down Expand Up @@ -421,7 +421,7 @@ class WalletImpl : public Wallet
if (!locked_wallet) {
return false;
}
block_hash = m_wallet->GetLastBlockHash();
block_hash = m_wallet->GetBestBlockHash();
balances = getBalances();
return true;
}
Expand Down
14 changes: 7 additions & 7 deletions src/wallet/rpc/backup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static void EnsureBlockDataFromTime(const CWallet& wallet, int64_t timestamp)
int height{0};
const bool found{chain.findFirstBlockWithTimeAndHeight(timestamp - TIMESTAMP_WINDOW, 0, FoundBlock().height(height))};

uint256 tip_hash{WITH_LOCK(wallet.cs_wallet, return wallet.GetLastBlockHash())};
uint256 tip_hash{WITH_LOCK(wallet.cs_wallet, return wallet.GetBestBlockHash())};
if (found && !chain.hasBlocks(tip_hash, height)) {
throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Pruned blocks from height %d required to import keys. Use RPC call getblockchaininfo to determine your pruned height.", height));
}
Expand Down Expand Up @@ -352,7 +352,7 @@ RPCHelpMan importprunedfunds()

LOCK(pwallet->cs_wallet);
int height;
if (!pwallet->chain().findAncestorByHash(pwallet->GetLastBlockHash(), merkleBlock.header.GetHash(), FoundBlock().height(height))) {
if (!pwallet->chain().findAncestorByHash(pwallet->GetBestBlockHash(), merkleBlock.header.GetHash(), FoundBlock().height(height))) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
}

Expand Down Expand Up @@ -527,7 +527,7 @@ RPCHelpMan importwallet()
if (!file.is_open()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
}
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetLastBlockHash(), FoundBlock().time(nTimeBegin)));
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetBestBlockHash(), FoundBlock().time(nTimeBegin)));

int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
file.seekg(0, file.beg);
Expand Down Expand Up @@ -738,7 +738,7 @@ RPCHelpMan dumpwallet()
wallet.GetKeyBirthTimes(mapKeyBirth);

int64_t block_time = 0;
CHECK_NONFATAL(wallet.chain().findBlock(wallet.GetLastBlockHash(), FoundBlock().time(block_time)));
CHECK_NONFATAL(wallet.chain().findBlock(wallet.GetBestBlockHash(), FoundBlock().time(block_time)));

// Note: To avoid a lock order issue, access to cs_main must be locked before cs_KeyStore.
// So we do the two things in this function that lock cs_main first: GetKeyBirthTimes, and findBlock.
Expand All @@ -759,7 +759,7 @@ RPCHelpMan dumpwallet()
// produce output
file << strprintf("# Wallet dump created by %s %s\n", CLIENT_NAME, FormatFullVersion());
file << strprintf("# * Created on %s\n", FormatISO8601DateTime(GetTime()));
file << strprintf("# * Best block at time of backup was %i (%s),\n", wallet.GetLastBlockHeight(), wallet.GetLastBlockHash().ToString());
file << strprintf("# * Best block at time of backup was %i (%s),\n", wallet.GetBestBlockHeight(), wallet.GetBestBlockHash().ToString());
file << strprintf("# mined on %s\n", FormatISO8601DateTime(block_time));
file << "\n";

Expand Down Expand Up @@ -1379,7 +1379,7 @@ RPCHelpMan importmulti()
if (!is_watchonly) EnsureWalletIsUnlocked(wallet);

// Verify all timestamps are present before importing any keys.
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetLastBlockHash(), FoundBlock().time(nLowestTimestamp).mtpTime(now)));
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetBestBlockHash(), FoundBlock().time(nLowestTimestamp).mtpTime(now)));
for (const UniValue& data : requests.getValues()) {
GetImportTimestamp(data, now);
}
Expand Down Expand Up @@ -1699,7 +1699,7 @@ RPCHelpMan importdescriptors()
LOCK(pwallet->cs_wallet);
EnsureWalletIsUnlocked(*pwallet);

CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetLastBlockHash(), FoundBlock().time(lowest_timestamp).mtpTime(now)));
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetBestBlockHash(), FoundBlock().time(lowest_timestamp).mtpTime(now)));

// Get all timestamps and extract the lowest timestamp
for (const UniValue& request : requests.getValues()) {
Expand Down
14 changes: 7 additions & 7 deletions src/wallet/rpc/transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ RPCHelpMan listsinceblock()
blockId = ParseHashV(request.params[0], "blockhash");
height = int{};
altheight = int{};
if (!wallet.chain().findCommonAncestor(blockId, wallet.GetLastBlockHash(), /*ancestor_out=*/FoundBlock().height(*height), /*block1_out=*/FoundBlock().height(*altheight))) {
if (!wallet.chain().findCommonAncestor(blockId, wallet.GetBestBlockHash(), /*ancestor_out=*/FoundBlock().height(*height), /*block1_out=*/FoundBlock().height(*altheight))) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
}
Expand All @@ -645,7 +645,7 @@ RPCHelpMan listsinceblock()
std::optional<std::string> filter_label;
if (!request.params[5].isNull()) filter_label.emplace(LabelFromValue(request.params[5]));

int depth = height ? wallet.GetLastBlockHeight() + 1 - *height : -1;
int depth = height ? wallet.GetBestBlockHeight() + 1 - *height : -1;

UniValue transactions(UniValue::VARR);

Expand Down Expand Up @@ -678,8 +678,8 @@ RPCHelpMan listsinceblock()
}

uint256 lastblock;
target_confirms = std::min(target_confirms, wallet.GetLastBlockHeight() + 1);
CHECK_NONFATAL(wallet.chain().findAncestorByHeight(wallet.GetLastBlockHash(), wallet.GetLastBlockHeight() + 1 - target_confirms, FoundBlock().hash(lastblock)));
target_confirms = std::min(target_confirms, wallet.GetBestBlockHeight() + 1);
CHECK_NONFATAL(wallet.chain().findAncestorByHeight(wallet.GetBestBlockHash(), wallet.GetBestBlockHeight() + 1 - target_confirms, FoundBlock().hash(lastblock)));

UniValue ret(UniValue::VOBJ);
ret.pushKV("transactions", std::move(transactions));
Expand Down Expand Up @@ -891,7 +891,7 @@ RPCHelpMan rescanblockchain()
{
LOCK(pwallet->cs_wallet);
EnsureWalletIsUnlocked(*pwallet);
int tip_height = pwallet->GetLastBlockHeight();
int tip_height = pwallet->GetBestBlockHeight();

if (!request.params[0].isNull()) {
start_height = request.params[0].getInt<int>();
Expand All @@ -910,11 +910,11 @@ RPCHelpMan rescanblockchain()
}

// We can't rescan beyond non-pruned blocks, stop and throw an error
if (!pwallet->chain().hasBlocks(pwallet->GetLastBlockHash(), start_height, stop_height)) {
if (!pwallet->chain().hasBlocks(pwallet->GetBestBlockHash(), start_height, stop_height)) {
throw JSONRPCError(RPC_MISC_ERROR, "Can't rescan beyond pruned data. Use RPC call getblockchaininfo to determine your pruned height.");
}

CHECK_NONFATAL(pwallet->chain().findAncestorByHeight(pwallet->GetLastBlockHash(), start_height, FoundBlock().hash(start_block)));
CHECK_NONFATAL(pwallet->chain().findAncestorByHeight(pwallet->GetBestBlockHash(), start_height, FoundBlock().hash(start_block)));
}

CWallet::ScanResult result =
Expand Down
4 changes: 2 additions & 2 deletions src/wallet/rpc/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ void AppendLastProcessedBlock(UniValue& entry, const CWallet& wallet)
{
AssertLockHeld(wallet.cs_wallet);
UniValue lastprocessedblock{UniValue::VOBJ};
lastprocessedblock.pushKV("hash", wallet.GetLastBlockHash().GetHex());
lastprocessedblock.pushKV("height", wallet.GetLastBlockHeight());
lastprocessedblock.pushKV("hash", wallet.GetBestBlockHash().GetHex());
lastprocessedblock.pushKV("height", wallet.GetBestBlockHeight());
entry.pushKV("lastprocessedblock", std::move(lastprocessedblock));
}

Expand Down
2 changes: 1 addition & 1 deletion src/wallet/spend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
use_anti_fee_sniping = false;
}
if (use_anti_fee_sniping) {
DiscourageFeeSniping(txNew, rng_fast, wallet.chain(), wallet.GetLastBlockHash(), wallet.GetLastBlockHeight());
DiscourageFeeSniping(txNew, rng_fast, wallet.chain(), wallet.GetBestBlockHash(), wallet.GetBestBlockHeight());
}

// Calculate the transaction fee
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/test/coinselector_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ BOOST_AUTO_TEST_CASE(bnb_sffo_restriction)
// Verify the coin selection process does not produce a BnB solution when SFFO is enabled.
// This is currently problematic because it could require a change output. And BnB is specialized on changeless solutions.
std::unique_ptr<CWallet> wallet = NewWallet(m_node);
WITH_LOCK(wallet->cs_wallet, wallet->SetLastBlockProcessed(300, uint256{})); // set a high block so internal UTXOs are selectable
WITH_LOCK(wallet->cs_wallet, wallet->SetBestBlock(300, uint256{})); // set a high block so internal UTXOs are selectable

FastRandomContext rand{};
CoinSelectionParams params{
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/test/fuzz/fees.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ FUZZ_TARGET(wallet_fees, .init = initialize_setup)
CWallet& wallet = *g_wallet_ptr;
{
LOCK(wallet.cs_wallet);
wallet.SetLastBlockProcessed(chainstate->m_chain.Height(), chainstate->m_chain.Tip()->GetBlockHash());
wallet.SetBestBlock(chainstate->m_chain.Height(), chainstate->m_chain.Tip()->GetBlockHash());
}

if (fuzzed_data_provider.ConsumeBool()) {
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/test/fuzz/scriptpubkeyman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm)
{
LOCK(wallet.cs_wallet);
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet.SetLastBlockProcessed(chainstate.m_chain.Height(), chainstate.m_chain.Tip()->GetBlockHash());
wallet.SetBestBlock(chainstate.m_chain.Height(), chainstate.m_chain.Tip()->GetBlockHash());
wallet.m_keypool_size = 1;
}

Expand Down
2 changes: 1 addition & 1 deletion src/wallet/test/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cc
auto wallet = std::make_unique<CWallet>(&chain, "", CreateMockableWalletDatabase());
{
LOCK2(wallet->cs_wallet, ::cs_main);
wallet->SetLastBlockProcessed(cchain.Height(), cchain.Tip()->GetBlockHash());
wallet->SetBestBlock(cchain.Height(), cchain.Tip()->GetBlockHash());
}
{
LOCK(wallet->cs_wallet);
Expand Down
18 changes: 9 additions & 9 deletions src/wallet/test/wallet_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
LOCK(wallet.cs_wallet);
LOCK(Assert(m_node.chainman)->GetMutex());
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
wallet.SetBestBlock(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet);
Expand All @@ -108,7 +108,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
LOCK(wallet.cs_wallet);
LOCK(Assert(m_node.chainman)->GetMutex());
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet.SetLastBlockProcessed(oldTip->nHeight, oldTip->GetBlockHash());
wallet.SetBestBlock(oldTip->nHeight, oldTip->GetBlockHash());
}
AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet);
Expand Down Expand Up @@ -153,7 +153,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
LOCK(wallet.cs_wallet);
LOCK(Assert(m_node.chainman)->GetMutex());
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
wallet.SetBestBlock(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet);
Expand Down Expand Up @@ -181,7 +181,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
LOCK(wallet.cs_wallet);
LOCK(Assert(m_node.chainman)->GetMutex());
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
wallet.SetBestBlock(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet);
Expand Down Expand Up @@ -218,7 +218,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
{
const std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(m_node.chain.get(), "", CreateMockableWalletDatabase());
wallet->SetupLegacyScriptPubKeyMan();
WITH_LOCK(wallet->cs_wallet, wallet->SetLastBlockProcessed(newTip->nHeight, newTip->GetBlockHash()));
WITH_LOCK(wallet->cs_wallet, wallet->SetBestBlock(newTip->nHeight, newTip->GetBlockHash()));
WalletContext context;
context.args = &m_args;
AddWallet(context, wallet);
Expand Down Expand Up @@ -290,7 +290,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)

AddWallet(context, wallet);
LOCK(Assert(m_node.chainman)->GetMutex());
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
wallet->SetBestBlock(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
JSONRPCRequest request;
request.context = &context;
Expand All @@ -316,7 +316,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
request.params.push_back(backup_file);
AddWallet(context, wallet);
LOCK(Assert(m_node.chainman)->GetMutex());
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
wallet->SetBestBlock(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
wallet::importwallet().HandleRequest(request);
RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt);

Expand Down Expand Up @@ -379,7 +379,7 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet.SetupDescriptorScriptPubKeyMans();

wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
wallet.SetBestBlock(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());

// Call GetImmatureCredit() once before adding the key to the wallet to
// cache the current immature credit amount, which is 0.
Expand Down Expand Up @@ -609,7 +609,7 @@ class ListCoinsTestingSetup : public TestChain100Setup

LOCK(wallet->cs_wallet);
LOCK(Assert(m_node.chainman)->GetMutex());
wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
wallet->SetBestBlock(wallet->GetBestBlockHeight() + 1, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
auto it = wallet->mapWallet.find(tx->GetHash());
BOOST_CHECK(it != wallet->mapWallet.end());
it->second.m_state = TxStateConfirmed{m_node.chainman->ActiveChain().Tip()->GetBlockHash(), m_node.chainman->ActiveChain().Height(), /*index=*/1};
Expand Down
Loading