upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/walletcmd.cpp
diff options
context:
space:
mode:
authormtg0001 <106211915+mtg0001@users.noreply.github.com>2026-08-02 10:56:50 -0300
committerGitHub <noreply@github.com>2026-08-02 10:56:50 -0300
commit89f6d045c8e3dacbfbb369a3ac89c0c33de22b4c (patch)
tree3ff7c5ed2c0814a51e5746320f42bfe9c893c56b /src/walletcmd.cpp
parentee340c535dd26c034e18c4d97bf225a56bf91f6f (diff)
Keep HD change recoverable and bound message stalls (#109)
Change from an HD wallet now goes to a newly derived phrase-backed key instead of reusing a spent input's key. Reusing an input key silently moved value back to a key the phrase cannot reproduce; if derivation fails the transaction is refused rather than creating unrecoverable change. Legacy wallets with no seed keep the 0.1.0 behaviour. Restore also scans past the pre-generated key-pool window before treating an empty batch as the end. The message parser no longer consumes a header it cannot complete: it reads from a copy, so the O(n) reinsert and the 100 ms sleep inside the shared message thread are gone, and a peer that sits on an incomplete payload is disconnected after two minutes. The wire cap drops from 256 MB to MAX_SIZE. New net-message self-test covers complete, incomplete, stale and oversized headers. Verified here: clean rebuild, all self-tests pass, lock order checked (no path takes cs_keyPool before cs_mapWallet), and a node built from this branch synced from genesis to the chain tip on the live network with zero rejections.
Diffstat (limited to 'src/walletcmd.cpp')
-rw-r--r--src/walletcmd.cpp7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/walletcmd.cpp b/src/walletcmd.cpp
index 8eb3592..fae2095 100644
--- a/src/walletcmd.cpp
+++ b/src/walletcmd.cpp
@@ -25,6 +25,10 @@
25// would restore a wallet that looks empty. 25// would restore a wallet that looks empty.
26static const int RESTORE_BATCH = 100; 26static const int RESTORE_BATCH = 100;
27static const int RESTORE_MAX = 10000; 27static const int RESTORE_MAX = 10000;
28// The wallet may have a full unused key pool in front of a change address
29// created while spending pre-phrase coins. Looking only one empty batch ahead
30// can stop just before that change output.
31static const int RESTORE_MIN_SCAN = KEYPOOL_SIZE + RESTORE_BATCH;
28 32
29int CmdNewPhrase() 33int CmdNewPhrase()
30{ 34{
@@ -105,6 +109,7 @@ bool RestoreFromPhrase(const std::string& strMnemonic,
105 // up nothing. Every derived key is written to the wallet before the scan, 109 // up nothing. Every derived key is written to the wallet before the scan,
106 // because the scan asks the wallet what belongs to it. 110 // because the scan asks the wallet what belongs to it.
107 int nTotalDerived = (int)nHDNext; 111 int nTotalDerived = (int)nHDNext;
112 int nStopDepth = max(nMinDepth, RESTORE_MIN_SCAN);
108 while (nTotalDerived < RESTORE_MAX) 113 while (nTotalDerived < RESTORE_MAX)
109 { 114 {
110 // Count wallet transactions, not scan hits. 115 // Count wallet transactions, not scan hits.
@@ -146,7 +151,7 @@ bool RestoreFromPhrase(const std::string& strMnemonic,
146 151
147 // A whole batch with nothing in it means far enough -- unless the 152 // A whole batch with nothing in it means far enough -- unless the
148 // caller asked to look deeper anyway. 153 // caller asked to look deeper anyway.
149 if (nWalletAfter == nWalletBefore && nTotalDerived >= nMinDepth) 154 if (nWalletAfter == nWalletBefore && nTotalDerived >= nStopDepth)
150 break; 155 break;
151 } 156 }
152 157