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:
authorbitflash-maintainer <noreply@bitflash.invalid>2026-08-26 22:41:53 +0000
committerbitflash-maintainer <noreply@bitflash.invalid>2026-08-26 22:41:53 +0000
commitbbe04dc8c96b4c4766d2771d3438233bf82687c0 (patch)
tree62e5a1febfb8e9bc38d133ac7981e9ef93918484 /src/walletcmd.cpp
parent991853fa55a749d28d6f9e507ce72b289df92785 (diff)
parent9e39a50d1f110020b0841d31e4b931aa877cc448 (diff)
Merge upstream v1.2.19 into the fork
Merges upstream tag v1.2.19 (9e39a50) into merge/upstream-1.2.18 (991853f). Unlike the 1.2.15->1.2.18 replay, bc3de30 is a true ancestor of our branch via a9b4f89, so this is an ordinary three-way merge with merge-base bc3de30. Delta: 36 files, +3265/-163, the Tor onion transport (managed Tor, signed direct onion endpoints, onion-only dial mode) and the nHDNext restore fix. src/main.cpp, main.h, script.cpp/h and db.cpp/h are byte-identical between the two tags, and the poll() socket loop carries no diff hunks, so the merge is consensus-neutral and the soak-tested socket paths are unchanged. relay/ is untouched; the payout ledger (rpc.cpp) is untouched. 7 conflict blocks in 6 files, resolved as follows. Makefile -- VERSION. Ours: stays 1.2.19+sec with the naming comment updated, so artifacts from this tree cannot be mistaken for the upstream release. src/Makefile, src/makefile.mingw -- HEADERS list. Ours (no market.h) plus their tor.h. NODE_OBJS auto-merged correctly: no market.o, tor.o present. src/selftest.cpp -- known-tests list. Union: payout-ledger (ours) and managed-tor (theirs). src/main_gui.cpp -- one block. Our /dumpaddresses kept; their BtfStopManagedTor() on the StartNode failure path taken. The /rvrelay pin, /noannounce and the marketplace removal auto-merged and were verified intact. src/nostr.cpp -- two blocks in ResolveDescriptor. Signature takes both out-params (our fExchangeOk, their rawOut). The body keeps our drain-to-EOSE read -- returning early poisons the pooled socket for the next caller -- and adds their rawOut capture. Our TLS 1.2 floor (SSL_CTX_set_min_proto_version) is untouched by this merge; upstream 1.2.19 still has no floor of its own. Upstream's release commit also added four build logs and a compiled Python cache (build-1219.log, build-17.log, build-appimage.log, build-node.log, scripts/__pycache__/bitflash_chain.cpython-313.pyc). Removed here; they are build output, not source.
Diffstat (limited to 'src/walletcmd.cpp')
-rw-r--r--src/walletcmd.cpp62
1 files changed, 56 insertions, 6 deletions
diff --git a/src/walletcmd.cpp b/src/walletcmd.cpp
index 0ea2251..e8ac4bf 100644
--- a/src/walletcmd.cpp
+++ b/src/walletcmd.cpp
@@ -54,6 +54,37 @@ bool RestoreScanReachedDepth(int nSchema,
54 return nLegacyNext >= nDepth; 54 return nLegacyNext >= nDepth;
55} 55}
56 56
57unsigned int WalletLastUsedPubKeyIndexNext(
58 const std::map<unsigned int, std::vector<unsigned char> >& mapPubKeysByIndex)
59{
60 std::map<std::vector<unsigned char>, unsigned int> mapIndexByPubKey;
61 for (std::map<unsigned int, std::vector<unsigned char> >::const_iterator it =
62 mapPubKeysByIndex.begin();
63 it != mapPubKeysByIndex.end(); ++it)
64 mapIndexByPubKey[it->second] = it->first;
65
66 unsigned int nNext = 0;
67 CRITICAL_BLOCK(cs_mapWallet)
68 {
69 for (map<uint256, CWalletTx>::iterator it = mapWallet.begin();
70 it != mapWallet.end(); ++it)
71 {
72 CWalletTx& wtx = (*it).second;
73 for (int i = 0; i < (int)wtx.vout.size(); i++)
74 {
75 vector<unsigned char> vchPubKey;
76 if (!ExtractPubKey(wtx.vout[i].scriptPubKey, false, vchPubKey))
77 continue;
78 std::map<std::vector<unsigned char>, unsigned int>::const_iterator mi =
79 mapIndexByPubKey.find(vchPubKey);
80 if (mi != mapIndexByPubKey.end() && mi->second + 1 > nNext)
81 nNext = mi->second + 1;
82 }
83 }
84 }
85 return nNext;
86}
87
57int CmdNewPhrase() 88int CmdNewPhrase()
58{ 89{
59 AttachTerminal(); 90 AttachTerminal();
@@ -132,7 +163,10 @@ bool RestoreFromPhrase(const std::string& strMnemonic,
132 // Derive forward in batches, scanning after each, until a whole batch turns 163 // Derive forward in batches, scanning after each, until a whole batch turns
133 // up nothing. Every derived key is written to the wallet before the scan, 164 // up nothing. Every derived key is written to the wallet before the scan,
134 // because the scan asks the wallet what belongs to it. 165 // because the scan asks the wallet what belongs to it.
135 int nTotalDerived = nHDKeySchema == HD_SCHEMA_BIP44 166 const bool fRestoreBIP44 = nHDKeySchema == HD_SCHEMA_BIP44;
167 unsigned int nLegacyScanNext = nHDNext;
168 std::map<unsigned int, vector<unsigned char> > mapLegacyScanPubKeys;
169 int nTotalDerived = fRestoreBIP44
136 ? (int)(nHDReceiveNext + nHDChangeNext) 170 ? (int)(nHDReceiveNext + nHDChangeNext)
137 : (int)nHDNext; 171 : (int)nHDNext;
138 int nStopDepth = max(nMinDepth, RESTORE_MIN_SCAN); 172 int nStopDepth = max(nMinDepth, RESTORE_MIN_SCAN);
@@ -151,7 +185,7 @@ bool RestoreFromPhrase(const std::string& strMnemonic,
151 nWalletBefore = mapWallet.size(); 185 nWalletBefore = mapWallet.size();
152 186
153 std::string strDeriveError; 187 std::string strDeriveError;
154 if (nHDKeySchema == HD_SCHEMA_BIP44) 188 if (fRestoreBIP44)
155 { 189 {
156 for (int i = 0; i < RESTORE_BATCH; i++) 190 for (int i = 0; i < RESTORE_BATCH; i++)
157 { 191 {
@@ -182,15 +216,15 @@ bool RestoreFromPhrase(const std::string& strMnemonic,
182 for (int i = 0; i < RESTORE_BATCH; i++) 216 for (int i = 0; i < RESTORE_BATCH; i++)
183 { 217 {
184 CKey key; 218 CKey key;
185 if (!DeriveHDKey(nHDNext, key, strDeriveError)) 219 if (!DeriveHDKey(nLegacyScanNext, key, strDeriveError))
186 break; 220 break;
187 if (!AddKey(key)) 221 if (!AddKey(key))
188 break; 222 break;
189 nHDNext++; 223 mapLegacyScanPubKeys[nLegacyScanNext] = key.GetPubKey();
224 nLegacyScanNext++;
190 nTotalDerived++; 225 nTotalDerived++;
191 } 226 }
192 nHDKeySchema = nSavedSchema; 227 nHDKeySchema = nSavedSchema;
193 CWalletDB().WriteHDNext(nHDNext);
194 } 228 }
195 else 229 else
196 { 230 {
@@ -209,6 +243,22 @@ bool RestoreFromPhrase(const std::string& strMnemonic,
209 243
210 ScanForWalletTransactions(pindexGenesisBlock); 244 ScanForWalletTransactions(pindexGenesisBlock);
211 245
246 if (fRestoreBIP44)
247 {
248 // The legacy branch is scanned only for compatibility with phrases
249 // created before BIP44. Persist the last used legacy index + 1, not
250 // the lookahead depth. Otherwise a restore with no legacy hits can
251 // leave hdnext at RESTORE_MAX and make future compatibility scans
252 // look exhausted even though no legacy key was ever used.
253 unsigned int nLegacyUsedNext =
254 WalletLastUsedPubKeyIndexNext(mapLegacyScanPubKeys);
255 if (nLegacyUsedNext != nHDNext)
256 {
257 nHDNext = nLegacyUsedNext;
258 CWalletDB().WriteHDNext(nHDNext);
259 }
260 }
261
212 size_t nWalletAfter = 0; 262 size_t nWalletAfter = 0;
213 CRITICAL_BLOCK(cs_mapWallet) 263 CRITICAL_BLOCK(cs_mapWallet)
214 nWalletAfter = mapWallet.size(); 264 nWalletAfter = mapWallet.size();
@@ -239,7 +289,7 @@ bool RestoreFromPhrase(const std::string& strMnemonic,
239 RestoreScanReachedDepth(nHDKeySchema, 289 RestoreScanReachedDepth(nHDKeySchema,
240 nHDReceiveNext, 290 nHDReceiveNext,
241 nHDChangeNext, 291 nHDChangeNext,
242 nHDNext, 292 fRestoreBIP44 ? nLegacyScanNext : nHDNext,
243 nStopDepth)) 293 nStopDepth))
244 break; 294 break;
245 } 295 }