upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp104
1 files changed, 90 insertions, 14 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 9082bd5..9bb3c24 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -181,6 +181,39 @@ static bool AddKeyIfMissing(const CKey& key)
181 return AddKey(key); 181 return AddKey(key);
182} 182}
183 183
184static bool DeriveNextHDWalletKey(vector<unsigned char>& vchPubKeyRet, string& strErrorRet)
185{
186 vchPubKeyRet.clear();
187 CRITICAL_BLOCK(cs_keyPool)
188 {
189 if (!HaveHDSeed())
190 {
191 strErrorRet = "no seed";
192 return false;
193 }
194
195 CKey key;
196 if (!DeriveHDKey(nHDNext, key, strErrorRet))
197 return false;
198 if (!AddKeyIfMissing(key))
199 {
200 strErrorRet = "could not write the derived key to wallet.dat";
201 return false;
202 }
203
204 unsigned int nNext = nHDNext + 1;
205 if (!CWalletDB().WriteHDNext(nNext))
206 {
207 strErrorRet = "could not advance the derivation counter";
208 return false;
209 }
210
211 nHDNext = nNext;
212 vchPubKeyRet = key.GetPubKey();
213 }
214 return true;
215}
216
184vector<unsigned char> GenerateNewKey() 217vector<unsigned char> GenerateNewKey()
185{ 218{
186 CKey key; 219 CKey key;
@@ -2310,27 +2343,55 @@ bool ProcessMessages(CNode* pfrom)
2310 if (LogAcceptsCategory("net")) printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", (int)(pstart - vRecv.begin())); 2343 if (LogAcceptsCategory("net")) printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", (int)(pstart - vRecv.begin()));
2311 vRecv.erase(vRecv.begin(), pstart); 2344 vRecv.erase(vRecv.begin(), pstart);
2312 2345
2313 // Read header 2346 // Read the header from a copy first. The old path consumed the header,
2347 // noticed the payload was incomplete, inserted the header back at the
2348 // front of the receive buffer, then slept inside the shared message
2349 // thread. A peer could announce a large payload and drip bytes forever,
2350 // making every pass pay for an O(n) insert and a 100 ms stall.
2314 CMessageHeader hdr; 2351 CMessageHeader hdr;
2315 vRecv >> hdr; 2352 CDataStream vHeader(vRecv.begin(), vRecv.begin() + sizeof(CMessageHeader),
2353 vRecv.nType, vRecv.nVersion);
2354 vHeader >> hdr;
2316 if (!hdr.IsValid()) 2355 if (!hdr.IsValid())
2317 { 2356 {
2318 if (LogAcceptsCategory("net")) printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); 2357 if (LogAcceptsCategory("net")) printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
2358 if (hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_SIZE)
2359 pfrom->fDisconnect = true;
2360 pfrom->nIncompleteMessageStart = 0;
2361 vRecv.ignore(sizeof(CMessageHeader));
2319 continue; 2362 continue;
2320 } 2363 }
2321 string strCommand = hdr.GetCommand(); 2364 string strCommand = hdr.GetCommand();
2322 2365
2323 // Message size 2366 // Message size
2324 unsigned int nMessageSize = hdr.nMessageSize; 2367 unsigned int nMessageSize = hdr.nMessageSize;
2325 if (nMessageSize > vRecv.size()) 2368 unsigned int nPayloadAvailable = vRecv.size() - sizeof(CMessageHeader);
2369 if (nMessageSize > nPayloadAvailable)
2326 { 2370 {
2327 // Rewind and wait for rest of message 2371 if (pfrom->nIncompleteMessageStart == 0 ||
2328 ///// need a mechanism to give up waiting for overlong message size error 2372 pfrom->nIncompleteMessageSize != nMessageSize ||
2329 if (LogAcceptsCategory("net")) printf("MESSAGE-BREAK 2\n"); 2373 pfrom->strIncompleteMessageCommand != strCommand)
2330 vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr)); 2374 {
2331 Sleep(100); 2375 pfrom->nIncompleteMessageStart = GetTime();
2376 pfrom->nIncompleteMessageSize = nMessageSize;
2377 pfrom->strIncompleteMessageCommand = strCommand;
2378 }
2379 else if (GetTime() - pfrom->nIncompleteMessageStart >
2380 BTF_INCOMPLETE_MESSAGE_TIMEOUT_SECS)
2381 {
2382 LogPrint("net",
2383 "disconnecting %s: incomplete %s message, %u of %u bytes after %d seconds\n",
2384 pfrom->addr.ToString().c_str(), strCommand.c_str(),
2385 nPayloadAvailable, nMessageSize,
2386 BTF_INCOMPLETE_MESSAGE_TIMEOUT_SECS);
2387 pfrom->fDisconnect = true;
2388 }
2332 break; 2389 break;
2333 } 2390 }
2391 pfrom->nIncompleteMessageStart = 0;
2392 pfrom->nIncompleteMessageSize = 0;
2393 pfrom->strIncompleteMessageCommand.clear();
2394 vRecv.ignore(sizeof(CMessageHeader));
2334 2395
2335 // Copy message to its own buffer 2396 // Copy message to its own buffer
2336 CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); 2397 CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
@@ -3774,13 +3835,28 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in
3774 // Fill vout[1] back to self with any change 3835 // Fill vout[1] back to self with any change
3775 if (nValueIn > nTotalValue) 3836 if (nValueIn > nTotalValue)
3776 { 3837 {
3777 // Use the same key as one of the coins
3778 vector<unsigned char> vchPubKey; 3838 vector<unsigned char> vchPubKey;
3779 CTransaction& txFirst = *(*setCoins.begin()); 3839 if (HaveHDSeed())
3780 foreach(const CTxOut& txout, txFirst.vout) 3840 {
3781 if (txout.IsMine()) 3841 string strError;
3782 if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) 3842 if (!DeriveNextHDWalletKey(vchPubKey, strError))
3783 break; 3843 {
3844 printf("CreateTransaction() : could not derive a phrase-backed change key: %s\n",
3845 strError.c_str());
3846 return false;
3847 }
3848 }
3849 else
3850 {
3851 // Legacy wallets have no deterministic seed. Preserve
3852 // the 0.1.0 behaviour for them: return change to a key
3853 // already proven to belong to this wallet.
3854 CTransaction& txFirst = *(*setCoins.begin());
3855 foreach(const CTxOut& txout, txFirst.vout)
3856 if (txout.IsMine())
3857 if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
3858 break;
3859 }
3784 if (vchPubKey.empty()) 3860 if (vchPubKey.empty())
3785 return false; 3861 return false;
3786 3862