Skip to content

Commit 7399221

Browse files
authored
Light Wallet Upgrades, Ubuntu 24 Support (#1047)
* Fixes for Ubuntu 24.04 build * LIght wallet build, now handles larger ringsize count * Add support for verbose utxo's in getwatchonlytxes * Increase initial sync for watchonly mode by 10x, add confirmations and timestamp, watchonly v2 database migration, enabling caching for watchonly * Add RPC calls for watchonly address backup and restore
1 parent 475537b commit 7399221

File tree

14 files changed

+1426
-205
lines changed

14 files changed

+1426
-205
lines changed

src/init.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,19 @@ void Shutdown()
281281
}
282282

283283
if (gArgs.GetBoolArg("-watchonly", false)) {
284+
// Flush any cached watch-only data before shutdown (cache is always enabled)
285+
LogPrintf("Flushing watch-only caches on shutdown...\n");
286+
287+
// Flush transaction cache
288+
if (!watchonlyTxCache.FlushAll()) {
289+
error("Failed to flush watch-only transaction cache on shutdown");
290+
}
291+
292+
// Flush block cache
293+
if (!watchonlyBlockCache.FlushAll()) {
294+
error("Failed to flush watch-only block cache on shutdown");
295+
}
296+
284297
if (!FlushWatchOnlyAddresses()) {
285298
error("Fail to write watchonly addresses to database.");
286299
}
@@ -649,6 +662,7 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex
649662
static bool fHaveGenesis = false;
650663
static CWaitableCriticalSection cs_GenesisWait;
651664
static CConditionVariable condvar_GenesisWait;
665+
static boost::signals2::connection genesisWaitConnection;
652666

653667
static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex)
654668
{
@@ -1816,6 +1830,10 @@ bool AppInitMain()
18161830

18171831
// Load watchonly addresses
18181832
if (gArgs.GetBoolArg("-watchonly", false)) {
1833+
// Cache is always enabled with fixed size of 1000
1834+
watchonlyTxCache.nMaxCacheSize = 1000;
1835+
LogPrintf("Watch-only transaction cache enabled with size 1000\n");
1836+
18191837
LoadWatchOnlyAddresses();
18201838
}
18211839

@@ -1856,7 +1874,7 @@ bool AppInitMain()
18561874
// Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
18571875
// No locking, as this happens before any background thread is started.
18581876
if (chainActive.Tip() == nullptr) {
1859-
uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait);
1877+
genesisWaitConnection = uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait);
18601878
} else {
18611879
fHaveGenesis = true;
18621880
}
@@ -1883,7 +1901,7 @@ bool AppInitMain()
18831901
while (!fHaveGenesis && !ShutdownRequested()) {
18841902
condvar_GenesisWait.wait_for(lock, std::chrono::milliseconds(500));
18851903
}
1886-
uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait);
1904+
genesisWaitConnection.disconnect();
18871905
}
18881906
}
18891907

src/logging.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ const CLogCategoryDesc LogCategories[] =
127127
{BCLog::STAKING, "staking"},
128128
{BCLog::RINGCT, "ringct"},
129129
{BCLog::WATCHONLYDB, "watchonlydb"},
130+
{BCLog::WATCHONLYIMPORT, "watchonlyimport"},
130131
{BCLog::ALL, "1"},
131132
{BCLog::ALL, "all"},
132133
};

src/logging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ namespace BCLog {
6161
STAKING = (1 << 26),
6262
RINGCT = (1 << 27),
6363
WATCHONLYDB = (1 << 28),
64+
WATCHONLYIMPORT = (1 << 29),
6465
ALL = ~(uint32_t)0,
6566
};
6667

src/rpc/client.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
236236
{ "getnewaddress", 3, "bech32"},
237237
{ "getnewaddress", 4, "makeV2"},
238238
{ "getwatchonlytxes", 1, "starting_index"},
239-
{ "getwatchonlytxes", 4, "testing"},
239+
{ "getwatchonlytxes", 2, "batch_size"},
240240

241241

242242

src/test/cuckoocache_tests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <cuckoocache.h>
66
#include <script/sigcache.h>
77
#include <test/test_veil.h>
8+
#include <deque>
89
#include <random.h>
910
#include <thread>
1011

src/validation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ extern std::unique_ptr<CZerocoinDB> pzerocoinDB;
534534
*/
535535
int GetSpendHeight(const CCoinsViewCache& inputs);
536536

537-
static bool isPowTimeStampActive() { return (chainActive.Tip()->nTime >= nPowTimeStampActive); }
537+
inline bool isPowTimeStampActive() { return (chainActive.Tip()->nTime >= nPowTimeStampActive); }
538538

539539
extern VersionBitsCache versionbitscache;
540540

src/veil/ringct/anonwallet.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,9 @@ isminetype AnonWallet::HaveStealthAddress(const CStealthAddress &sxAddr) const
365365
auto si = mapStealthAddresses.find(sxAddr.GetID());
366366
if (si != mapStealthAddresses.end()) {
367367

368-
if (mapWatchOnlyAddresses.count(si->second.ToString(true))) {
369-
return ISMINE_WATCH_ONLY;
370-
}
371-
372-
if (mapWatchOnlyAddresses.count(si->second.ToString(false))) {
368+
// Check if this is a watch-only address using CKeyID (V2)
369+
CKeyID keyID = si->second.scan_secret.GetPubKey().GetID();
370+
if (mapWatchOnlyAddresses.count(keyID)) {
373371
return ISMINE_WATCH_ONLY;
374372
}
375373

src/veil/ringct/lightwallet.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,19 +1475,20 @@ bool LightWalletAddRealOutputs(CMutableTransaction& txNew, std::vector<CWatchOnl
14751475

14761476
vSecretColumns[l] = GetRandInt(nSigRingSize);
14771477

1478-
vMI[l].resize(currentSize);
1478+
vMI[l].resize(nSigInputs);
14791479

1480-
for (size_t k = 0; k < vSelectedTxes.size(); ++k) {
1480+
size_t txOffset = currentSize - nSigInputs;
1481+
for (size_t k = 0; k < nSigInputs; ++k) {
14811482
vMI[l][k].resize(nSigRingSize);
14821483
for (size_t i = 0; i < nSigRingSize; ++i) {
14831484
if (i == vSecretColumns[l]) {
1484-
const auto &coin = vSelectedTxes[k];
1485-
const uint256 &txhash = vSelectedTxes[k].tx_hash;
1485+
const auto &coin = vSelectedTxes[txOffset + k];
1486+
const uint256 &txhash = vSelectedTxes[txOffset + k].tx_hash;
14861487

1487-
CCmpPubKey pk = vSelectedTxes[k].ringctout.pk;
1488-
memcpy(&vInputBlinds[l][k * 32], &vSelectedTxes[k].blind, 32);
1488+
CCmpPubKey pk = vSelectedTxes[txOffset + k].ringctout.pk;
1489+
memcpy(&vInputBlinds[l][k * 32], &vSelectedTxes[txOffset + k].blind, 32);
14891490

1490-
int64_t index = vSelectedTxes[k].ringctIndex;
1491+
int64_t index = vSelectedTxes[txOffset + k].ringctIndex;
14911492

14921493
if (setHave.count(index)) {
14931494
errorMsg = "Duplicate index found";

0 commit comments

Comments
 (0)