From 426a74ed3c3c98b791a8445dd276e89fc5d6175e Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Tue, 23 Sep 2014 05:18:47 -0400 Subject: [PATCH 0001/2337] Add scriptPubKey field to validateaddress RPC call --- src/rpcmisc.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index dd45eefd58a..d1ab5093ff8 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -161,6 +161,7 @@ Value validateaddress(const Array& params, bool fHelp) "{\n" " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n" + " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n" " \"ismine\" : true|false, (boolean) If the address is yours or not\n" " \"isscript\" : true|false, (boolean) If the key is a script\n" " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n" @@ -182,6 +183,10 @@ Value validateaddress(const Array& params, bool fHelp) CTxDestination dest = address.Get(); string currentAddress = address.ToString(); ret.push_back(Pair("address", currentAddress)); + + CScript scriptPubKey = GetScriptForDestination(dest); + ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + #ifdef ENABLE_WALLET isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); From 44bc988e7becb492a78ed92ea1052f4789012534 Mon Sep 17 00:00:00 2001 From: Cozz Lovan Date: Sun, 31 Aug 2014 05:55:27 +0200 Subject: [PATCH 0002/2337] [Wallet] Do not flush the wallet in AddToWalletIfInvolvingMe(..) --- src/db.cpp | 6 ++++-- src/db.h | 3 ++- src/init.cpp | 4 +++- src/test/accounting_tests.cpp | 6 +++--- src/wallet.cpp | 22 ++++++++++++++-------- src/wallet.h | 4 ++-- src/walletdb.cpp | 2 +- src/walletdb.h | 2 +- 8 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 12650e459f3..a9fd8e95170 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -218,10 +218,11 @@ void CDBEnv::CheckpointLSN(const std::string& strFile) } -CDB::CDB(const std::string& strFilename, const char* pszMode) : pdb(NULL), activeTxn(NULL) +CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL) { int ret; fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); + fFlushOnClose = fFlushOnCloseIn; if (strFilename.empty()) return; @@ -298,7 +299,8 @@ void CDB::Close() activeTxn = NULL; pdb = NULL; - Flush(); + if (fFlushOnClose) + Flush(); { LOCK(bitdb.cs_db); diff --git a/src/db.h b/src/db.h index d2023993837..271ecfecec5 100644 --- a/src/db.h +++ b/src/db.h @@ -97,8 +97,9 @@ protected: std::string strFile; DbTxn* activeTxn; bool fReadOnly; + bool fFlushOnClose; - explicit CDB(const std::string& strFilename, const char* pszMode = "r+"); + explicit CDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnCloseIn=true); ~CDB() { Close(); } public: diff --git a/src/init.cpp b/src/init.cpp index 980c589b293..b943b8662be 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1177,6 +1177,8 @@ bool AppInit2(boost::thread_group& threadGroup) // Restore wallet transaction metadata after -zapwallettxes=1 if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") { + CWalletDB walletdb(strWalletFile); + BOOST_FOREACH(const CWalletTx& wtxOld, vWtx) { uint256 hash = wtxOld.GetHash(); @@ -1192,7 +1194,7 @@ bool AppInit2(boost::thread_group& threadGroup) copyTo->fFromMe = copyFrom->fFromMe; copyTo->strFromAccount = copyFrom->strFromAccount; copyTo->nOrderPos = copyFrom->nOrderPos; - copyTo->WriteToDisk(); + copyTo->WriteToDisk(&walletdb); } } } diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index af2a9a214f0..c35f96495c2 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) walletdb.WriteAccountingEntry(ae); wtx.mapValue["comment"] = "z"; - pwalletMain->AddToWallet(wtx); + pwalletMain->AddToWallet(wtx, false, &walletdb); vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); vpwtx[0]->nTimeReceived = (unsigned int)1333333335; vpwtx[0]->nOrderPos = -1; @@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) --tx.nLockTime; // Just to change the hash :) *static_cast(&wtx) = CTransaction(tx); } - pwalletMain->AddToWallet(wtx); + pwalletMain->AddToWallet(wtx, false, &walletdb); vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); vpwtx[1]->nTimeReceived = (unsigned int)1333333336; @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) --tx.nLockTime; // Just to change the hash :) *static_cast(&wtx) = CTransaction(tx); } - pwalletMain->AddToWallet(wtx); + pwalletMain->AddToWallet(wtx, false, &walletdb); vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); vpwtx[2]->nTimeReceived = (unsigned int)1333333329; vpwtx[2]->nOrderPos = -1; diff --git a/src/wallet.cpp b/src/wallet.cpp index b20b0007ce2..caf1f67f519 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -512,7 +512,7 @@ void CWallet::MarkDirty() } } -bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) +bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb) { uint256 hash = wtxIn.GetHash(); @@ -533,7 +533,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) if (fInsertedNew) { wtx.nTimeReceived = GetAdjustedTime(); - wtx.nOrderPos = IncOrderPosNext(); + wtx.nOrderPos = IncOrderPosNext(pwalletdb); wtx.nTimeSmart = wtx.nTimeReceived; if (wtxIn.hashBlock != 0) @@ -610,7 +610,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) // Write to disk if (fInsertedNew || fUpdated) - if (!wtx.WriteToDisk()) + if (!wtx.WriteToDisk(pwalletdb)) return false; // Break debit/credit balance caches: @@ -644,10 +644,16 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl if (fExisted || IsMine(tx) || IsFromMe(tx)) { CWalletTx wtx(this,tx); + // Get merkle branch if transaction was found in a block if (pblock) wtx.SetMerkleBranch(*pblock); - return AddToWallet(wtx); + + // Do not flush the wallet here for performance reasons + // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism + CWalletDB walletdb(strWalletFile, "r+", false); + + return AddToWallet(wtx, false, &walletdb); } } return false; @@ -871,9 +877,9 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived, } -bool CWalletTx::WriteToDisk() +bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb) { - return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); + return pwalletdb->WriteTx(GetHash(), *this); } // Scan the block chain (starting in pindexStart) for transactions @@ -1499,14 +1505,14 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) // This is only to keep the database open to defeat the auto-flush for the // duration of this scope. This is the only place where this optimization // maybe makes sense; please don't do it anywhere else. - CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL; + CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL; // Take key pair from key pool so it won't be used again reservekey.KeepKey(); // Add tx to wallet, because if it has change it's also ours, // otherwise just for transaction history. - AddToWallet(wtxNew); + AddToWallet(wtxNew, false, pwalletdb); // Notify that old coins are spent set setCoins; diff --git a/src/wallet.h b/src/wallet.h index f3fffb22532..cd1a09035fa 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -246,7 +246,7 @@ public: TxItems OrderedTxItems(std::list& acentries, std::string strAccount = ""); void MarkDirty(); - bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet=false); + bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); void SyncTransaction(const CTransaction& tx, const CBlock* pblock); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate); void EraseFromWallet(const uint256 &hash); @@ -849,7 +849,7 @@ public: return true; } - bool WriteToDisk(); + bool WriteToDisk(CWalletDB *pwalletdb); int64_t GetTxTime() const; int GetRequestCount() const; diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 3e5a664a5d8..8831ad15759 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -390,7 +390,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, if (wtx.nOrderPos == -1) wss.fAnyUnordered = true; - pwallet->AddToWallet(wtx, true); + pwallet->AddToWallet(wtx, true, NULL); } else if (strType == "acentry") { diff --git a/src/walletdb.h b/src/walletdb.h index f3d6e61f8bc..590d63e333e 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -76,7 +76,7 @@ public: class CWalletDB : public CDB { public: - CWalletDB(const std::string& strFilename, const char* pszMode = "r+") : CDB(strFilename, pszMode) + CWalletDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose) { } From ba7fcc8de06602576ab6a5911879d3d8df80d36a Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Sun, 25 Aug 2013 14:13:25 -0400 Subject: [PATCH 0003/2337] Discourage fee sniping with nLockTime --- src/wallet.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index 026c53aa2e3..a64d27a9412 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1347,6 +1347,28 @@ bool CWallet::CreateTransaction(const vector >& vecSend, wtxNew.BindWallet(this); CMutableTransaction txNew; + // Discourage fee sniping. + // + // However because of a off-by-one-error in previous versions we need to + // neuter it by setting nLockTime to at least one less than nBestHeight. + // Secondly currently propagation of transactions created for block heights + // corresponding to blocks that were just mined may be iffy - transactions + // aren't re-accepted into the mempool - we additionally neuter the code by + // going ten blocks back. Doesn't yet do anything for sniping, but does act + // to shake out wallet bugs like not showing nLockTime'd transactions at + // all. + txNew.nLockTime = std::max(0, chainActive.Height() - 10); + + // Secondly occasionally randomly pick a nLockTime even further back, so + // that transactions that are delayed after signing for whatever reason, + // e.g. high-latency mix networks and some CoinJoin implementations, have + // better privacy. + if (GetRandInt(10) == 0) + txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100)); + + assert(txNew.nLockTime <= (unsigned int)chainActive.Height()); + assert(txNew.nLockTime < LOCKTIME_THRESHOLD); + { LOCK2(cs_main, cs_wallet); { @@ -1440,8 +1462,12 @@ bool CWallet::CreateTransaction(const vector >& vecSend, reservekey.ReturnKey(); // Fill vin + // + // Note how the sequence number is set to max()-1 so that the + // nLockTime set above actually works. BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) - txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second)); + txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), + std::numeric_limits::max()-1)); // Sign int nIn = 0; From b468e81443b95ab31384bc7f2d7bc927ce86d838 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 25 Oct 2014 22:10:58 +0000 Subject: [PATCH 0004/2337] Qt: Clarify sign/verify dialog text to specifically state that these messages only prove one receives with the address in question, and makes no claim to sender of transactions --- src/qt/forms/signverifymessagedialog.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui index e22aea86757..f993d650acc 100644 --- a/src/qt/forms/signverifymessagedialog.ui +++ b/src/qt/forms/signverifymessagedialog.ui @@ -30,7 +30,7 @@ - You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. Qt::PlainText @@ -230,7 +230,7 @@ - Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction! Qt::PlainText From 31aac02446472ec5bfc4676ab190ec9d37056503 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 5 Nov 2014 13:47:21 +0100 Subject: [PATCH 0005/2337] Qt: new icons - flat and b/w icons seems to be the new trend - support for HiDPI/retina - change icon sizes - fix assets-attribution.md - removed unused icons --- doc/assets-attribution.md | 115 +++------ src/Makefile.qt.include | 18 +- src/qt/bitcoin.qrc | 17 +- src/qt/bitcoingui.cpp | 16 +- src/qt/forms/sendcoinsentry.ui | 18 ++ src/qt/res/icons/about.png | Bin 0 -> 5925 bytes src/qt/res/icons/about_qt.png | Bin 0 -> 3107 bytes src/qt/res/icons/add.png | Bin 1112 -> 15199 bytes src/qt/res/icons/address-book.png | Bin 1690 -> 16150 bytes src/qt/res/icons/clock1.png | Bin 864 -> 2448 bytes src/qt/res/icons/clock2.png | Bin 863 -> 2269 bytes src/qt/res/icons/clock3.png | Bin 856 -> 2184 bytes src/qt/res/icons/clock4.png | Bin 869 -> 1995 bytes src/qt/res/icons/clock5.png | Bin 858 -> 2682 bytes src/qt/res/icons/configure.png | Bin 681 -> 3891 bytes src/qt/res/icons/connect0.png | Bin 0 -> 16890 bytes src/qt/res/icons/connect0_16.png | Bin 631 -> 0 bytes src/qt/res/icons/connect1.png | Bin 0 -> 16870 bytes src/qt/res/icons/connect1_16.png | Bin 541 -> 0 bytes src/qt/res/icons/connect2.png | Bin 0 -> 16566 bytes src/qt/res/icons/connect2_16.png | Bin 582 -> 0 bytes src/qt/res/icons/connect3.png | Bin 0 -> 16566 bytes src/qt/res/icons/connect3_16.png | Bin 591 -> 0 bytes src/qt/res/icons/connect4.png | Bin 0 -> 16117 bytes src/qt/res/icons/connect4_16.png | Bin 596 -> 0 bytes src/qt/res/icons/debugwindow.png | Bin 2240 -> 1330 bytes src/qt/res/icons/edit.png | Bin 1163 -> 2544 bytes src/qt/res/icons/editcopy.png | Bin 600 -> 1295 bytes src/qt/res/icons/editpaste.png | Bin 1135 -> 15778 bytes src/qt/res/icons/export.png | Bin 1931 -> 17005 bytes src/qt/res/icons/eye.png | Bin 536 -> 2806 bytes src/qt/res/icons/eye_minus.png | Bin 595 -> 3087 bytes src/qt/res/icons/eye_plus.png | Bin 661 -> 3368 bytes src/qt/res/icons/filesave.png | Bin 1251 -> 2874 bytes src/qt/res/icons/history.png | Bin 1343 -> 16271 bytes src/qt/res/icons/info.png | Bin 0 -> 2895 bytes src/qt/res/icons/key.png | Bin 1440 -> 2434 bytes src/qt/res/icons/lock_closed.png | Bin 1401 -> 1686 bytes src/qt/res/icons/lock_open.png | Bin 1359 -> 1751 bytes src/qt/res/icons/open.png | Bin 0 -> 2239 bytes src/qt/res/icons/overview.png | Bin 6327 -> 2215 bytes src/qt/res/icons/qrcode.png | Bin 143 -> 0 bytes src/qt/res/icons/quit.png | Bin 1778 -> 15766 bytes src/qt/res/icons/receive.png | Bin 1331 -> 2874 bytes src/qt/res/icons/remove.png | Bin 649 -> 16663 bytes src/qt/res/icons/send.png | Bin 1345 -> 17005 bytes src/qt/res/icons/synced.png | Bin 560 -> 16891 bytes src/qt/res/icons/transaction0.png | Bin 291 -> 1759 bytes src/qt/res/icons/transaction2.png | Bin 211 -> 16891 bytes src/qt/res/icons/transaction_conflicted.png | Bin 474 -> 15766 bytes src/qt/res/icons/tx_inout.png | Bin 1252 -> 2568 bytes src/qt/res/icons/tx_input.png | Bin 1114 -> 2590 bytes src/qt/res/icons/tx_mined.png | Bin 1458 -> 2166 bytes src/qt/res/icons/tx_output.png | Bin 1107 -> 2699 bytes src/qt/res/icons/unit_btc.png | Bin 2107 -> 1318 bytes src/qt/res/icons/unit_mbtc.png | Bin 2107 -> 1407 bytes src/qt/res/icons/unit_ubtc.png | Bin 2107 -> 1369 bytes src/qt/res/icons/verify.png | Bin 0 -> 2984 bytes src/qt/res/movies/makespinner.sh | 6 + src/qt/res/movies/spinner-000.png | Bin 861 -> 16636 bytes src/qt/res/movies/spinner-001.png | Bin 835 -> 2785 bytes src/qt/res/movies/spinner-002.png | Bin 849 -> 2814 bytes src/qt/res/movies/spinner-003.png | Bin 844 -> 2775 bytes src/qt/res/movies/spinner-004.png | Bin 836 -> 2850 bytes src/qt/res/movies/spinner-005.png | Bin 855 -> 2728 bytes src/qt/res/movies/spinner-006.png | Bin 852 -> 2734 bytes src/qt/res/movies/spinner-007.png | Bin 888 -> 2633 bytes src/qt/res/movies/spinner-008.png | Bin 865 -> 2611 bytes src/qt/res/movies/spinner-009.png | Bin 847 -> 2074 bytes src/qt/res/movies/spinner-010.png | Bin 854 -> 2666 bytes src/qt/res/movies/spinner-011.png | Bin 856 -> 2751 bytes src/qt/res/movies/spinner-012.png | Bin 861 -> 2828 bytes src/qt/res/movies/spinner-013.png | Bin 882 -> 2896 bytes src/qt/res/movies/spinner-014.png | Bin 847 -> 2867 bytes src/qt/res/movies/spinner-015.png | Bin 849 -> 2860 bytes src/qt/res/movies/spinner-016.png | Bin 851 -> 2825 bytes src/qt/res/movies/spinner-017.png | Bin 848 -> 2833 bytes src/qt/res/movies/spinner-018.png | Bin 850 -> 2147 bytes src/qt/res/movies/spinner-019.png | Bin 830 -> 2808 bytes src/qt/res/movies/spinner-020.png | Bin 847 -> 2800 bytes src/qt/res/movies/spinner-021.png | Bin 850 -> 2833 bytes src/qt/res/movies/spinner-022.png | Bin 858 -> 2823 bytes src/qt/res/movies/spinner-023.png | Bin 854 -> 2710 bytes src/qt/res/movies/spinner-024.png | Bin 868 -> 2732 bytes src/qt/res/movies/spinner-025.png | Bin 865 -> 2635 bytes src/qt/res/movies/spinner-026.png | Bin 864 -> 2643 bytes src/qt/res/movies/spinner-027.png | Bin 855 -> 2099 bytes src/qt/res/movies/spinner-028.png | Bin 836 -> 2665 bytes src/qt/res/movies/spinner-029.png | Bin 846 -> 2761 bytes src/qt/res/movies/spinner-030.png | Bin 866 -> 2832 bytes src/qt/res/movies/spinner-031.png | Bin 871 -> 2871 bytes src/qt/res/movies/spinner-032.png | Bin 861 -> 2839 bytes src/qt/res/movies/spinner-033.png | Bin 849 -> 2829 bytes src/qt/res/movies/spinner-034.png | Bin 859 -> 2851 bytes src/qt/res/movies/spinner-035.png | Bin 0 -> 2837 bytes src/qt/res/spinner.png | Bin 0 -> 16636 bytes src/qt/res/src/clock1.svg | 261 ------------------- src/qt/res/src/clock2.svg | 262 -------------------- src/qt/res/src/clock3.svg | 261 ------------------- src/qt/res/src/clock4.svg | 261 ------------------- src/qt/res/src/clock5.svg | 262 -------------------- src/qt/res/src/clock_0.svg | 14 ++ src/qt/res/src/clock_1.svg | 13 + src/qt/res/src/clock_2.svg | 14 ++ src/qt/res/src/clock_3.svg | 15 ++ src/qt/res/src/clock_4.svg | 18 ++ src/qt/res/src/clock_green.svg | 262 -------------------- src/qt/res/src/connect-0.svg | 11 + src/qt/res/src/connect-1.svg | 21 ++ src/qt/res/src/connect-2.svg | 22 ++ src/qt/res/src/connect-3.svg | 16 ++ src/qt/res/src/inout.svg | 122 --------- src/qt/res/src/mine.svg | 12 + src/qt/res/src/qt.svg | 25 ++ src/qt/res/src/questionmark.svg | 159 ------------ src/qt/res/src/tx_in.svg | 9 + src/qt/res/src/tx_inout.svg | 11 + src/qt/res/src/verify.svg | 14 ++ 118 files changed, 301 insertions(+), 1954 deletions(-) create mode 100644 src/qt/res/icons/about.png create mode 100644 src/qt/res/icons/about_qt.png create mode 100644 src/qt/res/icons/connect0.png delete mode 100644 src/qt/res/icons/connect0_16.png create mode 100644 src/qt/res/icons/connect1.png delete mode 100644 src/qt/res/icons/connect1_16.png create mode 100644 src/qt/res/icons/connect2.png delete mode 100644 src/qt/res/icons/connect2_16.png create mode 100644 src/qt/res/icons/connect3.png delete mode 100644 src/qt/res/icons/connect3_16.png create mode 100644 src/qt/res/icons/connect4.png delete mode 100644 src/qt/res/icons/connect4_16.png create mode 100644 src/qt/res/icons/info.png create mode 100644 src/qt/res/icons/open.png delete mode 100644 src/qt/res/icons/qrcode.png create mode 100644 src/qt/res/icons/verify.png create mode 100755 src/qt/res/movies/makespinner.sh create mode 100644 src/qt/res/movies/spinner-035.png create mode 100644 src/qt/res/spinner.png delete mode 100644 src/qt/res/src/clock1.svg delete mode 100644 src/qt/res/src/clock2.svg delete mode 100644 src/qt/res/src/clock3.svg delete mode 100644 src/qt/res/src/clock4.svg delete mode 100644 src/qt/res/src/clock5.svg create mode 100644 src/qt/res/src/clock_0.svg create mode 100644 src/qt/res/src/clock_1.svg create mode 100644 src/qt/res/src/clock_2.svg create mode 100644 src/qt/res/src/clock_3.svg create mode 100644 src/qt/res/src/clock_4.svg delete mode 100644 src/qt/res/src/clock_green.svg create mode 100644 src/qt/res/src/connect-0.svg create mode 100644 src/qt/res/src/connect-1.svg create mode 100644 src/qt/res/src/connect-2.svg create mode 100644 src/qt/res/src/connect-3.svg delete mode 100644 src/qt/res/src/inout.svg create mode 100644 src/qt/res/src/mine.svg create mode 100644 src/qt/res/src/qt.svg delete mode 100644 src/qt/res/src/questionmark.svg create mode 100644 src/qt/res/src/tx_in.svg create mode 100644 src/qt/res/src/tx_inout.svg create mode 100644 src/qt/res/src/verify.svg diff --git a/doc/assets-attribution.md b/doc/assets-attribution.md index cd864f254d7..082bd41495f 100644 --- a/doc/assets-attribution.md +++ b/doc/assets-attribution.md @@ -6,98 +6,51 @@ The following is a list of assets used in the bitcoin source and their proper at * License: MIT ### Assets Used - src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png, - src/qt/res/src/clock_green.svg, src/qt/res/src/clock1.svg, - src/qt/res/src/clock2.svg, src/qt/res/src/clock3.svg, - src/qt/res/src/clock4.svg, src/qt/res/src/clock5.svg, - src/qt/res/src/inout.svg, src/qt/res/src/questionmark.svg + src/qt/res/icons/watch*.png, src/qt/res/icons/tx_in.png, + src/qt/res/icons/tx_inout.png, -[David Vignoni](http://www.icon-king.com) +[Typicons/Stephen Hutchings](http://typicons.com) ----------------------- ### Info -* Icon Pack: NUVOLA ICON THEME for KDE 3.x -* Designer: David Vignoni (david@icon-king.com) -* License: LGPL -* Site: [http://www.icon-king.com/projects/nuvola](http://www.icon-king.com/projects/nuvola) +* Icon Pack: Typicons (http://typicons.com) +* Designer: Stephen Hutchings (and more) +* License: CC BY-SA +* Site: [https://github.com/stephenhutchings/typicons.font](https://github.com/stephenhutchings/typicons.font) ### Assets Used - src/qt/res/icons/address-book.png, src/qt/res/icons/export.png, - src/qt/res/icons/history.png, src/qt/res/icons/key.png, - src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png, - src/qt/res/icons/receive.png, src/qt/res/icons/send.png, - src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png - -schollidesign ------------------------ - -### Info -* Icon Pack: Human-O2 -* Designer: schollidesign -* License: GNU/GPL -* Site: [http://findicons.com/icon/93743/blocks_gnome_netstatus_0](http://findicons.com/icon/93743/blocks_gnome_netstatus_0) - -### Assets Used - src/qt/res/icons/connect*.png - -md2k7 ------------------------ - -### Info -* Designer: md2k7 -* License: You are free to do with these icons as you wish, including selling, copying, modifying etc. -* License: MIT -* Site: [https://bitcointalk.org/index.php?topic=15276.0](https://bitcointalk.org/index.php?topic=15276.0) - -### Assets Used - src/qt/res/icons/transaction*.png - -[Everaldo.com](http://www.everaldo.com) ------------------------ - -### Info -* Icon Pack: Crystal SVG -* Designer: [http://www.everaldo.com](http://www.everaldo.com) -* License: LGPL - -### Assets Used - src/qt/res/icons/configure.png, src/qt/res/icons/quit.png, - src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png, - src/qt/res/icons/add.png, src/qt/res/icons/edit.png, - src/qt/res/icons/remove.png (edited) - -Everaldo (Everaldo Coelho) ------------------------ - -### Info -* Icon Pack: Kids -* Designer: Everaldo (Everaldo Coelho) -* License: GNU/GPL -* Site: [http://findicons.com/icon/17102/reload?id=17102](http://findicons.com/icon/17102/reload?id=17102) - -### Assets Used - scripts/img/reload.xcf (modified), src/qt/res/movies/*.png - -[Vignoni David](http://techbase.kde.org/Projects/Oxygen) ------------------------ - -### Info -* Designer: Vignoni David -* License: Oxygen icon theme is dual licensed. You may copy it under the Creative Common Attribution-ShareAlike 3.0 License or the GNU Library General Public License. -* Site: [http://techbase.kde.org/Projects/Oxygen](http://techbase.kde.org/Projects/Oxygen) - -### Assets Used - src/qt/res/icons/debugwindow.png + src/qt/res/icons/add.png, src/qt/res/icons/address-book.png, + src/qt/res/icons/configure.png, src/qt/res/icons/connect4.png, + src/qt/res/icons/debugwindow.png, src/qt/res/icons/edit.png, + src/qt/res/icons/exitcopy.png, src/qt/res/icons/editpaste.png, + src/qt/res/icons/export.png, src/qt/res/icons/eye.png, + src/qt/res/icons/filesave.png, src/qt/res/icons/history.png, + src/qt/res/icons/info.png, src/qt/res/icons/key.png, + src/qt/res/icons/lock_*.png, src/qt/res/icons/open.png, + src/qt/res/icons/overview.png, src/qt/res/icons/quit.png, + src/qt/res/icons/receive.png, src/qt/res/icons/remove.png, + src/qt/res/icons/send.png, src/qt/res/icons/synced.png, + src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_input.png, Jonas Schnelli ----------------------- ### Info -* Designer: Jonas Schnelli (based on the original bitcoin logo from Bitboy) +* Designer: Jonas Schnelli +* Bitcoin Icon: (based on the original bitcoin logo from Bitboy) +* Some icons are based on Stephan Hutchings Typicons * License: MIT ### Assets Used - src/qt/res/icons/bitcoin.icns, src/qt/res/src/bitcoin.svg, - src/qt/res/src/bitcoin.ico, src/qt/res/src/bitcoin.png, - src/qt/res/src/bitcoin_testnet.png, docs/bitcoin_logo_doxygen.png, - src/qt/res/images/splash.png, src/qt/res/images/splash_testnet.png + src/qt/res/icons/about.png, src/qt/res/icons/about_qt.png, + src/qt/res/icons/clock*.png, src/qt/res/icons/connect[0-3].png, + src/qt/res/icons/eye_minus.png, src/qt/res/icons/verify.png, + src/qt/res/icons/eye_plus.png, src/qt/res/icons/tx_inout.png, + src/qt/res/icons/tx_output.png, src/qt/res/icons/bitcoin.icns, + src/qt/res/src/bitcoin.svg, src/qt/res/src/bitcoin.ico, + src/qt/res/src/bitcoin.png, src/qt/res/src/bitcoin_testnet.png, + docs/bitcoin_logo_doxygen.png, src/qt/res/images/splash.png, + src/qt/res/images/splash_testnet.png, src/qt/res/src/tx*.svg, + src/qt/res/src/connect*.svg, src/qt/res/src/clock*.svg, + src/qt/res/src/mine.svg, src/qt/res/src/qt.svg, + src/qt/res/src/verify.svg, diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index ac6d60df03c..d207f4ad685 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -212,6 +212,8 @@ BITCOIN_QT_H = \ RES_ICONS = \ qt/res/icons/add.png \ qt/res/icons/address-book.png \ + qt/res/icons/about.png \ + qt/res/icons/about_qt.png \ qt/res/icons/bitcoin.ico \ qt/res/icons/bitcoin.png \ qt/res/icons/bitcoin_testnet.ico \ @@ -222,11 +224,11 @@ RES_ICONS = \ qt/res/icons/clock4.png \ qt/res/icons/clock5.png \ qt/res/icons/configure.png \ - qt/res/icons/connect0_16.png \ - qt/res/icons/connect1_16.png \ - qt/res/icons/connect2_16.png \ - qt/res/icons/connect3_16.png \ - qt/res/icons/connect4_16.png \ + qt/res/icons/connect0.png \ + qt/res/icons/connect1.png \ + qt/res/icons/connect2.png \ + qt/res/icons/connect3.png \ + qt/res/icons/connect4.png \ qt/res/icons/debugwindow.png \ qt/res/icons/edit.png \ qt/res/icons/editcopy.png \ @@ -237,11 +239,12 @@ RES_ICONS = \ qt/res/icons/eye_plus.png \ qt/res/icons/filesave.png \ qt/res/icons/history.png \ + qt/res/icons/info.png \ qt/res/icons/key.png \ qt/res/icons/lock_closed.png \ qt/res/icons/lock_open.png \ + qt/res/icons/open.png \ qt/res/icons/overview.png \ - qt/res/icons/qrcode.png \ qt/res/icons/quit.png \ qt/res/icons/receive.png \ qt/res/icons/remove.png \ @@ -256,7 +259,8 @@ RES_ICONS = \ qt/res/icons/tx_mined.png \ qt/res/icons/unit_btc.png \ qt/res/icons/unit_mbtc.png \ - qt/res/icons/unit_ubtc.png + qt/res/icons/unit_ubtc.png \ + qt/res/icons/verify.png BITCOIN_QT_CPP = \ qt/bitcoinaddressvalidator.cpp \ diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 42bb091e25d..cd71b4b3fcc 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -4,11 +4,11 @@ res/icons/address-book.png res/icons/quit.png res/icons/send.png - res/icons/connect0_16.png - res/icons/connect1_16.png - res/icons/connect2_16.png - res/icons/connect3_16.png - res/icons/connect4_16.png + res/icons/connect0.png + res/icons/connect1.png + res/icons/connect2.png + res/icons/connect3.png + res/icons/connect4.png res/icons/transaction0.png res/icons/transaction2.png res/icons/transaction_conflicted.png @@ -43,8 +43,12 @@ res/icons/lock_open.png res/icons/key.png res/icons/filesave.png - res/icons/qrcode.png res/icons/debugwindow.png + res/icons/open.png + res/icons/info.png + res/icons/about.png + res/icons/about_qt.png + res/icons/verify.png res/images/about.png @@ -87,5 +91,6 @@ res/movies/spinner-032.png res/movies/spinner-033.png res/movies/spinner-034.png + res/movies/spinner-035.png diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 77cfdceef0a..45c6ea7be54 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -285,20 +285,16 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle) quitAction->setStatusTip(tr("Quit application")); quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); quitAction->setMenuRole(QAction::QuitRole); - aboutAction = new QAction(networkStyle->getAppIcon(), tr("&About Bitcoin Core"), this); + aboutAction = new QAction(QIcon(":/icons/about"), tr("&About Bitcoin Core"), this); aboutAction->setStatusTip(tr("Show information about Bitcoin Core")); aboutAction->setMenuRole(QAction::AboutRole); -#if QT_VERSION < 0x050000 - aboutQtAction = new QAction(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this); -#else - aboutQtAction = new QAction(QIcon(":/qt-project.org/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this); -#endif + aboutQtAction = new QAction(QIcon(":/icons/about_qt"), tr("About &Qt"), this); aboutQtAction->setStatusTip(tr("Show information about Qt")); aboutQtAction->setMenuRole(QAction::AboutQtRole); optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin")); optionsAction->setMenuRole(QAction::PreferencesRole); - toggleHideAction = new QAction(networkStyle->getAppIcon(), tr("&Show / Hide"), this); + toggleHideAction = new QAction(QIcon(":/icons/about"), tr("&Show / Hide"), this); toggleHideAction->setStatusTip(tr("Show or hide the main Window")); encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); @@ -310,7 +306,7 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle) changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption")); signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this); signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them")); - verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this); + verifyMessageAction = new QAction(QIcon(":/icons/verify"), tr("&Verify message..."), this); verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses")); openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this); @@ -321,10 +317,10 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle) usedReceivingAddressesAction = new QAction(QIcon(":/icons/address-book"), tr("&Receiving addresses..."), this); usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels")); - openAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_FileIcon), tr("Open &URI..."), this); + openAction = new QAction(QIcon(":/icons/open"), tr("Open &URI..."), this); openAction->setStatusTip(tr("Open a bitcoin: URI or payment request")); - showHelpMessageAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&Command-line options"), this); + showHelpMessageAction = new QAction(QIcon(":/icons/info"), tr("&Command-line options"), this); showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options")); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 9d829970f0f..9f8c0a48441 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -67,6 +67,12 @@ :/icons/address-book:/icons/address-book + + + 22 + 22 + + Alt+A @@ -84,6 +90,12 @@ :/icons/editpaste:/icons/editpaste + + + 22 + 22 + + Alt+P @@ -101,6 +113,12 @@ :/icons/remove:/icons/remove + + + 22 + 22 + + diff --git a/src/qt/res/icons/about.png b/src/qt/res/icons/about.png new file mode 100644 index 0000000000000000000000000000000000000000..eeef943355782e807af46ef65a7f10c9cd4a899c GIT binary patch literal 5925 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 literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/about_qt.png b/src/qt/res/icons/about_qt.png new file mode 100644 index 0000000000000000000000000000000000000000..d3665e98925eb9b8e63aa0cae7da5bd93bbd1a0f GIT binary patch literal 3107 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 literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png index ea53fc3493dde873101127e3e9f37edfdad968c7..ef995cc0b54629c9b8f14c576789a9a00b2c5747 100644 GIT binary patch literal 15199 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 K+`>gMDgOoB>bU&? literal 1690 zcmV;L24(q)P)r!I2aoic|aMG}NlzRW0Ov;r_i@@3 z9`}C5L}c0^+ip&>GU%AuS#pbhBycZj?VMNsl&$~^AD%2D^n`+~nZpG5#V8#l$K_vp zfQ143&bO;a0ni()yq7C8S6I=6-E(Pv@xUizU4P45>`Q7WxKX0kdboXnpSmFFfl`P(xMeuS1h?EL>{ zxSQja(07kk8t$5*q02~3tC|M6nwCyA^7|n=MTjA_1&!X!uVT`e|C>)(74-=&-+St$ z0JuKfp4*3gXNJSt)f+bcUC}gTqO^0Ik{T5ijVh{IG&Cr*GNS+ssgMtiW3oc#l_o-?GVpd@)+sRY!ros1Z+?2V z=kJaLytJ=j&j-ckGWk7plUe{K#-V@MNPD*$d5?~|Ru$#-qkP_G;(CXL6FIj?&THi3 zS}SL7=}4{CkyfjvyxoL∨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 literal 864 zcmV-m1E2hfP)nN5pVigXr3C_kjiza~ zFwQqymW7gS$EY4Hm&-2!82Hap`uh4BF81_{#x7lvlXo79a8P|X$_<)pVxcGEvI;u5%@K)45&!TW^(sT1=E56Y$J)$qsQDcF?P>cKQ?>yZ z(JFTqqCXg%?~=17+#V04CQvSwkRw8gbErNany8k9y9z_Jp-Eeocz-#b%{H-6D70y{ zw`RS_=}4whuxuLwl6DLEd>%$F2NViGQAau$L_RVPvL=izwe#v#Rc&RqZEv!IVMwwX zs13t*$fRmoHuO>vrant&6Y;t_d|J8$k;RLk8)X=amVk5K!c@!JY^xf|!iM73U<&>h zRA;i&=!;L{$nXnXcsvM`bIj1d+XMHYlYocBHJYMXL`bBQ2zloq5()#769jg(wn9o- zabVJwOb9Tq8$0&whUsyG3!y0#oa5UY*PW9^3yMiDYz{c!0)loS1wlH^aD;yT&cFbN ze{K+02Opee0A8u7By1PM)c0@5%;sT0z)(n;$-iep*?}VPF_oac1l%7#fKvKe>Fn(E zEcg4zmN&0&`1)=N(Qqy1xV?~$y7NUynUiv%SS0AA9IgzWc=Yhc*!1*j*4x`_Bub?N z*1I@gylMrskRQ*-M-fkahM_5#B6lT4;?vI*?mitvSq1ou=VG!@I5a#wT&QMRp^P8h z?)Ue|#zysfI*l5S7hbmqSNi+0XYXG4gMo?@jEsmI$>ixLLqlf)i0Z!}DbDBb|N6Bx zJ~Z^XKAT0zr9o&6`ws5MTzd1NiE+Fg7)W1FCU;lK6=nRh+S=M`d_G?*=X`_937KKA qf)KALaHBIbGXt?$EDu0d34Z`uKgY>+))0#T0000qj#P!vxX z{z@WBN)DwQ%1n{N!{4ch=TYyT7tf39{(i3O{@kDI<;}!8+e=HTNdf>M?Qk0Dy35$# zlGw95n^w>ryVygt!Po#mU5?Z*f6-kJ4m|CO0f4x}0Famr0Gqo};tT*pLjd4A9spoP z0H91MZNZ(`T?hv_*&_jA-O}->Eg2KBSqk1 zJcp4Ydo9D(%ob@2+F#bG5(>PN&Bf|~VqqPpO{!HK?D=mH(tf;gwlhr ztZdKEuLTn;gnm>_9I@8=hn-|_=Q+}}m?D#9#R7$__9CrmzoJ&3Yhqh&zkilWn9b!R`>O!?zC|uoRB5se{ z(QbxfR6BHj*3aTdomq*+Z>gdt%b6}b-2AiB_WYAm=mDkGFYVF+${>oBA+n`3ve`>c zY33YTrplD2E}4)$$5y^GhI9$ zN5zylZaTaeP73GSwdysDLtl0~u*O_+v$iL4s$D%MJ&aq4d}Y?u@#lHw=W4<`I?u%V zh8cFmZBJK&J|de-tB8iS6N_?ZE$j7nV)dUC*qzmS-Kr>#(3yKren&$lmnI!dewGng zTGD+rW2pr$81BI8T6JNjuu?O}iqV=mX`=qGmeehoQY1TZVo&oATiF1G%lryTm1U`7 z`~}K>zp|msML7M?@tJKS(0q$WWFhN94^jTDKmdwwYv&&-a%6A2;`o>J<(h4mu0u7x z@!Fii?0%(9FbE>%0_Xd8Jk~kMm;<}a#FgJSwX+ERkvQK?uo$l~Mjtxc(5Bkgw zT6uHXx6*$d_NJ&exuvM7=V&19Z}%JcO|4g9A9m`vfTc(RdX+l@r^52XC{&TUjBh-C z#qEimaa3TWjh0hAQ0&>yoX<44doAvC4md}rK8CN|WG5|&&b^=h+GA|-@eu{|8+5!j zO}q(iSiMgtM$gpO=|c@1p^08}A}n-ykYjv?#7NRW49L5L*B0tlE`*n0*OiRkuuxP7 zQsq@^sPrVAH8XtK0rs+TlPT$_`5seW@{13-j~w?s)-|oAzy~Y9SqW0^Q4OFg&5{w&8c~M#GYQmj_WV5)0uWz4#=e%<9VbGqKS()0Tdli*? z^)O<^%szdqac4*G&PFkjLT2CW07g)R)sDV0$$(Lu2-rSMhEKn5JBiiCv%BTj_O>Gk{8 ztK3E*U^Dkt*`QyF3o5I8qOAi_x;oD!k7XlRn_?^8f}AVNDQL=QoxNxeZQ}*uJBWsDi%U zg`u7fyLhoW(VFLTO^e~)){Eg|Z;G}L*3jkq$|D=K_cb;0NK=nwB36^O3A98cD6esYr7Gx z*5PHSxJml=iPKpSiQZ4?1;u)+u-6!s<(H)EdGbHZ>}F_HqgXqGves7V3XExrW=?Mc zPs4D+#D~bq*vs4tWA#8^fS5& zOT6I*^~-hWpnD$u6(*ntpYB2xM(6uyCd1re$>lWC-7ws3AO7D zIA6VG%iZ<(H5W=x3A z^0NU*@8nQ3Op~hCZEwz0BIk<3T07lqp&ZsXsd{5w7DSdNTB6i~w=#WQvY)Pbf4s(4 z{XTe^s$`UB0@+*Gz$bT}8_VU0`K)sp%^r#j%X==WDp@tJ@P$Xtaz9$8EUCS5;=cE9 zSva+o%h`EpvkjG)R$2J6AT^Tqunx3lRX&*ebfr84mnK_$Bg@J7d5dlG9 zhw$)dTGXEi47Di`FoGqTnef9=1-rvAeK literal 863 zcmV-l1EBngP)o2!Z1g@(uoU{O#RfG}7ATM0wbL=0A96WPXH zZj*vk1abOz0f_+p>DDlzlEhi$?#5{IZg<}E^L@|TIgv2-z{BUu;XFK?2ad%S4Gj%h zwr#%_1VM*Mv_GbH134G-p67WpfX^n0&G*#QRBOGVZtiK$x7F0`pw`aulD|M@`3Zk7 zmGt+E?r){4J{rGwAJ72C^Kh|PJi0qy^XuMxOIwqdBJW95X^Cn@W2YKv&b%N_wD3w- zLv^OFudn}kxdo6k@7kXIE)H69V}*aDWJgmoj~+gRoWaYs#q!fCO{UlZ!G`w@V_!NK-h#V_Q| z8#nay)vNks|A0Ps;-tQQaZ;Z<{;9q^GNwO^pB+AMP>+v{>f*q=s!%9&ZT=O+K&SeVg2>knErNRQXhJ~pohOat1lLddSdi~9{=P6^+us^8Zg)*(c9bGdHUFg zk8X{e(bJO`^f#9->8Z&HeP#5lzWn*e`lEN=EG5mG!-6g9>FKG>X0zQ=%8nWl?N>^g pWhc0s47R?$etT|it^#QO*S}zru%^4`6W;&;002ovPDHLkV1oCuuP6Wj diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png index 7314d5302b7e31564d4ffbe95b85863b8ee2a697..3d04655ed9500980d3a5ac74cbcbed52353a5650 100644 GIT binary patch literal 2184 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 i)#{C6u~-8Pd-xx;e71%+z|EKd0000 diff --git a/src/qt/res/icons/clock4.png b/src/qt/res/icons/clock4.png index 07f5bfab5f2161ae1a65fe3ce3fc66f83271636b..c3210c5af1ff0e4ff18e0498bbf0a040dbdf830c 100644 GIT binary patch literal 1995 zcmZ{ldpy&N8^^yDA}JJ^qZ-0AV>Z_{x7p0X7;{az%(lkNWh1xBQ76qA=d8?fm}?}3 zTq~hMIW6>Z%R%d$l7o>>v$`{VPxU!TwO`n;Y$AFdY>ud+vb4*&ov1XrxL zjLF}mC?}iums~n!kfS?!H~~QYFUnuTU1^^P^03Zzo z0MrctI22phN^uC$ISSPxS-QNYbTY3io z3LXTk6FF&oN|eexh|}qDI6Z#EOBGTBDJ=}e83dRpWSQOFkwNBT!}n%+lFJkha9!P1 zv$g)zrtIaqxboBm>3qf9zjn!C4bT`%@E*uP)q2IJLCNIT4*h-Yv`;IE^p(*Q4ojIg z8?86D=I13J`xbb(%P-`~UIbganUhLZMvN&4eob^U`uY^32v=J{9gHO0NLnvClnCP-U+5KQDuM#A^+6bcSN{ohZH@b=cCAxIcMe6B-!kBoGgZ}d1o^pZ$_t;oyTi4Y z(%Kuihb@LMP!$U~^h|Ux(dUU3dQb?nUGAaL;w&|cYkEh9M=R@&{uoy@+4R}QIe22A zoY}~2^pI+PzT5+Dyh>xZ2^+Gb7m#hxmv-~p(Ave}--y(LQyz-`@sPP3A^dlCYKkD5 zHm8|GlT2xw_TI)x#8yl9z9{+AB@#>9`?o{JXu6^=ip9lLJR7n+P_0BQSWWoCd2Dh5 zByBv66kEm6H!J%S-NlT4uT4`bQ~3h986lu&w4pou_x3EkbsTVCZpiLCzfEZumX4J? z4)!=cF}$g~>~+P^Y#)RfG?w^p^6d7R+DVns)}=qx0>&(UkaXbR;Fg|)-z59)b~rNcPDk7xci zTrQ3h^h`hKSF4cg{75~);#VQ@plCgM_lAp6!t6z94cclqPXZ`C68hVm$XRXJsNU#D zZ&?xP=&9RcGh^#un24-zeGH1Xb*mrP`l>JT(f2ffdXia90jLT;1+V-nv|BxaawH_8 z`t~o-)v~(qOa2uHBI%LAfm;QOQL~rFL3nOC+KJR&^!VlhZLk#L=}Yb~5cMl2m`@>E zjgOBKZXq$w?hlI_5FuAs?8&?vi=ns?+IYnfsPupc_7?&-f|zAKuWCx?XJus%zTlCl zJNzNX7vmEz87Tw=a7bjGJR*%3`I1U=(>-&gTkGsVU|?JjD&M>;a%v?5q)fO~x6y5X zO!N}0q4_M!;i#~m`YY?1m?V8FpB8@Tlsw|(M^WM($GQp$quIt-q#F@rLUg4o=3mmh z=q5vm36UU!ohE&ozSTCd)5`UhqQFiwA}Od*mC=&kH)xEhc(${}?Uo{csPGb%}{KWEWM7EtQS+i)m?>)jFw$zJR~JTa(Jm=XduJ4+E?8Z>#nGEYAKvs#yZ4DSi+vtgRQ;9D(d#l{ADPX1C1sW8{d|)R z`mk?b_cnh`hZVi!qC>IadtRT>zBe%mInFx}1{aWe>x{YjyVv?@S6$P1X6q}x)AAd> z37+puXj0@dWsQs~-l4}8-?n~dKe>B0Z9G309V@bDmsNJv=&JE(WiM7qL;k1Mvo9QG zz`CCdrzSg=(0^y2a?cwbS|0YvFkGzXOrI@F-FQ%x0xA^^pAB$vE+Wk@cEsrxzIk8S-yJqQVO^{soJ-21boh?Oo_qc8Sf*!h$fIC!tQ6#F zwts>})tF<17r$`SJzcwn*EnBQa>#B5qeQpCL3`FNX|`lqt9=exw{|&5+bxHaeHa4{ zE`Spe#-XAp@l+WA1l-&LW^N9HTa)3oD02kL(gq4QN5SDU>oueQQ;3d=Y3bP6ZQ~%mg;)djvMOF*P@Zn}B`% z@L*h0Y)m`{?8Qu=!w4*}>G#l&8qa3LuuxztQ#c%qNnkJ|z;I(QcrfXBr0g6(z!9;v In9z*>00NMHxc~qF literal 869 zcmV-r1DgDaP)C%v8`aWLO_%nD24_Sf#%nO{wj$1TTqE8 z!GM4Wst5vtq*k#0PRW`SVx!VLY`VdA^VrwjJA3Exc^9>WoZ)Z=_|7@Z2V-L&CMPHD za5#M2^Sm_Y=A^IWx+?GMf)L^cfClz}?Y&P=Pj|PqtFMzs;{&0VI9h`-9PYe}a&-e6 zg-yD8P5ic5pb>xWCIA8e>wojq)YM2%PjD&SnHV@^S%`B9T`NEo4PyRD@C3`fWm4Ja zYd6Nm#x4P14+5Ia$yDoS4|ChrP7%f8eR!gV+kY(K-sYb$`W}jZm%$qbubq*B!84VQ zhKGlb`-I(mb6Z${)4}5b(lxZS1VLm&2p6TDEz}(ii-nNvb7A1(`i}-LW^4AseES!x zE8=M@8jWUpo;Yw!*Gt&ATYyvw#sE?(R4NsSMhRe55Obi7i)cq3v9<=zy|UBGIX`PD zr82q^VZ=DXkq)S)S!sAu!f{+k&w=sH#9Z)zi}VQ>PQ8JyEG@~~jJ<-x#&04 z04UfY1wezCht)L!V|gek3)QNbw*kz97oaGC_0<(T)mK95nH2yEMDkx{zWQti#N0J&VQ|Eq7uJ;%ICHFb_=W?rDHvx8IGsC6v{ld0`Saa$Yps_m<|y5FyXeDD`qimZ*~;oGe9nHM`&V}XKpI@e1>(BXZ160yUT3Sodce8!;=EcFkn$3I74Er!NG}Iajh0ZFa v(t&`?C?$Dw+s%cQ%jKW)`FsTc;XnKXzVg5yGnYgS00000NkvXXu0mjfgBzRe diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png index 27e9630eb5a0ddd3484ef0f998ab292351db550a..84a9fa2842bb25db5a99fe8d4f73f5a342f30a41 100644 GIT binary patch literal 2682 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 diff --git a/src/qt/res/icons/configure.png b/src/qt/res/icons/configure.png index a1bd70aa4e94575277c8ba0905d8d6fa2816853e..fe9c6ec5ecf27879b8513434a95e9a3b3a7a39e2 100644 GIT binary patch literal 3891 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 P00000NkvXXu0mjfB=kDn diff --git a/src/qt/res/icons/connect0.png b/src/qt/res/icons/connect0.png new file mode 100644 index 0000000000000000000000000000000000000000..99bb2575d61d2c7d3d24c4bd235c991298e7d9be GIT binary patch literal 16890 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 literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/connect0_16.png b/src/qt/res/icons/connect0_16.png deleted file mode 100644 index a397e7e6a78a6fd1eef3b934e4c8401d325ae023..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631 zcmV--0*L*IP)WNFzB?|Y{2upzyK^lolYlJtyWC|OS;Tz7J)zjlF6j)HUQ@HImohX1uTSd z97lrx0E(h8z(TRZ;h-ANy8%pK6`P^!I%t{(jYi|CNvzds;ZP_9>2w-g zE|=9f5=Ns@D3{C7Y&OB;@!SCL#|;FekhrL2N(PC?c`zD{U^pCF z#S3BBI(dX*GMjloVlwV-0Evpl;#IrdmT^x^AFiw&(52hvG1L623X#J@Xcr0-z1Nd_ zF4qT?ej$Lld4s`#ZJhPL6C{lFJ8XSveH}W-$IrR7HL#CH{6yE^5&&NyW0-)=nbogQ z{2&&CL?#2Ftu5dXbg{eZ*G^9}<`m4WqGYdHL6oLXIJ$4yENt%Y!}qf@_;qpuKErU@ zDwRqeUET2cd?tj={~^}*5!k}~d!5TgG*OJLRw{5&D#7aZHhj%yjUNXG0zLWZ=*asz zm5ShqB4}tBfqTJV@Fjj&MO>bee0iyeJ3IM%%gaxG)@r~d5=MV8==_nSH?+`vl3()q z11UvOHzn!!3(YY4nr@t{s;YOp-IWRFja)x^{JB-gx90$2zuOgBviu(F^M7EVBZ40p Rt=|9u002ovPDHLkV1l7uC{O?Z diff --git a/src/qt/res/icons/connect1.png b/src/qt/res/icons/connect1.png new file mode 100644 index 0000000000000000000000000000000000000000..dffc692c76dd4d7b8b8e48a1d3309aae026cfb21 GIT binary patch literal 16870 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 literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/connect2_16.png b/src/qt/res/icons/connect2_16.png deleted file mode 100644 index 2a85ba50d72fef69a8f9d1a387c80145ccfbc170..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 582 zcmV-M0=fN(P)<96FfsOK*m=Qgn$YZuFK^zzlY$c)9Hvy1wjzx@q7XweBWQG*Xt}e0i#~8r(8ww z2TvL#Ez9a4EEqFbN4-?g?RGsLnW)vln_bxI{T{5>YBm1jKVU$n4~IjEx&r)E zDixm+j7&`IJ6PVK6T{^dc;^YQOQn*7I}jomDW#Ya7$zo`kOUqX_}2409@zr>&1RF= z34x2K``go_#|H=G?(R}hD9};6P3D=4xhIz9D+Ye97hRy?&}bzJD|H{sGv0rY;iE99Ut{oWdP$fEQpblgTXn2PrHg UP)Ga_g8%>k07*qoM6N<$f?dJ;E&u=k diff --git a/src/qt/res/icons/connect3.png b/src/qt/res/icons/connect3.png new file mode 100644 index 0000000000000000000000000000000000000000..3594fb117c33fe9ce151c545f27538f9db53ea1a GIT binary patch literal 16566 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 literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/connect3_16.png b/src/qt/res/icons/connect3_16.png deleted file mode 100644 index d4b35ecc5f3662af9f93915484a4da2db6ee0492..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 591 zcmV-V0bI(n)Efiw+KTD#Qv3Zc=dXc?;}3BVGK9YHaHjV;=RFu>F3W9ULAWd2v$=dKz+2$82&OMB=yW;( z&;z=Xi}8YwUR9X=M{#Rw%K=V+(}RNp+ht7jUTX~93F@_I&dwcI2jYb~`+U>S8 zc0v;NtCnBG@~#s0k4kc@16&};9CxfBiegCn!Wlu7AtetO0ExUN8JTeQx&E?u(tC`7 z8#ix#4TlL+*#J}`0)d1uiFb9=_PU#OahOq(_qqXLD5Xqznz(z2}*du~LsKMl*a|RJ4xh3VCEa;G> z5rD;iad+0%o?mQiyfAsr^_7(`fiYl|pa~L~u!mT2h;KutT?&PQ1-O9nJkPd|n$2hB z<>ggxX=!!8*=&Rf7%3Z_Asm1@A9HPe9c@{h`aa>Ef1idy zWTeIi#{&$p)|5)63J?LhSS(iDpi)s+q6j5|WMV=OqEnNa0szA-Fmdi_?Nq^Nay^uL ztP(H*DBt%z>&@cg{NeWYLx8z@{l|WBx4QF7Em**Vd1rHWD)*W{SuntpI^W-Yo9+US d09$06e*lLIMhb60(Rly>002ovPDHLkV1oGj2R8r! diff --git a/src/qt/res/icons/connect4.png b/src/qt/res/icons/connect4.png new file mode 100644 index 0000000000000000000000000000000000000000..0c667c7e06d861ba666ac22954376740be38ca60 GIT binary patch literal 16117 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 HN@xNAxD_Nz literal 2240 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 diff --git a/src/qt/res/icons/editcopy.png b/src/qt/res/icons/editcopy.png index 7807c59a88054f0fc3720100618bfeba55661108..db0c51772c9875cfa4e25bcd0a836b6b3145a95b 100644 GIT binary patch literal 1295 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEX7WqAsj$Z!;#Vf4nJ zcwPcw#uctzKY)UgC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6G%@pN$v zshIQj?(XiGREgss-%k!TahnivG+Q}Nq4ijdOOgP$?kD~u(So|HfzqCWNnD0m$}Su? zRw$gh)n(Szu}0|_?=6l%&I-q5RhC#&k8c}ih#vJhbmrXedEe*!{cC4%_T7hh?Kkz) z&&@Hm7M|JpGU|F2L-uLLj$(#KG7T2&3g?Jr?%mrFtE8lyjhKeM>G-14Qu z2kxEuv*KG@m9T?L4AUO&H#xT6{yNORjXwvR?fs(JaQMLDwa;J7Onq=}R&`Sxi-2G` z<9p_dRnz3G81KZqp0VKP=>r`%820r1|M9#?_CwCvqqE;LDkYhJ@Vl(|>%GW^jmNx? zJga7KTmSLxA3f%E>o;y-mgv*!pA060<^5RW4Ilo!cjip>YQIYkEm{hr95 zz-!4+$mcMJS>QRt5hP}5k(z-JRu*4a1$0gE0p$aC50oVYH>Td+U!2OTCFkIh z!xp#n&r$CEiA$Om9cK{ys8YZa|4_Oosk)(~f}vvFm8xsKN>{AId@vy*Or zUb^k){pil+4YI7)B)YyH;689$aHCq>)F~VeA3N&JKSaD%^eSLj{oTjq&V{Ou$f*__ zdomCGu03QBubIOx$7J^J{qxt2zZ;ul`9p#_8J?-_x&M8pWqd+)?Ck!I<^$z(WDj0@ zcU<#yIJ5eMnfsa6_xzm7Eb!^(jQPI5?0NS-MF|q5&>@F;yq9SMm4iS8rUw zJR>%Ie$2PZUe~`O1~T2IVxlxLC& z`XAgozp}kLaN*yNfDbMKX>#m&taiFvpE>+tvY9dS{C2q%)2?}(F`WtO8~A&f4{vWc zJM(ANYsawFCkzkVXjNXvSZ4U^+1cC!VrtgOH^S2!9{;Jn`!6F+F4y|fn^mj{haYr1 d5}DKA<=;>}=i8E71T2?;<(R9V%Q~loCID*(k0wY9a~+~n@<@#^aC{QLdu>+jy(<+r!DM>YSXQ^z`jcz*Ehz#-{0Zn948Dyh;GVctl&gSk+`W7rVw3Jk_*7R^>imXspCR4#$*H3-1CSALjNLx$rzIj zVAS`>{udfVV@x*SR)e(`yH^PP223`9Bj{-GGQ(s8^aXQ5gU35eE`XwRe_{7Mf%^wc z#tOZRF-~<1h0PNt=K$*4JY#YWj@so`z258F`$v&%K&#wh`T6zz^NYzAu#zo+$qm3t mt^q6A0#I8WU^31EEo*-TJ~w5qT=Sp+0000`b~`h diff --git a/src/qt/res/icons/editpaste.png b/src/qt/res/icons/editpaste.png index e217e308ea43cbe2bd4ca3c41415f76968972625..be8634674d210e0a70f34c4cfec4400ac0c52335 100644 GIT binary patch literal 15778 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 B97X^D diff --git a/src/qt/res/icons/export.png b/src/qt/res/icons/export.png index 5c1f51905428a5516438333f4ba59a42b6ba1696..18d05961940ce6f5a7dbcff459ad484a4a4c42a4 100644 GIT binary patch literal 17005 zcmeI4X;>5I7RQHxfUJT=0TE-Uw{9UTOG4O#f)b1v6x1qNCKAbJ5*8ITQL(|I73zYD z3Q83NDyS$Zg;+Q0MnpkTQKU*;3R<^oTd;Qm2sq;0-sko{_sh)lgyg*EJ^wTFd*5?r zz6=@csL8fgu2uj5*hYjiqoHrH@ndNY{ryHb>oW8;SRNjy1b~P-eNNl*31b?MTf-^O7A4%;{T`bKnB3 zpkEAyKuC{fPU=YqS^l^Ll}b)05K>Z7JX0v1GQ|P{iAJLlh-3npjE836m5Ze+ZYo}? z^yn6OufqhDe1%A^63L`kqb`>xOH%pcaK=QvN6&Rhn6J#oxGC}rtw+T`N6Q0diF`1xF?m2XyZ;_Irfb&`|7H7MCxQ8j+4;5a9Fs7Q0UhWO7wt0JIsY z&^E*qy*VTzokF9NeI^h|bRw~zNcT*b21_Oo2^SBnL8bNA=rL1eM|hkqo^ zl<|{{rP3oUfTVdoWPulzFTe}=L?I+i<>7fkk^s*YcvC?k+1H0c^Lj7cFZ?6vX$le4 z=D6a1bBt&IpQac<=A%^MA| zZwKpbP{x?9vZZtR##R=T$*cdR~E!p4k3=cx>FiiS6%)$M%KBNJXjua!)$gaK9+y&9b|h&w!rm zzyNPAFACHc;luC1#RUU`Y@)c3`M|s=E*KDG6UBwh2j)d_!GIu}C@y3^FfWP= z1_aqeaUt`8c~M+2Ajl?)3z-khi{gR-K{iob$b4X46c-E#vWbYxs_%VGPzt@InF76y z$!wOlLvM0o`Qgzl09Y~x0Mx4h;I}`a@5ca;L`lxJswv#G{-#GrKPM^y)#FJ7@#t9qf&-ejRE;*Bpd zFX1pxq{jakaWdy(k=;axEU9}eSrHbp^t#Ww`p25H<;!>2QzHze&(~;Qz0tRPJ9G5% zllOLaIL2$VcOGiadb|$lNOmr{dw5rCMop7@&YVW;J637Z##u^c!7htdHYaIU>G&Is z6SwM%aAbq2(pnN|aDRKo@s^E)%L7eC`Wt)si04^jjy}ebZ$jQSz~J!Ka9Fz^N4{<} zv4+91{J1j$hs9@%<`9EREEso&>ELo-6LV~X)>0l7X|OX*0iMknMw-WT|EK<)_5Ph& zl|xozkPDG^E-TsWkyT}4+!+dvOn>|s`_kTEYcN3oDd`T*a71S)6lOvFjhN zUL7_RnZ*vtzY-BPC==@@!ITh!*$w*4_4Vq-4o{ZlH*2LB*?-zZCgiuxz^5~s;=ZXw)eTfJ!` z-7IEA4$n2Wz>P9T^Gsd6uB_sA$CsllsLG>?Ol+lR@hgid%z|p2d+mdBE(u&Zv3*?o zkl?u;Q}xTtwvI1zi)te<4a?lwcx9rq++L2I6n5?VUg4jwVibPKfa4sa7I0N-IH{)qL4o(Pfqyb#f4iVj~{N*ywGl*(HUZv6dlNL z$hV)T#9VSK9aYA8fi+Ycf_GdWwFejUbi-KU%D2h4SDoFZX*dfBRNEZ?<=ageCLT4j zI~t-(o#Jjz9b?nR{d)PhsdZa?hb4%9y-RIQj%jN9>6lx^UUecK|3lpL?;Dm+u{jj! zf8^cjnAW5bqh>o%=(oNw5pRCDzN)}Vzn0fft8FU&qNbySM4VCt6km-vQ7HaQXW!ux zoi$%$9s@MoEZCvggKb&URYo&Mnxg}>zakQ5@@UY{cIiH`OkZ(tp*m;~Dd!+Q{ zjRRVXoFk`aU*dYKsj|<%6p$B}b$YEMF1~EI?a2hUz~p)cSPSfdf#bRr@L*=iak4A;z^%>7r1pw zG~M8nX?kR(&kF9jpog}X^t0Xb*PnNMeUP&|&G}*><<#YdITWj+==gIL-{V4l^TY|eBX%%X(MV62ANStA&PdTp(J?_Pie966&K%u#O(XQGuUwKP^A@iS0_UhW@ztkMC zE;c)OeD!O!?uyF4vtW?;WXA0|j}}sQm=(F7YSK#ZTw8Yijk;LETvNX&`K+@;Md=CK zS6!(O8Zou=kD@2JN7tv$#oQKDT{<*_QMV8%KHI*2!%zC}b@agc&1<**vg8&qofo)% z4QJ-wou2oV&eMaRojB#_;L~)BD!RUGJ?pjO%BLMIZv%5CtJ`%aR@zL-^@zOOQrVE? z!FlZ*?EKq(ZP-Zj_L}j<?^Sx^`eAK z{UOR#(q>b+Mp*r_RQIm^Bw>%f^0VWK7rySg;p!{9?!WezVCK{dFP;IZ>2?M9`}%U@ PKZJ+~i((!OiC_6I<-_re literal 1931 zcmV;62Xy#}P)#wsP7;z-1&IPssO`2@)pl!JZRl3VmPyK5RI7B%E>T3Ywl#eLt7@R=mPK_} zrDX!xQH3Q7Ei@5AO5`LbCr92Sk;uz=d(LxhhRmE!M#9c+KlL|r&HX%|uIu{W_dL(d z&z>OeK$lluwDz9)?2L(9dmZ<@V(!b2a^ExZ*!HN7W{k9uy&$b+lwE49s? ztgWss`m***Eh}2CK5stp-I?Cjxf&3(#vB;BT`xo)GoNm;$Lz}lvmaLeThcodc`ll9 z7dr4xRu5K|JQ%#?Z^IwG7?V6ipH{Bc^t>6GVV|z4xlJW|^vvu2JTpO**k>i#ojfxJIYO zX-xK5J(K>N2A+LZPo_Sj$J3uu@Y*6 zJ-k)8a)zWV)l{Zv(wbByCgtnHoh5p6{bpI`g{kkZzG}a#yCRZ0Ds*F8vAmfW-%N8p zUaz7`slqMoJmt}xWqYOa^{O1#)72AtaW@=oM}}+ZZzNBuu3i30BNnB}rvOWLuUEUo z`xP=PT)_z;YW2ta)NgW(=B-+-8x@t3B)_Sf%v@zt>aowHJ(IMeEq~>1INlS(pAatP ze=SvRSNw{-I-Kd%k14rUs&khzbpCRN^70(2z2TN5nUXwy$?cQ;l1^UnD`EalDgQ4j zj_p*{2|9Bpc1Q8`^^r&^A4u*4O5U|uf8Kmmcfv3wuU~Q-lFKL6*2yPn(nmQuzHh1Y zRh-^y$&x#M2Wnhwa5{m^L*NN!aBnx+x%t$1xh{c4O`SPSC$A z6P|4QMijK8DZaReh`n8~nKN5RwyjdxMosx}yAGUpt0ATtXzmF#SGh|nu9ga`q%uQ# zWnr!kZJi@+cuvz>@P3mMc(sb^l5+Nz<+>o}dk79^$o*yPKT}Kq5MTldv_^o>Pn`mj zF}yG?wj1jX_kl;-GqHcmDJ>zg$xpG%%Ql-6$oe;ULWt>8MYhdBwHE-?&{!bAZ-V!x zc|f&Z=-&&Pca7nnXIs;6bocw>LYUNK0Mo*$oC0iqM+TIa(>fYDggQ8$=?3bJ8D@@{2RJ_Bww-tS5JZ`l$hQXWM8p! z-3=B?V9$;E6Ynzvrh)c>cefix#kMCYbuh-mt$4kcH6a9=HyS{Ynw8B(pYsQ(t|l_t zpkt_=V;Qvs0cQPv*EbI|{_%4l2yP$rXb z&bqH=fzL;)Hg0-^<#6+(zRNHnjsw@`5F894&B0nHuLYcCa6HY;#-w6aEzYFS z?t^aa7&@foz(?S>jot|bJ2Ot3K58<+j3nj(Ck3`_3d$iU=%#L(g|>j;I(Y#{DWsgK zW&P$t-uobfx27Ip@r+~+tlk7^n~7_;jU9{fXccuYU0-a?%dM@6G{wRQ%kk=M9i^Q4 zQpQV)pSDErZz@&3TRM?r>hFiE^!8e(M$I~>L8A}p*Tc4GMC>P;HF>^1U+|XBZ2p7F zQYJ_luS(gkOSx0()K^C?V4(@-wXhtVxx2&jEgzi;uD0MS zhR{&J0!9rO<=`s7gQOz%0y)`lsQGQ!_Ujq4Vg4&)CWP(u)z6x;H!VLp=naPa;lWTU9qFe)q-RE&QjiS6#!|rtH zQW0d9!sSZHsf7Zdh5%S;0xRr3wW)GJmjU7J!rPpqI^Roaj-R3{UYs_c+mYuj&MP+Z zoYiJlA!J^=Wn`;2s^b4ae|Ta{5WC~=ZFYJDY<&#g?F=I$;2{e{@;~zP=RdG*GViZC RnzjG{002ovPDHLkV1oU{ux$VU diff --git a/src/qt/res/icons/eye.png b/src/qt/res/icons/eye.png index c4d182adbf4ed1140b7c715517e07802758ddeb5..7036708de5d9828e2548e79f01674cb39577dc3b 100644 GIT binary patch literal 2806 zcmcIm`9IT-AAfJOIWid??)xZLB}pa2)*QLE93c^rbIUai*@y@$8X2Y`XXWTq?&DpG zPmV%!e2lC3^U8ejC z5!mkTKIhxNOTv+sHWx*9Ctk!qZTA)>T3?C;0GpA20ja{=-PnD~Mq%8e@PvRUl5fN{ zfJ7o01cir0`uP&C84w}@3;Ac|06;9#25oUMwrGhNm+694>^1Mw&tR`yZ}Zgs(NI2u zyPi=&^?2=y6w%MOgf^<$v)1n+(}a%&jj-A5iEY)$*fWGPi8AARLg9^!krMjix^JNKQ56vt zwP#>5c$RC#t_}PKiGg&%id}4(RoTU@B_*ONYIq6;^x|4YyCy2dLfotAn|{pbIIC_c z6uN-=7JNu4j5t|&+YFSXy4Y41w`Vn2SnW!DXs2Z6J5HX=cSz?``Xs$cb+lB~TL|;m z9z6!B!%y|V55e12)j}{|AKaA3ONiM6QbEY{b<*h3xHAGW1C~286Z)ne4ScdlZJpsDqh`BK9D>Ail$m}2#T&VJg z#ny;#ysnJcs8HIUNUrQZ4quC4+nL3~oUGzGvrFp-xxs5};=*$5+TJgL)Xz#`3y{uI zy2oedfRj4q5r!zEdZbfvpMj4oQFn;`s#Z(gkCDC5-bgKvco=gA+A+^Q##D zlL9^RzJ;V!P_LZ5tWZb7B1nVtl<=wL{AuvI9TQJ^REFLD{m$HX(V>BTOl-pw*40W~ zZ*9Ud<#%G9M{hl$N_z6-CEIf>W^}<=@q~x+E6t1FN>h_3yhMR`x!<3bkon>u&Mx5| z^x^Rn=c~P-N-x;IVm08iD{x^;m4%%cSLM5af^cy}IK(H>tsh zqx9>|N*H&xyzwu4*4Zv9$Sf;M+>?5S=Sf#v){&j#41bfs;{6RH?wd?)@Q{TB99N{?g;w|v$Sl{ru5v(Wafv)8>hvmJglLtw*DrCqSJ`XLDtV7GA+un{IV<3ZZ7rL z_KVitl<(zb8lTUWRJAyybu;nk*I5`G81 z_3+G_C1l>m;p)uW5ZY|>q8K*_9v`JQ;Pcap*5L8?lfiZ*c*;0) z4a3-OJy9v8zbUAE-234i4tZ)Q5H<+!4C#yaLEBENo_Ea|96vo7Pq;hyJGV>7O(qZM zX^|gJw)C8TFZ59{I@}@q*9&-Ju|sypU(TPRrq-p4gwM@(bi|9FaConl5Y~w^6`%Ud zs_U@)aNIOm`GM|K^_XlssMv#jsI?Sm~w-9lX!@kxp><)@d5F$qr5x0K2JZF|YA9jzEnw+FF5ODEUf zJrosm2%68`i%}l^B3IPZFmWc3{{}t~ZP2O&*3L7yRZlK%-=0q|wv+;e7i^y|m73j| zmC@UjIw76ViVfWJ7qjC11)utIT1vBK486|*7oZ+;Y2~ysYd=%n+#orBo_Z%2$3$#; zQtm;NP0STxG@UyiyD!oKGyCI)IK%e>?|)7u8`XZN9nMziU;VY0j2T=E|DXSk zPZ>wEvaUV!Rm4HMoB0YZG-=|(tlo5RKV+>58tfqaQLsv!S$Fkz&0Y=iZ9%g1s``oj z>EAqQB?k#b9|v?NPL2H;Gd<_+O{QGC*?YOVs0Xmwm)$me{-jI+~nuWx1J%k8U`DN-PDn=Z7{R zSz8I+N^4j1>SSVi3kOB%413#r#96#>r+e1q}^Hc zV3Wp!aw*yXWn^Q|X0r2)73mqK8?#n2>PN?Q4RG>#*N2iLd#+AZ*k}IYSR?CB5rwB=u9xCz`{2__O#F zV_F$J#&ftWQjQ<)_?n`MGDV|@dOtQ69+&D!=Gks8Ym$fMJwNT)P6`)11J4-)$;K+8 z_hGA2y(3Ws@ttK&T3KbPBcPp&>-gpFo+yl=q)Gl;F4TkX{6`IJ2cm8^LY%z*WNEjf O0yY>2bgiXN(*FTDL<)ZZ literal 536 zcmV+z0_XjSP)W;VR5&6(dO?x@e&|q%ht7 zGdR6~s}6iHbMN{8bI!dp0_U795)QUtENmbktcUq1YhWKJAOw8#yf2`G8h8RDTW1>x zFgSI)-DirTY~^w}zou!cjYh*oo3bp=B9X|XR4NT?wc7i1IxRwXM|Eig4>(UG5*PJ) zU9MCr+oox*2Lb`tWMVJ^A{VXE9_3IjX)LYN=}e>Q<6tnD8iv6MRaH4fv3Sj8`G70R z2}f7l-ltsBkah_!*<>>5L;J4TY-Y_>C=^iHWS5s$)_XV{WuKpK%-*M5(x6b53~pMj z*7|5P+V&tQL6Rh<&*$^^IE!1l6#;YDSCK>m$LVxBn#p9MyAos(@~e-|qt0(OBPc<1Y5Fa$3^1BU(W2><_ISlHlK afB^v9dC^iz-u#^a0000co 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 literal 595 zcmV-Z0<8UsP))U=I<(!Y-aX7<9>mi9o?H_F_AoLP-|H z4jl}~6vtoR_rvL6#}518BhI|{{l53}_jCy%=zqd>^#%y}Wnpw3+ygoY1OKA#C+L70 z_y~rM&N1Lg9xICSRM++GY&N@Tn&!1eqv7SGrfJh?G&(AkNcG_r_+$jk3I$2DBb8maYoJZW_OFc=IbmSqXXFbu&_ zES?BWI}p15NMI`AB+ zCf4iqZnfL(b?z9C$A1Nb!G5`1zNl8K7vb^v{T(4bJ(1zPs+b)_(VT_IlUedp&Efy`DD%YiGg7BgO*&0H2j5 z#*yub{}?xveZMjA8e}_2l!?`KZuUv!_NA~fEZh074CO2EHa>MT~7=Ecx$XM#@AyX{JT7%!QD)lo-(4f;8me4 z%y}XGZ%1nPpee2O-L;Eo2)O$8bsO%q`xGjt;DvruA*LnG+}aTnMEjFMm2U#wlMmx@ z{Nu6F;2=$zb1iMIt$on&V{fE>%#SMp{)WpB)(;A-%Ax|Aa2nsHHCo0SO4ZONm}oWm zRuIw)3ByKUK-VSm0bvVSqqqMLG&NDo6UkD8PVl3^J3v^bWsGy9i&Sm-=~RKU8+^8$ z{6O2rJ#&pbh7@Q62$TE5$8uoFAaS^YDdp^9Iii}s{V3}iX}BsZPSP2sH+m1VhJR;A!74aDj~Z*9;zmvW>b zs&rmZFVrm~x$QalSL)Y8LF5-$qpgR0IY2KdC(Q%btd+G5yLlhTqHRnR3%IOzA!0uK z;D^+tZ1^UQI)WNOy5#F&#n=S`IQFXS%5L`Epq-(Ygr(h(RpgNZWvQ7GA63rp#8rtq z^ApCZ7glGy2?YkQHET6b)HVr+Zms|()2guS*3Byxk4GP1dck@i!ub;eMYMR?sGlw? zisnUIs8@^&w2Rm0exQU7jx2DJ#8l@&)-vo$WPM!VN2j&97=ttYH zoN7_k74|(6WDeIV@%@B`b39F2$Og#NxtDWUI!(~p^vl1if~Y=g=jylrYDadFY)HyB zVZ0?-@h8ncoIT+o6Mw@1UTEmhL~J{t>(B6#Rpmf&@eWJZfy>?e9}oIfWV?!SFop+| z=qG^o+h^~+Xb!aK)&0YKv-K{TH$lFXC7+^*_c9l7lbE8V2}-N|8WI%?g7Fv1;W6Hf zi@D7@q_Yy=VkE`9mRw(k-M$>@1u^P764%iDkcdA;-s%N)Km6V(#0tf8kt5+IV9UgJ zQ^;~YbjaZeSq3r# zXQG>4dEF{OZ0QXDY>JX`vk?GZyl&YVUfj1jp+|P>=`&w;P*dj4OcWAfK zo30SoR%%`7;Rf7RabL)!{2ae*>7>_t$glK}sY|?Tz|3zJeTsS>=}}?`P30c=n&{NN z9R$dEJN(;E?WcDw7Co?i`-kyP&OY#v$Z?R5{?gD^qQVVex{Z^AI7{5qyKsP3eOKi` z&i_@Ol3dI44YOVvs? zt+?{gKy>HFZYE?Ksre_??OQ5rDNp7gHFv+PN$o-Xg9sw!2&VwMcV#OASt^_Fee zud|mU_*Pdrd+(=yx2WxZ6f}@vQrOvZ-|=H%ad*rTmb|e4R(J-^t567lD{mEMm!=rq zGj$IqQD)Znv-o_jCAWtR-yf}hA2D#T+TXYK?z|>OD<@Gj_TzVE5bZN=Fy<8iqDcO^ z83V`liTjxQI%Tw$ceI5pY-lM&oz-a=^>!t1xvRmlF*l7>rcM>5wzo?KexBvFDm8nd5>WYzu2pc!Ys`-eAcb_pxvgJ{Na&j zA+v*IzBT&J-FH9>b*Sx8_MuHr_x!ny=c3W`uwBxNw&_N{oa2*`c4I%C&F$!bax0a# z{#KnJY@J+ilq4%@5YZFY)~<2U2EP$IAQhXnA5@LV}q_boKD-=nO1 zOq2VwiQ!rDrT(bUJ4a-_-80amv8trYh*&A(7U3EG=3s#aKTgs^sH&ij9nDjw2P*weNhYwPiS??i<=BvB3| zd$&AizWV8Sot#ls%!sc6*f!KL$GGdbRm+peZ!w$xNs9j^3Wc27{{XSPko+*9hO@6; zT=Pzy2PziciH`<~BczT;bx$AOZc6E#b7*S(F22nf-5hdeYI6=^DTcR$3d}%wZ^{R! zXvVka&-Ahwp43;=rpu3W3s3ZA{9KHzs&;sDDk7Avh}AL|hmCIOMoc3jWyN~Fxq9d? zYK0*1FAWC(Ll*i;DS+_|Lf_Y>2#cd9|`VWosmNa>kn>Ogt}*#zuJf7 z{jd*a49U%rb(gTY-)S4_9~Unv8St=B1|CiISDUD}7212RXwBi9hhRUo=#QOGNAhSM z$+H4hkt#Ss3TQB%b0|q?546&%%<=QLo1y%&2-Z2mh}lTOfj&WBVs|xqg}Q-WL-t=| z#93;ne{=}2H+4lwKi;t=TWeX1GZ#J!sXr7;w{wvL&%csPUN3thThsUYSiaL@5N*Wd zGLs}H%S?dOTkuz;q);72OSiGe1FGj_Dl@caqne?xI-M+k;9>quGF#gPe^{mFZ$YqQ zfsD^wm(qM+Dx4Ohw(G>&veRFc4Zd{n@O(jWXJGgQ=U1bxeEr5ON$TdCO0y-uoyIaJ z0xl3w=MOwGVQS?nf%#A8lf{?BHx%aguE-Tdy1bz5Q2MXXzSN5}&3*^MDU^mlbdw6w zrbDN0^bmycmFXl*+-*dtiD;eeccR;Es=Lr4Taud3VeiT&7>WUj@_JnJtOy{EfB_ zff>_p%$B^6rRh%&JX4cB(rD**q#yHZ-dM0`7M(@-o7y0#aCEa9<|5{vm%T-*T!M{! zyl^LnzXv?YrcThM>hZlt9J4 zHNRWzRPG5n+b3rh(nv2#hWhrY`BSH|)ZT=oWI<3A4O2xdaGt7`4@STkaC!+dkauyJ zVo5yz)HRTk=P$@~Za#35E5dwRIfS$cF*FD5mNe$OX^rj-Y5qVyUnoH-3vZlmB>RW>aQ zs=&7o4}=z}KzZ?#IDx#yZ&z(K}NCmxZGp-;Y&0FB*6@agy{J~qx m7W&VTEB{sS|EJ@KBN1zybz-qdmk|3`16Y~aVV;=aZ~Y&P_WZp7 literal 661 zcmV;G0&4wL`rG;P|h%(7N? zksjJjCUg*CEp!mX6%78ugHYL_SD6<<@ZcXH^f1|F6N?lSu~1OyVK)nzLJP&RAmY-) zDt2N!snUU!#|yklGG1}!`*B)`?XLgeCYLh z8Pu&(UmHGL$gOBJdZ$<{O8I<#$~4WfKp-G=yE+gk5@?KaR716-v9vtTpU19ityZh2 z>pCM8MPU?~%p)dAb4->mGn^G0=Bbu6q_v~Vd@L68;q--mzi+K8l}ce}6INEz*7wB3 zG&CAj80M*#G}vgK44zafm9b8zGv&gdf?zNRic*Hz*>je_<#K|<5&Uhii-DR?q~&ck z+n0L1J}8&VW+W0h?)7>{alN2v?;#Wt!Rz&5cMan4Gmti(!rjfKz2%qb&)Va+_vuu~ zz{DNhXf~VMxm@mhtyXJ`qR6}54xw6oBedIFAd2B1e!qX~UgLrN;)P3|Vx#;GY;a?6 z+hcIJ5imScj1eS^oJPixQ5rNC+%h}K`$6FJL?UtO`RWUG|MGx(*x-*~lRTI=-RpB# z<1>eIukveuH!v1QsMABlGMK(5&TKq;w?6|8RQr)GJc9)=@T%{z^&Jy$_0Iu-gNuNj v1N)Kxnid|R!PM==O+cYaVmRT1UjhsOT9g3B;L;7y00000NkvXXu0mjfDrh(C diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png index 02e78b931a39abb8606863a2e4357253c9b9b63f..a53390f5947b017d0c9842f7e798dc017e083a61 100644 GIT binary patch literal 2874 zcmV-A3&r$_P)? z7yT}xG4X{*O-=NvX*A(MpXA9WLKG6k$x9|h|C4H178JZ7d-6@@KfM>s`_qSwl#si6@Z9L1HKD<2e_eRHD`ez z0zXjIOQCFQ5`8HEf7cHIgMq4i4Orig(V*`HAR?ay4gsGGT=iSP3RV4W;ChqNR|4>N z{z<|+zr|a?z5NskCZ#qY6h7wSEwV|F_eIdS?5!dzyX_z#2o@)4)Bd`i!cMwEn27BdYog za1S;SSlVtR{UCrl4Q02g>fbv3r~kjLHMQMH`r#SiPr#=N6g`Iv`y<^7iO6K&KNNc= z__L~hx*(B z_yG5P;yvJ9;PX`BE=i2MZD zp{j4jv8*7f+K2;K47?6#O~)>SExT&8<8@$h>i%vW$)5p4WRi$%16~I1OKndC?gL&H zk!?QBB_*i=A~GL13Va`!oYI!aOvYXFQQrs2NG1Rg`2=tRxIdK*4d8y@gzt+aBoRQ{ z4Bl=Jc@u>NB%EoSDgyinSeU5oCbAIMC((&601>$hcp`SYJ-`#bZ=#YS0z8?h-KH}M z*Ei7{jfP*hw>oB_UIl&(tORbwt;*So8)9u59{}5c<+zc-Ex-=k z;E#p46HOzJ_8q7Ah}nCRV^1Zv>bb%P%ogz&whloMWoGr&|G4y@Cs~Lsbo{z!0#-+tLw# zEyoJhIf;mqO=AjRuA%HNiWF)SL07TV#2yMbzl}oISG#QxPuF zj{;D)&)zGBQ=SwN^YUx&piP7o!Cqif8Rz?Junh6Oq7nBbj6D)~&`@>;a8N`np%b`H z1pBP#j=?_4JAWzen!C*x9F3)qDid1(djZSC(*STlL>{y@X#>E15qYRYdo2;{x1Q_IDeL@){P`B=13ax=_AjV~SVN9& z!=m$XYxS+OY0m=>muzzy@VKG;^T6`d&K~1>mRE58&Qx|M+aktq?{vpQhDGF&uvXdeHk5V#uW%_XiSvPU zDWENM-h^$UNc(XCw}pEu+gErS%GiDqxH)|ag!JHOlUKCmjfKO#GSNll&CE`l{R+P?-DZR)gtNnZ*85Znfg zb#-3rxCA^}gZ+=z?EKbo3crJEzX@P*gwAUh!P#A1d>)7qrwf!KQ~{T*1K5u6h%0xTlF z^T9c8mxyezp6Jg>;e2p?wJ1hIu>=q^{Eub|@T`aww!xQumbAO5#p$yM4}XH&eLL0z zRHx%IZfe(f_HOcJQ``Fv5#9!32w+hII*l=FpJ`A?b?|P>=cnLqyNMIZ71b+D?0|vDrmc91(T)k%F(d!zr|4Z0B(!9vXS7i zwz?jp{GERk7%5_`P}cb`0y9e5Y}wb~sh$)7HHQBVA~;ggk!6k}Wu5QsZA==dQvkJw z{|+KJ9KrdAt2p1=+L$y@=UaefAmas9JzJ$QRlR`wTzj}mJ>zf~_qq8(l}c3gBj9<% zDfJBs)pYkq3;$!ZJssD%q3`_Xf$0J5++=9Gwlq+e04(AEJQc%#2N4_!==?(=o$qa& z1$<<%p_VjIR|<$4{zs#3%K18+`Uy-9{xw8 zZnupM*p`Uz$4xV@b*BzhJ%=q#1^+e>Q~*s0|D$OWL6OZO_7TDPZCLssd>ZKI@IQuq zQ*rC~I@vS~OpR<)(lih{1tfj?9}m5@chFc{$qiF-FQAGxS<^t!w}D^+@S({v_by8K zAB|qyO0NC8d~4^=sLpT0@;0y`WEu!ID_BGZfmaI_zW~gM9Rb=Aktw)IpHOb+&ycpv z#BC`*tKcb%RQ0tGZHG(&me6!KrSk#w+V-+Zo$qZ)mIi_dphWn$guL2N)hnr;--ab6 z21^4$Qb39De~YGA3f*8tWB~Vz<5ANpND zL}VdQG!*6V--QxsU{F;pzeMtXgh&CF@#!4?yWrD+WDA$?ulFACnNz0H=xgBS)F*_)t}Eu2MmW6cB!vN~S24 z`#%4Q_XHpM}XcYM}SN< zas=pY8nG~Bgd9myaaC2z{Jz2e$c~%f+)lY);LLPp1b7qpC2&LoIWCw0GQCM22%6wz0ZeeR046wD027@5 Y0z+)~;)8_LIRF3v07*qoM6N<$g5>>Ac>n+a literal 1251 zcmV<91RVQ`P)6F7_lu=Wz>Hs-StLB>OjwTcYtr5hL7SosjRaC-q`6Q7=Z=k+&_y)erI zdYvQt0~SZgs+byTplY~tL);w*2{8R>0Kk z%&RZG_8@yk;4q0-j!i=~i2^x$gjpe}`w9V~_!!Dqzy=#P{^Iv*t8^dhGI#XR6FZim zs)FVQdIn7;^!i2^g_J=RG(&a~E(muR1B3{HA|ghhF|u};o4ZI)m2M|yhC!eJ#H*(U zAqpV~QSc}Qq(n*#AOdPQGd^lrvn{(}=HaKAJ$wSo$u@}<4hx6@439R3K->~hQXK=t zh}+R^fUHhc$S%SOTS1I=yNq`$Vx+}D0V22nW6QZniCDHAx?M?0eHH!OP}H~pGa-aP zR@)>*X|XLpz)K*(4WJ68426`e_&Kr;mBF0`aZ&i07AYVE{9wk@U-VJMQu`3ymf#GY zP7pt<3fVJ2j1e!3?`v_pjx@Xp|BEV=E*Fn}xE#KYJ9ma4fZH*&*lt1$vUwAV2tyE$ zy!!VCLb1IuiwH%CL40mdg%;aA0G_VOi%uKvsB+RNbIO_v!@LJDu-o)NHQWQ`7K9L4 zU+YtAjhUim*e&|AjB4ImQ+1jdIjiqgBbyO*K&Mk-2wsAne~e1N250BT`R1~@V@gfc zC}ON+%=h@;+%_;FS!9qPR1oBj0!sbnSA?X(Y7d>q_?To6~QNk12b3MmlAWDqt`* z24Uw6lqO6Dv4Vw54HHYt9J(KxjMtI^Gbi|Zr-Dlhf$x4DVb`9>f#YLH6jCZpxT649 zSe{hLiMLM;c;?9oQu63hf~@WpVF;sRaOP}}Z-1F0{~k2LvefGwMMi=zx#ESmVVvl&{XN5Ur-y zYjb0xCTC@ODljn-Fe^V&<{55rI0I5LpaP~sT_;jgb9E_l`N|kKSJ!EphPsw^G-jx# zO##CA1S}e4Ah`glaHk9i7^SnHl#vcWX7Ybr1~A^r`|CT1Yg z;G_q+l4HP2jG2AV_5a>I4>jTwCq4xCBo;1jip~ z=+$x4UPpu$qGVE2F+CNrZlF#=zkwz}0!E`$J6^*-e!F(gmTsP$nc21FJgimh-P`5R z!72LQbW8(aY==~6?zS*z`?PaU(Ww|c}D?P=NI2S{lS^fjy^YgEURQo z4PW-Ia=K%f33q~^^mPQC{2LP?W#}kW9pbqQ3-jl{zw%!D%)O5P@ehf)4z*)yn^yn; N002ovPDHLkV1mgcKsNvY diff --git a/src/qt/res/icons/history.png b/src/qt/res/icons/history.png index ac955c7291d8e113bb6399264711857782f5813b..cb723abc5f71ddd9c1bc2969b233a49deb1a8feb 100644 GIT binary patch literal 16271 zcmeI3dsGv57RM*NL=?1Lx~_t4HkQ^dP9~EFBtri~B>aG>+wGn` zJ!f(bWbW_#yZ6p~?(cVJ^2fYdQuOP@gkcE~1SJ{@^`-201@{*p$NoQm^=LW!)!$w? z-U&g5quifpZT{>|2+De$E-QDH8%JXVW0m40W1^&PtDT(K z)t2`qVw%jBj8hq9MtdGrO&3mbP-7<*l@XI_2n{L8(Isfz7#qM!xp1-DYOy&ncecbI z7h{jPVMHSKPjS^`OLDn{;&Nk&IFE5qVwF?{6EZm}&eTXzl~RMEqr`F9L1c17E{E9} zu(QGD!ridVIU*3GD~_IW5)Rt#q8Xc*i;J6>T35D2!X*lQg4boWhZ5PGL3S)f#Esh# zR4PMyb0Ue5kG9^+S90vsW`N##znukuoIrnV7AK(HP3z>-k!( zy{2}$^6OXxL8QHUI?EdD6jDk#nOX-y<=3&7GNQMuchTl>ak@p~ls?a$a?^ddaZ13= zzZ3!$(z4fz0s#-a>Aj$MpO zb{WDlRT-+n!X9%#6c|yL7Y_uc8pUtxAi82P0;NmK2u9SQrO;T9i(qMS2^K@bWJ+%wTi6 za2r7x^g4DxO4B4}LQNWzCKH8K8o~rCGn6V=ttM2kSw`VmJ7~7e;g*Ow z+}Z!9DS8RhBUK^oWEW>c#G+-FuD_9ur6zVC?Gh}szaiOihm+#ATehTYzlAzjs6lZ) z{%wol1lP)R1h*R~Qj2sO4WCxXGw4S5Ea3f74#bae?>k3*HD%-5P=QeXS$zj_GGgYfz#s&QKtMe2~Q%jz2VDV6R1dfyM;Iz8_r zKlQQ&_F(r`*mZO0**dk{!vn^)UA6__{&t6Iksf2=1rwNG&b3cVt$)5!E#p4yV_iJRM7uI_G7Fxs;>=WQ9gU~qi1=b0#}Z@ybIWb-Yu!u+C39}uq;L!bLK?RZ21FM^OtTLB-)euMdIbyjHuml zQ)>=;ibXk|xpB9N6_2==$Jk#yJNH=BpZhfrx)bx_hZBan6H*hl#Lw$YgYFD$Kc4&P z)>gIsp^`Y=*c6tdh?RMtoJ;U`Q2fpvSr|?!w+`WRjyyrG^KKwI<=p>QN1fB zHF{^l!$r%XXA6>Mm}bsu^@vuSc6`J5qGf-~Tb%AG`e-8M8)?tF($wx6zWfx_bhe^- z(bo5pzYv{@HIKU4@Uw3WtuLS5TCrcD_~7G~35gv|lcz+bj&6N<)3%Q1V+w{ty8adN zy}57foc;;@_@Lwrh<%P~u1F!8nI&?Q3jm+wpa`>$U13#NNv?hk$y!qBUQ8(dx z<5n%)#I((uq}ye3BuQy=?v1uu_jks}cD*p?c1OzShib&UXQ&(&nGrc&Pi9gcx zmGRZb&d-0Z&1jf9ReF1evT;q_t}zQGYz4nkBr*H{xfNctOmsKC^UgMry14c=L)w=E zrX@B;KTNi@|1S1STw`p~v5A&J$5#*E=S@G+?!MkxRa>)k(4mjceNZuF-{Whg=Pt&5 zp0eQFk!vMd-vE2sob9c(DZ2Q}(Vs(ezHU0N^8Lx1srlr~GadMWwqc$6y29LbCF?6@ z4>^7!SXw@ksiuqTzq|>y22Q>0-{T ztO3`H-~3cwNOHEh^0=gvE7p9w23~yk z$ZM;1#*Urut-18%lHaHGt0>h~c+*5f?4m_6fdhj#Hhi$<;#FwyqPMq~eY^TP_sYB> MzevCFsmhoB4X)Tl;s5{u literal 1343 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 Ha?Jk#0c9^6 literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/key.png b/src/qt/res/icons/key.png index 2638b4f2315344884120f307480e0104da407a76..d21f81364d8470085f9404210e4160f0a8fccf56 100644 GIT binary patch literal 2434 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 literal 1440 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 Hu0mjf+o_Kp diff --git a/src/qt/res/icons/lock_open.png b/src/qt/res/icons/lock_open.png index 23ce3243aa2e0b81298e819114fed166cf8f9d57..50615b73362f5553fb54d6d3bb8faf32c886960b 100644 GIT binary patch literal 1751 zcmb7FX;f2(623`HSR$J&fnXuIC`-i{0!T!KfJq@D224^meI$Y)i!50hMbI0;Q^1G? ztYRAkT0poWP#3}@2q{I1B1?;)pq8~rsbI7~V^C=Nqo@7Vcix;c^PQP*e$MwzUda9c zBSX9)002hJK>7h4LVu<{MpwV{;rHlZozS1j(bq+$er&F;H%JSN5CQ=6$3GKM!^qd@ zhBhKbxQLw^Cz9|5M*xXLLP|(U62|b;j*wCX@n0_N!UF(?!=(Fhj?3pugKD^3Yp6Xs z*!+&4)fddo=r4>6qho)-))GPlriVlQ2t}w0ztD7X5q+AL??@CmMf&lGqve%Oe4k>~ z0p|=}fzX{oghoH^$X$%iTu417ycUU{i;jtsv?>88x zd;n55l$f|09?O^>$X3k^G+j?*C4DGDM4rjjSDUKAw5;NZHodEQKmB0kdI=li4hp=~ z6tZGwKncZjmWsWzTL4cY=m1@Yu0_ccx2o<2Z1BVA0u21?s(+9LgH!k`YP`T_iE8r>7Yu)eeWVJFEdP$d3rQyzL&D3&$I9< zxz9X_cku8tw~FcjHulX{8VCxojkwP`E9_CMnz;*mI@^tpqne%E+K{(6;^+qiUrb=U zWx~1B$Z!K!>%`Xx|1vcHVP4Lz4T(V=3cw(@n>sGxB~O2LOH~SM8QE`B^n4svO_nyL zRl#-_dMBbFj|HbwuMxwZEgFFTvL%NYQ=2I3LI+NLo71Kzt;Y*KIUD{><)c~TCPAwI zm?fM6kK_=$@^gqTo?17WD@egp8P5>o3A{7#Y8ZPV2x`w;nXOe-!P?Y)$z#Y)q2=p< zwUxQZOvrT0@>FTa5dJLIwEtp-a`EQLST1 z8r`nC|`7PET+erHx_2#+Sw(TWQ)RJkW$Mr zW2`eRdTJmRCZ6bN_HB#Pl9q~dfNeW;fs_QN2G1Xv)HOmH&tY0`~9-$-BndT zm5B9Pp#+Zbw`ri=x7c(`TLT=I#PQlyqwsrr1~HQo=P$eRO;XWGocj1oW@$G~C<3T> zx7DMwwu}_SOl;rdyv3aX6IW<%3hA}ozRpuKr*{qPc^jOpRM_#}0YYb$)~~DH>EPU0 zff9<))V{F(D5Q6Yar7RAM{KmDZXErXR{@iPvM%xZSO}NP+-=+;MbyVkL`Us}#6fA| z9R|0cpZq8a)kIgG_=hB?zg`v&ipT$!Cc*yH`tjTL{}Aq*2|ellm5IMrOlpkyDOdt{iymv6wqE0XI|jTNOxNDE7E)vO0%j)=PyEE69vH*9 zpU3(>HPe=SD+9or^0}X}+4IXEAr4hE80^z0fR96-AGhflC07qq5(~nxj_UwBl;ftw zGSja0C+qad+XhPtzRL%^;_-v&;b!A6_QiM`Z$Z9%;1NfDM`$FRe-;?g(|dWozyQHn zawy-)50qHDzjPzg#$6`=bGK>RqNmhG$5;;qC_NX~EN-|@NPhE=HZRd`C$~cBpXat> z9{&8Un7WKqa+VZU)u}z%G&WN1;3_)C8kvoK_!22!)tOka5T|DOkF8!+jQvuXsVt#{ z1sBdQy#@uIY0g16`{H4Ewa6iKI|86jlgT@xI{Kz_;p*0!78ij%>QUCIENYRsK!8>A zbte!wyyL-LthGUAp07s+;S-c1u9<%Kavc)L?G9Gi@%9aO&i5zqn&5^0D;_H+AhrF$ z(w(V#jo!ac?vZY#r5-K}fWo9b=PU+%-Wk+!hR$y;!kGg!x+AIqbuQmB^ir=%z}ed!(gs%dKSQF%V)KuTi@HAFJ+LYl-nHYsyS& Q);%GB$=FY?_vfAY1CTBKbN~PV literal 1359 zcmV-V1+e;wP)7ym$B4oV%;FQdCroNRgZ@mCBS-2g;m^=4^!qh6Uh%0nuMk6quo)5E5w! z0<0`V0jf+iM`@-maj4+XrRt{BZTH^y-uK@3oYN}@nDgFtHyqIiJ{-<_xt#C&JkNPU zjF5(g*Q>NvD-(&zMS;_W5KeFJy-RoQbRWs*z3+kRi~zw1Shj54vdNPteYAM-!rGde z@x)?rLLrBIK1X-=Ee;<(eDU<@6Q2NkM?Jvu@>96EH60|)lM2W+J@IFyFQ#tpM(&z||+;>Gplot-^&baZgyL~FXO?T^;> z_O{ExJ|RRX77oX$t*ymzoLAc0&z>|!T@GX@1tnO$dZRODO!*JZ&Ffyhd)K40vx8Ho zj{llU^=&prT~ta3s0s0S`DgX@jVtTw>KHpV&Xz47pSyD9(gNTfkHX58Z#8b+y36d} zf6VOI(PEmK-u`{Xisr`xdC(=7<&aslXwf@?45gq1Yu9et zSyh#2Qi`1Cr9~>0Tm}3_5t7MUQ)bL~{!DZ8hDsqc+qZvu6j=C3L)g^x?i0RJ(r90U zF~A*$Kq>d@jT<+wpE`9i`}XbeT3dg58u*+4iu(Gcn|ANsZ!TWEWwvem(kxi;^1?v= z%@CuEGTi9z?*||nje&3~7=qCcpy|zPi4%@voCp~c_C^$7XJbvo&-t^3AO>iPgDJ9) zkoPWlm*)6g?cDrpEZ+5Vyb$fEeKvY0<$5?W6gmqehaAFPYsP>6+)L9pS0th#tu!F8 z2&=GrGw8Wpg#alO+8DGl2qAE!z(|K|I!oKJ^Lv5yLssC)iPdk+ZI}}xRt+i#CLibz zUbPQW0|rbE^nE?Zmw|S`*b8GbO8|&Zs@y!N5X$u1DUH%Idv z314HkAfvOWs1TY{2jRquCMWI?y6iuL^03id*>~AFlU~Ip_4k()*0&ysbq&QN7 zc0j0M-U3HLH1g0ympz(gq2b*EA%r7h4pfY?afy_|3FH9_Taa2m| zG5F~U+|-3^$r-ra)$_r@FV4IljmO6rtu;jv7>17!LgsT<^Ea>G-pT)se*mfny+@Xr R#8mATv)TLWc00QI-X>P{66R0&pr3vbMLv!xl4wJo1?UZvIGDC(s(C( zFCnJ?0Jxa&XIlon6C%-QTRZ_Se2MV$H-$7J(&G$^Zbjz}wpp;!2mw0_#;yD|FEwC1(0zt5dzC z27W7tr+JkOJ!cwyu$Nm&t-u(pw5KQ?y6BLV(J3y6whxA8u(pGPWzm3v=hM$K{;qad z5)%%^dRDl$TRUU1Q36ZOc-kcA1$Ei5X|ptXV@G548Kv*64rQP67-#sMePp`e-F22q zwv2iKg3lpRS z(Os!lJa>Rqh6?qU1UYv^HUaefo65`aiX)m~=ccl=v>%%#lQ;0BW0mo%kV(niaZXgt zgQr2iLhg=!03%ShZd)N2l6#WO4eF!{p`1lEUJ$RN7xyo=0WTzv@%LD+XUGVg@7y{2 zMWj@OIQ+X@rBgG&S!@D7in6N64pRrR)I7C7jv|l)Ez(%kR1xH@F<50vCxX>M|IXDf zB1GcrvY1KR#Yen8hannj%aTvwA@E&l4dqC~gk=8ypY4otcn;tWbq55sIa>JiYpYIP ze29hJ`W@`25twd9813$jc@09Xdu7~V*ky=f&Hm$(Y@R%cJnQ|+4>2vu*T9S0jYYIS zkuvuBW=zs)?BiVSE~^gS0g(2CuL8J}ew4KH<1l@8mTc_3(eKeHR}DJuX?8QuhD1A+ zziu&Asz)odu&*r^TOimU07 zBEm13G_86m7gu3|ro>{`mh8K9VJrq0d;_=U(vq)&CdtDIu{F-mOGaOMov<{30=JE@ zb6ubU7|XlG2%Nv33c50t-HkPy-H+f9#1JyYGb0GbzrtI>wY31P1sC`(i@cE@@^fUI z;a|$0IF+S4M*JN8T%J(8rOxhv__9cN)4Q@a7**Y3+^1GF%+ zfdDkf@tHBPLT<`jLk&`n@n7OT>fP$(%itc;cOJf}5iezlv=%{L`OF>(K$I`&`$GZa z1DaDu=XUBDS(x?n!{wqrQ^%Mq2w=wtu8QIAK|J^K4- zvxU-6-UqKbIs*j5%*hFl{nDzMD09Q=6bYUyX^g0_BMVmWY3F>7cgh=@BmLz3l4cV# z$uEG;9O)Dp&0>>>WCd&7%eX)`GwciEbT2;mn_zkN(QR`m5n?1AIgXwC%wc8e+=s@c zUQj4H*^Q;!Oiv{Uge{_B{k8dNc-|KkJ5y~ae;0kKW*YsA1juo#j1McWBrJ%VuD%~# z6-b>_2Ma-S<^P}yV$>?pAsNMG2Z(Zhds_IuR02l}=o2jYIjo{rMUMBZ;%gG6;)w`7W^!o4 zP#l?x*%H&14tfHH9l#Kb7y?AlB%nTc^(m+3T;M$ znY^<%TXM~y^CzfD7QDzE~cj zLiJVKv+086uPAykw$fh*lfn$z40b|6h5(9DLBhU_di+*;GgPTSfP<#wuB}9*jYCJ& z=ia6mAG>~SYqtW?+!XK0?SHpg^Ai|vL}RT@(v*A$ED~86K3XRVfg!HN`uHkM=}d=J zm7KNrmem1^fq%(G-+45tZuFB*MH{LurpVPco#fbK(O&9222HYg; z$97D5w18!x*ABNqyZA=q46L7wuCN2uu}_YtE}$B#BSabo+7(Y4Kz}t%pe8Ij6>@7g zC3ZdEXuO^aK6N?^IMCdfAMN?+X(eO*<*n9NsO7I6v3iijh$~C>A!PLZwr!*%F;;0S z5V>&!=5d_IU%VZwhyK=<@s^`lJQ@yGrYv_`u$R_jO_%m=;(N%kI*p-l^Ymobyi??5 z#`xg-87rrjwpj^YCinnTat#qzUd1lkQqZEW+jGpL^BT`^!vjw!>d;{X%)+xLha(@1 zxGCU6p6A@luSMGARVOdUgpOwfTSW#InV{9w!R}0ss#;>}v-b?)P{!w6o!~b%Tz?I0 zf!P*^p~h9M+xk_&5u8jSqx)l3y!@z4eeT*YK`d=wiD1P|65Dd8{%smD?MC`cytqeg z_ei39E9(aw7`JQD5?ZtaeKjVE*?tRs?Rku9WdYStRr(`8qAvWeqS?0Xej8EKhXzfl z;4QF)kZ&toWykV;Yty=?V7nKdgim@8Fafu)kxK?2M!-&_yR;fVbknipvS)N~nSBLQKaB#DKVoSRI4-g_8X#fBK literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/overview.png b/src/qt/res/icons/overview.png index a274f0c48890a1400bad17bc00fd3084b588f7b5..36e1003c3c119ef5bfea14386c924ce5c3edb693 100644 GIT binary patch literal 2215 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 literal 6327 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 cfp@(i|MjW-`cLY%i?EnA( literal 1778 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 Y0z+)~;)8_LIRF3v07*qoM6N<$g5>>Ac>n+a literal 1331 zcmV-316w>Q6-gB5m8x16=fA=fzki3j4Hr1H6$#jo8ccB zDx$5-P&6HeT7zF(~m=lgj(hl|L-xh)iceBj}Qd*ORO-kE{SN!KDX?fVCDMAtsubRd_bQ6Gbf4ia`(@w6+kKG794rKz@fI^4vzCxsxH3>RxA_@u&|Nd+epr@ff{|;<&DmtAHjF z8%32qRaar_IU%~{u6+m~r$hoiJ6N``Kp-R2XZq5^aQ{@|huwd1w%hBUl5*So)SG_-Ot%K3lN0wDUF0i;Y{m ze$VyW|7;-|R0YTU&a6uFSC*C|SwtP1f#|=> z&h_yf6IF>+D&X1M`%-aH5s88XkG!*NpItzl)(DRPc(Ln_*BtpSNx) zAZ9h~?Lm|nl@lGB$*Aae-nzexTQ2X7pPxtNv`sWLG;gBNuMFk5o{)-}{kU-I<}n}C ziB=goa^Qf}Ec-+HKebNEo>(hokFAn^4=$J9BWs157Rs0p*U65?-O_sSpiG=yFI@a- zGHmA+p>$@~3=0pqWLk2{=bOZ2Q_{TeADJ+Ji}ZS6g_PdET>9KoE8Mt1M!mO2wr<%e zEzL<;vg&t9466yae8vNzoXGAmbjB!e=nR>^e4D8B5!t_Izl@*TASHL#ihuJWc_yq- zl>AUrlhoDkl+xj|B%Go5L+Q%yGi3V9`NL|=oZ2mtX=|0eyZ6Z#%eF}M!k?va+b(HI zHp`0d!}i=fM<}nF%2hQ^C|&8$69!LzGZBwXp7h4mJbuRoI7(ryfEQ!UrUN`b{s)?y zQq>gtF9C{ELD;tkxwPu<+n)PM7OdDRwQCyX(XlIqq0`&K3%(jkPjvV%RMeEyu3o@% pM>wwIOV-qr?^OfqIL&E#$iGq+DUN!ab#t}({a$>9pV00pp&ZDB~S_guI-AS(ox5)?*L#qfzJw% z1$emAxgvo%hbIaH&Eo}PNDTmt74c#YHyV`T!@vl>(3a45x}JdN^K1$J)*fUJu{{{c zcS)3hzKNbJZelc-#v`m?sxji}kbwY{aq#hi7@?FNZ%Y{Qr9-iznMA;kNMzBrgl`lD z@c|xQczclq#9NzN6S-sy3f_ihPO-M4Q7C433o^x$L?M$bXhaHyZe>HKQ1N32fvE;X z3<)os?&IJzRu1~lmJlhEiRmO#TwI)aoTa%)5<#NSXfzVpf@EPqgcL++f>6eZCkmxT zqb47H96%{o!WYZliBxdB&cw7<~0}4Q)ObX>urpyyZiew^br05GJ$Gg8+7#b4~kMY`5UavqfWofC* zaV>;k4C$1aQdWW(B>8|+QLKauI^O zMn{MN-7DQ*0&-*`2}>l3VUEr+ua5}v_V#!a4-S_vR3J5FkS6OV27AH^bl}K9CNvqX zplL`XQ&|);-HJ@Npe-X)=wvd?WK=oH!$ZX5hbK(!VMT^}z?73cpvA-E$TVc{Gyhe)GXDrVhWqjO1bc*(Bw>jOZreMtHiRs+amkUnXhxUBKau{8ew zI)J18u=Fq2h>HY;f3=`StwvN|Hj#?LWpNw{_)P>fClD95D~!zC@we+#2CeehzKq~alvUI#wadCL~sF$3r+(uMsXn`f(uYwa2kj)iVG1D zT!7+&(?E<-T!@I^0u&dV24aljLPP`?pt#^P5MvYe$ zfcL}Dxf=jt$pG+-4FL2U0GK1n3~h1(faxMvhi_Q%x1Z;Ky=9g2+~j(#5OtM6RrO<3 zZIbe$dmGR53^%8pB3UtAI6pSpZE-A2qq-Ue1Qczde&aHyE#%7Jmc!SS7pAAkT*(ei zb~n=STd%3SJ-GYf2b*B(TZ;7R*g>egp<078yAO2uj-yWn>%s63Eg2!yr zPH{|^6Dmv$d24Rzm1YIu`a2mv>8;1bo3yevwa%>W>?nS=VczA$;_GyFE<;4ioA-C6 z6<8g4YUiM*@}31gp&CVRQcC_jg!`pjD+1>1VSfvy*}4SwS<_ zE3MaW>{3~fK8@=$bZkz5Mjh@bAXtuDUszp0G9VXUcROD4i!`{OA=Y@e;M5XviSY0( zoS-{%S4B`kwOseW{Y~q7)hfP?{_~X8ALN(rcVkbwb*-_cWx2Ef=qgF^;`3b zv$OmNKg9sGqSc@FBvvRPaIqr*R~`3*umNY zT;=xC`SQbrQ^`dubBjCzoo^4?DPjG>gDZzHHFH#0`9p$iYItCWpDrdRATZlf_GB5` z)tmFLerbA@wO|DayKNiryd}#ZXWGDQ14!MwyXHvu>+D(#cAzNc9hZF|rXp(47N6wO z@z%B$*zFOa_xi2hFXblsL769gg#Lq@=o^f`da_pSe%DO-w4k0NzjryX+{%EnD%2z5 zx&H0SKymC)?@FZ}zpop#N!NV4u-&<3=i)bf6Q{Z(cU<^`Q;x&qA@;T8o}iwgtok-#m(lx2H-dVWq&RQcJ@})~ zjpR79vnOtuG~Vo}tD~Ho-*wyHszbgfxu;e4AC&|Da*4Zif;t$`=drB5FIp?atMy3i zrFB}Eeey)_BSR}Kv-sSidp4%hT@7u$=RU9-^~KFE&8lbRc)4jL=HaHfdX|~R2KO6Y zOHVJ=3W>QH952!a_PhrM2?HLSLmL zCGKrA*c$ZS7E^WG13Yvevrp@`qc0vu*cMk2J!88CA*Fk85Z8oAn2}R?h6H zzA0MYcWXtQcNjL}*$3$yageEXJ8!==CU4L1X|M1_i(eH+lxP32J+Wi?20`*Y^)A+# z>Cf@1VU*3Cm`<|_BfxC6K`|y=r;;+SS!XCeqbj`3DVqI5O>%X}r5T1)deE=yQay0b zWV3@RcTtaJ>CFy!M0D~q3D}v(X<;<(BWB*8YreC5x>&!teM=7irO1d@b@E#oSlA(I zpKEZ~_u(O@B@1nLRH+l4AcI)L?+31C>UUpBa?4w^M60PU1}Ixlnx7zdqYx9TwHH1) z3RHFerg2~uC%=`pk=?$e!bBy@k@>x7I-jF4)S7rX@cvJgSA)!x%dTp5Zc!>tYjct) zclPMq%;G#Kzi2x*K^|3OTJvg)a-?X^MHSLwi(jRwrkGGy9uOU&W50+Lc_!!n`A4yC zGw8&n#hX_*v|!-$N0{&W?@}(_kC7%V##_xd@OZy~6OEPY z6;|K)(@t$iGvD;i$A314jzyXmItoV$Bz-V7_V2Ii6h#DFxc$IuP$MOLX|HCnI_r+i zJMD}%we81BzwTpO#m6rRGF#Grdy4mVBN|@p_dot_-yhpn70K6Zb7Hx)Q)Bn(L;HhJ zttHCsvY2-BtmZzox86l94MpA;j@M@-9Kf?BUGte>}CnT>k5Ok#zdq zEYl)`!wtEn>?^y9*m;YKUvUdlJYB55@=eGh|LE+#$G4G3qZq8Z*zVnwDl&F|r|Y|P z54kwZJt(NLsF*^m7_O32Uaq~UExK@hK-jb{>JP7N?-n@s*m>{2Rk|SK?va1e50x!k z?%MUJT8Zbje$x#*mhSTc&2F!>MG>8^slc1yK_69>WjC_|BDOx?WphJnoHwL+pw&J- z2J8*G;HDg%k!Sf>w@IZ+>5o$vcDAlkUDF)m-;kkcf9`Qe=1+PxVFi6n*$m*S+uYkb z(yn>$N+u@XaF+aylN;}8*Sv6%^LL9gG#5LtH6E1xl=60ueb2z`7gCL)#)w9uN`=ac zJ?Ya94VFf|*jv)#HsJP#xx(FGwN{Fw>Gkt8H)UPLL%z^~olhLr1R5Ai@9DplBtWkz OfUBdY!!bMd#(x6@sjhPX literal 649 zcmV;40(Sk0P)J-8 zG#_n~d+#|iW*8#Cv|u&C`0ZKx&3VNbscQaQOU2HVMF!@#-^& zbEhURUdY7ITu6h*q88tKpF%7b*WT=Ad(S{~iLM8c>J_P#GU158BmeK!T1WlOhPi1vgG)snCey*8pJYoxKdMs0DK-St%xjI>m* z9%6#LiM|E`5IY@!f2Pjb*{khP|Fp{H(lXs2J0w6#iX(y;7^SozK%n1DVi3wE00$}G z7Z#bCo<_Bo*6+1xeBPk3@rBmL2Fd@I`ujohBM4W6u|6I6McWeKsw)0y;>2e@?RJf zBo)Aq38V&zfS8d;AOR8tCqi~>Cerl6ya3#(p1CGwX91FdNdcGwwuZc!0p9N??mY0C j!`TGhaO4>=V#J6)NhJ@SnNAkS00000NkvXXu0mjf%u*jv diff --git a/src/qt/res/icons/send.png b/src/qt/res/icons/send.png index 43c3d7922c15e1e4962264322228746d54162413..18d05961940ce6f5a7dbcff459ad484a4a4c42a4 100644 GIT binary patch literal 17005 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 PKZJ+~i((!OiC_6I<-_re literal 1345 zcmV-H1-|-;P)Nr3^29?oeI`6Gvz+ z8POr?ywEdVbFqLT@JUdiUM|VeO!b!b{G}4@g81KpBAq5QsAgeTzZ@&q0hK z8w+)NeHvR7_l`>FUmUQa_C^L(7WbPoYx`@7s1o3XoCB!D44V7cIL2RI&Z&&XRSM-e zC;+7Zh3i1*Dx%XdXor+i>^$OesMY16u?Zu};K@hF(yuH}-GATa+9;cZKy|J!VK(#} zOcWDmVvIFc*3ky(sEz_-6d4VkUDH~lBcWFTG`D*^_o2&umm03A6sFuYoFo=+#`OAy zQC1p&4Y>qB>jYN`^?OdR=A#z!(>{LS4DiB^Ab5U&HMjWWrF?>v zLT3SiAOz)jtlZ<^Ifk1D3lB~o#l{UkRBYX{e+Dq~tO1M&#t2~WEddFhSd5|zI;zpX zn=1eiK>>bty>ze%lS7nVo0)?wnshH>Wu zKwaHlK=10t4hRlHo@)plgKu#yzDn?vvN(8Xj8?=-Apio#5=C&w#SW84xZtH(zwt-b z)P3EC7rc;L0D;za&CR1rxO`Z#HC8yDi{mJZgKM$1V`t`XKEdvTS&9^7w175D9_uru z3c_@XZ99Hq>a$&L$>JdYfOG+Li%}b9#uxrEUJpUly-@uYg#09V%rM7(r(Zy$b>! zpE{EK08U3Szn;u8a-f|XU&wVsQyu0TH|^)1d*0<}Q+o}0;bVVs-T(9%-9$#;fHujQ z)#S`)l#odV^e#!?UBC8LD*A*>Ti!q_c}K}#G{M4I=wU-*1MK|l zfb4HLEKLWGNOZbYc6{6@qiruhFmE>{)t6exfu0BW_|rx?*4!+|jvbe|wVz0@flFiZ z7p$hVrtDvD$@?ll3KtxrwEA`n-KG1wV9C{`wkw|g%vLEIxgw_b z!nKswR$Ax@itcLYvhxwv(W-mlsd+fgD?rS-s{i#HiY29}8D+p600000NkvXXu0mjf DT@;2) diff --git a/src/qt/res/icons/synced.png b/src/qt/res/icons/synced.png index 9fad3847681ff1f54091598f4d2b47cf65098d82..d33914f0b4ac09d8b1a25890db6b3883731375c3 100644 GIT binary patch literal 16891 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 b>c#B_4cNl8 literal 560 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 literal 291 zcmV+;0o?wHP)O(_NB$rAU;Bzd z2Hh0l@>{8AWIPx&%o~^gJMiDLhk*k{9%!U6&;`sueNq{Z_xz99!@vuZLRYBM{$u-p zt0JJ28L&B3G5hhB|7mv_#Ifrajk&zxf59s@4WLpifYmf><^RgBY`Q>;umWD+Z7cqJ zY-QkKzybI|4lnudIu96jkIfWK3kDWk3OMZB!mpWUAv}l?+##1{{CC@g+YLOP pn@hgiPh#N2rGSxvk3kYOvH=}`LP{({BNzYx002ovPDHLkV1m2zdgA~9 diff --git a/src/qt/res/icons/transaction2.png b/src/qt/res/icons/transaction2.png index 8a804b05ac07ffc7a26f25a774cc58f42fb8273c..d33914f0b4ac09d8b1a25890db6b3883731375c3 100644 GIT binary patch literal 16891 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 b>c#B_4cNl8 literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`vpiiKLn;`P7g&4jT)WtNotvk^ zJ-#FLjS;;eXW1P7aCH24{+JVFlFjhZTIFngLxtAHS(XhygeE;RcX;E{^_JIT)_&%V zikh=p8-55+Vw60RVZ@%Kt&qm_s7U4PbcduP5(dJn9vVt0^K__RyXl=U>%yON-fI|L z9sV$#ZLnRUCMBn^uQ|oR*z#nV*(65BClUhOzO|YUE-Y7NU~n^=Y0W1h7!7nKgQu&X J%Q~loCIG2tN|XQq diff --git a/src/qt/res/icons/transaction_conflicted.png b/src/qt/res/icons/transaction_conflicted.png index 51fff649abfaf8097bcfe7b69e2f02f5ebfd6107..6e44a2d329adffe1a5ce13ccfa8b901f2f325765 100644 GIT binary patch literal 15766 zcmeI3dt4J&7RSe66k=h0@Di=WP+KcaCc`5kV~9dPff}Vq7m$a0(b#00)8~&-l2QB_7S-D1wV8ry5fgOHdV|6)4rjDokL}l9U>Pqzf#hQk9PxxvQ{TTo=i^`p)}2F0PK` zrGzVl3Q~^c;c-QJY8l&xH|*L;?##;E)hLrQjP1bw;Iy zuQLR>g4~M}gBetMoHXKuj_Zi4TtyTZBY8YWqQPt6zO>|EBAsD?9YqngC`lL*2;tG3 z)T%)rvOuqKE={e1F%720bVdW^hm7h+<`G81kVlM>a&UUg#8gcbiox8Yu2-uaHMPMQ zYoZVgARX1ykX%S&a1v%93iK*0)?|Eb$&fu3XNYt5B+NodfBkQh20(sMtfHuo$HglTpnWMztYd zC`v|zXs8$sLxP0}Dii`iT*?tK6oeYjDI6_E1d0rc0Vqetpf-2q*_z3Y8NYLQgFVlZ8s*(S`vpXPcq%I)hQEQ(^HjGHO78 z<7zZaBo>DYbHe#pgi6H^6N(VN62sK|2&F_6Aq-QgMdBPMM1=x$zb|wQp(=1}m4VRe zKN%Wuzc2JMJx(2SN)4cKtp3lY7$wYosp4=0)trSu(^9SLJjj+~Yle^Bo6z9S1Bq1X z4VYuQMe^?Lx4{!^@PKmoIJYgTR5^|^naZ&nFtrpOHafJdLC*m<{QoVWD?Z>pb`EnM zru(A}&Ayw|uZirbU;;=(=c#woQvjUHQTGT!n{@cC+4;*FnX z)R(qA%}USwO1p-L!t+`i$%D^D2gl7hKSw+JA)jxb-KO>T+hyJ8*SYuR`VXi3zfri$ z(0uj0_{P2khMHq%Up{!wqL?z5WY@@xgUJUu8O8s#wi)=E62!JgC!2V-y6)~>K*~|GpnKPV1ZAH?HsWivCxp+CA)Yap%PE+OL(9JcE&u)>I)W7tp_595+wsB%Vo|AbLV|#s(E8=?eMAw=xto5~Dk^EXX zJ7`0t-zM#YW!Glfj(Ugj+>6-l?_5tvvfIYjKG`&xxagxy|2XG^&4-TW-}Pvjb}M;3 z^mcLQdB0u(DYA*@vmTqSYEH|)dgXgbbN%5>LB)4Ewe}P{(*6AP7Z0=Vb{b0l75^Wc zC1!W_24`1x29+85+mf;_m8SFtkd>!)N7}c)dBR-1C;qtiBfmYnu=@k+uMZdR@NNlG z9)-%>jG2><++bZi1U((i?J0gC^q;IEUHjcNzszz!8;Rs8_FMXprYzIvEBaeiGt%9f zp})y*^lXXjpG}^;B#b*%ZsRv~xTW2M0{z^7Q%pWo^6Wkz(-wv7$Xe@yY3_TyH*HcK zD7W(KE~Rno%f_=hCvEw-+&YVszWU6xz-K0&k2twe{L1y>YcK4af%kao11p**VcQP< z5_Wac#+pU`I|FVdydrp=m3Cv@*&8}dz+!EeUbGk&*-D< z{#nB9^S4TUNd5eeH?1JK2rB0q?eUcQrk5YBlTSuG56#*p7r__|%5%scD}-#3_%@ zo1NGc&E*#aXI!p2v6uavq%Na@YzQG6?Dt)35(aBKpE$m5v*=a4I!ci}sp|3D8_!huE|Ghge(_zB_4AQ!$bPq#6KB4c zwd(Mv?Z^jvN`Aib&79pOk&b`U?Am_^TtC~PR-AlmTh_~>qK>(5oLE%a!KsT5PS*CO z*MD>L_?tB?%`0XcPswZlt|?{elGx;cuBWi&mv@YRs-z)KoYja-ePT`RjR}&K)yG?= z8@5!W)MzGH1-Do1YOtyMe7kr2fIsxvnVyn6o^F9qV8fF5&*7!J*)q25&i*{RZ+BV# ztlo9=GRwwYRV6=?<(X45-B7vtpkUv7%}WEXeJttuaze&p3oCjvE5(j_*R$FxZ9aX) cfp@(i|MjW-`cLY%i?EnA( literal 474 zcmV<00VV#4P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i^h> z1}rpU_YegD00CM_L_t(I%axO{YQj(yhCiFcv}uisN(TpL2c>ioiXhgd(k@OuflI+h za4q-(E)I2b5?{c@#TO7dskC$o2&I&?$xYIBu|+Tm`cHTG&v!o#oCv{*0vezIKfovO zwR!(15;R>dmnjyDq|<3E%VN1)G8&E8EA4h0;J8w$JT#llr&6hO4@5hi&d$e2egI9= zXti3FuIm?#MkAk0CU1wsp{Uhr)a!KsH5Ab8cIo%~sHz%sT^G;ujOlcW>$;>;DK>iv z2K>dg?GIU&ktFFnm&@Te4y)A)z}^e6ZBQr_7>~!yW-|bBu)$<9VK5l%boMsr^?C>) z4g$os4TKP9ex)!#WZMAv_A5yt08ddAV?Lk18HVw=Uaw#MAYle_B9XYtX0zA2u3rXq z!vH6lOy;gyt>)wL_|4|H4gxr)X}&BL3(L0cXTbAaRM--M7;p-_`<*htFWw%A5tOHp QdH?_b07*qoM6N<$g1DN%wg3PC diff --git a/src/qt/res/icons/tx_inout.png b/src/qt/res/icons/tx_inout.png index f1a7f7bbc3ab4bc3ec801efbb8b533cb6b624e24..cecd332ad1f6e461b217e30ff7d442556d851b8d 100644 GIT binary patch literal 2568 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 O0000wrg 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 literal 1458 zcmV;j1x@;iP)3Mvr;B4GHG4WM)DUZt$ww)Z{lU03uU`uwx>o+rQe?z|u8 z-d=a@b4|&L+u$*ySJ*%fjH+q(pTUiRDB5rowbdO=1Abn67A3}TZgW-9svq(;99YJ= z>|*#L4RFol9Cowsh$^H9Q-s^x31h+rUr$Omb`|qGoWah2^Z~1JQK1c59{N6$UF>1( zN1o~z_F_b3k0kKap0=V1uZ8}eP24sf3&mw?5 zAKlbad>Z+|U^HP0iq>)_J0rA^@nNh3MR`$cvbmh$Q{xZ-gYi|_4K2%YFF34q&3IEK zOcO1s`H(wiRSs7$Onqu5Z9-wCX)NWe7?IgrJHOr{6@>h4Iq` zdk9t3G2CtuI?9gB z5b;Y{6~=YG;TC<18Rx05?J6iO&KB{7Oj{Fq)ruvecL|fgV9Kn;(2Kp zYQc*||1wsJ(h}mmg*l=ln)fyy2W9;-|5fF%yTu7UhP$GzpECt7qZ#)l0XO#U4hHFn|_|@s@_} zmF~ewYY1v#2tOG?3;rSvyWCYPf;mDatYLg?Nk&RTl}p;O_nJHXVAO&wDpFI?WWhJk z=qoOIyPRWt%5ui8&7I^U*vah9>!76jA&Sm42>K~^MY`ohzofmGMJE)^2#Mcwz=Ub;FHeNYZWphQq z7@FwRKh$?=4liPSU(r>%j%*!TKkutMVEY=L#-1R?+Zo5>d_i@HdTXy2YVk_fXsbG7 zw~vL>fGkXjw@=&#`y@P0kVEgP>|wU945*X6yPhmVi#CcX4pUz5ENJZYTVIEyssPf zXz&Hm4_}#V;}* z+o-)}NUhg6P8kDRi1**A4r%Z^rEYJYD>be&G^7Q1)gQlW@cSxniRbiOkIyyEb9mHl z>fMjyGF~0BRJPPLzLVXkGoG-4R|9ZT#^Z!=Oc9SB>Ht{OMS3cM*%*v78gs20WIKay z*KT2eM#nMIBluHi)cpJO+jtr*s-DK`@QfQR&sMp<)@S-oyX=i$}tsE~P2p09NrI%K9roAG5QEP@7-W2gij9yX&^uaL;eobq~ zIdZN2Kn>6s)S&3ZA;0-nD|sn*OhS)}W1#2EU8B#cJEZ0ZE>#v0z*~vp&1lAdLypuv zPtfM(dUD(RwLtyo>z3M6HGKi$#f)yKt~UCl{IRBs@(6?cn*Q(4-yYI)TdB!mD*ylh M07*qoM6N<$f;~pXivR!s diff --git a/src/qt/res/icons/tx_output.png b/src/qt/res/icons/tx_output.png index a7c5ebf56b0e41285e95bbe35f653f4bb4db6cde..06d9d0adf27d7db1916b50e9bac7e57c60644dfc 100644 GIT binary patch literal 2699 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 Z{st&W#y17AgX;hQ002ovPDHLkV1oC_4k-Wt diff --git a/src/qt/res/icons/unit_btc.png b/src/qt/res/icons/unit_btc.png index ec3497435c9bd96caa594d5fa007a80efda05a04..f3246fa99948a136c79e1bc14abceb71d1571f83 100644 GIT binary patch literal 1318 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!3HE3&8=$zQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?_naLn2Bde0{8v^K*7iAWdWaj57fJ{tG z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09svx0_iVsd64 zh_4CO;OlGUnO9trn3tUD>0+w{G(s;kGsVi#!p+Ij$=t%!#o55n(AC7!(Z$T!+{N73 zz|`E)+{hKC*Cju>G&eP`1g19yq1O_pUQk-dEdbi=l3J8mmYU*Ll%J~r_On$cZnv1> zG!Lpb1-Dzwaq86vIz}H9vq&)w69Oh55EGtmfgE_sPt5}+_ab1r7EhHGWME*N>FMGa zQgQ1|WOr_}fk5wSodG1EhtA!xQUACW zYw49AS*p-bQsSV+#CR)Ayu&-iuLye!`B4sPcSC(RWr zE8#KuBc;Hw{v=0(?Bs^FbGiNzNIHsnbo%M-(*I$0~^|u6W-0~acDTiCVe6F zn)T`(Z0o((IjvYWPw3DS`H$I zft$ET&NU4myQ@6=@4Gz>acA)U#=*G9HD}F^)fNxu$`~`Qla2Yu^568BeWxL#&w*)A b)ebORtD3;ww(5Q(sO0i=^>bP0l+XkK7K6)N literal 2107 zcmeAS@N?(olHy`uVBq!ia0vp^@<1%W!3HGX{aEq_NUzopr0F#DPf&c&j diff --git a/src/qt/res/icons/unit_mbtc.png b/src/qt/res/icons/unit_mbtc.png index 32bf2f2ca05a4768fc8e280a1e4620e3daf42538..4e82b652748baca3f2ee28c27e41a074217f46a1 100644 GIT binary patch literal 1407 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!3HE3&8=$zQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?_naLn2Bde0{8v^K*7iAWdWaj57fJ{tG z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09svx0_iVsd64 zh_4CO;OlGUnO9trn3tUD>0+w{G(s;kGsVi#!p+Ij$=t-$#o55n(AC7!(Z$T!+{N73 zz|`E)+{hKC*Cju>G&eP`1g19yq1P0rUQk-dEdbi=l3J8mmYU*Ll%J~r_On$c7PmMW zI+~c7x&h5|a>MQxh~5+|Zh`7G!>Lyv=oo!a%p%1!ObD2KKumbL1#;jiKQ#}S+>3ze zx=HHKMFs}OPo6H0Ar-gYL^k#|8}PJT*FVtj;GV!*$703Q17d0@AK)-JWb9PWBGGtj zQuCjm6Ks4#v;@7yydJUqeiP#)eeSc2Oys?$=5F=_%nukpFjO$uFvv0RA1Gv9f5>c? zlCs{~i}@E~W?hzew!$RnNASg8pMGmC{cp{vu%(2R!Go#F_{QUkKRyhLrWOjmS+S9m zW5LWf;o1_-N$-#3OrO+mxw`AN{(~|mg#^A-J_dp8QnvWkyPIUigm?~bV43TveL-T& zVzaEnZ?vx2d!_Dit&1s;_%R{qr~iWV=1Sl5tY6Ao1*ZkO`zuN|Hc0wL*1IfeF1q=m z+UfjBA?A&K+>TH=ib!uk*PY$|TzRCG37{6PPPe{#~slIFvLQ%#ueOuprj6&jdR zKV{C0uy5x=U-jRdvv#>d`h$-8LWbv)+%0@U8Jm|)VOwb%nYOO-=RN(oy>a^YJZB_XUMbC0xC+yV^W36aBz4U>1*{drIQLA@z?3{AZ;GXgG z+#hE*IlgAz3pcI!u7WiTv+dt=|BX-nr*6pK f!2aMwk$3`w$re4Ih=sRpK}DjctDnm{r-UW|wJ`QB literal 2107 zcmeH|Jxc>Y5QaAh`O*Z_YGGk1l2)`*E+&U~hy=k8F!%=)ZN(y;wb=Rrf}MXL2r8B$ z79vU%L=Y4-HYza)@qOd%F)mR_rNvEnGCMPGW_Fiww>;vcW6`##QYvO=tWo$5&>9Zn zyHwtKfD6tHr7czEXJdDJ1)0cPW_&@Z_#p|bcE#J33KeauKiiWCoP?5PXngZ;z`ue2 zcLP;yN%MmB5lFe))cJazk_m7M-oPcufrgBYwMDQP1NS;1ywov02yOs3+6+3uI;fpw z5&j9>0Y1Q%KndIe8)%bF_3#T_6kh6>-Up7TdrJ!QfIG?pKK2;5xbZo>Hfkl$hy_9kzrEDQW{(X3-IO0KinGl()_oWO*K3*UY9D#9~ov2XL$;ofeI*s YY4CT}S8=*GuO8U}fi7AzZCsS=07?_naLn2Bde0{8v^K*7iAWdWaj57fJ{tG z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09svx0_iVsd64 zh_4CO;OlGUnO9trn3tUD>0+w{G(s;kGsVi$(9y)q)Xmt`#mUXk(AC7!(Z$T!+{N73 zz|`E)+{hKC*Cju>G&eP`1g19yq1ObbUQk-dEdbi=l3J8mmYU*Ll%J~r_On$cZnqfX zG!Lpb1-Dy_aO%|uIz}H9vq&)w69Oh55EGtmfgE_sPt5}+_ab1rUch{PAp-;B8BZ6- zkcwMxW;Euu81OJWyvlk>@Rr~Ujx`SM3zRo7X&>OYFPPAh-tu4Y5XY5?bHcM)RVDIjS`~QR(W=l?={j|-JlWA7LzZ{lsU(M{U%j-J&mkNn~ zkAG0cG(m$;l##(BdhXG1%lAL6V#<8%`xPQ>e2aPh3x2t5wD;(J^)KCrnPf_s&YC1& z6E^DDVqRr5p={qn7kBSN`Hn}=et*Z4z?{h8vuC^Qs{SW-f?qd%Oxu~brko=(e8FnQ zH#3<(O0xA|`h`c>%Knh{f_XCB z3=0~1Z@v+EGSiiz=&0Y$rMz>J*zEB-luA|0dSJXSpSVgDYS6?MpFn&9 z&J(C3YxsnJ0g4T!$-7ocrolD%26vzWA{hr8%fOic&n6*OsbhKwJOX~uR?r1@LCEYz z8B5=6ejA$bcRDhCiXf1Q|9rUtH8Q3z`9R!Hk!7-nrB{%*G|td&l(F=A8qs20V?2S>#PIis8R9D1gBoZFn zQcSp7L?eS-L?|(Kuls&}KfLGnJLmk)_UUZ@L|bc95urUo004-P%#7`JG~-_u6xfj+ zdY;`o3K3*TauD31C_%4;9UDzGa|r?fQvbgU{%Ml5vg4EqHgOKN51<5xdIov}p`oE# zSNyL9UGk)QYXt=QFz0mk0D!PE$=JXltnf!sILF;Y=5`6rHA$@&oqG?aS!(v+teUdE zvz<$w?H*f9g_3}x;7#*vM~tx)TnKB{he`21w}m;#B;RA`f5usytMWxY@J4H9KdjS_ z-a5?JnE2=Gd{1G}KRt~j1*)f3hvu2#le#{1pPp0mzAA~9K`x5V;01MF;ITqHBR&h+ zN38|+SWD@5yoFsp=>mwT3YU)l@8EqqB1Zh^I*bJ;h<>hG3Yz*1gdxMwD;_hGeXZMC z(~S~(d|6o%+>qld!6FjiCowAy=%8(Y0%t4hUW|!+=4C7haUKGlu=Vk|*~bODxxfYd z6*^-5t@LFufABoi2sy1gd<*2+@#IL!YYr3#0Xu+Ff0!yjl^~ps5l*JIHyQW;LQFWl zhR_g)4iqA*m_s-ok|#}iULI1e23G`*y2&=cPU<{6H8L&xcgR&!!#|q=jxUO5(=fmCVi7|y>bI!a`}4u4o!n+x&UV>{76c3UY}6lZ zM;tTqLy{?9V0>`K@p6dzyy>PC$XuX%Q7z*pHe~Y^rc;Id&X(owREor)V$jM~nh5{D zn$K`Grr&vXaiv!jw31eoyQ00hqLx{|FOrC~I}Vj_zI!yPRIGCe(t`FNZ#WC*3vfO9 z)06EydW$FT4#kM#wzZYDR&*gP$@L%tp(fVG^kK_GxFX}zE3LpgBQVkAsR1?KFV{K~0M{x?KW3qGqqlo#V6 zq4|b$0um7$#^Ss;a0_Y+4dt(p?}`Oy;Z@TGbb+~RkM=2T&B?>@ZQIN>BC@+6ExC8M zPvkzTt--nzqOilLqIL5OFY*u2Qn-O?1HTXZQL}qPt8^FW1kRvx+3GCL`z>>xc!dUi z%4|~<)4$=N_;&qC(^6HDupD;ky(QVdQoCQ6B+O`Cc@ZyLdr{alQZT>p7ANq7;X$7*X{YgBzTda z_t)4NjfFB_?a=E=QCsPq+l^5q#_-z)z)F?q1i$p9KLE!0o=I0{ndlFOMi%!nD@r!6 zhoKgl*V~4lwnW|PDe+Pz-BrIb`n@&#cT%|`b#d2_3yO~%?bhiHp1JFC`L>;efC+Hm z7Cv-#p{a=>9Py1PkHcN|S!dMZ5alALwlAls?X20|VES^eU1jQAe0eCf_h*P9g2f8W zbo2rd570)Q*=)|F(F#FtC^KDcCN!@`vJKbhxmWHlsQ zAd2fQhMM#9%X5lXjb7AUI~?w1jMn!T40-gofyZ>tb4i`kr5z>vmerd~r1XIrfpU@X ziy@C$HIchspOl%B*b>1)55X(4hZq@B`@O1oj=^;Q5i-SxIe5BqyPtF7Fxv&PA$|*& zY0xb7^*EDf7NG(8>xi9&4YV~Et{V4Tguh07-Wnv-e+7#H|JO@|YB`l3F`zd+We)ph zdA#BS7ILJkYI3c|j!thYYqf6&`jZsITWzGL~e^@rmNq^}64e>7Ib;_8^ zO{vjyycJ02fcux{0z+x0V^ZXR_PH)n%(4+GwhCH8$BOF6dzV_e z^JDu=4Pb8Xwjfco#R>e&<9pX@ph;LQ`m=%OCHVP6K}!Z@=NAqZU&HA=yJOq+s9d*+B6_-hI9M9?C zEVm)qdTFxTVdB)L3)`kAvF%N=@F2BMaJ~Y|F)8D6_k0IqhM_II*1AU1Kn|$Sj*aYV z;HO)AHw#4(!_`hM7X?tV81_Oh271)Em}+T@S9-|Vs-)bcW7bXq{4Brgv5#c0F2w!Jep4JtN3EOZNMczm$+dJiAD#!9JQP4C$IU>vx$ z)$Vj)0M=C5-VEc+V#t$_?=|=c-|B)n(D)0~hQ=jGw=3I+4P8AHCM7v@%^1hgUg*NA zKG*7gT1TpjTD$2DajC0d-~?N61-|7s`-{`~ROgyfeLt5I*N+XdC> zwv1hecZRaGIFzn=m~Es!u(^6JK64p^LB_p!r@{tmj zyM>;<6hoC#f85``TbH;IURJPIV|q=W=>~RY2mkmWHrAaE$a7|?+@cnrJf%x9XYLNl zyC##@?M_TB3NEaRt+Ig#Pf7_wt8@*lRp->P5BdAHEoKX^;SpN+ z>2A~;n6v=Nf-`Gfn&jTfe*(Rh$;>@Z_K{r0_A&3%>|fe1+VHv_r&7S*`u#eOnd#2) z;*v)ud$aJsZYB3!g*kn3L9Ko>wc0e^EK2AwHoTD$vO zD8tT}u6mLfGGXKo9z0-Zv4CeiDL*26G2)IJLnxt7tgt`5>-Ns!FgMX`gJ&A%#i?8F zB$nUH-S67>NZbXGw6{aBm51HSh`Mjn8D0Q#rq2A z>~QX?I3e3VZgl`FZYzrtid{+5a*|NN08wl)6C;U=#9tM3HJ5F(D_0(hHOi=Vd04cj044%KqgTL1ZxZtPq4!g@HisHhCrZ_9H<0)%*2JI zX@QoLFf@$1mfmt47&*4IP!^6I$&O<4#3Im-Fr%L!oG<2!!ucOaIXV5o#9&Q)eJ69zxZbF! z8B>eI?lB;O38XW6iUMK64-_|cya)dK(zyZ@XPT8Djp9BGOnB!!0j{K(&xKp)6_`Ul_#{)3{Mg4jU)nahz~dgAnCpOHt|kNWKtU7Mo`0gqvv?;x*Q0 zR4<-L%;d4yUJM#IV9Vu(QpseJBgvjkwh3e5@iru~L#WLbq9fUcNwFi~w~$HpL_B2- zqOUL1{k_l(J}X+eRVG4*{+FR4?(cCfGHHQmD|l3`*y!go?w#)l+tHx+ftb<_ z=+v?%Jty3_|7!uq<3rp(oMU@9oA*x}YCP1K>cc@q{4nu$rjYH*0eb>=qmPGt*JpZc zC!F%!kL12vh4ImMi}SW!-!G<<@;IY{jQ}o+IaUCI6YjmSsm$a0U}ZrgqsR0lN4)X^ zKls3F!WTL}-FF>~FLZvo@04pGk1M7TC(=zDhIlDY-SJbwAN+#ArrDFpc4Q~q^x^3q zeq0GVGMK>yx35UqlmvqPgwyny89mp1&=WE<;W=I|$cOn@HOEK6uL|I|6x`(3ly?g~ zxfA}+#?&qSp94d~AxWS#U~L2!EF!1?!3CuOYa_T|5kUnAE+`FH8^HyO2r58uL21C+ z2rgJePyvDqN(0tLaKR#i3J_dS8n8Bk3l>C3)-1-L(ojr07r+CQkTi$xexpAYc zcxj&NQ-e283?4j;xNsNizqgMt#ds*jD%M$bPAYn7QTgzmmp|+@`l#jL0U~peT0x&xtyRo} zL^Zv6bKCR3HM**CsoBjlf0rfxG4WY9LG>zy<30%79?@v%+R!b_wOb%lG*Xto&Q{Dy z`^zc-5N-B!Hj&yTYHG~^XjPxyuSL!umUK9IV*q4cD* zM*iC|#Z$^FTa`a&87wVYK9IzcRshM=u1gn}ol(J?1|O%7_T5u!sv5ngAo@MOF}y1wh>zkS+De|TPdb;;fnHS(5N#UGS{SH-f-4eh$ORa>+C zYfl`x7w5n0ykgIRUt6?H&D8utineJyLid+n+YpN$sp-A#;B=<(K#W~xe5-zsNe*!Q zNpR6t?K;YW;F68k&L(gz%IpULTD0}+Q*#qyDD%4RVi!IN>lpTK=O_}iK090!tu`XL z-{#k4zgk3M8si_l_$FUIvdX8tpAotk-%1=_Ci4w+cwP28zW`NTo8W2Q>^1CpzM5mc z19b+SeR2Ef*}q{)q9Mx8xKFNzN*`efBPXq(&_jkx_HCJD{@ z#pt#wPvvyLtn-7%GR#Md6?(etje4eY7u2x?2QOXLbu4zv&}#04U{uP8;Ih&xRrSLrs*b)z0Z{X(UHs&kZDxb_LOGz{7 zU)&sYp#RgKjC{{NH}E*ZQOVj+SfYBjSLc_QQ*3-yxu|1QCr9H%(>c|1Ri6%B^-j)L z*r11>X*hjlH`;b{9&Wn^Z*k!IPm+g8bxmvj?xT!Uw{})OQpKeGnEfWA5}#e15L;qg z^lN3je$kFE7gudRKlI~8!0MY>qL|J2%Ea~estLMXyN)pRE$utJ)tV~%$&Zh%=q)o~ z)~LjE=el<6t&x+Z*Rv6SQRNu692O(QY!)S zS`?0f8{NLBH+bTCw&#q(xMM{XO;zH{(Dib8lQ^;&b-~JYKhS0GciSQ_9q{!tSId-n z;H&yruXZeL)E{)Z*2ZfO4eVQu?m76KEl(hOC5RBdNy@za*lrWU(o(kDZQ)VFo=0jV zTkpPAE^m^`mS{dWXjmta@vx$1E1A@#kN*kr>K&KV+2Jp9PFyk6ZdPm7YEC!RW>PVh qnfD|2cH3>%Y9VgbA%zWZ18no0-M{2q?^FJN0x$Q~jB{=wiT?)O0-yW< literal 861 zcmV-j1ETziP)A8HPHTJ4VDT5>tRF!sZEG{2rpGBcZ|Y3@QN0t3MQ z>Z;C>3)Mfb4Ae_{BrHqOQ?fFBMW!dBOOZ(A`AsGo5vkJICT$TIeoy70o4q{dtXji& zla4=T7H#uhr!90>Q?1)k|1ew)op|Ep`4@+Whu_@xoEb!4;1IWy--ZVKFibMupzolitjtbKq)ZX>?gOq9onhOPJp<`y zVPuyHfMO^Caq|K9(^p>5-}UY>wN=AStA-PHZwpR!Uq7h{AOIw}f`#{^)D0uM3;;?~ zx=}RpwLwRF{B`P6^1GSODbtj7V#>+vue3HZdn*QJW>%VgXzCE~|WTq()A3?Cbqcgrgndi+|tjlf|i_qGS>>I~_~k*Vfim z0wD%~P@Ow6@Us6W`Mg{{IUkr}rMsBHWVPxwUtSEv>wV%_G5yNWTxPJYNh|2J2zT|g zC6l*fieV`lQUEM^LydN1DQjCurBV|_#9Fv<&m;FYFM3eO!<+q0GDf+YnV8GJGPu#R znoj?sSTqqBC9Z}1k>lsuZ^UEq(b3TxL_{dJ>vazvta$FRL*DK```z-_W%tHZ-#vx4 zmc8eIE$1@){y=O0rI$u0zaPx$y6zw%BHA?4maET3d>_7ZCiM*d*)TFij~b3!CTDIT zQC{Knbsny3_f$8cp>BRh1W>Tgp1_&UaN!XoXA|{9_guTAX!;iLdS5v^eV|{}P<8w6r#rXPAHk(T@6Pu>& n4$~HhV(|YhZ~MVayW;#Wu@*ehHphv+00000NkvXXu0mjf8V07} diff --git a/src/qt/res/movies/spinner-001.png b/src/qt/res/movies/spinner-001.png index e6ca67a1b0e849250988fe936a1bf5a96e922b79..4f6f9a487ba8f1714ad603c796a7efeafef0ca3d 100644 GIT binary patch literal 2785 zcmV<73Lf=|P)004R=004l4008;_004mL004C`008P>0026e000+nl3&F}00002 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 literal 835 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 diff --git a/src/qt/res/movies/spinner-003.png b/src/qt/res/movies/spinner-003.png index 52bed625661a41dcb99b78d372578d81689649cf..d7756e73bf6f79766b7aafe1b4bd91f64d198e3d 100644 GIT binary patch literal 2775 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 literal 836 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 ZG&uJE2kPFs3w8s5qunvvdp3T_{{RU==0N}e literal 855 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 Z!`Cb9{|D;dTv|K|07N_qS7+=J{cle~-aG&R literal 852 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 JYE3-i{sm;iw}t=! literal 865 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 literal 847 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 diff --git a/src/qt/res/movies/spinner-011.png b/src/qt/res/movies/spinner-011.png index 0d0e811ea7a38844f48aa045aca89eccf683a51d..fd4b63ca5aaa41c74f589827f2fbc875bcfaa3c8 100644 GIT binary patch literal 2751 zcmZ`*X*|>m7yjEBV;hX6DTA>yhM6owHOA1$&Rj*8?7Jpg_N=4EaxsGjlRZn}4&^OU z*|SV`g-T?p5N-*V%Iki(AKnk|hvz)!Ip;iI&+nny*_;;w$$|g?5V9Z=9F95SAMkS@ z*I)GchGXLPGqE-SfaV;*A09l%8tz4Oum*rwB>+fD1%SVgj`=eHM4|v-%^d)+3;>WK z)2{THAK!9%TAn8Wz`blm-D4$ijp!T>02UMffTPYVWB+*8XF)I_MbCX<#$6*#pL}s{ zZ_`)b7G=v{jKiIx;ev6Us@?weJUp5rmYFErWy(aoqFs^h4EBzV(NYzD3QN(QYPJJ4 z{wA%<4dTe;S+UniQ{~`9ba2Wqx5fmwJW34aAKYwvvbQ;3vcUdXnmEuFHM$i)y2X6I z#0=*Uglb-5xp$@T{M!VuB1;e|Av2#WHLGq_C4)Wds-*HTQ8%LpBLwt3Z+U^mvJ@#1 zybhMe5G8_GkHAn}dH&Md17-0@T0h~`%9ChfU#e#OI(CI*KXmnaWX|>M)HDJZeW^#S z*bY-*UR>uZ?iJVmE!O{Rr>=0Qt72c%3g`{PG|ZMhmQrhgw$`|VZ{E){am5)} zgn1YOOp6+dnfFK=y7x>F{$ND3c-~={{E2M!B5St_67$yUQjiU=qGQ(Zf}3oTSiW?f zJy~s)ub1+sc^k8~MLA>Kmjr+A5D~jY;2rNgiv6RGAd571T`QLE@h{lB@4pys(?U-m zId+RF5P9cP7%(cShTat#*sXYCXq$jayJA0NeD2FKf5TNtN`ogfbpT$-zk!1#=;m^Zyvk)h#}wMdXJILCJhsk3-`6JGdNhuPhc=$$A7u!_1^ zpOHFxO?J}sb-fkFah5H42k{hp(j#Mb)cr&Vo+?L!xX{O~K6tH}!t2Y&h5{9=;DLUc zDkN{DkdHroKcu!(D?co^OIehMao;mhWa9kMW3BOy%e8KW3mA&Of*k+KG|D<|cg1z= z{RbH?tl_A3r#^3M@anztXHq$9)@VOIaQnkTWoU7=V^I_Z@_gd#LtXgNhi6IT)`^-5 zEtU6ZW9c2de9mObK}1d9bUirw8sEUXcN@MZ<1npyc`vLKT!x&cHt`s!Eyjm}8d}l2mAzhG`T+4>sbZqT}g3`5b4RwbtYtw4KAmt8mEN1YIdJ?irP>bV0UZf>Rq;6 zsP|cG=izWS3{Z`p>DTGfc9G78K*kA9y7wmEt9A5N?=~`rRSyaPx*ttEjK9@RP6?OT=-TPW9PZPr2e7PcBOYf|R$d7YBLWQ+{)1(3hb-Qt~ zbZ)J-0%+xJ?(rbc^R60~ojctEIs8`@{@l(HrFL`3$!(e;mpF5{MorotG`F^i@YTPnDV=$p`R?J zPj;xonq5{)mTf1&Z3{oVe(vFG>zHYB3O)ImLAv)zBkiq)P+>}o+^l6EMDJ^h+HEnV zQ&aJx3hJ+;vm5N*mi5L_UxkMC8^cHy3 zz*XQh!b;zA7bF{IuXeCvM2w_84eYP6%=rfOGGel=V2dK{sTV0H{s4iDvJOfs#1W-a z(a^0A{Pzd?ud>-RnGvab-Ty%kT{{f=NH(!}6`os0OAlWD+WZYYy}<4h?mrRViTH-N z$d%hMc>FM4fW4&q4uJo#GA@4dV|9e6w={j#uF3OmP~O5Rlq7KU@AH!Ls4r2Ay5Wyk z{H`Ng^88pOaWCfkAHx@CUu(WD_-alc0DN_bzF>jJ)tYqv6X&KRuV1MIODVx>%^oY=s14q>PfB}<`v!$f zTWn02{1!AQab#{c+t4bX=Dw62FffH6L8}6KK;A**|YEEkc{xDH! zG9~rFfJA6%0&FFtbm{4n>^iAXu#zODqS|gS0lcgLk%aZU3}sG5w4n~OZ@xB&$tH2; zxeuKQ`8O;58=CN=3rF`G8$F51>lcqxo>GL_r3i122p_Chn9nf*x+ootmX3}V>NH7L v2aD0e>ga2rbg(GYe8!h6|6>Rtdk6T&{C~rruYX%QHUJi8HiRa;d&++S7xn6> literal 856 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 MttAfo$lNXV-)UD7@&Et; literal 861 zcmV-j1ETziP)!a_j~W%y?5@N+wQhIFV71bZk=ehcF1s23hr81*a(CO-PsIEBL7PLM~IdY zsYD?mhQ+WS%#0edB1u6atc+UNP+V%Y=3(b;cW!rk-+Q0_aI2~G{PpmB`0#w5A0Ob> zAk9#>Rcd;-LLyht3^pZvM(=TkOdrwX(IlR5$ETDYMAOLg+ znFs)kV0XHH@Av!bvQri z()m@WI4G6ED3r+6ZV@9+izHf~a=*J|UhG)Ev55(A1q47?DX=SWx2CK1^mP8c3O5*E zpIelD{ltQAFI_jMM>!?2mTpzEwA%x3s4%}exR#WsYDO}F02qcpGW@1hkWanR+kMvw z(q_HK8)zQt&q(RFPvpYz&$$w z4FC`{jp)-)KC-v-;dNUAfq4sNXI{I)%8VS0Rt&=zAp$f2XsvwLsZj=hvA=>_9@C0+ zadLX}VBf&@S)$?5UfZeIQ#QMaSb>)>_OCf}uGGf>FqX3~P6ktSqY@k?0xPCDzi{(n zu3K>l;>Kz@4zDc>>-cT}(9BG^d|_y$7{3~dckvx^4)8kaEu&_u)lD*Fx{-`&2teH|-RwQ)_uj%^)ICY6{7!Kd)~5B^ia z&Xr7O^wqW|UiQmelr-EW1Kt8Gz%~h$mjD% ncW&$Yu)5kx%*C}*>UQ!!)C(IsCAyUd00000NkvXXu0mjfFW;eT diff --git a/src/qt/res/movies/spinner-013.png b/src/qt/res/movies/spinner-013.png index 4ae5a671a34d1911be0215dd8348ebb6e5340864..863a9d29082b50f458161296f2e830279241b233 100644 GIT binary patch literal 2896 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 IM6N<$g5)-`-T(jq diff --git a/src/qt/res/movies/spinner-014.png b/src/qt/res/movies/spinner-014.png index c3a81add0e870a748db0c0b8f76519b6df2311b6..d01086cb98877d063814bd1dbd2662b4014086f6 100644 GIT binary patch literal 2867 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 Z@gIz^PxdZ3SQr2R002ovPDHLkV1m-%lQjSU diff --git a/src/qt/res/movies/spinner-015.png b/src/qt/res/movies/spinner-015.png index 184a9fe4249b059254e16c5e801b9d84d6cc9c69..402dbea69348329a8e5a6cfaececb1a5de76638b 100644 GIT binary patch literal 2860 zcmZ{mX*d*&0)>aqI@yObV`l~tX3P*{DP!zR_7qvhz9hql1||F0$C71`J+dV#O4&yu zMzWJEUqiUINaFjh@43(Yaev$&=e*B(o^$>mvL()l8wddc003?iW32TViT{X$<;?%e z{!)Ji7H>TZJpiCNsgj`H@3C_07x(ZAUYNR`1SW0*8zY~H~{e76#ziz0|3Hz zvRwKN&$`TbGb1bj@H9XIkTwk zW(?K-_04(^c9%k1;ew_rciYny`gXVNp^kaMBQ3f8=Cb0&&s-J1b0cl8yUU6s9a!~R zaK?+e^0qrwmMB1CE$9+!C&RAVI%eFgqIg)y1sv3>+g`NGx4hBphNmzm6i!hH3@#}y zf@Uy_&Y$}6H88mBs%dh`@&W~Vn*Aqv*EEfkt3I=5G%8dRt`hc4t0>lg=}&#FX{0`V z`?x{yXd%y#H<>%Hlmlh6KLi!6_IuMloX1r`9c0`rSu|%0YYGH-&8H%?2x+sx3ddst%0bU-n zzoTxwVWs$ZtCI2wT%$fVK@b>`{I(Byl9SXZH(Qb0KCfQm*ykA85K`Z5L0`v6*R_o+ ze8XY^=|ke6WM*EK>4{ZL^pwVPmeaAq`nHtJz$j^tS@tzS)Sb0X;Md#EK840 zz%*9I(Nr3D^(0+@meRCw5hwrhSvKP|_>{<@KkboRO}*78(t04j?xEO9@8T9exLF!t zfEv1}Wz>R5EAbi=E^8?dhy3RRIZeW;Tp?b?1f2swD4d`NMOa zcKe~@QJUbMi?J6Y^D?$zkU@4f)F@n77*1B~Y0~66tm_<@@zHq5m@^vh2KKfvRFas9 z@04(xq4%j7-J*!K-MGijJgiWH)8_M37=YI=o6>r%7N7!#%ea$Uf%4Lq=UgR=1C!0y)%p_O2$9{`En8*WvN)Z(4R& z=;?=hKT%TIDur{9t9Qz1Qa~+iYs_M{+)=~aD#H*$|0v5MNRV``@1GeTJ$&cVB%|NK6*Dz$lM;0W$7Z~ zG+xPsiwf;33fPDgWg1?Yy=cw1d&;Hm(Ti$Kt6~)E`ffCX&sWg$8!VK+DOlA`YStxZ z(i-Gi9w;66M`UcF_!eklP|h&Z1&D!G<_D`3=zr{-)*Uk>B^Ai)$7ZSshKy#9*F=$I^xW=_RR%CqOiQZ_Dvm9e~;zPcq~@~FAo@loW7vzus^3q8;1SXM$ea} zC|F+#alhoh;#u!mHI+44JlfaQhf!?#AR558P`vGcx@ScBb8L_GKD|02r2y}++~GrJ zt$CZqb~h!**`t&d6?#5gY>S=pS$4h@d2M)MWH~t(yA-mU-;nLaG!}%I_|6~r;#iT= zj44LHtQA+XCEGV!W%`-JUc{o**pTL#*IR)=!)6S$uvd3NQT8eJoaUgWp7_u*52#o= zkj2#TS0!yf=V+5Zv@`d0Ke`8@H=BKeA&aG0 zAK%Lq?QWQUp;2G%6rM{qmhBJLOI`vxm!9POzFTMReiYY7X1=AV=HD*NX9PW)6&y4?RE6zao)9p; z-eGy8OBUspn+6>h91|JlMh(hxeO2>>b#8lJMOpVjy(+Q>-48w2juR4MugEJ<8C8`d z897bU=l3sr0iBNl(k1b$kbncnyp7?#@K1v`4GLd5NbJ-^Cvl#bYCmjM7E1l0;ZH=G zOW$z}-0yV-b?|cM58ZuiW}sZ5T|&vu*BKHv=UhZ(M7; zFtUFVf9_|1pHyP_r28gnS@X6Z_iY7(B3H4HwZM}4Ti!&uS}r_`f$cuR!1=B2$2a#Q zA_FPieoez)B{A%=QH{Nlu9eQ}6g&>B^%D{Ze=kgc$FYcFk98`Jt@`xL~NWt%!q>Vi;PxF4U$1-rf6z2#w{kWBm>A%&jTqOM Fe*;B3Bv=3d literal 849 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 bF*hqPF*-0Xuh&)M00000NkvXXu0mjf%2ggk literal 851 zcmV-Z1FZasP)tIyL;Vz-{0@_$6Rgq`Rjafp2Iok0rH?2 zDnB+4{y#^^HvoVMYy`#$xYbXrbT%zdV7U>Ce*FUjeS_H^K^Ww4(ft-nZS(!ax?k zkLdJxny2dGs;bz{fR(|mOb~ldnC|A4xmBG#yzjfd$z33ThydFO#*cs2c5CpPHt(sm z^*e(hHwg-bW6{W(&$q80zVTIs&K^)&4wJ|+maVPPPXNGTrIgm%U;lVx`~A)B;YZuw zd13Ivr7otqVehUePt;XMqmx?uqka|ZEa$?xuyb}KH2_S&BAVOd`VAX5?D*)|?!gPG zu28@Vd0LFtCKoR&sjhiobFj3c#+j=mYix1`7e`*~pL6dtcyP_Sm%(lvuos?`0pPA! zS#ryk*E_!LI&^Y)`0CiM_uk(R07@waGbsSLH{otP{c-W=*Kd`cdgWU2*#hC^|DT&u&%qqJ(A0e z|EY~+6+>A7a8DxI5U;9rX0sMNe+sw#B7Nn0B=^(M#2FzK_QjG__2JgeSM~1I$?1~K zAG&)0ff0fQ0G?0NSEegRe(t|^{+Uf%AGt4CT2zuc;dJf%>x=W3WA8eY^&eYyyQZ{k z1|9n&J*lf>N0~szh@M{zf$RbRs9Uz8`Q-8Lly~!-WG)|+^ywWk{=;)Ju(wHGX|4Sf zuw5q5{1-10lTxI#77cJgOUskbHZ?Y^vm|3(O#PPXJC*9c_VL)riU002ovPDHLkV1g{yquc-h diff --git a/src/qt/res/movies/spinner-017.png b/src/qt/res/movies/spinner-017.png index ada83fbe84743773d4c2305e7ba584c7266faf64..e2c2e2ef78d59eb31d0a9736049f1d5e42a5ffb5 100644 GIT binary patch literal 2833 zcmV+s3-0uZP)004R=004l4008;_004mL004C`008P>0026e000+nl3&F}00002 zVoOIv0063uBQgL0010qNS#tmYNzwoSNzwtRMT+&bK&!MBr`EOt)}dmjts^kC9Y>TIii|-J z%ScC{Ol5eKszgfA05=3h8VDf@0RkZplAF^%5<+h7?zx+r^GG^;_rJY+c7NZyd-nI+ z-|x2vZsY$89$R`%q%Ym5q0Vi3x1d?xV>c!e$K%G#hpV zm+&j9BvcJf@?#S4x+R*m>LrUYbe8;<#3XugnhI(=K2eP<21tL6VI-p|=Y$&y$6BIS z2r`j4lNP0T!LzzT2!|B_q=O(bd;~dfbWbzzGsZgB7=4BiG+!kLIU75$;i2JO# ze8xDp#aDrsWS*uVDvAw$h{rm@Syg8|TeuK4O@miSbelwEc)6Q@wt=LUy&YULK;{l;$B8;zL8{5lSU( zwg`qF0LOh4ONFWBeSXw<*w8e648++ag9zplpoW=bNotR=x@jCq_fq526^ z?5C>pxOA_rU}=cz&*Ye-<%is5dgPDgCwyu`br+-TwU=}TOW(Om%nkAT`K2>o#;k~9 zdYQ^zlYL;j>56DGVp%So&1Z-YX**BqEm}nvg|RfU*l0p^iJe5VD3J`ijvgVKOB`=V zM0}4s6i4%rVq%mO(A%!%>tT~r_`xmq(1DVLdzSlKIp#}JGjow?l&1}t&3WN~`HT;1 zo5~JB%OJmQ^(-W^xkb9b&9cWHuS5zt(!DkuajX)w-9&N}BM+CXj;s8|`o*i0#UipP7!a?S2C|~SXklVa2~$mtF`WeNW+Xi< zkYKsc{q`@$SV=RMrOooeZk2Z(%pV%UE`bC^EKqw~%@Y$(hG6DuI8M1^L<`s@s7+#& zbwg+jp-Av=ULeacnhhplxD0jVS~rA;F~W^tpTllQztC4vK~I&3RhDj$OsWL+Z#k8J z(1>b27Nh~hbEj2A3A1DYE^*%R!0kuE{G>rv5skqoa7mRoxDnk%fNNoOmGrTSXm_DE zAclbBL`#HrP&ccHdIjEe(D=e}qNfFZT|ZtG(_V#Wx$t#As^llI7Uu+OOUF=|Q?;cl zYIVYeuunaug4$RW|GkQ^36uzGuo1>So2m82L(hM@L5pQ>y{>WRtulnPv%_i~6eZ6c|Y#%N;k zv6mtfHKFkky#@7o98)8zilJ;1z99$N6cV_DoW`7@I`UXdcZvP1F;bYoQNwDhU!Fvk z3W-+pgD88{7{L0FfM6NFk%--i-wQ`CBimYKZ2OcSIDRIx(P*2~`|v9!hZBv(x)ARMliKesZ#tC2>ou&CJnaH2OXUW}GhLXv_I6k_M57yPB#Zq9hsmKZ;+Go?PBY(8 zk47`ZF`jKLW}%chVd7{kl-NQI?{s962F3i`nY~sFoq@d4lr2(4fG5LDGmR`$g``sQ znd&CZ1{!{5@h5h2nAiEf;2rAB-`Ys?ZK1!&6(o=>G5)+Pi|Wqz&2ohoNp1fhkkOeU zwS^*=T28P+E$hTxXbfn>ZQ)ARk?r=IsRkb}P#YD=&sfQ@_HpT11+%3$4b4g!JD5$f zwKVOuGp4pGKe~=HR~;)Vv2bcdF*E&$N91&ei}xn7f*63;$pqX zb9P^VwbynusN_E!p%48`N9sg2ojAi4s~4n4W+z_KOrxn@#*x8gitPFVjuWQ= zgG%;tj^6Y&-AU8=23~YL(9{4(Ae+GyQ*1p|=gxNq7uZh;X{IX2 z%OJiszv0Drc7|C0bxLk7^_j%K=3U&x+bmi%YDyNQ_)>^r4xF%{iNPuM1!pYrG=)C`F0z%0h>QMjQ); zuCtBqf0xQ?co@Z2u7}VpWPHatcB?}pfoC|<^v#7rrdu8VY%l+shCw>h>B=QeaDeO9 z573^V;X^0r!nK6kxQ+IT{{b0kN7(|;<`Vz_03~!qSaf7zbY(hYa%Ew3WdJfTF*GeP zF)c7PR5CF-G&VXhH!CnPIxsNaitS$j001R)MObuXVRU6WZEs|0W_bWIFflYOF)=ML jHB>S&Iy5#qF*hqPF*-0Xuh&)M00000NkvXXu0mjflm{!; literal 848 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 X68?YS@tnsRF90~gUF@6e0#g13B+2Vh literal 850 zcmV-Y1FigtP)k_h9~;(s_yBz$W1{Cia`MQf64%0 zu~^o8y~o=hZp~)yu`%}u<__Yi7Q6cFgY+K(bAlA0C2@K|W;SUiy}kM1VDaiudS~z8 zm_P9Ner{SMtI`|wIIOdPRpP7j&dc>Jk3TYN3Wj>_LP{ZsNH(2l?Ea(cr+Z$H`$Le$ zy0~A{y!q*$44iO>W?CFk{xyZy=j*jg*AqZQ#IPl$xVBWh_i6j3mWCy3Qb2+bCt=Du z;wx<1yJfyOnWok7qc=wG}^?-yXg(L#K zQ&qnAiT^L2y7dd+YC8}eIbR*S@?A+NImzk)0QqIDrzdzJhiA_uKI2v>ZcpUhZ>Ki_ zLTXY-0C=msqGo*jVURhkx>rx*Q+~c-sF>Yc{dJyoOQNo zzur4})*j^!2XAyIZvy}!@IoB`Nhu`&_-c0?^N;jJXK#GNGaZ#2z3gW0a`DIyso|1B z=T3l@k(WJ_5Q3CaoaWRE%gZ)aWG2VFk$Jy1^dNZc+EAz~9u1ER0ihJs%l{R?l9QKV crELKC7iK0rVY$rXu>b%707*qoM6N<$g15?$vH$=8 diff --git a/src/qt/res/movies/spinner-019.png b/src/qt/res/movies/spinner-019.png index 03da25bc2a71fb490710b287fe18cce3c2f61d50..5f18f656089fc2100a8b65280c00b3d3ad6da86f 100644 GIT binary patch literal 2808 zcmV004R=004l4008;_004mL004C`008P>0026e000+nl3&F}00002 zVoOIv0063uBQgL0010qNS#tmYNzwoSNzwtRMT+dn@CFHw@K9b&%4;YV1Zg`Ad;nXf(*cTNMTg?xqk~h5)(=W;>0qf9oL01G ztBz8XQUQ&KgobAXG(aT0Omag=2zj1<2(RR>ea}g99vA-m+dg;Sz5e^L_Bv~=eSCO@ zI8uOmx4P3jpr{egbnd1zQRK6YLJwqc0XqFz!+8u046511G-A9K$_XU1mWHb|o69an z;`drC`!SQRTF^8w*hp8e#j+pIQ5!zrmEV!- zWXFz`b3TGHdwkSz2N;pn~>k>JJ5gZ9oN6qC^20Nvc+@Dc6 zODz)#2v0I;K;-rT2k-$ClU<|_uV9gco(s(2HftHws` z)TMzZBY~*SP(E(g@nN;pvymuoNox3*Kw%qHODzWVoTZpE76+$@74)z}*p8ThvCQH( zWLo&;3HDM=IeXYo3hDUi#!ne!+WQBrVF$IgO-;Ly!ZOa7%tsR^+0Hz&$h>N#Yd{RS zd`P27+cH+s+gpkN(X8N{iKu&6&3N<{szf7=Wt=cwvb&i@AQDW#X`Bu#=vh`WDCDsB zk;9u*nUJjJ&ynF}(7BU>FoFhoha6&B9SRz8Easr85<0{}x_C{oS>Q~iYs0F**IT^|`GnR48WGIR5(Dbv2ua!FX zJ;i(^u-H`nY+;Jh0`hYonOZkN-{c8cipRETHaGp3#$AHCVuqSZN;@g0l(&gFtQ!2h)8y{0u% zDH6NePL_q%I(=BjIShgn@ivp%u<+u@S8SPI*l%3;n4#!wzUAP7P9{_M8RLm=lg^B0 zj>1GKqMO|(Y6{ONteH-BkEwvJ{8j9|hDBEY!s^K0$uOa|jMu1ifoLhOaZIR>VTRQ$ zV3p_q?hwqA6&?F3>scI?)6U3bli+SZCIVN@iBj13$XP zmqKkL-RvP65X0-oJqWtjiGy1vT5athS|U=qBAl&Gqn3U`ZP1E+W`$@_{8e{rHm1$! zF6jR{F4{xX&rzY)k_xaL(%LdOZx7LE3dELauG7rG2-&3u8W-##dW8z1wuT(niFOxU z%0!{QSbU%95XNy_+#~xe#>848 zig@DNuCUgv)7l?cPm%kC!(#Y-ICD5+#o7d#^9R%TG5sjzBp+EZ-T=5?5%|qh z+(+#IbVl&4II5LoTa0RHB=B>-xbC*Rz*0*_N3tR^8+0ac7~pZSyGEX~I8=jJ*UCd& z#sj8}n@%?G*kcbh$9h^3(7$k*&f<39c=`2gCH&i5;yz zPjO>D?{SVMzz;$)OgB)M^OlkgJyw&1kMwp9VS9mcpzL%pB!~N_wOA_gdM<;7GXe<7YZslt;-8P5TE1 zgtYC%NPcT_zpb2my`N2uIGz&S9W6^950G?II~_lr_z{0nW{6!Yl{_5@vpIyfsJ5Vf z`Vo&09neT5n^7z!pHkD7#XQ;m^euZXvuh;qLw?0zlixK`h{0^iDWRSbj3A264722U zI?D6B&Sm@NrR~re#UCxqh=D;9!Rx!Qz73c63b@z%?~?gh$rZ~Yx2OD?tyry^!J{DN8g4$CK@k>kh8C^ph>ue`^fftj04pYiuYMh|x1X1wu2rI?c@h0A2InbLl0@P7K zIZ>2zmMZ+zqj5`plS(6v*A+{&in%xaQjcV1V+A^6m7bylPP-`8u;0aGaF#~Kis@GA zB#=kd?Lia_3h2#nacTDDJo(Ojiqw7dRC@6W8E++H+HN@I9j)d(!rt{pA zM4LE8yy9y604l_50JkVKdhvl``JQ5o+u}Is*smnWC^4}=iA(Ho_mja+5;Z6yo-tz9 z%1QFvO@npTOWMc_Y!RQt-s*NyYiJA>{YmR0@r!>Qr8+mn6ZCG?IHD=!e_q(SZjNje22Hn2jGUO$) z!~g&QC3HntbYx+4WjbSWWnpw>05UK!G%YbPEig4yGBG+dHaamkD=;xSFfiVV?Oy-@ z03~!qSaf7zbY(hiZ)9m^c>ppnF*GePF)c7PR5CF-G&VXhH!CnPIxsM=*Hz;H0000< KMNUMnLSTZDWG0dT literal 830 zcmV-E1Ht@>P)9moFv(+6Kt>-l)O&wb80_jiC#MN*LX z%sHfh06?QIk2Mn!Gcz1^TY7f7WwFOe6T)5ktA8HFZg#xtZ6Gjsz{g{p!;hIZ7A`#9 z5Ln9k)v3&N4(4jf;R>6+=Q~%Bq&ZO#K!f2!CK5sjO;e8YlVvq|^Ih{oq04t0n;y4# z>=D=MIq$xj>gm*AA^cM9{%hk;ol6B`Jq8a}A*ECR;Lpx2+`Vi28MoUrV`O)(#Q6E4 zeQB-zL351%kX-nU>yQ#4O_3QyLjyC7TfV?s3LpgllprYuq)CwifYdL%MGwx-;qLR} z_1XhT?SS^Nf2-9trJ^*gk*h8I_i=YeLcG%l07?o40P6~JPh2R=efscB>ieE5JHM%L z7~2aIgZ}Ap-wMra@g6D82(6lHWWIfgm@n;x>*7}HWu@6C0)`F%Cabfzpr|-CHg2}@ ze_t}7zvn|6I@g}vWUE4H@v2La`XX*THAxTu?&Me{^>Z!w_zy|-fK*Bn0i-G`0=K!R zm78n!M;`=N>dn7p>i%@+I?T*STT=4f(pP9L%W&SvdgR+BrFGQLG#=lixbJ2=vK|n%NB$a?NDKZT~x@GIm zqw}(J)(rffkWfl#Qj*Nd%F2s|@AH$IlK#45{bL*Y*zGqkRIU4$sxpo5cbt~T}bG0SA;&KMD7b9!?WRcu%_q6O; zDfx+(t|@)dp4UxJd+#;0bccXww;+g-$zw%QiqEbxjY%HT2R>mT^yl%J2mk;807*qo IM6N<$f+0zkKmY&$ diff --git a/src/qt/res/movies/spinner-020.png b/src/qt/res/movies/spinner-020.png index e7f2ac78e8843da3e07639c4e5a72713a8cd8923..c12ae20016110cc3b8f365a02aceb88cf082a2da 100644 GIT binary patch literal 2800 zcmV*(P)004R=004l4008;_004mL004C`008P>0026e000+nl3&F}00002 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 diff --git a/src/qt/res/movies/spinner-022.png b/src/qt/res/movies/spinner-022.png index 6e236c805e6ff1f53a8aa4a6b8567bc14141ae90..69c6657942fefad7860136eb60458932fa602afd 100644 GIT binary patch literal 2823 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 literal 858 zcmV-g1Eu_lP)_WT3%EDu&uUR#*MMfT~05TO;^YQLNGj08| zq!w3#%x`wRmC9%1+qw(9`-yvhZ?8*CVdRIJ3;T|g`+U!x7l2@f!Zj}q_I-Tn=q_h! zxFGUXOcviy3KO!ooU*ZNd+xQR;W{nfKn@S2Mgc{N!3+S!dr}>3>5ApKWv~2q)wSy? z(zC6hpP5z2R1wqA`rC8UuOA+beXiFG{rqESwlmaIoRW zN4xB2Gj^ggW`#5T{d*4{|Md8o7Y6sd*VUfg2a2R_1%g0C07%t5)w|`$*`fTBoU}wv z*2=`OCV6B3)-#E?_26xZBM@zzAp(HSXk%MrxGNeWvvkd!zjAf$f`~YVVipLA2t07*qoM6N<$f_4y`_5c6? diff --git a/src/qt/res/movies/spinner-023.png b/src/qt/res/movies/spinner-023.png index f1c32284858cff8176698031db664e679b3a8c92..7bed5bae85a5e2d92e6c3361f3edecb7623b197a 100644 GIT binary patch literal 2710 zcmZ{mc|6mPAICp5*W}!it1wOGoGa!&XJh8tw~$0esIOzmnWIHR!`Ia|M>a>Okeuag zA|=cb5fw%$BK1WoeSIIlzrKI`{&>Bg@7MeBe*OPScfs3>fMvk|0El2Qwr=~3{8xgY z{kfO-=H5O)=dGNq0H7gT_@^J=zE||exH$np92@|WuK~dK-}_tvfXhe#_~;7&#&iHU z9F}{w5551(d(P3`769&KD(mh$p>T}nB>=#V{VSeoyNsRvTQSzwiV!oiRvaHrczNWh z#rEgW6Vt>-p_G&qfS2siqZn3W!^nYQWCAOgwW8k?8jQ;q^SdhgCPhnvYmC&4+-JN# zQ8in})G~XK9_otuJcG(EsrX?!hVpSeT8OOb*o2AR+G5SM`~6 zj-6i7P8kle&3yN8L%bX;q8-~buaqs#qcw^)5qcD!W1F}7$$T=xc|9riqAwULDh98< z0ZIfvEQ!D^;T;exiYasf%5f4?GDg{G4izt%&ZQg+wGlh}sTbt3qkFu%vJah0mF*+6 zYzTa;u~)u&vjKz};hBs$j3Tzk-w4JBpRrkSQCwbFQu29kE!8$5S((0O`rKnef4i{A zKCPzVLrIb7Y*V}P{4zq_SNzTBgP|9W~4-j;JoI!nEB()nOPMW04+!5}md zqg?x_zM@)wk?$wsxT9bDyH{wHa#5*eOxJLzqj){7)70{fh@j6Karvp9Cy&|1eP1WM zs5PuF3Q;b29}7;mVAdnczIVQLeil}8NDEDh2c{<$!%S%>08bf_%_t8m&d$Fb|(c-*5kP)VONz2K!){gPz6Ac=aCodRg z5B6@@bn9I4Q}q-*{70t~NZIZz^D{f1Mf`Ag>;sj-XZjin79&QH0PV>iQ#Cs5&TIV!lhSW?LXqh;U&^TM%&@ptp|zrZ2~nAY zM6TZJ*@psUx~B+YK}YYVe2#|5Jq!xZHCJKqi$GeXny7Z<8AXe-{*7a=Q5PijuqD(3 z)dG7SO&mc$#&P#k1KpWmv*|_QILlvbfRK&A zB@bRH5EGIKRah#dzAV_LqV;@SejHVxgHpv}i_`BhCAIsgmXB-w-8l|-U-)e@%LN5P zoIN+g-=fC@N$`z-knD!bw!yP)f5M-Xo-&+o4V~Q z{N#j22PSI){n(zzXA@EJmmgGuNrsUS0U)*1$UzxBPnXPKvcC!HLZ^vH=Sh967-x=B z&z!ebPN!Vyi1`9h#Juw2G>~V+hgyY zkM4TfOkWiFNu~Nr`fa@mK4=DAJi@-f7|CAwkRZLO z^AbAOgiZAP#!ikIy*g5kB6y(Z0M4PkxOaY@W4=^b8T`1!p71yc?wApc@{*Guuhw5PwZO6FTYRL1G_)ea z9fp^mpLOkCS@+0FU%Fjf1sb-_wIJbJggrS|#)r=}vT(Y|t``r*J&f2>QYg+V>H1Fi zEX-dz7PBKco>F?H$923>R#7|Y1j8jFS>}4z5*YGb)u~jjcDvhbH79umh9+$6X7=+O zH3(|1s&cw$HXv`tB;9h&B0L{Ew6!T(NhKP^=DS@NNR^Kw<<4Eljk>i|ok`mEN?K&c z3}d`UkNt=d*VgKBlfxq-j$#kY2L$q$;iaa2WM6F znf7-^r5uFbX)Ej9xM#pH;rbaRRl<7(i|$c=LL(VWY*=U&uK1id*Sk$gO?82}6 zH@FHi;HLuQvMVQimJ&mz2alywD4CJr1rYr)3`8O$y$s1K=J-WN%*p#C;y<@WXSs}xW*x5Afqed`9W>pA3CW1G}jnLg!dZbSzc zuxW*FW#37@2sBeVck|rjMt=CI(mODSuwrq_T=@ z4bSH7cgG6(@qQEUccu%vW-+(cqA1?qaYThF4o3X^;cU4X3AN-RZ^CSw^gV^lkA`j3 z*&X`hgB=qb-`%0Kk+#`id&d7MLdy1m-zlmsdb&Qe7HyLYZ{}cE#j2Ijk`~L&=Q-3V(2LP-c-nP!# Gm;4Xy-pgtL literal 854 zcmV-c1F8IpP)9(U6g~HT@6CHN(i06;NFFvt{1QHYB-7dZ;+EArpXiFaFM@pMNz)iXZ0O(wryE7@=3 zT7HK7@LuB||NUcqru~ia{v`Mk-a6N}DjC_L4GbF*6NyAuZrib|S4TUjAyl-KB}*_` z8|?=s0DxaE&VP0NpL((DeR;au=>rHX0(5tGZ^(3|nrA)RT)dg`0u$w2$tnOk0Dwr? zO(t66Px#sn`xJ!;sI`$3fWQKPM4}}rx*{$w@ZQ68Aa~0h6Y)G|kTH<0&-QHJ_xhUm zPYexBkTM{{D0xx>P$S6Y^0)l*Ect$b!rc7CrHT9@0I)1&8H4IW53g%)ZA;^&N55Zf zOIa_J8*%1Jbr=8`07fs5ow<5-vKVs$v%WLB830_HoF#ch>YH5WzP0jqB~@vv%d4|j ztQ+V4EFWS5STU)&*~0Y$U;fyy82tA0`jscwwY=#CR0)ErPXNlEU$NtzqGIjHmtw)D zHQ9JiCiJQifVC0BMEuR+;r*W;%?_oSV4vPw{Op4r@uRC+SM&;)E|32H8?0t-Nk8u7 zO`BaZVY};oHv`ZeDH9PyL|HFvTKVqoKJT^1()z)fQXReJutngtX(Mpaj4cVL1 zw`Xz-Q^itw95BnhP$K~Vx2`T`r|LpF><87kLa91sjHxU$AOOL=)+EKmVnmz&4U|#} g5V|8VfdPPj0ibPQ(=}MDzW@LL07*qoM6N<$f?mpqQUCw| diff --git a/src/qt/res/movies/spinner-024.png b/src/qt/res/movies/spinner-024.png index d8cf21f1783f308ea754714ef01087c9ba6ca904..b3be8d3e8e71e176ea13cafde759474f81da707b 100644 GIT binary patch literal 2732 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 literal 865 zcmV-n1D^beP)We-# z)J6-|Agp58h9+KWV$>>4qy=T$ZMhUe3l_oMDtln}{AYaF#Sl!Kx0%d*Gnttm@IPiT zEC6I>%_bt=m_q=-M67^RKTxqRTwB&Qa_!b=eEQx`;yUvi3z*3gQM2aTxgZ-+wC%1s zbn=y|H)h7uaF%_EQy1=?Ie*2|_wtL+9=#DC9gYru_eCb1y3Gs{fvy{sYyfDk-}X}M zY)fY1gV3t<-lsa~)0(aRj<)vwhbKp(I@J4GvbDM5IKW^g20&nDCIUjC^2VPp_RP-o zK5P~~EHtJMGTm9^1pNLQ04OUh-Sd6-3(18@qaJJxzLRTgftd*)Z+~C+FV56}PJSE~ z>4BIi+|Jj_egv5Eyp|ULYPWAWGWSWfS?CIwlKXwT2mp(S*4H=ed%UfoX)ZP>v01E4 z{ux+dZ-LeMwK+`?H3IV3?72RECvqv4n%-2t%pH3?M|5q8&EdL7G#OWCX@XCDG=HqX zveE~d15XTJpF77yoN>)+_F5M1CNgu%X4|fV4bmWmZ3C1QxOsE@*5C6k1w0NhvxgKm5nzN&L7^{r z_Pw{e7H^#AZ-xTHJ45p&r!I|+-(GI1P8ILn88~bNu5DW$Rnxi|F;3`B=g zGZ*EzGfnPaU3PjUvRR*bwDetoU@;f~DEkyl&pj4=KiTisvCg1V87kbHmtVLkwY;oL z@u*xm-Q>9aU-vL{n9j6|Lba?}7HZ#O~1v8SA`|c#BCO rx{il`X(O_13-+2a^Lm2+Lo@yXieg{|)w05a00000NkvXXu0mjfOIMk9 diff --git a/src/qt/res/movies/spinner-026.png b/src/qt/res/movies/spinner-026.png index 5ee3d2fa8ef37adb6ef8acc2d39ada07fb8e71f5..dd92fc4fc17984dbdd453e20c1362d514801eae3 100644 GIT binary patch literal 2643 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 literal 864 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 O00000M*UNq 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 TFWgoR3IM#NJ*Lsz_xgVUOArx| literal 866 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 literal 871 zcmV-t1DO1YP)eQ`jQD-87g@GW5R!s~_5E2p+ynqCqEHNR*#0$Mx zBwiWK)DaWB(!?bLO_YEr%*iM$F8)nsXSts~?R_C0kFO(PHf~sR-`)@2+V!K$T-uf|rihg=4OZA*-v_#)SAoe4*m74dOr`025U^oN`gmr6SV02m`u z3T*$*M?ZaSS8OYHj-&Wf8Pai3u`J!~{yDr*E!+CqW!@d*J!2F22!I9valMmVm5995 zzooQwF?|%nDRFLms(Pj^=NnpC@Jo8>wp(*($z%-x~00^zM0txd#lKLVI zGuU&)|Nh{}%sxQMZI6WpTH7m|QB?5iDqtAMTtyC0oN60r0sx=CAwEB-CP)8pUtIrs zF>dgxr8E=04+eH`dc>8il(hBdJkk@>)zO)&Vk((@YRBQBp?<2<9t`*s_Gdx;{Mwc` z7$b5S+`~B+HKPA}xur|Poj;s9y5RA6+HTynShDgLvi?eH+CHh2)>T_pq?Ar=O9jEf zT?Y3EPR5GplJ4c^Y*V1o7Xbjl2xQy#rT31T!qTla}+;eYNVp${-bqmK#oxhNp zPS1YNp`|0Wz5d}lwijl;f$caq1V@Z9;)Xl)@+*Ds&gCxsV-<3`lsToX$wPYYi>r^+ zfn9fncTOEn$ZrQ?1ui@xx-KM5L?mr1-@E#up0Fp|@XL3f+tvJ-_Q}6kc8>n;Xm5LR zO()-S@ENry7W$P99%~wwj+GZ2oa*|QQmMY(kAJd1>EB+-pLL?XoN?J&A|>~UCUFhT zz6HQr#fkBj>=SP;uClA;Sq)H)Vyy{)9#2h-NA=h2?$(T}qMIn%yeRH$`5n!HE3j;a zp|4s_Kl^rhqh*z|8i3YNRQn<@t)aZ8*?#^Vb8_UII(cY>270<^T{y_YR|=RvJLR1I xEnWB$aC9Ai+m~!?@ZS$`^L8~(wP82s{sj)SQNkeKR!aZ?002ovPDHLkV1h)ksjdJ3 diff --git a/src/qt/res/movies/spinner-032.png b/src/qt/res/movies/spinner-032.png index d72c9bf0dd33440e89a7b54d3aee8348d4f2c76a..7460f80da35c99c219143d16d0d9f92d2716c587 100644 GIT binary patch literal 2839 zcmZ`*c{J1w7ygMJWh{(U#Z*|an=(3$P8UX0IDzJm>SmfFBF#urm?jLY9SdzB^fKSc_jl#u$TrIm2 zDmpGUaO1vX&-0h&0*iYgM+MW}NC}1T5NC~CQc3uYVK|fXE>I)Q6 zhqi<3#T48c`mBvR7$cV4ZiDrtET@M&4V4)IaCld{9sGM%@!#?np&vpDg@lpEW(MA# zuV7=}EwScMYqdFw-^(}}9iDT_tLg1_6GwFeVh)>D&kLv&eDvy-`UM@w3)kJg9=ebz zp!WNm({%FGWdpbTDS zL#1+B()(5;2Tm9Dm8cqj3)dKKcGkUa5sYv)wAE7E94J^c)o(S(3rgn`FKxK^+;bA| zbSI4F_(Xka;-?kZE)*?R;&6?v&jL_(*yO*Xfx<4&A2o3M54Q` zr%!NrmRSh%=VuF)^p@mvY@g9+Kg)Az`s512UtGWDOORoMx*sINW7{;28pe_(Q~P<^ z&>UGVlsDK)0;|FVn^;x5KQ`Fd(M$;LXv(@Lv-A;yXs)xiXNbuGgBf9K8vv73$$=?nC(r2_H0GKVV9pRmkz7w0=~=EnA$8~maYw1 zv@2?0X-9>0v+6(hkfZnyhPVo&=>9neT2R@pC_O{7#lu{9f^Qb!V}Iw7T^P5o6bogX z+gD_2X*|eZa&n$uyYxDDI(g*U-PRyKw0d1d6egYuu^Yxy-E3?dsgH#~sp( zDC-&A5P!!LBn*!)jOujJQbo`#3;Es=c>>KjcUR`4tgsGQSFfQ}eC$YToQ;~zth6K? zZCewKAZDv1LP%ENOe1rJuHm5jFOpx*(+#8dB;TguTwSM}%Wa)A#-|}V2EtsW!Sffy zg9wyW0>hK-t%>$3LX}I%J4Z@}lYM^ytoRrxuO1>ULCS}D|#o0J*Ts>WFdG?vOU+NN2tVeAt3s6vq zHf+IE_ei!Fg@2f2aLoIb5dLxM9f=Oem(s{UH@$6=dilDkDWqKn$i8^)Q(#PsTI zH&f#Mi%@(}xz6)voeA2MOka6_HJ6OU+%hc5u2Ce+-br8_TCOCu$h=IlO_EbKz)%Z} zF4tA2R=U21r;IYP$~}T_>#V9xglIfkSLCOjGI_7~*OF7PcTq$3Y5rT$OK;DJ3+o8= zA>6veaUE^YtxYk$U7V5)wbsBu`*>lN&td1Y8 z=g0D!Kx4ta)^Us4@?y<{6H!@Cx~gsXWdPjtV(5e{n?_eNnE&HJ>sX~<;>)TKuc4B- z=-g|6ezR|5aqU-4-G~X_QQuc%zK&NNJcT%NB!j>xH*3x!?G5-E477JB$3oNk=3bJ7 zGO2e^ujTjE*MySBBJYlz>%jYTX|My~(oRpGr8A~oPswEHa}z&ZXSGkj?hXNQ?Rk~Y zS7juN>Kae_XQS?XYcrF$dsPQQ?M5O4xAT^NkPHRprqzSis+0|&Y**8j?tQ|Rl;-Xq zram~H+o&;evA zTFs?P6Rm6t|2jCd6y9%>VvTt($-K|_7EQoONCcCpZ*b>kRBS;dN279M;4u|mc((FA zgKR_{=Bb0smRiR*iGr}nGM4=lC95N#n+ayk#gt(U*m_2A`cqkQL1#h^ow2r7nWDKn zGPoWJ8asABZG-1_gL~hb!E}2GHEryt-~K7HjObQQ`SWu|*iZ39i4WEB9j9h zLU@x_*eA=0vr+f1&q!>UtI9FKKdBpV3%p8@ceDsMu|9>5xF00(+Ef&qQUKdMsQZZK z4>;}4&~nUzI#0q^nkZqv^ox|Al1*Y3ZzB>yk!kfRtbS?JB@787d<`?uJqp8&`JF78}{!&^VbRK zM{(tCQ#&UPzDG5@r90lw2k(#cjrKnv00x1=b)Zlk2m%L#BH{YTgG~j2A|a3|^6JI^ d5rjqf1qUSjf5E+R*ZBhhU}NckZn3yT_!qvGBdh=b literal 861 zcmV-j1ETziP)$+mhkd=JJD&HU7PNaewrye3oxIsEN_`@_cRSZ%qhgFdDx}53*KuQ}`OrNdF3rB1G z`n8c=mL=G-q$Q;gMUxD`34y(pV7C&G?sNN}f6un6*0*@bV zDL=H{`cb@cw(vP%6fsF@Oi^Gic_rtLA4k2NaO?^niF8cuz9YY(c~iI-D(lx(Wjv~w z!in!DsuLv zW3x|b diff --git a/src/qt/res/movies/spinner-033.png b/src/qt/res/movies/spinner-033.png index a8b822bfaf24df1c8359008d91ef0a9e4bc27507..d327e8fb0814506f48e7789d89952659b303d39a 100644 GIT binary patch literal 2829 zcmZ{mX*kr48pi)(Xvq57cg@(h8O<;zDU6+rol3@xeV3VJi9!t7_p%f*_E0HX2{D%J zBP9FwN@;|bP>yq*>wGvL&WHQ{UH5f8zwb{1_NpN}t1v470PMy_7^_nf|DCf;r~M~$ zuI3a>9y;ba0ML-icI*N=-I4?&D{}w{lLml$F#z!E zF+$hn99Iz-y2vfk2?5^+q@Yr%vwvKSUbeQkhHq`XokqQ!Ke8XXw0|5qf2loq=*My7 zI@1yvl7jkgDIqc%(o-1O*_A(itx)jeRbjqxUo#804hzRZ^%QpHknbTGlww)m|;YDYxT9js1L> zE}om%>LJ`gK$v89Jh zp^K~PORn-u7c4=`Q5beo!`3XleusIoE6M6N)l`TYI=B!BHzz^pmih{M=d;Qd7a4}? z?Y~(HBu~|B`VcV1S&GD`vS9B1*6#QfmTZbz47FD>8`@95rvFJ$ln9M!ELgb4v=;t& zi(w}^c^!q3*N&iB^-@3Lf#(k6Z5Hb3MP_*Jncng-V6+{C4W!E*Rqj_?cY(BV3SKCJ z`K~r1V`F%{t(zf{&r_Z5{@#XG)V@i3J1BpXVmc$mmez?HQs7c1;O{MRtVNIyvwb~; z)99rka!SnmKZd~5kj_eI`@9awjVhU<=H*@)k!(zprFIuMhb)&GFKYhWh4qnZ#f> z{_iCj*Cnr-=H>-}%teNSt)VUHA1HrbY@0Up^vhAl*?2dSjuE6i+eMt3*n^*H+9k}+ z);@$-VdM%%X!!`TWa7=rSBy1L_;=mr`(rv1OR$ygMW`;-QVxPYt`*@>EYXy5aiyIL+i3pBr7=CQ zEmpKIr92dqNm82~06jD!zzw&91SB4rmA&=4wu^uGR1Z|S1{%EK`xhn)ZYx>kQm*<} z-hf~WW>t=6qa*~+hH{nww)V*U znKY)o1X1y^8$x@eN26l5H53ETMiXHpv0oIDO7b-^g{9;n=bP0Y@L{ZC)*Lp$pmNXC zxkJ8gtu3)Hk5#rjc5F_8gTiW=--NNTn)qsb5C*r3LVhUqBzwl78t*jo#FSbTV?X6r z(H~cEH9ow%zSvQ*4>c%G2+vjvi=D(gs1Pu(u6q0*u<>; z(>B5%IX)=hft0W|lbOC>d5%y&6|jIOFC?m4xto}=0?DAxtMxgWiG5B;rP6!4{?@(j zacr(fw@i{?THYlbX55_Ge(KU`;F09LNXK10GtLSZLd%{0Z+Xt|k={v^D@nr1WSHq1 z=S2&Un{Ej62eC^vyvT!>%^P|mjwN}+=3Z~BxiS^p+#e z)qpYMu`r^><&a@&=2CY_G(VWznyj8Cs{+5h_UHE=kR(P$uO>O-6lEaL6kt z4&^$?Q3bi){Q-jpe`lyEiQV=f+SMjt!Woase`^oChdb@A60u2n}b7Sca1DpJ-j6hy7cY3E-6K=YzO79(EPlug@hNM2P@P<^1&ZV z9}d}2*e{N5%;manN*C zW=9BfYs&A-&QibVVW_=XsAKH8QPZD4rnO$vtq&Jyh3beLA*f@=`ND%3eIs`zH`aaO zh?N(*A@SpdZyD3+3;x#?JNk@fSGDNPCbBMJ zVfy>9P`dSy0&~w=Bnl7uy-#r&9j z{BqQ5MI9u%i2hBA$WfS+9kBFI{iEkrAzxs_=1Rm3As(IT%MJH9ZlzHOg*`Rjw0Nqwo?do5S&~#9B zq=<;P0ldijb3@FsjuuL`Yj@HjOLS-7H;Joe|Dpu*N;pc<6USV z)sd%)A>w^djIZT)PYWr1zZg$B#EZ;XSIZcYaLfswa^Z;d^R-`MMQ-bj^G|BO;Z!v} zQGvo}%*K)u3sISp+^NUI*oza2Z>nnJJ89(BC}FQL8mwRJ&D>0$jb^L;t@} TH)*?kDgeg%S253Zanb(*#Nrsf literal 849 zcmV-X1FrmuP)*vu-EFffV7rT{n1-|xFor_#7Qw`Tk;K?)VvP}PG>wYB)!?OG z9!!ie#K1}_s1Fb?Da8j&03Q?~R!CEbw@RfD777d9?QYLG-}tcEnpWrSo6P+4&CLG? zEC^;&3v<;xgNT@jn3?BlXnqmM7)T%(O|`dWR%bJrwu(o^pGQs|J3TgfQYy^nse!xs@jF^Wz z(*wJnv$u&5M$ZS0OHoQUCddyiG3n-Z{_%(JuS#jsjyEm~t?Aymv{WjNYa%FP#BWN* z*X-I_*d{K_3xjnZ95|NW?Hi#xT9c2x+x7eN*YclvSvYYo8prAJ>(jmw0{~hv$ny!^ zo$85T*vIOZoSx%jleyY#x73H8X-!@tDH~Im4OLjXsyyu%DrGlM1ZWX>0AcNNd;QBf zCwF}8Le8<-aXs-2wB3}jk{3%cN=3@{qR0#oadGln`zOGiQ4Cc(QRwN1TJ|s8tYTt- z5s$@ItnWzn_H9mn{LWLUFH`lAyNE~;5rc?`ne3+Y;&okJ-F**i*x1wDl3fX~Qx*A- zBe3<^-j6KHiU0t#)(QaLerx-uA|g`G%hb73a&-8UUmx9ccRvx^idj1W9Rh$yHf?z2 z@WC(6)y$=R-}eEsn-hgQCyw-cS1#v`g`!#(m6qj;t#t(RIuX2b#dr-jq}t!;UHjVS zL;HsSfC);A2(;xiBnsao0^?KMXk23WID7skFZWepuaST@Mq;;T6Zda_^49n4sYCYQ zzF!6bz=#k5fD;TgU)ssPg@a`jOAeG};c_wTd7|~nzx+SLx?-&xr0mD#d`J}mnct+K6+>~&9H^o4?^7`d b3kd!Pu1_(a7dOi400000NkvXXu0mjf5*(M@ diff --git a/src/qt/res/movies/spinner-034.png b/src/qt/res/movies/spinner-034.png index 684aa385e01d954a347c1dbbf85bb58ee694920c..d8432751daef0c6ca1d9779d4efc29b449547604 100644 GIT binary patch literal 2851 zcmV+;3*7XHP)004R=004l4008;_004mL004C`008P>0026e000+nl3&F}00002 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 BG?oAW literal 859 zcmV-h1El5sdWu6p3W!}*>A&+|Q> z157*2q^9To(fD5)-B&h=}O> zngO6@&a77sZ=HAjMoXJuRnBwEiBC$5;L53z)%LLocni*B{@S`PgG9 zoa_pvZVh>dD@zJX?PxjjD;qHGsgzYOzWLI~P=8;>k+JJHdd?6541!ihp!o7`??v`F z^!nbww)T$U1LGMtRT{}#vbnKrSN%d?g+CbK+XHC|+fjVop?_Te{=r3tQpAoc`nkt^ zueuyCmu?)b@43@=l5*dI>lg#J|JFo>Cn^HyZNFU9aKtu#kw5YW1;hM$u zKCgGyltGF~0gQOn%$N6XivBdX-x6u_$e}I8T_AG?69~*qAo3hJeCP)ek>7sp?BBk9 z+rCJ&WZonflcP4NB$~hcg(nN%iG;1k2>?w_4wdDxhVJj0|9J052VvW zgNlR*a59d#fjq0M?eiVq9{i%cMMShx$}j+hrym+wW=951+hmO0HJmiZ%+tU8dG&1P z?Gu2~&}7Umow@SEjZZb%bfxH%=9b+6;JU6RfKV5=UMmcdE#wb2zu{~WXAB@eI&S8r z&iyfQ-U^t7i|1JLBVh}TJNiFpOe82IoR;1@!{0LjTK;ce l0Vu{jE6bDdx5m@!{{lH?K$RVPShD~C002ovPDHLkV1jp_$lvO^qaQ^w(rBjZjsch1Vrot>0*!%WGRBP%1>qf~YXS-EV= z7DD>vTR-1Fe}DY`c)g$R*W>Yi{{JRgT9`0{_(1>wFvDR`>vQ7%4L!~I{FAv*eGVEg zeRF*Ps83@&L(`sjQFoZNIRHdT0zhmW0Q~xU&P@QoD*?ck8vtl!0{~CpBiCNz^V^FU zGZQEPRHcY3pErgen0*KUz(4()3l&DBQvd)7z@hrcaO!TpZxCvVtN;G`n@4$U^b#-t ztYaYhOq7)&hbH@)Eou5f(?h-T$F@Fl7LLF5stt!49UR^6XeU>wAo(IR8k2EVu_Qh6 z*IB@nKEC|HKARMSgxL4F3D&0u0ee(wY4!E|yrKQY#gloj@5eX2zBkP{MC~%R1Pg!} zMzUO1gE*eC=u(e%By$He=q6G?YC#uk#K)T+t#OjZ#>Xp{0mVmt6V=3Pki&p6rYzrT zFUX!Zqo*pnosfZw9Vk2Q@AQ9a`SN)PTaOR5>{}@ch4^d(A`DrcQJ_Oqk6fIhPG!Ce zZzp%PZWvy#uw!*I{xgA!niMFKl_~n4jk(gEl9c1OjNte zKA?)!b{-TX+c*VFk3(T?t-OrPzbFK6fw&9g!Qoah=0n$d*H+xaXuMMB|U9 zDC(jSqqju*h~1t$Z&=RW&5TW&&lnM_7x1zJP7&)nTXKn6WF0R5gOQ2Oyxx35Y^lYi zI(8oai=Io;NnBDhCCD3Pf%2{2UfcIr@n0>AAPovFDuiWx6lr4z!war)%RIIf^hun4 zQZld>xGP#&@*_+u;dpB~ctNZv<&3!5V-n@?J0f0@3U7$Lf`(}Q-~d&&6{oqD--nbp z7m3KZLr2Wsx*cbMrIX9@_?(!0rUvK^_f3+@@@DhZ^j{HBYc_SKcunW`1Sv8Zt!_g( zKz4()Qh98~uiYsK(jeAoTH9EBWT@%O)ScH^qJSg*9ZMlDiYg3x1Z3nxpdL z?LwtHO}V#WIBW3pg9jG|hdSSFY_IhE@XhV9J(lNE=So4wsR}L8wrd)xB(yNm$hrw{ zs@qO?n=;CEV;@9^V!9&pF;3MDdy~O_t#?6kGCNv_4b|B^tU>Gp$0gbI_Fbc$67eA z+#g~#P&YG*k}0wREvvRGr~Na759E5m`#JUC^$r^`z^$TdWiiMWWw z#^WE{A_uBl6<&(vU+{OP-}3(_UD&p0P>-dhWRW{4xGUQ(BzL*2uo)w;G3wgu98qi! z`sTpwhhCr!PQJ)->vBa?tT%W&o+{y6vjA--%3-rg1_R+VG<>O!m8sTk@=U?09YQRI z!km7Kk$pK4lXH_oA61J_#IG;y5WiV$z2EA@I+`3=uy=3q%M=e=<-U9>XW(Ckf;!X0 zzcius68ckU3G=aYj?)~SWU>;08~97JXdyU0f(fZjrWR_N~$SDXOEDZnzDSrvD3GFmFJ8wg*)uvsN^$W*H!h zLEiT2m?8?e6x!xLA7Q_G`fUl#Z#1$J=@kxN4vNUWnm@9+G2C=xDU!#lw>VTqjUsqO z(S3H2QfH^t*- zV62!bLszq`8ks8`{>=I`%&@GMjI@=-%u+G9)bKp6YuK{#l1U`)O)*z}t{A@Rsq9+0p z>&*`Q^atu+Iad1O?}ShPAv{SNj1JH{MvymoNLY{SXxWB5^RqYA$kOu5U7g}+K@l6~ z?`>;x<#psXBxw{v!dfCydYf}s@zCGNy9b~L5#&O^)nuE#k5WhF2~0Ss19Qbj6*wIFI*V0Aeq lu$Ge20%_Ove+2(PtdD2J{}<|JP^;$x05`IL)*84y{4duTIKBV? literal 0 HcmV?d00001 diff --git a/src/qt/res/spinner.png b/src/qt/res/spinner.png new file mode 100644 index 0000000000000000000000000000000000000000..b296a584817bf764bdd86f0acb6b5c7974b912b4 GIT binary patch literal 16636 zcmeI4dpuP68^;ghQiPCcMVUru3v)4pnV2wxEXszZ?PeNdjF_2bhK4STmc(|^?v~gx z(iRi_*rcK|?RFy}+BS0Avg@))mtB{(^*e(&Nqc_3-|P41IWJ=#-|y#np6_`-&-Xj? z&#}*MwWp5O0xbXlbi7tE)`IV10Q#rq2A z>~QX?I3e3VZgl`FZYzrtid{+5a*|NN08wl)6C;U=#9tM3HJ5F(D_0(hHOi=Vd04cj044%KqgTL1ZxZtPq4!g@HisHhCrZ_9H<0)%*2JI zX@QoLFf@$1mfmt47&*4IP!^6I$&O<4#3Im-Fr%L!oG<2!!ucOaIXV5o#9&Q)eJ69zxZbF! z8B>eI?lB;O38XW6iUMK64-_|cya)dK(zyZ@XPT8Djp9BGOnB!!0j{K(&xKp)6_`Ul_#{)3{Mg4jU)nahz~dgAnCpOHt|kNWKtU7Mo`0gqvv?;x*Q0 zR4<-L%;d4yUJM#IV9Vu(QpseJBgvjkwh3e5@iru~L#WLbq9fUcNwFi~w~$HpL_B2- zqOUL1{k_l(J}X+eRVG4*{+FR4?(cCfGHHQmD|l3`*y!go?w#)l+tHx+ftb<_ z=+v?%Jty3_|7!uq<3rp(oMU@9oA*x}YCP1K>cc@q{4nu$rjYH*0eb>=qmPGt*JpZc zC!F%!kL12vh4ImMi}SW!-!G<<@;IY{jQ}o+IaUCI6YjmSsm$a0U}ZrgqsR0lN4)X^ zKls3F!WTL}-FF>~FLZvo@04pGk1M7TC(=zDhIlDY-SJbwAN+#ArrDFpc4Q~q^x^3q zeq0GVGMK>yx35UqlmvqPgwyny89mp1&=WE<;W=I|$cOn@HOEK6uL|I|6x`(3ly?g~ zxfA}+#?&qSp94d~AxWS#U~L2!EF!1?!3CuOYa_T|5kUnAE+`FH8^HyO2r58uL21C+ z2rgJePyvDqN(0tLaKR#i3J_dS8n8Bk3l>C3)-1-L(ojr07r+CQkTi$xexpAYc zcxj&NQ-e283?4j;xNsNizqgMt#ds*jD%M$bPAYn7QTgzmmp|+@`l#jL0U~peT0x&xtyRo} zL^Zv6bKCR3HM**CsoBjlf0rfxG4WY9LG>zy<30%79?@v%+R!b_wOb%lG*Xto&Q{Dy z`^zc-5N-B!Hj&yTYHG~^XjPxyuSL!umUK9IV*q4cD* zM*iC|#Z$^FTa`a&87wVYK9IzcRshM=u1gn}ol(J?1|O%7_T5u!sv5ngAo@MOF}y1wh>zkS+De|TPdb;;fnHS(5N#UGS{SH-f-4eh$ORa>+C zYfl`x7w5n0ykgIRUt6?H&D8utineJyLid+n+YpN$sp-A#;B=<(K#W~xe5-zsNe*!Q zNpR6t?K;YW;F68k&L(gz%IpULTD0}+Q*#qyDD%4RVi!IN>lpTK=O_}iK090!tu`XL z-{#k4zgk3M8si_l_$FUIvdX8tpAotk-%1=_Ci4w+cwP28zW`NTo8W2Q>^1CpzM5mc z19b+SeR2Ef*}q{)q9Mx8xKFNzN*`efBPXq(&_jkx_HCJD{@ z#pt#wPvvyLtn-7%GR#Md6?(etje4eY7u2x?2QOXLbu4zv&}#04U{uP8;Ih&xRrSLrs*b)z0Z{X(UHs&kZDxb_LOGz{7 zU)&sYp#RgKjC{{NH}E*ZQOVj+SfYBjSLc_QQ*3-yxu|1QCr9H%(>c|1Ri6%B^-j)L z*r11>X*hjlH`;b{9&Wn^Z*k!IPm+g8bxmvj?xT!Uw{})OQpKeGnEfWA5}#e15L;qg z^lN3je$kFE7gudRKlI~8!0MY>qL|J2%Ea~estLMXyN)pRE$utJ)tV~%$&Zh%=q)o~ z)~LjE=el<6t&x+Z*Rv6SQRNu692O(QY!)S zS`?0f8{NLBH+bTCw&#q(xMM{XO;zH{(Dib8lQ^;&b-~JYKhS0GciSQ_9q{!tSId-n z;H&yruXZeL)E{)Z*2ZfO4eVQu?m76KEl(hOC5RBdNy@za*lrWU(o(kDZQ)VFo=0jV zTkpPAE^m^`mS{dWXjmta@vx$1E1A@#kN*kr>K&KV+2Jp9PFyk6ZdPm7YEC!RW>PVh qnfD|2cH3>%Y9VgbA%zWZ18no0-M{2q?^FJN0x$Q~jB{=wiT?)O0-yW< literal 0 HcmV?d00001 diff --git a/src/qt/res/src/clock1.svg b/src/qt/res/src/clock1.svg deleted file mode 100644 index 793dc7f91cc..00000000000 --- a/src/qt/res/src/clock1.svg +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/qt/res/src/clock2.svg b/src/qt/res/src/clock2.svg deleted file mode 100644 index 6a78adf7004..00000000000 --- a/src/qt/res/src/clock2.svg +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/qt/res/src/clock3.svg b/src/qt/res/src/clock3.svg deleted file mode 100644 index 09ccc2549f2..00000000000 --- a/src/qt/res/src/clock3.svg +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/qt/res/src/clock4.svg b/src/qt/res/src/clock4.svg deleted file mode 100644 index 7d9dc37acb9..00000000000 --- a/src/qt/res/src/clock4.svg +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/qt/res/src/clock5.svg b/src/qt/res/src/clock5.svg deleted file mode 100644 index 9fd58d9d973..00000000000 --- a/src/qt/res/src/clock5.svg +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/qt/res/src/clock_0.svg b/src/qt/res/src/clock_0.svg new file mode 100644 index 00000000000..2a4ae023557 --- /dev/null +++ b/src/qt/res/src/clock_0.svg @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/src/qt/res/src/clock_1.svg b/src/qt/res/src/clock_1.svg new file mode 100644 index 00000000000..4e49772d26a --- /dev/null +++ b/src/qt/res/src/clock_1.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/src/qt/res/src/clock_2.svg b/src/qt/res/src/clock_2.svg new file mode 100644 index 00000000000..995446e46e3 --- /dev/null +++ b/src/qt/res/src/clock_2.svg @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/src/qt/res/src/clock_3.svg b/src/qt/res/src/clock_3.svg new file mode 100644 index 00000000000..ea47a847300 --- /dev/null +++ b/src/qt/res/src/clock_3.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/src/qt/res/src/clock_4.svg b/src/qt/res/src/clock_4.svg new file mode 100644 index 00000000000..43160288d8a --- /dev/null +++ b/src/qt/res/src/clock_4.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock_green.svg b/src/qt/res/src/clock_green.svg deleted file mode 100644 index e31f0e7995a..00000000000 --- a/src/qt/res/src/clock_green.svg +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/qt/res/src/connect-0.svg b/src/qt/res/src/connect-0.svg new file mode 100644 index 00000000000..bedbec77776 --- /dev/null +++ b/src/qt/res/src/connect-0.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/qt/res/src/connect-1.svg b/src/qt/res/src/connect-1.svg new file mode 100644 index 00000000000..d3d4e46a419 --- /dev/null +++ b/src/qt/res/src/connect-1.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/src/qt/res/src/connect-2.svg b/src/qt/res/src/connect-2.svg new file mode 100644 index 00000000000..d5becc52b79 --- /dev/null +++ b/src/qt/res/src/connect-2.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/src/qt/res/src/connect-3.svg b/src/qt/res/src/connect-3.svg new file mode 100644 index 00000000000..9bfa04721f9 --- /dev/null +++ b/src/qt/res/src/connect-3.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/src/qt/res/src/inout.svg b/src/qt/res/src/inout.svg deleted file mode 100644 index bfab8ef6ab3..00000000000 --- a/src/qt/res/src/inout.svg +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff --git a/src/qt/res/src/mine.svg b/src/qt/res/src/mine.svg new file mode 100644 index 00000000000..4a3f786607f --- /dev/null +++ b/src/qt/res/src/mine.svg @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/src/qt/res/src/qt.svg b/src/qt/res/src/qt.svg new file mode 100644 index 00000000000..9ef54f493cd --- /dev/null +++ b/src/qt/res/src/qt.svg @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/src/qt/res/src/questionmark.svg b/src/qt/res/src/questionmark.svg deleted file mode 100644 index c03c159a5f1..00000000000 --- a/src/qt/res/src/questionmark.svg +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - ? - ? - - - ? - - diff --git a/src/qt/res/src/tx_in.svg b/src/qt/res/src/tx_in.svg new file mode 100644 index 00000000000..a8911f90454 --- /dev/null +++ b/src/qt/res/src/tx_in.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/src/qt/res/src/tx_inout.svg b/src/qt/res/src/tx_inout.svg new file mode 100644 index 00000000000..5b66889783c --- /dev/null +++ b/src/qt/res/src/tx_inout.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/src/qt/res/src/verify.svg b/src/qt/res/src/verify.svg new file mode 100644 index 00000000000..1ff11b7f5ed --- /dev/null +++ b/src/qt/res/src/verify.svg @@ -0,0 +1,14 @@ + + + + + + + From 7c041b3b91aa08a8f5863382b865a5174281ad03 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Mon, 10 Nov 2014 02:52:28 -0500 Subject: [PATCH 0006/2337] Check against MANDATORY flags prior to accepting to mempool Previously transactions were only tested again the STANDARD_SCRIPT_VERIFY_FLAGS prior to mempool acceptance, so any bugs in those flags that allowed actually-invalid transactions to pass would result in allowing invalid transactions into the mempool. Fortunately there is a second check in CreateNewBlock() that would prevent those transactions from being mined, resulting in an invalid block, however this could still be exploited as a DoS attack. --- src/main.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 4aa49531b34..8d4a9e59f15 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1039,6 +1039,21 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa { return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString()); } + + // Check again against just the consensus-critical mandatory script + // verification flags, in case of bugs in the standard flags that cause + // transactions to pass as valid when they're actually invalid. For + // instance the STRICTENC flag was incorrectly allowing certain + // CHECKSIG NOT scripts to pass, even though they were invalid. + // + // There is a similar check in CreateNewBlock() to prevent creating + // invalid blocks, however allowing such transactions into the mempool + // can be exploited as a DoS attack. + if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) + { + return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); + } + // Store transaction in memory pool.addUnchecked(hash, entry); } From 4a8fc152a957e54e6dd910de4382678f5c405198 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 10 Nov 2014 16:41:57 +0100 Subject: [PATCH 0007/2337] [Qt] the RPC Console should be a QWidget to make window more independent - fix issue #5254 --- src/qt/bitcoingui.cpp | 7 ++++++- src/qt/forms/rpcconsole.ui | 2 +- src/qt/rpcconsole.cpp | 13 +++++++------ src/qt/rpcconsole.h | 6 +++--- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 77cfdceef0a..cc799609a78 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -128,7 +128,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : setUnifiedTitleAndToolBarOnMac(true); #endif - rpcConsole = new RPCConsole(enableWallet ? this : 0); + rpcConsole = new RPCConsole(0); #ifdef ENABLE_WALLET if(enableWallet) { @@ -234,6 +234,8 @@ BitcoinGUI::~BitcoinGUI() delete appMenuBar; MacDockIconHandler::instance()->setMainWindow(NULL); #endif + + delete rpcConsole; } void BitcoinGUI::createActions(const NetworkStyle *networkStyle) @@ -831,6 +833,9 @@ void BitcoinGUI::closeEvent(QCloseEvent *event) if(!clientModel->getOptionsModel()->getMinimizeToTray() && !clientModel->getOptionsModel()->getMinimizeOnClose()) { + // close rpcConsole in case it was open to make some space for the shutdown window + rpcConsole->close(); + QApplication::quit(); } } diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index c5ac371619c..a8b94354da9 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -1,7 +1,7 @@ RPCConsole - + 0 diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 2d2d448b49f..2defdf8bb47 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -200,7 +200,7 @@ void RPCExecutor::request(const QString &command) } RPCConsole::RPCConsole(QWidget *parent) : - QDialog(parent), + QWidget(parent), ui(new Ui::RPCConsole), clientModel(0), historyPtr(0), @@ -278,7 +278,7 @@ bool RPCConsole::eventFilter(QObject* obj, QEvent *event) } } } - return QDialog::eventFilter(obj, event); + return QWidget::eventFilter(obj, event); } void RPCConsole::setClientModel(ClientModel *model) @@ -366,11 +366,12 @@ void RPCConsole::clear() tr("Type help for an overview of available commands.")), true); } -void RPCConsole::reject() +void RPCConsole::keyPressEvent(QKeyEvent *event) { - // Ignore escape keypress if this is not a seperate window - if(windowType() != Qt::Widget) - QDialog::reject(); + if(windowType() != Qt::Widget && event->key() == Qt::Key_Escape) + { + close(); + } } void RPCConsole::message(int category, const QString &message, bool html) diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 4bb9b62e932..fae254b336b 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -10,7 +10,7 @@ #include "net.h" -#include +#include class ClientModel; @@ -23,7 +23,7 @@ class QItemSelection; QT_END_NAMESPACE /** Local Bitcoin RPC console. */ -class RPCConsole: public QDialog +class RPCConsole: public QWidget { Q_OBJECT @@ -43,6 +43,7 @@ public: protected: virtual bool eventFilter(QObject* obj, QEvent *event); + void keyPressEvent(QKeyEvent *); private slots: void on_lineEdit_returnPressed(); @@ -59,7 +60,6 @@ private slots: public slots: void clear(); - void reject(); void message(int category, const QString &message, bool html = false); /** Set number of connections shown in the UI */ void setNumConnections(int count); From 13f903187c3aed26993b89dd3a135e646cfc7437 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Thu, 13 Nov 2014 15:15:53 +0100 Subject: [PATCH 0008/2337] init: minor parameter interaction updates - use __func__ instead of hard-coded function name for logging - update -discover help message to reflect newly added parameter interaction - use DEFAULT_LISTEN in a parameter interaction check instead a hard coded value --- src/init.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index b290d541588..fd5fcb09df6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -254,7 +254,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -bantime= " + strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400) + "\n"; strUsage += " -bind= " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n"; strUsage += " -connect= " + _("Connect only to the specified node(s)") + "\n"; - strUsage += " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n"; + strUsage += " -discover " + _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)") + "\n"; strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n"; strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n"; strUsage += " -externalip= " + _("Specify your own public address") + "\n"; @@ -550,59 +550,64 @@ bool AppInit2(boost::thread_group& threadGroup) #endif // ********************************************************* Step 2: parameter interactions + // Set this early so that parameter interactions go to console fPrintToConsole = GetBoolArg("-printtoconsole", false); fLogTimestamps = GetBoolArg("-logtimestamps", true); fLogIPs = GetBoolArg("-logips", false); - if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) { - // when specifying an explicit binding address, you want to listen on it - // even when -connect or -proxy is specified + // when specifying an explicit binding address, you want to listen on it + // even when -connect or -proxy is specified + if (mapArgs.count("-bind")) { if (SoftSetBoolArg("-listen", true)) - LogPrintf("AppInit2 : parameter interaction: -bind or -whitebind set -> setting -listen=1\n"); + LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__); + } + if (mapArgs.count("-whitebind")) { + if (SoftSetBoolArg("-listen", true)) + LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__); } if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default if (SoftSetBoolArg("-dnsseed", false)) - LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -dnsseed=0\n"); + LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__); if (SoftSetBoolArg("-listen", false)) - LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -listen=0\n"); + LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__); } if (mapArgs.count("-proxy")) { // to protect privacy, do not listen by default if a default proxy server is specified if (SoftSetBoolArg("-listen", false)) - LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -listen=0\n"); + LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); // to protect privacy, do not discover addresses by default if (SoftSetBoolArg("-discover", false)) - LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -discover=0\n"); + LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__); } - if (!GetBoolArg("-listen", true)) { + if (!GetBoolArg("-listen", DEFAULT_LISTEN)) { // do not map ports or try to retrieve public IP when not listening (pointless) if (SoftSetBoolArg("-upnp", false)) - LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -upnp=0\n"); + LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); if (SoftSetBoolArg("-discover", false)) - LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -discover=0\n"); + LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__); } if (mapArgs.count("-externalip")) { // if an explicit public IP is specified, do not try to find others if (SoftSetBoolArg("-discover", false)) - LogPrintf("AppInit2 : parameter interaction: -externalip set -> setting -discover=0\n"); + LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__); } if (GetBoolArg("-salvagewallet", false)) { // Rewrite just private keys: rescan to find transactions if (SoftSetBoolArg("-rescan", true)) - LogPrintf("AppInit2 : parameter interaction: -salvagewallet=1 -> setting -rescan=1\n"); + LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); } // -zapwallettx implies a rescan if (GetBoolArg("-zapwallettxes", false)) { if (SoftSetBoolArg("-rescan", true)) - LogPrintf("AppInit2 : parameter interaction: -zapwallettxes= -> setting -rescan=1\n"); + LogPrintf("%s: parameter interaction: -zapwallettxes= -> setting -rescan=1\n", __func__); } // Make sure enough file descriptors are available From a9306587a42eac7fb889b9c8d03140980fdf1398 Mon Sep 17 00:00:00 2001 From: Flavien Charlon Date: Fri, 14 Nov 2014 10:20:58 +0000 Subject: [PATCH 0009/2337] Change the default maximum OP_RETURN size to 80 bytes The value can be changed through the '-datacarriersize' option, this is modifying the default value for that option. --- src/script/standard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/standard.h b/src/script/standard.h index f3dcc75fdc8..f4446b0fe43 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -25,7 +25,7 @@ public: CScriptID(const uint160& in) : uint160(in) {} }; -static const unsigned int MAX_OP_RETURN_RELAY = 40; //! bytes +static const unsigned int MAX_OP_RETURN_RELAY = 80; //! bytes extern unsigned nMaxDatacarrierBytes; /** From 44e9a6b22e472971aebf647f4386fb5a4436a0e3 Mon Sep 17 00:00:00 2001 From: Flavien Charlon Date: Sun, 16 Nov 2014 15:43:12 +0000 Subject: [PATCH 0010/2337] Update the 'test_IsStandard' unit test The maximum length for the payload of an OP_RETURN output is now 80 bytes, and unit tests must be modified to account for the change. --- src/test/transaction_tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index d4c9b1a0ea0..dab2249f25f 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -342,12 +342,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) t.vout[0].scriptPubKey = CScript() << OP_1; BOOST_CHECK(!IsStandardTx(t, reason)); - // 40-byte TX_NULL_DATA (standard) - t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); + // 80-byte TX_NULL_DATA (standard) + t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); BOOST_CHECK(IsStandardTx(t, reason)); - // 41-byte TX_NULL_DATA (non-standard) - t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800"); + // 81-byte TX_NULL_DATA (non-standard) + t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800"); BOOST_CHECK(!IsStandardTx(t, reason)); // TX_NULL_DATA w/o PUSHDATA From eef747bba81e66b2d551a3670a659bbe9dd4a8ce Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 20 Nov 2014 20:45:24 +0000 Subject: [PATCH 0011/2337] libbitcoinconsensus: Add pkg-config support --- Makefile.am | 5 +++++ configure.ac | 1 + libbitcoinconsensus.pc.in | 11 +++++++++++ 3 files changed, 17 insertions(+) create mode 100644 libbitcoinconsensus.pc.in diff --git a/Makefile.am b/Makefile.am index 6bc00443134..9b4d52c63c1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,6 +4,11 @@ SUBDIRS = src GZIP_ENV="-9n" +if BUILD_BITCOIN_LIBS +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libbitcoinconsensus.pc +endif + BITCOIND_BIN=$(top_builddir)/src/bitcoind$(EXEEXT) BITCOIN_QT_BIN=$(top_builddir)/src/qt/bitcoin-qt$(EXEEXT) BITCOIN_CLI_BIN=$(top_builddir)/src/bitcoin-cli$(EXEEXT) diff --git a/configure.ac b/configure.ac index 6784521d818..86c7cc948fc 100644 --- a/configure.ac +++ b/configure.ac @@ -680,6 +680,7 @@ AC_MSG_CHECKING([whether to build libraries]) AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes]) if test x$build_bitcoin_libs = xyes; then AC_DEFINE(HAVE_CONSENSUS_LIB, 1, [Define this symbol if the consensus lib has been built]) + AC_CONFIG_FILES([libbitcoinconsensus.pc:libbitcoinconsensus.pc.in]) fi AC_MSG_RESULT($build_bitcoin_libs) diff --git a/libbitcoinconsensus.pc.in b/libbitcoinconsensus.pc.in new file mode 100644 index 00000000000..3ca1696a31c --- /dev/null +++ b/libbitcoinconsensus.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Bitcoin Core consensus library +Description: Library for the Bitcoin consensus protocol. +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lbitcoinconsensus +Cflags: -I${includedir} +Requires.private: libcrypto From 71acb865402ab4423633c7e5f03b7ec4ef8c8e18 Mon Sep 17 00:00:00 2001 From: Heath Date: Mon, 24 Nov 2014 13:38:39 -0500 Subject: [PATCH 0012/2337] print the caught error instead of raising an error --- contrib/bitrpc/bitrpc.py | 144 +++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/contrib/bitrpc/bitrpc.py b/contrib/bitrpc/bitrpc.py index 02577b1b6aa..c3ce9d79362 100644 --- a/contrib/bitrpc/bitrpc.py +++ b/contrib/bitrpc/bitrpc.py @@ -20,9 +20,9 @@ if cmd == "backupwallet": try: path = raw_input("Enter destination path/filename: ") print access.backupwallet(path) - except: - print "\n---An error occurred---\n" - + except Exception as inst: + print inst + elif cmd == "encryptwallet": try: pwd = getpass.getpass(prompt="Enter passphrase: ") @@ -32,29 +32,29 @@ elif cmd == "encryptwallet": print "\n---Wallet encrypted. Server stopping, restart to run with encrypted wallet---\n" else: print "\n---Passphrases do not match---\n" - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getaccount": try: addr = raw_input("Enter a Bitcoin address: ") print access.getaccount(addr) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getaccountaddress": try: acct = raw_input("Enter an account name: ") print access.getaccountaddress(acct) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getaddressesbyaccount": try: acct = raw_input("Enter an account name: ") print access.getaddressesbyaccount(acct) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getbalance": try: @@ -64,57 +64,57 @@ elif cmd == "getbalance": print access.getbalance(acct, mc) except: print access.getbalance() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getblockbycount": try: height = raw_input("Height: ") print access.getblockbycount(height) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getblockcount": try: print access.getblockcount() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getblocknumber": try: print access.getblocknumber() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getconnectioncount": try: print access.getconnectioncount() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getdifficulty": try: print access.getdifficulty() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getgenerate": try: print access.getgenerate() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "gethashespersec": try: print access.gethashespersec() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getinfo": try: print access.getinfo() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getnewaddress": try: @@ -123,8 +123,8 @@ elif cmd == "getnewaddress": print access.getnewaddress(acct) except: print access.getnewaddress() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getreceivedbyaccount": try: @@ -134,8 +134,8 @@ elif cmd == "getreceivedbyaccount": print access.getreceivedbyaccount(acct, mc) except: print access.getreceivedbyaccount() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getreceivedbyaddress": try: @@ -145,15 +145,15 @@ elif cmd == "getreceivedbyaddress": print access.getreceivedbyaddress(addr, mc) except: print access.getreceivedbyaddress() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "gettransaction": try: txid = raw_input("Enter a transaction ID: ") print access.gettransaction(txid) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "getwork": try: @@ -162,8 +162,8 @@ elif cmd == "getwork": print access.gettransaction(data) except: print access.gettransaction() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "help": try: @@ -172,8 +172,8 @@ elif cmd == "help": print access.help(cmd) except: print access.help() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "listaccounts": try: @@ -182,8 +182,8 @@ elif cmd == "listaccounts": print access.listaccounts(mc) except: print access.listaccounts() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "listreceivedbyaccount": try: @@ -193,8 +193,8 @@ elif cmd == "listreceivedbyaccount": print access.listreceivedbyaccount(mc, incemp) except: print access.listreceivedbyaccount() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "listreceivedbyaddress": try: @@ -204,8 +204,8 @@ elif cmd == "listreceivedbyaddress": print access.listreceivedbyaddress(mc, incemp) except: print access.listreceivedbyaddress() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "listtransactions": try: @@ -216,8 +216,8 @@ elif cmd == "listtransactions": print access.listtransactions(acct, count, frm) except: print access.listtransactions() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "move": try: @@ -230,8 +230,8 @@ elif cmd == "move": print access.move(frm, to, amt, mc, comment) except: print access.move(frm, to, amt) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "sendfrom": try: @@ -245,8 +245,8 @@ elif cmd == "sendfrom": print access.sendfrom(frm, to, amt, mc, comment, commentto) except: print access.sendfrom(frm, to, amt) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "sendmany": try: @@ -258,8 +258,8 @@ elif cmd == "sendmany": print access.sendmany(frm,to,mc,comment) except: print access.sendmany(frm,to) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "sendtoaddress": try: @@ -271,16 +271,16 @@ elif cmd == "sendtoaddress": print access.sendtoaddress(to,amt,comment,commentto) except: print access.sendtoaddress(to,amt) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "setaccount": try: addr = raw_input("Address: ") acct = raw_input("Account:") print access.setaccount(addr,acct) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "setgenerate": try: @@ -290,36 +290,36 @@ elif cmd == "setgenerate": print access.setgenerate(gen, cpus) except: print access.setgenerate(gen) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "settxfee": try: amt = raw_input("Amount:") print access.settxfee(amt) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "stop": try: print access.stop() - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "validateaddress": try: addr = raw_input("Address: ") print access.validateaddress(addr) - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "walletpassphrase": try: pwd = getpass.getpass(prompt="Enter wallet passphrase: ") access.walletpassphrase(pwd, 60) print "\n---Wallet unlocked---\n" - except: - print "\n---An error occurred---\n" + except Exception as inst: + print inst elif cmd == "walletpassphrasechange": try: @@ -328,10 +328,8 @@ elif cmd == "walletpassphrasechange": access.walletpassphrasechange(pwd, pwd2) print print "\n---Passphrase changed---\n" - except: - print - print "\n---An error occurred---\n" - print + except Exception as inst: + print inst else: print "Command not found or not supported" From 850c570d685a3bd350eea30c4688185c586de1db Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Tue, 25 Nov 2014 16:12:55 +0800 Subject: [PATCH 0013/2337] No longer check osx compatibility in RenameThread 10.5 support has been dropped for some time now. --- src/util.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 0cdf4e614d8..d40b985dc17 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -698,13 +698,8 @@ void RenameThread(const char* name) // removed. pthread_set_name_np(pthread_self(), name); -#elif defined(MAC_OSX) && defined(__MAC_OS_X_VERSION_MAX_ALLOWED) - -// pthread_setname_np is XCode 10.6-and-later -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 +#elif defined(MAC_OSX) pthread_setname_np(name); -#endif - #else // Prevent warnings for unused parameters... (void)name; From ae4151bbad74ab54de818d7704fa4568ee65e40d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 25 Oct 2014 05:24:14 -0700 Subject: [PATCH 0014/2337] No semantic change: reuse stack variable in P2SH evaluation --- src/script/interpreter.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 5eda23731d7..d97f917c373 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1107,21 +1107,24 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne if (!scriptSig.IsPushOnly()) return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); - // stackCopy cannot be empty here, because if it was the + // Restore stack. + swap(stack, stackCopy); + + // stack cannot be empty here, because if it was the // P2SH HASH <> EQUAL scriptPubKey would be evaluated with // an empty stack and the EvalScript above would return false. - assert(!stackCopy.empty()); + assert(!stack.empty()); - const valtype& pubKeySerialized = stackCopy.back(); + const valtype& pubKeySerialized = stack.back(); CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); - popstack(stackCopy); + popstack(stack); - if (!EvalScript(stackCopy, pubKey2, flags, checker, serror)) + if (!EvalScript(stack, pubKey2, flags, checker, serror)) // serror is set return false; - if (stackCopy.empty()) + if (stack.empty()) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - if (!CastToBool(stackCopy.back())) + if (!CastToBool(stack.back())) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); else return set_success(serror); From b6e03cc59208305681745ad06f2056ffe6690597 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 12 Oct 2014 18:39:47 -0700 Subject: [PATCH 0015/2337] Add SCRIPT_VERIFY_CLEANSTACK (BIP62 rule 6) Based on an earlier patch by Peter Todd, though the rules here are different (P2SH scripts should not have a CLEANSTACK check before the P2SH evaluation). --- src/script/interpreter.cpp | 15 ++++++++++++--- src/script/interpreter.h | 8 +++++++- src/script/script_error.h | 1 + src/test/data/script_invalid.json | 12 ++++++++++++ src/test/data/script_valid.json | 18 ++++++++++++++++++ src/test/script_tests.cpp | 16 ++++++++++++++++ src/test/transaction_tests.cpp | 3 ++- 7 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index d97f917c373..1b187f5ef5c 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1096,7 +1096,6 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne return false; if (stack.empty()) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - if (CastToBool(stack.back()) == false) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); @@ -1126,8 +1125,18 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne return set_error(serror, SCRIPT_ERR_EVAL_FALSE); if (!CastToBool(stack.back())) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - else - return set_success(serror); + } + + // The CLEANSTACK check is only performed after potential P2SH evaluation, + // as the non-P2SH evaluation of a P2SH script will obviously not result in + // a clean stack (the P2SH inputs remain). + if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) { + // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK + // would be possible, which is not a softfork (and P2SH should be one). + assert((flags & SCRIPT_VERIFY_P2SH) != 0); + if (stack.size() != 1) { + return set_error(serror, SCRIPT_ERR_CLEANSTACK); + } } return set_success(serror); diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 35b2f6c65a1..9b35b176aeb 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -67,8 +67,14 @@ enum // discouraged NOPs fails the script. This verification flag will never be // a mandatory flag applied to scripts in a block. NOPs that are not // executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected. - SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7) + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7), + // Require that only a single stack element remains after evaluation. This changes the success criterion from + // "At least one stack element must remain, and when interpreted as a boolean, it must be true" to + // "Exactly one stack element must remain, and when interpreted as a boolean, it must be true". + // (softfork safe, BIP62 rule 6) + // Note: CLEANSTACK should never be used without P2SH. + SCRIPT_VERIFY_CLEANSTACK = (1U << 8), }; uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); diff --git a/src/script/script_error.h b/src/script/script_error.h index ac1f2deae5a..f085b63032d 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -43,6 +43,7 @@ typedef enum ScriptError_t SCRIPT_ERR_SIG_HIGH_S, SCRIPT_ERR_SIG_NULLDUMMY, SCRIPT_ERR_PUBKEYTYPE, + SCRIPT_ERR_CLEANSTACK, /* softfork safeness */ SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 71e757714cb..d21abebb48c 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -671,6 +671,18 @@ signatures and pubkeys. "SIGPUSHONLY", "P2SH(P2PK) with non-push scriptSig" ], +[ + "11 0x47 0x3044022057c4ba463d3b8e6848b3896be14c6953caf0528cd390ad15104a109c94b558ba02206fa3922154e1d0bfca92ce5f9adbe4991be33f3f5b7f6bf501e895b7e37fd72f01", + "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "CLEANSTACK,P2SH", + "P2PK with unnecessary input" +], +[ + "11 0x47 0x304402203407c26745ea95ee31fbb5074e730ff9be235d5a8d8e0a2c868358bf6a04797402205cc0e594dfd275583472168298d448be59c2530a4ea4d7c37311b82108f9f8bc01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", + "CLEANSTACK,P2SH", + "P2SH with unnecessary input" +], ["The End"] ] diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index ada45a64ed1..072c7dcafd1 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -822,6 +822,24 @@ See also the corresponding inverted versions of these tests in script_invalid.js "SIGPUSHONLY", "2-of-2 with two identical keys and sigs pushed" ], +[ + "11 0x47 0x304402204ba8b04dfe8657608427b996bd7c151ff8cd8579b3316c7314549a6c59f6bfb7022058cf052927fbc5e51e26dd4711c470bbf7f3adc8aaaf7bfa304eff6bb6e6399e01", + "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "P2SH", + "P2PK with unnecessary input but no CLEANSTACK" +], +[ + "11 0x47 0x304402202beaa2f6a4ec783091643797f9819b5ae39a03dfcf3b934746e96dd6b2ad5f7202200650a618fb2ce08b4edd160351172e016a041c81622d806390420d15cc6cece401 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", + "P2SH", + "P2SH with unnecessary input but no CLEANSTACK" +], +[ + "0x47 0x3044022048505fd42afde400932558ea7fa76a52c2fff3130fa820a6a05647f64d5d780e022056a6bc823c95cedf68f6f67ad036533b48b9f3f706355a71f9f6e647e889f79201 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", + "CLEANSTACK,P2SH", + "P2SH with CLEANSTACK" +], ["The End"] ] diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 6952f4c5844..22c182b1225 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -489,6 +489,22 @@ BOOST_AUTO_TEST_CASE(script_build) "2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY ).Num(0).PushSig(keys.key1).PushSig(keys.key1)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH + ).Num(11).PushSig(keys.key0)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH + ).Num(11).PushSig(keys.key0)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true + ).Num(11).PushSig(keys.key0).PushRedeem()); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true + ).Num(11).PushSig(keys.key0).PushRedeem()); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).PushRedeem()); + std::map tests_good; std::map tests_bad; diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index e939e899725..67b2dd5df66 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -38,7 +38,8 @@ static std::map mapFlagNames = boost::assign::map_list_of (string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY) (string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA) (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY) - (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS); + (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) + (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK); unsigned int ParseScriptFlags(string strFlags) { From da918ac06e0d064e9584959ab3d241d03500e972 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 19 Nov 2014 15:52:50 +0100 Subject: [PATCH 0016/2337] Make SCRIPT_VERIFY_CLEANSTACK a standardness requirement --- src/script/standard.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/script/standard.h b/src/script/standard.h index c4b82b4c45a..ed85816a375 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -48,7 +48,8 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_MINIMALDATA | SCRIPT_VERIFY_NULLDUMMY | - SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS; + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | + SCRIPT_VERIFY_CLEANSTACK; /** For convenience, standard but not mandatory verify flags. */ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; From 63d1ae5556ea40dde0cca20addda4bba40005496 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 25 Nov 2014 16:26:20 +0100 Subject: [PATCH 0017/2337] Do all block index writes in a batch --- src/chain.h | 2 +- src/main.cpp | 31 +++++++++++++++---------------- src/txdb.cpp | 25 ++++++++++++------------- src/txdb.h | 4 +--- 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/chain.h b/src/chain.h index c01240665d7..e76d5a3d9ad 100644 --- a/src/chain.h +++ b/src/chain.h @@ -293,7 +293,7 @@ public: hashPrev = 0; } - explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) { + explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { hashPrev = (pprev ? pprev->GetBlockHash() : 0); } diff --git a/src/main.cpp b/src/main.cpp index 88fb31980fb..832d7747f82 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1784,24 +1784,23 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { // First make sure all block and undo data is flushed to disk. FlushBlockFile(); // Then update all block file information (which may refer to block and undo files). - bool fileschanged = false; - for (set::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) { - if (!pblocktree->WriteBlockFileInfo(*it, vinfoBlockFile[*it])) { - return state.Abort("Failed to write to block index"); + { + std::vector > vFiles; + vFiles.reserve(setDirtyFileInfo.size()); + for (set::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) { + vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it])); + setDirtyFileInfo.erase(it++); + } + std::vector vBlocks; + vBlocks.reserve(setDirtyBlockIndex.size()); + for (set::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { + vBlocks.push_back(*it); + setDirtyBlockIndex.erase(it++); + } + if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { + return state.Abort("Files to write to block index database"); } - fileschanged = true; - setDirtyFileInfo.erase(it++); } - if (fileschanged && !pblocktree->WriteLastBlockFile(nLastBlockFile)) { - return state.Abort("Failed to write to block index"); - } - for (set::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { - if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(*it))) { - return state.Abort("Failed to write to block index"); - } - setDirtyBlockIndex.erase(it++); - } - pblocktree->Sync(); // Finally flush the chainstate (which may refer to block index entries). if (!pcoinsTip->Flush()) return state.Abort("Failed to write to coin database"); diff --git a/src/txdb.cpp b/src/txdb.cpp index 0731d843f3e..29ef3503749 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -66,23 +66,10 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) { } -bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) -{ - return Write(make_pair('b', blockindex.GetBlockHash()), blockindex); -} - -bool CBlockTreeDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo &info) { - return Write(make_pair('f', nFile), info); -} - bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { return Read(make_pair('f', nFile), info); } -bool CBlockTreeDB::WriteLastBlockFile(int nFile) { - return Write('l', nFile); -} - bool CBlockTreeDB::WriteReindexing(bool fReindexing) { if (fReindexing) return Write('R', '1'); @@ -152,6 +139,18 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { return true; } +bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { + CLevelDBBatch batch; + for (std::vector >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { + batch.Write(make_pair('f', it->first), *it->second); + } + batch.Write('l', nLastFile); + for (std::vector::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { + batch.Write(make_pair('b', (*it)->GetBlockHash()), CDiskBlockIndex(*it)); + } + return WriteBatch(batch, true); +} + bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { return Read(make_pair('t', txid), pos); } diff --git a/src/txdb.h b/src/txdb.h index 9a98fcc41b7..f81fc626897 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -48,11 +48,9 @@ private: CBlockTreeDB(const CBlockTreeDB&); void operator=(const CBlockTreeDB&); public: - bool WriteBlockIndex(const CDiskBlockIndex& blockindex); + bool WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo); bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo); - bool WriteBlockFileInfo(int nFile, const CBlockFileInfo &fileinfo); bool ReadLastBlockFile(int &nFile); - bool WriteLastBlockFile(int nFile); bool WriteReindexing(bool fReindex); bool ReadReindexing(bool &fReindex); bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos); From 2747f7cf77f6ef3515899a0d8dbe1bad68114da7 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 21 Nov 2014 13:49:39 +0100 Subject: [PATCH 0018/2337] [Qt] fix missing plural form for a string in sendcoinsdialog - this was reported on Transifex by pryds (Thank you!) --- src/qt/sendcoinsdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 46eb58ca439..2bacd48a42f 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -631,7 +631,7 @@ void SendCoinsDialog::updateSmartFeeLabel() { ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB"); ui->labelSmartFee2->hide(); - ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %1 block(s).").arg(nBlocksToConfirm)); + ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", nBlocksToConfirm)); } updateFeeMinimizedLabel(); From 50db7d9f09f2fda7c97816d810e478c10dba3cb2 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 21 Nov 2014 13:52:26 +0100 Subject: [PATCH 0019/2337] [Qt] change some strings to reflect name change to Bitcoin Core --- src/qt/askpassphrasedialog.cpp | 2 +- src/qt/bitcoingui.cpp | 2 +- src/qt/forms/optionsdialog.ui | 6 +++--- src/qt/forms/rpcconsole.ui | 2 +- src/qt/rpcconsole.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index fa9ac6b135c..2c8d93fbafa 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -119,7 +119,7 @@ void AskPassphraseDialog::accept() { QMessageBox::warning(this, tr("Wallet encrypted"), "" + - tr("Bitcoin will close now to finish the encryption process. " + tr("Bitcoin Core will close now to finish the encryption process. " "Remember that encrypting your wallet cannot fully protect " "your bitcoins from being stolen by malware infecting your computer.") + "

" + diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 6a457d361fe..f52075ce197 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -296,7 +296,7 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle) aboutQtAction->setStatusTip(tr("Show information about Qt")); aboutQtAction->setMenuRole(QAction::AboutQtRole); optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); - optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin")); + optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core")); optionsAction->setMenuRole(QAction::PreferencesRole); toggleHideAction = new QAction(networkStyle->getAppIcon(), tr("&Show / Hide"), this); toggleHideAction->setStatusTip(tr("Show or hide the main Window")); diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 51156ade4ff..19421dc813d 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -30,10 +30,10 @@ - Automatically start Bitcoin after logging in to the system. + Automatically start Bitcoin Core after logging in to the system. - &Start Bitcoin on system login + &Start Bitcoin Core on system login @@ -375,7 +375,7 @@ - The user interface language can be set here. This setting will take effect after restarting Bitcoin. + The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index c5ac371619c..b62e9475ab3 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -331,7 +331,7 @@ - Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files. + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. &Open diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 2d2d448b49f..27de9e3d58b 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -361,7 +361,7 @@ void RPCConsole::clear() "b { color: #006060; } " ); - message(CMD_REPLY, (tr("Welcome to the Bitcoin RPC console.") + "
" + + message(CMD_REPLY, (tr("Welcome to the Bitcoin Core RPC console.") + "
" + tr("Use up and down arrows to navigate history, and Ctrl-L to clear screen.") + "
" + tr("Type help for an overview of available commands.")), true); } From 4709160b506e09a14386adb24f08493108d2ba8c Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Tue, 2 Dec 2014 15:06:55 +0100 Subject: [PATCH 0020/2337] [Qt] fix a translation that occurs 2 times but was a little different --- src/qt/forms/sendcoinsdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 0bf04c75eb3..eebb459327e 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -855,7 +855,7 @@ - If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte. + If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte. per kilobyte From cac15bedb1398a1eb72837b74ab76266305172e1 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Thu, 4 Dec 2014 00:53:16 -0500 Subject: [PATCH 0021/2337] Test unexecuted OP_CODESEPARATOR OP_CODESEPARATOR is an actual executed instruction, not a declarative thing, so if it's wrapped in an OP_IF it can be turned off. Using this to implement Rivest's Paywords is left as an exercise for the reader. --- src/test/data/tx_invalid.json | 12 ++++++++++++ src/test/data/tx_valid.json | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 638a705f9f3..456e0d2f7bd 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -103,5 +103,17 @@ [[["ad503f72c18df5801ee64d76090afe4c607fb2b822e9b7b63c5826c50e22fc3b", 0, "0x21 0x027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5 CHECKSIG NOT"]], "01000000013bfc220ec526583cb6b7e922b8b27f604cfe0a09764de61e80f58dc1723f50ad0000000000ffffffff0101000000000000002321027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5ac00000000", "P2SH"], + +["Inverted versions of tx_valid CODESEPARATOR IF block tests"], + +["CODESEPARATOR in an unexecuted IF block does not change what is hashed"], +[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]], +"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a48304502207a6974a77c591fa13dff60cabbb85a0de9e025c09c65a4b2285e47ce8e22f761022100f0efaac9ff8ac36b10721e0aae1fb975c90500b50c56e8a0cc52b0403f0425dd0151ffffffff010000000000000000016a00000000", "P2SH"], + +["As above, with the IF block executed"], +[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]], +"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510100ffffffff010000000000000000016a00000000", "P2SH"], + + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index aa8e5ca6c35..182b88ef67f 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -149,6 +149,15 @@ [[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 1"]], "010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a900000000924830450221009c0a27f886a1d8cb87f6f595fbc3163d28f7a81ec3c4b252ee7f3ac77fd13ffa02203caa8dfa09713c8c4d7ef575c75ed97812072405d932bd11e6a1593a98b679370148304502201e3861ef39a526406bad1e20ecad06be7375ad40ddb582c9be42d26c3a0d7b240221009d0a3985e96522e59635d19cc4448547477396ce0ef17a58e7d74c3ef464292301ffffffff010000000000000000016a00000000", "P2SH"], +["CODESEPARATOR in an unexecuted IF block does not change what is hashed"], +[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]], +"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a48304502207a6974a77c591fa13dff60cabbb85a0de9e025c09c65a4b2285e47ce8e22f761022100f0efaac9ff8ac36b10721e0aae1fb975c90500b50c56e8a0cc52b0403f0425dd0100ffffffff010000000000000000016a00000000", "P2SH"], + +["As above, with the IF block executed"], +[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]], +"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510151ffffffff010000000000000000016a00000000", "P2SH"], + + ["CHECKSIG is legal in scriptSigs"], [[["ccf7f4053a02e653c36ac75c891b7496d0dc5ce5214f6c913d9cf8f1329ebee0", 0, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]], "0100000001e0be9e32f1f89c3d916c4f21e55cdcd096741b895cc76ac353e6023a05f4f7cc00000000d86149304602210086e5f736a2c3622ebb62bd9d93d8e5d76508b98be922b97160edc3dcca6d8c47022100b23c312ac232a4473f19d2aeb95ab7bdf2b65518911a0d72d50e38b5dd31dc820121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac4730440220508fa761865c8abd81244a168392876ee1d94e8ed83897066b5e2df2400dad24022043f5ee7538e87e9c6aef7ef55133d3e51da7cc522830a9c4d736977a76ef755c0121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"], From 35f7227a860b2b8c273e4bb299e6bd67cfef9a3f Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Thu, 4 Dec 2014 21:37:26 +0100 Subject: [PATCH 0022/2337] Clean up wallet encryption code. Add a new method DecryptKey in crypter.cpp, that combines the logic for decrypting, initialising and validating a CKey object. This was previously duplicated. --- src/crypter.cpp | 39 +++++++++++++++++---------------------- src/crypter.h | 3 --- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/crypter.cpp b/src/crypter.cpp index 756538836df..88f39bc4768 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -102,7 +102,7 @@ bool CCrypter::Decrypt(const std::vector& vchCiphertext, CKeyingM } -bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext) +static bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext) { CCrypter cKeyCrypter; std::vector chIV(WALLET_CRYPTO_KEY_SIZE); @@ -112,7 +112,7 @@ bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vch return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext); } -bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext) +static bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext) { CCrypter cKeyCrypter; std::vector chIV(WALLET_CRYPTO_KEY_SIZE); @@ -122,6 +122,19 @@ bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key) +{ + CKeyingMaterial vchSecret; + if(!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) + return false; + + if (vchSecret.size() != 32) + return false; + + key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed()); + return key.VerifyPubKey(vchPubKey); +} + bool CCryptoKeyStore::SetCrypted() { LOCK(cs_KeyStore); @@ -161,20 +174,8 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) { const CPubKey &vchPubKey = (*mi).second.first; const std::vector &vchCryptedSecret = (*mi).second.second; - CKeyingMaterial vchSecret; - if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) - { - keyFail = true; - break; - } - if (vchSecret.size() != 32) - { - keyFail = true; - break; - } CKey key; - key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed()); - if (key.GetPubKey() != vchPubKey) + if (!DecryptKey(vMasterKeyIn, vchCryptedSecret, vchPubKey, key)) { keyFail = true; break; @@ -243,13 +244,7 @@ bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const { const CPubKey &vchPubKey = (*mi).second.first; const std::vector &vchCryptedSecret = (*mi).second.second; - CKeyingMaterial vchSecret; - if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) - return false; - if (vchSecret.size() != 32) - return false; - keyOut.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed()); - return true; + return DecryptKey(vMasterKey, vchCryptedSecret, vchPubKey, keyOut); } } return false; diff --git a/src/crypter.h b/src/crypter.h index f7018cfdbea..656658b0fee 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -107,9 +107,6 @@ public: } }; -bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext); -bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext); - /** Keystore which keeps the private keys encrypted. * It derives from the basic key store, which is used if no encryption is active. */ From 88eb44d30f205d8e3f170db44d994c3c4c95736a Mon Sep 17 00:00:00 2001 From: Blake Jakopovic Date: Wed, 3 Dec 2014 11:22:12 +1000 Subject: [PATCH 0023/2337] Revised translation process doc --- doc/translation_process.md | 164 +++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 71 deletions(-) diff --git a/doc/translation_process.md b/doc/translation_process.md index 9475b1dc721..eed467706ee 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -1,21 +1,100 @@ Translations ============ -The Bitcoin Core GUI can be easily translated into other languages. Here's how we -handle those translations. +The Bitcoin-Core project has been designed to support multiple localisations. This makes adding new phrases, and completely new languages easily achievable. For managing all application translations, Bitcoin-Core makes use of the Transifex online translation management tool. -Files and Folders ------------------ +### Helping to translate (using Transifex) +Transifex is setup to monitor the Github repo for updates, and when code containing new translations is found, Transifex will process any changes. It may take several hours after a pull-request has been merged, to appear in the Transifex web interface. -### bitcoin-qt.pro +Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-boarder money transfers, any help making that easier is greatly appreciated. -This file takes care of generating `.qm` files from `.ts` files. It is mostly -automated. +See the [Transifex Bitcoin project](https://www.transifex.com/projects/p/bitcoin/) to assist in translations. You should also join the translation mailing list for announcements - see details below. -### src/qt/bitcoin.qrc +### Writing code with translations +We use automated scripts to help extract translations in both Qt, and non-Qt source files. It is rarely necessary to manually edit the files in `src/qt/locale/`. The translation source files must adhere to the following format: +`bitcoin_xx_YY.ts or bitcoin_xx.ts` -This file must be updated whenever a new translation is added. Please note that -files must end with `.qm`, not `.ts`. +`src/qt/locale/bitcoin_en.ts` is treated in a special way. It is used as the source for all other translations. Whenever a string in the source code is changed, this file must be updated to reflect those changes. A custom script is used to extract strings from the non-Qt parts. This script makes use of `gettext`, so make sure that utility is installed (ie, `apt-get install gettext` on Ubuntu/Debian). Once this has been updated, `lupdate` (included in the Qt SDK) is used to update `bitcoin_en.ts`. + +To automatically regenerate the `bitcoin_en.ts` file, run the following commands: +```sh +cd src/ +make translate +``` + +`contrib/bitcoin-qt.pro` takes care of generating `.qm` (binary compiled) files from `.ts` (source files) files. It’s mostly automated, and you shouldn’t need to worry about it. + +**Example Qt translation** +```cpp +QToolBar *toolbar = addToolBar(tr("Tabs toolbar")); +``` + +### Creating a pull-request +For general PRs, you shouldn’t include any updates to the translation source files. They will be updated periodically, primarily around pre-releases, allowing time for any new phrases to be translated before public releases. This is also important in avoiding translation related merge conflicts. + +When an updated source file is merged into the Github repo, Transifex will automatically detect it (although it can take several hours). Once processed, the new strings will show up as "Remaining" in the Transifex web interface and are ready for translators. + +To create the pull-request, use the following commands: +``` +git add src/qt/bitcoinstrings.cpp src/qt/locale/bitcoin_en.ts +git commit +``` + +### Creating a Transifex account +Visit the [Transifex Signup](https://www.transifex.com/signup/) page to create an account. Take note of your username and password, as they will be required to configure the command-line tool. + +You can find the Bitcoin translation project at [https://www.transifex.com/projects/p/bitcoin/](https://www.transifex.com/projects/p/bitcoin/). + +### Installing the Transifex client command-line tool +The client it used to fetch updated translations. If you are having problems, or need more details, see [http://docs.transifex.com/developer/client/setup](http://docs.transifex.com/developer/client/setup) + +**For Linux and Mac** + +`pip install transifex-client` + +Setup your transifex client config as follows. Please *ignore the token field*. + +```ini +nano ~/.transifexrc + +[https://www.transifex.com] +hostname = https://www.transifex.com +password = PASSWORD +token = +username = USERNAME +``` + +**For Windows** + +Please see [http://docs.transifex.com/developer/client/setup#windows](http://docs.transifex.com/developer/client/setup#windows) for details on installation. + +The Transifex Bitcoin project config file is included as part of the repo. It can be found at `.tx/config`, however you shouldn’t need change anything. + +### Synchronising translations +To assist in updating translations, we have created a script to help. + +1. `python contrib/devtools/update-translations.py` +2. Update `src/qt/bitcoin.qrc` manually or via + `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/locale\/\1.qm<\/file>/'` +3. Update `src/qt/Makefile.am` manually or via + `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/ locale\/\1.ts \\/'` +4. `git add` new translations from `src/qt/locale/` + +**Do not directly download translations** one by one from the Transifex website, as we do a few post-processing steps before committing the translations. + +### Handling Plurals (in source files) +When new plurals are added to the source file, it's important to do the following steps: + +1. Open `bitcoin_en.ts` in Qt Linguist (included in the Qt SDK) +2. Search for `%n`, which will take you to the parts in the translation that use plurals +3. Look for empty `English Translation (Singular)` and `English Translation (Plural)` fields +4. Add the appropriate strings for the singular and plural form of the base string +5. Mark the item as done (via the green arrow symbol in the toolbar) +6. Repeat from step 2, until all singular and plural forms are in the source file +7. Save the source file + +### Translating a new language +To create a new language template, you will need to edit the languages manifest file `src/qt/bitcoin.qrc` and add a new entry. Below is an example of the english language entry. ```xml @@ -24,66 +103,9 @@ files must end with `.qm`, not `.ts`. ``` -### src/qt/locale/ +**Note:** that the language translation file **must end in `.qm`** (the compiled extension), and not `.ts`. -This directory contains all translations. Filenames must adhere to this format: +### Questions and general assistance +The Bitcoin-Core translation maintainers include *tcatm, seone, Diapolo, wumpus and luke-jr*.You can find them, and others, in the Freenode IRC chatroom - `irc.freenode.net #bitcoin-dev`. - bitcoin_xx_YY.ts or bitcoin_xx.ts - -#### bitcoin_en.ts (Source file) - -`src/qt/locale/bitcoin_en.ts` is treated in a special way. It is used as the -source for all other translations. Whenever a string in the code is changed -this file must be updated to reflect those changes. A custom script is used -to extract strings from the non-Qt parts. This script makes use of `gettext`, -so make sure that utility is installed (ie, `apt-get install gettext` on -Ubuntu/Debian). Once this has been updated, lupdate (included in the Qt SDK) -is used to update bitcoin_en.ts. This process has been automated, from src/qt, -simply run: - make translate - -##### Handling of plurals in the source file - -When new plurals are added to the source file, it's important to do the following steps: - -1. Open bitcoin_en.ts in Qt Linguist (also included in the Qt SDK) -2. Search for `%n`, which will take you to the parts in the translation that use plurals -3. Look for empty `English Translation (Singular)` and `English Translation (Plural)` fields -4. Add the appropriate strings for the singular and plural form of the base string -5. Mark the item as done (via the green arrow symbol in the toolbar) -6. Repeat from step 2. until all singular and plural forms are in the source file -7. Save the source file - -##### Creating the pull-request - -An updated source file should be merged to github and Transifex will pick it -up from there (can take some hours). Afterwards the new strings show up as "Remaining" -in Transifex and can be translated. - -To create the pull-request you have to do: - - git add src/qt/bitcoinstrings.cpp src/qt/locale/bitcoin_en.ts - git commit - -Syncing with Transifex ----------------------- - -We are using https://transifex.com as a frontend for translating the client. - -https://www.transifex.com/projects/p/bitcoin/resource/tx/ - -The "Transifex client" (see: http://support.transifex.com/customer/portal/topics/440187-transifex-client/articles) -is used to fetch new translations from Transifex. The configuration for this client (`.tx/config`) -is part of the repository. - -Do not directly download translations one by one from the Transifex website, as we do a few -postprocessing steps before committing the translations. - -### Fetching new translations - -1. `python contrib/devtools/update-translations.py` -2. update `src/qt/bitcoin.qrc` manually or via - `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/locale\/\1.qm<\/file>/'` -3. update `src/qt/Makefile.am` manually or via - `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/ locale\/\1.ts \\/'` -4. `git add` new translations from `src/qt/locale/` +If you are a translator, you should also subscribe to the mailing list, https://groups.google.com/forum/#!forum/bitcoin-translators. Announcements will be posted during application pre-releases to notify translators to check for updates. \ No newline at end of file From 8d174d6b5dc012d9191fddc53bb92ea780a4bb77 Mon Sep 17 00:00:00 2001 From: Micha Date: Sun, 7 Dec 2014 17:55:53 +0200 Subject: [PATCH 0024/2337] Make several small string fixes in linearize-data.py - Add a space after the fixed string prepended to file names when input or output file changes - Clarify the error message when the genesis block is not found in the hash list (...why do we have this at all?) --- contrib/linearize/linearize-data.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index 2dac3a614b0..e7a8762eb09 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -148,7 +148,7 @@ class BlockDataCopier: outFname = self.settings['output_file'] else: outFname = "%s/blk%05d.dat" % (self.settings['output'], outFn) - print("Output file" + outFname) + print("Output file " + outFname) self.outF = open(outFname, "wb") self.outF.write(inhdr) @@ -189,7 +189,7 @@ class BlockDataCopier: while self.blkCountOut < len(self.blkindex): if not self.inF: fname = self.inFileName(self.inFn) - print("Input file" + fname) + print("Input file " + fname) try: self.inF = open(fname, "rb") except IOError: @@ -205,7 +205,7 @@ class BlockDataCopier: inMagic = inhdr[:4] if (inMagic != self.settings['netmagic']): - print("Invalid magic:" + inMagic) + print("Invalid magic: " + inMagic) return inLenLE = inhdr[4:] su = struct.unpack(" Date: Mon, 8 Dec 2014 13:55:12 +0200 Subject: [PATCH 0025/2337] Remove genesis block hash from error --- contrib/linearize/linearize-data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index e7a8762eb09..f59fe9f6e76 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -292,7 +292,7 @@ if __name__ == '__main__': blkmap = mkblockmap(blkindex) if not "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" in blkmap: - print("Genesis block (000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f) not found in hashlist") + print("Genesis block not found in hashlist") else: BlockDataCopier(settings, blkindex, blkmap).run() From ecae2acb06d44509425a9cdad38ed9a5bce15cbe Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 11 Dec 2014 01:58:25 +0100 Subject: [PATCH 0026/2337] Squashed 'src/secp256k1/' changes from b0210a9..bccaf86 bccaf86 Merge pull request #150 2a53a47 Merge pull request #151 5f5a31f Merge pull request #149 3907277 Merge pull request #142 a3e0611 Enable tests in x86 travis builds 45da235 x86 builder 8bb0e93 Merge pull request #155 971fe81 build: fix openssl detection for cross builds f22d73e Explicitly access %0..%2 as 64-bit so we use the right registers for x32 ABI e66d4d6 Avoid the stack in assembly and use explicit registers cf7b2b4 Fix ECDSA message hashes to 32 bytes 056ad31 Really compile with -O3 by default 74ad63a Merge pull request #146 9000458 Merge pull request #145 1f46b00 build: fix __builtin_expect detection for clang aaba2e0 Merge pull request #136 8a0775c Merge pull request #144 ee1eaa7 Merge pull request #141 c88e2b8 Compile with -O3 by default 6558a26 Make the benchmarks print out stats 000bdf6 Rename bench_verify to bench_recovery 7c6fed2 Add a few more additional tests. 992e03b travis: add clang to the test matrix b43b79a Merge pull request #143 e06a924 Include time.h header for time(). 8d11164 Add some additional tests. 3545627 Merge pull request #118 6a9901e Merge pull request #137 376b28b Merge pull request #128 1728806 Merge pull request #138 a5759c5 Check return value of malloc 39bd94d Variable time normalize ad86bdf Merge pull request #140 54b768c Another redundant secp256k1_fe_normalize 69dcaab Merge pull request #139 1c29f2e Remove redundant secp256k1_fe_normalize from secp256k1_gej_add_ge_var. 2b9388b Remove unused secp256k1_fe_inv_all f461b76 Allocate precomputation arrays on the heap b2c9681 Make {mul,sqr}_inner use the same argument order as {mul,sqr} 6793505 Convert YASM code into inline assembly f048615 Rewrite field assembly to match the C version 3ce74b1 Tweak precomputed table size for G git-subtree-dir: src/secp256k1 git-subtree-split: bccaf86caa9c44166e5a66600b742c516e03c3f0 --- .travis.yml | 19 +- Makefile.am | 30 +-- build-aux/m4/bitcoin_secp.m4 | 51 ++-- configure.ac | 11 +- include/secp256k1.h | 32 +-- nasm_lt.sh | 57 ---- src/bench.h | 37 +++ src/bench_inv.c | 45 ++-- src/bench_recover.c | 46 ++++ src/bench_sign.c | 65 +++-- src/bench_verify.c | 59 +++-- src/ecdsa_impl.h | 8 +- src/eckey_impl.h | 8 +- src/ecmult_gen_impl.h | 6 +- src/ecmult_impl.h | 17 +- src/field.h | 8 +- src/field_10x26_impl.h | 64 ++++- src/field_5x52_asm.asm | 469 --------------------------------- src/field_5x52_asm_impl.h | 495 ++++++++++++++++++++++++++++++++++- src/field_5x52_impl.h | 48 +++- src/field_5x52_int128_impl.h | 4 +- src/field_gmp_impl.h | 4 + src/field_impl.h | 32 +-- src/group.h | 7 +- src/group_impl.h | 59 +++-- src/scalar_impl.h | 2 +- src/secp256k1.c | 38 +-- src/tests.c | 332 +++++++++++++++++++---- src/util.h | 6 + 29 files changed, 1206 insertions(+), 853 deletions(-) delete mode 100755 nasm_lt.sh create mode 100644 src/bench.h create mode 100644 src/bench_recover.c delete mode 100644 src/field_5x52_asm.asm diff --git a/.travis.yml b/.travis.yml index 3a85e8cba0d..28cd61dbc9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,14 @@ -language: cpp -compiler: gcc +language: c +compiler: + - clang + - gcc install: - sudo apt-get install -qq libssl-dev - - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" -o "$FIELD" = "gmp" ]; then sudo apt-get install -qq libgmp-dev; fi - - if [ "$FIELD" = "64bit_asm" ]; then sudo apt-get install -qq yasm; fi + - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" -o "$FIELD" = "gmp" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi + - if [ -n "$EXTRAPACKAGES" ]; then sudo apt-get update && sudo apt-get install --no-install-recommends --no-upgrade $EXTRAPACKAGES; fi env: global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no BUILD=check EXTRAFLAGS= + - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES= matrix: - SCALAR=32bit - SCALAR=64bit @@ -22,6 +24,11 @@ env: - BIGNUM=none ENDOMORPHISM=yes - BUILD=distcheck - EXTRAFLAGS=CFLAGS=-DDETERMINISTIC + - HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" + - HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" ENDOMORPHISM=yes before_script: ./autogen.sh -script: ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS && make -j2 $BUILD +script: + - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi + - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi + - ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS $USE_HOST && make -j2 $BUILD os: linux diff --git a/Makefile.am b/Makefile.am index dbf1790f341..390d2c9ffa4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,12 +1,6 @@ ACLOCAL_AMFLAGS = -I build-aux/m4 lib_LTLIBRARIES = libsecp256k1.la -if USE_ASM -COMMON_LIB = libsecp256k1_common.la -else -COMMON_LIB = -endif -noinst_LTLIBRARIES = $(COMMON_LIB) include_HEADERS = include/secp256k1.h noinst_HEADERS = noinst_HEADERS += src/scalar.h @@ -43,30 +37,30 @@ noinst_HEADERS += src/field_gmp.h noinst_HEADERS += src/field_gmp_impl.h noinst_HEADERS += src/field.h noinst_HEADERS += src/field_impl.h +noinst_HEADERS += src/bench.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libsecp256k1.pc -if USE_ASM -libsecp256k1_common_la_SOURCES = src/field_5x52_asm.asm -endif - libsecp256k1_la_SOURCES = src/secp256k1.c libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include $(SECP_INCLUDES) -libsecp256k1_la_LIBADD = $(COMMON_LIB) $(SECP_LIBS) +libsecp256k1_la_LIBADD = $(SECP_LIBS) noinst_PROGRAMS = if USE_BENCHMARK -noinst_PROGRAMS += bench_verify bench_sign bench_inv +noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_inv bench_verify_SOURCES = src/bench_verify.c bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) bench_verify_LDFLAGS = -static +bench_recover_SOURCES = src/bench_recover.c +bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_recover_LDFLAGS = -static bench_sign_SOURCES = src/bench_sign.c bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) bench_sign_LDFLAGS = -static bench_inv_SOURCES = src/bench_inv.c -bench_inv_LDADD = $(COMMON_LIB) $(SECP_LIBS) +bench_inv_LDADD = $(SECP_LIBS) bench_inv_LDFLAGS = -static bench_inv_CPPFLAGS = $(SECP_INCLUDES) endif @@ -75,15 +69,9 @@ if USE_TESTS noinst_PROGRAMS += tests tests_SOURCES = src/tests.c tests_CPPFLAGS = -DVERIFY $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) -tests_LDADD = $(COMMON_LIB) $(SECP_LIBS) $(SECP_TEST_LIBS) +tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) tests_LDFLAGS = -static TESTS = tests endif -EXTRA_DIST = autogen.sh nasm_lt.sh - -#x86_64 only -if USE_ASM -.asm.lo: - $(LIBTOOL) --mode=compile --tag YASM $(srcdir)/nasm_lt.sh $(YASM) -f $(YASM_BINFMT) $(YAFLAGS) -I$(srcdir) -I. $< -o $@ -endif +EXTRA_DIST = autogen.sh diff --git a/build-aux/m4/bitcoin_secp.m4 b/build-aux/m4/bitcoin_secp.m4 index 4ca28f99cfa..1373478c9c5 100644 --- a/build-aux/m4/bitcoin_secp.m4 +++ b/build-aux/m4/bitcoin_secp.m4 @@ -11,38 +11,16 @@ fi dnl AC_DEFUN([SECP_64BIT_ASM_CHECK],[ -if test x"$host_cpu" == x"x86_64"; then - AC_CHECK_PROG(YASM, yasm, yasm) -else - if test x"$set_field" = x"64bit_asm"; then - AC_MSG_ERROR([$set_field field support explicitly requested but is not compatible with this host]) - fi -fi -if test x$YASM = x; then - if test x"$set_field" = x"64bit_asm"; then - AC_MSG_ERROR([$set_field field support explicitly requested but yasm was not found]) - fi - has_64bit_asm=no -else - case x"$host_os" in - xdarwin*) - YASM_BINFMT=macho64 - ;; - x*-gnux32) - YASM_BINFMT=elfx32 - ;; - *) - YASM_BINFMT=elf64 - ;; - esac - if $YASM -f help | grep -q $YASM_BINFMT; then - has_64bit_asm=yes - else - if test x"$set_field" = x"64bit_asm"; then - AC_MSG_ERROR([$set_field field support explicitly requested but yasm doesn't support $YASM_BINFMT format]) - fi - AC_MSG_WARN([yasm too old for $YASM_BINFMT format]) - has_64bit_asm=no +AC_MSG_CHECKING(for x86_64 assembly availability) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include ]],[[ + uint64_t a = 11, tmp; + __asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); + ]])],[has_64bit_asm=yes],[has_64bit_asm=no]) +AC_MSG_RESULT([$has_64bit_asm]) +if test x"$set_field" == x"64bit_asm"; then + if test x"$has_64bit_asm" == x"no"; then + AC_MSG_ERROR([$set_field field support explicitly requested but no x86_64 assembly available]) fi fi ]) @@ -52,8 +30,13 @@ AC_DEFUN([SECP_OPENSSL_CHECK],[ if test x"$use_pkgconfig" = x"yes"; then : #NOP m4_ifdef([PKG_CHECK_MODULES],[ - PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes; AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no]) - : #NOP + PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no]) + if test x"$has_libcrypto" = x"yes"; then + TEMP_LIBS="$LIBS" + LIBS="$LIBS $CRYPTO_LIBS" + AC_CHECK_LIB(crypto, main,[AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no]) + LIBS="$TEMP_LIBS" + fi ]) else AC_CHECK_HEADER(openssl/crypto.h,[AC_CHECK_LIB(crypto, main,[has_libcrypto=yes; CRYPTO_LIBS=-lcrypto; AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])] diff --git a/configure.ac b/configure.ac index 6e6fccd7fdd..40e121e8064 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,10 @@ AC_PATH_TOOL(AR, ar) AC_PATH_TOOL(RANLIB, ranlib) AC_PATH_TOOL(STRIP, strip) +if test "x$CFLAGS" = "x"; then + CFLAGS="-O3 -g" +fi + AC_PROG_CC_C99 if test x"$ac_cv_prog_cc_c99" == x"no"; then AC_MSG_ERROR([c99 compiler support required]) @@ -103,7 +107,11 @@ AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto], AC_CHECK_TYPES([__int128]) -AC_CHECK_DECL(__builtin_expect,AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]),,) +AC_MSG_CHECKING([for __builtin_expect]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])], + [ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]) ], + [ AC_MSG_RESULT([no]) + ]) if test x"$req_field" = x"auto"; then SECP_64BIT_ASM_CHECK @@ -283,7 +291,6 @@ AC_SUBST(SECP_INCLUDES) AC_SUBST(SECP_LIBS) AC_SUBST(SECP_TEST_LIBS) AC_SUBST(SECP_TEST_INCLUDES) -AC_SUBST(YASM_BINFMT) AM_CONDITIONAL([USE_ASM], [test x"$set_field" == x"64bit_asm"]) AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" != x"no"]) diff --git a/include/secp256k1.h b/include/secp256k1.h index 94a6ef483f3..dca7ca00e7e 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -62,8 +62,7 @@ void secp256k1_stop(void); * 0: incorrect signature * -1: invalid public key * -2: invalid signature - * In: msg: the message being verified (cannot be NULL) - * msglen: the length of the message (at most 32) + * In: msg32: the 32-byte message hash being verified (cannot be NULL) * sig: the signature being verified (cannot be NULL) * siglen: the length of the signature * pubkey: the public key to verify with (cannot be NULL) @@ -71,19 +70,17 @@ void secp256k1_stop(void); * Requires starting using SECP256K1_START_VERIFY. */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( - const unsigned char *msg, - int msglen, + const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); /** Create an ECDSA signature. * Returns: 1: signature created * 0: nonce invalid, try another one - * In: msg: the message being signed (cannot be NULL) - * msglen: the length of the message being signed (at most 32) + * In: msg32: the 32-byte message hash being signed (cannot be NULL) * seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid) * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG) * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) @@ -92,19 +89,17 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( * Requires starting using SECP256K1_START_SIGN. */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign( - const unsigned char *msg, - int msglen, + const unsigned char *msg32, unsigned char *sig, int *siglen, const unsigned char *seckey, const unsigned char *nonce -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); /** Create a compact ECDSA signature (64 byte + recovery id). * Returns: 1: signature created * 0: nonce invalid, try another one - * In: msg: the message being signed (cannot be NULL) - * msglen: the length of the message being signed (at most 32) + * In: msg32: the 32-byte message hash being signed (cannot be NULL) * seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid) * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG) * Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL) @@ -112,19 +107,17 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign( * Requires starting using SECP256K1_START_SIGN. */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign_compact( - const unsigned char *msg, - int msglen, + const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Recover an ECDSA public key from a compact signature. * Returns: 1: public key successfully recovered (which guarantees a correct signature). * 0: otherwise. - * In: msg: the message assumed to be signed (cannot be NULL) - * msglen: the length of the message (at most 32) + * In: msg32: the 32-byte message hash assumed to be signed (cannot be NULL) * sig64: signature as 64 byte array (cannot be NULL) * compressed: whether to recover a compressed or uncompressed pubkey * recid: the recovery id (0-3, as returned by ecdsa_sign_compact) @@ -133,14 +126,13 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign_compact( * Requires starting using SECP256K1_START_VERIFY. */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact( - const unsigned char *msg, - int msglen, + const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Verify an ECDSA secret key. * Returns: 1: secret key is valid diff --git a/nasm_lt.sh b/nasm_lt.sh deleted file mode 100755 index 6cd73294c06..00000000000 --- a/nasm_lt.sh +++ /dev/null @@ -1,57 +0,0 @@ -#! /bin/sh -command="" -infile="" -o_opt=no -pic=no -while [ $# -gt 0 ]; do - case "$1" in - -DPIC|-fPIC|-fpic|-Kpic|-KPIC) - if [ "$pic" != "yes" ] ; then - command="$command -DPIC" - pic=yes - fi - ;; - -f|-fbin|-faout|-faoutb|-fcoff|-felf|-felf64|-fas86| \ - -fobj|-fwin32|-fwin64|-frdf|-fieee|-fmacho|-fmacho64) - # it's a file format specifier for nasm. - command="$command $1" - ;; - -f*) - # maybe a code-generation flag for gcc. - ;; - -[Ii]*) - incdir=`echo "$1" | sed 's/^-[Ii]//'` - if [ "x$incdir" = x -a "x$2" != x ] ; then - case "$2" in - -*) ;; - *) incdir="$2"; shift;; - esac - fi - if [ "x$incdir" != x ] ; then - # In the case of NASM, the trailing slash is necessary. - incdir=`echo "$incdir" | sed 's%/*$%/%'` - command="$command -I$incdir" - fi - ;; - -o*) - o_opt=yes - command="$command $1" - ;; - *.asm) - infile=$1 - command="$command $1" - ;; - *) - command="$command $1" - ;; - esac - shift -done -if [ "$o_opt" != yes ] ; then - # By default, NASM creates an output file - # in the same directory as the input file. - outfile="-o `echo $infile | sed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.o" - command="$command $outfile" -fi -echo $command -exec $command diff --git a/src/bench.h b/src/bench.h new file mode 100644 index 00000000000..668ec39f715 --- /dev/null +++ b/src/bench.h @@ -0,0 +1,37 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_BENCH_H_ +#define _SECP256K1_BENCH_H_ + +#include +#include +#include "sys/time.h" + +static double gettimedouble(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_usec * 0.000001 + tv.tv_sec; +} + +void run_benchmark(void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { + double min = HUGE_VAL; + double sum = 0.0; + double max = 0.0; + for (int i = 0; i < count; i++) { + if (setup) setup(data); + double begin = gettimedouble(); + benchmark(data); + double total = gettimedouble() - begin; + if (teardown) teardown(data); + if (total < min) min = total; + if (total > max) max = total; + sum += total; + } + printf("min %.3fus / avg %.3fus / max %.3fus\n", min * 1000000.0 / iter, (sum / count) * 1000000.0 / iter, max * 1000000.0 / iter); +} + +#endif diff --git a/src/bench_inv.c b/src/bench_inv.c index d6f664333fd..3bdedea30e4 100644 --- a/src/bench_inv.c +++ b/src/bench_inv.c @@ -12,30 +12,41 @@ #include "field_impl.h" #include "group_impl.h" #include "scalar_impl.h" +#include "bench.h" + +typedef struct { + secp256k1_scalar_t base, x; +} bench_inv_t; + +void bench_inv_setup(void* arg) { + bench_inv_t *data = (bench_inv_t*)arg; -int main(void) { static const unsigned char init[32] = { 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13, 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35, 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59, 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83 }; - static const unsigned char fini[32] = { - 0xba, 0x28, 0x58, 0xd8, 0xaa, 0x11, 0xd6, 0xf2, - 0xfa, 0xce, 0x50, 0xb1, 0x67, 0x19, 0xb1, 0xa6, - 0xe0, 0xaa, 0x84, 0x53, 0xf6, 0x80, 0xfc, 0x23, - 0x88, 0x3c, 0xd6, 0x74, 0x9f, 0x27, 0x09, 0x03 - }; - secp256k1_ge_start(); - secp256k1_scalar_t base, x; - secp256k1_scalar_set_b32(&base, init, NULL); - secp256k1_scalar_set_b32(&x, init, NULL); - for (int i=0; i<1000000; i++) { - secp256k1_scalar_inverse(&x, &x); - secp256k1_scalar_add(&x, &x, &base); + + secp256k1_scalar_set_b32(&data->base, init, NULL); + secp256k1_scalar_set_b32(&data->x, init, NULL); +} + +void bench_inv(void* arg) { + bench_inv_t *data = (bench_inv_t*)arg; + + for (int i=0; i<20000; i++) { + secp256k1_scalar_inverse(&data->x, &data->x); + secp256k1_scalar_add(&data->x, &data->x, &data->base); } - unsigned char res[32]; - secp256k1_scalar_get_b32(res, &x); - CHECK(memcmp(res, fini, 32) == 0); +} + +int main(void) { + secp256k1_ge_start(); + + bench_inv_t data; + run_benchmark(bench_inv, bench_inv_setup, NULL, &data, 10, 20000); + + secp256k1_ge_stop(); return 0; } diff --git a/src/bench_recover.c b/src/bench_recover.c new file mode 100644 index 00000000000..b1e0f33efa6 --- /dev/null +++ b/src/bench_recover.c @@ -0,0 +1,46 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include "include/secp256k1.h" +#include "util.h" +#include "bench.h" + +typedef struct { + unsigned char msg[32]; + unsigned char sig[64]; +} bench_recover_t; + +void bench_recover(void* arg) { + bench_recover_t *data = (bench_recover_t*)arg; + + unsigned char pubkey[33]; + for (int i=0; i<20000; i++) { + int pubkeylen = 33; + CHECK(secp256k1_ecdsa_recover_compact(data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2)); + for (int j = 0; j < 32; j++) { + data->sig[j + 32] = data->msg[j]; /* Move former message to S. */ + data->msg[j] = data->sig[j]; /* Move former R to message. */ + data->sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ + } + } +} + +void bench_recover_setup(void* arg) { + bench_recover_t *data = (bench_recover_t*)arg; + + for (int i = 0; i < 32; i++) data->msg[i] = 1 + i; + for (int i = 0; i < 64; i++) data->sig[i] = 65 + i; +} + +int main(void) { + secp256k1_start(SECP256K1_START_VERIFY); + + bench_recover_t data; + run_benchmark(bench_recover, bench_recover_setup, NULL, &data, 10, 20000); + + secp256k1_stop(); + return 0; +} diff --git a/src/bench_sign.c b/src/bench_sign.c index f01f11d689b..66e71e1ac42 100644 --- a/src/bench_sign.c +++ b/src/bench_sign.c @@ -3,46 +3,45 @@ * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#include -#include #include "include/secp256k1.h" #include "util.h" +#include "bench.h" + +typedef struct { + unsigned char msg[32]; + unsigned char nonce[32]; + unsigned char key[32]; +} bench_sign_t; + +static void bench_sign_setup(void* arg) { + bench_sign_t *data = (bench_sign_t*)arg; + + for (int i = 0; i < 32; i++) data->msg[i] = i + 1; + for (int i = 0; i < 32; i++) data->nonce[i] = i + 33; + for (int i = 0; i < 32; i++) data->key[i] = i + 65; +} + +static void bench_sign(void* arg) { + bench_sign_t *data = (bench_sign_t*)arg; + + unsigned char sig[64]; + for (int i=0; i<20000; i++) { + int recid = 0; + CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, data->nonce, &recid)); + for (int j = 0; j < 32; j++) { + data->nonce[j] = data->key[j]; /* Move former key to nonce */ + data->msg[j] = sig[j]; /* Move former R to message. */ + data->key[j] = sig[j + 32]; /* Move former S to key. */ + } + } +} int main(void) { secp256k1_start(SECP256K1_START_SIGN); - unsigned char msg[32]; - unsigned char nonce[32]; - unsigned char key[32]; - - for (int i = 0; i < 32; i++) msg[i] = i + 1; - for (int i = 0; i < 32; i++) nonce[i] = i + 33; - for (int i = 0; i < 32; i++) key[i] = i + 65; - - unsigned char sig[64]; - - for (int i=0; i<1000000; i++) { - int recid = 0; - CHECK(secp256k1_ecdsa_sign_compact(msg, 32, sig, key, nonce, &recid)); - for (int j = 0; j < 32; j++) { - nonce[j] = key[j]; /* Move former key to nonce */ - msg[j] = sig[j]; /* Move former R to message. */ - key[j] = sig[j + 32]; /* Move former S to key. */ - } - } - - static const unsigned char fini[64] = { - 0x92, 0x03, 0xef, 0xf1, 0x58, 0x0b, 0x49, 0x8d, - 0x22, 0x3d, 0x49, 0x0e, 0xbf, 0x26, 0x50, 0x0e, - 0x2d, 0x62, 0x90, 0xd7, 0x82, 0xbd, 0x3d, 0x5c, - 0xa9, 0x10, 0xa5, 0x49, 0xb1, 0xd8, 0x8c, 0xc0, - 0x5b, 0x5e, 0x9e, 0x68, 0x51, 0x3d, 0xe8, 0xec, - 0x82, 0x30, 0x82, 0x88, 0x8c, 0xfd, 0xe7, 0x71, - 0x15, 0x92, 0xfc, 0x14, 0x59, 0x78, 0x31, 0xb3, - 0xf6, 0x07, 0x91, 0x18, 0x00, 0x8d, 0x4c, 0xb2 - }; - CHECK(memcmp(sig, fini, 64) == 0); + bench_sign_t data; + run_benchmark(bench_sign, bench_sign_setup, NULL, &data, 10, 20000); secp256k1_stop(); return 0; diff --git a/src/bench_verify.c b/src/bench_verify.c index 690595516d7..b123c4087d6 100644 --- a/src/bench_verify.c +++ b/src/bench_verify.c @@ -9,35 +9,46 @@ #include "include/secp256k1.h" #include "util.h" +#include "bench.h" + +typedef struct { + unsigned char msg[32]; + unsigned char key[32]; + unsigned char nonce[32]; + unsigned char sig[72]; + int siglen; + unsigned char pubkey[33]; + int pubkeylen; +} benchmark_verify_t; + +static void benchmark_verify(void* arg) { + benchmark_verify_t* data = (benchmark_verify_t*)arg; + + for (int i=0; i<20000; i++) { + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + CHECK(secp256k1_ecdsa_verify(data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (i == 0)); + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + } +} int main(void) { - secp256k1_start(SECP256K1_START_VERIFY); + secp256k1_start(SECP256K1_START_VERIFY | SECP256K1_START_SIGN); - unsigned char msg[32]; - unsigned char sig[64]; + benchmark_verify_t data; - for (int i = 0; i < 32; i++) msg[i] = 1 + i; - for (int i = 0; i < 64; i++) sig[i] = 65 + i; + for (int i = 0; i < 32; i++) data.msg[i] = 1 + i; + for (int i = 0; i < 32; i++) data.key[i] = 33 + i; + for (int i = 0; i < 32; i++) data.nonce[i] = 65 + i; + data.siglen = 72; + CHECK(secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, data.nonce)); + data.pubkeylen = 33; + CHECK(secp256k1_ec_pubkey_create(data.pubkey, &data.pubkeylen, data.key, 1)); - unsigned char pubkey[33]; - for (int i=0; i<1000000; i++) { - int pubkeylen = 33; - CHECK(secp256k1_ecdsa_recover_compact(msg, 32, sig, pubkey, &pubkeylen, 1, i % 2)); - for (int j = 0; j < 32; j++) { - sig[j + 32] = msg[j]; /* Move former message to S. */ - msg[j] = sig[j]; /* Move former R to message. */ - sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ - } - } - - static const unsigned char fini[33] = { - 0x02, - 0x52, 0x63, 0xae, 0x9a, 0x9d, 0x47, 0x1f, 0x1a, - 0xb2, 0x36, 0x65, 0x89, 0x11, 0xe7, 0xcc, 0x86, - 0xa3, 0xab, 0x97, 0xb6, 0xf1, 0xaf, 0xfd, 0x8f, - 0x9b, 0x38, 0xb6, 0x18, 0x55, 0xe5, 0xc2, 0x43 - }; - CHECK(memcmp(fini, pubkey, 33) == 0); + run_benchmark(benchmark_verify, NULL, NULL, &data, 10, 20000); secp256k1_stop(); return 0; diff --git a/src/ecdsa_impl.h b/src/ecdsa_impl.h index a951d0b4adf..8825d05fed9 100644 --- a/src/ecdsa_impl.h +++ b/src/ecdsa_impl.h @@ -27,7 +27,7 @@ static void secp256k1_ecdsa_start(void) { return; /* Allocate. */ - secp256k1_ecdsa_consts_t *ret = (secp256k1_ecdsa_consts_t*)malloc(sizeof(secp256k1_ecdsa_consts_t)); + secp256k1_ecdsa_consts_t *ret = (secp256k1_ecdsa_consts_t*)checked_malloc(sizeof(secp256k1_ecdsa_consts_t)); static const unsigned char order[] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, @@ -38,7 +38,7 @@ static void secp256k1_ecdsa_start(void) { secp256k1_fe_set_b32(&ret->order_as_fe, order); secp256k1_fe_negate(&ret->p_minus_order, &ret->order_as_fe, 1); - secp256k1_fe_normalize(&ret->p_minus_order); + secp256k1_fe_normalize_var(&ret->p_minus_order); /* Set the global pointer. */ secp256k1_ecdsa_consts = ret; @@ -122,7 +122,7 @@ static int secp256k1_ecdsa_sig_recompute(secp256k1_scalar_t *r2, const secp256k1 secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1); if (!secp256k1_gej_is_infinity(&pr)) { secp256k1_fe_t xr; secp256k1_gej_get_x_var(&xr, &pr); - secp256k1_fe_normalize(&xr); + secp256k1_fe_normalize_var(&xr); unsigned char xrb[32]; secp256k1_fe_get_b32(xrb, &xr); secp256k1_scalar_set_b32(r2, xrb, NULL); ret = 1; @@ -144,7 +144,7 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256 secp256k1_fe_add(&fx, &secp256k1_ecdsa_consts->order_as_fe); } secp256k1_ge_t x; - if (!secp256k1_ge_set_xo(&x, &fx, recid & 1)) + if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) return 0; secp256k1_gej_t xj; secp256k1_gej_set_ge(&xj, &x); diff --git a/src/eckey_impl.h b/src/eckey_impl.h index 0f218ced9e8..b3fa7d9bd21 100644 --- a/src/eckey_impl.h +++ b/src/eckey_impl.h @@ -17,7 +17,7 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) { if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) { secp256k1_fe_t x; - return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo(elem, &x, pub[0] == 0x03); + return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03); } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { secp256k1_fe_t x, y; if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { @@ -26,7 +26,7 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned cha secp256k1_ge_set_xy(elem, &x, &y); if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) return 0; - return secp256k1_ge_is_valid(elem); + return secp256k1_ge_is_valid_var(elem); } else { return 0; } @@ -36,8 +36,8 @@ static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char if (secp256k1_ge_is_infinity(elem)) { return 0; } - secp256k1_fe_normalize(&elem->x); - secp256k1_fe_normalize(&elem->y); + secp256k1_fe_normalize_var(&elem->x); + secp256k1_fe_normalize_var(&elem->y); secp256k1_fe_get_b32(&pub[1], &elem->x); if (compressed) { *size = 33; diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index af0ead522d4..5a5b16ce14c 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -34,7 +34,7 @@ static void secp256k1_ecmult_gen_start(void) { return; /* Allocate the precomputation table. */ - secp256k1_ecmult_gen_consts_t *ret = (secp256k1_ecmult_gen_consts_t*)malloc(sizeof(secp256k1_ecmult_gen_consts_t)); + secp256k1_ecmult_gen_consts_t *ret = (secp256k1_ecmult_gen_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_gen_consts_t)); /* get the generator */ const secp256k1_ge_t *g = &secp256k1_ge_consts->g; @@ -47,7 +47,7 @@ static void secp256k1_ecmult_gen_start(void) { secp256k1_fe_t nums_x; VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32)); secp256k1_ge_t nums_ge; - VERIFY_CHECK(secp256k1_ge_set_xo(&nums_ge, &nums_x, 0)); + VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0)); secp256k1_gej_set_ge(&nums_gej, &nums_ge); /* Add G to make the bits in x uniformly distributed. */ secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, g); @@ -73,7 +73,7 @@ static void secp256k1_ecmult_gen_start(void) { secp256k1_gej_double_var(&numsbase, &numsbase); if (j == 62) { /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ - secp256k1_gej_neg(&numsbase, &numsbase); + secp256k1_gej_neg_var(&numsbase, &numsbase); secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej); } } diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h index 445b81593f8..65367710469 100644 --- a/src/ecmult_impl.h +++ b/src/ecmult_impl.h @@ -15,11 +15,13 @@ #define WINDOW_A 5 /** larger numbers may result in slightly better performance, at the cost of - exponentially larger precomputed tables. WINDOW_G == 14 results in 640 KiB. */ + exponentially larger precomputed tables. */ #ifdef USE_ENDOMORPHISM -#define WINDOW_G 14 -#else +/** Two tables for window size 15: 1.375 MiB. */ #define WINDOW_G 15 +#else +/** One table for window size 16: 1.375 MiB. */ +#define WINDOW_G 16 #endif /** Fill a table 'pre' with precomputed odd multiples of a. W determines the size of the table. @@ -43,13 +45,14 @@ static void secp256k1_ecmult_table_precomp_gej_var(secp256k1_gej_t *pre, const s static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const secp256k1_gej_t *a, int w) { const int table_size = 1 << (w-2); - secp256k1_gej_t prej[table_size]; + secp256k1_gej_t *prej = checked_malloc(sizeof(secp256k1_gej_t) * table_size); prej[0] = *a; secp256k1_gej_t d; secp256k1_gej_double_var(&d, a); for (int i=1; ig; diff --git a/src/field.h b/src/field.h index 0cdf0fb4792..53aa29e13fd 100644 --- a/src/field.h +++ b/src/field.h @@ -50,6 +50,9 @@ static void secp256k1_fe_stop(void); /** Normalize a field element. */ static void secp256k1_fe_normalize(secp256k1_fe_t *r); +/** Normalize a field element, without constant-time guarantee. */ +static void secp256k1_fe_normalize_var(secp256k1_fe_t *r); + /** Set a field element equal to a small integer. Resulting field element is normalized. */ static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a); @@ -93,7 +96,7 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a); /** Sets a field element to be the (modular) square root (if any exist) of another. Requires the * input's magnitude to be at most 8. The output magnitude is 1 (but not guaranteed to be * normalized). Return value indicates whether a square root was found. */ -static int secp256k1_fe_sqrt(secp256k1_fe_t *r, const secp256k1_fe_t *a); +static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a); /** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ @@ -105,9 +108,6 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a); /** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and * outputs must not overlap in memory. */ -static void secp256k1_fe_inv_all(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]); - -/** Potentially faster version of secp256k1_fe_inv_all, without constant-time guarantee. */ static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]); /** Convert a field element to a hexadecimal string. */ diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index c4403fba22d..d20229cda6b 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -103,6 +103,62 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { #endif } +static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + uint32_t m; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) + & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); + + if (x) { + t0 += 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; + + /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ + VERIFY_CHECK(t9 >> 22 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t9 &= 0x03FFFFFUL; + } + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { r->n[0] = a; r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; @@ -271,7 +327,7 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1 #define VERIFY_BITS(x, n) do { } while(0) #endif -SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b, uint32_t *r) { +SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) { VERIFY_BITS(a[0], 30); VERIFY_BITS(a[1], 30); VERIFY_BITS(a[2], 30); @@ -598,7 +654,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint32_t *a, const uin /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ } -SECP256K1_INLINE static void secp256k1_fe_sqr_inner(const uint32_t *a, uint32_t *r) { +SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) { VERIFY_BITS(a[0], 30); VERIFY_BITS(a[1], 30); VERIFY_BITS(a[2], 30); @@ -879,7 +935,7 @@ static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const s secp256k1_fe_verify(b); VERIFY_CHECK(r != b); #endif - secp256k1_fe_mul_inner(a->n, b->n, r->n); + secp256k1_fe_mul_inner(r->n, a->n, b->n); #ifdef VERIFY r->magnitude = 1; r->normalized = 0; @@ -892,7 +948,7 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { VERIFY_CHECK(a->magnitude <= 8); secp256k1_fe_verify(a); #endif - secp256k1_fe_sqr_inner(a->n, r->n); + secp256k1_fe_sqr_inner(r->n, a->n); #ifdef VERIFY r->magnitude = 1; r->normalized = 0; diff --git a/src/field_5x52_asm.asm b/src/field_5x52_asm.asm deleted file mode 100644 index 5e785f76305..00000000000 --- a/src/field_5x52_asm.asm +++ /dev/null @@ -1,469 +0,0 @@ - ;; Added by Diederik Huys, March 2013 - ;; - ;; Provided public procedures: - ;; secp256k1_fe_mul_inner - ;; secp256k1_fe_sqr_inner - ;; - ;; Needed tools: YASM (http://yasm.tortall.net) - ;; - ;; - - BITS 64 - -%ifidn __OUTPUT_FORMAT__,macho64 -%define SYM(x) _ %+ x -%else -%define SYM(x) x -%endif - - ;; Procedure ExSetMult - ;; Register Layout: - ;; INPUT: rdi = a->n - ;; rsi = b->n - ;; rdx = r->a - ;; - ;; INTERNAL: rdx:rax = multiplication accumulator - ;; r9:r8 = c - ;; r10-r13 = t0-t3 - ;; r14 = b.n[0] / t4 - ;; r15 = b.n[1] / t5 - ;; rbx = b.n[2] / t6 - ;; rcx = b.n[3] / t7 - ;; rbp = Constant 0FFFFFFFFFFFFFh / t8 - ;; rsi = b.n / b.n[4] / t9 - - GLOBAL SYM(secp256k1_fe_mul_inner) - ALIGN 32 -SYM(secp256k1_fe_mul_inner): - push rbp - push rbx - push r12 - push r13 - push r14 - push r15 - push rdx - mov r14,[rsi+8*0] ; preload b.n[0]. This will be the case until - ; b.n[0] is no longer needed, then we reassign - ; r14 to t4 - ;; c=a.n[0] * b.n[0] - mov rax,[rdi+0*8] ; load a.n[0] - mov rbp,0FFFFFFFFFFFFFh - mul r14 ; rdx:rax=a.n[0]*b.n[0] - mov r15,[rsi+1*8] - mov r10,rbp ; load modulus into target register for t0 - mov r8,rax - and r10,rax ; only need lower qword of c - shrd r8,rdx,52 - xor r9,r9 ; c < 2^64, so we ditch the HO part - - ;; c+=a.n[0] * b.n[1] + a.n[1] * b.n[0] - mov rax,[rdi+0*8] - mul r15 - add r8,rax - adc r9,rdx - - mov rax,[rdi+1*8] - mul r14 - mov r11,rbp - mov rbx,[rsi+2*8] - add r8,rax - adc r9,rdx - and r11,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=a.n[0 1 2] * b.n[2 1 0] - mov rax,[rdi+0*8] - mul rbx - add r8,rax - adc r9,rdx - - mov rax,[rdi+1*8] - mul r15 - add r8,rax - adc r9,rdx - - mov rax,[rdi+2*8] - mul r14 - mov r12,rbp - mov rcx,[rsi+3*8] - add r8,rax - adc r9,rdx - and r12,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=a.n[0 1 2 3] * b.n[3 2 1 0] - mov rax,[rdi+0*8] - mul rcx - add r8,rax - adc r9,rdx - - mov rax,[rdi+1*8] - mul rbx - add r8,rax - adc r9,rdx - - mov rax,[rdi+2*8] - mul r15 - add r8,rax - adc r9,rdx - - mov rax,[rdi+3*8] - mul r14 - mov r13,rbp - mov rsi,[rsi+4*8] ; load b.n[4] and destroy pointer - add r8,rax - adc r9,rdx - and r13,r8 - - shrd r8,r9,52 - xor r9,r9 - - - ;; c+=a.n[0 1 2 3 4] * b.n[4 3 2 1 0] - mov rax,[rdi+0*8] - mul rsi - add r8,rax - adc r9,rdx - - mov rax,[rdi+1*8] - mul rcx - add r8,rax - adc r9,rdx - - mov rax,[rdi+2*8] - mul rbx - add r8,rax - adc r9,rdx - - mov rax,[rdi+3*8] - mul r15 - add r8,rax - adc r9,rdx - - mov rax,[rdi+4*8] - mul r14 - mov r14,rbp ; load modulus into t4 and destroy a.n[0] - add r8,rax - adc r9,rdx - and r14,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=a.n[1 2 3 4] * b.n[4 3 2 1] - mov rax,[rdi+1*8] - mul rsi - add r8,rax - adc r9,rdx - - mov rax,[rdi+2*8] - mul rcx - add r8,rax - adc r9,rdx - - mov rax,[rdi+3*8] - mul rbx - add r8,rax - adc r9,rdx - - mov rax,[rdi+4*8] - mul r15 - mov r15,rbp - add r8,rax - adc r9,rdx - - and r15,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=a.n[2 3 4] * b.n[4 3 2] - mov rax,[rdi+2*8] - mul rsi - add r8,rax - adc r9,rdx - - mov rax,[rdi+3*8] - mul rcx - add r8,rax - adc r9,rdx - - mov rax,[rdi+4*8] - mul rbx - mov rbx,rbp - add r8,rax - adc r9,rdx - - and rbx,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=a.n[3 4] * b.n[4 3] - mov rax,[rdi+3*8] - mul rsi - add r8,rax - adc r9,rdx - - mov rax,[rdi+4*8] - mul rcx - mov rcx,rbp - add r8,rax - adc r9,rdx - and rcx,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=a.n[4] * b.n[4] - mov rax,[rdi+4*8] - mul rsi - ;; mov rbp,rbp ; modulus already there! - add r8,rax - adc r9,rdx - and rbp,r8 - shrd r8,r9,52 - xor r9,r9 - - mov rsi,r8 ; load c into t9 and destroy b.n[4] - - ;; ******************************************************* -common_exit_norm: - mov rdi,01000003D10h ; load constant - - mov rax,r15 ; get t5 - mul rdi - add rax,r10 ; +t0 - adc rdx,0 - mov r10,0FFFFFFFFFFFFFh ; modulus. Sadly, we ran out of registers! - mov r8,rax ; +c - and r10,rax - shrd r8,rdx,52 - xor r9,r9 - - mov rax,rbx ; get t6 - mul rdi - add rax,r11 ; +t1 - adc rdx,0 - mov r11,0FFFFFFFFFFFFFh ; modulus - add r8,rax ; +c - adc r9,rdx - and r11,r8 - shrd r8,r9,52 - xor r9,r9 - - mov rax,rcx ; get t7 - mul rdi - add rax,r12 ; +t2 - adc rdx,0 - pop rbx ; retrieve pointer to this.n - mov r12,0FFFFFFFFFFFFFh ; modulus - add r8,rax ; +c - adc r9,rdx - and r12,r8 - mov [rbx+2*8],r12 ; mov into this.n[2] - shrd r8,r9,52 - xor r9,r9 - - mov rax,rbp ; get t8 - mul rdi - add rax,r13 ; +t3 - adc rdx,0 - mov r13,0FFFFFFFFFFFFFh ; modulus - add r8,rax ; +c - adc r9,rdx - and r13,r8 - mov [rbx+3*8],r13 ; -> this.n[3] - shrd r8,r9,52 - xor r9,r9 - - mov rax,rsi ; get t9 - mul rdi - add rax,r14 ; +t4 - adc rdx,0 - mov r14,0FFFFFFFFFFFFh ; !!! - add r8,rax ; +c - adc r9,rdx - and r14,r8 - mov [rbx+4*8],r14 ; -> this.n[4] - shrd r8,r9,48 ; !!! - xor r9,r9 - - mov rax,01000003D1h - mul r8 - add rax,r10 - adc rdx,0 - mov r10,0FFFFFFFFFFFFFh ; modulus - mov r8,rax - and rax,r10 - shrd r8,rdx,52 - mov [rbx+0*8],rax ; -> this.n[0] - add r8,r11 - mov [rbx+1*8],r8 ; -> this.n[1] - - pop r15 - pop r14 - pop r13 - pop r12 - pop rbx - pop rbp - ret - - - ;; PROC ExSetSquare - ;; Register Layout: - ;; INPUT: rdi = a.n - ;; rsi = this.a - ;; INTERNAL: rdx:rax = multiplication accumulator - ;; r9:r8 = c - ;; r10-r13 = t0-t3 - ;; r14 = a.n[0] / t4 - ;; r15 = a.n[1] / t5 - ;; rbx = a.n[2] / t6 - ;; rcx = a.n[3] / t7 - ;; rbp = 0FFFFFFFFFFFFFh / t8 - ;; rsi = a.n[4] / t9 - GLOBAL SYM(secp256k1_fe_sqr_inner) - ALIGN 32 -SYM(secp256k1_fe_sqr_inner): - push rbp - push rbx - push r12 - push r13 - push r14 - push r15 - push rsi - mov rbp,0FFFFFFFFFFFFFh - - ;; c=a.n[0] * a.n[0] - mov r14,[rdi+0*8] ; r14=a.n[0] - mov r10,rbp ; modulus - mov rax,r14 - mul rax - mov r15,[rdi+1*8] ; a.n[1] - add r14,r14 ; r14=2*a.n[0] - mov r8,rax - and r10,rax ; only need lower qword - shrd r8,rdx,52 - xor r9,r9 - - ;; c+=2*a.n[0] * a.n[1] - mov rax,r14 ; r14=2*a.n[0] - mul r15 - mov rbx,[rdi+2*8] ; rbx=a.n[2] - mov r11,rbp ; modulus - add r8,rax - adc r9,rdx - and r11,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=2*a.n[0]*a.n[2]+a.n[1]*a.n[1] - mov rax,r14 - mul rbx - add r8,rax - adc r9,rdx - - mov rax,r15 - mov r12,rbp ; modulus - mul rax - mov rcx,[rdi+3*8] ; rcx=a.n[3] - add r15,r15 ; r15=a.n[1]*2 - add r8,rax - adc r9,rdx - and r12,r8 ; only need lower dword - shrd r8,r9,52 - xor r9,r9 - - ;; c+=2*a.n[0]*a.n[3]+2*a.n[1]*a.n[2] - mov rax,r14 - mul rcx - add r8,rax - adc r9,rdx - - mov rax,r15 ; rax=2*a.n[1] - mov r13,rbp ; modulus - mul rbx - mov rsi,[rdi+4*8] ; rsi=a.n[4] - add r8,rax - adc r9,rdx - and r13,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=2*a.n[0]*a.n[4]+2*a.n[1]*a.n[3]+a.n[2]*a.n[2] - mov rax,r14 ; last time we need 2*a.n[0] - mul rsi - add r8,rax - adc r9,rdx - - mov rax,r15 - mul rcx - mov r14,rbp ; modulus - add r8,rax - adc r9,rdx - - mov rax,rbx - mul rax - add rbx,rbx ; rcx=2*a.n[2] - add r8,rax - adc r9,rdx - and r14,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=2*a.n[1]*a.n[4]+2*a.n[2]*a.n[3] - mov rax,r15 ; last time we need 2*a.n[1] - mul rsi - add r8,rax - adc r9,rdx - - mov rax,rbx - mul rcx - mov r15,rbp ; modulus - add r8,rax - adc r9,rdx - and r15,r8 - shrd r8,r9,52 - xor r9,r9 - - ;; c+=2*a.n[2]*a.n[4]+a.n[3]*a.n[3] - mov rax,rbx ; last time we need 2*a.n[2] - mul rsi - add r8,rax - adc r9,rdx - - mov rax,rcx ; a.n[3] - mul rax - mov rbx,rbp ; modulus - add r8,rax - adc r9,rdx - and rbx,r8 ; only need lower dword - lea rax,[2*rcx] - shrd r8,r9,52 - xor r9,r9 - - ;; c+=2*a.n[3]*a.n[4] - mul rsi - mov rcx,rbp ; modulus - add r8,rax - adc r9,rdx - and rcx,r8 ; only need lower dword - shrd r8,r9,52 - xor r9,r9 - - ;; c+=a.n[4]*a.n[4] - mov rax,rsi - mul rax - ;; mov rbp,rbp ; modulus is already there! - add r8,rax - adc r9,rdx - and rbp,r8 - shrd r8,r9,52 - xor r9,r9 - - mov rsi,r8 - - ;; ******************************************************* - jmp common_exit_norm - end - - diff --git a/src/field_5x52_asm_impl.h b/src/field_5x52_asm_impl.h index f29605b11b9..98cc004bf04 100644 --- a/src/field_5x52_asm_impl.h +++ b/src/field_5x52_asm_impl.h @@ -1,13 +1,502 @@ /********************************************************************** - * Copyright (c) 2013 Pieter Wuille * + * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ +/** + * Changelog: + * - March 2013, Diederik Huys: original version + * - November 2014, Pieter Wuille: updated to use Peter Dettman's parallel multiplication algorithm + * - December 2014, Pieter Wuille: converted from YASM to GCC inline assembly + */ + #ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_ #define _SECP256K1_FIELD_INNER5X52_IMPL_H_ -void __attribute__ ((sysv_abi)) secp256k1_fe_mul_inner(const uint64_t *a, const uint64_t *b, uint64_t *r); -void __attribute__ ((sysv_abi)) secp256k1_fe_sqr_inner(const uint64_t *a, uint64_t *r); +SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { +/** + * Registers: rdx:rax = multiplication accumulator + * r9:r8 = c + * r15:rcx = d + * r10-r14 = a0-a4 + * rbx = b + * rdi = r + * rsi = a / t? + */ + uint64_t tmp1, tmp2, tmp3; +__asm__ __volatile__( + "movq 0(%%rsi),%%r10\n" + "movq 8(%%rsi),%%r11\n" + "movq 16(%%rsi),%%r12\n" + "movq 24(%%rsi),%%r13\n" + "movq 32(%%rsi),%%r14\n" + + /* d += a3 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r13\n" + "movq %%rax,%%rcx\n" + "movq %%rdx,%%r15\n" + /* d += a2 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a1 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d = a0 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c = a4 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r14\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += (c & M) * R */ + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* t3 (tmp1) = d & M */ + "movq %%rcx,%%rsi\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rsi\n" + "movq %%rsi,%q1\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* d += a4 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a2 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a1 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a0 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += c * R */ + "movq %%r8,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* t4 = d & M (%%rsi) */ + "movq %%rcx,%%rsi\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* tx = t4 >> 48 (tmp3) */ + "movq %%rsi,%%rax\n" + "shrq $48,%%rax\n" + "movq %%rax,%q3\n" + /* t4 &= (M >> 4) (tmp2) */ + "movq $0xffffffffffff,%%rax\n" + "andq %%rax,%%rsi\n" + "movq %%rsi,%q2\n" + /* c = a0 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r10\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += a4 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a2 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a1 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* u0 = d & M (%%rsi) */ + "movq %%rcx,%%rsi\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* u0 = (u0 << 4) | tx (%%rsi) */ + "shlq $4,%%rsi\n" + "movq %q3,%%rax\n" + "orq %%rax,%%rsi\n" + /* c += u0 * (R >> 4) */ + "movq $0x1000003d1,%%rax\n" + "mulq %%rsi\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[0] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,0(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += a1 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* c += a0 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d += a4 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a2 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c += (d & M) * R */ + "movq %%rcx,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* r[1] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,8(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += a2 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* c += a1 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* c += a0 * b2 (last use of %%r10 = a0) */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* fetch t3 (%%r10, overwrites a0), t4 (%%rsi) */ + "movq %q2,%%rsi\n" + "movq %q1,%%r10\n" + /* d += a4 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c += (d & M) * R */ + "movq %%rcx,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 (%%rcx only) */ + "shrdq $52,%%r15,%%rcx\n" + /* r[2] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,16(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += t3 */ + "addq %%r10,%%r8\n" + /* c += d * R */ + "movq %%rcx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[3] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,24(%%rdi)\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* c += t4 (%%r8 only) */ + "addq %%rsi,%%r8\n" + /* r[4] = c */ + "movq %%r8,32(%%rdi)\n" +: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) +: "b"(b), "D"(r) +: "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" +); +} + +SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { +/** + * Registers: rdx:rax = multiplication accumulator + * r9:r8 = c + * rcx:rbx = d + * r10-r14 = a0-a4 + * r15 = M (0xfffffffffffff) + * rdi = r + * rsi = a / t? + */ + uint64_t tmp1, tmp2, tmp3; +__asm__ __volatile__( + "movq 0(%%rsi),%%r10\n" + "movq 8(%%rsi),%%r11\n" + "movq 16(%%rsi),%%r12\n" + "movq 24(%%rsi),%%r13\n" + "movq 32(%%rsi),%%r14\n" + "movq $0xfffffffffffff,%%r15\n" + + /* d = (a0*2) * a3 */ + "leaq (%%r10,%%r10,1),%%rax\n" + "mulq %%r13\n" + "movq %%rax,%%rbx\n" + "movq %%rdx,%%rcx\n" + /* d += (a1*2) * a2 */ + "leaq (%%r11,%%r11,1),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c = a4 * a4 */ + "movq %%r14,%%rax\n" + "mulq %%r14\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += (c & M) * R */ + "andq %%r15,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* t3 (tmp1) = d & M */ + "movq %%rbx,%%rsi\n" + "andq %%r15,%%rsi\n" + "movq %%rsi,%q1\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* a4 *= 2 */ + "addq %%r14,%%r14\n" + /* d += a0 * a4 */ + "movq %%r10,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d+= (a1*2) * a3 */ + "leaq (%%r11,%%r11,1),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += a2 * a2 */ + "movq %%r12,%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += c * R */ + "movq %%r8,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* t4 = d & M (%%rsi) */ + "movq %%rbx,%%rsi\n" + "andq %%r15,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* tx = t4 >> 48 (tmp3) */ + "movq %%rsi,%%rax\n" + "shrq $48,%%rax\n" + "movq %%rax,%q3\n" + /* t4 &= (M >> 4) (tmp2) */ + "movq $0xffffffffffff,%%rax\n" + "andq %%rax,%%rsi\n" + "movq %%rsi,%q2\n" + /* c = a0 * a0 */ + "movq %%r10,%%rax\n" + "mulq %%r10\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += a1 * a4 */ + "movq %%r11,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += (a2*2) * a3 */ + "leaq (%%r12,%%r12,1),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* u0 = d & M (%%rsi) */ + "movq %%rbx,%%rsi\n" + "andq %%r15,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* u0 = (u0 << 4) | tx (%%rsi) */ + "shlq $4,%%rsi\n" + "movq %q3,%%rax\n" + "orq %%rax,%%rsi\n" + /* c += u0 * (R >> 4) */ + "movq $0x1000003d1,%%rax\n" + "mulq %%rsi\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[0] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,0(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* a0 *= 2 */ + "addq %%r10,%%r10\n" + /* c += a0 * a1 */ + "movq %%r10,%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d += a2 * a4 */ + "movq %%r12,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += a3 * a3 */ + "movq %%r13,%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c += (d & M) * R */ + "movq %%rbx,%%rax\n" + "andq %%r15,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* r[1] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,8(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += a0 * a2 (last use of %%r10) */ + "movq %%r10,%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* fetch t3 (%%r10, overwrites a0),t4 (%%rsi) */ + "movq %q2,%%rsi\n" + "movq %q1,%%r10\n" + /* c += a1 * a1 */ + "movq %%r11,%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d += a3 * a4 */ + "movq %%r13,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c += (d & M) * R */ + "movq %%rbx,%%rax\n" + "andq %%r15,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 (%%rbx only) */ + "shrdq $52,%%rcx,%%rbx\n" + /* r[2] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,16(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += t3 */ + "addq %%r10,%%r8\n" + /* c += d * R */ + "movq %%rbx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[3] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,24(%%rdi)\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* c += t4 (%%r8 only) */ + "addq %%rsi,%%r8\n" + /* r[4] = c */ + "movq %%r8,32(%%rdi)\n" +: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) +: "D"(r) +: "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" +); +} #endif diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index 75b210eaf68..63176d6de40 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -102,6 +102,50 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { #endif } +static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + uint64_t m; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL) + & (t0 >= 0xFFFFEFFFFFC2FULL)); + + if (x) { + t0 += 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; + + /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */ + VERIFY_CHECK(t4 >> 48 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t4 &= 0x0FFFFFFFFFFFFULL; + } + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { r->n[0] = a; r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; @@ -255,7 +299,7 @@ static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const s secp256k1_fe_verify(b); VERIFY_CHECK(r != b); #endif - secp256k1_fe_mul_inner(a->n, b->n, r->n); + secp256k1_fe_mul_inner(r->n, a->n, b->n); #ifdef VERIFY r->magnitude = 1; r->normalized = 0; @@ -268,7 +312,7 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { VERIFY_CHECK(a->magnitude <= 8); secp256k1_fe_verify(a); #endif - secp256k1_fe_sqr_inner(a->n, r->n); + secp256k1_fe_sqr_inner(r->n, a->n); #ifdef VERIFY r->magnitude = 1; r->normalized = 0; diff --git a/src/field_5x52_int128_impl.h b/src/field_5x52_int128_impl.h index e552fb4319e..ec631833cfa 100644 --- a/src/field_5x52_int128_impl.h +++ b/src/field_5x52_int128_impl.h @@ -15,7 +15,7 @@ #define VERIFY_BITS(x, n) do { } while(0) #endif -SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b, uint64_t *r) { +SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { VERIFY_BITS(a[0], 56); VERIFY_BITS(a[1], 56); VERIFY_BITS(a[2], 56); @@ -152,7 +152,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uin /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ } -SECP256K1_INLINE static void secp256k1_fe_sqr_inner(const uint64_t *a, uint64_t *r) { +SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { VERIFY_BITS(a[0], 56); VERIFY_BITS(a[1], 56); VERIFY_BITS(a[2], 56); diff --git a/src/field_gmp_impl.h b/src/field_gmp_impl.h index 8af7dd68f8e..73a55c4f00d 100644 --- a/src/field_gmp_impl.h +++ b/src/field_gmp_impl.h @@ -46,6 +46,10 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { mpn_sub(r->n, r->n, FIELD_LIMBS, secp256k1_field_p, FIELD_LIMBS); } +static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { + secp256k1_fe_normalize(r); +} + SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { r->n[0] = a; for (int i=1; i 0) { - int j = i--; - secp256k1_fe_mul(&r[j], &r[i], &u); - secp256k1_fe_mul(&u, &u, &a[j]); - } - - r[0] = u; -} - static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]) { if (len < 1) return; @@ -277,7 +253,7 @@ static void secp256k1_fe_start(void) { #endif if (secp256k1_fe_consts == NULL) { secp256k1_fe_inner_start(); - secp256k1_fe_consts_t *ret = (secp256k1_fe_consts_t*)malloc(sizeof(secp256k1_fe_consts_t)); + secp256k1_fe_consts_t *ret = (secp256k1_fe_consts_t*)checked_malloc(sizeof(secp256k1_fe_consts_t)); #ifndef USE_NUM_NONE secp256k1_num_set_bin(&ret->p, secp256k1_fe_consts_p, sizeof(secp256k1_fe_consts_p)); #endif diff --git a/src/group.h b/src/group.h index 0f14bd25f30..ecfebcdc0c0 100644 --- a/src/group.h +++ b/src/group.h @@ -51,15 +51,16 @@ static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, cons /** Set a group element (affine) equal to the point with the given X coordinate, and given oddness * for Y. Return value indicates whether the result is valid. */ -static int secp256k1_ge_set_xo(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd); +static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd); /** Check whether a group element is the point at infinity. */ static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a); /** Check whether a group element is valid (i.e., on the curve). */ -static int secp256k1_ge_is_valid(const secp256k1_ge_t *a); +static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a); static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a); +static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a); /** Get a hex representation of a point. *rlen will be overwritten with the real length. */ static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a); @@ -84,7 +85,7 @@ static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a); static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a); /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ -static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a); +static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a); /** Check whether a group element is the point at infinity. */ static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a); diff --git a/src/group_impl.h b/src/group_impl.h index cbd0d8c4fc6..1ab5d5fe7bf 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -28,13 +28,17 @@ static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a) { } static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) { - r->infinity = a->infinity; - r->x = a->x; - r->y = a->y; + *r = *a; secp256k1_fe_normalize(&r->y); secp256k1_fe_negate(&r->y, &r->y, 1); } +static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a) { + *r = *a; + secp256k1_fe_normalize_var(&r->y); + secp256k1_fe_negate(&r->y, &r->y, 1); +} + static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a) { char cx[65]; int lx=65; char cy[65]; int ly=65; @@ -85,15 +89,16 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) { static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t r[len], const secp256k1_gej_t a[len]) { size_t count = 0; - secp256k1_fe_t az[len]; + secp256k1_fe_t *az = checked_malloc(sizeof(secp256k1_fe_t) * len); for (size_t i=0; iy); } -static int secp256k1_ge_set_xo(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) { +static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) { r->x = *x; secp256k1_fe_t x2; secp256k1_fe_sqr(&x2, x); secp256k1_fe_t x3; secp256k1_fe_mul(&x3, x, &x2); r->infinity = 0; secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7); secp256k1_fe_add(&c, &x3); - if (!secp256k1_fe_sqrt(&r->y, &c)) + if (!secp256k1_fe_sqrt_var(&r->y, &c)) return 0; - secp256k1_fe_normalize(&r->y); + secp256k1_fe_normalize_var(&r->y); if (secp256k1_fe_is_odd(&r->y) != odd) secp256k1_fe_negate(&r->y, &r->y, 1); return 1; @@ -162,12 +168,12 @@ static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a) secp256k1_fe_mul(r, &a->x, &zi2); } -static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) { +static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) { r->infinity = a->infinity; r->x = a->x; r->y = a->y; r->z = a->z; - secp256k1_fe_normalize(&r->y); + secp256k1_fe_normalize_var(&r->y); secp256k1_fe_negate(&r->y, &r->y, 1); } @@ -175,7 +181,7 @@ static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a) { return a->infinity; } -static int secp256k1_gej_is_valid(const secp256k1_gej_t *a) { +static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { if (a->infinity) return 0; /** y^2 = x^3 + 7 @@ -189,12 +195,12 @@ static int secp256k1_gej_is_valid(const secp256k1_gej_t *a) { secp256k1_fe_t z6; secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); secp256k1_fe_mul_int(&z6, 7); secp256k1_fe_add(&x3, &z6); - secp256k1_fe_normalize(&y2); - secp256k1_fe_normalize(&x3); + secp256k1_fe_normalize_var(&y2); + secp256k1_fe_normalize_var(&x3); return secp256k1_fe_equal(&y2, &x3); } -static int secp256k1_ge_is_valid(const secp256k1_ge_t *a) { +static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) { if (a->infinity) return 0; /* y^2 = x^3 + 7 */ @@ -202,8 +208,8 @@ static int secp256k1_ge_is_valid(const secp256k1_ge_t *a) { secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7); secp256k1_fe_add(&x3, &c); - secp256k1_fe_normalize(&y2); - secp256k1_fe_normalize(&x3); + secp256k1_fe_normalize_var(&y2); + secp256k1_fe_normalize_var(&x3); return secp256k1_fe_equal(&y2, &x3); } @@ -255,11 +261,11 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); secp256k1_fe_t s1; secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_normalize(&u1); - secp256k1_fe_normalize(&u2); + secp256k1_fe_normalize_var(&u1); + secp256k1_fe_normalize_var(&u2); if (secp256k1_fe_equal(&u1, &u2)) { - secp256k1_fe_normalize(&s1); - secp256k1_fe_normalize(&s2); + secp256k1_fe_normalize_var(&s1); + secp256k1_fe_normalize_var(&s2); if (secp256k1_fe_equal(&s1, &s2)) { secp256k1_gej_double_var(r, a); } else { @@ -294,15 +300,14 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * } r->infinity = 0; secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z); - secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize(&u1); + secp256k1_fe_t u1 = a->x; secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); - secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize(&s1); + secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_var(&s1); secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_normalize(&u1); - secp256k1_fe_normalize(&u2); + secp256k1_fe_normalize_var(&u1); + secp256k1_fe_normalize_var(&u2); if (secp256k1_fe_equal(&u1, &u2)) { - secp256k1_fe_normalize(&s1); - secp256k1_fe_normalize(&s2); + secp256k1_fe_normalize_var(&s2); if (secp256k1_fe_equal(&s1, &s2)) { secp256k1_gej_double_var(r, a); } else { @@ -434,7 +439,7 @@ static void secp256k1_ge_start(void) { }; #endif if (secp256k1_ge_consts == NULL) { - secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)malloc(sizeof(secp256k1_ge_consts_t)); + secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)checked_malloc(sizeof(secp256k1_ge_consts_t)); #ifdef USE_ENDOMORPHISM VERIFY_CHECK(secp256k1_fe_set_b32(&ret->beta, secp256k1_ge_consts_beta)); #endif diff --git a/src/scalar_impl.h b/src/scalar_impl.h index 7fc159df772..4408cce2d88 100644 --- a/src/scalar_impl.h +++ b/src/scalar_impl.h @@ -40,7 +40,7 @@ static void secp256k1_scalar_start(void) { return; /* Allocate. */ - secp256k1_scalar_consts_t *ret = (secp256k1_scalar_consts_t*)malloc(sizeof(secp256k1_scalar_consts_t)); + secp256k1_scalar_consts_t *ret = (secp256k1_scalar_consts_t*)checked_malloc(sizeof(secp256k1_scalar_consts_t)); #ifndef USE_NUM_NONE static const unsigned char secp256k1_scalar_consts_order[] = { diff --git a/src/secp256k1.c b/src/secp256k1.c index 20fc27df74a..0328db88fc4 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -40,15 +40,12 @@ void secp256k1_stop(void) { secp256k1_fe_stop(); } -int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { +int secp256k1_ecdsa_verify(const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { DEBUG_CHECK(secp256k1_ecmult_consts != NULL); - DEBUG_CHECK(msg != NULL); - DEBUG_CHECK(msglen <= 32); + DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig != NULL); DEBUG_CHECK(pubkey != NULL); - unsigned char msg32[32] = {0}; - memcpy(msg32 + 32 - msglen, msg, msglen); int ret = -3; secp256k1_scalar_t m; secp256k1_ecdsa_sig_t s; @@ -72,10 +69,9 @@ end: return ret; } -int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned char *signature, int *signaturelen, const unsigned char *seckey, const unsigned char *nonce) { +int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, const unsigned char *nonce) { DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); - DEBUG_CHECK(message != NULL); - DEBUG_CHECK(messagelen <= 32); + DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(signature != NULL); DEBUG_CHECK(signaturelen != NULL); DEBUG_CHECK(seckey != NULL); @@ -85,12 +81,7 @@ int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned secp256k1_scalar_set_b32(&sec, seckey, NULL); int overflow = 0; secp256k1_scalar_set_b32(&non, nonce, &overflow); - { - unsigned char c[32] = {0}; - memcpy(c + 32 - messagelen, message, messagelen); - secp256k1_scalar_set_b32(&msg, c, NULL); - memset(c, 0, 32); - } + secp256k1_scalar_set_b32(&msg, msg32, NULL); int ret = !secp256k1_scalar_is_zero(&non) && !overflow; secp256k1_ecdsa_sig_t sig; if (ret) { @@ -105,10 +96,9 @@ int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned return ret; } -int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid) { +int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid) { DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); - DEBUG_CHECK(message != NULL); - DEBUG_CHECK(messagelen <= 32); + DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig64 != NULL); DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(nonce != NULL); @@ -117,12 +107,7 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, u secp256k1_scalar_set_b32(&sec, seckey, NULL); int overflow = 0; secp256k1_scalar_set_b32(&non, nonce, &overflow); - { - unsigned char c[32] = {0}; - memcpy(c + 32 - messagelen, message, messagelen); - secp256k1_scalar_set_b32(&msg, c, NULL); - memset(c, 0, 32); - } + secp256k1_scalar_set_b32(&msg, msg32, NULL); int ret = !secp256k1_scalar_is_zero(&non) && !overflow; secp256k1_ecdsa_sig_t sig; if (ret) { @@ -138,18 +123,15 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, u return ret; } -int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { +int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { DEBUG_CHECK(secp256k1_ecmult_consts != NULL); - DEBUG_CHECK(msg != NULL); - DEBUG_CHECK(msglen <= 32); + DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig64 != NULL); DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(pubkeylen != NULL); DEBUG_CHECK(recid >= 0 && recid <= 3); int ret = 0; - unsigned char msg32[32] = {0}; - memcpy(msg32 + 32 - msglen, msg, msglen); secp256k1_scalar_t m; secp256k1_ecdsa_sig_t sig; int overflow = 0; diff --git a/src/tests.c b/src/tests.c index 78cdd67f279..7ebb19ff99c 100644 --- a/src/tests.c +++ b/src/tests.c @@ -11,6 +11,8 @@ #include #include +#include + #include "secp256k1.c" #include "testrand_impl.h" @@ -46,7 +48,7 @@ void random_group_element_test(secp256k1_ge_t *ge) { secp256k1_fe_t fe; do { random_field_element_test(&fe); - if (secp256k1_ge_set_xo(ge, &fe, secp256k1_rand32() & 1)) + if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand32() & 1)) break; } while(1); } @@ -400,6 +402,30 @@ void scalar_test(void) { CHECK(secp256k1_scalar_eq(&r1, &r2)); } + { + /* Test multiplicative identity. */ + secp256k1_scalar_t r1, v1; + secp256k1_scalar_set_int(&v1,1); + secp256k1_scalar_mul(&r1, &s1, &v1); + CHECK(secp256k1_scalar_eq(&r1, &s1)); + } + + { + /* Test additive identity. */ + secp256k1_scalar_t r1, v0; + secp256k1_scalar_set_int(&v0,0); + secp256k1_scalar_add(&r1, &s1, &v0); + CHECK(secp256k1_scalar_eq(&r1, &s1)); + } + + { + /* Test zero product property. */ + secp256k1_scalar_t r1, v0; + secp256k1_scalar_set_int(&v0,0); + secp256k1_scalar_mul(&r1, &s1, &v0); + CHECK(secp256k1_scalar_eq(&r1, &v0)); + } + } void run_scalar_tests(void) { @@ -411,9 +437,12 @@ void run_scalar_tests(void) { /* (-1)+1 should be zero. */ secp256k1_scalar_t s, o; secp256k1_scalar_set_int(&s, 1); + CHECK(secp256k1_scalar_is_one(&s)); secp256k1_scalar_negate(&o, &s); secp256k1_scalar_add(&o, &o, &s); CHECK(secp256k1_scalar_is_zero(&o)); + secp256k1_scalar_negate(&o, &o); + CHECK(secp256k1_scalar_is_zero(&o)); } #ifndef USE_NUM_NONE @@ -459,14 +488,14 @@ void random_fe_non_zero(secp256k1_fe_t *nz) { void random_fe_non_square(secp256k1_fe_t *ns) { random_fe_non_zero(ns); secp256k1_fe_t r; - if (secp256k1_fe_sqrt(&r, ns)) { + if (secp256k1_fe_sqrt_var(&r, ns)) { secp256k1_fe_negate(ns, ns, 1); } } int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { secp256k1_fe_t an = *a; secp256k1_fe_normalize(&an); - secp256k1_fe_t bn = *b; secp256k1_fe_normalize(&bn); + secp256k1_fe_t bn = *b; secp256k1_fe_normalize_var(&bn); return secp256k1_fe_equal(&an, &bn); } @@ -476,6 +505,55 @@ int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) { return check_fe_equal(&x, &one); } +void run_field_misc(void) { + const unsigned char f32_5[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + }; + secp256k1_fe_t x; + secp256k1_fe_t y; + secp256k1_fe_t z; + secp256k1_fe_t q; + secp256k1_fe_t fe5; + CHECK(secp256k1_fe_set_b32(&fe5, f32_5)); + for (int i=0; i<5*count; i++) { + random_fe(&x); + random_fe_non_zero(&y); + /* Test the fe equality and comparison operations. */ + CHECK(secp256k1_fe_cmp_var(&x, &x) == 0); + CHECK(secp256k1_fe_equal(&x, &x)); + z = x; + secp256k1_fe_add(&z,&y); + secp256k1_fe_normalize(&z); + /* Test the conditional move. */ + secp256k1_fe_cmov(&z, &x, 0); + CHECK(secp256k1_fe_equal(&x, &z) == 0); + CHECK(secp256k1_fe_cmp_var(&x, &z) != 0); + secp256k1_fe_cmov(&y, &x, 1); + CHECK(secp256k1_fe_equal(&x, &y)); + /* Test that mul_int, mul, and add agree. */ + secp256k1_fe_add(&y, &x); + secp256k1_fe_add(&y, &x); + z = x; + secp256k1_fe_mul_int(&z, 3); + CHECK(check_fe_equal(&y, &z)); + secp256k1_fe_add(&y, &x); + secp256k1_fe_add(&z, &x); + CHECK(check_fe_equal(&z, &y)); + z = x; + secp256k1_fe_mul_int(&z, 5); + secp256k1_fe_mul(&q, &x, &fe5); + CHECK(check_fe_equal(&z, &q)); + secp256k1_fe_negate(&x, &x, 1); + secp256k1_fe_add(&z, &x); + secp256k1_fe_add(&q, &x); + CHECK(check_fe_equal(&y, &z)); + CHECK(check_fe_equal(&q, &y)); + } +} + void run_field_inv(void) { secp256k1_fe_t x, xi, xii; for (int i=0; i<10*count; i++) { @@ -498,23 +576,6 @@ void run_field_inv_var(void) { } } -void run_field_inv_all(void) { - secp256k1_fe_t x[16], xi[16], xii[16]; - /* Check it's safe to call for 0 elements */ - secp256k1_fe_inv_all(0, xi, x); - for (int i=0; i>=2; + if ((r & 3) == 0) len = (r & 252) >> 3; + r>>=8; + if (len == 65) { + in[0] = (r & 2) ? 4 : (r & 1? 6 : 7); + } else { + in[0] = (r & 1) ? 2 : 3; + } + r>>=2; + if ((r & 7) == 0) in[0] = (r & 2040) >> 3; + r>>=11; + if (len > 1) secp256k1_rand256(&in[1]); + if (len > 33) secp256k1_rand256(&in[33]); + secp256k1_ge_t elem; + secp256k1_ge_t elem2; + if (secp256k1_eckey_pubkey_parse(&elem, in, len)) { + unsigned char out[65]; + unsigned char firstb; + int res; + int size = len; + firstb = in[0]; + /* If the pubkey can be parsed, it should round-trip... */ + CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33)); + CHECK(size == len); + CHECK(memcmp(&in[1], &out[1], len-1) == 0); + /* ... except for the type of hybrid inputs. */ + if ((in[0] != 6) && (in[0] != 7)) CHECK(in[0] == out[0]); + size = 65; + CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0)); + CHECK(size == 65); + CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size)); + CHECK(ge_equals_ge(&elem,&elem2)); + /* Check that the X9.62 hybrid type is checked. */ + in[0] = (r & 1) ? 6 : 7; + res = secp256k1_eckey_pubkey_parse(&elem2, in, size); + if (firstb == 2 || firstb == 3) { + if (in[0] == firstb + 4) CHECK(res); + else CHECK(!res); + } + if (res) { + CHECK(ge_equals_ge(&elem,&elem2)); + CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0)); + CHECK(memcmp(&in[1], &out[1], 64) == 0); + } + } +} + +void run_random_pubkeys(void) { + for (int i=0; i<10*count; i++) { + test_random_pubkeys(); + } +} + void run_ecdsa_end_to_end(void) { for (int i=0; i<64*count; i++) { test_ecdsa_end_to_end(); @@ -995,10 +1127,10 @@ void test_ecdsa_edge_cases(void) { }; unsigned char pubkey[65]; int pubkeylen = 65; - CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 0)); - CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 1)); - CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 2)); - CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 3)); + CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 0)); + CHECK(secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 1)); + CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 2)); + CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 3)); /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */ const unsigned char sigb64[64] = { @@ -1016,6 +1148,36 @@ void test_ecdsa_edge_cases(void) { for (int recid = 0; recid < 4; recid++) { /* (4,4) encoded in DER. */ unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04}; + unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01}; + unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00}; + unsigned char sigbderalt1[39] = { + 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, + }; + unsigned char sigbderalt2[39] = { + 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + }; + unsigned char sigbderalt3[40] = { + 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, + }; + unsigned char sigbderalt4[40] = { + 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + }; /* (order + r,4) encoded in DER. */ unsigned char sigbderlong[40] = { 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF, @@ -1024,18 +1186,45 @@ void test_ecdsa_edge_cases(void) { 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04 }; - CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sigb64, pubkeyb, &pubkeyblen, 1, recid)); - CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1); + CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid)); + CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1); for (int recid2 = 0; recid2 < 4; recid2++) { unsigned char pubkey2b[33]; int pubkey2blen = 33; - CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sigb64, pubkey2b, &pubkey2blen, 1, recid2)); + CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2)); /* Verifying with (order + r,4) should always fail. */ - CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1); + CHECK(secp256k1_ecdsa_verify(msg32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1); } + /* DER parsing tests. */ + /* Zero length r/s. */ + CHECK(secp256k1_ecdsa_verify(msg32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2); + CHECK(secp256k1_ecdsa_verify(msg32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2); + /* Leading zeros. */ + CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1); + CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1); + CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1); + CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1); + sigbderalt3[4] = 1; + CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2); + sigbderalt4[7] = 1; + CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2); /* Damage signature. */ sigbder[7]++; - CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0); + CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0); + sigbder[7]--; + CHECK(secp256k1_ecdsa_verify(msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2); + CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2); + for(int i = 0; i<8; i++) { + unsigned char orig = sigbder[i]; + /*Try every single-byte change.*/ + for (int c=0; c<256; c++) { + if (c == orig ) continue; + sigbder[i] = c; + CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == + (i==4 || i==7) ? 0 : -2 ); + } + sigbder[i] = orig; + } } /* Test the case where ECDSA recomputes a point that is infinity. */ @@ -1069,18 +1258,60 @@ void test_ecdsa_edge_cases(void) { }; unsigned char pubkeyc[65]; int pubkeyclen = 65; - CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1); - CHECK(secp256k1_ecdsa_verify(msg32, 32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1); + CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1); + CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1); sigcder[4] = 0; sigc64[31] = 0; - CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); - CHECK(secp256k1_ecdsa_verify(msg32, 32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); + CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); + CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); sigcder[4] = 1; sigcder[7] = 0; sigc64[31] = 1; sigc64[63] = 0; - CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); - CHECK(secp256k1_ecdsa_verify(msg32, 32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); + CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); + CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); + } + + /*Signature where s would be zero.*/ + { + const unsigned char nonce[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; + const unsigned char key[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; + unsigned char msg[32] = { + 0x86, 0x41, 0x99, 0x81, 0x06, 0x23, 0x44, 0x53, + 0xaa, 0x5f, 0x9d, 0x6a, 0x31, 0x78, 0xf4, 0xf7, + 0xb8, 0x12, 0xe0, 0x0b, 0x81, 0x7a, 0x77, 0x62, + 0x65, 0xdf, 0xdd, 0x31, 0xb9, 0x3e, 0x29, 0xa9, + }; + unsigned char sig[72]; + int siglen = 72; + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce) == 0); + msg[31] = 0xaa; + siglen = 72; + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce) == 1); + } + + /* Privkey export where pubkey is the point at infinity. */ + { + unsigned char privkey[300]; + unsigned char seckey[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, + }; + int outlen = 300; + CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 0)); + CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 1)); } } @@ -1185,8 +1416,8 @@ int main(int argc, char **argv) { /* field tests */ run_field_inv(); run_field_inv_var(); - run_field_inv_all(); run_field_inv_all_var(); + run_field_misc(); run_sqr(); run_sqrt(); @@ -1199,6 +1430,7 @@ int main(int argc, char **argv) { run_ecmult_chain(); /* ecdsa tests */ + run_random_pubkeys(); run_ecdsa_sign_verify(); run_ecdsa_end_to_end(); run_ecdsa_edge_cases(); diff --git a/src/util.h b/src/util.h index 08b23a9d38c..c3a8f3a42bf 100644 --- a/src/util.h +++ b/src/util.h @@ -61,6 +61,12 @@ #define VERIFY_CHECK(cond) do { (void)(cond); } while(0) #endif +static inline void *checked_malloc(size_t size) { + void *ret = malloc(size); + CHECK(ret != NULL); + return ret; +} + /* Macro for restrict, when available and not in a VERIFY build. */ #if defined(SECP256K1_BUILD) && defined(VERIFY) # define SECP256K1_RESTRICT From 830ee48b5994f8a5cce8c011672be0612867c9b7 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 11 Dec 2014 02:06:28 +0100 Subject: [PATCH 0027/2337] Update Bitcoin for libsecp256k1 API change --- src/key.cpp | 4 ++-- src/pubkey.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/key.cpp b/src/key.cpp index acf62360a47..36613342b8b 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -82,7 +82,7 @@ bool CKey::Sign(const uint256 &hash, std::vector& vchSig, uint32_ prng.Generate((unsigned char*)&nonce, 32); nonce += test_case; int nSigLen = 72; - int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, 32, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce); + int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce); nonce = 0; if (ret) { vchSig.resize(nSigLen); @@ -114,7 +114,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector& vchSig) do { uint256 nonce; prng.Generate((unsigned char*)&nonce, 32); - int ret = secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, 32, &vchSig[1], begin(), (unsigned char*)&nonce, &rec); + int ret = secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, &vchSig[1], begin(), (unsigned char*)&nonce, &rec); nonce = 0; if (ret) break; diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 91979ff4dc8..80bbac9205d 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -16,7 +16,7 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector& vchS if (!IsValid()) return false; #ifdef USE_SECP256K1 - if (secp256k1_ecdsa_verify((const unsigned char*)&hash, 32, &vchSig[0], vchSig.size(), begin(), size()) != 1) + if (secp256k1_ecdsa_verify((const unsigned char*)&hash, &vchSig[0], vchSig.size(), begin(), size()) != 1) return false; #else CECKey key; @@ -35,7 +35,7 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector Date: Thu, 11 Dec 2014 16:03:46 +0100 Subject: [PATCH 0028/2337] Now that 0.10 has been branched, master is 0.10.99 --- configure.ac | 2 +- doc/Doxyfile | 2 +- doc/README.md | 2 +- doc/README_windows.txt | 2 +- doc/release-notes.md | 123 ----------------------------------------- src/clientversion.h | 2 +- 6 files changed, 5 insertions(+), 128 deletions(-) diff --git a/configure.ac b/configure.ac index c4c21eaf4f6..efb4c003193 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 9) +define(_CLIENT_VERSION_MINOR, 10) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) diff --git a/doc/Doxyfile b/doc/Doxyfile index e0339e652eb..8a11d1e8d01 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -34,7 +34,7 @@ PROJECT_NAME = Bitcoin # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 0.9.99 +PROJECT_NUMBER = 0.10.99 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/doc/README.md b/doc/README.md index d5d61738e87..3ec5f11df27 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -Bitcoin 0.9.99 BETA +Bitcoin 0.10.99 BETA ===================== Copyright (c) 2009-2014 Bitcoin Developers diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 368f2b45e1f..9780a2cb134 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin 0.9.99 BETA +Bitcoin 0.10.99 BETA Copyright (c) 2009-2014 Bitcoin Core Developers diff --git a/doc/release-notes.md b/doc/release-notes.md index f804e8c11b2..1cb517e5c71 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,126 +1,3 @@ (note: this is a temporary file, to be added-to by anybody, and moved to release-notes at release time) -Block file backwards-compatibility warning -=========================================== - -Because release 0.10.0 makes use of headers-first synchronization and parallel -block download, the block files and databases are not backwards-compatible -with older versions of Bitcoin Core: - -* Blocks will be stored on disk out of order (in the order they are -received, really), which makes it incompatible with some tools or -other programs. Reindexing using earlier versions will also not work -anymore as a result of this. - -* The block index database will now hold headers for which no block is -stored on disk, which earlier versions won't support. - -If you want to be able to downgrade smoothly, make a backup of your entire data -directory. Without this your node will need start syncing (or importing from -bootstrap.dat) anew afterwards. - -This does not affect wallet forward or backward compatibility. - -Transaction fee changes -======================= - -This release automatically estimates how high a transaction fee (or how -high a priority) transactions require to be confirmed quickly. The default -settings will create transactions that confirm quickly; see the new -'txconfirmtarget' setting to control the tradeoff between fees and -confirmation times. - -Prior releases used hard-coded fees (and priorities), and would -sometimes create transactions that took a very long time to confirm. - -Statistics used to estimate fees and priorities are saved in the -data directory in the `fee_estimates.dat` file just before -program shutdown, and are read in at startup. - -New Command Line Options ---------------------------- - -- `-txconfirmtarget=n` : create transactions that have enough fees (or priority) -so they are likely to confirm within n blocks (default: 1). This setting -is over-ridden by the -paytxfee option. - -New RPC methods ----------------- - -- `estimatefee nblocks` : Returns approximate fee-per-1,000-bytes needed for -a transaction to be confirmed within nblocks. Returns -1 if not enough -transactions have been observed to compute a good estimate. - -- `estimatepriority nblocks` : Returns approximate priority needed for -a zero-fee transaction to confirm within nblocks. Returns -1 if not -enough free transactions have been observed to compute a good -estimate. - -RPC access control changes -========================================== - -Subnet matching for the purpose of access control is now done -by matching the binary network address, instead of with string wildcard matching. -For the user this means that `-rpcallowip` takes a subnet specification, which can be - -- a single IP address (e.g. `1.2.3.4` or `fe80::0012:3456:789a:bcde`) -- a network/CIDR (e.g. `1.2.3.0/24` or `fe80::0000/64`) -- a network/netmask (e.g. `1.2.3.4/255.255.255.0` or `fe80::0012:3456:789a:bcde/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff`) - -An arbitrary number of `-rpcallow` arguments can be given. An incoming connection will be accepted if its origin address -matches one of them. - -For example: - -| 0.9.x and before | 0.10.x | -|--------------------------------------------|---------------------------------------| -| `-rpcallowip=192.168.1.1` | `-rpcallowip=192.168.1.1` (unchanged) | -| `-rpcallowip=192.168.1.*` | `-rpcallowip=192.168.1.0/24` | -| `-rpcallowip=192.168.*` | `-rpcallowip=192.168.0.0/16` | -| `-rpcallowip=*` (dangerous!) | `-rpcallowip=::/0` | - -Using wildcards will result in the rule being rejected with the following error in debug.log: - - Error: Invalid -rpcallowip subnet specification: *. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). - -RPC Server "Warm-Up" Mode -========================= - -The RPC server is started earlier now, before most of the expensive -intialisations like loading the block index. It is available now almost -immediately after starting the process. However, until all initialisations -are done, it always returns an immediate error with code -28 to all calls. - -This new behaviour can be useful for clients to know that a server is already -started and will be available soon (for instance, so that they do not -have to start it themselves). - -Improved signing security -========================= - -For 0.10 the security of signing against unusual attacks has been -improved by making the signatures constant time and deterministic. - -This change is a result of switching signing to use libsecp256k1 -instead of OpenSSL. Libsecp256k1 is a cryptographic library -optimized for the curve Bitcoin uses which was created by Bitcoin -Core developer Pieter Wuille. - -There exist attacks[1] against most ECC implementations where an -attacker on shared virtual machine hardware could extract a private -key if they could cause a target to sign using the same key hundreds -of times. While using shared hosts and reusing keys are inadvisable -for other reasons, it's a better practice to avoid the exposure. - -OpenSSL has code in their source repository for derandomization -and reduction in timing leaks, and we've eagerly wanted to use -it for a long time but this functionality has still not made its -way into a released version of OpenSSL. Libsecp256k1 achieves -significantly stronger protection: As far as we're aware this is -the only deployed implementation of constant time signing for -the curve Bitcoin uses and we have reason to believe that -libsecp256k1 is better tested and more thoroughly reviewed -than the implementation in OpenSSL. - -[1] https://eprint.iacr.org/2014/161.pdf diff --git a/src/clientversion.h b/src/clientversion.h index 0a36eb80123..32deaa0f1ef 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -15,7 +15,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 -#define CLIENT_VERSION_MINOR 9 +#define CLIENT_VERSION_MINOR 10 #define CLIENT_VERSION_REVISION 99 #define CLIENT_VERSION_BUILD 0 From aa768f1848b00e0fd615016598d3fb1f1da240ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Thu, 11 Dec 2014 16:06:23 +0100 Subject: [PATCH 0029/2337] signrawtransaction: validate private key. --- src/rpcrawtransaction.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 8de15ff9e2f..4a1af2207a2 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -587,6 +587,8 @@ Value signrawtransaction(const Array& params, bool fHelp) if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); CKey key = vchSecret.GetKey(); + if (!key.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); tempKeystore.AddKey(key); } } From 012598880cf69a6a4d4d495c78e40ab4abb4eb39 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 22 Nov 2014 15:44:43 +0100 Subject: [PATCH 0030/2337] Implement test for merkle tree malleability in CPartialMerkleTree This is a check that is mentioned in BIP 37, but never implemented in the reference code. As Bitcoin Core so far never decodes partial merkle trees, this is not a problem. But perhaps others use the code as a reference. --- src/merkleblock.cpp | 10 ++++++++-- src/test/pmt_tests.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 8618e355d74..0500cfde889 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -93,10 +93,16 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns } else { // otherwise, descend into the subtrees to extract matched txids and hashes uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right; - if (pos*2+1 < CalcTreeWidth(height-1)) + if (pos*2+1 < CalcTreeWidth(height-1)) { right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch); - else + if (right == left) { + // If the left and right branch should never be identical as the transaction + // hashes covered by them must be unique. + fBad = true; + } + } else { right = left; + } // and combine them before returning return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); } diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 3b535a84fd8..eea5b0af499 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -10,6 +10,7 @@ #include +#include #include using namespace std; @@ -104,4 +105,14 @@ BOOST_AUTO_TEST_CASE(pmt_test1) } } +BOOST_AUTO_TEST_CASE(pmt_malleability) +{ + std::vector vTxid = boost::assign::list_of(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(9)(10); + std::vector vMatch = boost::assign::list_of(false)(false)(false)(false)(false)(false)(false)(false)(false)(true)(true)(false); + + CPartialMerkleTree tree(vTxid, vMatch); + std::vector vTxid2; + BOOST_CHECK(tree.ExtractMatches(vTxid) == 0); +} + BOOST_AUTO_TEST_SUITE_END() From 9dcd524f3248cb4fca5613a3c11dddcc7a0efbd7 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 24 Nov 2014 14:51:10 +0100 Subject: [PATCH 0031/2337] Make IsSuperMajority a standalone function --- src/chain.h | 8 -------- src/main.cpp | 15 ++++++++++----- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/chain.h b/src/chain.h index 1c2d89933b2..a8a6b4dd647 100644 --- a/src/chain.h +++ b/src/chain.h @@ -236,14 +236,6 @@ public: return pbegin[(pend - pbegin)/2]; } - /** - * Returns true if there are nRequired or more blocks of minVersion or above - * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart - * and going backwards. - */ - static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, - unsigned int nRequired); - std::string ToString() const { return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", diff --git a/src/main.cpp b/src/main.cpp index 50e63e93e45..bc08c3ea29d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,6 +67,13 @@ map mapOrphanTransactions; map > mapOrphanTransactionsByPrev; void EraseOrphansFor(NodeId peer); +/** + * Returns true if there are nRequired or more blocks of minVersion or above + * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart + * and going backwards. + */ +static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired); + /** Constant stuff for coinbase transactions we create: */ CScript COINBASE_FLAGS; @@ -2479,8 +2486,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta return state.DoS(100, error("%s : forked chain older than last checkpoint (height %d)", __func__, nHeight)); // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 2 && - CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) + if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) { return state.Invalid(error("%s : rejected nVersion=1 block", __func__), REJECT_OBSOLETE, "bad-version"); @@ -2501,8 +2507,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): - if (block.nVersion >= 2 && - CBlockIndex::IsSuperMajority(2, pindexPrev, Params().EnforceBlockUpgradeMajority())) + if (block.nVersion >= 2 && IsSuperMajority(2, pindexPrev, Params().EnforceBlockUpgradeMajority())) { CScript expect = CScript() << nHeight; if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || @@ -2600,7 +2605,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, return true; } -bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired) +static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired) { unsigned int nToCheck = Params().ToCheckBlockUpgradeMajority(); unsigned int nFound = 0; From 5ea3bc06d501594a36c97e20df2d446e87956aed Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 23 Nov 2014 14:07:38 +0100 Subject: [PATCH 0032/2337] Move remaining CBlockIndex methods to chain.cpp --- src/chain.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 48 ------------------------------------------------ 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/src/chain.cpp b/src/chain.cpp index e13c0478614..3dbaf5a36a4 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -57,3 +57,52 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { pindex = pindex->pprev; return pindex; } + +/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ +int static inline InvertLowestOne(int n) { return n & (n - 1); } + +/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */ +int static inline GetSkipHeight(int height) { + if (height < 2) + return 0; + + // Determine which height to jump back to. Any number strictly lower than height is acceptable, + // but the following expression seems to perform well in simulations (max 110 steps to go back + // up to 2**18 blocks). + return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height); +} + +CBlockIndex* CBlockIndex::GetAncestor(int height) +{ + if (height > nHeight || height < 0) + return NULL; + + CBlockIndex* pindexWalk = this; + int heightWalk = nHeight; + while (heightWalk > height) { + int heightSkip = GetSkipHeight(heightWalk); + int heightSkipPrev = GetSkipHeight(heightWalk - 1); + if (heightSkip == height || + (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && + heightSkipPrev >= height))) { + // Only follow pskip if pprev->pskip isn't better than pskip->pprev. + pindexWalk = pindexWalk->pskip; + heightWalk = heightSkip; + } else { + pindexWalk = pindexWalk->pprev; + heightWalk--; + } + } + return pindexWalk; +} + +const CBlockIndex* CBlockIndex::GetAncestor(int height) const +{ + return const_cast(this)->GetAncestor(height); +} + +void CBlockIndex::BuildSkip() +{ + if (pprev) + pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); +} diff --git a/src/main.cpp b/src/main.cpp index bc08c3ea29d..7533c32614b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2618,54 +2618,6 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned return (nFound >= nRequired); } -/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ -int static inline InvertLowestOne(int n) { return n & (n - 1); } - -/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */ -int static inline GetSkipHeight(int height) { - if (height < 2) - return 0; - - // Determine which height to jump back to. Any number strictly lower than height is acceptable, - // but the following expression seems to perform well in simulations (max 110 steps to go back - // up to 2**18 blocks). - return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height); -} - -CBlockIndex* CBlockIndex::GetAncestor(int height) -{ - if (height > nHeight || height < 0) - return NULL; - - CBlockIndex* pindexWalk = this; - int heightWalk = nHeight; - while (heightWalk > height) { - int heightSkip = GetSkipHeight(heightWalk); - int heightSkipPrev = GetSkipHeight(heightWalk - 1); - if (heightSkip == height || - (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && - heightSkipPrev >= height))) { - // Only follow pskip if pprev->pskip isn't better than pskip->pprev. - pindexWalk = pindexWalk->pskip; - heightWalk = heightSkip; - } else { - pindexWalk = pindexWalk->pprev; - heightWalk--; - } - } - return pindexWalk; -} - -const CBlockIndex* CBlockIndex::GetAncestor(int height) const -{ - return const_cast(this)->GetAncestor(height); -} - -void CBlockIndex::BuildSkip() -{ - if (pprev) - pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); -} bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp) { From eb0d34b494e36af01d4636c69e6570943fb30f1c Mon Sep 17 00:00:00 2001 From: jtimon Date: Thu, 6 Nov 2014 17:59:46 +0100 Subject: [PATCH 0033/2337] Remove unused chainparam networkID --- src/chainparams.cpp | 4 ---- src/chainparams.h | 1 - src/chainparamsbase.cpp | 4 ---- src/chainparamsbase.h | 1 - 4 files changed, 10 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 8a6a061ea1e..51ae0a35bc5 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -101,7 +101,6 @@ static const Checkpoints::CCheckpointData dataRegtest = { class CMainParams : public CChainParams { public: CMainParams() { - networkID = CBaseChainParams::MAIN; strNetworkID = "main"; /** * The message start string is designed to be unlikely to occur in normal data. @@ -190,7 +189,6 @@ static CMainParams mainParams; class CTestNetParams : public CMainParams { public: CTestNetParams() { - networkID = CBaseChainParams::TESTNET; strNetworkID = "test"; pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; @@ -247,7 +245,6 @@ static CTestNetParams testNetParams; class CRegTestParams : public CTestNetParams { public: CRegTestParams() { - networkID = CBaseChainParams::REGTEST; strNetworkID = "regtest"; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; @@ -292,7 +289,6 @@ static CRegTestParams regTestParams; class CUnitTestParams : public CMainParams, public CModifiableParams { public: CUnitTestParams() { - networkID = CBaseChainParams::UNITTEST; strNetworkID = "unittest"; nDefaultPort = 18445; vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds. diff --git a/src/chainparams.h b/src/chainparams.h index 5d1ee1d3c6b..c5268356cc7 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -97,7 +97,6 @@ protected: int nMinerThreads; std::vector vSeeds; std::vector base58Prefixes[MAX_BASE58_TYPES]; - CBaseChainParams::Network networkID; std::string strNetworkID; CBlock genesis; std::vector vFixedSeeds; diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 8646a31603c..40a7eacb931 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -21,7 +21,6 @@ class CBaseMainParams : public CBaseChainParams public: CBaseMainParams() { - networkID = CBaseChainParams::MAIN; nRPCPort = 8332; } }; @@ -35,7 +34,6 @@ class CBaseTestNetParams : public CBaseMainParams public: CBaseTestNetParams() { - networkID = CBaseChainParams::TESTNET; nRPCPort = 18332; strDataDir = "testnet3"; } @@ -50,7 +48,6 @@ class CBaseRegTestParams : public CBaseTestNetParams public: CBaseRegTestParams() { - networkID = CBaseChainParams::REGTEST; strDataDir = "regtest"; } }; @@ -64,7 +61,6 @@ class CBaseUnitTestParams : public CBaseMainParams public: CBaseUnitTestParams() { - networkID = CBaseChainParams::UNITTEST; strDataDir = "unittest"; } }; diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index eaf3fea1b6f..1e5895a6315 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -32,7 +32,6 @@ protected: int nRPCPort; std::string strDataDir; - Network networkID; }; /** From 422f873ef3d62f7dff9c00dc0f221912ce28f130 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 11 Dec 2014 15:38:29 -0500 Subject: [PATCH 0034/2337] depends: teach 'make download' to download sources for all hosts --- depends/Makefile | 11 +++++++++-- depends/README.usage | 5 ++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index 5de01597142..f803268c17c 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -122,5 +122,12 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ $(AT)touch $@ install: $(host_prefix)/share/config.site -download: $(all_sources) -.PHONY: install cached +download-one: $(all_sources) +download-osx: + @$(MAKE) -s HOST=x86_64-apple-darwin11 download-one +download-linux: + @$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one +download-win: + @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one +download: download-osx download-linux download-win +.PHONY: install cached download-one download-osx download-linux download-win download diff --git a/depends/README.usage b/depends/README.usage index e768feecf76..f5aa5314a1f 100644 --- a/depends/README.usage +++ b/depends/README.usage @@ -29,4 +29,7 @@ If some packages are not built, for example 'make NO_WALLET=1', the appropriate options will be passed to bitcoin's configure. In this case, --disable-wallet. Additional targets: -download: run 'make download' to fetch sources without building them +download: run 'make download' to fetch all sources without building them +download-osx: run 'make download-osx' to fetch all sources needed for osx builds +download-win: run 'make download-win' to fetch all sources needed for win builds +download-linux: run 'make download-linux' to fetch all sources needed for linux builds From d546191dc28fac0e365c8f2aba47ac69a8920d6c Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 11 Dec 2014 15:40:41 -0500 Subject: [PATCH 0035/2337] depends: Move source stamps to source dir and misc cleanups Since the last commit will force rebuilds of all depends, take the opportunity to clean up a few other things that would trigger rebuilds as well. - Move source stamps to the sources dir so that SOURCES_PATH is respected for "make download". - Only print "fetching..." when actually downloading a file. - Avoid using non-deterministic paths for the recipe hash (patch location). This should ensure that all builders get the same resulting build-ids. - Use a per-package source paths. This will allow for removing old source files in the future. - Use a host-agnostic path for downloads which gets cleaned up properly. --- depends/Makefile | 1 + depends/funcs.mk | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index f803268c17c..e2ef7ee49bd 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -31,6 +31,7 @@ endif base_build_dir=$(BASEDIR)/work/build base_staging_dir=$(BASEDIR)/work/staging +base_download_dir=$(BASEDIR)/work/download canonical_host:=$(shell ./config.sub $(HOST)) build:=$(shell ./config.sub $(BUILD)) diff --git a/depends/funcs.mk b/depends/funcs.mk index c1fc0a0e331..79015c047ca 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -20,18 +20,19 @@ $(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dep endef define fetch_file -(test -f $(SOURCES_PATH)/$(4) || \ - ( mkdir -p $$($(1)_extract_dir) && \ - ( $(build_DOWNLOAD) "$$($(1)_extract_dir)/$(4).temp" "$(2)/$(3)" || \ - $(build_DOWNLOAD) "$$($(1)_extract_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(3)" ) && \ - echo "$(5) $$($(1)_extract_dir)/$(4).temp" > $$($(1)_extract_dir)/.$(4).hash && \ - $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$(4).hash && \ - mv $$($(1)_extract_dir)/$(4).temp $(SOURCES_PATH)/$(4) )) +(test -f $$($(1)_source_dir)/$(4) || \ + ( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \ + ( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" || \ + $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(3)" ) && \ + echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \ + $(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \ + mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \ + rm -rf $$($(1)_download_dir) )) endef define int_get_build_recipe_hash $(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)))) -$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM))) +$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | cut -d" " -f1 | $(build_SHA256SUM))) endef define int_get_build_id @@ -45,17 +46,19 @@ final_build_id_long+=$($(package)_build_id_long) #compute package-specific paths $(1)_build_subdir?=. $(1)_download_file?=$($(1)_file_name) -$(1)_source:=$(SOURCES_PATH)/$($(1)_file_name) +$(1)_source_dir:=$(SOURCES_PATH) +$(1)_source:=$$($(1)_source_dir)/$($(1)_file_name) $(1)_staging_dir=$(base_staging_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id) $(1)_staging_prefix_dir:=$$($(1)_staging_dir)$($($(1)_type)_prefix) $(1)_extract_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id) +$(1)_download_dir:=$(base_download_dir)/$(1)-$($(1)_version) $(1)_build_dir:=$$($(1)_extract_dir)/$$($(1)_build_subdir) $(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id) $(1)_prefixbin:=$($($(1)_type)_prefix)/bin/ $(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz #stamps -$(1)_fetched=$$($(1)_extract_dir)/.stamp_fetched +$(1)_fetched=$$($(1)_source_dir)/download-stamps/.stamp_fetched-$(1)-$($(1)_file_name) $(1)_extracted=$$($(1)_extract_dir)/.stamp_extracted $(1)_preprocessed=$$($(1)_extract_dir)/.stamp_preprocessed $(1)_cleaned=$$($(1)_extract_dir)/.stamp_cleaned @@ -150,7 +153,6 @@ endef define int_add_cmds $($(1)_fetched): - $(AT)echo Fetching $(1)... $(AT)mkdir -p $$(@D) $(SOURCES_PATH) $(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1)) $(AT)touch $$@ From d7db4b6317fd9c79bd6fd7c7455d7186b306411f Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 11 Dec 2014 17:37:54 -0500 Subject: [PATCH 0036/2337] depends: fix packages with hard-coded SOURCES_PATH Also fixes a nasty bug that removes the downloaded comparisontool jar file. --- depends/packages/native_cctools.mk | 8 ++++---- depends/packages/native_comparisontool.mk | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index ad989cb544b..1675afe7813 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -39,11 +39,11 @@ $(package)_ldflags+=-m32 -Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib $(package)_ldflags+=-L$$(native_cctools_extract_dir)/clang+llvm-3.2-x86-linux-ubuntu-12.04/lib endef define $(package)_extract_cmds - tar --strip-components=1 -xf $(SOURCES_PATH)/$($(package)_toolchain4_file_name) && \ + tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_toolchain4_file_name) && \ ln -sf $($(package)_source) cctools2odcctools/$($(package)_file_name) && \ - ln -sf $(SOURCES_PATH)/$($(package)_ld64_file_name) cctools2odcctools/$($(package)_ld64_file_name) && \ - ln -sf $(SOURCES_PATH)/$($(package)_dyld_file_name) cctools2odcctools/$($(package)_dyld_file_name) && \ - tar xf $(SOURCES_PATH)/$($(package)_clang_file_name) && \ + ln -sf $($(package)_source_dir)/$($(package)_ld64_file_name) cctools2odcctools/$($(package)_ld64_file_name) && \ + ln -sf $($(package)_source_dir)/$($(package)_dyld_file_name) cctools2odcctools/$($(package)_dyld_file_name) && \ + tar xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ mkdir -p $(SDK_PATH) sdks &&\ cd sdks; ln -sf $(OSX_SDK) MacOSX$(OSX_SDK_VERSION).sdk endef diff --git a/depends/packages/native_comparisontool.mk b/depends/packages/native_comparisontool.mk index 3d430d4306a..d1b86dc2de5 100644 --- a/depends/packages/native_comparisontool.mk +++ b/depends/packages/native_comparisontool.mk @@ -17,5 +17,5 @@ endef define $(package)_stage_cmds mkdir -p $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname) && \ - mv $(SOURCES_PATH)/$($(package)_file_name) $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname)/$($(package)_install_filename) + cp $($(package)_source) $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname)/$($(package)_install_filename) endef From e27d7cb24835c6ce16c12eb758c2d75806103c4a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 11 Dec 2014 18:53:24 -0500 Subject: [PATCH 0037/2337] docs: release process fixups Add instructions for manually fetching sources, as well as some misc. fixes. --- doc/release-process.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/doc/release-process.md b/doc/release-process.md index a16d4ace4a6..30f9797752d 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -40,7 +40,7 @@ Release Process ###fetch and build inputs: (first time, or when dependency versions change) - mkdir -p inputs; cd inputs/ + mkdir -p inputs Register and download the Apple SDK: (see OSX Readme for details) @@ -50,7 +50,15 @@ Release Process tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk - Build Bitcoin Core for Linux, Windows, and OS X: +###Optional: Seed the Gitian sources cache + + By default, gitian will fetch source files as needed. For offline builds, they can be fetched ahead of time: + + make -C ../bitcoin/depends download SOURCES_PATH=`pwd`/cache/common + + Only missing files will be fetched, so this is safe to re-run for each build. + +###Build Bitcoin Core for Linux, Windows, and OS X: ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml @@ -63,7 +71,6 @@ Release Process mv build/out/bitcoin-*-unsigned.tar.gz inputs mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ popd -bitcoin-0.9.99-osx-unsigned.tar.gz Build output expected: 1. source tarball (bitcoin-${VERSION}.tar.gz) @@ -84,11 +91,12 @@ Commit your signature to gitian.sigs: git push # Assuming you can push to the gitian.sigs tree popd -Wait for OSX detached signature: + Wait for OSX detached signature: Once the OSX build has 3 matching signatures, Gavin will sign it with the apple App-Store key. He will then upload a detached signature to be combined with the unsigned app to create a signed binary. -Create the signed OSX binary: + Create the signed OSX binary: + pushd ./gitian-builder # Fetch the signature as instructed by Gavin cp signature.tar.gz inputs/ From f676c80f437e15ab0ee190e93baea733a88db0f2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 8 Dec 2014 13:44:49 +0100 Subject: [PATCH 0038/2337] Add /rest/headers --- qa/rpc-tests/rest.py | 49 +++++++++++++++++++++++---------- src/rest.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 14 deletions(-) diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index cb1868de362..704d889739f 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -23,41 +23,64 @@ except ImportError: def http_get_call(host, port, path, response_object = 0): conn = httplib.HTTPConnection(host, port) conn.request('GET', path) - + if response_object: return conn.getresponse() - + return conn.getresponse().read() class RESTTest (BitcoinTestFramework): FORMAT_SEPARATOR = "." - + def run_test(self): url = urlparse.urlparse(self.nodes[0].url) bb_hash = self.nodes[0].getbestblockhash() - + # check binary format response = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"bin", True) assert_equal(response.status, 200) - assert_greater_than(int(response.getheader('content-length')), 10) - + assert_greater_than(int(response.getheader('content-length')), 80) + response_str = response.read() + + # compare with block header + response_header = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"bin", True) + assert_equal(response_header.status, 200) + assert_equal(int(response_header.getheader('content-length')), 80) + response_header_str = response_header.read() + assert_equal(response_str[0:80], response_header_str) + + # check block hex format + response_hex = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True) + assert_equal(response_hex.status, 200) + assert_greater_than(int(response_hex.getheader('content-length')), 160) + response_hex_str = response_hex.read() + assert_equal(response_str.encode("hex")[0:160], response_hex_str[0:160]) + + # compare with hex block header + response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True) + assert_equal(response_header_hex.status, 200) + assert_greater_than(int(response_header_hex.getheader('content-length')), 160) + response_header_hex_str = response_header_hex.read() + assert_equal(response_hex_str[0:160], response_header_hex_str[0:160]) + assert_equal(response_header_str.encode("hex")[0:160], response_header_hex_str[0:160]) + # check json format json_string = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+'json') json_obj = json.loads(json_string) assert_equal(json_obj['hash'], bb_hash) - + # do tx test tx_hash = json_obj['tx'][0]['txid']; json_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"json") json_obj = json.loads(json_string) assert_equal(json_obj['txid'], tx_hash) - + # check hex format response hex_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"hex", True) assert_equal(response.status, 200) assert_greater_than(int(response.getheader('content-length')), 10) - + # check block tx details # let's make 3 tx and mine them on node 1 txs = [] @@ -65,25 +88,23 @@ class RESTTest (BitcoinTestFramework): txs.append(self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)) txs.append(self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)) self.sync_all() - + # now mine the transactions newblockhash = self.nodes[1].setgenerate(True, 1) self.sync_all() - + #check if the 3 tx show up in the new block json_string = http_get_call(url.hostname, url.port, '/rest/block/'+newblockhash[0]+self.FORMAT_SEPARATOR+'json') json_obj = json.loads(json_string) for tx in json_obj['tx']: if not 'coinbase' in tx['vin'][0]: #exclude coinbase assert_equal(tx['txid'] in txs, True) - + #check the same but without tx details json_string = http_get_call(url.hostname, url.port, '/rest/block/notxdetails/'+newblockhash[0]+self.FORMAT_SEPARATOR+'json') json_obj = json.loads(json_string) for tx in txs: assert_equal(tx in json_obj['tx'], True) - - if __name__ == '__main__': RESTTest ().main () diff --git a/src/rest.cpp b/src/rest.cpp index 6329b44c535..c52dbb3cd24 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -89,6 +89,69 @@ static bool ParseHashStr(const string& strReq, uint256& v) return true; } +static bool rest_headers(AcceptedConnection* conn, + string& strReq, + map& mapHeaders, + bool fRun) +{ + vector params; + enum RetFormat rf = ParseDataFormat(params, strReq); + vector path; + boost::split(path, params[0], boost::is_any_of("/")); + + if (path.size() != 2) + throw RESTERR(HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers//.."); + + long count = strtol(path[0].c_str(), NULL, 10); + if (count < 1 || count > 2000) + throw RESTERR(HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); + + string hashStr = path[1]; + uint256 hash; + if (!ParseHashStr(hashStr, hash)) + throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + + std::vector headers; + headers.reserve(count); + { + LOCK(cs_main); + BlockMap::const_iterator it = mapBlockIndex.find(hash); + const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : NULL; + while (pindex != NULL && chainActive.Contains(pindex)) { + headers.push_back(pindex->GetBlockHeader()); + if (headers.size() == (unsigned long)count) + break; + pindex = chainActive.Next(pindex); + } + } + + CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); + BOOST_FOREACH(const CBlockHeader &header, headers) { + ssHeader << header; + } + + switch (rf) { + case RF_BINARY: { + string binaryHeader = ssHeader.str(); + conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryHeader.size(), "application/octet-stream") << binaryHeader << std::flush; + return true; + } + + case RF_HEX: { + string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; + conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + return true; + } + + default: { + throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + static bool rest_block(AcceptedConnection* conn, string& strReq, map& mapHeaders, @@ -224,6 +287,7 @@ static const struct { {"/rest/tx/", rest_tx}, {"/rest/block/notxdetails/", rest_block_notxdetails}, {"/rest/block/", rest_block_extended}, + {"/rest/headers/", rest_headers}, }; bool HTTPReq_REST(AcceptedConnection* conn, From 164a45f57a8a7367e67a5e65b9e938844730cd87 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Sat, 13 Dec 2014 09:03:33 +0000 Subject: [PATCH 0039/2337] Fix download link for gitian builds --- depends/packages/native_cdrkit.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/native_cdrkit.mk b/depends/packages/native_cdrkit.mk index 2cc388b4b30..cf694edb30e 100644 --- a/depends/packages/native_cdrkit.mk +++ b/depends/packages/native_cdrkit.mk @@ -1,6 +1,6 @@ package=native_cdrkit $(package)_version=1.1.11 -$(package)_download_path=http://distro.ibiblio.org/fatdog/source/c +$(package)_download_path=http://distro.ibiblio.org/fatdog/source/600/c $(package)_file_name=cdrkit-$($(package)_version).tar.bz2 $(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564 $(package)_patches=cdrkit-deterministic.patch From 26a6bae7537c73cb4b713293ce29b7c6d71a542d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Mon, 15 Dec 2014 11:06:15 +0100 Subject: [PATCH 0040/2337] Add time offset to getpeerinfo output --- src/main.cpp | 4 +++- src/net.cpp | 2 ++ src/net.h | 2 ++ src/rpcnet.cpp | 2 ++ src/timedata.cpp | 4 +--- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7533c32614b..d917c6e0ea5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3450,7 +3450,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->nStartingHeight, addrMe.ToString(), pfrom->id, remoteAddr); - AddTimeData(pfrom->addr, nTime); + int64_t nTimeOffset = nTime - GetTime(); + pfrom->nTimeOffset = nTimeOffset; + AddTimeData(pfrom->addr, nTimeOffset); } diff --git a/src/net.cpp b/src/net.cpp index 42b3c30fb77..95524a8b0f7 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -523,6 +523,7 @@ void CNode::copyStats(CNodeStats &stats) X(nLastSend); X(nLastRecv); X(nTimeConnected); + X(nTimeOffset); X(addrName); X(nVersion); X(cleanSubVer); @@ -1934,6 +1935,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn nSendBytes = 0; nRecvBytes = 0; nTimeConnected = GetTime(); + nTimeOffset = 0; addr = addrIn; addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; nVersion = 0; diff --git a/src/net.h b/src/net.h index a475be0b334..af200cf89e9 100644 --- a/src/net.h +++ b/src/net.h @@ -154,6 +154,7 @@ public: int64_t nLastSend; int64_t nLastRecv; int64_t nTimeConnected; + int64_t nTimeOffset; std::string addrName; int nVersion; std::string cleanSubVer; @@ -235,6 +236,7 @@ public: int64_t nLastSend; int64_t nLastRecv; int64_t nTimeConnected; + int64_t nTimeOffset; CAddress addr; std::string addrName; CService addrLocal; diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 6ddbd62fca8..e579856b1fa 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -91,6 +91,7 @@ Value getpeerinfo(const Array& params, bool fHelp) " \"bytessent\": n, (numeric) The total bytes sent\n" " \"bytesrecv\": n, (numeric) The total bytes received\n" " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"timeoffset\": ttt, (numeric) The time offset in seconds\n" " \"pingtime\": n, (numeric) ping time\n" " \"pingwait\": n, (numeric) ping wait\n" " \"version\": v, (numeric) The peer version, such as 7001\n" @@ -131,6 +132,7 @@ Value getpeerinfo(const Array& params, bool fHelp) obj.push_back(Pair("bytessent", stats.nSendBytes)); obj.push_back(Pair("bytesrecv", stats.nRecvBytes)); obj.push_back(Pair("conntime", stats.nTimeConnected)); + obj.push_back(Pair("timeoffset", stats.nTimeOffset)); obj.push_back(Pair("pingtime", stats.dPingTime)); if (stats.dPingWait > 0.0) obj.push_back(Pair("pingwait", stats.dPingWait)); diff --git a/src/timedata.cpp b/src/timedata.cpp index 59f7778db17..2192ed2eff0 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -40,10 +40,8 @@ static int64_t abs64(int64_t n) return (n >= 0 ? n : -n); } -void AddTimeData(const CNetAddr& ip, int64_t nTime) +void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) { - int64_t nOffsetSample = nTime - GetTime(); - LOCK(cs_nTimeOffset); // Ignore duplicates static set setKnown; From 73caf47dfe9c398aac75b5f6bcd1e0a644479a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Mon, 15 Dec 2014 11:07:55 +0100 Subject: [PATCH 0041/2337] Display time offset in the debug window's Peers tab --- src/qt/forms/rpcconsole.ui | 25 ++++++++++++++++++++++++- src/qt/guiutil.cpp | 5 +++++ src/qt/guiutil.h | 5 ++++- src/qt/rpcconsole.cpp | 1 + 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index c5ac371619c..c3cb20750b7 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -1043,7 +1043,30 @@ - + + + + Time Offset + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + Qt::Vertical diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index a1ae756c43e..98c556db755 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -843,4 +843,9 @@ QString formatPingTime(double dPingTime) return dPingTime == 0 ? QObject::tr("N/A") : QString(QObject::tr("%1 ms")).arg(QString::number((int)(dPingTime * 1000), 10)); } +QString formatTimeOffset(int64_t nTimeOffset) +{ + return QString(QObject::tr("%1 s")).arg(QString::number((int)nTimeOffset, 10)); +} + } // namespace GUIUtil diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 09c79db2d91..d39fad7d870 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -188,7 +188,10 @@ namespace GUIUtil /* Format a CNodeCombinedStats.dPingTime into a user-readable string or display N/A, if 0*/ QString formatPingTime(double dPingTime); - + + /* Format a CNodeCombinedStats.nTimeOffset into a user-readable string. */ + QString formatTimeOffset(int64_t nTimeOffset); + #if defined(Q_OS_MAC) && QT_VERSION >= 0x050000 // workaround for Qt OSX Bug: // https://bugreports.qt-project.org/browse/QTBUG-15631 diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 2d2d448b49f..4b7c5a96356 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -607,6 +607,7 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats) ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes)); ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected)); ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime)); + ui->timeoffset->setText(GUIUtil::formatTimeOffset(stats->nodeStats.nTimeOffset)); ui->peerVersion->setText(QString("%1").arg(stats->nodeStats.nVersion)); ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer)); ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound")); From 64849306905e625fd44d297e8d58c3e1dd98cb90 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 15 Dec 2014 14:38:25 -0800 Subject: [PATCH 0042/2337] Apply AreSane() checks to the fees from the network. 'Sane' was already defined by this code as: fee.GetFeePerK() > minRelayFee.GetFeePerK() * 10000 But sanity was only enforced for data loaded from disk. Note that this is a pretty expansive definition of 'sane': A 10 BTC fee is still passes the test if its on a 100kb transaction. This prevents a single insane fee on the network from making us reject our stored fee data at start. We still may reject valid saved fee state if minRelayFee is changed between executions. This also reduces the risk and limits the damage from a cascading failure where one party pays a bunch of insane fees which cases others to pay insane fees. --- src/txmempool.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 840eb536baa..dcdf5653fe8 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -91,22 +91,32 @@ public: * Used as belt-and-suspenders check when reading to detect * file corruption */ - bool AreSane(const std::vector& vecFee, const CFeeRate& minRelayFee) + static bool AreSane(const CFeeRate fee, const CFeeRate& minRelayFee) + { + if (fee < CFeeRate(0)) + return false; + if (fee.GetFeePerK() > minRelayFee.GetFeePerK() * 10000) + return false; + return true; + } + static bool AreSane(const std::vector& vecFee, const CFeeRate& minRelayFee) { BOOST_FOREACH(CFeeRate fee, vecFee) { - if (fee < CFeeRate(0)) - return false; - if (fee.GetFeePerK() > minRelayFee.GetFeePerK() * 10000) + if (!AreSane(fee, minRelayFee)) return false; } return true; } - bool AreSane(const std::vector vecPriority) + static bool AreSane(const double priority) + { + return priority >= 0; + } + static bool AreSane(const std::vector vecPriority) { BOOST_FOREACH(double priority, vecPriority) { - if (priority < 0) + if (!AreSane(priority)) return false; } return true; @@ -167,12 +177,12 @@ private: bool sufficientFee = (feeRate > minRelayFee); bool sufficientPriority = AllowFree(dPriority); const char* assignedTo = "unassigned"; - if (sufficientFee && !sufficientPriority) + if (sufficientFee && !sufficientPriority && CBlockAverage::AreSane(feeRate, minRelayFee)) { history[nBlocksTruncated].RecordFee(feeRate); assignedTo = "fee"; } - else if (sufficientPriority && !sufficientFee) + else if (sufficientPriority && !sufficientFee && CBlockAverage::AreSane(dPriority)) { history[nBlocksTruncated].RecordPriority(dPriority); assignedTo = "priority"; From 87e8e1ca8bbcfc37d52c701ea2b0a991fce0d2a7 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 16 Dec 2014 00:55:21 -0300 Subject: [PATCH 0043/2337] minor fix on script test data docs --- src/test/data/script_invalid.json | 2 +- src/test/data/script_valid.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 86d39b5c208..44e0dca8be2 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -1,5 +1,5 @@ [ -["Format is: [scriptPubKey, scriptSig, flags, ... comments]"], +["Format is: [scriptSig, scriptPubKey, flags, ... comments]"], ["It is evaluated as if there was a crediting coinbase transaction with two 0"], ["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], ["followed by a spending transaction which spends this output as only input (and"], diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index d3075de646a..a1b7b119efe 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -1,5 +1,5 @@ [ -["Format is: [scriptPubKey, scriptSig, flags, ... comments]"], +["Format is: [scriptSig, scriptPubKey, flags, ... comments]"], ["It is evaluated as if there was a crediting coinbase transaction with two 0"], ["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], ["followed by a spending transaction which spends this output as only input (and"], From 78253fcbad69b28f1c0c3cfc7f8dcaecbb68c390 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Sat, 13 Dec 2014 12:09:33 +0800 Subject: [PATCH 0044/2337] Remove references to X11 licence --- contrib/bitcoind.bash-completion | 2 +- contrib/devtools/symbol-check.py | 2 +- contrib/devtools/update-translations.py | 2 +- contrib/linearize/linearize-data.py | 2 +- contrib/linearize/linearize-hashes.py | 2 +- doc/README.md | 2 +- doc/README_windows.txt | 2 +- qa/rpc-tests/wallet.py | 2 +- qa/rpc-tests/walletbackup.py | 2 +- src/alert.h | 2 +- src/allocators.cpp | 2 +- src/allocators.h | 2 +- src/bitcoin-cli-res.rc | 2 +- src/bitcoin-cli.cpp | 2 +- src/bitcoin-tx.cpp | 2 +- src/bitcoind-res.rc | 2 +- src/bitcoind.cpp | 2 +- src/coincontrol.h | 2 +- src/compat.h | 2 +- src/core_io.h | 2 +- src/core_read.cpp | 2 +- src/core_write.cpp | 2 +- src/crypter.cpp | 2 +- src/db.cpp | 2 +- src/miner.cpp | 2 +- src/miner.h | 2 +- src/mruset.h | 2 +- src/net.cpp | 2 +- src/net.h | 2 +- src/netbase.cpp | 2 +- src/netbase.h | 2 +- src/noui.cpp | 2 +- src/noui.h | 2 +- src/pow.cpp | 2 +- src/pow.h | 2 +- src/primitives/block.cpp | 2 +- src/primitives/block.h | 2 +- src/protocol.cpp | 2 +- src/protocol.h | 2 +- src/qt/addressbookpage.cpp | 2 +- src/qt/addressbookpage.h | 2 +- src/qt/addresstablemodel.cpp | 2 +- src/qt/addresstablemodel.h | 2 +- src/qt/askpassphrasedialog.cpp | 2 +- src/qt/askpassphrasedialog.h | 2 +- src/qt/bitcoin.cpp | 2 +- src/qt/bitcoinaddressvalidator.cpp | 2 +- src/qt/bitcoinaddressvalidator.h | 2 +- src/qt/bitcoinamountfield.cpp | 2 +- src/qt/bitcoinamountfield.h | 2 +- src/qt/bitcoingui.cpp | 2 +- src/qt/bitcoingui.h | 2 +- src/qt/bitcoinunits.cpp | 2 +- src/qt/bitcoinunits.h | 2 +- src/qt/clientmodel.cpp | 2 +- src/qt/clientmodel.h | 2 +- src/qt/coincontroldialog.cpp | 2 +- src/qt/coincontroldialog.h | 2 +- src/qt/coincontroltreewidget.cpp | 2 +- src/qt/coincontroltreewidget.h | 2 +- src/qt/csvmodelwriter.cpp | 2 +- src/qt/csvmodelwriter.h | 2 +- src/qt/editaddressdialog.cpp | 2 +- src/qt/editaddressdialog.h | 2 +- src/qt/guiconstants.h | 2 +- src/qt/guiutil.cpp | 2 +- src/qt/guiutil.h | 2 +- src/qt/intro.cpp | 2 +- src/qt/intro.h | 2 +- src/qt/macdockiconhandler.h | 2 +- src/qt/macdockiconhandler.mm | 2 +- src/qt/macnotificationhandler.h | 2 +- src/qt/macnotificationhandler.mm | 2 +- src/qt/notificator.cpp | 2 +- src/qt/notificator.h | 2 +- src/qt/openuridialog.cpp | 2 +- src/qt/openuridialog.h | 2 +- src/qt/optionsdialog.cpp | 2 +- src/qt/optionsdialog.h | 2 +- src/qt/optionsmodel.cpp | 2 +- src/qt/optionsmodel.h | 2 +- src/qt/overviewpage.cpp | 2 +- src/qt/overviewpage.h | 2 +- src/qt/peertablemodel.cpp | 2 +- src/qt/peertablemodel.h | 2 +- src/qt/qvalidatedlineedit.cpp | 2 +- src/qt/qvalidatedlineedit.h | 2 +- src/qt/qvaluecombobox.cpp | 2 +- src/qt/qvaluecombobox.h | 2 +- src/qt/receivecoinsdialog.cpp | 2 +- src/qt/receivecoinsdialog.h | 2 +- src/qt/receiverequestdialog.cpp | 2 +- src/qt/receiverequestdialog.h | 2 +- src/qt/recentrequeststablemodel.cpp | 2 +- src/qt/recentrequeststablemodel.h | 2 +- src/qt/res/bitcoin-qt-res.rc | 2 +- src/qt/rpcconsole.cpp | 2 +- src/qt/rpcconsole.h | 2 +- src/qt/sendcoinsdialog.cpp | 2 +- src/qt/sendcoinsdialog.h | 2 +- src/qt/sendcoinsentry.cpp | 2 +- src/qt/sendcoinsentry.h | 2 +- src/qt/signverifymessagedialog.cpp | 2 +- src/qt/signverifymessagedialog.h | 2 +- src/qt/splashscreen.cpp | 2 +- src/qt/splashscreen.h | 2 +- src/qt/trafficgraphwidget.cpp | 2 +- src/qt/trafficgraphwidget.h | 2 +- src/qt/transactiondesc.cpp | 2 +- src/qt/transactiondesc.h | 2 +- src/qt/transactiondescdialog.cpp | 2 +- src/qt/transactiondescdialog.h | 2 +- src/qt/transactionfilterproxy.cpp | 2 +- src/qt/transactionfilterproxy.h | 2 +- src/qt/transactionrecord.cpp | 2 +- src/qt/transactionrecord.h | 2 +- src/qt/transactiontablemodel.cpp | 2 +- src/qt/transactiontablemodel.h | 2 +- src/qt/transactionview.cpp | 2 +- src/qt/transactionview.h | 2 +- src/qt/utilitydialog.cpp | 2 +- src/qt/utilitydialog.h | 2 +- src/qt/walletframe.cpp | 2 +- src/qt/walletframe.h | 2 +- src/qt/walletmodel.cpp | 2 +- src/qt/walletmodel.h | 2 +- src/qt/walletmodeltransaction.cpp | 2 +- src/qt/walletmodeltransaction.h | 2 +- src/qt/walletview.cpp | 2 +- src/qt/walletview.h | 2 +- src/qt/winshutdownmonitor.cpp | 2 +- src/qt/winshutdownmonitor.h | 2 +- src/random.cpp | 2 +- src/random.h | 2 +- src/streams.h | 2 +- src/sync.cpp | 2 +- src/sync.h | 2 +- src/test/Checkpoints_tests.cpp | 2 +- src/test/DoS_tests.cpp | 2 +- src/test/accounting_tests.cpp | 2 +- src/test/alert_tests.cpp | 2 +- src/test/allocator_tests.cpp | 2 +- src/test/base32_tests.cpp | 2 +- src/test/base58_tests.cpp | 2 +- src/test/base64_tests.cpp | 2 +- src/test/bctest.py | 2 +- src/test/bignum.h | 2 +- src/test/bip32_tests.cpp | 2 +- src/test/bitcoin-util-test.py | 2 +- src/test/bloom_tests.cpp | 2 +- src/test/checkblock_tests.cpp | 2 +- src/test/compress_tests.cpp | 2 +- src/test/crypto_tests.cpp | 2 +- src/test/data/README.md | 2 +- src/test/getarg_tests.cpp | 2 +- src/test/hash_tests.cpp | 2 +- src/test/key_tests.cpp | 2 +- src/test/main_tests.cpp | 2 +- src/test/miner_tests.cpp | 2 +- src/test/mruset_tests.cpp | 2 +- src/test/multisig_tests.cpp | 2 +- src/test/netbase_tests.cpp | 2 +- src/test/pmt_tests.cpp | 2 +- src/test/rpc_tests.cpp | 2 +- src/test/rpc_wallet_tests.cpp | 2 +- src/test/script_P2SH_tests.cpp | 2 +- src/test/scriptnum_tests.cpp | 2 +- src/test/serialize_tests.cpp | 2 +- src/test/sighash_tests.cpp | 2 +- src/test/sigopcount_tests.cpp | 2 +- src/test/skiplist_tests.cpp | 2 +- src/test/test_bitcoin.cpp | 2 +- src/test/timedata_tests.cpp | 2 +- src/test/transaction_tests.cpp | 2 +- src/test/uint256_tests.cpp | 2 +- src/test/univalue_tests.cpp | 2 +- src/test/util_tests.cpp | 2 +- src/test/wallet_tests.cpp | 2 +- src/threadsafety.h | 2 +- src/txdb.cpp | 2 +- src/ui_interface.h | 2 +- src/uint256.cpp | 2 +- src/univalue/gen.cpp | 2 +- src/univalue/univalue.cpp | 2 +- src/univalue/univalue.h | 2 +- src/univalue/univalue_read.cpp | 2 +- src/univalue/univalue_write.cpp | 2 +- src/walletdb.cpp | 2 +- src/walletdb.h | 2 +- 189 files changed, 189 insertions(+), 189 deletions(-) diff --git a/contrib/bitcoind.bash-completion b/contrib/bitcoind.bash-completion index 37ece258996..3cc959c0a6d 100644 --- a/contrib/bitcoind.bash-completion +++ b/contrib/bitcoind.bash-completion @@ -1,6 +1,6 @@ # bash programmable completion for bitcoind(1) and bitcoin-cli(1) # Copyright (c) 2012,2014 Christian von Roques -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. have bitcoind && { diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index f3999f1c0b5..fad891f800e 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -1,6 +1,6 @@ #!/usr/bin/python # Copyright (c) 2014 Wladimir J. van der Laan -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' A script to check that the (Linux) executables produced by gitian only contain diff --git a/contrib/devtools/update-translations.py b/contrib/devtools/update-translations.py index 0be632069a9..f955e4a1f22 100755 --- a/contrib/devtools/update-translations.py +++ b/contrib/devtools/update-translations.py @@ -1,6 +1,6 @@ #!/usr/bin/python # Copyright (c) 2014 Wladimir J. van der Laan -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Run this script from the root of the repository to update all translations from diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index f59fe9f6e76..4079844e331 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -3,7 +3,7 @@ # linearize-data.py: Construct a linear, no-fork version of the chain. # # Copyright (c) 2013-2014 The Bitcoin developers -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/contrib/linearize/linearize-hashes.py b/contrib/linearize/linearize-hashes.py index dc7f6540499..707dfcf87e5 100755 --- a/contrib/linearize/linearize-hashes.py +++ b/contrib/linearize/linearize-hashes.py @@ -3,7 +3,7 @@ # linearize-hashes.py: List blocks in a linear, no-fork version of the chain. # # Copyright (c) 2013-2014 The Bitcoin developers -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/doc/README.md b/doc/README.md index 3ec5f11df27..812d8bf1f74 100644 --- a/doc/README.md +++ b/doc/README.md @@ -71,6 +71,6 @@ The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/ License --------------------- -Distributed under the [MIT/X11 software license](http://www.opensource.org/licenses/mit-license.php). +Distributed under the [MIT software license](http://www.opensource.org/licenses/mit-license.php). This product includes software developed by the OpenSSL Project for use in the [OpenSSL Toolkit](https://www.openssl.org/). This product includes cryptographic software written by Eric Young ([eay@cryptsoft.com](mailto:eay@cryptsoft.com)), and UPnP software written by Thomas Bernard. diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 9780a2cb134..226ce4576e3 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -2,7 +2,7 @@ Bitcoin 0.10.99 BETA Copyright (c) 2009-2014 Bitcoin Core Developers -Distributed under the MIT/X11 software license, see the accompanying +Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php. This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (https://www.openssl.org/). This product includes diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index bf71d5ebc51..d99540b58a6 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2 # Copyright (c) 2014 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index 6a42d9dfa4e..049697c2db5 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2 # Copyright (c) 2014 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """ diff --git a/src/alert.h b/src/alert.h index 96c203b557c..de4aad81479 100644 --- a/src/alert.h +++ b/src/alert.h @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_ALERT_H diff --git a/src/allocators.cpp b/src/allocators.cpp index dfe26f1b1e2..b1a6a8f98ec 100644 --- a/src/allocators.cpp +++ b/src/allocators.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "allocators.h" diff --git a/src/allocators.h b/src/allocators.h index 78a3b76d0cd..599a4ddc41a 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_ALLOCATORS_H diff --git a/src/bitcoin-cli-res.rc b/src/bitcoin-cli-res.rc index b1aa1b0e167..4ea1f38e47e 100644 --- a/src/bitcoin-cli-res.rc +++ b/src/bitcoin-cli-res.rc @@ -21,7 +21,7 @@ BEGIN VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-cli" VALUE "LegalCopyright", COPYRIGHT_STR - VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." VALUE "OriginalFilename", "bitcoin-cli.exe" VALUE "ProductName", "Bitcoin-cli" VALUE "ProductVersion", VER_PRODUCTVERSION_STR diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index ea349b197e5..e7e04b3ecfc 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chainparamsbase.h" diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 7308d936617..582f04f3dce 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" diff --git a/src/bitcoind-res.rc b/src/bitcoind-res.rc index 2e6d7544950..d183179b171 100644 --- a/src/bitcoind-res.rc +++ b/src/bitcoind-res.rc @@ -21,7 +21,7 @@ BEGIN VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoind" VALUE "LegalCopyright", COPYRIGHT_STR - VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." VALUE "OriginalFilename", "bitcoind.exe" VALUE "ProductName", "Bitcoind" VALUE "ProductVersion", VER_PRODUCTVERSION_STR diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index be7757b0b6c..ea945f54f6f 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "clientversion.h" diff --git a/src/coincontrol.h b/src/coincontrol.h index cf619987237..634cc3a298d 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_COINCONTROL_H diff --git a/src/compat.h b/src/compat.h index dffd4ecf52f..44bf0d1ff5e 100644 --- a/src/compat.h +++ b/src/compat.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_COMPAT_H diff --git a/src/core_io.h b/src/core_io.h index aba1928a366..c805dbc6d5d 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_CORE_IO_H diff --git a/src/core_read.cpp b/src/core_read.cpp index 65c3a08c551..1de92594cd4 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "core_io.h" diff --git a/src/core_write.cpp b/src/core_write.cpp index 760b6a71bf7..400b4c623df 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "core_io.h" diff --git a/src/crypter.cpp b/src/crypter.cpp index 756538836df..de32dc412cd 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "crypter.h" diff --git a/src/db.cpp b/src/db.cpp index 12650e459f3..cb24912fe0b 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "db.h" diff --git a/src/miner.cpp b/src/miner.cpp index ad294314212..ce675256795 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "miner.h" diff --git a/src/miner.h b/src/miner.h index aede0e6d4b0..998ea57a76d 100644 --- a/src/miner.h +++ b/src/miner.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_MINER_H diff --git a/src/mruset.h b/src/mruset.h index 1691875f57b..bf7c7fdeeaa 100644 --- a/src/mruset.h +++ b/src/mruset.h @@ -1,5 +1,5 @@ // Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_MRUSET_H diff --git a/src/net.cpp b/src/net.cpp index 42b3c30fb77..e6a066a4e2e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) diff --git a/src/net.h b/src/net.h index a475be0b334..c705a85c803 100644 --- a/src/net.h +++ b/src/net.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_NET_H diff --git a/src/netbase.cpp b/src/netbase.cpp index 053c645a1be..1fc3334b7b8 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifdef HAVE_CONFIG_H diff --git a/src/netbase.h b/src/netbase.h index 09fe094946e..fe5d64320c9 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_NETBASE_H diff --git a/src/noui.cpp b/src/noui.cpp index 8f3b0275b00..630b095d0b7 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "noui.h" diff --git a/src/noui.h b/src/noui.h index dbd4320fa7f..c7e4aaa1e1b 100644 --- a/src/noui.h +++ b/src/noui.h @@ -1,5 +1,5 @@ // Copyright (c) 2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_NOUI_H diff --git a/src/pow.cpp b/src/pow.cpp index bdcfa852f40..3b41083f9d0 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "pow.h" diff --git a/src/pow.h b/src/pow.h index cf28656bd8a..293634be6f6 100644 --- a/src/pow.h +++ b/src/pow.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_POW_H diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 225bb80be81..cf7a392a32d 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "primitives/block.h" diff --git a/src/primitives/block.h b/src/primitives/block.h index a1895925395..9c0a6deccaf 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_PRIMITIVES_BLOCK_H diff --git a/src/protocol.cpp b/src/protocol.cpp index 72fdd753a81..f8f43a05f77 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "protocol.h" diff --git a/src/protocol.h b/src/protocol.h index 2ac8f3d8f7f..e578c1ec999 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef __cplusplus diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index f336d47e83e..303c7c2335a 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 031c424785f..b3c308dc0b1 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_ADDRESSBOOKPAGE_H diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 8d5284d5e9f..c42a55ec27e 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "addresstablemodel.h" diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 310647d7c30..33504e0c694 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_ADDRESSTABLEMODEL_H diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index fa9ac6b135c..dbfab0e9389 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "askpassphrasedialog.h" diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index 66050860606..bedbea21351 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_ASKPASSPHRASEDIALOG_H diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 123777a71bc..962a44f0792 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp index 293cc168b97..d7c4d27066d 100644 --- a/src/qt/bitcoinaddressvalidator.cpp +++ b/src/qt/bitcoinaddressvalidator.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bitcoinaddressvalidator.h" diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h index 15a6245da4e..5689266081d 100644 --- a/src/qt/bitcoinaddressvalidator.h +++ b/src/qt/bitcoinaddressvalidator.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_BITCOINADDRESSVALIDATOR_H diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index 5b8ab23b26a..408634dec03 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bitcoinamountfield.h" diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index 1bad8ce1b8c..4bab91eaf0b 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_BITCOINAMOUNTFIELD_H diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 6a457d361fe..4366a42ff84 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bitcoingui.h" diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 662ef9d9e84..7cda8c15cb9 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_BITCOINGUI_H diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 5c542b59ae4..863d4a01aa7 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bitcoinunits.h" diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index 7a4f38274d5..c40fd8b16cd 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_BITCOINUNITS_H diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index aedda490719..a121ec5879b 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "clientmodel.h" diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index c7a05e287d0..5a8b436602a 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_CLIENTMODEL_H diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 85b43b7b1f5..5647661ba57 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "coincontroldialog.h" diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index bd4f5d7f1ed..8945bf18050 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_COINCONTROLDIALOG_H diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp index 907b5caa056..bb8f385bb20 100644 --- a/src/qt/coincontroltreewidget.cpp +++ b/src/qt/coincontroltreewidget.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "coincontroltreewidget.h" diff --git a/src/qt/coincontroltreewidget.h b/src/qt/coincontroltreewidget.h index 643eaf0c709..e9bfe2352b5 100644 --- a/src/qt/coincontroltreewidget.h +++ b/src/qt/coincontroltreewidget.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_COINCONTROLTREEWIDGET_H diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp index ac8c6b41d42..a998850198e 100644 --- a/src/qt/csvmodelwriter.cpp +++ b/src/qt/csvmodelwriter.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "csvmodelwriter.h" diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h index c613ce73eb5..d3cf5d732c1 100644 --- a/src/qt/csvmodelwriter.h +++ b/src/qt/csvmodelwriter.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_CSVMODELWRITER_H diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 46982cc339c..2be7598e7b8 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "editaddressdialog.h" diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index aa1103a2f51..e25db7a1165 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_EDITADDRESSDIALOG_H diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 8f3e476fd9a..819e5c9e275 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_GUICONSTANTS_H diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index a1ae756c43e..5adf17361b7 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "guiutil.h" diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 09c79db2d91..73b63789be9 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_GUIUTIL_H diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 7618bff69d9..5cf53cdcbe8 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "intro.h" diff --git a/src/qt/intro.h b/src/qt/intro.h index c9c0d448faa..03974841b52 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_INTRO_H diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 1ffab75c9a1..98913698467 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_MACDOCKICONHANDLER_H diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index a2ff148d9da..e7b58b9cc07 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "macdockiconhandler.h" diff --git a/src/qt/macnotificationhandler.h b/src/qt/macnotificationhandler.h index f7a4cb7f5b0..c08c3279945 100644 --- a/src/qt/macnotificationhandler.h +++ b/src/qt/macnotificationhandler.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_MACNOTIFICATIONHANDLER_H diff --git a/src/qt/macnotificationhandler.mm b/src/qt/macnotificationhandler.mm index aa50a0d9fbb..dd3f622818a 100644 --- a/src/qt/macnotificationhandler.mm +++ b/src/qt/macnotificationhandler.mm @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "macnotificationhandler.h" diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 3d588cd3171..86b205ed8a9 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "notificator.h" diff --git a/src/qt/notificator.h b/src/qt/notificator.h index 61c27e7ff88..a7605f83bec 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_NOTIFICATOR_H diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index 06189aeaf3e..a1de7aceaed 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "openuridialog.h" diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index f04ec71b32c..4f4fdccaf5e 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_OPENURIDIALOG_H diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 069080219e2..8ce9fd7a6e4 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index 511719f53c5..0197491506d 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 7054509fe6f..1e11de3c115 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 84fd49a7b8b..061ae1ad92d 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_OPTIONSMODEL_H diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 669d5474fd6..18c900d025c 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "overviewpage.h" diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index e889eae8be0..803816fa41d 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_OVERVIEWPAGE_H diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index cfa05300cff..7840b9283ed 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "peertablemodel.h" diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index 23e71fc685f..ac3a18c0539 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_PEERTABLEMODEL_H diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp index c2567835c91..d960e4b1960 100644 --- a/src/qt/qvalidatedlineedit.cpp +++ b/src/qt/qvalidatedlineedit.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "qvalidatedlineedit.h" diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h index 0996164b0fe..810d5f27698 100644 --- a/src/qt/qvalidatedlineedit.h +++ b/src/qt/qvalidatedlineedit.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_QVALIDATEDLINEEDIT_H diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index ad083f63571..8c578dfa5e0 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "qvaluecombobox.h" diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index 821f41716b5..62b1d90ddf6 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_QVALUECOMBOBOX_H diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index f2c76c83555..ee3a046aa24 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "receivecoinsdialog.h" diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 220fb5c7a81..ae93b5aa85a 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_RECEIVECOINSDIALOG_H diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index cc2f00916f2..9d932cfc903 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "receiverequestdialog.h" diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 6f3b9838e26..b69ef42573e 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_RECEIVEREQUESTDIALOG_H diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 5533adab8b9..adc4e115ed6 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "recentrequeststablemodel.h" diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index ec6a49070da..741a8148f04 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_RECENTREQUESTSTABLEMODEL_H diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc index 809235be5f9..d71438d21af 100644 --- a/src/qt/res/bitcoin-qt-res.rc +++ b/src/qt/res/bitcoin-qt-res.rc @@ -24,7 +24,7 @@ BEGIN VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-qt" VALUE "LegalCopyright", COPYRIGHT_STR - VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." VALUE "OriginalFilename", "bitcoin-qt.exe" VALUE "ProductName", "Bitcoin Core" VALUE "ProductVersion", VER_PRODUCTVERSION_STR diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 2d2d448b49f..6f2efa00975 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcconsole.h" diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 4bb9b62e932..eda10332907 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_RPCCONSOLE_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 46eb58ca439..0e331e21d58 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "sendcoinsdialog.h" diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 15d39782a1e..9db9252f7df 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_SENDCOINSDIALOG_H diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 52545c3857b..6a71081993d 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "sendcoinsentry.h" diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 69ad1032df9..b3d846c949c 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_SENDCOINSENTRY_H diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index d4d021e21c1..c793262adda 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "signverifymessagedialog.h" diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index 36550edc8d7..d8e240b555b 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_SIGNVERIFYMESSAGEDIALOG_H diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index b4b81440ca8..f65ceac624e 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "splashscreen.h" diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 4d9651f022f..63eb0714c02 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_SPLASHSCREEN_H diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 5f14b807976..a1a03b2971e 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "trafficgraphwidget.h" diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h index 50571e0b2d2..18336de949c 100644 --- a/src/qt/trafficgraphwidget.h +++ b/src/qt/trafficgraphwidget.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_TRAFFICGRAPHWIDGET_H diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 1efad8259bb..ed8be628a6a 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "transactiondesc.h" diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h index fc958a097c4..04f54ba08e9 100644 --- a/src/qt/transactiondesc.h +++ b/src/qt/transactiondesc.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_TRANSACTIONDESC_H diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp index 5ca575fdd47..56e1fc050b6 100644 --- a/src/qt/transactiondescdialog.cpp +++ b/src/qt/transactiondescdialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "transactiondescdialog.h" diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h index c12c18e824c..f10a1362175 100644 --- a/src/qt/transactiondescdialog.h +++ b/src/qt/transactiondescdialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_TRANSACTIONDESCDIALOG_H diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index 2a0f621d1e3..67733d31187 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "transactionfilterproxy.h" diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index 5836b114ab2..42f4df4d652 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_TRANSACTIONFILTERPROXY_H diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 5278c8673a2..9905ca76f9a 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "transactionrecord.h" diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index e26453cda47..3accbb26eeb 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_TRANSACTIONRECORD_H diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 79cb4a62966..73e3d9de7dd 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "transactiontablemodel.h" diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index cfefe4cf193..525b23bfe8e 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_TRANSACTIONTABLEMODEL_H diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index d1539738721..58f33f95a72 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "transactionview.h" diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index be6989adee2..baad0fcbfb0 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_TRANSACTIONVIEW_H diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 58bf0406248..929f8156dc3 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "utilitydialog.h" diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index e10b4dc8afa..1cbded02532 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_UTILITYDIALOG_H diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index fead0229285..4084adc96cb 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "walletframe.h" diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index ae8592840d5..68bd1ce219d 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_WALLETFRAME_H diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index b20465794d0..8355125c4df 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "walletmodel.h" diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index d7e391f8d16..17f1b9f2e94 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_WALLETMODEL_H diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index e9e20c7d519..a9183d11abc 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "walletmodeltransaction.h" diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index 4272529abe0..48bcbc88419 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_WALLETMODELTRANSACTION_H diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 9bab180108c..77db9757fbb 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "walletview.h" diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 95890ccd67e..6c2c3ca61e5 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_WALLETVIEW_H diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp index a06f42f66eb..51391a9331a 100644 --- a/src/qt/winshutdownmonitor.cpp +++ b/src/qt/winshutdownmonitor.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "winshutdownmonitor.h" diff --git a/src/qt/winshutdownmonitor.h b/src/qt/winshutdownmonitor.h index 26f5d803616..a8176f95146 100644 --- a/src/qt/winshutdownmonitor.h +++ b/src/qt/winshutdownmonitor.h @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_WINSHUTDOWNMONITOR_H diff --git a/src/random.cpp b/src/random.cpp index fc9505ae73d..3a1311cb595 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "random.h" diff --git a/src/random.h b/src/random.h index aa55ca2b6f3..214ee0a7979 100644 --- a/src/random.h +++ b/src/random.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_RANDOM_H diff --git a/src/streams.h b/src/streams.h index b07b11eb3da..ba074a4c23e 100644 --- a/src/streams.h +++ b/src/streams.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_STREAMS_H diff --git a/src/sync.cpp b/src/sync.cpp index ef35c9d646a..e2f05e62a0b 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "sync.h" diff --git a/src/sync.h b/src/sync.h index cd0aa7b20e7..29006b3ed9a 100644 --- a/src/sync.h +++ b/src/sync.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SYNC_H diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 8f70f18c7c0..4ea6a91d543 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index f9746fdaa5c..9407511ecb8 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index af2a9a214f0..bed63991e62 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "wallet.h" diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 4869ba52acc..c77a360d0b8 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 69888da3dfa..991b4ac0999 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "util.h" diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index 68617abbdd5..5d20a90ad0c 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "utilstrencodings.h" diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index e495435b817..e7d02818818 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index f2bf3326ad8..9e6cb342ccd 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "utilstrencodings.h" diff --git a/src/test/bctest.py b/src/test/bctest.py index ef461014eab..3a8d0ea51bf 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -1,5 +1,5 @@ # Copyright 2014 BitPay, Inc. -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import subprocess diff --git a/src/test/bignum.h b/src/test/bignum.h index f64c9872025..7ed62606f8b 100644 --- a/src/test/bignum.h +++ b/src/test/bignum.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_TEST_BIGNUM_H diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 9cf07fc38cc..3d28e06ffc7 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py index 0eece14cfe3..20afb16a9eb 100755 --- a/src/test/bitcoin-util-test.py +++ b/src/test/bitcoin-util-test.py @@ -1,6 +1,6 @@ #!/usr/bin/python # Copyright 2014 BitPay, Inc. -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import os diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 2de226fdd65..c32098efa09 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bloom.h" diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index fc36b43e16e..a4121caa8b2 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index bf404cf0cfa..b4e4f2046f5 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "compressor.h" diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 26708f5071a..47bfd710cde 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "crypto/rfc6979_hmac_sha256.h" diff --git a/src/test/data/README.md b/src/test/data/README.md index f69a021ca0a..55ac95739c7 100644 --- a/src/test/data/README.md +++ b/src/test/data/README.md @@ -9,6 +9,6 @@ License The data files in this directory are Copyright (c) 2012-2014 The Bitcoin Core developers - Distributed under the MIT/X11 software license, see the accompanying + Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index 8a984304f4e..5fb0f4ccdd8 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "util.h" diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index b8e290f071f..f1ad25e6ee9 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "hash.h" diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 43b18ce61e5..1333aba4716 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "key.h" diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index bf57dd81d9f..2a72a220a48 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "primitives/transaction.h" diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 53c2e7b2619..44c57a8eaf2 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "main.h" diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp index 547cd1090c5..813ec9b8b20 100644 --- a/src/test/mruset_tests.cpp +++ b/src/test/mruset_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "mruset.h" diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 8d06caa147c..42a159cda27 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "key.h" diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index c26e7383842..93614599492 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "netbase.h" diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 3b535a84fd8..807a5d1e5fd 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "merkleblock.h" diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index d5475a92bfa..c7355d1e33c 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcserver.h" diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 91da0c4420d..a83bd120cab 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcserver.h" diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index a969eefa053..63553556ec0 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "key.h" diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index 5621e127293..cfbaf26e703 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bignum.h" diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 59e95f2fd12..fe49af711bd 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "serialize.h" diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 8abde887cee..a9d2f9e8cad 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "data/sighash.json.h" diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 5bf0862c714..3326601492a 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "pubkey.h" diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index a123f1d197f..646c7e6aded 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "main.h" diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index e50218d8efb..f2dae99d693 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #define BOOST_TEST_MODULE Bitcoin Test Suite diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index aa4fa0d500e..58ed963274e 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // #include "timedata.h" diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index e939e899725..2594f89ac3e 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "data/tx_invalid.json.h" diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index 4b1a2ae58f4..d05b28956c4 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 23bc5f6b126..5f0c1deb8e2 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay, Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index feea1403511..1c5778abed5 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "util.h" diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp index 90fc470e064..289cc8c9055 100644 --- a/src/test/wallet_tests.cpp +++ b/src/test/wallet_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "wallet.h" diff --git a/src/threadsafety.h b/src/threadsafety.h index 7515d050e72..5409c030186 100644 --- a/src/threadsafety.h +++ b/src/threadsafety.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_THREADSAFETY_H diff --git a/src/txdb.cpp b/src/txdb.cpp index 29ef3503749..44f7d15da14 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "txdb.h" diff --git a/src/ui_interface.h b/src/ui_interface.h index 1231d5ed0bc..8d63e0464c3 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_UI_INTERFACE_H diff --git a/src/uint256.cpp b/src/uint256.cpp index 79406f24757..9dbf68aeeaa 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "uint256.h" diff --git a/src/univalue/gen.cpp b/src/univalue/gen.cpp index f0b352eef08..abebe886349 100644 --- a/src/univalue/gen.cpp +++ b/src/univalue/gen.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index b0171e48c41..4e445a542a9 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index 5ac301d9e5c..88d73b8c64f 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -1,5 +1,5 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_UNIVALUE_UNIVALUE_H diff --git a/src/univalue/univalue_read.cpp b/src/univalue/univalue_read.cpp index 405be3e81f8..5cea7789961 100644 --- a/src/univalue/univalue_read.cpp +++ b/src/univalue/univalue_read.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp index 9565cfa11a7..9a1d364c95b 100644 --- a/src/univalue/univalue_write.cpp +++ b/src/univalue/univalue_write.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include diff --git a/src/walletdb.cpp b/src/walletdb.cpp index ffddd8106b3..d2233aeea30 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "walletdb.h" diff --git a/src/walletdb.h b/src/walletdb.h index 7ff41c7c8d4..38699043ba1 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_WALLETDB_H From 1340f00200016c5891f894493d3c0b66e5105bfe Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 9 Dec 2014 17:31:23 +0100 Subject: [PATCH 0045/2337] [RPC-TESTS] ability to run single test manually adds possibility to run ./qa/pull-tester/rpc-tests.sh --- qa/pull-tester/rpc-tests.sh | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index d6ee00bb7df..15cac145957 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -15,18 +15,28 @@ fi #Run the tests +testScripts=( + 'wallet.py' + 'listtransactions.py' + 'mempool_resurrect_test.py' + 'txn_doublespend.py' + 'txn_doublespend.py --mineblock' + 'getchaintips.py' + 'rest.py' + 'mempool_spendcoinbase.py' + 'mempool_coinbase_spends.py' + 'httpbasics.py' +# 'forknotify.py' +); if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then - ${BUILDDIR}/qa/rpc-tests/wallet.py --srcdir "${BUILDDIR}/src" - ${BUILDDIR}/qa/rpc-tests/listtransactions.py --srcdir "${BUILDDIR}/src" - ${BUILDDIR}/qa/rpc-tests/mempool_resurrect_test.py --srcdir "${BUILDDIR}/src" - ${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --srcdir "${BUILDDIR}/src" - ${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --mineblock --srcdir "${BUILDDIR}/src" - ${BUILDDIR}/qa/rpc-tests/getchaintips.py --srcdir "${BUILDDIR}/src" - ${BUILDDIR}/qa/rpc-tests/rest.py --srcdir "${BUILDDIR}/src" - ${BUILDDIR}/qa/rpc-tests/mempool_spendcoinbase.py --srcdir "${BUILDDIR}/src" - ${BUILDDIR}/qa/rpc-tests/httpbasics.py --srcdir "${BUILDDIR}/src" - ${BUILDDIR}/qa/rpc-tests/mempool_coinbase_spends.py --srcdir "${BUILDDIR}/src" - #${BUILDDIR}/qa/rpc-tests/forknotify.py --srcdir "${BUILDDIR}/src" + for (( i = 0; i < ${#testScripts[@]}; i++ )) + do + if [ -z "$1" ] || [ "$1" == "${testScripts[$i]}" ] || [ "$1.py" == "${testScripts[$i]}" ] + then + echo -e "running testscript \033[1m${testScripts[$i]}...\033[0m" + ${BUILDDIR}/qa/rpc-tests/${testScripts[$i]} --srcdir "${BUILDDIR}/src" + fi + done else echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled" fi From 54f2571a00632e9813b9fabb447c7cc80f74ad29 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 6 Nov 2014 16:28:29 +0100 Subject: [PATCH 0046/2337] Qt: HiDPI (retina) support for splash screen - remove splash screen images (reduce binary size) - dynamicly draw splash screen with available icon. - remove testnet icon - dynamicly colorize testnet icon --- doc/assets-attribution.md | 3 +- src/Makefile.qt.include | 8 +-- src/qt/bitcoin.qrc | 3 - src/qt/networkstyle.cpp | 92 +++++++++++++++++++++++---- src/qt/networkstyle.h | 10 +-- src/qt/res/bitcoin-qt-res.rc | 1 - src/qt/res/icons/bitcoin.png | Bin 32547 -> 350390 bytes src/qt/res/icons/bitcoin_testnet.ico | Bin 45855 -> 0 bytes src/qt/res/icons/bitcoin_testnet.png | Bin 28227 -> 0 bytes src/qt/res/images/splash.png | Bin 43398 -> 0 bytes src/qt/res/images/splash_testnet.png | Bin 34142 -> 0 bytes src/qt/splashscreen.cpp | 41 ++++++++++-- 12 files changed, 122 insertions(+), 36 deletions(-) delete mode 100755 src/qt/res/icons/bitcoin_testnet.ico delete mode 100644 src/qt/res/icons/bitcoin_testnet.png delete mode 100644 src/qt/res/images/splash.png delete mode 100644 src/qt/res/images/splash_testnet.png diff --git a/doc/assets-attribution.md b/doc/assets-attribution.md index 082bd41495f..6c5f91a834d 100644 --- a/doc/assets-attribution.md +++ b/doc/assets-attribution.md @@ -49,8 +49,7 @@ Jonas Schnelli src/qt/res/icons/tx_output.png, src/qt/res/icons/bitcoin.icns, src/qt/res/src/bitcoin.svg, src/qt/res/src/bitcoin.ico, src/qt/res/src/bitcoin.png, src/qt/res/src/bitcoin_testnet.png, - docs/bitcoin_logo_doxygen.png, src/qt/res/images/splash.png, - src/qt/res/images/splash_testnet.png, src/qt/res/src/tx*.svg, + docs/bitcoin_logo_doxygen.png, src/qt/res/src/tx*.svg, src/qt/res/src/connect*.svg, src/qt/res/src/clock*.svg, src/qt/res/src/mine.svg, src/qt/res/src/qt.svg, src/qt/res/src/verify.svg, diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 4c455483a01..25d76c146b9 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -216,8 +216,6 @@ RES_ICONS = \ qt/res/icons/about_qt.png \ qt/res/icons/bitcoin.ico \ qt/res/icons/bitcoin.png \ - qt/res/icons/bitcoin_testnet.ico \ - qt/res/icons/bitcoin_testnet.png \ qt/res/icons/clock1.png \ qt/res/icons/clock2.png \ qt/res/icons/clock3.png \ @@ -315,9 +313,7 @@ BITCOIN_QT_CPP += \ endif RES_IMAGES = \ - qt/res/images/about.png \ - qt/res/images/splash.png \ - qt/res/images/splash_testnet.png + qt/res/images/about.png RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png) @@ -371,7 +367,7 @@ qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX #locale/foo.ts -> locale/foo.qm QT_QM=$(QT_TS:.ts=.qm) -.SECONDARY: $(QT_QM) +SECONDARY: $(QT_QM) qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index cd71b4b3fcc..b54f2e2ed66 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -25,7 +25,6 @@ res/icons/editpaste.png res/icons/editcopy.png res/icons/add.png - res/icons/bitcoin_testnet.png res/icons/edit.png res/icons/history.png res/icons/overview.png @@ -52,8 +51,6 @@ res/images/about.png - res/images/splash.png - res/images/splash_testnet.png res/movies/spinner-000.png diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 62c44703f47..b8112799df1 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -11,22 +11,22 @@ static const struct { const char *networkId; const char *appName; - const char *appIcon; + const int iconColorHueShift; + const int iconColorSaturationReduction; const char *titleAddText; - const char *splashImage; } network_styles[] = { - {"main", QAPP_APP_NAME_DEFAULT, ":/icons/bitcoin", "", ":/images/splash"}, - {"test", QAPP_APP_NAME_TESTNET, ":/icons/bitcoin_testnet", QT_TRANSLATE_NOOP("SplashScreen", "[testnet]"), ":/images/splash_testnet"}, - {"regtest", QAPP_APP_NAME_TESTNET, ":/icons/bitcoin_testnet", "[regtest]", ":/images/splash_testnet"} + {"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""}, + {"test", QAPP_APP_NAME_TESTNET, 70, 30, QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")}, + {"regtest", QAPP_APP_NAME_TESTNET, 70, 30, "[regtest]"} }; static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles); // titleAddText needs to be const char* for tr() -NetworkStyle::NetworkStyle(const QString &appName, const QString &appIcon, const char *titleAddText, const QString &splashImage): +NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText): appName(appName), - appIcon(appIcon), - titleAddText(qApp->translate("SplashScreen", titleAddText)), - splashImage(splashImage) + iconColorHueShift(iconColorHueShift), + iconColorSaturationReduction(iconColorSaturationReduction), + titleAddText(qApp->translate("SplashScreen", titleAddText)) { } @@ -38,10 +38,78 @@ const NetworkStyle *NetworkStyle::instantiate(const QString &networkId) { return new NetworkStyle( network_styles[x].appName, - network_styles[x].appIcon, - network_styles[x].titleAddText, - network_styles[x].splashImage); + network_styles[x].iconColorHueShift, + network_styles[x].iconColorSaturationReduction, + network_styles[x].titleAddText); } } return 0; } + +QIcon NetworkStyle::getAppIcon() const +{ + return getAppIcon(QSize(256,256)); +} + +QIcon NetworkStyle::getAppIcon(const QSize size) const +{ + // load pixmap + QPixmap pixmap(":/icons/bitcoin"); + + if(pixmap.size().width() != size.width() && pixmap.size().height() != size.height()) + { + QPixmap scaledPixmap = pixmap.scaled(size, Qt::KeepAspectRatio); + if(!scaledPixmap.isNull()) + { + pixmap = scaledPixmap; + } + } + + if(iconColorHueShift != 0 && iconColorSaturationReduction != 0) + { + // copy the pixmap because on linux the original pixmap will be affected + pixmap = pixmap.copy(); + + // generate QImage from QPixmap + QImage img = pixmap.toImage(); + + int h,s,l,a; + + // traverse though lines + for(int y=0;y( img.scanLine( y ) ); + + // loop through pixels + for(int x=0;xiconColorSaturationReduction) + { + s -= iconColorSaturationReduction; + } + col.setHsl(h,s,l,a); + + // set the pixel + scL[x] = col.rgba(); + } + } + + //convert back to QPixmap + pixmap.convertFromImage(img); + } + + QIcon icon(pixmap); + return icon; +} diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h index e49b86c9503..2bfb3c1d55f 100644 --- a/src/qt/networkstyle.h +++ b/src/qt/networkstyle.h @@ -17,17 +17,17 @@ public: static const NetworkStyle *instantiate(const QString &networkId); const QString &getAppName() const { return appName; } - const QIcon &getAppIcon() const { return appIcon; } const QString &getTitleAddText() const { return titleAddText; } - const QPixmap &getSplashImage() const { return splashImage; } + QIcon getAppIcon() const; + QIcon getAppIcon(const QSize size) const; private: - NetworkStyle(const QString &appName, const QString &appIcon, const char *titleAddText, const QString &splashImage); + NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText); QString appName; - QIcon appIcon; + int iconColorHueShift; + int iconColorSaturationReduction; QString titleAddText; - QPixmap splashImage; }; #endif // BITCOIN_QT_NETWORKSTYLE_H diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc index 809235be5f9..a72dfc02f62 100644 --- a/src/qt/res/bitcoin-qt-res.rc +++ b/src/qt/res/bitcoin-qt-res.rc @@ -1,5 +1,4 @@ IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico" -IDI_ICON2 ICON DISCARDABLE "icons/bitcoin_testnet.ico" #include // needed for VERSIONINFO #include "../../clientversion.h" // holds the needed client version information diff --git a/src/qt/res/icons/bitcoin.png b/src/qt/res/icons/bitcoin.png index ce5fbb0c2c57d22cda52df58d4bff21b94bfe79f..705a20260af0ebd2f2fbe3f3dfaf99f32db4be3b 100644 GIT binary patch literal 350390 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

2)j+z8iSV`RQImd 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 F{XdB=2n7HD literal 32547 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 Gd;bp|-Plk7 diff --git a/src/qt/res/icons/bitcoin_testnet.png b/src/qt/res/icons/bitcoin_testnet.png deleted file mode 100644 index 1202021f538ea1f46f5d6f5c5511590186d913c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28227 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 z 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�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 c #include #include +#include SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) : QWidget(0, f), curAlignment(0) @@ -30,6 +31,10 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) int titleCopyrightVSpace = 40; float fontFactor = 1.0; + float devicePixelRatio = 1.0; +#if QT_VERSION > 0x050100 + devicePixelRatio = ((QGuiApplication*)QCoreApplication::instance())->devicePixelRatio(); +#endif // define text to place QString titleText = tr("Bitcoin Core"); @@ -39,12 +44,34 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) QString font = "Arial"; - // load the bitmap for writing some text over it - pixmap = networkStyle->getSplashImage(); + // create a bitmap according to device pixelratio + QSize splashSize(480*devicePixelRatio,320*devicePixelRatio); + pixmap = QPixmap(splashSize); + +#if QT_VERSION > 0x050100 + // change to HiDPI if it makes sense + pixmap.setDevicePixelRatio(devicePixelRatio); +#endif QPainter pixPaint(&pixmap); pixPaint.setPen(QColor(100,100,100)); + // draw a slighly radial gradient + QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio); + gradient.setColorAt(0, Qt::white); + gradient.setColorAt(1, QColor(247,247,247)); + QRect rGradient(QPoint(0,0), splashSize); + pixPaint.fillRect(rGradient, gradient); + + // draw the bitcoin icon, expected size of PNG: 1024x1024 + QRect rectIcon(QPoint(-150,-122), QSize(430,430)); + + const QSize requiredSize(1024,1024); + QIcon appIcon = networkStyle->getAppIcon(requiredSize); + QPixmap icon(appIcon.pixmap(requiredSize)); + + pixPaint.drawPixmap(rectIcon, icon); + // check font size and drawing with pixPaint.setFont(QFont(font, 33*fontFactor)); QFontMetrics fm = pixPaint.fontMetrics(); @@ -57,7 +84,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) pixPaint.setFont(QFont(font, 33*fontFactor)); fm = pixPaint.fontMetrics(); titleTextWidth = fm.width(titleText); - pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop,titleText); + pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop,titleText); pixPaint.setFont(QFont(font, 15*fontFactor)); @@ -68,11 +95,11 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) pixPaint.setFont(QFont(font, 10*fontFactor)); titleVersionVSpace -= 5; } - pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText); + pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText); // draw copyright stuff pixPaint.setFont(QFont(font, 10*fontFactor)); - pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText); + pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText); // draw additional text if special network if(!titleAddText.isEmpty()) { @@ -81,7 +108,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) pixPaint.setFont(boldFont); fm = pixPaint.fontMetrics(); int titleAddTextWidth = fm.width(titleAddText); - pixPaint.drawText(pixmap.width()-titleAddTextWidth-10,15,titleAddText); + pixPaint.drawText(pixmap.width()/devicePixelRatio-titleAddTextWidth-10,15,titleAddText); } pixPaint.end(); @@ -90,7 +117,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) setWindowTitle(titleText + " " + titleAddText); // Resize window and move to center of desktop, disallow resizing - QRect r(QPoint(), pixmap.size()); + QRect r(QPoint(), QSize(pixmap.size().width()/devicePixelRatio,pixmap.size().height()/devicePixelRatio)); resize(r.size()); setFixedSize(r.size()); move(QApplication::desktop()->screenGeometry().center() - r.center()); From 8e76ca0429db552cbf6f51dadd5467a1bc899027 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 14 Nov 2014 12:58:30 +0100 Subject: [PATCH 0047/2337] Qt: Go back to using QIcon functionality for scaling --- src/qt/networkstyle.cpp | 58 ++++++++++++----------------------------- src/qt/networkstyle.h | 6 ++--- src/qt/splashscreen.cpp | 3 +-- 3 files changed, 20 insertions(+), 47 deletions(-) diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index b8112799df1..3762b848429 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -24,52 +24,13 @@ static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*netw // titleAddText needs to be const char* for tr() NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText): appName(appName), - iconColorHueShift(iconColorHueShift), - iconColorSaturationReduction(iconColorSaturationReduction), titleAddText(qApp->translate("SplashScreen", titleAddText)) -{ -} - -const NetworkStyle *NetworkStyle::instantiate(const QString &networkId) -{ - for (unsigned x=0; xgetAppIcon(requiredSize); - QPixmap icon(appIcon.pixmap(requiredSize)); + QPixmap icon(networkStyle->getAppIcon().pixmap(requiredSize)); pixPaint.drawPixmap(rectIcon, icon); From ac23394ea8118fe50131513bcd68c822a7ac4095 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 14 Nov 2014 17:16:31 +0100 Subject: [PATCH 0048/2337] resize tray icon because a 1024x1024 icon won't show in ubuntu (bug) --- src/qt/bitcoingui.cpp | 6 +++--- src/qt/networkstyle.cpp | 3 ++- src/qt/networkstyle.h | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index f63ebac6ea0..3f5d0a191b2 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -115,8 +115,8 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : } windowTitle += " " + networkStyle->getTitleAddText(); #ifndef Q_OS_MAC - QApplication::setWindowIcon(networkStyle->getAppIcon()); - setWindowIcon(networkStyle->getAppIcon()); + QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon()); + setWindowIcon(networkStyle->getTrayAndWindowIcon()); #else MacDockIconHandler::instance()->setIcon(networkStyle->getAppIcon()); #endif @@ -491,7 +491,7 @@ void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle) trayIcon = new QSystemTrayIcon(this); QString toolTip = tr("Bitcoin Core client") + " " + networkStyle->getTitleAddText(); trayIcon->setToolTip(toolTip); - trayIcon->setIcon(networkStyle->getAppIcon()); + trayIcon->setIcon(networkStyle->getTrayAndWindowIcon()); trayIcon->show(); #endif diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 3762b848429..ff05174fb44 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -71,7 +71,8 @@ NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, pixmap.convertFromImage(img); } - appIcon = QIcon(pixmap); + appIcon = QIcon(pixmap); + trayAndWindowIcon = QIcon(pixmap.scaled(QSize(256,256))); } const NetworkStyle *NetworkStyle::instantiate(const QString &networkId) diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h index 3e3332cd8bf..953004c1275 100644 --- a/src/qt/networkstyle.h +++ b/src/qt/networkstyle.h @@ -18,6 +18,7 @@ public: const QString &getAppName() const { return appName; } const QIcon &getAppIcon() const { return appIcon; } + const QIcon &getTrayAndWindowIcon() const { return trayAndWindowIcon; } const QString &getTitleAddText() const { return titleAddText; } private: @@ -25,6 +26,7 @@ private: QString appName; QIcon appIcon; + QIcon trayAndWindowIcon; QString titleAddText; }; From bf7835c2713e9cc8356cd1a32bf99c40e222773b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Tue, 25 Nov 2014 18:54:36 +0100 Subject: [PATCH 0049/2337] Fix small typos in comments and error messages Rebased-From: 67b2d819cdf6181e7f016e5366ce7479830893bd Github-Pull: #5404 --- src/chain.h | 2 +- src/main.cpp | 8 ++++---- src/txmempool.cpp | 4 ++-- src/uint256.cpp | 2 +- src/wallet_ismine.cpp | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/chain.h b/src/chain.h index a8a6b4dd647..98db9898796 100644 --- a/src/chain.h +++ b/src/chain.h @@ -95,7 +95,7 @@ enum BlockStatus { class CBlockIndex { public: - //! pointer to the hash of the block, if any. memory is owned by this CBlockIndex + //! pointer to the hash of the block, if any. Memory is owned by this CBlockIndex const uint256* phashBlock; //! pointer to the index of the predecessor of this block diff --git a/src/main.cpp b/src/main.cpp index 7533c32614b..4160e4b788d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1025,7 +1025,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa hash.ToString(), nFees, txMinFee), REJECT_INSUFFICIENTFEE, "insufficient fee"); - // Continuously rate-limit free (really, very-low-fee)transactions + // Continuously rate-limit free (really, very-low-fee) transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize)) @@ -1050,7 +1050,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) - return error("AcceptToMemoryPool: : insane fees %s, %d > %d", + return error("AcceptToMemoryPool: insane fees %s, %d > %d", hash.ToString(), nFees, ::minRelayTxFee.GetFee(nSize) * 10000); @@ -1058,7 +1058,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // This is done last to help prevent CPU exhaustion denial-of-service attacks. if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) { - return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString()); + return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString()); } // Store transaction in memory pool.addUnchecked(hash, entry); @@ -2988,7 +2988,7 @@ bool InitBlockIndex() { return error("LoadBlockIndex() : genesis block not accepted"); if (!ActivateBestChain(state, &block)) return error("LoadBlockIndex() : genesis block cannot be activated"); - // Force a chainstate write so that when we VerifyDB in a moment, it doesnt check stale data + // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); } catch(std::runtime_error &e) { return error("LoadBlockIndex() : failed to initialize block database: %s", e.what()); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 840eb536baa..a9567d3b157 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -241,8 +241,8 @@ public: } } - //After new samples are added, we have to clear the sorted lists, - //so they'll be resorted the next time someone asks for an estimate + // After new samples are added, we have to clear the sorted lists, + // so they'll be resorted the next time someone asks for an estimate sortedFeeSamples.clear(); sortedPrioritySamples.clear(); diff --git a/src/uint256.cpp b/src/uint256.cpp index 79406f24757..9ac886f8157 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -99,7 +99,7 @@ base_uint& base_uint::operator/=(const base_uint& b) if (div_bits > num_bits) // the result is certainly 0. return *this; int shift = num_bits - div_bits; - div <<= shift; // shift so that div and nun align. + div <<= shift; // shift so that div and num align. while (shift >= 0) { if (num >= div) { num -= div; diff --git a/src/wallet_ismine.cpp b/src/wallet_ismine.cpp index 05dc40aaee5..839f694850f 100644 --- a/src/wallet_ismine.cpp +++ b/src/wallet_ismine.cpp @@ -74,7 +74,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) case TX_MULTISIG: { // Only consider transactions "mine" if we own ALL the - // keys involved. multi-signature transactions that are + // keys involved. Multi-signature transactions that are // partially owned (somebody else has a key that can spend // them) enable spend-out-from-under-you attacks, especially // in shared-wallet situations. From 270f42d39f84f17d8f0e8f6c747b66cba880f2e2 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 16 Dec 2014 12:59:36 +0100 Subject: [PATCH 0050/2337] [Qt] fix a = 0x040700 pixmap.convertFromImage(img); +#else + pixmap = QPixmap::fromImage(img); +#endif } appIcon = QIcon(pixmap); From ff63801bc0ad4c363d2e15af07f7063a3859b605 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 16 Dec 2014 13:35:41 +0100 Subject: [PATCH 0051/2337] [Qt] light blue icon color for regtest Changing the icons color for regtest in now lightweight. --- src/qt/networkstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index a1a067dd776..2da54876cd7 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -17,7 +17,7 @@ static const struct { } network_styles[] = { {"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""}, {"test", QAPP_APP_NAME_TESTNET, 70, 30, QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")}, - {"regtest", QAPP_APP_NAME_TESTNET, 70, 30, "[regtest]"} + {"regtest", QAPP_APP_NAME_TESTNET, 160, 30, "[regtest]"} }; static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles); From 7c8e4c5cfb3dd88bbe89cc14b703d7c59bafed6e Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Tue, 16 Dec 2014 13:45:27 +0100 Subject: [PATCH 0052/2337] Make pass-by-ref arguments const. Make some of the arguments in rest.cpp, that are passed by reference but never modified, const to emphasise that. --- src/rest.cpp | 30 +++++++++++++++--------------- src/rpcserver.h | 4 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index c52dbb3cd24..69e6c08886c 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -90,8 +90,8 @@ static bool ParseHashStr(const string& strReq, uint256& v) } static bool rest_headers(AcceptedConnection* conn, - string& strReq, - map& mapHeaders, + const std::string& strReq, + const std::map& mapHeaders, bool fRun) { vector params; @@ -153,8 +153,8 @@ static bool rest_headers(AcceptedConnection* conn, } static bool rest_block(AcceptedConnection* conn, - string& strReq, - map& mapHeaders, + const std::string& strReq, + const std::map& mapHeaders, bool fRun, bool showTxDetails) { @@ -211,24 +211,24 @@ static bool rest_block(AcceptedConnection* conn, } static bool rest_block_extended(AcceptedConnection* conn, - string& strReq, - map& mapHeaders, + const std::string& strReq, + const std::map& mapHeaders, bool fRun) { return rest_block(conn, strReq, mapHeaders, fRun, true); } static bool rest_block_notxdetails(AcceptedConnection* conn, - string& strReq, - map& mapHeaders, + const std::string& strReq, + const std::map& mapHeaders, bool fRun) { return rest_block(conn, strReq, mapHeaders, fRun, false); } static bool rest_tx(AcceptedConnection* conn, - string& strReq, - map& mapHeaders, + const std::string& strReq, + const std::map& mapHeaders, bool fRun) { vector params; @@ -280,8 +280,8 @@ static bool rest_tx(AcceptedConnection* conn, static const struct { const char* prefix; bool (*handler)(AcceptedConnection* conn, - string& strURI, - map& mapHeaders, + const std::string& strURI, + const std::map& mapHeaders, bool fRun); } uri_prefixes[] = { {"/rest/tx/", rest_tx}, @@ -291,8 +291,8 @@ static const struct { }; bool HTTPReq_REST(AcceptedConnection* conn, - string& strURI, - map& mapHeaders, + const std::string& strURI, + const std::map& mapHeaders, bool fRun) { try { @@ -307,7 +307,7 @@ bool HTTPReq_REST(AcceptedConnection* conn, return uri_prefixes[i].handler(conn, strReq, mapHeaders, fRun); } } - } catch (RestErr& re) { + } catch (const RestErr& re) { conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush; return false; } diff --git a/src/rpcserver.h b/src/rpcserver.h index 2b2428445d7..8fea38126c0 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -227,8 +227,8 @@ extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool // in rest.cpp extern bool HTTPReq_REST(AcceptedConnection *conn, - std::string& strURI, - std::map& mapHeaders, + const std::string& strURI, + const std::map& mapHeaders, bool fRun); #endif // BITCOIN_RPCSERVER_H From 27df4123c433e5ad4e5592f0a8fbc40ca933865b Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sun, 7 Dec 2014 13:29:06 +0100 Subject: [PATCH 0053/2337] make all catch() arguments const - I saw this on http://en.cppreference.com/w/cpp/language/try_catch and thought it would be a good idea - also unify used format to better be able to search for exception uses in our codebase --- src/bitcoin-cli.cpp | 12 ++++++------ src/bitcoin-tx.cpp | 8 ++++---- src/bitcoind.cpp | 4 ++-- src/core_read.cpp | 4 ++-- src/init.cpp | 6 +++--- src/main.cpp | 24 ++++++++++++------------ src/miner.cpp | 2 +- src/net.cpp | 10 +++++----- src/qt/bitcoin.cpp | 12 ++++++------ src/qt/intro.cpp | 4 ++-- src/qt/paymentrequestplus.cpp | 3 +-- src/qt/rpcconsole.cpp | 6 +++--- src/rest.cpp | 2 +- src/rpcprotocol.h | 3 +-- src/rpcrawtransaction.cpp | 2 +- src/rpcserver.cpp | 16 ++++++++-------- src/script/bitcoinconsensus.cpp | 2 +- src/test/alert_tests.cpp | 2 +- src/test/rpc_tests.cpp | 3 +-- src/txdb.cpp | 4 ++-- src/txmempool.cpp | 4 ++-- src/util.cpp | 9 ++++----- src/util.h | 10 +++++----- src/walletdb.cpp | 8 ++++---- 24 files changed, 78 insertions(+), 82 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index ea349b197e5..51ab14785b3 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -86,7 +86,7 @@ static bool AppInitRPC(int argc, char* argv[]) } try { ReadConfigFile(mapArgs, mapMultiArgs); - } catch(std::exception &e) { + } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return false; } @@ -206,7 +206,7 @@ int CommandLineRPC(int argc, char *argv[]) // Connection succeeded, no need to retry. break; } - catch (const CConnectionFailed& e) { + catch (const CConnectionFailed&) { if (fWait) MilliSleep(1000); else @@ -214,10 +214,10 @@ int CommandLineRPC(int argc, char *argv[]) } } while (fWait); } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } - catch (std::exception& e) { + catch (const std::exception& e) { strPrint = string("error: ") + e.what(); nRet = EXIT_FAILURE; } @@ -240,7 +240,7 @@ int main(int argc, char* argv[]) if(!AppInitRPC(argc, argv)) return EXIT_FAILURE; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRPC()"); return EXIT_FAILURE; } catch (...) { @@ -252,7 +252,7 @@ int main(int argc, char* argv[]) try { ret = CommandLineRPC(argc, argv); } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "CommandLineRPC()"); } catch (...) { PrintExceptionContinue(NULL, "CommandLineRPC()"); diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 7308d936617..890eaaedbe0 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -586,10 +586,10 @@ static int CommandLineRawTx(int argc, char* argv[]) OutputTx(tx); } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } - catch (std::exception& e) { + catch (const std::exception& e) { strPrint = string("error: ") + e.what(); nRet = EXIT_FAILURE; } @@ -612,7 +612,7 @@ int main(int argc, char* argv[]) if(!AppInitRawTx(argc, argv)) return EXIT_FAILURE; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRawTx()"); return EXIT_FAILURE; } catch (...) { @@ -624,7 +624,7 @@ int main(int argc, char* argv[]) try { ret = CommandLineRawTx(argc, argv); } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "CommandLineRawTx()"); } catch (...) { PrintExceptionContinue(NULL, "CommandLineRawTx()"); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index be7757b0b6c..6e735fe3d97 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -97,7 +97,7 @@ bool AppInit(int argc, char* argv[]) try { ReadConfigFile(mapArgs, mapMultiArgs); - } catch(std::exception &e) { + } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return false; } @@ -147,7 +147,7 @@ bool AppInit(int argc, char* argv[]) detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup)); fRet = AppInit2(threadGroup); } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInit()"); } catch (...) { PrintExceptionContinue(NULL, "AppInit()"); diff --git a/src/core_read.cpp b/src/core_read.cpp index 65c3a08c551..c15b9787608 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -102,7 +102,7 @@ bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx) try { ssData >> tx; } - catch (const std::exception &) { + catch (const std::exception&) { return false; } @@ -119,7 +119,7 @@ bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk) try { ssBlock >> block; } - catch (const std::exception &) { + catch (const std::exception&) { return false; } diff --git a/src/init.cpp b/src/init.cpp index 11329c16aa4..63199b3206e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -778,7 +778,7 @@ bool AppInit2(boost::thread_group& threadGroup) try { boost::filesystem::rename(pathDatabase, pathDatabaseBak); LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); - } catch(boost::filesystem::filesystem_error &error) { + } catch (const boost::filesystem::filesystem_error&) { // failure is ok (well, not really, but it's not worse than what we started with) } @@ -931,7 +931,7 @@ bool AppInit2(boost::thread_group& threadGroup) filesystem::create_hard_link(source, dest); LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string()); linked = true; - } catch (filesystem::filesystem_error & e) { + } catch (const filesystem::filesystem_error& e) { // Note: hardlink creation failing is not a disaster, it just means // blocks will get re-downloaded from peers. LogPrintf("Error hardlinking blk%04u.dat : %s\n", i, e.what()); @@ -1008,7 +1008,7 @@ bool AppInit2(boost::thread_group& threadGroup) strLoadError = _("Corrupted block database detected"); break; } - } catch(std::exception &e) { + } catch (const std::exception& e) { if (fDebug) LogPrintf("%s\n", e.what()); strLoadError = _("Error opening block database"); break; diff --git a/src/main.cpp b/src/main.cpp index 4160e4b788d..9c038f90fa7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1091,7 +1091,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock file >> header; fseek(file.Get(), postx.nTxOffset, SEEK_CUR); file >> txOut; - } catch (std::exception &e) { + } catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } hashBlock = header.GetHash(); @@ -1174,7 +1174,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) try { filein >> block; } - catch (std::exception &e) { + catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } @@ -2598,7 +2598,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, return state.Abort("Failed to write block"); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("AcceptBlock() : ReceivedBlockTransactions failed"); - } catch(std::runtime_error &e) { + } catch (const std::runtime_error& e) { return state.Abort(std::string("System error: ") + e.what()); } @@ -2990,7 +2990,7 @@ bool InitBlockIndex() { return error("LoadBlockIndex() : genesis block cannot be activated"); // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); - } catch(std::runtime_error &e) { + } catch (const std::runtime_error& e) { return error("LoadBlockIndex() : failed to initialize block database: %s", e.what()); } } @@ -3030,7 +3030,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) blkdat >> nSize; if (nSize < 80 || nSize > MAX_BLOCK_SIZE) continue; - } catch (const std::exception &) { + } catch (const std::exception&) { // no valid block header found; don't complain break; } @@ -3090,11 +3090,11 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) mapBlocksUnknownParent.erase(it); } } - } catch (std::exception &e) { + } catch (const std::exception& e) { LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what()); } } - } catch(std::runtime_error &e) { + } catch (const std::runtime_error& e) { AbortNode(std::string("System error: ") + e.what()); } if (nLoaded > 0) @@ -4088,7 +4088,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, ss << ": hash " << hash.ToString(); } LogPrint("net", "Reject %s\n", SanitizeString(ss.str())); - } catch (std::ios_base::failure& e) { + } catch (const std::ios_base::failure&) { // Avoid feedback loops by preventing reject messages from triggering a new reject message. LogPrint("net", "Unparseable reject message received\n"); } @@ -4192,7 +4192,7 @@ bool ProcessMessages(CNode* pfrom) fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime); boost::this_thread::interruption_point(); } - catch (std::ios_base::failure& e) + catch (const std::ios_base::failure& e) { pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message")); if (strstr(e.what(), "end of data")) @@ -4210,10 +4210,10 @@ bool ProcessMessages(CNode* pfrom) PrintExceptionContinue(&e, "ProcessMessages()"); } } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "ProcessMessages()"); } catch (...) { PrintExceptionContinue(NULL, "ProcessMessages()"); @@ -4507,7 +4507,7 @@ bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock filein >> *this; filein >> hashChecksum; } - catch (std::exception &e) { + catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } diff --git a/src/miner.cpp b/src/miner.cpp index ad294314212..09c505ffd15 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -565,7 +565,7 @@ void static BitcoinMiner(CWallet *pwallet) } } } - catch (boost::thread_interrupted) + catch (const boost::thread_interrupted&) { LogPrintf("BitcoinMiner terminated\n"); throw; diff --git a/src/net.cpp b/src/net.cpp index 42b3c30fb77..9e492d2fc05 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -601,7 +601,7 @@ int CNetMessage::readHeader(const char *pch, unsigned int nBytes) try { hdrbuf >> hdr; } - catch (const std::exception &) { + catch (const std::exception&) { return -1; } @@ -1068,7 +1068,7 @@ void ThreadMapPort() MilliSleep(20*60*1000); // Refresh every 20 minutes } } - catch (boost::thread_interrupted) + catch (const boost::thread_interrupted&) { r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r); @@ -1854,7 +1854,7 @@ bool CAddrDB::Write(const CAddrMan& addr) try { fileout << ssPeers; } - catch (std::exception &e) { + catch (const std::exception& e) { return error("%s : Serialize or I/O error - %s", __func__, e.what()); } FileCommit(fileout.Get()); @@ -1890,7 +1890,7 @@ bool CAddrDB::Read(CAddrMan& addr) filein.read((char *)&vchData[0], dataSize); filein >> hashIn; } - catch (std::exception &e) { + catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } filein.fclose(); @@ -1914,7 +1914,7 @@ bool CAddrDB::Read(CAddrMan& addr) // de-serialize address data into one CAddrMan object ssPeers >> addr; } - catch (std::exception &e) { + catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 123777a71bc..9b02650797b 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -173,7 +173,7 @@ private: boost::thread_group threadGroup; /// Pass fatal exception message to UI thread - void handleRunawayException(std::exception *e); + void handleRunawayException(const std::exception *e); }; /** Main Bitcoin application object */ @@ -240,7 +240,7 @@ BitcoinCore::BitcoinCore(): { } -void BitcoinCore::handleRunawayException(std::exception *e) +void BitcoinCore::handleRunawayException(const std::exception *e) { PrintExceptionContinue(e, "Runaway exception"); emit runawayException(QString::fromStdString(strMiscWarning)); @@ -260,7 +260,7 @@ void BitcoinCore::initialize() StartDummyRPCThread(); } emit initializeResult(rv); - } catch (std::exception& e) { + } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { handleRunawayException(NULL); @@ -277,7 +277,7 @@ void BitcoinCore::shutdown() Shutdown(); qDebug() << __func__ << ": Shutdown finished"; emit shutdownResult(1); - } catch (std::exception& e) { + } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { handleRunawayException(NULL); @@ -551,7 +551,7 @@ int main(int argc, char *argv[]) } try { ReadConfigFile(mapArgs, mapMultiArgs); - } catch(std::exception &e) { + } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr("Bitcoin Core"), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); return false; @@ -628,7 +628,7 @@ int main(int argc, char *argv[]) app.exec(); app.requestShutdown(); app.exec(); - } catch (std::exception& e) { + } catch (const std::exception& e) { PrintExceptionContinue(&e, "Runaway exception"); app.handleRunawayException(QString::fromStdString(strMiscWarning)); } catch (...) { diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 7618bff69d9..65486a02fc2 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -95,7 +95,7 @@ void FreespaceChecker::check() replyMessage = tr("Path already exists, and is not a directory."); } } - } catch(fs::filesystem_error &e) + } catch (const fs::filesystem_error&) { /* Parent directory does not exist or is not accessible */ replyStatus = ST_ERROR; @@ -180,7 +180,7 @@ void Intro::pickDataDirectory() try { TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir)); break; - } catch(fs::filesystem_error &e) { + } catch (const fs::filesystem_error&) { QMessageBox::critical(0, tr("Bitcoin Core"), tr("Error: Specified data directory \"%1\" cannot be created.").arg(dataDir)); /* fall through, back to choosing screen */ diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index a40b5bbcd84..ca3f06962ac 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -181,8 +181,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c } // TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ? } - catch (SSLVerifyError& err) - { + catch (const SSLVerifyError& err) { fResult = false; qWarning() << "PaymentRequestPlus::getMerchant : SSL error: " << err.what(); } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 2defdf8bb47..9fb15dc6fd8 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -180,7 +180,7 @@ void RPCExecutor::request(const QString &command) emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); } - catch (json_spirit::Object& objError) + catch (const json_spirit::Object& objError) { try // Nice formatting for standard-format error { @@ -188,12 +188,12 @@ void RPCExecutor::request(const QString &command) std::string message = find_value(objError, "message").get_str(); emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); } - catch(std::runtime_error &) // raised when converting to invalid type, i.e. missing code or message + catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message { // Show raw JSON object emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false))); } } - catch (std::exception& e) + catch (const std::exception& e) { emit reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what())); } diff --git a/src/rest.cpp b/src/rest.cpp index c52dbb3cd24..304e1d747a9 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -307,7 +307,7 @@ bool HTTPReq_REST(AcceptedConnection* conn, return uri_prefixes[i].handler(conn, strReq, mapHeaders, fRun); } } - } catch (RestErr& re) { + } catch (const RestErr& re) { conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush; return false; } diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index f7cd50f9f60..f4a4877d388 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -122,8 +122,7 @@ public: tcp::resolver::query query(server.c_str(), port.c_str()); endpoint_iterator = resolver.resolve(query); #if BOOST_VERSION >= 104300 - } catch(boost::system::system_error &e) - { + } catch (const boost::system::system_error&) { // If we at first don't succeed, try blanket lookup (IPv4+IPv6 independent of configured interfaces) tcp::resolver::query query(server.c_str(), port.c_str(), resolver_query_base::flags()); endpoint_iterator = resolver.resolve(query); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 4a1af2207a2..f596c358a90 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -545,7 +545,7 @@ Value signrawtransaction(const Array& params, bool fHelp) ssData >> tx; txVariants.push_back(tx); } - catch (const std::exception &) { + catch (const std::exception&) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); } } diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 252b0866a2f..c0f0d253f2d 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -174,7 +174,7 @@ string CRPCTable::help(string strCommand) const if (setDone.insert(pfn).second) (*pfn)(params, true); } - catch (std::exception& e) + catch (const std::exception& e) { // Help text is returned in an exception string strHelp = string(e.what()); @@ -631,7 +631,7 @@ void StartRPCThreads() try { vEndpoints.push_back(ParseEndpoint(addr, defaultPort)); } - catch(const boost::system::system_error &) + catch (const boost::system::system_error&) { uiInterface.ThreadSafeMessageBox( strprintf(_("Could not parse -rpcbind value %s as network address"), addr), @@ -676,7 +676,7 @@ void StartRPCThreads() if(bBindAny && bindAddress == asio::ip::address_v6::any() && !v6_only_error) break; } - catch(boost::system::system_error &e) + catch (const boost::system::system_error& e) { LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", bindAddress.to_string(), endpoint.port(), e.what()); strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), bindAddress.to_string(), endpoint.port(), e.what()); @@ -842,11 +842,11 @@ static Object JSONRPCExecOne(const Value& req) Value result = tableRPC.execute(jreq.strMethod, jreq.params); rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id); } - catch (Object& objError) + catch (const Object& objError) { rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); } - catch (std::exception& e) + catch (const std::exception& e) { rpc_result = JSONRPCReplyObj(Value::null, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); @@ -922,12 +922,12 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush; } - catch (Object& objError) + catch (const Object& objError) { ErrorReply(conn->stream(), objError, jreq.id); return false; } - catch (std::exception& e) + catch (const std::exception& e) { ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); return false; @@ -1013,7 +1013,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s } return result; } - catch (std::exception& e) + catch (const std::exception& e) { throw JSONRPCError(RPC_MISC_ERROR, e.what()); } diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index d4fd2ad7d9b..e80e55df759 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -79,7 +79,7 @@ int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned i set_error(err, bitcoinconsensus_ERR_OK); return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, SignatureChecker(tx, nIn), NULL); - } catch (std::exception &e) { + } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } } diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 4869ba52acc..614960fa6d5 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -92,7 +92,7 @@ struct ReadAlerts alerts.push_back(alert); } } - catch (std::exception) { } + catch (const std::exception&) { } } ~ReadAlerts() { } diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index d5475a92bfa..4826fae5223 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -39,8 +39,7 @@ Value CallRPC(string args) Value result = (*method)(params, false); return result; } - catch (Object& objError) - { + catch (const Object& objError) { throw runtime_error(find_value(objError, "message").get_str()); } } diff --git a/src/txdb.cpp b/src/txdb.cpp index 29ef3503749..bb108f38baa 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -129,7 +129,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { ss << VARINT(0); } pcursor->Next(); - } catch (std::exception &e) { + } catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } } @@ -218,7 +218,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() } else { break; // if shutdown requested or finished loading block index } - } catch (std::exception &e) { + } catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a9567d3b157..1df9c5c79c7 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -648,7 +648,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const fileout << CLIENT_VERSION; // version that wrote the file minerPolicyEstimator->Write(fileout); } - catch (const std::exception &) { + catch (const std::exception&) { LogPrintf("CTxMemPool::WriteFeeEstimates() : unable to write policy estimator data (non-fatal)"); return false; } @@ -667,7 +667,7 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein) LOCK(cs); minerPolicyEstimator->Read(filein, minRelayFee); } - catch (const std::exception &) { + catch (const std::exception&) { LogPrintf("CTxMemPool::ReadFeeEstimates() : unable to read policy estimator data (non-fatal)"); return false; } diff --git a/src/util.cpp b/src/util.cpp index 0cdf4e614d8..282e54e4886 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -346,7 +346,7 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue) return SoftSetArg(strArg, std::string("0")); } -static std::string FormatException(std::exception* pex, const char* pszThread) +static std::string FormatException(const std::exception* pex, const char* pszThread) { #ifdef WIN32 char pszModule[MAX_PATH] = ""; @@ -362,7 +362,7 @@ static std::string FormatException(std::exception* pex, const char* pszThread) "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); } -void PrintExceptionContinue(std::exception* pex, const char* pszThread) +void PrintExceptionContinue(const std::exception* pex, const char* pszThread) { std::string message = FormatException(pex, pszThread); LogPrintf("\n\n************************\n%s\n", message); @@ -514,7 +514,7 @@ bool TryCreateDirectory(const boost::filesystem::path& p) try { return boost::filesystem::create_directory(p); - } catch (boost::filesystem::filesystem_error) { + } catch (const boost::filesystem::filesystem_error&) { if (!boost::filesystem::exists(p) || !boost::filesystem::is_directory(p)) throw; } @@ -721,8 +721,7 @@ void SetupEnvironment() #else // boost filesystem v2 std::locale(); // Raises runtime error if current locale is invalid #endif - } catch(std::runtime_error &e) - { + } catch (const std::runtime_error&) { setenv("LC_ALL", "C", 1); // Force C locale } #endif diff --git a/src/util.h b/src/util.h index a4aaf29f914..623c24f5cc7 100644 --- a/src/util.h +++ b/src/util.h @@ -84,7 +84,7 @@ static inline bool error(const char* format) return false; } -void PrintExceptionContinue(std::exception* pex, const char* pszThread); +void PrintExceptionContinue(const std::exception *pex, const char* pszThread); void ParseParameters(int argc, const char*const argv[]); void FileCommit(FILE *fileout); bool TruncateFile(FILE *file, unsigned int length); @@ -186,12 +186,12 @@ template void LoopForever(const char* name, Callable func, func(); } } - catch (boost::thread_interrupted) + catch (const boost::thread_interrupted&) { LogPrintf("%s thread stop\n", name); throw; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, name); throw; } @@ -214,12 +214,12 @@ template void TraceThread(const char* name, Callable func) func(); LogPrintf("%s thread exit\n", name); } - catch (boost::thread_interrupted) + catch (const boost::thread_interrupted&) { LogPrintf("%s thread interrupt\n", name); throw; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, name); throw; } diff --git a/src/walletdb.cpp b/src/walletdb.cpp index ffddd8106b3..94e17c6a587 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -460,7 +460,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, { ssValue >> hash; } - catch(...){} + catch (...) {} bool fSkipCheck = false; @@ -664,7 +664,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) } pcursor->close(); } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } catch (...) { @@ -757,7 +757,7 @@ DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector& vTxHash, vec } pcursor->close(); } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } catch (...) { @@ -878,7 +878,7 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) #endif LogPrintf("copied wallet.dat to %s\n", pathDest.string()); return true; - } catch(const filesystem::filesystem_error &e) { + } catch (const filesystem::filesystem_error& e) { LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what()); return false; } From 7f718139191d67da29c5d856d29e035bbc51e659 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 17 Dec 2014 09:34:09 +0000 Subject: [PATCH 0054/2337] Bugfix: prioritisetransaction: Do some basic sanity checking on txid Besides giving a nicer error, this also prevents logging arbitrary data (which could have been used to exploit log readers) into debug.log --- src/core_io.h | 1 + src/core_read.cpp | 5 +++++ src/rpcmining.cpp | 3 +-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core_io.h b/src/core_io.h index aba1928a366..bc2eb1edd09 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -19,6 +19,7 @@ extern CScript ParseScript(std::string s); extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk); extern uint256 ParseHashUV(const UniValue& v, const std::string& strName); +extern uint256 ParseHashStr(const std::string&, const std::string& strName); extern std::vector ParseHexUV(const UniValue& v, const std::string& strName); // core_write.cpp diff --git a/src/core_read.cpp b/src/core_read.cpp index 65c3a08c551..beb746ce970 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -131,6 +131,11 @@ uint256 ParseHashUV(const UniValue& v, const string& strName) string strHex; if (v.isStr()) strHex = v.getValStr(); + return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error +} + +uint256 ParseHashStr(const std::string& strHex, const std::string& strName) +{ if (!IsHex(strHex)) // Note: IsHex("") is false throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')"); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 45899d3db53..9694ec2ea0c 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -288,8 +288,7 @@ Value prioritisetransaction(const Array& params, bool fHelp) + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000") ); - uint256 hash; - hash.SetHex(params[0].get_str()); + uint256 hash = ParseHashStr(params[0].get_str(), "txid"); CAmount nAmount = params[2].get_int64(); From e85855fa557214ab28f77548a7e2c4baf088ed9d Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Wed, 17 Dec 2014 19:36:20 +0800 Subject: [PATCH 0055/2337] Drop beta suffixes from readmes --- doc/README.md | 2 +- doc/README_windows.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/README.md b/doc/README.md index 3ec5f11df27..73a268ee96e 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -Bitcoin 0.10.99 BETA +Bitcoin 0.10.99 ===================== Copyright (c) 2009-2014 Bitcoin Developers diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 9780a2cb134..80e6f779a4e 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin 0.10.99 BETA +Bitcoin 0.10.99 Copyright (c) 2009-2014 Bitcoin Core Developers From e36e619886fd0beba4dfc8155c1c068f9d7df0db Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 17 Dec 2014 13:20:11 +0100 Subject: [PATCH 0056/2337] Add mips, mipsel and aarch64 to depends platforms --- depends/packages/openssl.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index 6d7a556c110..ad64494c1f2 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -14,6 +14,9 @@ $(package)_config_opts_linux=-fPIC $(package)_config_opts_x86_64_linux=linux-x86_64 $(package)_config_opts_i686_linux=linux-generic32 $(package)_config_opts_arm_linux=linux-generic32 +$(package)_config_opts_aarch64_linux=linux-generic64 +$(package)_config_opts_mipsel_linux=linux-generic32 +$(package)_config_opts_mips_linux=linux-generic32 $(package)_config_opts_x86_64_darwin=darwin64-x86_64-cc $(package)_config_opts_x86_64_mingw32=mingw64 $(package)_config_opts_i686_mingw32=mingw From 7a3b83269ec26612aa3399ae3f978264996c32fd Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 17 Dec 2014 22:37:54 +0100 Subject: [PATCH 0057/2337] [QA] fix httpbasics RPC test typo --- qa/rpc-tests/httpbasics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index a94edaffa53..85e85e7f0fb 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -20,7 +20,7 @@ try: except ImportError: import urlparse -class RESTTest (BitcoinTestFramework): +class HTTPBasicsTest (BitcoinTestFramework): def run_test(self): ################################################# @@ -73,4 +73,4 @@ class RESTTest (BitcoinTestFramework): if __name__ == '__main__': - RESTTest ().main () + HTTPBasicsTest ().main () From 469d564951a47f704a08e8265aa165e2d0fc78ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Thu, 18 Dec 2014 13:34:16 +0100 Subject: [PATCH 0058/2337] Build winshutdownmonitor.cpp on Windows only. --- src/Makefile.qt.include | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 25d76c146b9..c0cc8f34e5f 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -279,8 +279,11 @@ BITCOIN_QT_CPP = \ qt/rpcconsole.cpp \ qt/splashscreen.cpp \ qt/trafficgraphwidget.cpp \ - qt/utilitydialog.cpp \ - qt/winshutdownmonitor.cpp + qt/utilitydialog.cpp + +if TARGET_WINDOWS +BITCOIN_QT_CPP += qt/winshutdownmonitor.cpp +endif if ENABLE_WALLET BITCOIN_QT_CPP += \ From 146c0a7c5acc06070badf1db442520fab5395614 Mon Sep 17 00:00:00 2001 From: 21E14 <21xe14@gmail.com> Date: Thu, 18 Dec 2014 20:25:04 -0500 Subject: [PATCH 0059/2337] Add RandAddSeedPerfmon to MakeNewKey --- src/key.cpp | 1 + src/wallet.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/key.cpp b/src/key.cpp index 36613342b8b..3d5886d350b 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -34,6 +34,7 @@ bool CKey::Check(const unsigned char *vch) { } void CKey::MakeNewKey(bool fCompressedIn) { + RandAddSeedPerfmon(); do { GetRandBytes(vch, sizeof(vch)); } while (!Check(vch)); diff --git a/src/wallet.cpp b/src/wallet.cpp index 32a64daac0c..b6699a41da0 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -70,7 +70,6 @@ CPubKey CWallet::GenerateNewKey() AssertLockHeld(cs_wallet); // mapKeyMetadata bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets - RandAddSeedPerfmon(); CKey secret; secret.MakeNewKey(fCompressed); From 3bf5f52808a5f7cd3958c9eea273d99fd11417ca Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Sat, 13 Dec 2014 12:35:39 +0800 Subject: [PATCH 0060/2337] Create developer-notes.md Moves coding guidelines and development tips/tricks into a single file. Also adds a section explaining pull request terminology. --- README.md | 37 +-------------------- doc/README.md | 2 +- doc/{coding.md => developer-notes.md} | 48 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 37 deletions(-) rename doc/{coding.md => developer-notes.md} (67%) diff --git a/README.md b/README.md index cf650fe5433..03a698996de 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ submitter will be asked to start a discussion (if they haven't already) on the The patch will be accepted if there is broad consensus that it is a good thing. Developers should expect to rework and resubmit patches if the code doesn't -match the project's coding conventions (see [doc/coding.md](doc/coding.md)) or are +match the project's coding conventions (see [doc/developer-notes.md](doc/developer-notes.md)) or are controversial. The `master` branch is regularly built and tested, but is not guaranteed to be @@ -85,38 +85,3 @@ Translations are periodically pulled from Transifex and merged into the git repo pull from Transifex would automatically overwrite them again. Translators should also subscribe to the [mailing list](https://groups.google.com/forum/#!forum/bitcoin-translators). - -Development tips and tricks ---------------------------- - -**compiling for debugging** - -Run configure with the --enable-debug option, then make. Or run configure with -CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need. - -**debug.log** - -If the code is behaving strangely, take a look in the debug.log file in the data directory; -error and debugging messages are written there. - -The -debug=... command-line option controls debugging; running with just -debug will turn -on all categories (and give you a very large debug.log file). - -The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt -to see it. - -**testnet and regtest modes** - -Run with the -testnet option to run with "play bitcoins" on the test network, if you -are testing multi-machine code that needs to operate across the internet. - -If you are testing something that can run on one machine, run with the -regtest option. -In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests -that run in -regtest mode. - -**DEBUG_LOCKORDER** - -Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs -can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure -CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks -are held, and adds warnings to the debug.log file if inconsistencies are detected. diff --git a/doc/README.md b/doc/README.md index 3ec5f11df27..50753b5ee0a 100644 --- a/doc/README.md +++ b/doc/README.md @@ -51,7 +51,7 @@ Development --------------------- The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/README.md) contains relevant information on the development process and automated testing. -- [Coding Guidelines](coding.md) +- [Developer Notes](developer-notes.md) - [Multiwallet Qt Development](multiwallet-qt.md) - [Release Notes](release-notes.md) - [Release Process](release-process.md) diff --git a/doc/coding.md b/doc/developer-notes.md similarity index 67% rename from doc/coding.md rename to doc/developer-notes.md index 43294dbe4c1..eaeb90da1d1 100644 --- a/doc/coding.md +++ b/doc/developer-notes.md @@ -89,6 +89,41 @@ Not OK (used plenty in the current source, but not picked up): A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html, but if possible use one of the above styles. +Development tips and tricks +--------------------------- + +**compiling for debugging** + +Run configure with the --enable-debug option, then make. Or run configure with +CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need. + +**debug.log** + +If the code is behaving strangely, take a look in the debug.log file in the data directory; +error and debugging messages are written there. + +The -debug=... command-line option controls debugging; running with just -debug will turn +on all categories (and give you a very large debug.log file). + +The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt +to see it. + +**testnet and regtest modes** + +Run with the -testnet option to run with "play bitcoins" on the test network, if you +are testing multi-machine code that needs to operate across the internet. + +If you are testing something that can run on one machine, run with the -regtest option. +In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests +that run in -regtest mode. + +**DEBUG_LOCKORDER** + +Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs +can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure +CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks +are held, and adds warnings to the debug.log file if inconsistencies are detected. + Locking/mutex usage notes ------------------------- @@ -136,3 +171,16 @@ Threads - BitcoinMiner : Generates bitcoins (if wallet is enabled). - Shutdown : Does an orderly shutdown of everything. + +Pull Request Terminology +------------------------ + +Concept ACK - Agree with the idea and overall direction, but haven't reviewed the code changes or tested them. + +utACK (untested ACK) - Reviewed and agree with the code changes but haven't actually tested them. + +Tested ACK - Reviewed the code changes and have verified the functionality or bug fix. + +ACK - A loose ACK can be confusing. It's best to avoid them unless it's a documentation/comment only change in which case there is nothing to test/verify; therefore the tested/untested distinction is not there. + +NACK - Disagree with the code changes/concept. Should be accompanied by an explanation. From 6e718f94358bd023e5867d94c683a5635a1ff3f9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 16:24:15 +0100 Subject: [PATCH 0061/2337] Remove outdated comment about NTP The comment has been around since 0.1, but NTP inside the client isn't deemed necessary so remove the comment to avoid confusion. --- src/net.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 9e492d2fc05..2773b63f7ca 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -445,7 +445,6 @@ void CNode::PushVersion() { int nBestHeight = g_signals.GetHeight().get_value_or(0); - /// when NTP implemented, change to just nTime = GetAdjustedTime() int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0))); CAddress addrMe = GetLocalAddress(&addr); From 84857e87e42e412336ea60d0f8544c1679bab827 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sun, 7 Dec 2014 12:57:11 +0100 Subject: [PATCH 0062/2337] add missing CAutoFile::IsNull() check in main Rebased-From: ccd056a30db0ba5e04b858a682907b378e464d34 Github-Pull: #5437 --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 9c038f90fa7..3e0741ae7b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1086,6 +1086,8 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock CDiskTxPos postx; if (pblocktree->ReadTxIndex(hash, postx)) { CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); + if (file.IsNull()) + return error("%s: OpenBlockFile failed", __func__); CBlockHeader header; try { file >> header; From f914f1a746d7f91951c1da262a4a749dd3ebfa71 Mon Sep 17 00:00:00 2001 From: sandakersmann Date: Wed, 17 Dec 2014 02:47:57 +0100 Subject: [PATCH 0063/2337] Added "Core" to copyright headers Github-Pull: #5494 Rebased-From: 15de949bb9277e442302bdd8dee299a8d6deee60 --- contrib/devtools/README.md | 4 ++-- contrib/devtools/fix-copyright-headers.py | 4 ++-- contrib/linearize/linearize-data.py | 2 +- contrib/linearize/linearize-hashes.py | 2 +- src/alert.cpp | 2 +- src/alert.h | 2 +- src/allocators.cpp | 2 +- src/allocators.h | 2 +- src/amount.cpp | 2 +- src/amount.h | 2 +- src/base58.cpp | 2 +- src/base58.h | 2 +- src/bitcoin-cli.cpp | 2 +- src/bitcoin-tx.cpp | 2 +- src/bitcoind.cpp | 2 +- src/bloom.cpp | 2 +- src/bloom.h | 2 +- src/chain.cpp | 2 +- src/chain.h | 2 +- src/chainparams.cpp | 2 +- src/chainparams.h | 2 +- src/chainparamsbase.cpp | 2 +- src/chainparamsbase.h | 2 +- src/checkpoints.cpp | 2 +- src/checkpoints.h | 2 +- src/checkqueue.h | 2 +- src/clientversion.cpp | 2 +- src/clientversion.h | 2 +- src/coincontrol.h | 2 +- src/coins.cpp | 2 +- src/coins.h | 2 +- src/compat.h | 2 +- src/compat/glibc_compat.cpp | 2 +- src/compat/glibc_sanity.cpp | 2 +- src/compat/glibcxx_compat.cpp | 2 +- src/compat/glibcxx_sanity.cpp | 2 +- src/compat/sanity.h | 2 +- src/compat/strnlen.cpp | 2 +- src/compressor.cpp | 2 +- src/compressor.h | 2 +- src/core_io.h | 2 +- src/core_read.cpp | 2 +- src/core_write.cpp | 2 +- src/crypter.cpp | 2 +- src/crypter.h | 2 +- src/crypto/common.h | 2 +- src/crypto/hmac_sha256.cpp | 2 +- src/crypto/hmac_sha256.h | 2 +- src/crypto/hmac_sha512.cpp | 2 +- src/crypto/hmac_sha512.h | 2 +- src/crypto/rfc6979_hmac_sha256.cpp | 2 +- src/crypto/rfc6979_hmac_sha256.h | 2 +- src/crypto/ripemd160.cpp | 2 +- src/crypto/ripemd160.h | 2 +- src/crypto/sha1.cpp | 2 +- src/crypto/sha1.h | 2 +- src/crypto/sha256.cpp | 2 +- src/crypto/sha256.h | 2 +- src/crypto/sha512.cpp | 2 +- src/crypto/sha512.h | 2 +- src/db.cpp | 2 +- src/db.h | 2 +- src/eccryptoverify.cpp | 2 +- src/eccryptoverify.h | 2 +- src/ecwrapper.cpp | 2 +- src/ecwrapper.h | 2 +- src/hash.cpp | 2 +- src/hash.h | 2 +- src/init.cpp | 2 +- src/init.h | 2 +- src/key.cpp | 2 +- src/key.h | 2 +- src/keystore.cpp | 2 +- src/keystore.h | 2 +- src/leveldbwrapper.cpp | 2 +- src/leveldbwrapper.h | 2 +- src/limitedmap.h | 2 +- src/main.cpp | 2 +- src/main.h | 2 +- src/merkleblock.cpp | 2 +- src/merkleblock.h | 2 +- src/miner.cpp | 2 +- src/miner.h | 2 +- src/mruset.h | 2 +- src/net.cpp | 2 +- src/net.h | 2 +- src/netbase.cpp | 2 +- src/netbase.h | 2 +- src/noui.cpp | 2 +- src/noui.h | 2 +- src/pow.cpp | 2 +- src/pow.h | 2 +- src/primitives/block.cpp | 2 +- src/primitives/block.h | 2 +- src/primitives/transaction.cpp | 2 +- src/primitives/transaction.h | 2 +- src/protocol.cpp | 2 +- src/protocol.h | 2 +- src/pubkey.cpp | 2 +- src/pubkey.h | 2 +- src/qt/addressbookpage.cpp | 2 +- src/qt/addressbookpage.h | 2 +- src/qt/addresstablemodel.cpp | 2 +- src/qt/addresstablemodel.h | 2 +- src/qt/askpassphrasedialog.cpp | 2 +- src/qt/askpassphrasedialog.h | 2 +- src/qt/bitcoin.cpp | 2 +- src/qt/bitcoinaddressvalidator.cpp | 2 +- src/qt/bitcoinaddressvalidator.h | 2 +- src/qt/bitcoinamountfield.cpp | 2 +- src/qt/bitcoinamountfield.h | 2 +- src/qt/bitcoingui.cpp | 2 +- src/qt/bitcoingui.h | 2 +- src/qt/bitcoinunits.cpp | 2 +- src/qt/bitcoinunits.h | 2 +- src/qt/clientmodel.cpp | 2 +- src/qt/clientmodel.h | 2 +- src/qt/coincontroldialog.cpp | 2 +- src/qt/coincontroldialog.h | 2 +- src/qt/coincontroltreewidget.cpp | 2 +- src/qt/coincontroltreewidget.h | 2 +- src/qt/csvmodelwriter.cpp | 2 +- src/qt/csvmodelwriter.h | 2 +- src/qt/editaddressdialog.cpp | 2 +- src/qt/editaddressdialog.h | 2 +- src/qt/guiconstants.h | 2 +- src/qt/guiutil.cpp | 2 +- src/qt/guiutil.h | 2 +- src/qt/intro.cpp | 2 +- src/qt/intro.h | 2 +- src/qt/macdockiconhandler.h | 2 +- src/qt/macnotificationhandler.h | 2 +- src/qt/networkstyle.cpp | 2 +- src/qt/networkstyle.h | 2 +- src/qt/notificator.cpp | 2 +- src/qt/notificator.h | 2 +- src/qt/openuridialog.cpp | 2 +- src/qt/openuridialog.h | 2 +- src/qt/optionsdialog.cpp | 2 +- src/qt/optionsdialog.h | 2 +- src/qt/optionsmodel.cpp | 2 +- src/qt/optionsmodel.h | 2 +- src/qt/overviewpage.cpp | 2 +- src/qt/overviewpage.h | 2 +- src/qt/paymentrequestplus.cpp | 2 +- src/qt/paymentserver.cpp | 2 +- src/qt/paymentserver.h | 2 +- src/qt/peertablemodel.cpp | 2 +- src/qt/peertablemodel.h | 2 +- src/qt/qvalidatedlineedit.cpp | 2 +- src/qt/qvalidatedlineedit.h | 2 +- src/qt/qvaluecombobox.cpp | 2 +- src/qt/qvaluecombobox.h | 2 +- src/qt/receivecoinsdialog.cpp | 2 +- src/qt/receivecoinsdialog.h | 2 +- src/qt/receiverequestdialog.cpp | 2 +- src/qt/receiverequestdialog.h | 2 +- src/qt/recentrequeststablemodel.cpp | 2 +- src/qt/recentrequeststablemodel.h | 2 +- src/qt/rpcconsole.cpp | 2 +- src/qt/rpcconsole.h | 2 +- src/qt/sendcoinsdialog.cpp | 2 +- src/qt/sendcoinsdialog.h | 2 +- src/qt/sendcoinsentry.cpp | 2 +- src/qt/sendcoinsentry.h | 2 +- src/qt/signverifymessagedialog.cpp | 2 +- src/qt/signverifymessagedialog.h | 2 +- src/qt/splashscreen.cpp | 2 +- src/qt/splashscreen.h | 2 +- src/qt/test/paymentrequestdata.h | 2 +- src/qt/test/paymentservertests.cpp | 2 +- src/qt/test/paymentservertests.h | 2 +- src/qt/test/test_main.cpp | 2 +- src/qt/test/uritests.cpp | 2 +- src/qt/test/uritests.h | 2 +- src/qt/trafficgraphwidget.cpp | 2 +- src/qt/trafficgraphwidget.h | 2 +- src/qt/transactiondesc.cpp | 2 +- src/qt/transactiondesc.h | 2 +- src/qt/transactiondescdialog.cpp | 2 +- src/qt/transactiondescdialog.h | 2 +- src/qt/transactionfilterproxy.cpp | 2 +- src/qt/transactionfilterproxy.h | 2 +- src/qt/transactionrecord.cpp | 2 +- src/qt/transactionrecord.h | 2 +- src/qt/transactiontablemodel.cpp | 2 +- src/qt/transactiontablemodel.h | 2 +- src/qt/transactionview.cpp | 2 +- src/qt/transactionview.h | 2 +- src/qt/utilitydialog.cpp | 2 +- src/qt/utilitydialog.h | 2 +- src/qt/walletframe.cpp | 2 +- src/qt/walletframe.h | 2 +- src/qt/walletmodel.cpp | 2 +- src/qt/walletmodel.h | 2 +- src/qt/walletmodeltransaction.cpp | 2 +- src/qt/walletmodeltransaction.h | 2 +- src/qt/walletview.cpp | 2 +- src/qt/walletview.h | 2 +- src/qt/winshutdownmonitor.cpp | 2 +- src/qt/winshutdownmonitor.h | 2 +- src/random.cpp | 2 +- src/random.h | 2 +- src/rest.cpp | 2 +- src/rpcblockchain.cpp | 2 +- src/rpcclient.cpp | 2 +- src/rpcclient.h | 2 +- src/rpcdump.cpp | 2 +- src/rpcmining.cpp | 2 +- src/rpcmisc.cpp | 2 +- src/rpcnet.cpp | 2 +- src/rpcprotocol.cpp | 2 +- src/rpcprotocol.h | 2 +- src/rpcrawtransaction.cpp | 2 +- src/rpcserver.cpp | 2 +- src/rpcserver.h | 2 +- src/rpcwallet.cpp | 2 +- src/script/bitcoinconsensus.cpp | 2 +- src/script/bitcoinconsensus.h | 2 +- src/script/interpreter.cpp | 2 +- src/script/interpreter.h | 2 +- src/script/script.cpp | 2 +- src/script/script.h | 2 +- src/script/script_error.cpp | 2 +- src/script/script_error.h | 2 +- src/script/sigcache.cpp | 2 +- src/script/sigcache.h | 2 +- src/script/sign.cpp | 2 +- src/script/sign.h | 2 +- src/script/standard.cpp | 2 +- src/script/standard.h | 2 +- src/serialize.h | 2 +- src/streams.h | 2 +- src/sync.cpp | 2 +- src/sync.h | 2 +- src/test/bignum.h | 2 +- src/threadsafety.h | 2 +- src/timedata.cpp | 2 +- src/timedata.h | 2 +- src/txdb.cpp | 2 +- src/txdb.h | 2 +- src/txmempool.cpp | 2 +- src/txmempool.h | 2 +- src/ui_interface.h | 2 +- src/uint256.cpp | 2 +- src/uint256.h | 2 +- src/undo.h | 2 +- src/util.cpp | 2 +- src/util.h | 2 +- src/utilmoneystr.cpp | 2 +- src/utilmoneystr.h | 2 +- src/utilstrencodings.cpp | 2 +- src/utilstrencodings.h | 2 +- src/utiltime.cpp | 2 +- src/utiltime.h | 2 +- src/version.h | 2 +- src/wallet.cpp | 2 +- src/wallet.h | 2 +- src/wallet_ismine.cpp | 2 +- src/wallet_ismine.h | 2 +- src/walletdb.cpp | 2 +- src/walletdb.h | 2 +- 262 files changed, 264 insertions(+), 264 deletions(-) diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index a57b4e561e6..40495cce8b1 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -44,10 +44,10 @@ If you run this script from src/ it will automatically update the year on the co .cpp and .h files if these have a git commit from the current year. For example a file changed in 2014 (with 2014 being the current year): -```// Copyright (c) 2009-2013 The Bitcoin developers``` +```// Copyright (c) 2009-2013 The Bitcoin Core developers``` would be changed to: -```// Copyright (c) 2009-2014 The Bitcoin developers``` +```// Copyright (c) 2009-2014 The Bitcoin Core developers``` symbol-check.py ================== diff --git a/contrib/devtools/fix-copyright-headers.py b/contrib/devtools/fix-copyright-headers.py index 52fdc99144b..5e849525485 100755 --- a/contrib/devtools/fix-copyright-headers.py +++ b/contrib/devtools/fix-copyright-headers.py @@ -7,11 +7,11 @@ a perl regex one liner. For example: if it finds something like this and we're in 2014 -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers it will change it to -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers It will do this for all the files in the folder and its children. diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index 4079844e331..a3a1173b1f3 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -2,7 +2,7 @@ # # linearize-data.py: Construct a linear, no-fork version of the chain. # -# Copyright (c) 2013-2014 The Bitcoin developers +# Copyright (c) 2013-2014 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/contrib/linearize/linearize-hashes.py b/contrib/linearize/linearize-hashes.py index 707dfcf87e5..854cf1f9eeb 100755 --- a/contrib/linearize/linearize-hashes.py +++ b/contrib/linearize/linearize-hashes.py @@ -2,7 +2,7 @@ # # linearize-hashes.py: List blocks in a linear, no-fork version of the chain. # -# Copyright (c) 2013-2014 The Bitcoin developers +# Copyright (c) 2013-2014 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/src/alert.cpp b/src/alert.cpp index 64399a42607..370d0cecc6f 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/alert.h b/src/alert.h index de4aad81479..af42171af5b 100644 --- a/src/alert.h +++ b/src/alert.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/allocators.cpp b/src/allocators.cpp index b1a6a8f98ec..d3958aa4d70 100644 --- a/src/allocators.cpp +++ b/src/allocators.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/allocators.h b/src/allocators.h index 599a4ddc41a..6a131c35172 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/amount.cpp b/src/amount.cpp index e6f5b7d4407..0a394c96fc0 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/amount.h b/src/amount.h index c0d37954cb0..9212244a885 100644 --- a/src/amount.h +++ b/src/amount.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/base58.cpp b/src/base58.cpp index c594993ea09..980d3cbf429 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/base58.h b/src/base58.h index c4cb96814cc..ed134e6e77a 100644 --- a/src/base58.h +++ b/src/base58.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 14d9fcd0f38..668d492d6bc 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 549b5ab6d81..337cd44cd94 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index b882f104ab9..8a1745b50d7 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bloom.cpp b/src/bloom.cpp index da30e6f355f..e60576f4b4c 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bloom.h b/src/bloom.h index f54922edb98..191ffa19b32 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chain.cpp b/src/chain.cpp index 3dbaf5a36a4..719256106e0 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chain.h b/src/chain.h index 98db9898796..b459c975f82 100644 --- a/src/chain.h +++ b/src/chain.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 8a6a061ea1e..7562509bd51 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparams.h b/src/chainparams.h index 5d1ee1d3c6b..60c7b475856 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 8646a31603c..e45536ce71f 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index eaf3fea1b6f..24db9b2840c 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 0fb4411e633..71579bb309e 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkpoints.h b/src/checkpoints.h index 65c5165f0f0..29dc5f83a95 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkqueue.h b/src/checkqueue.h index 2ee46a1210a..b8e2a17c763 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/clientversion.cpp b/src/clientversion.cpp index b3414fdb4b5..aae0569bba2 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/clientversion.h b/src/clientversion.h index 32deaa0f1ef..40de7837aa7 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/coincontrol.h b/src/coincontrol.h index 634cc3a298d..92fae9847c3 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/coins.cpp b/src/coins.cpp index c2e802c9536..bc430c9c7e6 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/coins.h b/src/coins.h index dbe3f8bd316..9b73ae3a874 100644 --- a/src/coins.h +++ b/src/coins.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat.h b/src/compat.h index 44bf0d1ff5e..7a5438a11e6 100644 --- a/src/compat.h +++ b/src/compat.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp index f149a08cd59..3b9c70df7fe 100644 --- a/src/compat/glibc_compat.cpp +++ b/src/compat/glibc_compat.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat/glibc_sanity.cpp b/src/compat/glibc_sanity.cpp index 607e23b5682..d62d74d462c 100644 --- a/src/compat/glibc_sanity.cpp +++ b/src/compat/glibc_sanity.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat/glibcxx_compat.cpp b/src/compat/glibcxx_compat.cpp index e0b4ac51f59..4f2771e57a0 100644 --- a/src/compat/glibcxx_compat.cpp +++ b/src/compat/glibcxx_compat.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat/glibcxx_sanity.cpp b/src/compat/glibcxx_sanity.cpp index aafa4a6aef8..cee8a98c7f5 100644 --- a/src/compat/glibcxx_sanity.cpp +++ b/src/compat/glibcxx_sanity.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat/sanity.h b/src/compat/sanity.h index 7f5bc1a4fb5..909c4f6da82 100644 --- a/src/compat/sanity.h +++ b/src/compat/sanity.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat/strnlen.cpp b/src/compat/strnlen.cpp index 7f3e1598875..1ac266c2d1b 100644 --- a/src/compat/strnlen.cpp +++ b/src/compat/strnlen.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compressor.cpp b/src/compressor.cpp index c47a0f6f8c5..20c154fc1e5 100644 --- a/src/compressor.cpp +++ b/src/compressor.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compressor.h b/src/compressor.h index efb8119d018..4a720908305 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_io.h b/src/core_io.h index c805dbc6d5d..e0620e86b6f 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_read.cpp b/src/core_read.cpp index 750f83ee52c..a49705e0459 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_write.cpp b/src/core_write.cpp index 400b4c623df..b6fd7fe8773 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypter.cpp b/src/crypter.cpp index de32dc412cd..00f7f7f1bd8 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypter.h b/src/crypter.h index f7018cfdbea..7b4c2f26132 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/common.h b/src/crypto/common.h index 67c30023c3c..8b04b1f728f 100644 --- a/src/crypto/common.h +++ b/src/crypto/common.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/hmac_sha256.cpp b/src/crypto/hmac_sha256.cpp index 435896538bf..3c791625d01 100644 --- a/src/crypto/hmac_sha256.cpp +++ b/src/crypto/hmac_sha256.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/hmac_sha256.h b/src/crypto/hmac_sha256.h index 1fdee5a7cdd..1519c1457e0 100644 --- a/src/crypto/hmac_sha256.h +++ b/src/crypto/hmac_sha256.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/hmac_sha512.cpp b/src/crypto/hmac_sha512.cpp index 940a93277c0..5939c6ec47f 100644 --- a/src/crypto/hmac_sha512.cpp +++ b/src/crypto/hmac_sha512.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/hmac_sha512.h b/src/crypto/hmac_sha512.h index 17d75021aa2..17dee61ea8e 100644 --- a/src/crypto/hmac_sha512.h +++ b/src/crypto/hmac_sha512.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/rfc6979_hmac_sha256.cpp b/src/crypto/rfc6979_hmac_sha256.cpp index 3f935abfea3..a8c971c3ba9 100644 --- a/src/crypto/rfc6979_hmac_sha256.cpp +++ b/src/crypto/rfc6979_hmac_sha256.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/rfc6979_hmac_sha256.h b/src/crypto/rfc6979_hmac_sha256.h index e67ddcf8fe5..f3a54a5d118 100644 --- a/src/crypto/rfc6979_hmac_sha256.h +++ b/src/crypto/rfc6979_hmac_sha256.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp index cb4a94a44da..77c9acfc26e 100644 --- a/src/crypto/ripemd160.cpp +++ b/src/crypto/ripemd160.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h index f468ec67227..687204fdae8 100644 --- a/src/crypto/ripemd160.h +++ b/src/crypto/ripemd160.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp index 7f78fdfc6d2..0b895b33a29 100644 --- a/src/crypto/sha1.cpp +++ b/src/crypto/sha1.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h index e28f98decdb..7b2a21bc6c6 100644 --- a/src/crypto/sha1.h +++ b/src/crypto/sha1.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 8410e593054..5b9f00a0a2d 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h index bde1a59bedb..85cf33739ae 100644 --- a/src/crypto/sha256.h +++ b/src/crypto/sha256.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/sha512.cpp b/src/crypto/sha512.cpp index 22c3103bed1..564127cc319 100644 --- a/src/crypto/sha512.cpp +++ b/src/crypto/sha512.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/crypto/sha512.h b/src/crypto/sha512.h index 5566d5db3ef..f1f17caf90c 100644 --- a/src/crypto/sha512.h +++ b/src/crypto/sha512.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/db.cpp b/src/db.cpp index cb24912fe0b..94629968d5c 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/db.h b/src/db.h index 1c572d8970d..717462ff4f1 100644 --- a/src/db.h +++ b/src/db.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/eccryptoverify.cpp b/src/eccryptoverify.cpp index 435154d608e..e894e1122c5 100644 --- a/src/eccryptoverify.cpp +++ b/src/eccryptoverify.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/eccryptoverify.h b/src/eccryptoverify.h index da7e80c7c32..c67c1e44fce 100644 --- a/src/eccryptoverify.h +++ b/src/eccryptoverify.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp index 5ce7e612946..c29390eb98b 100644 --- a/src/ecwrapper.cpp +++ b/src/ecwrapper.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/ecwrapper.h b/src/ecwrapper.h index 4efde516507..efb6cd18a77 100644 --- a/src/ecwrapper.h +++ b/src/ecwrapper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/hash.cpp b/src/hash.cpp index aaca00ea2d3..a7eb5a2a0b1 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The Bitcoin developers +// Copyright (c) 2013-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/hash.h b/src/hash.h index 5a34cdc5c3c..e56b784a61f 100644 --- a/src/hash.h +++ b/src/hash.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/init.cpp b/src/init.cpp index 63199b3206e..220d3b93ae1 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/init.h b/src/init.h index f2f7ac6747a..d451f65be93 100644 --- a/src/init.h +++ b/src/init.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/key.cpp b/src/key.cpp index 36613342b8b..7f1cef17082 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/key.h b/src/key.h index d85abe095c7..85cc1e55db0 100644 --- a/src/key.h +++ b/src/key.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/keystore.cpp b/src/keystore.cpp index 879f0997201..482125a39ae 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/keystore.h b/src/keystore.h index 60502e9a29c..6655264d720 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp index 70980fede5a..c353dfa6d90 100644 --- a/src/leveldbwrapper.cpp +++ b/src/leveldbwrapper.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h index 42479206c89..c65e842704a 100644 --- a/src/leveldbwrapper.h +++ b/src/leveldbwrapper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/limitedmap.h b/src/limitedmap.h index 03727d7c425..e8ea549653b 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/main.cpp b/src/main.cpp index 3e0741ae7b8..dd71c53d9d3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/main.h b/src/main.h index 8f0378647d1..717cec769e2 100644 --- a/src/main.h +++ b/src/main.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 8618e355d74..1b7ee27e02a 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/merkleblock.h b/src/merkleblock.h index c549e3cdbab..52c914967ff 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/miner.cpp b/src/miner.cpp index 82f992e854b..2133b13e629 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/miner.h b/src/miner.h index 998ea57a76d..02dedb1712a 100644 --- a/src/miner.h +++ b/src/miner.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/mruset.h b/src/mruset.h index bf7c7fdeeaa..1969f419cbf 100644 --- a/src/mruset.h +++ b/src/mruset.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Bitcoin developers +// Copyright (c) 2012 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/net.cpp b/src/net.cpp index 3f4017d1316..474a3e42882 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/net.h b/src/net.h index c705a85c803..fed5a5959fd 100644 --- a/src/net.h +++ b/src/net.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/netbase.cpp b/src/netbase.cpp index 1fc3334b7b8..a2ac6575bcd 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/netbase.h b/src/netbase.h index fe5d64320c9..5bf13a673f3 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/noui.cpp b/src/noui.cpp index 630b095d0b7..3a77361919e 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/noui.h b/src/noui.h index c7e4aaa1e1b..15cd30a639d 100644 --- a/src/noui.h +++ b/src/noui.h @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin developers +// Copyright (c) 2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/pow.cpp b/src/pow.cpp index 3b41083f9d0..e91e3d893c3 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/pow.h b/src/pow.h index 293634be6f6..89b219f808f 100644 --- a/src/pow.h +++ b/src/pow.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index cf7a392a32d..2b6a302ee97 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/block.h b/src/primitives/block.h index 9c0a6deccaf..1449882bd05 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 336151905ce..230aedd896b 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index a7a1e013ede..da350123000 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/protocol.cpp b/src/protocol.cpp index f8f43a05f77..71c6bd152bb 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/protocol.h b/src/protocol.h index e578c1ec999..f8394ce52fd 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 80bbac9205d..3ae67ca5feb 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/pubkey.h b/src/pubkey.h index 37351cff0e8..69b73a4e1ce 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 303c7c2335a..fd3c1f2c0d0 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index b3c308dc0b1..5105f09ced8 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index c42a55ec27e..bfb5bf3fec9 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 33504e0c694..6b34b2eac22 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 181ef081292..9b7b59c0db3 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index bedbea21351..74d54d18f7b 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 08f72e17165..1adf4e00cb4 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp index d7c4d27066d..d712705c431 100644 --- a/src/qt/bitcoinaddressvalidator.cpp +++ b/src/qt/bitcoinaddressvalidator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h index 5689266081d..30d4a26d0e7 100644 --- a/src/qt/bitcoinaddressvalidator.h +++ b/src/qt/bitcoinaddressvalidator.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index 408634dec03..fdb9bcd6d6a 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index 4bab91eaf0b..b047e6c51a0 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 89a4f9838e6..4eef1858552 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 7cda8c15cb9..7509a00734b 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 863d4a01aa7..758fba70584 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index c40fd8b16cd..a01fcc8cf97 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index a121ec5879b..493cdd6dd23 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 5a8b436602a..4856a72d7d0 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 5647661ba57..e650e0ffa6f 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 8945bf18050..09744430660 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp index bb8f385bb20..6cbcf7128d8 100644 --- a/src/qt/coincontroltreewidget.cpp +++ b/src/qt/coincontroltreewidget.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroltreewidget.h b/src/qt/coincontroltreewidget.h index e9bfe2352b5..98a7d32f050 100644 --- a/src/qt/coincontroltreewidget.h +++ b/src/qt/coincontroltreewidget.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp index a998850198e..55c59570889 100644 --- a/src/qt/csvmodelwriter.cpp +++ b/src/qt/csvmodelwriter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h index d3cf5d732c1..a2bf379f4eb 100644 --- a/src/qt/csvmodelwriter.h +++ b/src/qt/csvmodelwriter.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 2be7598e7b8..1c22594cd74 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index e25db7a1165..13c6da8edaf 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 819e5c9e275..a0a2993ea36 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 5adf17361b7..a3ede9fd622 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 73b63789be9..4f8c683147f 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 88dbfd24d07..fb7ed155943 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/intro.h b/src/qt/intro.h index 03974841b52..c9735615b67 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 98913698467..1217bd8e88a 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/macnotificationhandler.h b/src/qt/macnotificationhandler.h index c08c3279945..bd66b96b218 100644 --- a/src/qt/macnotificationhandler.h +++ b/src/qt/macnotificationhandler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 2da54876cd7..4541c75886b 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h index 953004c1275..b78a9f5948f 100644 --- a/src/qt/networkstyle.h +++ b/src/qt/networkstyle.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 86b205ed8a9..5a564248ec6 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/notificator.h b/src/qt/notificator.h index a7605f83bec..182e948c7d4 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index a1de7aceaed..1c843aecb14 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index 4f4fdccaf5e..d5c434ba9c8 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 8ce9fd7a6e4..a0f3993e695 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index 0197491506d..f4e5157595b 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 1e11de3c115..7d2dbd96de7 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 061ae1ad92d..bf892768ed5 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 18c900d025c..01b4036f853 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 803816fa41d..64cb1dc4e0b 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index ca3f06962ac..35846bc153d 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index bd3dab41a8f..3f8e89535e1 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index e1305b94376..2fc24395f62 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 7840b9283ed..dfb7a623afc 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index ac3a18c0539..bff7bb824ef 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp index d960e4b1960..346369392c8 100644 --- a/src/qt/qvalidatedlineedit.cpp +++ b/src/qt/qvalidatedlineedit.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h index 810d5f27698..f63568d27f7 100644 --- a/src/qt/qvalidatedlineedit.h +++ b/src/qt/qvalidatedlineedit.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index 8c578dfa5e0..f73268c9587 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index 62b1d90ddf6..dc85d64cb5b 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index ee3a046aa24..aa1440e2c63 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index ae93b5aa85a..70a1842fa2e 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 9d932cfc903..0c4a20cf92c 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index b69ef42573e..3e5f897be6f 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index adc4e115ed6..5221ec3e24a 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index 741a8148f04..85bad126dba 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 9528e72d26a..271315b8c54 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 947d2b4a952..fff5cfbf592 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 46cbbb161a1..cde77a5d44e 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 9db9252f7df..14adb025735 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 6a71081993d..ad9189d20a7 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index b3d846c949c..4cb00cd36a2 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index c793262adda..e16e245b634 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index d8e240b555b..27807adc849 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 049b775d59f..366ed3df3de 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 63eb0714c02..84e4556dd86 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index aeaa7d89a03..37544cdebbb 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index 8f49cb94642..70254cd75d7 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h index 0717111f664..c98bbf0833a 100644 --- a/src/qt/test/paymentservertests.h +++ b/src/qt/test/paymentservertests.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index f2161c2f793..da5f0743907 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp index 78a7b1b9b47..8b53c0d5c77 100644 --- a/src/qt/test/uritests.cpp +++ b/src/qt/test/uritests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h index ed30a9f4a78..a0b7dc6c72e 100644 --- a/src/qt/test/uritests.h +++ b/src/qt/test/uritests.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index a1a03b2971e..0b2eb9eaf2e 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h index 18336de949c..4c6b17fe7ea 100644 --- a/src/qt/trafficgraphwidget.h +++ b/src/qt/trafficgraphwidget.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index ed8be628a6a..68c275d4945 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h index 04f54ba08e9..5467348ee90 100644 --- a/src/qt/transactiondesc.h +++ b/src/qt/transactiondesc.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp index 56e1fc050b6..fadaa98f4aa 100644 --- a/src/qt/transactiondescdialog.cpp +++ b/src/qt/transactiondescdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h index f10a1362175..54374e359d4 100644 --- a/src/qt/transactiondescdialog.h +++ b/src/qt/transactiondescdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index 67733d31187..7981eb7c91f 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index 42f4df4d652..acea9a1e3bc 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 9905ca76f9a..fea436806a5 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 3accbb26eeb..a5bc3757171 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 73e3d9de7dd..1dea5cdad9f 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 525b23bfe8e..5eaccad0648 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 58f33f95a72..00fd209c9ff 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index baad0fcbfb0..2858982f097 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 929f8156dc3..e6cec8173e9 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 1cbded02532..288b985f137 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index 4084adc96cb..892947bf3ab 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 68bd1ce219d..eea97defc93 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 8355125c4df..6006a7bd7b6 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 17f1b9f2e94..d8df25f6606 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index a9183d11abc..8f32e46148d 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index 48bcbc88419..b6bb6d67f6b 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 77db9757fbb..28b9c3b5694 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 6c2c3ca61e5..f3d14c065c0 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin developers +// Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp index 51391a9331a..1bc4f779597 100644 --- a/src/qt/winshutdownmonitor.cpp +++ b/src/qt/winshutdownmonitor.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/winshutdownmonitor.h b/src/qt/winshutdownmonitor.h index a8176f95146..0bed55a2c63 100644 --- a/src/qt/winshutdownmonitor.h +++ b/src/qt/winshutdownmonitor.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/random.cpp b/src/random.cpp index 3a1311cb595..663456e962b 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/random.h b/src/random.h index 214ee0a7979..1a2d3e8ee24 100644 --- a/src/random.h +++ b/src/random.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rest.cpp b/src/rest.cpp index 69e6c08886c..4702f0d7070 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 66e86ebace4..71fb7c8233a 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 03ce9acbbf7..4e45bc32ab4 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcclient.h b/src/rpcclient.h index a91c2eb0332..42fa2d06fe2 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 8b95373cffe..8666779cc16 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 45899d3db53..44ebff9d32d 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 90b9c99caa0..b8805b9d51d 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 6ddbd62fca8..2886f7adab5 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 2f7c491f3d4..c4d6f06b12c 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index f4a4877d388..4f3f70fb372 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index f596c358a90..b87a8baac3c 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index c0f0d253f2d..c5d74afba94 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcserver.h b/src/rpcserver.h index 8fea38126c0..fb561ab939a 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index e43eee1551a..63da8a20b57 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index e80e55df759..c8dd54a7471 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index 15e3337a8de..9d9c266435f 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 3231f2e74e5..80a32e78f90 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 35b2f6c65a1..3c4e7d466a7 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/script.cpp b/src/script/script.cpp index b879d72d6b9..fd33924732c 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/script.h b/src/script/script.h index 9c22cb908cf..78fd12cd290 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index 5d24ed98ba8..d8ecfde1d71 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/script_error.h b/src/script/script_error.h index 091524f35cb..5c260327b60 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 5580a5933e6..75ecdb563dc 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sigcache.h b/src/script/sigcache.h index df2a2ea13c8..3bd11caff52 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 03c33ad9b52..adddd4ec789 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sign.h b/src/script/sign.h index 45a5e0dea33..e197d5fab37 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/standard.cpp b/src/script/standard.cpp index ab6e6cde0de..d0e2250049c 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/standard.h b/src/script/standard.h index c4b82b4c45a..1d29ef57aa8 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/serialize.h b/src/serialize.h index ad38a3fa22a..e4a4039c719 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/streams.h b/src/streams.h index ba074a4c23e..6bd6d2b920f 100644 --- a/src/streams.h +++ b/src/streams.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/sync.cpp b/src/sync.cpp index e2f05e62a0b..e28caee8e76 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2012 The Bitcoin developers +// Copyright (c) 2011-2012 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/sync.h b/src/sync.h index 29006b3ed9a..7891e415605 100644 --- a/src/sync.h +++ b/src/sync.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/bignum.h b/src/test/bignum.h index 7ed62606f8b..365b17a1c5d 100644 --- a/src/test/bignum.h +++ b/src/test/bignum.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/threadsafety.h b/src/threadsafety.h index 5409c030186..d01c50abb6b 100644 --- a/src/threadsafety.h +++ b/src/threadsafety.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2009-2012 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/timedata.cpp b/src/timedata.cpp index 59f7778db17..d04f3d2f781 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/timedata.h b/src/timedata.h index 64595ffc37a..2296baf11bb 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txdb.cpp b/src/txdb.cpp index f735476a1a3..5096ab19a5d 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txdb.h b/src/txdb.h index f81fc626897..f6b6b84fcf2 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 1df9c5c79c7..40d24d3b787 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txmempool.h b/src/txmempool.h index f671352b585..0732af67e65 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/ui_interface.h b/src/ui_interface.h index 8d63e0464c3..3f11a1ddabe 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2012 The Bitcoin developers +// Copyright (c) 2012 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/uint256.cpp b/src/uint256.cpp index 9d87327d8cd..918c1a7cd7b 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/uint256.h b/src/uint256.h index 56f7f44a162..139270ac498 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/undo.h b/src/undo.h index 2301bd8b431..e6d8fd58627 100644 --- a/src/undo.h +++ b/src/undo.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/util.cpp b/src/util.cpp index 282e54e4886..0d0f7e5f919 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/util.h b/src/util.h index 623c24f5cc7..bbb0e81039a 100644 --- a/src/util.h +++ b/src/util.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp index 3e076a02661..2fbc048878f 100644 --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h index 6a153db5fa7..cd9b04810d9 100644 --- a/src/utilmoneystr.h +++ b/src/utilmoneystr.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 419a63c4317..c15bddc6fb9 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index 0c0171b8944..b0edd8b542d 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utiltime.cpp b/src/utiltime.cpp index 9c137e8aa0a..8f0dcae29d3 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utiltime.h b/src/utiltime.h index 9d7d42fe473..900992f8717 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/version.h b/src/version.h index a5a72c5467b..38b3d2e7343 100644 --- a/src/version.h +++ b/src/version.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin developers +// Copyright (c) 2012-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet.cpp b/src/wallet.cpp index 94e6ccf99e3..9b9a1d1735e 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet.h b/src/wallet.h index 2dd2146e8cf..8ad01265d6a 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet_ismine.cpp b/src/wallet_ismine.cpp index 839f694850f..5482348e356 100644 --- a/src/wallet_ismine.cpp +++ b/src/wallet_ismine.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet_ismine.h b/src/wallet_ismine.h index 5f0c0c1a012..6293df8b10e 100644 --- a/src/wallet_ismine.h +++ b/src/wallet_ismine.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 416403b096f..4fd7eb512b9 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/walletdb.h b/src/walletdb.h index 38699043ba1..45c00328a4c 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. From dd14a0e799b6552ae85aaab2b0b48f788c578aea Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 19 Dec 2014 14:39:10 -0500 Subject: [PATCH 0064/2337] docs: update gitian building docs --- doc/gitian-building.md | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index b356a5d88d8..defddedc6e2 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -291,7 +291,7 @@ Setting up gitian images ------------------------- Gitian needs virtual images of the operating system to build in. -Currently this is Ubuntu Precise for both x86 architectures. +Currently this is Ubuntu Precise for x86_64. These images will be copied and used every time that a build is started to make sure that the build is deterministic. Creating the images will take a while, but only has to be done once. @@ -300,7 +300,6 @@ Execute the following as user `debian`: ```bash cd gitian-builder -bin/make-base-vm --lxc --arch i386 --suite precise bin/make-base-vm --lxc --arch amd64 --suite precise ``` @@ -311,27 +310,10 @@ There will be a lot of warnings printed during build of the images. These can be Getting and building the inputs -------------------------------- -In [doc/release-process.md](release-process.md) in the bitcoin repository under 'Fetch and build inputs'. -you will find a list of `wget` commands that can be executed to get the dependencies. - -I needed to add `--no-check-certificate` to the OpenSSL wget line to make it work. -Likely this is because the ca-certificates in Debian 7.4 is fairly old. This does not create a -security issue as the gitian descriptors check the integrity of the input archives and refuse to work -if any one is corrupted. - -After downloading the archives, execute the `gbuild` commands to build the dependencies. -This can take a long time, but only has to be done when the dependencies change, for example -to upgrade the used version. - -**Note**: Do not forget to copy the result from `build/out` to `inputs` after every gbuild command! This will save -you a lot of time. - -At any time you can check the package installation and build progress with - -```bash -tail -f var/install.log -tail -f var/build.log -``` +Follow the instructions in [doc/release-process.md](release-process.md) in the bitcoin repository +under 'Fetch and build inputs' to install sources which require manual intervention. Also follow +the next step: 'Seed the Gitian sources cache', which will fetch all necessary source files allowing +for gitian to work offline. Building Bitcoin ---------------- @@ -339,6 +321,15 @@ Building Bitcoin To build Bitcoin (for Linux, OSX and Windows) just follow the steps under 'perform gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository. +This may take a long time as it also builds the dependencies needed for each descriptor. +These dependencies will be cached after a successful build to avoid rebuilding them when possible. + +At any time you can check the package installation and build progress with + +```bash +tail -f var/install.log +tail -f var/build.log + Output from `gbuild` will look something like Initialized empty Git repository in /home/debian/gitian-builder/inputs/bitcoin/.git/ @@ -348,7 +339,7 @@ Output from `gbuild` will look something like Resolving deltas: 100% (25724/25724), done. From https://github.com/bitcoin/bitcoin ... (new tags, new branch etc) - --- Building for precise i386 --- + --- Building for precise x86_64 --- Stopping target if it is up Making a new image copy stdin: is not a tty @@ -363,9 +354,6 @@ Output from `gbuild` will look something like lxc-start: Connection refused - inotify event with no name (mask 32768) Running build script (log in var/build.log) -As when building the dependencies, the progress of package installation and building -can be inspected in `var/install.log` and `var/build.log`. - Building an alternative repository ----------------------------------- From aa279d613152e87ea25edfdf76c86779c0632f18 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 16 Dec 2014 01:43:40 -0800 Subject: [PATCH 0065/2337] Enforce minRelayTxFee on wallet created tx and add a maxtxfee option. Previously the minRelayTxFee was only enforced on user specified values. It was possible for smartfee to produce a fee below minRelayTxFee which would just result in the transaction getting stuck because it can't be relayed. This also introduces a maxtxfee option which sets an absolute maximum for any fee created by the wallet, with an intention of increasing user confidence that the automatic fees won't burn them. This was frequently a concern even before smartfees. If the configured fee policy won't even allow the wallet to meet the relay fee the transaction creation may be aborted. --- src/init.cpp | 15 +++++++++++++++ src/wallet.cpp | 49 +++++++++++++++++++++++++++++-------------------- src/wallet.h | 5 +++++ 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 11329c16aa4..c5ced8654e3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -288,6 +288,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n"; strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n"; strUsage += " -txconfirmtarget= " + strprintf(_("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)"), 1) + "\n"; + strUsage += " -maxtxfee= " + strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee)) + "\n"; strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n"; strUsage += " -wallet= " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n"; strUsage += " -walletnotify= " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n"; @@ -697,6 +698,20 @@ bool AppInit2(boost::thread_group& threadGroup) mapArgs["-paytxfee"], ::minRelayTxFee.ToString())); } } + if (mapArgs.count("-maxtxfee")) + { + CAmount nMaxFee = 0; + if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) + return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s'"), mapArgs["-maptxfee"])); + if (nMaxFee > nHighTransactionMaxFeeWarning) + InitWarning(_("Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.")); + maxTxFee = nMaxFee; + if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) + { + return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), + mapArgs["-maxtxfee"], ::minRelayTxFee.ToString())); + } + } nTxConfirmTarget = GetArg("-txconfirmtarget", 1); bSpendZeroConfChange = GetArg("-spendzeroconfchange", true); fSendFreeTransactions = GetArg("-sendfreetransactions", false); diff --git a/src/wallet.cpp b/src/wallet.cpp index 32a64daac0c..dd87fab44b1 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -26,6 +26,7 @@ using namespace std; * Settings */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); +CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; unsigned int nTxConfirmTarget = 1; bool bSpendZeroConfChange = true; bool fSendFreeTransactions = false; @@ -1499,28 +1500,33 @@ bool CWallet::CreateTransaction(const vector >& vecSend, } dPriority = wtxNew.ComputePriority(dPriority, nBytes); + // Can we complete this as a free transaction? + if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE) + { + // Not enough fee: enough priority? + double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget); + // Not enough mempool history to estimate: use hard-coded AllowFree. + if (dPriorityNeeded <= 0 && AllowFree(dPriority)) + break; + + // Small enough, and priority high enough, to send for free + if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded) + break; + } + CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool); + // If we made it here and we aren't even able to meet the relay fee on the next pass, give up + // because we must be at the maximum allowed fee. + if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes)) + { + strFailReason = _("Transaction too large for fee policy"); + return false; + } + if (nFeeRet >= nFeeNeeded) break; // Done, enough fee included. - // Too big to send for free? Include more fee and try again: - if (!fSendFreeTransactions || nBytes > MAX_FREE_TRANSACTION_CREATE_SIZE) - { - nFeeRet = nFeeNeeded; - continue; - } - - // Not enough fee: enough priority? - double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget); - // Not enough mempool history to estimate: use hard-coded AllowFree. - if (dPriorityNeeded <= 0 && AllowFree(dPriority)) - break; - - // Small enough, and priority high enough, to send for free - if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded) - break; - // Include more fee and try again. nFeeRet = nFeeNeeded; continue; @@ -1591,9 +1597,6 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge { // payTxFee is user-set "I want to pay this much" CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes); - // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee - if (nFeeNeeded > 0 && nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes)) - nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes); // user selected total at least (default=true) if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK()) nFeeNeeded = payTxFee.GetFeePerK(); @@ -1604,6 +1607,12 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge // back to a hard-coded fee if (nFeeNeeded == 0) nFeeNeeded = minTxFee.GetFee(nTxBytes); + // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee + if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes)) + nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes); + // But always obey the maximum + if (nFeeNeeded > maxTxFee) + nFeeNeeded = maxTxFee; return nFeeNeeded; } diff --git a/src/wallet.h b/src/wallet.h index 2dd2146e8cf..058107edf17 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -30,6 +30,7 @@ * Settings */ extern CFeeRate payTxFee; +extern CAmount maxTxFee; extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; extern bool fSendFreeTransactions; @@ -39,6 +40,10 @@ extern bool fPayAtLeastCustomFee; static const CAmount DEFAULT_TRANSACTION_FEE = 0; //! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; +//! -maxtxfee default +static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) +static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning; //! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; From be43492945f740514ad5f949d9bb4f47ef2b1926 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 19 Dec 2014 18:02:44 -0500 Subject: [PATCH 0066/2337] build: fix 'make distcheck' Rather than treating the .py as a regular built test, run it from check-local so that we can better control the paths used. --- src/Makefile.test.include | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 9e9f478d8fe..c6bd0cf9c6e 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -1,4 +1,4 @@ -TESTS += test/test_bitcoin test/bitcoin-util-test.py +TESTS += test/test_bitcoin bin_PROGRAMS += test/test_bitcoin TEST_SRCDIR = test TEST_BINARY=test/test_bitcoin$(EXEEXT) @@ -105,6 +105,8 @@ bitcoin_test_clean : FORCE rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY) check-local: + @echo "Running test/bitcoin-util-test.py..." + $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check %.json.h: %.json From adaa568722e59cde510c5fe1997c49cbb9d7db12 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 27 Oct 2014 00:07:25 -0700 Subject: [PATCH 0067/2337] Add script to verify all merge commits are signed --- contrib/README.md | 3 ++ contrib/verify-commits/gpg.sh | 15 +++++++ contrib/verify-commits/pre-push-hook.sh | 16 ++++++++ contrib/verify-commits/trusted-git-root | 1 + contrib/verify-commits/trusted-keys | 5 +++ contrib/verify-commits/verify-commits.sh | 51 ++++++++++++++++++++++++ 6 files changed, 91 insertions(+) create mode 100755 contrib/verify-commits/gpg.sh create mode 100755 contrib/verify-commits/pre-push-hook.sh create mode 100644 contrib/verify-commits/trusted-git-root create mode 100644 contrib/verify-commits/trusted-keys create mode 100755 contrib/verify-commits/verify-commits.sh diff --git a/contrib/README.md b/contrib/README.md index dae975e9efc..7d4b91e887f 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -16,6 +16,9 @@ Repository Tools Specific tools for developers working on this repository. Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG. +### [Verify-Commits](/contrib/verify-commits) ### +Tool to verify that every merge commit was signed by a developer using the above `github-merge.sh` script. + ### [Linearize](/contrib/linearize) ### Construct a linear, no-fork, best version of the blockchain. diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh new file mode 100755 index 00000000000..6b5137e7b54 --- /dev/null +++ b/contrib/verify-commits/gpg.sh @@ -0,0 +1,15 @@ +#!/bin/sh +INPUT=$(/dev/null); do + case "$LINE" in "[GNUPG:] VALIDSIG"*) + while read KEY; do + case "$LINE" in "[GNUPG:] VALIDSIG $KEY "*) VALID=true;; esac + done < ./contrib/verify-commits/trusted-keys + esac +done +if ! $VALID; then + exit 1 +fi +echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null diff --git a/contrib/verify-commits/pre-push-hook.sh b/contrib/verify-commits/pre-push-hook.sh new file mode 100755 index 00000000000..607c0cac45e --- /dev/null +++ b/contrib/verify-commits/pre-push-hook.sh @@ -0,0 +1,16 @@ +#!/bin/bash +if ! [[ "$2" =~ [git@]?[www.]?github.com[:|/]bitcoin/bitcoin[.git]? ]]; then + exit 0 +fi + +while read LINE; do + set -- A $LINE + if [ "$4" != "refs/heads/master" ]; then + continue + fi + if ! ./contrib/verify-commits/verify-commits.sh $3 > /dev/null 2>&1; then + echo "ERROR: A commit is not signed, can't push" + ./contrib/verify-commits/verify-commits.sh + exit 1 + fi +done < /dev/stdin diff --git a/contrib/verify-commits/trusted-git-root b/contrib/verify-commits/trusted-git-root new file mode 100644 index 00000000000..eb13f8762e5 --- /dev/null +++ b/contrib/verify-commits/trusted-git-root @@ -0,0 +1 @@ +053038e5ba116cb319fb85f3cb3e062cf1b3df15 diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys new file mode 100644 index 00000000000..658ad0375ba --- /dev/null +++ b/contrib/verify-commits/trusted-keys @@ -0,0 +1,5 @@ +71A3B16735405025D447E8F274810B012346C9A6 +1F4410F6A89268CE3197A84C57896D2FF8F0B657 +01CDF4627A3B88AAE4A571C87588242FBE38D3A8 +AF8BE07C7049F3A26B239D5325B3083201782B2F +81291FA67D2C379A006A053FEAB5AF94D9E9ABE7 diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh new file mode 100755 index 00000000000..5841fa2077a --- /dev/null +++ b/contrib/verify-commits/verify-commits.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +DIR=$(dirname "$0") + +echo "Please verify all commits in the following list are not evil:" +git log "$DIR" + +VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root") + +HAVE_FAILED=false +IS_SIGNED () { + if [ $1 = $VERIFIED_ROOT ]; then + return 0; + fi + if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then + return 1; + fi + local PARENTS=$(git show -s --format=format:%P $1) + for PARENT in $PARENTS; do + if IS_SIGNED $PARENT > /dev/null; then + return 0; + fi + done + if ! "$HAVE_FAILED"; then + echo "No parent of $1 was signed with a trusted key!" > /dev/stderr + echo "Parents are:" > /dev/stderr + for PARENT in $PARENTS; do + git show -s $PARENT > /dev/stderr + done + HAVE_FAILED=true + fi + return 1; +} + +if [ x"$1" = "x" ]; then + TEST_COMMIT="HEAD" +else + TEST_COMMIT="$1" +fi + +IS_SIGNED "$TEST_COMMIT" +RES=$? +if [ "$RES" = 1 ]; then + if ! "$HAVE_FAILED"; then + echo "$TEST_COMMIT was not signed with a trusted key!" + fi +else + echo "There is a valid path from $TEST_COMMIT to $VERIFIED_ROOT where all commits are signed!" +fi + +exit $RES From 39c809942d7e526a25dde470cd5e95e43fd7a774 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 20 Dec 2014 13:58:51 +0100 Subject: [PATCH 0068/2337] contrib: make github-merge require signing - Exit when there is no signing key configured - Exit when user does not want to sign off --- contrib/devtools/github-merge.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh index 6f68496ed86..ec7a1f4c4b3 100755 --- a/contrib/devtools/github-merge.sh +++ b/contrib/devtools/github-merge.sh @@ -156,12 +156,17 @@ read -p "Press 's' to sign off on the merge. " -n 1 -r >&2 echo if [[ "d$REPLY" =~ ^d[Ss]$ ]]; then if [[ "$(git config --get user.signingkey)" == "" ]]; then - echo "WARNING: No GPG signing key set, not signing. Set one using:" >&2 + echo "ERROR: No GPG signing key set, not signing. Set one using:" >&2 echo "git config --global user.signingkey " >&2 - git commit -q --signoff --amend --no-edit + cleanup + exit 1 else git commit -q --gpg-sign --amend --no-edit fi +else + echo "Not signing off on merge, exiting." + cleanup + exit 1 fi # Clean up temporary branches, and put the result in $BRANCH. From 1e22d4594f14cb5cd39dde86df76999861493e08 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Sat, 20 Dec 2014 21:26:31 +0800 Subject: [PATCH 0069/2337] Add libbitcoinconsensus.pc to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7343e722d5c..9f1e5228032 100644 --- a/.gitignore +++ b/.gitignore @@ -111,3 +111,5 @@ qa/pull-tester/test.*/* !src/leveldb*/Makefile /doc/doxygen/ + +libbitcoinconsensus.pc From 1b37333a7f113ba2458346074610861de4547927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Sat, 20 Dec 2014 16:57:46 +0100 Subject: [PATCH 0070/2337] Remove no longer needed declaration of CBlockLocator --- src/db.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/db.h b/src/db.h index 1c572d8970d..1e87852d136 100644 --- a/src/db.h +++ b/src/db.h @@ -23,8 +23,6 @@ class CDiskBlockIndex; class COutPoint; -struct CBlockLocator; - extern unsigned int nWalletDBUpdated; void ThreadFlushWalletDB(const std::string& strWalletFile); From bdb6a71d3d4173b02d24f302af2c2707df85e95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Sat, 20 Dec 2014 16:58:40 +0100 Subject: [PATCH 0071/2337] IsNull doesn't change CBlockLocator, add const hint --- src/primitives/block.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/primitives/block.h b/src/primitives/block.h index a1895925395..4f2ed36b461 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -162,7 +162,7 @@ struct CBlockLocator vHave.clear(); } - bool IsNull() + bool IsNull() const { return vHave.empty(); } From ff09e31a51dcee404c9c037c7c5f50c522e67ea8 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 7 Nov 2014 23:18:21 -0800 Subject: [PATCH 0072/2337] sleep-wait on genesis block during init with -reindex --- src/init.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 220d3b93ae1..afcfdb06213 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1207,6 +1207,11 @@ bool AppInit2(boost::thread_group& threadGroup) vImportFiles.push_back(strFile); } threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); + if (chainActive.Tip() == NULL) { + LogPrintf("Waiting for genesis block to be imported...\n"); + while (!fRequestShutdown && chainActive.Tip() == NULL) + MilliSleep(10); + } // ********************************************************* Step 10: start node From 4bc95c43871645c1d69a0d719c13b38151a3a13f Mon Sep 17 00:00:00 2001 From: Jameson Lopp Date: Sun, 21 Dec 2014 09:10:43 -0500 Subject: [PATCH 0073/2337] remove max orphan blocks config parameter since it is no longer functional --- src/init.cpp | 1 - src/main.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 220d3b93ae1..22026c44683 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -231,7 +231,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -datadir=

" + _("Specify data directory") + "\n"; strUsage += " -dbcache= " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n"; strUsage += " -loadblock= " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n"; - strUsage += " -maxorphanblocks= " + strprintf(_("Keep at most unconnectable blocks in memory (default: %u)"), DEFAULT_MAX_ORPHAN_BLOCKS) + "\n"; strUsage += " -maxorphantx= " + strprintf(_("Keep at most unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n"; strUsage += " -par= " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n"; #ifndef WIN32 diff --git a/src/main.h b/src/main.h index 717cec769e2..662d5756f76 100644 --- a/src/main.h +++ b/src/main.h @@ -64,8 +64,6 @@ static const unsigned int MAX_P2SH_SIGOPS = 15; static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; -/** Default for -maxorphanblocks, maximum number of orphan blocks kept in memory */ -static const unsigned int DEFAULT_MAX_ORPHAN_BLOCKS = 750; /** The maximum size of a blk?????.dat file (since 0.8) */ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ From 34970223472c9e83689a1c710eebc7c16f152b02 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 11 Dec 2014 13:35:14 +0100 Subject: [PATCH 0074/2337] Reject headers that build on an invalid parent --- src/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index ad3f70eed90..762a404032d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -449,6 +449,10 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vectorIsValid(BLOCK_VALID_TREE)) { + // We consider the chain that this peer is on invalid. + return; + } if (pindex->nStatus & BLOCK_HAVE_DATA) { if (pindex->nChainTx) state->pindexLastCommonBlock = pindex; @@ -2563,6 +2567,8 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc if (mi == mapBlockIndex.end()) return state.DoS(10, error("%s : prev block not found", __func__), 0, "bad-prevblk"); pindexPrev = (*mi).second; + if (pindexPrev->nStatus & BLOCK_FAILED_MASK) + return state.DoS(100, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); } if (!ContextualCheckBlockHeader(block, state, pindexPrev)) From 2a3d988b802dcea4453241e37168d8511078940a Mon Sep 17 00:00:00 2001 From: "Eric R. Schulz" Date: Mon, 22 Dec 2014 21:04:53 -0500 Subject: [PATCH 0075/2337] bitcoin-tx: Fix JSON validation of prevtxs --- src/bitcoin-tx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 337cd44cd94..56ca600ed43 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -368,7 +368,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) // Add previous txouts given in the RPC call: if (!registers.count("prevtxs")) throw runtime_error("prevtxs register variable must be set."); - UniValue prevtxsObj = registers["privatekeys"]; + UniValue prevtxsObj = registers["prevtxs"]; { for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) { UniValue prevOut = prevtxsObj[previdx]; From a089c50981e822014ffc18e8a37b3518feb52206 Mon Sep 17 00:00:00 2001 From: "Eric R. Schulz" Date: Tue, 23 Dec 2014 02:59:00 +0000 Subject: [PATCH 0076/2337] bitcoin-tx: Refer to the JSON fields rather than the whole object --- src/bitcoin-tx.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 56ca600ed43..05a85810ec2 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -379,13 +379,13 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) if (!prevOut.checkObject(types)) throw runtime_error("prevtxs internal object typecheck fail"); - uint256 txid = ParseHashUV(prevOut, "txid"); + uint256 txid = ParseHashUV(prevOut["txid"], "txid"); int nOut = atoi(prevOut["vout"].getValStr()); if (nOut < 0) throw runtime_error("vout must be positive"); - vector pkData(ParseHexUV(prevOut, "scriptPubKey")); + vector pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey")); CScript scriptPubKey(pkData.begin(), pkData.end()); { From c90770430d7c1eb7ece2d4ddb987b0f2210fd86f Mon Sep 17 00:00:00 2001 From: Adam Weiss Date: Thu, 18 Dec 2014 18:28:29 -0500 Subject: [PATCH 0077/2337] DOS: Respect max per-peer blocks in flight limit Don't allow immediate inv driven block downloads if a peer already has MAX_BLOCKS_IN_TRANSIT_PER_PEER active downloads. Prevents bogus inv spam from blowing up block transfer tracking data structures. --- src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 9c038f90fa7..accdfd10b2e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3574,7 +3574,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // doing this will result in the received block being rejected as an orphan in case it is // not a direct successor. pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); - if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20) { + CNodeState *nodestate = State(pfrom->GetId()); + if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20 && + nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vToFetch.push_back(inv); // Mark block as in flight already, even though the actual "getdata" message only goes out // later (within the same cs_main lock, though). From 7c5dd603065ec8a568bedde4d7cf311a6dc9ff2e Mon Sep 17 00:00:00 2001 From: Everett Forth Date: Mon, 22 Dec 2014 23:41:14 -0800 Subject: [PATCH 0078/2337] Adding RPC tests for the following wallet related calls: getbalance, listsinceblock, listtransactions, listlockunspent, listaccounts listaddressgroupings --- src/test/rpc_wallet_tests.cpp | 37 ++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index a83bd120cab..57c49c2dfc5 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -93,6 +93,13 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */ BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error); + + /********************************* + * getbalance + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("getbalance")); + BOOST_CHECK_NO_THROW(CallRPC("getbalance " + demoAddress.ToString())); + /********************************* * listunspent *********************************/ @@ -124,6 +131,35 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true")); BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error); + /********************************* + * listsinceblock + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listsinceblock")); + + /********************************* + * listtransactions + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listtransactions")); + BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString())); + BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20")); + BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20 0")); + BOOST_CHECK_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " not_int"), runtime_error); + + /********************************* + * listlockunspent + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listlockunspent")); + + /********************************* + * listaccounts + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listaccounts")); + + /********************************* + * listaddressgroupings + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listaddressgroupings")); + /********************************* * getrawchangeaddress *********************************/ @@ -179,5 +215,4 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get()); } - BOOST_AUTO_TEST_SUITE_END() From a15dba5dff1229b67ff44bf16ff14063e885f376 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 23 Dec 2014 22:02:16 +0000 Subject: [PATCH 0079/2337] en: Avoid ambiguous language regarding when transactions confirm --- src/init.cpp | 2 +- src/rpcmining.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 13a7192a73d..430f02930bf 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -286,7 +286,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n"; strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n"; strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n"; - strUsage += " -txconfirmtarget= " + strprintf(_("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)"), 1) + "\n"; + strUsage += " -txconfirmtarget= " + strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1) + "\n"; strUsage += " -maxtxfee= " + strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee)) + "\n"; strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n"; strUsage += " -wallet= " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n"; diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 44ebff9d32d..17552bc388f 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -674,7 +674,7 @@ Value estimatefee(const Array& params, bool fHelp) throw runtime_error( "estimatefee nblocks\n" "\nEstimates the approximate fee per kilobyte\n" - "needed for a transaction to get confirmed\n" + "needed for a transaction to begin confirmation\n" "within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" @@ -706,7 +706,7 @@ Value estimatepriority(const Array& params, bool fHelp) throw runtime_error( "estimatepriority nblocks\n" "\nEstimates the approximate priority\n" - "a zero-fee transaction needs to get confirmed\n" + "a zero-fee transaction needs to begin confirmation\n" "within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" From 566c6cb8a2a277d9c5e4897ad02c5bb15786523c Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 23 Dec 2014 19:42:40 -0500 Subject: [PATCH 0080/2337] gitian: attempt to fix tarball determinisim --- contrib/gitian-descriptors/gitian-linux.yml | 4 ++-- contrib/gitian-descriptors/gitian-osx.yml | 6 +++--- contrib/gitian-descriptors/gitian-win.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index bba2104edb7..28bd9211acd 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -79,7 +79,7 @@ script: | mkdir -p temp pushd temp tar xf ../$SOURCEDIST - find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$SOURCEDIST + find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd ORIGPATH="$PATH" @@ -99,7 +99,7 @@ script: | find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find . | sort | tar --no-recursion -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz cd ../../ done mkdir -p $OUTDIR/src diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index eb6df2096eb..4f05aad2335 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -90,7 +90,7 @@ script: | mkdir -p temp pushd temp tar xf ../$SOURCEDIST - find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$SOURCEDIST + find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd ORIGPATH="$PATH" @@ -116,7 +116,7 @@ script: | cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff mv dist unsigned-app-${i} pushd unsigned-app-${i} - find . | sort | tar --no-recursion -czf ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz -T - + find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz popd make deploy @@ -126,7 +126,7 @@ script: | find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find . | sort | tar --no-recursion -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz cd ../../ done mkdir -p $OUTDIR/src diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 97c823cde69..4baa08c88da 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -83,7 +83,7 @@ script: | mkdir -p temp pushd temp tar xf ../$SOURCEDIST - find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$SOURCEDIST + find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd ORIGPATH="$PATH" From 2c14d1532fe66a243cdbfb7de48b298213305765 Mon Sep 17 00:00:00 2001 From: "Eric R. Schulz" Date: Wed, 24 Dec 2014 01:35:40 +0000 Subject: [PATCH 0081/2337] bitcoin-tx: Add test case for signing a tx --- src/Makefile.test.include | 3 ++- src/test/data/bitcoin-util-test.json | 10 ++++++++++ src/test/data/txcreatesign.hex | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/test/data/txcreatesign.hex diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 9e9f478d8fe..b9d15f4df39 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -14,7 +14,8 @@ EXTRA_DIST += \ test/data/tt-locktime317000-out.hex \ test/data/tx394b54bb.hex \ test/data/txcreate1.hex \ - test/data/txcreate2.hex + test/data/txcreate2.hex \ + test/data/txcreatesign.hex JSON_TEST_FILES = \ test/data/script_valid.json \ diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index f8424b72a34..6090421cb66 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -46,5 +46,15 @@ { "exec": "./bitcoin-tx", "args": ["-create", "outscript=0:"], "output_cmp": "txcreate2.hex" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", + "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", + "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]", + "sign=ALL", + "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], + "output_cmp": "txcreatesign.hex" } ] diff --git a/src/test/data/txcreatesign.hex b/src/test/data/txcreatesign.hex new file mode 100644 index 00000000000..56ce28a8655 --- /dev/null +++ b/src/test/data/txcreatesign.hex @@ -0,0 +1 @@ +01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d0000000000ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000 From d78f0dafd520f481f909cca7e361a4e482cbea72 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Thu, 25 Dec 2014 03:12:17 -0500 Subject: [PATCH 0082/2337] Fix CScriptID(const CScript& in) in empty script case Previously an empty script wouldn't be hashed, and CScriptID would be assigned the incorrect value of 0 instead. This bug can be seen in the RPC decodescript command: $ btc decodescript "" { "asm" : "", "type" : "nonstandard", "p2sh" : "31h1vYVSYuKP6AhS86fbRdMw9XHieotbST" } Correct output: $ btc decodescript "" { "asm" : "", "type" : "nonstandard", "p2sh" : "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy" } --- src/script/standard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/standard.cpp b/src/script/standard.cpp index d0e2250049c..ce50e3aad83 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -18,7 +18,7 @@ typedef vector valtype; unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY; -CScriptID::CScriptID(const CScript& in) : uint160(in.size() ? Hash160(in.begin(), in.end()) : 0) {} +CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {} const char* GetTxnOutputType(txnouttype t) { From d44c545673c0d75d1a2febe69685904787f8b21c Mon Sep 17 00:00:00 2001 From: azeteki Date: Sun, 21 Dec 2014 05:28:14 +0000 Subject: [PATCH 0083/2337] Add unconfirmedbalance field to getwalletinfo --- src/rpcwallet.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 63da8a20b57..7c371ae2e94 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1990,7 +1990,8 @@ Value getwalletinfo(const Array& params, bool fHelp) "\nResult:\n" "{\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n" + " \"balance\": xxxxxxx, (numeric) the total confirmed bitcoin balance of the wallet\n" + " \"unconfirmedbalance\": xxxx, (numeric) the total unconfirmed bitcoin balance of the wallet\n" " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" @@ -2004,6 +2005,7 @@ Value getwalletinfo(const Array& params, bool fHelp) Object obj; obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); + obj.push_back(Pair("unconfirmedbalance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); From 8024d67dae9da4a5259cddc0fa713146272f7aad Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 24 Dec 2014 21:10:59 -0800 Subject: [PATCH 0084/2337] Add immature balances to getwalletinfo. --- src/rpcwallet.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 7c371ae2e94..8366430f18f 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1991,7 +1991,8 @@ Value getwalletinfo(const Array& params, bool fHelp) "{\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" " \"balance\": xxxxxxx, (numeric) the total confirmed bitcoin balance of the wallet\n" - " \"unconfirmedbalance\": xxxx, (numeric) the total unconfirmed bitcoin balance of the wallet\n" + " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed bitcoin balance of the wallet\n" + " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet\n" " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" @@ -2005,7 +2006,8 @@ Value getwalletinfo(const Array& params, bool fHelp) Object obj; obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); - obj.push_back(Pair("unconfirmedbalance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); + obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); + obj.push_back(Pair("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance()))); obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); From 12d927a391b83041479f06e72051d37cc4e66655 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 25 Dec 2014 08:57:16 +0100 Subject: [PATCH 0085/2337] RPC test for immature balance --- qa/rpc-tests/wallet.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index d99540b58a6..f280ac380e7 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -41,6 +41,10 @@ class WalletTest (BitcoinTestFramework): self.nodes[0].setgenerate(True, 1) + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 50) + assert_equal(walletinfo['balance'], 0) + self.sync_all() self.nodes[1].setgenerate(True, 101) self.sync_all() @@ -54,6 +58,9 @@ class WalletTest (BitcoinTestFramework): self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 0) + # Have node0 mine a block, thus he will collect his own fee. self.nodes[0].setgenerate(True, 1) self.sync_all() From a094b3d9732aaca362e883655319852e4ce9a174 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sat, 27 Dec 2014 01:38:47 -0800 Subject: [PATCH 0086/2337] Remove bitnodes.io from dnsseeds. I'm not comfortable with retaining this entry. --- src/chainparams.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 7562509bd51..f4bc6e1d703 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -156,7 +156,6 @@ public: vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); - vSeeds.push_back(CDNSSeedData("bitnodes.io", "seed.bitnodes.io")); vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); base58Prefixes[PUBKEY_ADDRESS] = list_of(0); From 1f670846f709a486ee224bb2582474da47c9c6b2 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 27 Dec 2014 12:28:34 +0100 Subject: [PATCH 0087/2337] [Docs] clean up assets-attributen.md - Make sure it represents the current state --- doc/assets-attribution.md | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/doc/assets-attribution.md b/doc/assets-attribution.md index 6c5f91a834d..31fe4e5b7a5 100644 --- a/doc/assets-attribution.md +++ b/doc/assets-attribution.md @@ -1,14 +1,5 @@ The following is a list of assets used in the bitcoin source and their proper attribution. -[Wladimir van der Laan](https://github.com/laanwj) ------------------------ -#### Info -* License: MIT - -### Assets Used - src/qt/res/icons/watch*.png, src/qt/res/icons/tx_in.png, - src/qt/res/icons/tx_inout.png, - [Typicons/Stephen Hutchings](http://typicons.com) ----------------------- @@ -30,7 +21,7 @@ The following is a list of assets used in the bitcoin source and their proper at src/qt/res/icons/overview.png, src/qt/res/icons/quit.png, src/qt/res/icons/receive.png, src/qt/res/icons/remove.png, src/qt/res/icons/send.png, src/qt/res/icons/synced.png, - src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_input.png, + src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_output.png, Jonas Schnelli ----------------------- @@ -38,18 +29,19 @@ Jonas Schnelli ### Info * Designer: Jonas Schnelli * Bitcoin Icon: (based on the original bitcoin logo from Bitboy) -* Some icons are based on Stephan Hutchings Typicons +* Some icons are based on Stephan Hutchings Typicons (these are under CC BY-SA license) * License: MIT ### Assets Used src/qt/res/icons/about.png, src/qt/res/icons/about_qt.png, - src/qt/res/icons/clock*.png, src/qt/res/icons/connect[0-3].png, - src/qt/res/icons/eye_minus.png, src/qt/res/icons/verify.png, - src/qt/res/icons/eye_plus.png, src/qt/res/icons/tx_inout.png, - src/qt/res/icons/tx_output.png, src/qt/res/icons/bitcoin.icns, - src/qt/res/src/bitcoin.svg, src/qt/res/src/bitcoin.ico, - src/qt/res/src/bitcoin.png, src/qt/res/src/bitcoin_testnet.png, - docs/bitcoin_logo_doxygen.png, src/qt/res/src/tx*.svg, - src/qt/res/src/connect*.svg, src/qt/res/src/clock*.svg, - src/qt/res/src/mine.svg, src/qt/res/src/qt.svg, + src/qt/res/icons/bitcoin.icns, src/qt/res/icons/bitcoin.ico, + src/qt/res/icons/bitcoin.png, src/qt/res/icons/clock*.png, + src/qt/res/icons/connect[0-3].png, src/qt/res/icons/eye_minus.png, + src/qt/res/icons/eye_plus.png, src/qt/res/icons/verify.png, + src/qt/res/icons/tx_inout.png, src/qt/res/icons/tx_input.png, + src/qt/res/icons/unit_btc.png, src/qt/res/icons/unit_mbtc.png, + src/qt/res/icons/unit_ubtc.png, src/qt/res/src/verify.svg + src/qt/res/src/bitcoin.svg, src/qt/res/src/clock*.svg, + src/qt/res/src/connect*.svg, src/qt/res/src/mine.svg, + src/qt/res/src/qt.svg, src/qt/res/src/tx*.svg, src/qt/res/src/verify.svg, From de779b307b5b65ae6a632ee7a7110cc1da3fc410 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 27 Dec 2014 12:31:09 +0100 Subject: [PATCH 0088/2337] [Qt] new icon for the debug window --- src/qt/res/icons/debugwindow.png | Bin 1330 -> 15930 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/qt/res/icons/debugwindow.png b/src/qt/res/icons/debugwindow.png index 0a2ee5f1fb0ab4139c1635a45f69c240a4857690..576e57ab03521439359c8f539e4c274d42828f39 100644 GIT binary patch literal 15930 zcmeI3d0Z3M7RM(nvRFauilW9KEl`umLV&~&REQ6>0a-+NZVZzNjASDT5)n0sJ`oiw z0%B2XYu#$){ zTN2U}q*LgjYAr_Rv-nJu&E?Po1uPEVU%=svp>x?B9?W6GTmh5A5&8!TIRW&xiy?L; zERj|w7siB5Y)eP{7tBc2>or0c&dkhYW%5{RZ3@g02m~;j3v;F8= z1$h@I4AY@nT%*U;D!L^ulB~|q2QwI!MD17GeJM5ViB!5ab_7M(fM{S2iw$?@BtzSM zG#Ofjb!jpb#uS(mQ|WbtAE#SCO{!Y2)}^X@NZCH!V`8EvQfYhcZr7_+cAHwKm&_#) zv?1-*Qx`W+gTXPFPMx7eG09xwR=m2qdp$1iC{CwHmYE*cjv4SC+$=LTH)|`{DkLKA zRT!$p5WQL(r&cS(wl16U4k0}>lMMe~>N|?v5ef@K^q81vMt>%U%j5>e zakxUBzmVhq8Jin;Xg$m4=B0A<%0#O9G9dgKp90kuFJ87h>k zwMs-U#+67425VF)BDiA^P`0;}FjTEjYl&rHVx9=@ZW!>gwwW+OrPCuS6pIKG69X(9 zmkHT?G%$dV@R(cyhB5v57?+7)fdNcDCg92iJhnfdEw@6HNCs_LdW%03YTOop4jxsT7*$tRX1a}(kSXR4dn;ZWB7SI+SaPK)sW-6xo z(1x;wvZ{IxqEpNDnTQq}pF;Em=|;DO?CjGuwg|SI`wF~s6>OuOi}S8s-!G=fa-0c? zMj#f2SPQ@r!S9WAWVY!OECp3$SoQuvY|BOb@DW#=FF4=TH<82_obT$};W|}?>&4u* zbX|r4FUzTGI~8Jy2LwzUz~}S$BDm{tSC1*U0aGM|;l%dUS(=i=4Qg}hI@7IZVvnA{ zOq-{zT)>aHwVJk3;!%NkN`c!SQ#u#AeJA|IM#nAv#eu7Qk%j>iU<@?xIh}DHie56 z5h$Q=fiy^M3KuCNP(a}VX^`3!E>c9GfWigRAhju6q=-NPg$txXYE!sK5rF~<7f6HD zrf`uW0tFNT|p65c2%wtjT_+dkp(e)LQ$rTcjhs#eA_m}}coydJK zHQ4Zc&e9iSZf-GO-Bgrt%tzw7n{g(DdA0A=07*c^iG(jz*(2nG)~>s=fcJaLv5j|r zePi-$iMso^b>UYF)bhKsZ386zzNso2Xy-y7ZTte7VCUSO@mo=TP1)qFG1sO)?)BKI zz;3>AxG8?K!-MMmBVU#>Y152}=IQ1r^WS%cyf}1b_QNadjyV}<29MG!>%DpZb*y#} z(;{gXcdi~HS);>GI%w+ZzAKz9P@-S4w);97`tR`bnEBb%vfOg#rvaMShzD7RaNU|+ zP>uZx*M)5C>b=v`jfGJwuC~}cwy(Bp*(n_~AcR%}^%e_WDtE8Txlz6D)W6_|V{G~Ov zGP;M^z?L)mOVU$Im); zONp-YE%x-|j+lQGYRx}%a5wMd+wE_-Py5Pu97}A@iZLEZUVR+8tF0;-xQb?Wcsggr z&6nRo(YX^ZarbQ7piY{cJ5q8lc&qC3JASt=v!yq zJJsy+s*il+=Hi8Yp-Y=+Fj68~3wp!GN5wf`RMvPrWzya^2FoRM@V(=Z1)+{8uutCnUtkvDNpQI z3-6tOV=u~d8}7(5i%X7w)cOxqYejt>Z12AB^(WE1c%yyvfXjy#5! zc3_*=#x?|){O8x`mZALZfsm8g*ZL20H7TD$U{0yHnwXFs-0w zsrEK~heOMPUO7%i`_lF7@?7`8=7!Tp=G54Yjji3^t66>JKV=o?hU-O-?1)dNE8s?5Om!&+p@$lCQQyUsurX(k8mrwhY~y5%1Nv zir*BQyxFrN13n6Q=L^uFysTw(Q-(Q)=2#_bDxU>u@{*;W?5q>+8oZ~##XN&nxagnP z`FSHVwx>93#fBKFR^@D-Rdx4<(_&V#d;sQWd_K4-XTA8FnqfIToO17XzwqQDd+7Yi XeR+0EW_(JV4nJ zcwPcw#uctzKY)UgC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6F6@9E+g zQZeW4-2L6Mp(4la(-#XmT{$#kdTO$kqmIu;A%i6X*BTBz%1T#0)b=C)#tm1GnO<8q zZs@*f#u=gF7N#4rVPmJ~iC?Qv?CR>O&`JBl`0lc`b^5ctGe7@5P*VPG=bX=#<`aa+4<^ zt)DTU(cPMJLc4#X_}#yo^{n1MQM+*FTEprUKLll1*Il#ZRgYmXu9mdmf7AcY+VFSd z=h8f9&b=%%ZcaYnn)c|>TI|Gr+ys(TO1 zp0=+0?CdLwWSvd`?ek}l-y+|aaiFk#|FvzCS4cj%x}eU*QqeNsmU+fa#|LI-Q+6@$ zVXq0AKYONYf@Fo*j{OHK_cM3D`{z6RfnfRTY!mH&t_gSV=Cd7<<4r4*s1UY@tT@FK z`Yt|S*!+>u2cPC`^O;v`{oB8?c$3%E#X+;4)VV9MSX^50c4eGg0nZdG^W{==E~$LC z7E(Nrl(^fs{60sAdDbhLTro5KvwuUBSZ0W9`>ml6CgxQfI_vjJ7mkAR#NG1DNvR7> z!k6xx-xbH{-N)iVALQ4U;Ceo z6&LQ-XNuZpv|lJblh=NBe!4{UwBtK>-n6`OM(x1#jP(ch-C&a|`@a5mnaC!A5dJ4V zF7b;xj0KOj->7B&&NRJISW&hsGlns2k=ebDdzK|mrRu)}B9=dze}|#Zwf2|dk4OjG z4WX+VyCU)e-fkBOt9kJtF<|f6pN6YedL1cfeKlErUu%uJKXbNsctbcxMZ&}xxvON> zxzvC9uk>j5lmBZ3eO6rK+&1HH`SXP`(WU3qVy~-zQTwoeML17*!}A9Bm1TRPT(a43 zhwzu?1+RS@&!D$G?xFS)bH-T-Y5C0hZ$5qDZ(M%&uit|SZl`bD;|TgFZKTE+@+a0n z3`82S0ZB2QSO(Gks?K5#NBI+0Fs=CE$P>sQYCmBi=YmJ<#wtJ+d=gy@T6OL`jzD$J z&p@h^pG5*m_Gh6D*(-kRHJJXMx#QoA>yi#%T8K_W=j5MGUTYJfxJn;bzA<>Z`njxg HN@xNAxD_Nz From c444c620c62c51d65f7de0b2a3c351e61ab1e388 Mon Sep 17 00:00:00 2001 From: jtimon Date: Sun, 19 Oct 2014 02:57:02 +0200 Subject: [PATCH 0089/2337] Decouple CCoins from CTxInUndo --- src/coins.cpp | 22 ++++------------------ src/coins.h | 6 +----- src/main.cpp | 17 ++++++++++++++--- 3 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index bc430c9c7e6..f4599ff39df 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -31,29 +31,15 @@ void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) con nBytes += nLastUsedByte; } -bool CCoins::Spend(const COutPoint &out, CTxInUndo &undo) { - if (out.n >= vout.size()) +bool CCoins::Spend(uint32_t nPos) +{ + if (nPos >= vout.size() || vout[nPos].IsNull()) return false; - if (vout[out.n].IsNull()) - return false; - undo = CTxInUndo(vout[out.n]); - vout[out.n].SetNull(); + vout[nPos].SetNull(); Cleanup(); - if (vout.size() == 0) { - undo.nHeight = nHeight; - undo.fCoinBase = fCoinBase; - undo.nVersion = this->nVersion; - } return true; } -bool CCoins::Spend(int nPos) { - CTxInUndo undo; - COutPoint out(0, nPos); - return Spend(out, undo); -} - - bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } uint256 CCoinsView::GetBestBlock() const { return uint256(0); } diff --git a/src/coins.h b/src/coins.h index 9b73ae3a874..2be52ad171f 100644 --- a/src/coins.h +++ b/src/coins.h @@ -9,7 +9,6 @@ #include "compressor.h" #include "serialize.h" #include "uint256.h" -#include "undo.h" #include #include @@ -237,11 +236,8 @@ public: Cleanup(); } - //! mark an outpoint spent, and construct undo information - bool Spend(const COutPoint &out, CTxInUndo &undo); - //! mark a vout spent - bool Spend(int nPos); + bool Spend(uint32_t nPos); //! check whether a particular output is still available bool IsAvailable(unsigned int nPos) const { diff --git a/src/main.cpp b/src/main.cpp index 2410230ef43..3f775e3d333 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1383,9 +1383,20 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach if (!tx.IsCoinBase()) { txundo.vprevout.reserve(tx.vin.size()); BOOST_FOREACH(const CTxIn &txin, tx.vin) { - txundo.vprevout.push_back(CTxInUndo()); - bool ret = inputs.ModifyCoins(txin.prevout.hash)->Spend(txin.prevout, txundo.vprevout.back()); - assert(ret); + CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash); + unsigned nPos = txin.prevout.n; + + if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull()) + assert(false); + // mark an outpoint spent, and construct undo information + txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos])); + coins->Spend(nPos); + if (coins->vout.size() == 0) { + CTxInUndo& undo = txundo.vprevout.back(); + undo.nHeight = coins->nHeight; + undo.fCoinBase = coins->fCoinBase; + undo.nVersion = coins->nVersion; + } } } From d7621ccf9d064db19de742ed1a0ac59fffa06c0d Mon Sep 17 00:00:00 2001 From: jtimon Date: Mon, 27 Oct 2014 16:07:50 +0100 Subject: [PATCH 0090/2337] Decouple miner.o and txmempool.o from CTxUndo --- src/main.cpp | 6 ++++++ src/main.h | 2 +- src/miner.cpp | 3 +-- src/txmempool.cpp | 7 +++---- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 3f775e3d333..bcd3a5ff051 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1404,6 +1404,12 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); } +void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) +{ + CTxUndo txundo; + UpdateCoins(tx, state, inputs, txundo, nHeight); +} + bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore), &error)) { diff --git a/src/main.h b/src/main.h index 662d5756f76..e38b413be13 100644 --- a/src/main.h +++ b/src/main.h @@ -290,7 +290,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi unsigned int flags, bool cacheStore, std::vector *pvChecks = NULL); /** Apply the effects of this transaction on the UTXO set represented by view */ -void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight); +void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight); /** Context-independent validity checks */ bool CheckTransaction(const CTransaction& tx, CValidationState& state); diff --git a/src/miner.cpp b/src/miner.cpp index 2133b13e629..0ac974d6e13 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -279,8 +279,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) continue; - CTxUndo txundo; - UpdateCoins(tx, state, view, txundo, nHeight); + UpdateCoins(tx, state, view, nHeight); // Added pblock->vtx.push_back(tx); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 3071ab025c5..01bf1ec080a 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -585,9 +585,9 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const if (fDependsWait) waitingOnDependants.push_back(&it->second); else { - CValidationState state; CTxUndo undo; + CValidationState state; assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL)); - UpdateCoins(tx, state, mempoolDuplicate, undo, 1000000); + UpdateCoins(tx, state, mempoolDuplicate, 1000000); } } unsigned int stepsSinceLastRemove = 0; @@ -601,8 +601,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const assert(stepsSinceLastRemove < waitingOnDependants.size()); } else { assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL)); - CTxUndo undo; - UpdateCoins(entry->GetTx(), state, mempoolDuplicate, undo, 1000000); + UpdateCoins(entry->GetTx(), state, mempoolDuplicate, 1000000); stepsSinceLastRemove = 0; } } From e035c6a7371027fe33c460ee2d0946a7f1e4e592 Mon Sep 17 00:00:00 2001 From: jtimon Date: Mon, 27 Oct 2014 14:35:52 +0100 Subject: [PATCH 0091/2337] Decouple CBlockUndo from CDiskBlockPos --- src/main.cpp | 31 ++++++++++++++++--------------- src/main.h | 3 --- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bcd3a5ff051..ec24e55ce1c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1520,7 +1520,8 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi return true; } - +bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock); +bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock); bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean) { @@ -1535,7 +1536,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex CDiskBlockPos pos = pindex->GetUndoPos(); if (pos.IsNull()) return error("DisconnectBlock() : no undo data available"); - if (!blockUndo.ReadFromDisk(pos, pindex->pprev->GetBlockHash())) + if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash())) return error("DisconnectBlock() : failure reading undo data"); if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) @@ -1777,7 +1778,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin CDiskBlockPos pos; if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) return error("ConnectBlock() : FindUndoPos failed"); - if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash())) + if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash())) return state.Abort("Failed to write undo data"); // update nUndoPos in block index @@ -2943,7 +2944,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth CBlockUndo undo; CDiskBlockPos pos = pindex->GetUndoPos(); if (!pos.IsNull()) { - if (!undo.ReadFromDisk(pos, pindex->pprev->GetBlockHash())) + if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash())) return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); } } @@ -4509,44 +4510,44 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } -bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) +bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock) { // Open history file to append CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); if (fileout.IsNull()) - return error("CBlockUndo::WriteToDisk : OpenUndoFile failed"); + return error("%s : OpenUndoFile failed", __func__); // Write index header - unsigned int nSize = fileout.GetSerializeSize(*this); + unsigned int nSize = fileout.GetSerializeSize(blockundo); fileout << FLATDATA(Params().MessageStart()) << nSize; // Write undo data long fileOutPos = ftell(fileout.Get()); if (fileOutPos < 0) - return error("CBlockUndo::WriteToDisk : ftell failed"); + return error("%s : ftell failed", __func__); pos.nPos = (unsigned int)fileOutPos; - fileout << *this; + fileout << blockundo; // calculate & write checksum CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); hasher << hashBlock; - hasher << *this; + hasher << blockundo; fileout << hasher.GetHash(); return true; } -bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock) +bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock) { // Open history file to read CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); if (filein.IsNull()) - return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed"); + return error("%s : OpenBlockFile failed", __func__); // Read block uint256 hashChecksum; try { - filein >> *this; + filein >> blockundo; filein >> hashChecksum; } catch (const std::exception& e) { @@ -4556,9 +4557,9 @@ bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock // Verify checksum CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); hasher << hashBlock; - hasher << *this; + hasher << blockundo; if (hashChecksum != hasher.GetHash()) - return error("CBlockUndo::ReadFromDisk : Checksum mismatch"); + return error("%s : Checksum mismatch", __func__); return true; } diff --git a/src/main.h b/src/main.h index e38b413be13..7d6c293a3ff 100644 --- a/src/main.h +++ b/src/main.h @@ -314,9 +314,6 @@ public: inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(vtxundo); } - - bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock); - bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock); }; From 937ba572d0758891f43c658d7d98d7bd747c3ce4 Mon Sep 17 00:00:00 2001 From: jtimon Date: Mon, 27 Oct 2014 14:42:49 +0100 Subject: [PATCH 0092/2337] MOVEONLY: CBlockUndo from main.h to undo.h --- src/main.cpp | 1 + src/main.h | 16 ---------------- src/undo.h | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ec24e55ce1c..24ed487af0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,7 @@ #include "txdb.h" #include "txmempool.h" #include "ui_interface.h" +#include "undo.h" #include "util.h" #include "utilmoneystr.h" diff --git a/src/main.h b/src/main.h index 7d6c293a3ff..9049f5bb7d4 100644 --- a/src/main.h +++ b/src/main.h @@ -25,7 +25,6 @@ #include "tinyformat.h" #include "txmempool.h" #include "uint256.h" -#include "undo.h" #include #include @@ -302,21 +301,6 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason); bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64_t nBlockTime = 0); -/** Undo information for a CBlock */ -class CBlockUndo -{ -public: - std::vector vtxundo; // for all but the coinbase - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(vtxundo); - } -}; - - /** * Closure representing one script verification * Note that this stores references to the spending transaction diff --git a/src/undo.h b/src/undo.h index e6d8fd58627..1c4ed95bf2e 100644 --- a/src/undo.h +++ b/src/undo.h @@ -68,4 +68,18 @@ public: } }; +/** Undo information for a CBlock */ +class CBlockUndo +{ +public: + std::vector vtxundo; // for all but the coinbase + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(vtxundo); + } +}; + #endif // BITCOIN_UNDO_H From 87fb31086d70e4902170976ce261a01c8c380c00 Mon Sep 17 00:00:00 2001 From: jtimon Date: Wed, 3 Dec 2014 00:39:03 +0100 Subject: [PATCH 0093/2337] Move UndoWriteToDisk() and UndoReadFromDisk() to anon namespace --- src/main.cpp | 114 +++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 24ed487af0a..f6033566ef1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1521,8 +1521,63 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi return true; } -bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock); -bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock); +namespace { + +bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock) +{ + // Open history file to append + CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); + if (fileout.IsNull()) + return error("%s : OpenUndoFile failed", __func__); + + // Write index header + unsigned int nSize = fileout.GetSerializeSize(blockundo); + fileout << FLATDATA(Params().MessageStart()) << nSize; + + // Write undo data + long fileOutPos = ftell(fileout.Get()); + if (fileOutPos < 0) + return error("%s : ftell failed", __func__); + pos.nPos = (unsigned int)fileOutPos; + fileout << blockundo; + + // calculate & write checksum + CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); + hasher << hashBlock; + hasher << blockundo; + fileout << hasher.GetHash(); + + return true; +} + +bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock) +{ + // Open history file to read + CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) + return error("%s : OpenBlockFile failed", __func__); + + // Read block + uint256 hashChecksum; + try { + filein >> blockundo; + filein >> hashChecksum; + } + catch (const std::exception& e) { + return error("%s : Deserialize or I/O error - %s", __func__, e.what()); + } + + // Verify checksum + CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); + hasher << hashBlock; + hasher << blockundo; + if (hashChecksum != hasher.GetHash()) + return error("%s : Checksum mismatch", __func__); + + return true; +} + +} // anon namespace bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean) { @@ -4510,61 +4565,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle) return true; } - -bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock) -{ - // Open history file to append - CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); - if (fileout.IsNull()) - return error("%s : OpenUndoFile failed", __func__); - - // Write index header - unsigned int nSize = fileout.GetSerializeSize(blockundo); - fileout << FLATDATA(Params().MessageStart()) << nSize; - - // Write undo data - long fileOutPos = ftell(fileout.Get()); - if (fileOutPos < 0) - return error("%s : ftell failed", __func__); - pos.nPos = (unsigned int)fileOutPos; - fileout << blockundo; - - // calculate & write checksum - CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); - hasher << hashBlock; - hasher << blockundo; - fileout << hasher.GetHash(); - - return true; -} - -bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock) -{ - // Open history file to read - CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); - if (filein.IsNull()) - return error("%s : OpenBlockFile failed", __func__); - - // Read block - uint256 hashChecksum; - try { - filein >> blockundo; - filein >> hashChecksum; - } - catch (const std::exception& e) { - return error("%s : Deserialize or I/O error - %s", __func__, e.what()); - } - - // Verify checksum - CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); - hasher << hashBlock; - hasher << blockundo; - if (hashChecksum != hasher.GetHash()) - return error("%s : Checksum mismatch", __func__); - - return true; -} - std::string CBlockFileInfo::ToString() const { return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast)); } From 9b7d3fb16574f1604c0837f9ac0f402672add87f Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 6 Nov 2014 19:55:52 +0000 Subject: [PATCH 0094/2337] Adopt style colour for button icons --- src/Makefile.qt.include | 2 + src/qt/addressbookpage.cpp | 6 +++ src/qt/bitcoingui.cpp | 52 +++++++++--------- src/qt/coincontroldialog.cpp | 5 +- src/qt/intro.cpp | 3 +- src/qt/networkstyle.cpp | 1 + src/qt/overviewpage.cpp | 4 +- src/qt/receivecoinsdialog.cpp | 6 +++ src/qt/rpcconsole.cpp | 6 ++- src/qt/scicon.cpp | 84 ++++++++++++++++++++++++++++++ src/qt/scicon.h | 24 +++++++++ src/qt/sendcoinsdialog.cpp | 5 ++ src/qt/sendcoinsentry.cpp | 7 +++ src/qt/signverifymessagedialog.cpp | 10 ++++ src/qt/transactiontablemodel.cpp | 8 ++- src/qt/transactiontablemodel.h | 4 +- src/qt/transactionview.cpp | 5 +- src/qt/walletview.cpp | 3 +- 18 files changed, 198 insertions(+), 37 deletions(-) create mode 100644 src/qt/scicon.cpp create mode 100644 src/qt/scicon.h diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 25d76c146b9..8b782b2ad5d 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -191,6 +191,7 @@ BITCOIN_QT_H = \ qt/receiverequestdialog.h \ qt/recentrequeststablemodel.h \ qt/rpcconsole.h \ + qt/scicon.h \ qt/sendcoinsdialog.h \ qt/sendcoinsentry.h \ qt/signverifymessagedialog.h \ @@ -277,6 +278,7 @@ BITCOIN_QT_CPP = \ qt/qvalidatedlineedit.cpp \ qt/qvaluecombobox.cpp \ qt/rpcconsole.cpp \ + qt/scicon.cpp \ qt/splashscreen.cpp \ qt/trafficgraphwidget.cpp \ qt/utilitydialog.cpp \ diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index fd3c1f2c0d0..5485d89f3e1 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -14,6 +14,7 @@ #include "csvmodelwriter.h" #include "editaddressdialog.h" #include "guiutil.h" +#include "scicon.h" #include #include @@ -34,6 +35,11 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : ui->copyAddress->setIcon(QIcon()); ui->deleteAddress->setIcon(QIcon()); ui->exportButton->setIcon(QIcon()); +#else + ui->newAddress->setIcon(SingleColorIcon(":/icons/add")); + ui->copyAddress->setIcon(SingleColorIcon(":/icons/editcopy")); + ui->deleteAddress->setIcon(SingleColorIcon(":/icons/remove")); + ui->exportButton->setIcon(SingleColorIcon(":/icons/export")); #endif switch(mode) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 4eef1858552..3b8fd985a02 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -14,6 +14,7 @@ #include "optionsdialog.h" #include "optionsmodel.h" #include "rpcconsole.h" +#include "scicon.h" #include "utilitydialog.h" #ifdef ENABLE_WALLET @@ -36,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -242,28 +242,28 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle) { QActionGroup *tabGroup = new QActionGroup(this); - overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this); + overviewAction = new QAction(SingleColorIcon(":/icons/overview"), tr("&Overview"), this); overviewAction->setStatusTip(tr("Show general overview of wallet")); overviewAction->setToolTip(overviewAction->statusTip()); overviewAction->setCheckable(true); overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1)); tabGroup->addAction(overviewAction); - sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send"), this); + sendCoinsAction = new QAction(SingleColorIcon(":/icons/send"), tr("&Send"), this); sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address")); sendCoinsAction->setToolTip(sendCoinsAction->statusTip()); sendCoinsAction->setCheckable(true); sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); tabGroup->addAction(sendCoinsAction); - receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive"), this); + receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this); receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)")); receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip()); receiveCoinsAction->setCheckable(true); receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); tabGroup->addAction(receiveCoinsAction); - historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this); + historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this); historyAction->setStatusTip(tr("Browse transaction history")); historyAction->setToolTip(historyAction->statusTip()); historyAction->setCheckable(true); @@ -283,46 +283,46 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle) connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); #endif // ENABLE_WALLET - quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this); + quitAction = new QAction(TextColorIcon(":/icons/quit"), tr("E&xit"), this); quitAction->setStatusTip(tr("Quit application")); quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); quitAction->setMenuRole(QAction::QuitRole); - aboutAction = new QAction(QIcon(":/icons/about"), tr("&About Bitcoin Core"), this); + aboutAction = new QAction(TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this); aboutAction->setStatusTip(tr("Show information about Bitcoin Core")); aboutAction->setMenuRole(QAction::AboutRole); - aboutQtAction = new QAction(QIcon(":/icons/about_qt"), tr("About &Qt"), this); + aboutQtAction = new QAction(TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this); aboutQtAction->setStatusTip(tr("Show information about Qt")); aboutQtAction->setMenuRole(QAction::AboutQtRole); - optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); + optionsAction = new QAction(TextColorIcon(":/icons/options"), tr("&Options..."), this); optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core")); optionsAction->setMenuRole(QAction::PreferencesRole); - toggleHideAction = new QAction(QIcon(":/icons/about"), tr("&Show / Hide"), this); + toggleHideAction = new QAction(TextColorIcon(":/icons/about"), tr("&Show / Hide"), this); toggleHideAction->setStatusTip(tr("Show or hide the main Window")); - encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); + encryptWalletAction = new QAction(TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet")); encryptWalletAction->setCheckable(true); - backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); + backupWalletAction = new QAction(TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); backupWalletAction->setStatusTip(tr("Backup wallet to another location")); - changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this); + changePassphraseAction = new QAction(TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this); changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption")); - signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this); + signMessageAction = new QAction(TextColorIcon(":/icons/edit"), tr("Sign &message..."), this); signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them")); - verifyMessageAction = new QAction(QIcon(":/icons/verify"), tr("&Verify message..."), this); + verifyMessageAction = new QAction(TextColorIcon(":/icons/verify"), tr("&Verify message..."), this); verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses")); - openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this); + openRPCConsoleAction = new QAction(TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this); openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console")); - usedSendingAddressesAction = new QAction(QIcon(":/icons/address-book"), tr("&Sending addresses..."), this); + usedSendingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this); usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels")); - usedReceivingAddressesAction = new QAction(QIcon(":/icons/address-book"), tr("&Receiving addresses..."), this); + usedReceivingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this); usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels")); - openAction = new QAction(QIcon(":/icons/open"), tr("Open &URI..."), this); + openAction = new QAction(TextColorIcon(":/icons/open"), tr("Open &URI..."), this); openAction->setStatusTip(tr("Open a bitcoin: URI or payment request")); - showHelpMessageAction = new QAction(QIcon(":/icons/info"), tr("&Command-line options"), this); + showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this); showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options")); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); @@ -629,7 +629,7 @@ void BitcoinGUI::setNumConnections(int count) case 7: case 8: case 9: icon = ":/icons/connect_3"; break; default: icon = ":/icons/connect_4"; break; } - labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelConnectionsIcon->setPixmap(SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count)); } @@ -671,7 +671,7 @@ void BitcoinGUI::setNumBlocks(int count) if(secs < 90*60) { tooltip = tr("Up to date") + QString(".
") + tooltip; - labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + labelBlocksIcon->setPixmap(SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); #ifdef ENABLE_WALLET if(walletFrame) @@ -717,7 +717,7 @@ void BitcoinGUI::setNumBlocks(int count) tooltip = tr("Catching up...") + QString("
") + tooltip; if(count != prevBlocks) { - labelBlocksIcon->setPixmap(QIcon(QString( + labelBlocksIcon->setPixmap(SingleColorIcon(QString( ":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0'))) .pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES; @@ -911,7 +911,7 @@ void BitcoinGUI::setEncryptionStatus(int status) break; case WalletModel::Unlocked: labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently unlocked")); encryptWalletAction->setChecked(true); changePassphraseAction->setEnabled(true); @@ -919,7 +919,7 @@ void BitcoinGUI::setEncryptionStatus(int status) break; case WalletModel::Locked: labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently locked")); encryptWalletAction->setChecked(true); changePassphraseAction->setEnabled(true); @@ -1066,7 +1066,7 @@ void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *optionsModel) /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */ void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits) { - setPixmap(QIcon(":/icons/unit_" + BitcoinUnits::id(newUnits)).pixmap(31,STATUSBAR_ICONSIZE)); + setPixmap(SingleColorIcon(":/icons/unit_" + BitcoinUnits::id(newUnits)).pixmap(31,STATUSBAR_ICONSIZE)); } /** Shows context menu with Display Unit options by the mouse coordinates */ diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index e650e0ffa6f..60e7d62a7a7 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -10,6 +10,7 @@ #include "guiutil.h" #include "init.h" #include "optionsmodel.h" +#include "scicon.h" #include "walletmodel.h" #include "coincontrol.h" @@ -274,7 +275,7 @@ void CoinControlDialog::lockCoin() COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); model->lockCoin(outpt); contextMenuItem->setDisabled(true); - contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed")); + contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); updateLabelLocked(); } @@ -776,7 +777,7 @@ void CoinControlDialog::updateView() COutPoint outpt(txhash, out.i); coinControl->UnSelect(outpt); // just to be sure itemOutput->setDisabled(true); - itemOutput->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed")); + itemOutput->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); } // set checkbox diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index fb7ed155943..9f72602b4dc 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -6,6 +6,7 @@ #include "ui_intro.h" #include "guiutil.h" +#include "scicon.h" #include "util.h" @@ -167,7 +168,7 @@ void Intro::pickDataDirectory() /* If current default data directory does not exist, let the user choose one */ Intro intro; intro.setDataDirectory(dataDir); - intro.setWindowIcon(QIcon(":icons/bitcoin")); + intro.setWindowIcon(SingleColorIcon(":icons/bitcoin")); while(true) { diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 4541c75886b..e28f903b2ea 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -5,6 +5,7 @@ #include "networkstyle.h" #include "guiconstants.h" +#include "scicon.h" #include diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 01b4036f853..4fa15db9c6f 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -10,6 +10,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "transactionfilterproxy.h" #include "transactiontablemodel.h" #include "walletmodel.h" @@ -34,7 +35,7 @@ public: { painter->save(); - QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); + QIcon icon = qvariant_cast(index.data(TransactionTableModel::RawDecorationRole)); QRect mainRect = option.rect; QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE)); int xspace = DECORATION_SIZE + 8; @@ -42,6 +43,7 @@ public: int halfheight = (mainRect.height() - 2*ypad)/2; QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight); QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight); + icon = SingleColorIcon(icon, SingleColor()); icon.paint(painter, decorationRect); QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime(); diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index aa1440e2c63..28cbd3abed7 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -12,6 +12,7 @@ #include "optionsmodel.h" #include "receiverequestdialog.h" #include "recentrequeststablemodel.h" +#include "scicon.h" #include "walletmodel.h" #include @@ -33,6 +34,11 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) : ui->receiveButton->setIcon(QIcon()); ui->showRequestButton->setIcon(QIcon()); ui->removeRequestButton->setIcon(QIcon()); +#else + ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); + ui->receiveButton->setIcon(SingleColorIcon(":/icons/receiving_addresses")); + ui->showRequestButton->setIcon(SingleColorIcon(":/icons/edit")); + ui->removeRequestButton->setIcon(SingleColorIcon(":/icons/remove")); #endif // context menu actions diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 271315b8c54..a5e3ae2b354 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -8,6 +8,7 @@ #include "clientmodel.h" #include "guiutil.h" #include "peertablemodel.h" +#include "scicon.h" #include "main.h" #include "chainparams.h" @@ -210,8 +211,9 @@ RPCConsole::RPCConsole(QWidget *parent) : GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this); #ifndef Q_OS_MAC - ui->openDebugLogfileButton->setIcon(QIcon(":/icons/export")); + ui->openDebugLogfileButton->setIcon(SingleColorIcon(":/icons/export")); #endif + ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); // Install event filter for up and down arrow ui->lineEdit->installEventFilter(this); @@ -348,7 +350,7 @@ void RPCConsole::clear() ui->messagesWidget->document()->addResource( QTextDocument::ImageResource, QUrl(ICON_MAPPING[i].url), - QImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + SingleColorImage(ICON_MAPPING[i].source, SingleColor()).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } // Set default style sheet diff --git a/src/qt/scicon.cpp b/src/qt/scicon.cpp new file mode 100644 index 00000000000..a0ffcd82a92 --- /dev/null +++ b/src/qt/scicon.cpp @@ -0,0 +1,84 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "scicon.h" + +#include +#include +#include +#include +#include +#include + +static void MakeSingleColorImage(QImage& img, const QColor& colorbase) +{ + img = img.convertToFormat(QImage::Format_ARGB32); + for (int x = img.width(); x--; ) + { + for (int y = img.height(); y--; ) + { + const QRgb rgb = img.pixel(x, y); + img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb))); + } + } +} + +QImage SingleColorImage(const QString& filename, const QColor& colorbase) +{ + QImage img(filename); + MakeSingleColorImage(img, colorbase); + return img; +} + +QIcon SingleColorIcon(const QIcon& ico, const QColor& colorbase) +{ + QIcon new_ico; + QSize sz; + Q_FOREACH(sz, ico.availableSizes()) + { + QImage img(ico.pixmap(sz).toImage()); + MakeSingleColorImage(img, colorbase); + new_ico.addPixmap(QPixmap::fromImage(img)); + } + return new_ico; +} + +QIcon SingleColorIcon(const QString& filename, const QColor& colorbase) +{ + return QIcon(QPixmap::fromImage(SingleColorImage(filename, colorbase))); +} + +QColor SingleColor() +{ + const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight)); + const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText)); + const QColor colorText(QApplication::palette().color(QPalette::WindowText)); + const int colorTextLightness = colorText.lightness(); + QColor colorbase; + if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness)) + colorbase = colorHighlightBg; + else + colorbase = colorHighlightFg; + return colorbase; +} + +QIcon SingleColorIcon(const QString& filename) +{ + return SingleColorIcon(filename, SingleColor()); +} + +static QColor TextColor() +{ + return QColor(QApplication::palette().color(QPalette::WindowText)); +} + +QIcon TextColorIcon(const QString& filename) +{ + return SingleColorIcon(filename, TextColor()); +} + +QIcon TextColorIcon(const QIcon& ico) +{ + return SingleColorIcon(ico, TextColor()); +} diff --git a/src/qt/scicon.h b/src/qt/scicon.h new file mode 100644 index 00000000000..1388069ddb4 --- /dev/null +++ b/src/qt/scicon.h @@ -0,0 +1,24 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_SCICON_H +#define BITCOIN_QT_SCICON_H + +#include + +QT_BEGIN_NAMESPACE +class QColor; +class QIcon; +class QString; +QT_END_NAMESPACE + +QImage SingleColorImage(const QString& filename, const QColor&); +QIcon SingleColorIcon(const QIcon&, const QColor&); +QIcon SingleColorIcon(const QString& filename, const QColor&); +QColor SingleColor(); +QIcon SingleColorIcon(const QString& filename); +QIcon TextColorIcon(const QIcon&); +QIcon TextColorIcon(const QString& filename); + +#endif // BITCOIN_QT_SCICON_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index cde77a5d44e..ffee56131de 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -11,6 +11,7 @@ #include "coincontroldialog.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "sendcoinsentry.h" #include "walletmodel.h" @@ -38,6 +39,10 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) : ui->addButton->setIcon(QIcon()); ui->clearButton->setIcon(QIcon()); ui->sendButton->setIcon(QIcon()); +#else + ui->addButton->setIcon(SingleColorIcon(":/icons/add")); + ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); + ui->sendButton->setIcon(SingleColorIcon(":/icons/send")); #endif GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index ad9189d20a7..6db6eee75be 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -9,6 +9,7 @@ #include "addresstablemodel.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "walletmodel.h" #include @@ -21,6 +22,12 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) : { ui->setupUi(this); + ui->addressBookButton->setIcon(SingleColorIcon(":/icons/address-book")); + ui->pasteButton->setIcon(SingleColorIcon(":/icons/editpaste")); + ui->deleteButton->setIcon(SingleColorIcon(":/icons/remove")); + ui->deleteButton_is->setIcon(SingleColorIcon(":/icons/remove")); + ui->deleteButton_s->setIcon(SingleColorIcon(":/icons/remove")); + setCurrentWidget(ui->SendCoins); #ifdef Q_OS_MAC diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index e16e245b634..970f6a520d8 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -7,6 +7,7 @@ #include "addressbookpage.h" #include "guiutil.h" +#include "scicon.h" #include "walletmodel.h" #include "base58.h" @@ -25,6 +26,15 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : { ui->setupUi(this); + ui->addressBookButton_SM->setIcon(SingleColorIcon(":/icons/address-book")); + ui->pasteButton_SM->setIcon(SingleColorIcon(":/icons/editpaste")); + ui->copySignatureButton_SM->setIcon(SingleColorIcon(":/icons/editcopy")); + ui->signMessageButton_SM->setIcon(SingleColorIcon(":/icons/edit")); + ui->clearButton_SM->setIcon(SingleColorIcon(":/icons/remove")); + ui->addressBookButton_VM->setIcon(SingleColorIcon(":/icons/address-book")); + ui->verifyMessageButton_VM->setIcon(SingleColorIcon(":/icons/transaction_0")); + ui->clearButton_VM->setIcon(SingleColorIcon(":/icons/remove")); + #if QT_VERSION >= 0x040700 ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature")); #endif diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 1dea5cdad9f..6771e771800 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -8,6 +8,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "transactiondesc.h" #include "transactionrecord.h" #include "walletmodel.h" @@ -504,7 +505,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const switch(role) { - case Qt::DecorationRole: + case RawDecorationRole: switch(index.column()) { case Status: @@ -515,6 +516,11 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const return txAddressDecoration(rec); } break; + case Qt::DecorationRole: + { + QIcon icon = qvariant_cast(index.data(RawDecorationRole)); + return TextColorIcon(icon); + } case Qt::DisplayRole: switch(index.column()) { diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 5eaccad0648..30a15df9e6e 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -64,7 +64,9 @@ public: /** Formatted amount, without brackets when unconfirmed */ FormattedAmountRole, /** Transaction status (TransactionRecord::Status) */ - StatusRole + StatusRole, + /** Unprocessed icon */ + RawDecorationRole, }; int rowCount(const QModelIndex &parent) const; diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 00fd209c9ff..526940632e0 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -10,6 +10,7 @@ #include "editaddressdialog.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "transactiondescdialog.h" #include "transactionfilterproxy.h" #include "transactionrecord.h" @@ -54,8 +55,8 @@ TransactionView::TransactionView(QWidget *parent) : watchOnlyWidget = new QComboBox(this); watchOnlyWidget->setFixedWidth(24); watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All); - watchOnlyWidget->addItem(QIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes); - watchOnlyWidget->addItem(QIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No); + watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes); + watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No); hlayout->addWidget(watchOnlyWidget); dateWidget = new QComboBox(this); diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 28b9c3b5694..9d6a0601949 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -12,6 +12,7 @@ #include "optionsmodel.h" #include "overviewpage.h" #include "receivecoinsdialog.h" +#include "scicon.h" #include "sendcoinsdialog.h" #include "signverifymessagedialog.h" #include "transactiontablemodel.h" @@ -44,7 +45,7 @@ WalletView::WalletView(QWidget *parent): QPushButton *exportButton = new QPushButton(tr("&Export"), this); exportButton->setToolTip(tr("Export the data in the current tab to a file")); #ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac - exportButton->setIcon(QIcon(":/icons/export")); + exportButton->setIcon(SingleColorIcon(":/icons/export")); #endif hbox_buttons->addStretch(); hbox_buttons->addWidget(exportButton); From 244fdc7beef2e9091e1a7dc764379005960cf87b Mon Sep 17 00:00:00 2001 From: Julian Yap Date: Sun, 28 Dec 2014 00:22:44 -1000 Subject: [PATCH 0095/2337] Fix typo --- doc/gitian-building.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index defddedc6e2..1312979cac7 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -83,7 +83,7 @@ Unixy OSes by entering the following in a terminal: After creating the VM, we need to configure it. -- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attacked to `NAT`. +- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attached to `NAT`. ![](gitian-building/network_settings.png) From 99913f0f70039d82f6cadbe4da4f831062800d1a Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Sun, 28 Dec 2014 22:57:39 +0100 Subject: [PATCH 0096/2337] Fix reference. The text talked about "Quit" while Bitcoin uses "Exit" in its menu. --- src/qt/forms/optionsdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 19421dc813d..55c4f5ac584 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -330,7 +330,7 @@ - Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu. M&inimize on close From dd3f69736a6e25044b8802057ba9982592575cdb Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 27 Dec 2014 19:19:51 +0000 Subject: [PATCH 0097/2337] Use real text rather than image-rendered text for unit selector The width of each unit is measured to set a fixed width for the widget, and the color is set to match the other status widgets. --- src/Makefile.qt.include | 3 --- src/qt/bitcoin.qrc | 3 --- src/qt/bitcoingui.cpp | 12 +++++++++++- src/qt/res/icons/unit_btc.png | Bin 1318 -> 0 bytes src/qt/res/icons/unit_mbtc.png | Bin 1407 -> 0 bytes src/qt/res/icons/unit_ubtc.png | Bin 1369 -> 0 bytes 6 files changed, 11 insertions(+), 7 deletions(-) delete mode 100644 src/qt/res/icons/unit_btc.png delete mode 100644 src/qt/res/icons/unit_mbtc.png delete mode 100644 src/qt/res/icons/unit_ubtc.png diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 8b782b2ad5d..806b4f95562 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -256,9 +256,6 @@ RES_ICONS = \ qt/res/icons/tx_input.png \ qt/res/icons/tx_output.png \ qt/res/icons/tx_mined.png \ - qt/res/icons/unit_btc.png \ - qt/res/icons/unit_mbtc.png \ - qt/res/icons/unit_ubtc.png \ qt/res/icons/verify.png BITCOIN_QT_CPP = \ diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index b54f2e2ed66..bcaf95d91ce 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -35,9 +35,6 @@ res/icons/tx_input.png res/icons/tx_output.png res/icons/tx_inout.png - res/icons/unit_btc.png - res/icons/unit_mbtc.png - res/icons/unit_ubtc.png res/icons/lock_closed.png res/icons/lock_open.png res/icons/key.png diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 3b8fd985a02..2810eae0528 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1027,6 +1027,16 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() : { createContextMenu(); setToolTip(tr("Unit to show amounts in. Click to select another unit.")); + QList units = BitcoinUnits::availableUnits(); + int max_width = 0; + const QFontMetrics fm(font()); + foreach (const BitcoinUnits::Unit unit, units) + { + max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit))); + } + setMinimumSize(max_width, 0); + setAlignment(Qt::AlignRight | Qt::AlignVCenter); + setStyleSheet(QString("QLabel { color : %1 }").arg(SingleColor().name())); } /** So that it responds to button clicks */ @@ -1066,7 +1076,7 @@ void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *optionsModel) /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */ void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits) { - setPixmap(SingleColorIcon(":/icons/unit_" + BitcoinUnits::id(newUnits)).pixmap(31,STATUSBAR_ICONSIZE)); + setText(BitcoinUnits::name(newUnits)); } /** Shows context menu with Display Unit options by the mouse coordinates */ diff --git a/src/qt/res/icons/unit_btc.png b/src/qt/res/icons/unit_btc.png deleted file mode 100644 index f3246fa99948a136c79e1bc14abceb71d1571f83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1318 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!3HE3&8=$zQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?_naLn2Bde0{8v^K*7iAWdWaj57fJ{tG z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09svx0_iVsd64 zh_4CO;OlGUnO9trn3tUD>0+w{G(s;kGsVi#!p+Ij$=t%!#o55n(AC7!(Z$T!+{N73 zz|`E)+{hKC*Cju>G&eP`1g19yq1O_pUQk-dEdbi=l3J8mmYU*Ll%J~r_On$cZnv1> zG!Lpb1-Dzwaq86vIz}H9vq&)w69Oh55EGtmfgE_sPt5}+_ab1r7EhHGWME*N>FMGa zQgQ1|WOr_}fk5wSodG1EhtA!xQUACW zYw49AS*p-bQsSV+#CR)Ayu&-iuLye!`B4sPcSC(RWr zE8#KuBc;Hw{v=0(?Bs^FbGiNzNIHsnbo%M-(*I$0~^|u6W-0~acDTiCVe6F zn)T`(Z0o((IjvYWPw3DS`H$I zft$ET&NU4myQ@6=@4Gz>acA)U#=*G9HD}F^)fNxu$`~`Qla2Yu^568BeWxL#&w*)A b)ebORtD3;ww(5Q(sO0i=^>bP0l+XkK7K6)N diff --git a/src/qt/res/icons/unit_mbtc.png b/src/qt/res/icons/unit_mbtc.png deleted file mode 100644 index 4e82b652748baca3f2ee28c27e41a074217f46a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1407 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!3HE3&8=$zQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?_naLn2Bde0{8v^K*7iAWdWaj57fJ{tG z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09svx0_iVsd64 zh_4CO;OlGUnO9trn3tUD>0+w{G(s;kGsVi#!p+Ij$=t-$#o55n(AC7!(Z$T!+{N73 zz|`E)+{hKC*Cju>G&eP`1g19yq1P0rUQk-dEdbi=l3J8mmYU*Ll%J~r_On$c7PmMW zI+~c7x&h5|a>MQxh~5+|Zh`7G!>Lyv=oo!a%p%1!ObD2KKumbL1#;jiKQ#}S+>3ze zx=HHKMFs}OPo6H0Ar-gYL^k#|8}PJT*FVtj;GV!*$703Q17d0@AK)-JWb9PWBGGtj zQuCjm6Ks4#v;@7yydJUqeiP#)eeSc2Oys?$=5F=_%nukpFjO$uFvv0RA1Gv9f5>c? zlCs{~i}@E~W?hzew!$RnNASg8pMGmC{cp{vu%(2R!Go#F_{QUkKRyhLrWOjmS+S9m zW5LWf;o1_-N$-#3OrO+mxw`AN{(~|mg#^A-J_dp8QnvWkyPIUigm?~bV43TveL-T& zVzaEnZ?vx2d!_Dit&1s;_%R{qr~iWV=1Sl5tY6Ao1*ZkO`zuN|Hc0wL*1IfeF1q=m z+UfjBA?A&K+>TH=ib!uk*PY$|TzRCG37{6PPPe{#~slIFvLQ%#ueOuprj6&jdR zKV{C0uy5x=U-jRdvv#>d`h$-8LWbv)+%0@U8Jm|)VOwb%nYOO-=RN(oy>a^YJZB_XUMbC0xC+yV^W36aBz4U>1*{drIQLA@z?3{AZ;GXgG z+#hE*IlgAz3pcI!u7WiTv+dt=|BX-nr*6pK f!2aMwk$3`w$re4Ih=sRpK}DjctDnm{r-UW|wJ`QB diff --git a/src/qt/res/icons/unit_ubtc.png b/src/qt/res/icons/unit_ubtc.png deleted file mode 100644 index 96b254770dc0232a39d5e110c6924c9d44b4d284..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1369 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!3HE3&8=$zQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?_naLn2Bde0{8v^K*7iAWdWaj57fJ{tG z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09svx0_iVsd64 zh_4CO;OlGUnO9trn3tUD>0+w{G(s;kGsVi$(9y)q)Xmt`#mUXk(AC7!(Z$T!+{N73 zz|`E)+{hKC*Cju>G&eP`1g19yq1ObbUQk-dEdbi=l3J8mmYU*Ll%J~r_On$cZnqfX zG!Lpb1-Dy_aO%|uIz}H9vq&)w69Oh55EGtmfgE_sPt5}+_ab1rUch{PAp-;B8BZ6- zkcwMxW;Euu81OJWyvlk>@Rr~Ujx`SM3zRo7X&>OYFPPAh-tu4Y5XY5?bHcM)RVDIjS`~QR(W=l?={j|-JlWA7LzZ{lsU(M{U%j-J&mkNn~ zkAG0cG(m$;l##(BdhXG1%lAL6V#<8%`xPQ>e2aPh3x2t5wD;(J^)KCrnPf_s&YC1& z6E^DDVqRr5p={qn7kBSN`Hn}=et*Z4z?{h8vuC^Qs{SW-f?qd%Oxu~brko=(e8FnQ zH#3<(O0xA|`h`c>%Knh{f_XCB z3=0~1Z@v+EGSiiz=& Date: Sat, 27 Dec 2014 13:18:36 +0100 Subject: [PATCH 0098/2337] [REST] add /rest/chaininfos --- qa/rpc-tests/rest.py | 9 ++++++++- src/rest.cpp | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index 704d889739f..a9d41cf3672 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -78,7 +78,7 @@ class RESTTest (BitcoinTestFramework): # check hex format response hex_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"hex", True) - assert_equal(response.status, 200) + assert_equal(hex_string.status, 200) assert_greater_than(int(response.getheader('content-length')), 10) # check block tx details @@ -106,5 +106,12 @@ class RESTTest (BitcoinTestFramework): for tx in txs: assert_equal(tx in json_obj['tx'], True) + #test rest bestblock + bb_hash = self.nodes[0].getbestblockhash() + + json_string = http_get_call(url.hostname, url.port, '/rest/chaininfo.json') + json_obj = json.loads(json_string) + assert_equal(json_obj['bestblockhash'], bb_hash) + if __name__ == '__main__': RESTTest ().main () diff --git a/src/rest.cpp b/src/rest.cpp index 4702f0d7070..c9535c3b454 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -95,7 +95,7 @@ static bool rest_headers(AcceptedConnection* conn, bool fRun) { vector params; - enum RetFormat rf = ParseDataFormat(params, strReq); + const RetFormat rf = ParseDataFormat(params, strReq); vector path; boost::split(path, params[0], boost::is_any_of("/")); @@ -159,7 +159,7 @@ static bool rest_block(AcceptedConnection* conn, bool showTxDetails) { vector params; - enum RetFormat rf = ParseDataFormat(params, strReq); + const RetFormat rf = ParseDataFormat(params, strReq); string hashStr = params[0]; uint256 hash; @@ -226,13 +226,39 @@ static bool rest_block_notxdetails(AcceptedConnection* conn, return rest_block(conn, strReq, mapHeaders, fRun, false); } +static bool rest_chaininfo(AcceptedConnection* conn, + const std::string& strReq, + const std::map& mapHeaders, + bool fRun) +{ + vector params; + const RetFormat rf = ParseDataFormat(params, strReq); + + switch (rf) { + case RF_JSON: { + Array rpcParams; + Value chainInfoObject = getblockchaininfo(rpcParams, false); + + string strJSON = write_string(chainInfoObject, false) + "\n"; + conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + return true; + } + default: { + throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + static bool rest_tx(AcceptedConnection* conn, const std::string& strReq, const std::map& mapHeaders, bool fRun) { vector params; - enum RetFormat rf = ParseDataFormat(params, strReq); + const RetFormat rf = ParseDataFormat(params, strReq); string hashStr = params[0]; uint256 hash; @@ -287,6 +313,7 @@ static const struct { {"/rest/tx/", rest_tx}, {"/rest/block/notxdetails/", rest_block_notxdetails}, {"/rest/block/", rest_block_extended}, + {"/rest/chaininfo", rest_chaininfo}, {"/rest/headers/", rest_headers}, }; From 2c0f901ea90e3efab5e15abeba011597cfdd92c1 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 29 Dec 2014 20:26:47 +0100 Subject: [PATCH 0099/2337] [REST] rest/chaininfos add documentation --- doc/REST-interface.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/REST-interface.md b/doc/REST-interface.md index 0af650b4e8e..23154ee903e 100644 --- a/doc/REST-interface.md +++ b/doc/REST-interface.md @@ -10,6 +10,8 @@ Supported API Given a transaction hash, Returns a transaction, in binary, hex-encoded binary or JSON formats. +For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option. + `GET /rest/block/BLOCK-HASH.{bin|hex|json}` `GET /rest/block/notxdetails/BLOCK-HASH.{bin|hex|json}` @@ -20,7 +22,17 @@ The HTTP request and response are both handled entirely in-memory, thus making m With the /notxdetails/ option JSON response will only contain the transaction hash instead of the complete transaction details. The option only affects the JSON response. -For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option. +`GET /rest/chaininfo.json` + +Returns various state info regarding block chain processing. +Only supports JSON as output format. +* chain : (string) current network name as defined in BIP70 (main, test, regtest) +* blocks : (numeric) the current number of blocks processed in the server +* headers : (numeric) the current number of headers we have validated +* bestblockhash : (string) the hash of the currently best block +* difficulty : (numeric) the current difficulty +* verificationprogress : (numeric) estimate of verification progress [0..1] +* chainwork : (string) total amount of work in active chain, in hexadecimal Risks ------------- From 8db17607510eb250f3faf7963affa337eb7039d5 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 29 Dec 2014 15:19:19 -0500 Subject: [PATCH 0100/2337] rpcserver: attempt to fix uncaught exception. --- src/rpcserver.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index c5d74afba94..210c7fe9733 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -650,14 +650,16 @@ void StartRPCThreads() bool fListening = false; std::string strerr; + std::string straddress; BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints) { - asio::ip::address bindAddress = endpoint.address(); - LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", bindAddress.to_string(), endpoint.port(), bBindAny); - boost::system::error_code v6_only_error; - boost::shared_ptr acceptor(new ip::tcp::acceptor(*rpc_io_service)); - try { + asio::ip::address bindAddress = endpoint.address(); + straddress = bindAddress.to_string(); + LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny); + boost::system::error_code v6_only_error; + boost::shared_ptr acceptor(new ip::tcp::acceptor(*rpc_io_service)); + acceptor->open(endpoint.protocol()); acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); @@ -678,8 +680,8 @@ void StartRPCThreads() } catch (const boost::system::system_error& e) { - LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", bindAddress.to_string(), endpoint.port(), e.what()); - strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), bindAddress.to_string(), endpoint.port(), e.what()); + LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what()); + strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what()); } } From 78a7cd38f46717aafcf0456752788e6d788aa2a9 Mon Sep 17 00:00:00 2001 From: Ben Holden-Crowther Date: Mon, 29 Dec 2014 20:50:57 +0000 Subject: [PATCH 0101/2337] Updated license date Changed 2014 to 2015 in preparation for new year --- COPYING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYING b/COPYING index 6219bd75a64..9fd32666224 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2009-2014 Bitcoin Developers +Copyright (c) 2009-2015 Bitcoin Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 1c52aad540ec1370db60fd68fc3485413e3cb8e1 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 23 Dec 2014 23:50:21 +0100 Subject: [PATCH 0102/2337] Require sufficent priority for relay of free transactions --- qa/pull-tester/run-bitcoind-for-test.sh.in | 2 +- src/init.cpp | 1 + src/main.cpp | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/qa/pull-tester/run-bitcoind-for-test.sh.in b/qa/pull-tester/run-bitcoind-for-test.sh.in index 42d8ad52e88..14ae08e4e58 100755 --- a/qa/pull-tester/run-bitcoind-for-test.sh.in +++ b/qa/pull-tester/run-bitcoind-for-test.sh.in @@ -10,7 +10,7 @@ touch "$DATADIR/regtest/debug.log" tail -q -n 1 -F "$DATADIR/regtest/debug.log" | grep -m 1 -q "Done loading" & WAITER=$! PORT=`expr 10000 + $$ % 55536` -"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` & +"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -relaypriority=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` & BITCOIND=$! #Install a watchdog. diff --git a/src/init.cpp b/src/init.cpp index a09caeea401..006f0a2a3ac 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -324,6 +324,7 @@ std::string HelpMessage(HelpMessageMode mode) if (GetBoolArg("-help-debug", false)) { strUsage += " -limitfreerelay= " + strprintf(_("Continuously rate-limit free transactions to *1000 bytes per minute (default:%u)"), 15) + "\n"; + strUsage += " -relaypriority " + strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1) + "\n"; strUsage += " -maxsigcachesize= " + strprintf(_("Limit size of signature cache to entries (default: %u)"), 50000) + "\n"; } strUsage += " -minrelaytxfee= " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n"; diff --git a/src/main.cpp b/src/main.cpp index 2410230ef43..011189544cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1029,6 +1029,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa hash.ToString(), nFees, txMinFee), REJECT_INSUFFICIENTFEE, "insufficient fee"); + // Require that free transactions have sufficient priority to be mined in the next block. + if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) { + return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority"); + } + // Continuously rate-limit free (really, very-low-fee) transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. @@ -1048,7 +1053,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // At default rate it would take over a month to fill 1GB if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000) return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"), - REJECT_INSUFFICIENTFEE, "insufficient priority"); + REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); dFreeCount += nSize; } From de236f57c68c2c29d148a2df9e019f431cee3cb7 Mon Sep 17 00:00:00 2001 From: Pavel Vasin Date: Mon, 29 Dec 2014 18:48:19 +0300 Subject: [PATCH 0103/2337] clarify obscure uses of EvalScript() The 3rd argument of EvalScript() is the unsigned int flags, not a bool. --- src/main.cpp | 2 +- src/test/script_tests.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2410230ef43..3b9a0d4cf0b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -762,7 +762,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) // IsStandard() will have already returned false // and this method isn't called. vector > stack; - if (!EvalScript(stack, tx.vin[i].scriptSig, false, BaseSignatureChecker())) + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) return false; if (whichType == TX_SCRIPTHASH) diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 4d2a9aff45c..458b033131f 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -607,21 +607,21 @@ BOOST_AUTO_TEST_CASE(script_PushData) ScriptError err; vector > directStack; - BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), true, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector > pushdata1Stack; - BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), true, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK(pushdata1Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector > pushdata2Stack; - BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), true, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK(pushdata2Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector > pushdata4Stack; - BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), true, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK(pushdata4Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } From 0d50c2fd81ee7239570954e6eacb3dbbfe3bb5fe Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 30 Dec 2014 02:36:58 -0500 Subject: [PATCH 0104/2337] dmg: fix deterministic dmg creation and docs --- contrib/gitian-descriptors/gitian-osx-signer.yml | 6 +++--- doc/release-process.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index db9b4af93d0..1792f9de3f5 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -10,7 +10,7 @@ packages: reference_datetime: "2013-06-01 00:00:00" remotes: [] files: -- "bitcoin-0.9.99-osx-unsigned.tar.gz" +- "bitcoin-osx-unsigned.tar.gz" - "signature.tar.gz" script: | WRAP_DIR=$HOME/wrapped @@ -28,8 +28,8 @@ script: | chmod +x ${WRAP_DIR}/${prog} done - UNSIGNED=`echo bitcoin-*.tar.gz` - SIGNED=`echo ${UNSIGNED} | sed 's/.tar.*//' | sed 's/-unsigned//'`.dmg + UNSIGNED=bitcoin-osx-unsigned.tar.gz + SIGNED=bitcoin-osx-signed.dmg tar -xf ${UNSIGNED} ./detached-sig-apply.sh ${UNSIGNED} signature.tar.gz diff --git a/doc/release-process.md b/doc/release-process.md index 30f9797752d..eb2eb619bd7 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -68,7 +68,7 @@ Release Process mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml - mv build/out/bitcoin-*-unsigned.tar.gz inputs + mv build/out/bitcoin-*-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ popd Build output expected: @@ -102,7 +102,7 @@ Commit your signature to gitian.sigs: cp signature.tar.gz inputs/ ./bin/gbuild -i ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml - mv build/out/bitcoin-${VERSION}-osx.dmg ../ + mv build/out/bitcoin-osx-signed.dmg ../bitcoin-${VERSION}-osx.dmg popd Commit your signature for the signed OSX binary: From 06206bb3b78067f1f433dde8062c8ab01aaf43eb Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Tue, 30 Dec 2014 17:46:57 +0800 Subject: [PATCH 0105/2337] Correct tooltip on address book page --- src/qt/forms/addressbookpage.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui index 52fdc6ef06b..264edeb7200 100644 --- a/src/qt/forms/addressbookpage.ui +++ b/src/qt/forms/addressbookpage.ui @@ -27,7 +27,7 @@ Qt::CustomContextMenu - Double-click to edit address or label + Right-click to edit address or label false From 7b782f5b01f4c2d906a28800d01ffd05ad257cbe Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 30 Dec 2014 14:32:07 +0000 Subject: [PATCH 0106/2337] RPCWallet: Notate all account stuff as deprecated --- contrib/debian/manpages/bitcoind.1 | 24 +++++----- src/rpcmisc.cpp | 2 +- src/rpcrawtransaction.cpp | 2 +- src/rpcwallet.cpp | 73 +++++++++++++----------------- 4 files changed, 46 insertions(+), 55 deletions(-) diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1 index a1b17d6077f..c225b9f3e95 100644 --- a/contrib/debian/manpages/bitcoind.1 +++ b/contrib/debian/manpages/bitcoind.1 @@ -85,19 +85,19 @@ This help message Safely copies *wallet.dat* to 'destination', which can be a directory or a path with filename. .TP \fBgetaccount 'bitcoinaddress'\fR -Returns the account associated with the given address. +DEPRECATED. Returns the account associated with the given address. .TP \fBsetaccount 'bitcoinaddress' ['account']\fR -Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account']. +DEPRECATED. Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account']. .TP \fBgetaccountaddress 'account'\fR -Returns a new bitcoin address for 'account'. +DEPRECATED. Returns a new bitcoin address for 'account'. .TP \fBgetaddressesbyaccount 'account'\fR -Returns the list of addresses associated with the given 'account'. +DEPRECATED. Returns the list of addresses associated with the given 'account'. .TP \fBgetbalance 'account'\fR -Returns the server's available balance, or the balance for 'account'. +Returns the server's available balance, or the balance for 'account' (accounts are deprecated). .TP \fBgetblockcount\fR Returns the number of blocks in the longest block chain. @@ -124,10 +124,10 @@ Returns a recent hashes per second performance measurement while generating. Returns an object containing server information. .TP \fBgetnewaddress 'account'\fR -Returns a new bitcoin address for receiving payments. If 'account' is specified (recommended), it is added to the address book so payments received with the address will be credited to 'account'. +Returns a new bitcoin address for receiving payments. If 'account' is specified (deprecated), it is added to the address book so payments received with the address will be credited to 'account'. .TP \fBgetreceivedbyaccount 'account' ['minconf=1']\fR -Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations. +DEPRECATED. Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations. .TP \fBgetreceivedbyaddress 'bitcoinaddress' ['minconf=1']\fR Returns the total amount received by 'bitcoinaddress' in transactions with at least ['minconf'] confirmations. @@ -147,13 +147,13 @@ If 'data' is specified, tries to solve the block and returns true if it was succ List commands, or get help for a command. .TP \fBlistaccounts ['minconf=1']\fR -List accounts and their current balances. +DEPRECATED. List accounts and their current balances. *note: requires bitcoin 0.3.20 or later. .TP \fBlistreceivedbyaccount ['minconf=1'] ['includeempty=false']\fR ['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing: - "account" : the account of the receiving address. + "account" : DEPRECATED. the account of the receiving address. "amount" : total amount received by the address. "confirmations" : number of confirmations of the most recent transaction included. .TP @@ -161,7 +161,7 @@ List accounts and their current balances. ['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing: "address" : receiving address. - "account" : the account of the receiving address. + "account" : DEPRECATED. the account of the receiving address. "amount" : total amount received by the address. "confirmations" : number of confirmations of the most recent transaction included. .TP @@ -180,10 +180,10 @@ Returns a list of the last ['count'] transactions for 'account' \- for all accou *note: requires bitcoin 0.3.20 or later. .TP \fBmove <'fromaccount'> <'toaccount'> <'amount'> ['minconf=1'] ['comment']\fR -Moves funds between accounts. +DEPRECATED. Moves funds between accounts. .TP \fBsendfrom* <'account'> <'bitcoinaddress'> <'amount'> ['minconf=1'] ['comment'] ['comment-to']\fR -Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success. +DEPRECATED. Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success. .TP \fBsendtoaddress 'bitcoinaddress' 'amount' ['comment'] ['comment-to']\fR Sends amount from the server's available balance to 'bitcoinaddress'. amount is a real and is rounded to the nearest 0.01. Returns transaction id on success. diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 90b9c99caa0..7732e053676 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -166,7 +166,7 @@ Value validateaddress(const Array& params, bool fHelp) " \"isscript\" : true|false, (boolean) If the key is a script\n" " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n" " \"iscompressed\" : true|false, (boolean) If the address is compressed\n" - " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n" + " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n" "}\n" "\nExamples:\n" + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"") diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 8de15ff9e2f..c16d7289909 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -218,7 +218,7 @@ Value listunspent(const Array& params, bool fHelp) " \"txid\" : \"txid\", (string) the transaction id \n" " \"vout\" : n, (numeric) the vout value\n" " \"address\" : \"address\", (string) the bitcoin address\n" - " \"account\" : \"account\", (string) The associated account, or \"\" for the default account\n" + " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" " \"scriptPubKey\" : \"key\", (string) the script key\n" " \"amount\" : x.xxx, (numeric) the transaction amount in btc\n" " \"confirmations\" : n (numeric) The number of confirmations\n" diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index e43eee1551a..66c13a7688f 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -81,17 +81,15 @@ Value getnewaddress(const Array& params, bool fHelp) throw runtime_error( "getnewaddress ( \"account\" )\n" "\nReturns a new Bitcoin address for receiving payments.\n" - "If 'account' is specified (recommended), it is added to the address book \n" + "If 'account' is specified (DEPRECATED), it is added to the address book \n" "so payments received with the address will be credited to 'account'.\n" "\nArguments:\n" - "1. \"account\" (string, optional) The account name for the address to be linked to. if not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n" + "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. if not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n" "\nResult:\n" "\"bitcoinaddress\" (string) The new bitcoin address\n" "\nExamples:\n" + HelpExampleCli("getnewaddress", "") - + HelpExampleCli("getnewaddress", "\"\"") - + HelpExampleCli("getnewaddress", "\"myaccount\"") - + HelpExampleRpc("getnewaddress", "\"myaccount\"") + + HelpExampleRpc("getnewaddress", "") ); // Parse the account first so we don't generate a key if there's an error @@ -156,7 +154,7 @@ Value getaccountaddress(const Array& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "getaccountaddress \"account\"\n" - "\nReturns the current Bitcoin address for receiving payments to this account.\n" + "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n" "\nArguments:\n" "1. \"account\" (string, required) The account name for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n" "\nResult:\n" @@ -214,7 +212,7 @@ Value setaccount(const Array& params, bool fHelp) if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "setaccount \"bitcoinaddress\" \"account\"\n" - "\nSets the account associated with the given address.\n" + "\nDEPRECATED. Sets the account associated with the given address.\n" "\nArguments:\n" "1. \"bitcoinaddress\" (string, required) The bitcoin address to be associated with an account.\n" "2. \"account\" (string, required) The account to assign the address to.\n" @@ -256,7 +254,7 @@ Value getaccount(const Array& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "getaccount \"bitcoinaddress\"\n" - "\nReturns the account associated with the given address.\n" + "\nDEPRECATED. Returns the account associated with the given address.\n" "\nArguments:\n" "1. \"bitcoinaddress\" (string, required) The bitcoin address for account lookup.\n" "\nResult:\n" @@ -283,7 +281,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "getaddressesbyaccount \"account\"\n" - "\nReturns the list of addresses for the given account.\n" + "\nDEPRECATED. Returns the list of addresses for the given account.\n" "\nArguments:\n" "1. \"account\" (string, required) The account name.\n" "\nResult:\n" @@ -402,7 +400,7 @@ Value listaddressgroupings(const Array& params, bool fHelp) " [\n" " \"bitcoinaddress\", (string) The bitcoin address\n" " amount, (numeric) The amount in btc\n" - " \"account\" (string, optional) The account\n" + " \"account\" (string, optional) The account (DEPRECATED)\n" " ]\n" " ,...\n" " ]\n" @@ -544,7 +542,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getreceivedbyaccount \"account\" ( minconf )\n" - "\nReturns the total amount received by addresses with in transactions with at least [minconf] confirmations.\n" + "\nDEPRECATED. Returns the total amount received by addresses with in transactions with at least [minconf] confirmations.\n" "\nArguments:\n" "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" @@ -629,26 +627,22 @@ Value getbalance(const Array& params, bool fHelp) throw runtime_error( "getbalance ( \"account\" minconf includeWatchonly )\n" "\nIf account is not specified, returns the server's total available balance.\n" - "If account is specified, returns the balance in the account.\n" + "If account is specified (DEPRECATED), returns the balance in the account.\n" "Note that the account \"\" is not the same as leaving the parameter out.\n" "The server total may be different to the balance in the default \"\" account.\n" "\nArguments:\n" - "1. \"account\" (string, optional) The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n" + "1. \"account\" (string, optional) DEPRECATED. The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n" "\nResult:\n" "amount (numeric) The total amount in btc received for this account.\n" "\nExamples:\n" - "\nThe total amount in the server across all accounts\n" + "\nThe total amount in the wallet\n" + HelpExampleCli("getbalance", "") + - "\nThe total amount in the server across all accounts, with at least 5 confirmations\n" + "\nThe total amount in the wallet at least 5 blocks confirmed\n" + HelpExampleCli("getbalance", "\"*\" 6") + - "\nThe total amount in the default account with at least 1 confirmation\n" - + HelpExampleCli("getbalance", "\"\"") + - "\nThe total amount in the account named tabby with at least 6 confirmations\n" - + HelpExampleCli("getbalance", "\"tabby\" 6") + "\nAs a json rpc call\n" - + HelpExampleRpc("getbalance", "\"tabby\", 6") + + HelpExampleRpc("getbalance", "\"*\", 6") ); if (params.size() == 0) @@ -712,7 +706,7 @@ Value movecmd(const Array& params, bool fHelp) if (fHelp || params.size() < 3 || params.size() > 5) throw runtime_error( "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n" - "\nMove a specified amount from one account in your wallet to another.\n" + "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n" "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n" @@ -777,7 +771,7 @@ Value sendfrom(const Array& params, bool fHelp) if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n" - "\nSent an amount from an account to a bitcoin address.\n" + "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address.\n" "The amount is a real and is rounded to the nearest 0.00000001." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" @@ -838,7 +832,7 @@ Value sendmany(const Array& params, bool fHelp) "\nSend multiple times. Amounts are double-precision floating point numbers." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" - "1. \"fromaccount\" (string, required) The account to send the funds from, can be \"\" for the default account\n" + "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" " {\n" " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in btc is the value\n" @@ -851,11 +845,11 @@ Value sendmany(const Array& params, bool fHelp) " the number of addresses.\n" "\nExamples:\n" "\nSend two amounts to two different addresses:\n" - + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + "\nSend two amounts to two different addresses setting the confirmation and comment:\n" - + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + "\nAs a json rpc call\n" - + HelpExampleRpc("sendmany", "\"tabby\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") + + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") ); string strAccount = AccountFromValue(params[0]); @@ -920,7 +914,7 @@ Value addmultisigaddress(const Array& params, bool fHelp) string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n" "\nAdd a nrequired-to-sign multisignature address to the wallet.\n" "Each key is a Bitcoin address or hex-encoded public key.\n" - "If 'account' is specified, assign address to that account.\n" + "If 'account' is specified (DEPRECATED), assign address to that account.\n" "\nArguments:\n" "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" @@ -929,7 +923,7 @@ Value addmultisigaddress(const Array& params, bool fHelp) " \"address\" (string) bitcoin address or hex-encoded public key\n" " ...,\n" " ]\n" - "3. \"account\" (string, optional) An account to assign the addresses to.\n" + "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n" "\nResult:\n" "\"bitcoinaddress\" (string) A bitcoin address associated with the keys.\n" @@ -1105,7 +1099,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) " {\n" " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n" " \"address\" : \"receivingaddress\", (string) The receiving address\n" - " \"account\" : \"accountname\", (string) The account of the receiving address. The default account is \"\".\n" + " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n" " \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n" " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n" " }\n" @@ -1126,7 +1120,7 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) if (fHelp || params.size() > 3) throw runtime_error( "listreceivedbyaccount ( minconf includeempty includeWatchonly)\n" - "\nList balances by account.\n" + "\nDEPRECATED. List balances by account.\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" "2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n" @@ -1253,15 +1247,14 @@ Value listtransactions(const Array& params, bool fHelp) "listtransactions ( \"account\" count from includeWatchonly)\n" "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n" "\nArguments:\n" - "1. \"account\" (string, optional) The account name. If not included, it will list all transactions for all accounts.\n" - " If \"\" is set, it will list transactions for the default account.\n" + "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n" "2. count (numeric, optional, default=10) The number of transactions to return\n" "3. from (numeric, optional, default=0) The number of transactions to skip\n" "4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n" "\nResult:\n" "[\n" " {\n" - " \"account\":\"accountname\", (string) The account name associated with the transaction. \n" + " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n" " It will be \"\" for the default account.\n" " \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for \n" " move transactions (category = move).\n" @@ -1295,12 +1288,10 @@ Value listtransactions(const Array& params, bool fHelp) "\nExamples:\n" "\nList the most recent 10 transactions in the systems\n" + HelpExampleCli("listtransactions", "") + - "\nList the most recent 10 transactions for the tabby account\n" - + HelpExampleCli("listtransactions", "\"tabby\"") + - "\nList transactions 100 to 120 from the tabby account\n" - + HelpExampleCli("listtransactions", "\"tabby\" 20 100") + + "\nList transactions 100 to 120\n" + + HelpExampleCli("listtransactions", "\"*\" 20 100") + "\nAs a json rpc call\n" - + HelpExampleRpc("listtransactions", "\"tabby\", 20, 100") + + HelpExampleRpc("listtransactions", "\"*\", 20, 100") ); string strAccount = "*"; @@ -1363,7 +1354,7 @@ Value listaccounts(const Array& params, bool fHelp) if (fHelp || params.size() > 2) throw runtime_error( "listaccounts ( minconf includeWatchonly)\n" - "\nReturns Object that has account names as keys, account balances as values.\n" + "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n" "2. includeWatchonly (bool, optional, default=false) Include balances in watchonly addresses (see 'importaddress')\n" @@ -1446,7 +1437,7 @@ Value listsinceblock(const Array& params, bool fHelp) "\nResult:\n" "{\n" " \"transactions\": [\n" - " \"account\":\"accountname\", (string) The account name associated with the transaction. Will be \"\" for the default account.\n" + " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n" " \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n" " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n" " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the 'move' category for moves \n" @@ -1540,7 +1531,7 @@ Value gettransaction(const Array& params, bool fHelp) " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n" " \"details\" : [\n" " {\n" - " \"account\" : \"accountname\", (string) The account name involved in the transaction, can be \"\" for the default account.\n" + " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" " \"address\" : \"bitcoinaddress\", (string) The bitcoin address involved in the transaction\n" " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n" " \"amount\" : x.xxx (numeric) The amount in btc\n" From 8f6860a083837e1f991ed75993f7c4fbcb10462c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 30 Dec 2014 15:15:40 +0000 Subject: [PATCH 0107/2337] Bugfix: RPCWallet: Docs: Booleans aren't quoted --- src/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index e43eee1551a..82fae2dffc2 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1103,7 +1103,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) "\nResult:\n" "[\n" " {\n" - " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n" + " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" " \"address\" : \"receivingaddress\", (string) The receiving address\n" " \"account\" : \"accountname\", (string) The account of the receiving address. The default account is \"\".\n" " \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n" @@ -1135,7 +1135,7 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) "\nResult:\n" "[\n" " {\n" - " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n" + " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" " \"account\" : \"accountname\", (string) The account name of the receiving account\n" " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n" " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n" From 4f1ee565b5669fece4178d590f37a577c4062420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Tue, 30 Dec 2014 23:02:46 +0100 Subject: [PATCH 0108/2337] Clean AcceptToMemoryPool error messages --- src/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2410230ef43..0e199fe6035 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -926,11 +926,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa *pfMissingInputs = false; if (!CheckTransaction(tx, state)) - return error("AcceptToMemoryPool: : CheckTransaction failed"); + return error("AcceptToMemoryPool: CheckTransaction failed"); // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) - return state.DoS(100, error("AcceptToMemoryPool: : coinbase as individual tx"), + return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"), REJECT_INVALID, "coinbase"); // Rather not work on nonstandard transactions (unless -testnet/-regtest) @@ -1000,7 +1000,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Check for non-standard pay-to-script-hash in inputs if (Params().RequireStandard() && !AreInputsStandard(tx, view)) - return error("AcceptToMemoryPool: : nonstandard transaction input"); + return error("AcceptToMemoryPool: nonstandard transaction input"); // Check that the transaction doesn't have an excessive number of // sigops, making it impossible to mine. Since the coinbase transaction @@ -1076,7 +1076,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // can be exploited as a DoS attack. if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) { - return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); + return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); } // Store transaction in memory From 228d2385254ee136ef64d229a414fdd7cefea9a0 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 31 Dec 2014 03:19:24 +0000 Subject: [PATCH 0109/2337] Make CCoinsViewCache's copy constructor private It is easily confused with CCoinsViewCache(CCoinsView*), which creates a sub-cache, but instead of creating a sub-cache, the copy constructor would copy the original and use that original's base, defeating the intended isolation. --- src/coins.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/coins.h b/src/coins.h index dbe3f8bd316..e6ba1689491 100644 --- a/src/coins.h +++ b/src/coins.h @@ -441,6 +441,11 @@ public: private: CCoinsMap::iterator FetchCoins(const uint256 &txid); CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const; + + /** + * By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache. + */ + CCoinsViewCache(const CCoinsViewCache &); }; #endif // BITCOIN_COINS_H From 1b178a7f966cd3649b7f0a52ffc4b8ef4c227900 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 31 Dec 2014 03:28:05 +0000 Subject: [PATCH 0110/2337] Bugfix: ConnectBlock: In case the genesis block gets in with fJustCheck, behave correctly --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 70e3973e6c7..7c5b7401ede 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1616,7 +1616,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Special case for the genesis block, skipping connection of its transactions // (its coinbase is unspendable) if (block.GetHash() == Params().HashGenesisBlock()) { - view.SetBestBlock(pindex->GetBlockHash()); + if (!fJustCheck) + view.SetBestBlock(pindex->GetBlockHash()); return true; } From 643415aade0dae528098df2d822288ba0c5f6ce2 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Wed, 31 Dec 2014 12:03:00 +0100 Subject: [PATCH 0111/2337] [Qt] update a translation string and argument counts --- src/qt/paymentserver.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 3f8e89535e1..b3dbb693d73 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -667,8 +667,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) // BIP70 DoS protection if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - QString msg = tr("Payment request %2 is too large (%3 bytes, allowed %4 bytes).") - .arg(__func__) + QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") .arg(reply->request().url().toString()) .arg(reply->size()) .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); From d57b303e1e5b3fc31da0769b14b01fdcc19b1f7a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 30 Dec 2014 18:45:29 -0500 Subject: [PATCH 0112/2337] depends: fix major regression after d546191dc. Broken hash logic caused all depends on some platforms (osx at least) to end up with the same build-id. Without this fix, nothing will be rebuilt when recipes or dependencies change. --- depends/funcs.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index 79015c047ca..337634253f5 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -31,8 +31,8 @@ define fetch_file endef define int_get_build_recipe_hash -$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)))) -$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | cut -d" " -f1 | $(build_SHA256SUM))) +$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)) | cut -d" " -f1)) +$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM) | cut -d" " -f1)) endef define int_get_build_id From 23f3435962f0cfa57a95b293094fe9d0fe9d968c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 1 Jan 2015 11:35:29 +0000 Subject: [PATCH 0113/2337] Rename MAX_TX_SIGOPS to MAX_STANDARD_TX_SIGOPS to match similar policy constant MAX_STANDARD_TX_SIZE --- src/main.cpp | 6 +++--- src/main.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5c0f0116d6d..7a75ca2cf6f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1005,15 +1005,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Check that the transaction doesn't have an excessive number of // sigops, making it impossible to mine. Since the coinbase transaction - // itself can contain sigops MAX_TX_SIGOPS is less than + // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than // merely non-standard transaction. unsigned int nSigOps = GetLegacySigOpCount(tx); nSigOps += GetP2SHSigOpCount(tx, view); - if (nSigOps > MAX_TX_SIGOPS) + if (nSigOps > MAX_STANDARD_TX_SIGOPS) return state.DoS(0, error("AcceptToMemoryPool : too many sigops %s, %d > %d", - hash.ToString(), nSigOps, MAX_TX_SIGOPS), + hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS), REJECT_NONSTANDARD, "bad-txns-too-many-sigops"); CAmount nValueOut = tx.GetValueOut(); diff --git a/src/main.h b/src/main.h index 9049f5bb7d4..35e5608386b 100644 --- a/src/main.h +++ b/src/main.h @@ -60,7 +60,7 @@ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of sigops we're willing to relay/mine in a single tx */ -static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; +static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** The maximum size of a blk?????.dat file (since 0.8) */ From e6df2bb48f4bff7a2dec4aa226102b0cf2cd828b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 2 Jan 2015 10:42:33 +0100 Subject: [PATCH 0114/2337] Remove redundant copyright notices from README files The normative place for these for the entire project is COPYING, and the main README already has a MIT license section. --- README.md | 2 -- doc/README.md | 5 +---- doc/README_windows.txt | 12 ++---------- src/test/data/README.md | 8 +++----- 4 files changed, 6 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 03a698996de..67c5ed5b414 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,6 @@ Bitcoin Core integration/staging tree https://www.bitcoin.org -Copyright (c) 2009-2014 Bitcoin Core Developers - What is Bitcoin? ---------------- diff --git a/doc/README.md b/doc/README.md index 1696518f874..b2a0c2dcb7a 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,9 +1,6 @@ -Bitcoin 0.10.99 +Bitcoin Core 0.10.99 ===================== -Copyright (c) 2009-2014 Bitcoin Developers - - Setup --------------------- [Bitcoin Core](http://bitcoin.org/en/download) is the original Bitcoin client and it builds the backbone of the network. However, it downloads and stores the entire history of Bitcoin transactions (which is currently several GBs); depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more. Thankfully you only have to do this once. If you would like the process to go faster you can [download the blockchain directly](bootstrap.md). diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 5ac1152055e..c5829416965 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,13 +1,5 @@ -Bitcoin 0.10.99 - -Copyright (c) 2009-2014 Bitcoin Core Developers - -Distributed under the MIT software license, see the accompanying -file COPYING or http://www.opensource.org/licenses/mit-license.php. -This product includes software developed by the OpenSSL Project for use in -the OpenSSL Toolkit (https://www.openssl.org/). This product includes -cryptographic software written by Eric Young (eay@cryptsoft.com). - +Bitcoin Core 0.10.99 +===================== Intro ----- diff --git a/src/test/data/README.md b/src/test/data/README.md index 55ac95739c7..2463daa42a5 100644 --- a/src/test/data/README.md +++ b/src/test/data/README.md @@ -6,9 +6,7 @@ This directory contains data-driven tests for various aspects of Bitcoin. License -------- -The data files in this directory are - - Copyright (c) 2012-2014 The Bitcoin Core developers - Distributed under the MIT software license, see the accompanying - file COPYING or http://www.opensource.org/licenses/mit-license.php. +The data files in this directory are distributed under the MIT software +license, see the accompanying file COPYING or +http://www.opensource.org/licenses/mit-license.php. From edbc9045cb21020d0cc19d226f55ee169e2ffb92 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 2 Jan 2015 10:49:20 +0100 Subject: [PATCH 0115/2337] Bump project-wide COPYRIGHT_YEAR to 2015 There is still a redundancy here between configure.ac and clientversion.h. --- configure.ac | 2 +- src/clientversion.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index b28898a4fae..adcd1c0dd57 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ define(_CLIENT_VERSION_MINOR, 10) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) -define(_COPYRIGHT_YEAR, 2014) +define(_COPYRIGHT_YEAR, 2015) AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@bitcoin.org],[bitcoin]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) diff --git a/src/clientversion.h b/src/clientversion.h index 40de7837aa7..3c8c969f9d5 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -26,7 +26,7 @@ * Copyright year (2009-this) * Todo: update this when changing our copyright comments in the source */ -#define COPYRIGHT_YEAR 2014 +#define COPYRIGHT_YEAR 2015 #endif //HAVE_CONFIG_H From 269d8ba0d24eb9a35c8c9e4995eccedfb723717b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 2 Jan 2015 17:27:18 +0100 Subject: [PATCH 0116/2337] Remove declaration of no longer existent CheckWork Also make ProcessBlockFound static as it is not used outside miner.cpp. Alternative implementation of #5549. --- src/miner.cpp | 2 +- src/miner.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 0ac974d6e13..3bd2a9a41fc 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -411,7 +411,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) return CreateNewBlock(scriptPubKey); } -bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) +static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) { LogPrintf("%s\n", pblock->ToString()); LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue)); diff --git a/src/miner.h b/src/miner.h index 02dedb1712a..3c08b030f6b 100644 --- a/src/miner.h +++ b/src/miner.h @@ -24,8 +24,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); -/** Check mined block */ -bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); extern double dHashesPerSec; From ec90c97d13a4770c0c794f46eccc675e3c1a5103 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 30 Dec 2014 21:37:30 -0500 Subject: [PATCH 0117/2337] depends: osx: fix qt5 build against 10.10 sdk --- depends/packages/qt.mk | 3 +- depends/patches/qt/qt5-yosemite.patch | 52 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 depends/patches/qt/qt5-yosemite.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 6a8e714a489..57f973d59dd 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -7,7 +7,7 @@ $(package)_dependencies=openssl $(package)_linux_dependencies=freetype fontconfig dbus libxcb libX11 xproto libXext $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib -$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch qt5-tablet-osx.patch +$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch qt5-tablet-osx.patch qt5-yosemite.patch define $(package)_set_vars $(package)_config_opts_release = -release @@ -56,6 +56,7 @@ define $(package)_preprocess_cmds cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \ patch -p1 < $($(package)_patch_dir)/qt5-tablet-osx.patch && \ + patch -d qtbase -p1 < $($(package)_patch_dir)/qt5-yosemite.patch && \ echo "QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ diff --git a/depends/patches/qt/qt5-yosemite.patch b/depends/patches/qt/qt5-yosemite.patch new file mode 100644 index 00000000000..d569d34d47f --- /dev/null +++ b/depends/patches/qt/qt5-yosemite.patch @@ -0,0 +1,52 @@ +The following patch was taken from upstream: +https://qt.gitorious.org/qt/qtbase/commit/70e4428b6f1c6a4bad112203f67ee7d22107616c.patch + +The first hunk was removed because it conflicts with 5.2.1, and is not currently needed. + +From 70e4428b6f1c6a4bad112203f67ee7d22107616c Mon Sep 17 00:00:00 2001 +From: Gabriel de Dietrich +Date: Tue, 3 Jun 2014 14:20:20 +0200 +Subject: [PATCH] Cocoa: Adapt to Xcode 6 clang version sudden pickiness +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Yes, that means OS X Yosemite fix. + +Change-Id: I236f7af7b803de24ff0895e04c9a9253b5cfdb3b +Reviewed-by: Morten Johan Sørvig +--- + .../platforms/cocoa/qcocoaaccessibilityelement.mm | 2 +- + .../platforms/cocoa/qcocoaapplicationdelegate.mm | 2 +- + src/plugins/platforms/cocoa/qcocoamenuloader.mm | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +index f841184..548c6a2 100644 +--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm ++++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +@@ -124,7 +124,7 @@ static void cleanupCocoaApplicationDelegate() + [dockMenu release]; + [qtMenuLoader release]; + if (reflectionDelegate) { +- [NSApp setDelegate:reflectionDelegate]; ++ [[NSApplication sharedApplication] setDelegate:reflectionDelegate]; + [reflectionDelegate release]; + } + [[NSNotificationCenter defaultCenter] removeObserver:self]; +diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm +index 60bc3b5..9340e94 100644 +--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm ++++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm +@@ -174,7 +174,7 @@ QT_END_NAMESPACE + - (void)removeActionsFromAppMenu + { + for (NSMenuItem *item in [appMenu itemArray]) +- [item setTag:nil]; ++ [item setTag:0]; + } + + - (void)dealloc +-- +1.7.1 + From 4fe6c3c24fbd84fec7d7952a521e0cb443a3d72b Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 30 Dec 2014 19:10:15 -0500 Subject: [PATCH 0118/2337] depends: major upgrade to darwin toolchain tl;dr: Update to the newer stable toolchain and SDK for OSX without giving up any backwards compatibility. We can move to clang 3.5 as a next step which allows use to use libc++ and the 10.10 sdk, but we'll need to find a build that works in gitian/travis first. Switch to a new, better maintained fork of cctools: https://github.com/tpoechtrager/cctools-port I've forked this and will be working on it some as well: https://github.com/theuni/cctools-port This brings in: cctools v862 ld64: v241.9 It also fixes 64bit builds, so there's no longer any need to use a 32bit clang. Since clang is no longer tied to an old/crusty 32bit build, clang has been upgraded to 3.3. Unfortunately, there's a bug in 3.4 that breaks builds. 3.5 works fine, but there are no binary builds compatible with precise, which is currently used for gitian and travis. We could always build our own if necessary. After updating to stable clang/linker/cctools, it's possible to use a more recent SDK. The current SDK (10.7) through the most recent 10.10 have all been built/tested successfully, both with and without 10.6 compatibility. However, 10.10 requires clang 3.5. SDKs >= 10.9 use libc++ rather than libstdc++. This is verified working as well. --- depends/hosts/darwin.mk | 5 +- depends/packages/native_cctools.mk | 87 +++++++++++------------------- depends/packages/native_libuuid.mk | 3 -- depends/packages/native_openssl.mk | 2 +- depends/packages/qt.mk | 2 +- depends/patches/qt/mac-qmake.conf | 2 +- 6 files changed, 38 insertions(+), 63 deletions(-) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 8d718eba17b..c1070d8775f 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,8 +1,9 @@ OSX_MIN_VERSION=10.6 OSX_SDK_VERSION=10.7 OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk -darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) +LD64_VERSION=241.9 +darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) +darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) darwin_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index 1675afe7813..bf50880e15b 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,80 +1,57 @@ package=native_cctools -$(package)_version=809 -$(package)_download_path=http://www.opensource.apple.com/tarballs/cctools -$(package)_file_name=cctools-$($(package)_version).tar.gz -$(package)_sha256_hash=03ba62749b843b131c7304a044a98c6ffacd65b1399b921d69add0375f79d8ad -$(package)_build_subdir=cctools2odcctools/odcctools-$($(package)_version) +$(package)_version=59d21d2c793c51d205c8b4ab14b9b28e63c72445 +$(package)_download_path=https://github.com/theuni/cctools-port/archive +$(package)_file_name=$($(package)_version).tar.gz +$(package)_sha256_hash=e13c7129b9d496adf4d674156b4a1d72d8b936f29f377aae8f8b5e7b650cc305 +$(package)_build_subdir=cctools $(package)_dependencies=native_libuuid native_openssl -$(package)_ld64_download_file=ld64-127.2.tar.gz -$(package)_ld64_download_path=http://www.opensource.apple.com/tarballs/ld64 -$(package)_ld64_file_name=$($(package)_ld64_download_file) -$(package)_ld64_sha256_hash=97b75547b2bd761306ab3e15ae297f01e7ab9760b922bc657f4ef72e4e052142 -$(package)_dyld_download_file=dyld-195.5.tar.gz -$(package)_dyld_download_path=http://www.opensource.apple.com/tarballs/dyld -$(package)_dyld_file_name=$($(package)_dyld_download_file) -$(package)_dyld_sha256_hash=2cf0484c87cf79b606b351a7055a247dae84093ae92c747a74e0cde2c8c8f83c -$(package)_toolchain4_download_file=10cc648683617cca8bcbeae507888099b41b530c.tar.gz -$(package)_toolchain4_download_path=https://github.com/mingwandroid/toolchain4/archive -$(package)_toolchain4_file_name=toolchain4-1.tar.gz -$(package)_toolchain4_sha256_hash=18406961fd4a1ec5c7ea35c91d6a80a2f8bb797a2bd243a610bd75e13eff9aca -$(package)_clang_download_file=clang+llvm-3.2-x86-linux-ubuntu-12.04.tar.gz -$(package)_clang_download_path=http://llvm.org/releases/3.2 -$(package)_clang_file_name=clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz -$(package)_clang_sha256_hash=b9d57a88f9514fa1f327a1a703756d0c1c960f4c58494a5bd80313245d13ffff - +$(package)_clang_version=3.3 +$(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version) +$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz +$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz +$(package)_clang_sha256_hash=60d8f69f032d62ef61bf527857ebb933741ec3352d4d328c5516aa520662dab7 define $(package)_fetch_cmds $(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_ld64_download_path),$($(package)_ld64_download_file),$($(package)_ld64_file_name),$($(package)_ld64_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_dyld_download_path),$($(package)_dyld_download_file),$($(package)_dyld_file_name),$($(package)_dyld_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_toolchain4_download_path),$($(package)_toolchain4_download_file),$($(package)_toolchain4_file_name),$($(package)_toolchain4_sha256_hash)) +$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) +endef + +define $(package)_extract_cmds + mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \ + tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ + echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \ + echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \ + chmod +x toolchain/bin/$(host)-dsymutil && \ + tar --strip-components=1 -xf $($(package)_source) endef define $(package)_set_vars -$(package)_config_opts=--target=$(host) --with-sysroot=$(OSX_SDK) -$(package)_cflags+=-m32 -$(package)_cxxflags+=-m32 -$(package)_cppflags+=-D__DARWIN_UNIX03 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -$(package)_ldflags+=-m32 -Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib -$(package)_ldflags+=-L$$(native_cctools_extract_dir)/clang+llvm-3.2-x86-linux-ubuntu-12.04/lib -endef -define $(package)_extract_cmds - tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_toolchain4_file_name) && \ - ln -sf $($(package)_source) cctools2odcctools/$($(package)_file_name) && \ - ln -sf $($(package)_source_dir)/$($(package)_ld64_file_name) cctools2odcctools/$($(package)_ld64_file_name) && \ - ln -sf $($(package)_source_dir)/$($(package)_dyld_file_name) cctools2odcctools/$($(package)_dyld_file_name) && \ - tar xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ - mkdir -p $(SDK_PATH) sdks &&\ - cd sdks; ln -sf $(OSX_SDK) MacOSX$(OSX_SDK_VERSION).sdk +$(package)_config_opts=--target=$(host) CC=toolchain/clang CXX=toolchain/clang++ +$(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib endef define $(package)_preprocess_cmds - sed -i "s|GCC_DIR|LLVM_CLANG_DIR|g" cctools2odcctools/extract.sh && \ - sed -i "s|llvmgcc42-2336.1|clang+llvm-3.2-x86-linux-ubuntu-12.04|g" cctools2odcctools/extract.sh && \ - sed -i "s|/llvmCore/include/llvm-c|/include/llvm-c \$$$${LLVM_CLANG_DIR}/include/llvm |" cctools2odcctools/extract.sh && \ - sed -i "s|fAC_INIT|AC_INIT|" cctools2odcctools/files/configure.ac && \ - sed -i 's/\# Dynamically linked LTO/\t ;\&\n\t linux*)\n# Dynamically linked LTO/' cctools2odcctools/files/configure.ac && \ - cd cctools2odcctools; ./extract.sh --osxver $(OSX_SDK_VERSION) && \ - sed -i "s|define\tPC|define\tPC_|" odcctools-809/include/architecture/sparc/reg.h + cd $($(package)_build_subdir); ./autogen.sh endef define $(package)_config_cmds + export "PATH=$($(package)_extract_dir)/toolchain/bin:$(PATH)" && \ $($(package)_autoconf) endef define $(package)_build_cmds + export "PATH=$($(package)_extract_dir)/toolchain/bin:$(PATH)" && \ $(MAKE) endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ - cd ../../clang+llvm-3.2-x86-linux-ubuntu-12.04 && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/clang/3.2/include && \ - mkdir -p $($(package)_staging_prefix_dir)/bin && \ + cd $($(package)_extract_dir)/toolchain && \ + mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \ + mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \ cp -P bin/clang bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ - cp lib/clang/3.2/include/* $($(package)_staging_prefix_dir)/lib/clang/3.2/include/ && \ - echo "#!/bin/sh" > $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ - echo "exit 0" >> $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ - chmod +x $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil + cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \ + cp bin/$(host)-dsymutil $($(package)_staging_prefix_dir)/bin && \ + if `test -d include/c++/`; then cp -rf include/c++/ $($(package)_staging_prefix_dir)/include/; fi && \ + if `test -d lib/c++/`; then cp -rf lib/c++/ $($(package)_staging_prefix_dir)/lib/; fi endef diff --git a/depends/packages/native_libuuid.mk b/depends/packages/native_libuuid.mk index b25540f80df..741eabfe802 100644 --- a/depends/packages/native_libuuid.mk +++ b/depends/packages/native_libuuid.mk @@ -6,9 +6,6 @@ $(package)_sha256_hash=dbc7a138a3218d9b80a0626b5b692d76934d6746d8cbb762751be3378 define $(package)_set_vars $(package)_config_opts=--disable-elf-shlibs --disable-uuidd -$(package)_cflags+=-m32 -$(package)_ldflags+=-m32 -$(package)_cxxflags+=-m32 endef define $(package)_config_cmds diff --git a/depends/packages/native_openssl.mk b/depends/packages/native_openssl.mk index 1f25d6afccd..108c6e94428 100644 --- a/depends/packages/native_openssl.mk +++ b/depends/packages/native_openssl.mk @@ -4,7 +4,7 @@ $(package)_download_path=https://www.openssl.org/source $(package)_file_name=openssl-$($(package)_version).tar.gz $(package)_sha256_hash=9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 define $(package)_set_vars -$(package)_build_config_opts= --prefix=$(build_prefix) no-zlib no-shared no-krb5C linux-generic32 -m32 +$(package)_build_config_opts= --prefix=$(build_prefix) no-zlib no-shared no-krb5C linux-generic64 endef define $(package)_config_cmds diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 57f973d59dd..59c12d22f19 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -34,7 +34,7 @@ $(package)_config_opts += -qt-libpng -qt-libjpeg -qt-zlib -qt-pcre ifneq ($(build_os),darwin) $(package)_config_opts_darwin = -xplatform macx-clang-linux -device-option MAC_SDK_PATH=$(OSX_SDK) -device-option CROSS_COMPILE="$(host)-" -$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) -device-option MAC_TARGET=$(host) +$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) -device-option MAC_TARGET=$(host) -device-option MAC_LD64_VERSION=$(LD64_VERSION) endif $(package)_config_opts_linux = -qt-xkbcommon -qt-xcb -no-eglfs -no-linuxfb -system-freetype -no-sm -fontconfig -no-xinput2 -no-libudev -no-egl -no-opengl diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf index f7302265bcd..a97945bc8c1 100644 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -15,7 +15,7 @@ QMAKE_MAC_SDK.macosx.platform_name = macosx QMAKE_CFLAGS += -target $${MAC_TARGET} QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS QMAKE_CXXFLAGS += $$QMAKE_CFLAGS -QMAKE_LFLAGS += -target $${MAC_TARGET} +QMAKE_LFLAGS += -target $${MAC_TARGET} -mlinker-version=$${MAC_LD64_VERSION} QMAKE_AR = $${CROSS_COMPILE}ar cq QMAKE_RANLIB=$${CROSS_COMPILE}ranlib QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool From 46f54bf7968c0640e67756bcf6819d74e2e52554 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 31 Dec 2014 02:55:17 -0500 Subject: [PATCH 0119/2337] build: osx builders no longer need 32bit compiler support --- .travis.yml | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1630c1d02a4..8b9ede3e1c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ matrix: - compiler: ": 32-bit + dash" env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash" - compiler: ": Cross-Mac" - env: HOST=x86_64-apple-darwin11 PACKAGES="gcc-multilib g++-multilib cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.7 GOAL="deploy" + env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.7 GOAL="deploy" - compiler: ": Win64" env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2" - compiler: ": Win32" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 4f05aad2335..0732d35301a 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -6,7 +6,7 @@ suites: architectures: - "amd64" packages: -- "g++-multilib" +- "g++" - "git-core" - "pkg-config" - "autoconf2.13" From a3241998e1e300e87e7c57d92c2478f67ec91db6 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 19 Dec 2014 15:21:29 -0500 Subject: [PATCH 0120/2337] namespace: remove boost namespace pollution --- src/bitcoin-cli.cpp | 14 +++++------ src/core_read.cpp | 1 - src/db.cpp | 5 ++-- src/init.cpp | 25 +++++++++--------- src/main.cpp | 3 +-- src/net.cpp | 1 - src/qt/paymentserver.cpp | 1 - src/rpcmisc.cpp | 1 - src/rpcprotocol.cpp | 1 - src/rpcrawtransaction.cpp | 1 - src/rpcserver.cpp | 53 +++++++++++++++++++-------------------- src/rpcwallet.cpp | 1 - src/walletdb.cpp | 13 +++++----- 13 files changed, 53 insertions(+), 67 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 668d492d6bc..f273a15713f 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -15,8 +15,6 @@ #define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */ using namespace std; -using namespace boost; -using namespace boost::asio; using namespace json_spirit; std::string HelpMessageCli() @@ -108,12 +106,12 @@ Object CallRPC(const string& strMethod, const Array& params) // Connect to localhost bool fUseSSL = GetBoolArg("-rpcssl", false); - asio::io_service io_service; - ssl::context context(io_service, ssl::context::sslv23); - context.set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3); - asio::ssl::stream sslStream(io_service, context); - SSLIOStreamDevice d(sslStream, fUseSSL); - iostreams::stream< SSLIOStreamDevice > stream(d); + boost::asio::io_service io_service; + boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23); + context.set_options(boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3); + boost::asio::ssl::stream sslStream(io_service, context); + SSLIOStreamDevice d(sslStream, fUseSSL); + boost::iostreams::stream< SSLIOStreamDevice > stream(d); const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort()))); if (!fConnected) diff --git a/src/core_read.cpp b/src/core_read.cpp index 7999030662d..85b60e9adba 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -20,7 +20,6 @@ #include #include -using namespace boost; using namespace boost::algorithm; using namespace std; diff --git a/src/db.cpp b/src/db.cpp index 94629968d5c..fcc177f1ccd 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -24,7 +24,6 @@ #include using namespace std; -using namespace boost; unsigned int nWalletDBUpdated; @@ -73,9 +72,9 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) boost::this_thread::interruption_point(); path = pathIn; - filesystem::path pathLogDir = path / "database"; + boost::filesystem::path pathLogDir = path / "database"; TryCreateDirectory(pathLogDir); - filesystem::path pathErrorFile = path / "db.log"; + boost::filesystem::path pathErrorFile = path / "db.log"; LogPrintf("CDBEnv::Open : LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); unsigned int nEnvFlags = 0; diff --git a/src/init.cpp b/src/init.cpp index a09caeea401..1b0c909b962 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -43,7 +43,6 @@ #include #include -using namespace boost; using namespace std; #ifdef ENABLE_WALLET @@ -427,12 +426,12 @@ void ThreadImport(std::vector vImportFiles) } // hardcoded $DATADIR/bootstrap.dat - filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat"; - if (filesystem::exists(pathBootstrap)) { + boost::filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat"; + if (boost::filesystem::exists(pathBootstrap)) { FILE *file = fopen(pathBootstrap.string().c_str(), "rb"); if (file) { CImportingNow imp; - filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; + boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; LogPrintf("Importing bootstrap.dat...\n"); LoadExternalBlockFile(file); RenameOver(pathBootstrap, pathBootstrapOld); @@ -816,7 +815,7 @@ bool AppInit2(boost::thread_group& threadGroup) return false; } - if (filesystem::exists(GetDataDir() / strWalletFile)) + if (boost::filesystem::exists(GetDataDir() / strWalletFile)) { CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) @@ -937,20 +936,20 @@ bool AppInit2(boost::thread_group& threadGroup) fReindex = GetBoolArg("-reindex", false); // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/ - filesystem::path blocksDir = GetDataDir() / "blocks"; - if (!filesystem::exists(blocksDir)) + boost::filesystem::path blocksDir = GetDataDir() / "blocks"; + if (!boost::filesystem::exists(blocksDir)) { - filesystem::create_directories(blocksDir); + boost::filesystem::create_directories(blocksDir); bool linked = false; for (unsigned int i = 1; i < 10000; i++) { - filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i); - if (!filesystem::exists(source)) break; - filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1); + boost::filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i); + if (!boost::filesystem::exists(source)) break; + boost::filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1); try { - filesystem::create_hard_link(source, dest); + boost::filesystem::create_hard_link(source, dest); LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string()); linked = true; - } catch (const filesystem::filesystem_error& e) { + } catch (const boost::filesystem::filesystem_error& e) { // Note: hardlink creation failing is not a disaster, it just means // blocks will get re-downloaded from peers. LogPrintf("Error hardlinking blk%04u.dat : %s\n", i, e.what()); diff --git a/src/main.cpp b/src/main.cpp index f02a6a12efe..f768f1e29fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,7 +28,6 @@ #include #include -using namespace boost; using namespace std; #if defined(NDEBUG) @@ -2788,7 +2787,7 @@ bool AbortNode(const std::string &strMessage, const std::string &userMessage) { bool CheckDiskSpace(uint64_t nAdditionalBytes) { - uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available; + uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available; // Check for nMinDiskSpace bytes (currently 50MB) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) diff --git a/src/net.cpp b/src/net.cpp index 6401ecbf83e..d07882c7f4c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -49,7 +49,6 @@ #endif #endif -using namespace boost; using namespace std; namespace { diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index b3dbb693d73..66331ee4b4c 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -46,7 +46,6 @@ #include #endif -using namespace boost; using namespace std; const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 7c08a5c2469..1013418184c 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -23,7 +23,6 @@ #include "json/json_spirit_utils.h" #include "json/json_spirit_value.h" -using namespace boost; using namespace boost::assign; using namespace json_spirit; using namespace std; diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index c4d6f06b12c..b08598d0bf9 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -26,7 +26,6 @@ #include "json/json_spirit_writer_template.h" using namespace std; -using namespace boost; using namespace boost::asio; using namespace json_spirit; diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index b87a8baac3c..35319e4803a 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -25,7 +25,6 @@ #include "json/json_spirit_utils.h" #include "json/json_spirit_value.h" -using namespace boost; using namespace boost::assign; using namespace json_spirit; using namespace std; diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 210c7fe9733..a070ab5bbe7 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -26,7 +26,6 @@ #include #include "json/json_spirit_writer_template.h" -using namespace boost; using namespace boost::asio; using namespace json_spirit; using namespace std; @@ -39,7 +38,7 @@ static std::string rpcWarmupStatus("RPC server started"); static CCriticalSection cs_rpcWarmup; //! These are created by StartRPCThreads, destroyed in StopRPCThreads -static asio::io_service* rpc_io_service = NULL; +static boost::asio::io_service* rpc_io_service = NULL; static map > deadlineTimers; static ssl::context* rpc_ssl_context = NULL; static boost::thread_group* rpc_worker_group = NULL; @@ -428,7 +427,7 @@ class AcceptedConnectionImpl : public AcceptedConnection { public: AcceptedConnectionImpl( - asio::io_service& io_service, + boost::asio::io_service& io_service, ssl::context &context, bool fUseSSL) : sslStream(io_service, context), @@ -453,11 +452,11 @@ public: } typename Protocol::endpoint peer; - asio::ssl::stream sslStream; + boost::asio::ssl::stream sslStream; private: SSLIOStreamDevice _d; - iostreams::stream< SSLIOStreamDevice > _stream; + boost::iostreams::stream< SSLIOStreamDevice > _stream; }; void ServiceConnection(AcceptedConnection *conn); @@ -504,7 +503,7 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptoris_open()) + if (error != boost::asio::error::operation_aborted && acceptor->is_open()) RPCListen(acceptor, context, fUseSSL); AcceptedConnectionImpl* tcp_conn = dynamic_cast< AcceptedConnectionImpl* >(conn.get()); @@ -535,7 +534,7 @@ static ip::tcp::endpoint ParseEndpoint(const std::string &strEndpoint, int defau std::string addr; int port = defaultPort; SplitHostPort(strEndpoint, port, addr); - return ip::tcp::endpoint(asio::ip::address::from_string(addr), port); + return ip::tcp::endpoint(boost::asio::ip::address::from_string(addr), port); } void StartRPCThreads() @@ -590,7 +589,7 @@ void StartRPCThreads() } assert(rpc_io_service == NULL); - rpc_io_service = new asio::io_service(); + rpc_io_service = new boost::asio::io_service(); rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23); const bool fUseSSL = GetBoolArg("-rpcssl", false); @@ -599,14 +598,14 @@ void StartRPCThreads() { rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3); - filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); - if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile; - if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string()); + boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); + if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile; + if (boost::filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string()); else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string()); - filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); - if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile; - if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem); + boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); + if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile; + if (boost::filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem); else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string()); string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"); @@ -618,8 +617,8 @@ void StartRPCThreads() int defaultPort = GetArg("-rpcport", BaseParams().RPCPort()); if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs { - vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v6::loopback(), defaultPort)); - vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v4::loopback(), defaultPort)); + vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::loopback(), defaultPort)); + vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), defaultPort)); if (mapArgs.count("-rpcbind")) { LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n"); @@ -641,8 +640,8 @@ void StartRPCThreads() } } } else { // No specific bind address specified, bind to any - vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v6::any(), defaultPort)); - vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v4::any(), defaultPort)); + vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort)); + vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort)); // Prefer making the socket dual IPv6/IPv4 instead of binding // to both addresses seperately. bBindAny = true; @@ -654,7 +653,7 @@ void StartRPCThreads() BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints) { try { - asio::ip::address bindAddress = endpoint.address(); + boost::asio::ip::address bindAddress = endpoint.address(); straddress = bindAddress.to_string(); LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny); boost::system::error_code v6_only_error; @@ -665,7 +664,7 @@ void StartRPCThreads() // Try making the socket dual IPv6/IPv4 when listening on the IPv6 "any" address acceptor->set_option(boost::asio::ip::v6_only( - !bBindAny || bindAddress != asio::ip::address_v6::any()), v6_only_error); + !bBindAny || bindAddress != boost::asio::ip::address_v6::any()), v6_only_error); acceptor->bind(endpoint); acceptor->listen(socket_base::max_connections); @@ -675,7 +674,7 @@ void StartRPCThreads() fListening = true; rpc_acceptors.push_back(acceptor); // If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately - if(bBindAny && bindAddress == asio::ip::address_v6::any() && !v6_only_error) + if(bBindAny && bindAddress == boost::asio::ip::address_v6::any() && !v6_only_error) break; } catch (const boost::system::system_error& e) @@ -693,7 +692,7 @@ void StartRPCThreads() rpc_worker_group = new boost::thread_group(); for (int i = 0; i < GetArg("-rpcthreads", 4); i++) - rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service)); + rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service)); fRPCRunning = true; } @@ -701,12 +700,12 @@ void StartDummyRPCThread() { if(rpc_io_service == NULL) { - rpc_io_service = new asio::io_service(); + rpc_io_service = new boost::asio::io_service(); /* Create dummy "work" to keep the thread from exiting when no timeouts active, * see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */ - rpc_dummy_work = new asio::io_service::work(*rpc_io_service); + rpc_dummy_work = new boost::asio::io_service::work(*rpc_io_service); rpc_worker_group = new boost::thread_group(); - rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service)); + rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service)); fRPCRunning = true; } } @@ -719,7 +718,7 @@ void StopRPCThreads() // First, cancel all timers and acceptors // This is not done automatically by ->stop(), and in some cases the destructor of - // asio::io_service can hang if this is skipped. + // boost::asio::io_service can hang if this is skipped. boost::system::error_code ec; BOOST_FOREACH(const boost::shared_ptr &acceptor, rpc_acceptors) { @@ -787,7 +786,7 @@ void RPCRunLater(const std::string& name, boost::function func, int6 deadlineTimers.insert(make_pair(name, boost::shared_ptr(new deadline_timer(*rpc_io_service)))); } - deadlineTimers[name]->expires_from_now(posix_time::seconds(nSeconds)); + deadlineTimers[name]->expires_from_now(boost::posix_time::seconds(nSeconds)); deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func)); } diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 56be6dba135..a6b38ead624 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -23,7 +23,6 @@ #include "json/json_spirit_value.h" using namespace std; -using namespace boost; using namespace boost::assign; using namespace json_spirit; diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 4fd7eb512b9..668130ed695 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -18,7 +18,6 @@ #include #include -using namespace boost; using namespace std; static uint64_t nAccountingEntryNumber = 0; @@ -865,20 +864,20 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) bitdb.mapFileUseCount.erase(wallet.strWalletFile); // Copy wallet.dat - filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; - filesystem::path pathDest(strDest); - if (filesystem::is_directory(pathDest)) + boost::filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; + boost::filesystem::path pathDest(strDest); + if (boost::filesystem::is_directory(pathDest)) pathDest /= wallet.strWalletFile; try { #if BOOST_VERSION >= 104000 - filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists); + boost::filesystem::copy_file(pathSrc, pathDest, boost::filesystem::copy_option::overwrite_if_exists); #else - filesystem::copy_file(pathSrc, pathDest); + boost::filesystem::copy_file(pathSrc, pathDest); #endif LogPrintf("copied wallet.dat to %s\n", pathDest.string()); return true; - } catch (const filesystem::filesystem_error& e) { + } catch (const boost::filesystem::filesystem_error& e) { LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what()); return false; } From 9b1ab860ff00180142d9e514f3e1b6a91c86df7a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 19 Dec 2014 16:49:00 -0500 Subject: [PATCH 0121/2337] namespace: drop boost::assign altogether here Standard functions are even simpler --- src/test/multisig_tests.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 42a159cda27..69d85221881 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -15,12 +15,10 @@ #include "wallet_ismine.h" #endif -#include #include #include using namespace std; -using namespace boost::assign; typedef vector valtype; @@ -81,22 +79,21 @@ BOOST_AUTO_TEST_CASE(multisig_verify) CScript s; // Test a AND b: - keys.clear(); - keys += key[0],key[1]; // magic operator+= from boost.assign + keys.assign(1,key[0]); + keys.push_back(key[1]); s = sign_multisig(a_and_b, keys, txTo[0], 0); BOOST_CHECK(VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); for (int i = 0; i < 4; i++) { - keys.clear(); - keys += key[i]; + keys.assign(1,key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 1: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); - keys.clear(); - keys += key[1],key[i]; + keys.assign(1,key[1]); + keys.push_back(key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 2: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); @@ -105,8 +102,7 @@ BOOST_AUTO_TEST_CASE(multisig_verify) // Test a OR b: for (int i = 0; i < 4; i++) { - keys.clear(); - keys += key[i]; + keys.assign(1,key[i]); s = sign_multisig(a_or_b, keys, txTo[1], 0); if (i == 0 || i == 1) { @@ -132,8 +128,8 @@ BOOST_AUTO_TEST_CASE(multisig_verify) for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { - keys.clear(); - keys += key[i],key[j]; + keys.assign(1,key[i]); + keys.push_back(key[j]); s = sign_multisig(escrow, keys, txTo[2], 0); if (i < j && i < 3 && j < 3) { From 856e862f4a736fbdc38daae3b7f0fa34e1da317c Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 19 Dec 2014 16:50:15 -0500 Subject: [PATCH 0122/2337] namespace: drop most boost namespaces and a few header cleanups A few boost::asio were left around because they're very wordy otherwise. --- src/bitcoin-tx.cpp | 3 +-- src/chainparams.cpp | 21 ++++++++++----------- src/chainparamsbase.cpp | 4 ---- src/core_read.cpp | 13 ++++++------- src/rpcmisc.cpp | 1 - src/rpcprotocol.cpp | 1 - src/rpcrawtransaction.cpp | 17 ++++++++--------- src/rpcwallet.cpp | 7 +++---- src/test/bloom_tests.cpp | 1 - src/test/script_tests.cpp | 7 ------- src/test/transaction_tests.cpp | 3 +-- 11 files changed, 29 insertions(+), 49 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 05a85810ec2..ead652a7297 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -22,7 +22,6 @@ #include #include -using namespace boost::assign; using namespace std; static bool fCreateBlank; @@ -375,7 +374,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) if (!prevOut.isObject()) throw runtime_error("expected prevtxs internal object"); - map types = map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR); + map types = boost::assign::map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR); if (!prevOut.checkObject(types)) throw runtime_error("prevtxs internal object typecheck fail"); diff --git a/src/chainparams.cpp b/src/chainparams.cpp index f4bc6e1d703..00c2367a6ba 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -14,7 +14,6 @@ #include using namespace std; -using namespace boost::assign; struct SeedSpec6 { uint8_t addr[16]; @@ -158,11 +157,11 @@ public: vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); - base58Prefixes[PUBKEY_ADDRESS] = list_of(0); - base58Prefixes[SCRIPT_ADDRESS] = list_of(5); - base58Prefixes[SECRET_KEY] = list_of(128); - base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x88)(0xB2)(0x1E); - base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x88)(0xAD)(0xE4); + base58Prefixes[PUBKEY_ADDRESS] = boost::assign::list_of(0); + base58Prefixes[SCRIPT_ADDRESS] = boost::assign::list_of(5); + base58Prefixes[SECRET_KEY] = boost::assign::list_of(128); + base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E); + base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4); convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main)); @@ -217,11 +216,11 @@ public: vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me")); vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de")); - base58Prefixes[PUBKEY_ADDRESS] = list_of(111); - base58Prefixes[SCRIPT_ADDRESS] = list_of(196); - base58Prefixes[SECRET_KEY] = list_of(239); - base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x87)(0xCF); - base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x83)(0x94); + base58Prefixes[PUBKEY_ADDRESS] = boost::assign::list_of(111); + base58Prefixes[SCRIPT_ADDRESS] = boost::assign::list_of(196); + base58Prefixes[SECRET_KEY] = boost::assign::list_of(239); + base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF); + base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94); convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test)); diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index e45536ce71f..09fd0df8772 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -9,10 +9,6 @@ #include -#include - -using namespace boost::assign; - /** * Main network */ diff --git a/src/core_read.cpp b/src/core_read.cpp index 85b60e9adba..e064955ff02 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -20,7 +20,6 @@ #include #include -using namespace boost::algorithm; using namespace std; CScript ParseScript(std::string s) @@ -43,13 +42,13 @@ CScript ParseScript(std::string s) string strName(name); mapOpNames[strName] = (opcodetype)op; // Convenience: OP_ADD and just ADD are both recognized: - replace_first(strName, "OP_", ""); + boost::algorithm::replace_first(strName, "OP_", ""); mapOpNames[strName] = (opcodetype)op; } } vector words; - split(words, s, is_any_of(" \t\n"), token_compress_on); + boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on); for (std::vector::const_iterator w = words.begin(); w != words.end(); ++w) { @@ -57,20 +56,20 @@ CScript ParseScript(std::string s) { // Empty string, ignore. (boost::split given '' will return one word) } - else if (all(*w, is_digit()) || - (starts_with(*w, "-") && all(string(w->begin()+1, w->end()), is_digit()))) + else if (all(*w, boost::algorithm::is_digit()) || + (boost::algorithm::starts_with(*w, "-") && all(string(w->begin()+1, w->end()), boost::algorithm::is_digit()))) { // Number int64_t n = atoi64(*w); result << n; } - else if (starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end()))) + else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end()))) { // Raw hex data, inserted NOT pushed onto stack: std::vector raw = ParseHex(string(w->begin()+2, w->end())); result.insert(result.end(), raw.begin(), raw.end()); } - else if (w->size() >= 2 && starts_with(*w, "'") && ends_with(*w, "'")) + else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") && boost::algorithm::ends_with(*w, "'")) { // Single-quoted string, pushed as data. NOTE: this is poor-man's // parsing, spaces/tabs/newlines in single-quoted strings won't work. diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 1013418184c..184aacf5a88 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -23,7 +23,6 @@ #include "json/json_spirit_utils.h" #include "json/json_spirit_value.h" -using namespace boost::assign; using namespace json_spirit; using namespace std; diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index b08598d0bf9..95d6b9e5317 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -26,7 +26,6 @@ #include "json/json_spirit_writer_template.h" using namespace std; -using namespace boost::asio; using namespace json_spirit; //! Number of bytes to allocate and read at most at once in post data diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 35319e4803a..5981134af32 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -25,7 +25,6 @@ #include "json/json_spirit_utils.h" #include "json/json_spirit_value.h" -using namespace boost::assign; using namespace json_spirit; using namespace std; @@ -231,7 +230,7 @@ Value listunspent(const Array& params, bool fHelp) + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") ); - RPCTypeCheck(params, list_of(int_type)(int_type)(array_type)); + RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type)); int nMinDepth = 1; if (params.size() > 0) @@ -335,7 +334,7 @@ Value createrawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"") ); - RPCTypeCheck(params, list_of(array_type)(obj_type)); + RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type)); Array inputs = params[0].get_array(); Object sendTo = params[1].get_obj(); @@ -429,7 +428,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("decoderawtransaction", "\"hexstring\"") ); - RPCTypeCheck(params, list_of(str_type)); + RPCTypeCheck(params, boost::assign::list_of(str_type)); CTransaction tx; @@ -467,7 +466,7 @@ Value decodescript(const Array& params, bool fHelp) + HelpExampleRpc("decodescript", "\"hexstring\"") ); - RPCTypeCheck(params, list_of(str_type)); + RPCTypeCheck(params, boost::assign::list_of(str_type)); Object r; CScript script; @@ -533,7 +532,7 @@ Value signrawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("signrawtransaction", "\"myhex\"") ); - RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true); + RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true); vector txData(ParseHexV(params[0], "argument 1")); CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); @@ -605,7 +604,7 @@ Value signrawtransaction(const Array& params, bool fHelp) Object prevOut = p.get_obj(); - RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); + RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); uint256 txid = ParseHashO(prevOut, "txid"); @@ -633,7 +632,7 @@ Value signrawtransaction(const Array& params, bool fHelp) // if redeemScript given and not using the local wallet (private keys // given), add redeemScript to the tempKeystore so it can be signed: if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { - RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type)); + RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type)); Value v = find_value(prevOut, "redeemScript"); if (!(v == Value::null)) { vector rsData(ParseHexV(v, "redeemScript")); @@ -723,7 +722,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("sendrawtransaction", "\"signedhex\"") ); - RPCTypeCheck(params, list_of(str_type)(bool_type)); + RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type)); // parse hex string from parameter CTransaction tx; diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index a6b38ead624..9d51ff20dd4 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -23,7 +23,6 @@ #include "json/json_spirit_value.h" using namespace std; -using namespace boost::assign; using namespace json_spirit; int64_t nWalletUnlockTime; @@ -1872,9 +1871,9 @@ Value lockunspent(const Array& params, bool fHelp) ); if (params.size() == 1) - RPCTypeCheck(params, list_of(bool_type)); + RPCTypeCheck(params, boost::assign::list_of(bool_type)); else - RPCTypeCheck(params, list_of(bool_type)(array_type)); + RPCTypeCheck(params, boost::assign::list_of(bool_type)(array_type)); bool fUnlock = params[0].get_bool(); @@ -1891,7 +1890,7 @@ Value lockunspent(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); const Object& o = output.get_obj(); - RPCTypeCheck(o, map_list_of("txid", str_type)("vout", int_type)); + RPCTypeCheck(o, boost::assign::map_list_of("txid", str_type)("vout", int_type)); string txid = find_value(o, "txid").get_str(); if (!IsHex(txid)) diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index c32098efa09..98a2cbc92f8 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -20,7 +20,6 @@ #include using namespace std; -using namespace boost::tuples; BOOST_AUTO_TEST_SUITE(bloom_tests) diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 4d2a9aff45c..a5c6a21f4b0 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -23,12 +23,6 @@ #include #include -#include -#include -#include -#include -#include -#include #include #include #include "json/json_spirit_reader_template.h" @@ -37,7 +31,6 @@ using namespace std; using namespace json_spirit; -using namespace boost::algorithm; // Uncomment if you want to output updated JSON tests. // #define UPDATE_JSON_TESTS diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 2594f89ac3e..48386994af5 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -24,7 +24,6 @@ using namespace std; using namespace json_spirit; -using namespace boost::algorithm; // In script_tests.cpp extern Array read_json(const std::string& jsondata); @@ -47,7 +46,7 @@ unsigned int ParseScriptFlags(string strFlags) } unsigned int flags = 0; vector words; - split(words, strFlags, is_any_of(",")); + boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(",")); BOOST_FOREACH(string word, words) { From 4caad26ba1230a26f45f3c0279a24617ec809bab Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 2 Jan 2015 19:31:04 -0500 Subject: [PATCH 0123/2337] depends: bump cctools to a custom version with less deps This one no longer requires native libuuid or libcrypto --- depends/packages/native_cctools.mk | 11 +++++------ depends/packages/native_libuuid.mk | 21 --------------------- depends/packages/native_openssl.mk | 21 --------------------- depends/packages/packages.mk | 2 +- 4 files changed, 6 insertions(+), 49 deletions(-) delete mode 100644 depends/packages/native_libuuid.mk delete mode 100644 depends/packages/native_openssl.mk diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index bf50880e15b..951ad4fb290 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,10 +1,9 @@ package=native_cctools -$(package)_version=59d21d2c793c51d205c8b4ab14b9b28e63c72445 +$(package)_version=ee31ae567931c426136c94aad457c7b51d844beb $(package)_download_path=https://github.com/theuni/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=e13c7129b9d496adf4d674156b4a1d72d8b936f29f377aae8f8b5e7b650cc305 +$(package)_sha256_hash=ef107e6ab1b3994cb22e14f4f5c59ea0c0b5a988e6b21d42ed9616b018bbcbf9 $(package)_build_subdir=cctools -$(package)_dependencies=native_libuuid native_openssl $(package)_clang_version=3.3 $(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version) $(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz @@ -25,8 +24,10 @@ define $(package)_extract_cmds endef define $(package)_set_vars -$(package)_config_opts=--target=$(host) CC=toolchain/clang CXX=toolchain/clang++ +$(package)_config_opts=--target=$(host) --disable-libuuid $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib +$(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang +$(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ endef define $(package)_preprocess_cmds @@ -34,12 +35,10 @@ define $(package)_preprocess_cmds endef define $(package)_config_cmds - export "PATH=$($(package)_extract_dir)/toolchain/bin:$(PATH)" && \ $($(package)_autoconf) endef define $(package)_build_cmds - export "PATH=$($(package)_extract_dir)/toolchain/bin:$(PATH)" && \ $(MAKE) endef diff --git a/depends/packages/native_libuuid.mk b/depends/packages/native_libuuid.mk deleted file mode 100644 index 741eabfe802..00000000000 --- a/depends/packages/native_libuuid.mk +++ /dev/null @@ -1,21 +0,0 @@ -package:=native_libuuid -$(package)_version=1.41.14 -$(package)_download_path=http://downloads.sourceforge.net/e2fsprogs -$(package)_file_name=e2fsprogs-libs-$($(package)_version).tar.gz -$(package)_sha256_hash=dbc7a138a3218d9b80a0626b5b692d76934d6746d8cbb762751be33785d8d9f5 - -define $(package)_set_vars -$(package)_config_opts=--disable-elf-shlibs --disable-uuidd -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C lib/uuid -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) -C lib/uuid install -endef diff --git a/depends/packages/native_openssl.mk b/depends/packages/native_openssl.mk deleted file mode 100644 index 108c6e94428..00000000000 --- a/depends/packages/native_openssl.mk +++ /dev/null @@ -1,21 +0,0 @@ -package=native_openssl -$(package)_version=1.0.1h -$(package)_download_path=https://www.openssl.org/source -$(package)_file_name=openssl-$($(package)_version).tar.gz -$(package)_sha256_hash=9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 -define $(package)_set_vars -$(package)_build_config_opts= --prefix=$(build_prefix) no-zlib no-shared no-krb5C linux-generic64 -endef - -define $(package)_config_cmds - ./Configure $($(package)_build_config_opts) &&\ - sed -i "s|engines apps test|engines|" Makefile -endef - -define $(package)_build_cmds - $(MAKE) -j1 -endef - -define $(package)_stage_cmds - $(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index bbf53cc2dce..08fd8a52478 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -19,5 +19,5 @@ wallet_packages=bdb upnp_packages=miniupnpc ifneq ($(build_os),darwin) -darwin_native_packages=native_libuuid native_openssl native_cctools native_cdrkit native_libdmg-hfsplus +darwin_native_packages=native_cctools native_cdrkit native_libdmg-hfsplus endif From 70477a0bdf6eb6d123ce256f064bbd3bc356c82a Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Sun, 28 Dec 2014 22:39:53 +0100 Subject: [PATCH 0124/2337] On close of splashscreen interrupt verifyDB With the splashscreen being able to be closed it is possible to shutdown during the lengthy verifyDB method. (Takes about a minute on my machine). This change allows us to shutdown much sooner. Github-Pull: #5557 --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index f02a6a12efe..4fcb4f093ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3017,6 +3017,8 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth } else nGoodTransactions += block.vtx.size(); } + if (ShutdownRequested()) + return true; } if (pindexFailure) return error("VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions); From 7eeeac0ff59d4b822bc1f4fcd914572c957834ed Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 3 Jan 2015 15:43:01 +0000 Subject: [PATCH 0125/2337] Remove dead BitcoinUnits::id code and update assets-attribution for non-image unit selector --- doc/assets-attribution.md | 8 +++----- src/qt/bitcoinunits.cpp | 11 ----------- src/qt/bitcoinunits.h | 2 -- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/doc/assets-attribution.md b/doc/assets-attribution.md index 31fe4e5b7a5..c860cdc5349 100644 --- a/doc/assets-attribution.md +++ b/doc/assets-attribution.md @@ -39,9 +39,7 @@ Jonas Schnelli src/qt/res/icons/connect[0-3].png, src/qt/res/icons/eye_minus.png, src/qt/res/icons/eye_plus.png, src/qt/res/icons/verify.png, src/qt/res/icons/tx_inout.png, src/qt/res/icons/tx_input.png, - src/qt/res/icons/unit_btc.png, src/qt/res/icons/unit_mbtc.png, - src/qt/res/icons/unit_ubtc.png, src/qt/res/src/verify.svg - src/qt/res/src/bitcoin.svg, src/qt/res/src/clock*.svg, - src/qt/res/src/connect*.svg, src/qt/res/src/mine.svg, - src/qt/res/src/qt.svg, src/qt/res/src/tx*.svg, + src/qt/res/src/verify.svg, src/qt/res/src/bitcoin.svg, + src/qt/res/src/clock*.svg, src/qt/res/src/connect*.svg, + src/qt/res/src/mine.svg, src/qt/res/src/qt.svg, src/qt/res/src/tx*.svg, src/qt/res/src/verify.svg, diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 758fba70584..425b45d9186 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -36,17 +36,6 @@ bool BitcoinUnits::valid(int unit) } } -QString BitcoinUnits::id(int unit) -{ - switch(unit) - { - case BTC: return QString("btc"); - case mBTC: return QString("mbtc"); - case uBTC: return QString("ubtc"); - default: return QString("???"); - } -} - QString BitcoinUnits::name(int unit) { switch(unit) diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index a01fcc8cf97..1871c33a78b 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -76,8 +76,6 @@ public: static QList availableUnits(); //! Is unit ID valid? static bool valid(int unit); - //! Identifier, e.g. for image names - static QString id(int unit); //! Short name static QString name(int unit); //! Longer description From 02bced16615f072b1d9960e7e5027b6eb4f41384 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 4 Jan 2015 17:15:02 +0100 Subject: [PATCH 0126/2337] Bugfix: only track UTXO modification after lookup Otherwise, if CCoinsViewCache::ModifyCoins throws an exception in between setting hasModifier and constructing the CCoinsModifier, the cache ends up in an inconsistent state, resulting in an assert failure in the next modification. Bug discovered by Wladimir J. van der Laan. --- src/coins.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index bc430c9c7e6..4917de625ca 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -106,7 +106,6 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const { CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { assert(!hasModifier); - hasModifier = true; std::pair ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); if (ret.second) { if (!base->GetCoins(txid, ret.first->second.coins)) { @@ -247,7 +246,10 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const return tx.ComputePriority(dResult); } -CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {} +CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) { + assert(!cache.hasModifier); + cache.hasModifier = true; +} CCoinsModifier::~CCoinsModifier() { From e41345790f1041f5c5e5605d73a0af174769aa55 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 4 Jan 2015 19:11:44 +0100 Subject: [PATCH 0127/2337] Catch LevelDB errors during flush --- src/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 2410230ef43..6bc1cefedee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1807,6 +1807,7 @@ enum FlushStateMode { bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { LOCK(cs_main); static int64_t nLastWrite = 0; + try { if ((mode == FLUSH_STATE_ALWAYS) || ((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) || (mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) { @@ -1846,6 +1847,9 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { } nLastWrite = GetTimeMicros(); } + } catch (const std::runtime_error& e) { + return state.Abort(std::string("System error while flushing: ") + e.what()); + } return true; } From 0ea28baeb8e83a1cc7870090ac20eed9d7ca8539 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Sat, 20 Dec 2014 17:04:21 -0500 Subject: [PATCH 0128/2337] Reject non-final txs even in testnet/regtest Previous behavior with IsFinalTx() being an IsStandard() rule was rather confusing and interferred with testing of protocols that depended on nLockTime. --- src/main.cpp | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index dd71c53d9d3..1ac1e8d5342 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -620,34 +620,11 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) bool IsStandardTx(const CTransaction& tx, string& reason) { - AssertLockHeld(cs_main); if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) { reason = "version"; return false; } - // Treat non-final transactions as non-standard to prevent a specific type - // of double-spend attack, as well as DoS attacks. (if the transaction - // can't be mined, the attacker isn't expending resources broadcasting it) - // Basically we don't want to propagate transactions that can't be included in - // the next block. - // - // However, IsFinalTx() is confusing... Without arguments, it uses - // chainActive.Height() to evaluate nLockTime; when a block is accepted, chainActive.Height() - // is set to the value of nHeight in the block. However, when IsFinalTx() - // is called within CBlock::AcceptBlock(), the height of the block *being* - // evaluated is what is used. Thus if we want to know if a transaction can - // be part of the *next* block, we need to call IsFinalTx() with one more - // than chainActive.Height(). - // - // Timestamps on the other hand don't get any special treatment, because we - // can't know what timestamp the next block will have, and there aren't - // timestamp applications where it matters. - if (!IsFinalTx(tx, chainActive.Height() + 1)) { - reason = "non-final"; - return false; - } - // Extremely large transactions with lots of inputs can cost the network // almost as much to process as they cost the sender in fees, because // computing signature hashes is O(ninputs*txsize). Limiting transactions @@ -936,6 +913,26 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa error("AcceptToMemoryPool : nonstandard transaction: %s", reason), REJECT_NONSTANDARD, reason); + // Only accept nLockTime-using transactions that can be mined in the next + // block; we don't want our mempool filled up with transactions that can't + // be mined yet. + // + // However, IsFinalTx() is confusing... Without arguments, it uses + // chainActive.Height() to evaluate nLockTime; when a block is accepted, + // chainActive.Height() is set to the value of nHeight in the block. + // However, when IsFinalTx() is called within CBlock::AcceptBlock(), the + // height of the block *being* evaluated is what is used. Thus if we want + // to know if a transaction can be part of the *next* block, we need to + // call IsFinalTx() with one more than chainActive.Height(). + // + // Timestamps on the other hand don't get any special treatment, because we + // can't know what timestamp the next block will have, and there aren't + // timestamp applications where it matters. + if (!IsFinalTx(tx, chainActive.Height() + 1)) + return state.DoS(0, + error("AcceptToMemoryPool : non-final"), + REJECT_NONSTANDARD, "non-final"); + // is it already in the memory pool? uint256 hash = tx.GetHash(); if (pool.exists(hash)) From 0cc0d8d60b8aec483a926a94aa7f85b9b0d0aca3 Mon Sep 17 00:00:00 2001 From: jtimon Date: Fri, 10 Oct 2014 11:19:36 +0200 Subject: [PATCH 0129/2337] Get rid of the internal miner's hashmeter --- src/miner.cpp | 42 ++---------------------------------------- src/miner.h | 3 --- src/rpcmining.cpp | 20 -------------------- src/rpcserver.cpp | 1 - src/rpcserver.h | 1 - 5 files changed, 2 insertions(+), 65 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index ad294314212..cf384bb7b5b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -364,8 +364,6 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& // // Internal miner // -double dHashesPerSec = 0.0; -int64_t nHPSTimerStart = 0; // // ScanHash scans nonces looking for a hash with at least some zero bits. @@ -395,10 +393,8 @@ bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phas return true; // If nothing found after trying for a while, return -1 - if ((nNonce & 0xffff) == 0) - return false; if ((nNonce & 0xfff) == 0) - boost::this_thread::interruption_point(); + return false; } } @@ -485,14 +481,9 @@ void static BitcoinMiner(CWallet *pwallet) uint256 hashTarget = uint256().SetCompact(pblock->nBits); uint256 hash; uint32_t nNonce = 0; - uint32_t nOldNonce = 0; while (true) { - bool fFound = ScanHash(pblock, nNonce, &hash); - uint32_t nHashesDone = nNonce - nOldNonce; - nOldNonce = nNonce; - // Check if something found - if (fFound) + if (ScanHash(pblock, nNonce, &hash)) { if (hash <= hashTarget) { @@ -514,35 +505,6 @@ void static BitcoinMiner(CWallet *pwallet) } } - // Meter hashes/sec - static int64_t nHashCounter; - if (nHPSTimerStart == 0) - { - nHPSTimerStart = GetTimeMillis(); - nHashCounter = 0; - } - else - nHashCounter += nHashesDone; - if (GetTimeMillis() - nHPSTimerStart > 4000) - { - static CCriticalSection cs; - { - LOCK(cs); - if (GetTimeMillis() - nHPSTimerStart > 4000) - { - dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart); - nHPSTimerStart = GetTimeMillis(); - nHashCounter = 0; - static int64_t nLogTime; - if (GetTime() - nLogTime > 30 * 60) - { - nLogTime = GetTime(); - LogPrintf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0); - } - } - } - } - // Check for stop or if block needs to be rebuilt boost::this_thread::interruption_point(); // Regtest mode doesn't require peers diff --git a/src/miner.h b/src/miner.h index aede0e6d4b0..53f3b964e1d 100644 --- a/src/miner.h +++ b/src/miner.h @@ -28,7 +28,4 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); -extern double dHashesPerSec; -extern int64_t nHPSTimerStart; - #endif // BITCOIN_MINER_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 45899d3db53..fd66fc78be1 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -201,24 +201,6 @@ Value setgenerate(const Array& params, bool fHelp) return Value::null; } -Value gethashespersec(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "gethashespersec\n" - "\nReturns a recent hashes per second performance measurement while generating.\n" - "See the getgenerate and setgenerate calls to turn generation on and off.\n" - "\nResult:\n" - "n (numeric) The recent hashes per second when generation is on (will return 0 if generation is off)\n" - "\nExamples:\n" - + HelpExampleCli("gethashespersec", "") - + HelpExampleRpc("gethashespersec", "") - ); - - if (GetTimeMillis() - nHPSTimerStart > 8000) - return (int64_t)0; - return (int64_t)dHashesPerSec; -} #endif @@ -237,7 +219,6 @@ Value getmininginfo(const Array& params, bool fHelp) " \"errors\": \"...\" (string) Current errors\n" " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n" " \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n" - " \"hashespersec\": n (numeric) The hashes per second of the generation, or 0 if no generation.\n" " \"pooledtx\": n (numeric) The size of the mem pool\n" " \"testnet\": true|false (boolean) If using testnet or not\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" @@ -260,7 +241,6 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("chain", Params().NetworkIDString())); #ifdef ENABLE_WALLET obj.push_back(Pair("generate", getgenerate(params, false))); - obj.push_back(Pair("hashespersec", gethashespersec(params, false))); #endif return obj; } diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 252b0866a2f..b82a33adccf 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -282,7 +282,6 @@ static const CRPCCommand vRPCCommands[] = #ifdef ENABLE_WALLET /* Coin generation */ { "generating", "getgenerate", &getgenerate, true, false, false }, - { "generating", "gethashespersec", &gethashespersec, true, false, false }, { "generating", "setgenerate", &setgenerate, true, true, false }, #endif diff --git a/src/rpcserver.h b/src/rpcserver.h index 2b2428445d7..08d3501c6e2 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -154,7 +154,6 @@ extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fH extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); From 5d3064bc44e0b608a428e230f384bd3f846dedca Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 10:05:51 +0100 Subject: [PATCH 0130/2337] Temporarily add SetNull/IsNull/GetCheapHash to base_uint Also add a stub for arith_uint256 and its conversion functions, for now completely based on uint256. Eases step-by-step migration to blob. --- src/arith_uint256.h | 19 +++++++++++++++++++ src/uint256.h | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/arith_uint256.h diff --git a/src/arith_uint256.h b/src/arith_uint256.h new file mode 100644 index 00000000000..3bb384ca8ae --- /dev/null +++ b/src/arith_uint256.h @@ -0,0 +1,19 @@ +#ifndef BITCOIN_ARITH_UINT256_H +#define BITCOIN_ARITH_UINT256_H + +// Temporary for migration to opaque uint160/256 +#include "uint256.h" + +class arith_uint256 : public uint256 { +public: + arith_uint256() {} + arith_uint256(const base_uint<256>& b) : uint256(b) {} + arith_uint256(uint64_t b) : uint256(b) {} + explicit arith_uint256(const std::string& str) : uint256(str) {} + explicit arith_uint256(const std::vector& vch) : uint256(vch) {} +}; + +#define ArithToUint256(x) (x) +#define UintToArith256(x) (x) + +#endif // BITCOIN_UINT256_H diff --git a/src/uint256.h b/src/uint256.h index 139270ac498..8189b27cb3c 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -283,6 +283,23 @@ public: { s.read((char*)pn, sizeof(pn)); } + + // Temporary for migration to opaque uint160/256 + uint64_t GetCheapHash() const + { + return GetLow64(); + } + void SetNull() + { + memset(pn, 0, sizeof(pn)); + } + bool IsNull() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } }; /** 160-bit unsigned big integer. */ @@ -330,4 +347,7 @@ public: uint64_t GetHash(const uint256& salt) const; }; +// Temporary for migration to opaque uint160/256 +inline uint256 uint256S(const std::string &x) { return uint256(x); } + #endif // BITCOIN_UINT256_H From 4f1524966a99c83db8c0c9f1ff74789253a1171e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 09:11:16 +0100 Subject: [PATCH 0131/2337] Replace direct use of 0 with SetNull and IsNull Replace x=0 with .SetNull(), x==0 with IsNull(), x!=0 with !IsNull(). Replace uses of uint256(0) with uint256(). --- src/bitcoin-tx.cpp | 4 ++-- src/chain.h | 8 ++++---- src/chainparams.cpp | 2 +- src/coins.cpp | 6 +++--- src/coins.h | 2 +- src/core_write.cpp | 2 +- src/key.cpp | 4 ++-- src/main.cpp | 22 +++++++++++----------- src/merkleblock.cpp | 18 +++++++++--------- src/net.cpp | 2 +- src/primitives/block.cpp | 4 ++-- src/primitives/block.h | 4 ++-- src/primitives/transaction.cpp | 2 +- src/primitives/transaction.h | 4 ++-- src/protocol.cpp | 2 +- src/pubkey.h | 2 +- src/rest.cpp | 2 +- src/rpcblockchain.cpp | 2 +- src/rpcrawtransaction.cpp | 6 +++--- src/rpcwallet.cpp | 4 ++-- src/script/standard.h | 2 +- src/test/pmt_tests.cpp | 6 +++--- src/test/script_P2SH_tests.cpp | 2 +- src/test/sigopcount_tests.cpp | 2 +- src/txdb.cpp | 6 +++--- src/wallet.cpp | 10 +++++----- src/wallet.h | 2 +- src/walletdb.cpp | 4 ++-- 28 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 05a85810ec2..f095551c48e 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -315,7 +315,7 @@ static bool findSighashFlags(int& flags, const string& flagStr) uint256 ParseHashUO(map& o, string strKey) { if (!o.count(strKey)) - return 0; + return uint256(); return ParseHashUV(o[strKey], strKey); } @@ -485,7 +485,7 @@ static void MutateTx(CMutableTransaction& tx, const string& command, static void OutputTxJSON(const CTransaction& tx) { UniValue entry(UniValue::VOBJ); - TxToUniv(tx, 0, entry); + TxToUniv(tx, uint256(), entry); string jsonOutput = entry.write(4); fprintf(stdout, "%s\n", jsonOutput.c_str()); diff --git a/src/chain.h b/src/chain.h index b459c975f82..d7741762c75 100644 --- a/src/chain.h +++ b/src/chain.h @@ -150,14 +150,14 @@ public: nFile = 0; nDataPos = 0; nUndoPos = 0; - nChainWork = 0; + nChainWork = uint256(); nTx = 0; nChainTx = 0; nStatus = 0; nSequenceId = 0; nVersion = 0; - hashMerkleRoot = 0; + hashMerkleRoot = uint256(); nTime = 0; nBits = 0; nNonce = 0; @@ -282,11 +282,11 @@ public: uint256 hashPrev; CDiskBlockIndex() { - hashPrev = 0; + hashPrev = uint256(); } explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { - hashPrev = (pprev ? pprev->GetBlockHash() : 0); + hashPrev = (pprev ? pprev->GetBlockHash() : uint256()); } ADD_SERIALIZE_METHODS; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index f4bc6e1d703..7e76a0bfa2d 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -141,7 +141,7 @@ public: txNew.vout[0].nValue = 50 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; genesis.vtx.push_back(txNew); - genesis.hashPrevBlock = 0; + genesis.hashPrevBlock.SetNull(); genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1231006505; diff --git a/src/coins.cpp b/src/coins.cpp index f4599ff39df..ef4f96fdeec 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -42,7 +42,7 @@ bool CCoins::Spend(uint32_t nPos) bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } -uint256 CCoinsView::GetBestBlock() const { return uint256(0); } +uint256 CCoinsView::GetBestBlock() const { return uint256(); } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; } bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } @@ -57,7 +57,7 @@ bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStat CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} -CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), hashBlock(0) { } +CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false) { } CCoinsViewCache::~CCoinsViewCache() { @@ -128,7 +128,7 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const { } uint256 CCoinsViewCache::GetBestBlock() const { - if (hashBlock == uint256(0)) + if (hashBlock.IsNull()) hashBlock = base->GetBestBlock(); return hashBlock; } diff --git a/src/coins.h b/src/coins.h index 4f1afb00de2..fe2eaa08e52 100644 --- a/src/coins.h +++ b/src/coins.h @@ -297,7 +297,7 @@ struct CCoinsStats uint256 hashSerialized; CAmount nTotalAmount; - CCoinsStats() : nHeight(0), hashBlock(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), hashSerialized(0), nTotalAmount(0) {} + CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {} }; diff --git a/src/core_write.cpp b/src/core_write.cpp index b6fd7fe8773..c3babec2fc0 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -127,7 +127,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) } entry.pushKV("vout", vout); - if (hashBlock != 0) + if (!hashBlock.IsNull()) entry.pushKV("blockhash", hashBlock.GetHex()); entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction". diff --git a/src/key.cpp b/src/key.cpp index f09536fbbe2..50ccb09213c 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -84,7 +84,7 @@ bool CKey::Sign(const uint256 &hash, std::vector& vchSig, uint32_ nonce += test_case; int nSigLen = 72; int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce); - nonce = 0; + nonce = uint256(); if (ret) { vchSig.resize(nSigLen); return true; @@ -116,7 +116,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector& vchSig) uint256 nonce; prng.Generate((unsigned char*)&nonce, 32); int ret = secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, &vchSig[1], begin(), (unsigned char*)&nonce, &rec); - nonce = 0; + nonce = uint256(); if (ret) break; } while(true); diff --git a/src/main.cpp b/src/main.cpp index 4fcb4f093ae..c392138ff38 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -261,7 +261,7 @@ struct CNodeState { nMisbehavior = 0; fShouldBan = false; pindexBestKnownBlock = NULL; - hashLastUnknownBlock = uint256(0); + hashLastUnknownBlock.SetNull(); pindexLastCommonBlock = NULL; fSyncStarted = false; nStallingSince = 0; @@ -349,12 +349,12 @@ void ProcessBlockAvailability(NodeId nodeid) { CNodeState *state = State(nodeid); assert(state != NULL); - if (state->hashLastUnknownBlock != 0) { + if (!state->hashLastUnknownBlock.IsNull()) { BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock); if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) { if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) state->pindexBestKnownBlock = itOld->second; - state->hashLastUnknownBlock = uint256(0); + state->hashLastUnknownBlock.SetNull(); } } } @@ -1712,7 +1712,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return false; // verify that the view's current state corresponds to the previous block - uint256 hashPrevBlock = pindex->pprev == NULL ? uint256(0) : pindex->pprev->GetBlockHash(); + uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash(); assert(hashPrevBlock == view.GetBestBlock()); // Special case for the genesis block, skipping connection of its transactions @@ -2835,7 +2835,7 @@ boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char CBlockIndex * InsertBlockIndex(uint256 hash) { - if (hash == 0) + if (hash.IsNull()) return NULL; // Return existing @@ -3369,7 +3369,7 @@ void static ProcessGetData(CNode* pfrom) vector vInv; vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash())); pfrom->PushMessage("inv", vInv); - pfrom->hashContinue = 0; + pfrom->hashContinue.SetNull(); } } } @@ -3604,7 +3604,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Use deterministic randomness to send to the same nodes for 24 hours // at a time so the setAddrKnowns of the chosen nodes prevent repeats static uint256 hashSalt; - if (hashSalt == 0) + if (hashSalt.IsNull()) hashSalt = GetRandHash(); uint64_t hashAddr = addr.GetHash(); uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)); @@ -3738,7 +3738,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pindex) pindex = chainActive.Next(pindex); int nLimit = 500; - LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop==uint256(0) ? "end" : hashStop.ToString(), nLimit, pfrom->id); + LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id); for (; pindex; pindex = chainActive.Next(pindex)) { if (pindex->GetBlockHash() == hashStop) @@ -3954,7 +3954,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // from there instead. LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); - pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0)); + pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256()); } } @@ -4452,7 +4452,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) nSyncStarted++; CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader; LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight); - pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0)); + pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256()); } } @@ -4483,7 +4483,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) { // 1/4 of tx invs blast to all immediately static uint256 hashSalt; - if (hashSalt == 0) + if (hashSalt.IsNull()) hashSalt = GetRandHash(); uint256 hashRand = inv.hash ^ hashSalt; hashRand = Hash(BEGIN(hashRand), END(hashRand)); diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index f9006d46d59..b51b002b954 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -76,7 +76,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns if (nBitsUsed >= vBits.size()) { // overflowed the bits array - failure fBad = true; - return 0; + return uint256(); } bool fParentOfMatch = vBits[nBitsUsed++]; if (height==0 || !fParentOfMatch) { @@ -84,7 +84,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns if (nHashUsed >= vHash.size()) { // overflowed the hash array - failure fBad = true; - return 0; + return uint256(); } const uint256 &hash = vHash[nHashUsed++]; if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid @@ -128,16 +128,16 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch) { vMatch.clear(); // An empty set will not work if (nTransactions == 0) - return 0; + return uint256(); // check for excessively high numbers of transactions if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction - return 0; + return uint256(); // there can never be more hashes provided than one for every txid if (vHash.size() > nTransactions) - return 0; + return uint256(); // there must be at least one bit per node in the partial tree, and at least one node per hash if (vBits.size() < vHash.size()) - return 0; + return uint256(); // calculate height of tree int nHeight = 0; while (CalcTreeWidth(nHeight) > 1) @@ -147,12 +147,12 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch) { uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); // verify that no problems occured during the tree traversal if (fBad) - return 0; + return uint256(); // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) if ((nBitsUsed+7)/8 != (vBits.size()+7)/8) - return 0; + return uint256(); // verify that all hashes were consumed if (nHashUsed != vHash.size()) - return 0; + return uint256(); return hashMerkleRoot; } diff --git a/src/net.cpp b/src/net.cpp index 6401ecbf83e..05484687142 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1949,7 +1949,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn nRefCount = 0; nSendSize = 0; nSendOffset = 0; - hashContinue = 0; + hashContinue = uint256(); nStartingHeight = -1; fGetAddr = false; fRelayTxes = false; diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 2b6a302ee97..3b4a360395f 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -74,7 +74,7 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const if (fMutated) { *fMutated = mutated; } - return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); + return (vMerkleTree.empty() ? uint256() : vMerkleTree.back()); } std::vector CBlock::GetMerkleBranch(int nIndex) const @@ -96,7 +96,7 @@ std::vector CBlock::GetMerkleBranch(int nIndex) const uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, int nIndex) { if (nIndex == -1) - return 0; + return uint256(); for (std::vector::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it) { if (nIndex & 1) diff --git a/src/primitives/block.h b/src/primitives/block.h index 1449882bd05..53fcd104ad1 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -53,8 +53,8 @@ public: void SetNull() { nVersion = CBlockHeader::CURRENT_VERSION; - hashPrevBlock = 0; - hashMerkleRoot = 0; + hashPrevBlock.SetNull(); + hashMerkleRoot.SetNull(); nTime = 0; nBits = 0; nNonce = 0; diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 230aedd896b..848d4d3e60c 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -72,7 +72,7 @@ void CTransaction::UpdateHash() const *const_cast(&hash) = SerializeHash(*this); } -CTransaction::CTransaction() : hash(0), nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { } +CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { } CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) { UpdateHash(); diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index da350123000..1b5a47e0da9 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -28,8 +28,8 @@ public: READWRITE(FLATDATA(*this)); } - void SetNull() { hash = 0; n = (uint32_t) -1; } - bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); } + void SetNull() { hash.SetNull(); n = (uint32_t) -1; } + bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); } friend bool operator<(const COutPoint& a, const COutPoint& b) { diff --git a/src/protocol.cpp b/src/protocol.cpp index 71c6bd152bb..2dfded43bea 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -96,7 +96,7 @@ void CAddress::Init() CInv::CInv() { type = 0; - hash = 0; + hash.SetNull(); } CInv::CInv(int typeIn, const uint256& hashIn) diff --git a/src/pubkey.h b/src/pubkey.h index 69b73a4e1ce..b0768d4f476 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -27,7 +27,7 @@ class CKeyID : public uint160 { public: - CKeyID() : uint160(0) {} + CKeyID() : uint160() {} CKeyID(const uint160& in) : uint160(in) {} }; diff --git a/src/rest.cpp b/src/rest.cpp index 4702f0d7070..1ee1d529126 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -240,7 +240,7 @@ static bool rest_tx(AcceptedConnection* conn, throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CTransaction tx; - uint256 hashBlock = 0; + uint256 hashBlock = uint256(); if (!GetTransaction(hash, tx, hashBlock, true)) throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 71fb7c8233a..4705c07b8c0 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -70,7 +70,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe if(txDetails) { Object objTx; - TxToJSON(tx, uint256(0), objTx); + TxToJSON(tx, uint256(), objTx); txs.push_back(objTx); } else diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index b87a8baac3c..10dc2ca93e9 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -89,7 +89,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) } entry.push_back(Pair("vout", vout)); - if (hashBlock != 0) { + if (!hashBlock.IsNull()) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { @@ -178,7 +178,7 @@ Value getrawtransaction(const Array& params, bool fHelp) fVerbose = (params[1].get_int() != 0); CTransaction tx; - uint256 hashBlock = 0; + uint256 hashBlock; if (!GetTransaction(hash, tx, hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); @@ -438,7 +438,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); Object result; - TxToJSON(tx, 0, result); + TxToJSON(tx, uint256(), result); return result; } diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index af7e8221cc7..21f6bcae3d7 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1477,7 +1477,7 @@ Value listsinceblock(const Array& params, bool fHelp) if (params.size() > 0) { - uint256 blockId = 0; + uint256 blockId; blockId.SetHex(params[0].get_str()); BlockMap::iterator it = mapBlockIndex.find(blockId); @@ -1510,7 +1510,7 @@ Value listsinceblock(const Array& params, bool fHelp) } CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; - uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : 0; + uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256(); Object ret; ret.push_back(Pair("transactions", transactions)); diff --git a/src/script/standard.h b/src/script/standard.h index 1d29ef57aa8..dbeeace4d9b 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -20,7 +20,7 @@ class CScript; class CScriptID : public uint160 { public: - CScriptID() : uint160(0) {} + CScriptID() : uint160() {} CScriptID(const CScript& in); CScriptID(const uint160& in) : uint160(in) {} }; diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 56e05416646..af3d90f2eb1 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) // calculate actual merkle root and height uint256 merkleRoot1 = block.BuildMerkleTree(); - std::vector vTxid(nTx, 0); + std::vector vTxid(nTx, uint256()); for (unsigned int j=0; j vTxid2; - BOOST_CHECK(tree.ExtractMatches(vTxid) == 0); + BOOST_CHECK(tree.ExtractMatches(vTxid).IsNull()); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 63553556ec0..77e70022df9 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(set) BOOST_AUTO_TEST_CASE(is) { // Test CScript::IsPayToScriptHash() - uint160 dummy(0); + uint160 dummy; CScript p2sh; p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL; BOOST_CHECK(p2sh.IsPayToScriptHash()); diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 3326601492a..3c8264d89d1 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount) BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U); BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U); - uint160 dummy(0); + uint160 dummy; s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U); s1 << OP_IF << OP_CHECKSIG << OP_ENDIF; diff --git a/src/txdb.cpp b/src/txdb.cpp index 5096ab19a5d..4467cdce707 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -39,7 +39,7 @@ bool CCoinsViewDB::HaveCoins(const uint256 &txid) const { uint256 CCoinsViewDB::GetBestBlock() const { uint256 hashBestChain; if (!db.Read('B', hashBestChain)) - return uint256(0); + return uint256(); return hashBestChain; } @@ -56,7 +56,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { CCoinsMap::iterator itOld = it++; mapCoins.erase(itOld); } - if (hashBlock != uint256(0)) + if (!hashBlock.IsNull()) BatchWriteHashBestChain(batch, hashBlock); LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); @@ -179,7 +179,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() boost::scoped_ptr pcursor(NewIterator()); CDataStream ssKeySet(SER_DISK, CLIENT_VERSION); - ssKeySet << make_pair('b', uint256(0)); + ssKeySet << make_pair('b', uint256()); pcursor->Seek(ssKeySet.str()); // Load mapBlockIndex diff --git a/src/wallet.cpp b/src/wallet.cpp index 4920cb21fc0..6c5af3bdc7d 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -579,7 +579,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) wtx.nOrderPos = IncOrderPosNext(); wtx.nTimeSmart = wtx.nTimeReceived; - if (wtxIn.hashBlock != 0) + if (!wtxIn.hashBlock.IsNull()) { if (mapBlockIndex.count(wtxIn.hashBlock)) { @@ -630,7 +630,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) if (!fInsertedNew) { // Merge - if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) + if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock) { wtx.hashBlock = wtxIn.hashBlock; fUpdated = true; @@ -795,7 +795,7 @@ int CWalletTx::GetRequestCount() const if (IsCoinBase()) { // Generated block - if (hashBlock != 0) + if (!hashBlock.IsNull()) { map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -811,7 +811,7 @@ int CWalletTx::GetRequestCount() const nRequests = (*mi).second; // How about the block it's in? - if (nRequests == 0 && hashBlock != 0) + if (nRequests == 0 && !hashBlock.IsNull()) { map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -2317,7 +2317,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const { - if (hashBlock == 0 || nIndex == -1) + if (hashBlock.IsNull() || nIndex == -1) return 0; AssertLockHeld(cs_main); diff --git a/src/wallet.h b/src/wallet.h index 4d95d0ae2e7..1d0dc97c6cf 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -519,7 +519,7 @@ public: void Init() { - hashBlock = 0; + hashBlock = uint256(); nIndex = -1; fMerkleVerified = false; } diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 4fd7eb512b9..0ec83e7b323 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -439,7 +439,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } CKey key; CPrivKey pkey; - uint256 hash = 0; + uint256 hash; if (strType == "key") { @@ -464,7 +464,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, bool fSkipCheck = false; - if (hash != 0) + if (!hash.IsNull()) { // hash pubkey/privkey to accelerate wallet load std::vector vchKey; From 807658549c61d1fb0da3138ea0ca749ecba61723 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 09:12:11 +0100 Subject: [PATCH 0132/2337] Replace GetLow64 with GetCheapHash --- src/addrman.cpp | 8 ++++---- src/main.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 1982db52ae3..1e08ae772ea 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -15,12 +15,12 @@ int CAddrInfo::GetTriedBucket(const std::vector& nKey) const CDataStream ss1(SER_GETHASH, 0); std::vector vchKey = GetKey(); ss1 << nKey << vchKey; - uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64(); + uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); CDataStream ss2(SER_GETHASH, 0); std::vector vchGroupKey = GetGroup(); ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); - uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64(); + uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; } @@ -30,11 +30,11 @@ int CAddrInfo::GetNewBucket(const std::vector& nKey, const CNetAd std::vector vchGroupKey = GetGroup(); std::vector vchSourceGroupKey = src.GetGroup(); ss1 << nKey << vchGroupKey << vchSourceGroupKey; - uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64(); + uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); CDataStream ss2(SER_GETHASH, 0); ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); - uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64(); + uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); return hash2 % ADDRMAN_NEW_BUCKET_COUNT; } diff --git a/src/main.h b/src/main.h index 9049f5bb7d4..1e00114768d 100644 --- a/src/main.h +++ b/src/main.h @@ -106,7 +106,7 @@ static const unsigned char REJECT_CHECKPOINT = 0x43; struct BlockHasher { - size_t operator()(const uint256& hash) const { return hash.GetLow64(); } + size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } }; extern CScript COINBASE_FLAGS; From 2eae3157f65197109d7745ea3926d086de812f7b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 09:17:25 +0100 Subject: [PATCH 0133/2337] Replace uint256(1) with static constant SignatureHash and its test function SignatureHashOld return uint256(1) as a special error signaling value. Return a local static constant with the same value instead. --- src/script/interpreter.cpp | 5 +++-- src/test/sighash_tests.cpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 80a32e78f90..7f8b371d605 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1030,16 +1030,17 @@ public: uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { + static const uint256 one("0000000000000000000000000000000000000000000000000000000000000001"); if (nIn >= txTo.vin.size()) { // nIn out of range - return 1; + return one; } // Check for invalid use of SIGHASH_SINGLE if ((nHashType & 0x1f) == SIGHASH_SINGLE) { if (nIn >= txTo.vout.size()) { // nOut out of range - return 1; + return one; } } diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index a9d2f9e8cad..036f70ec0f6 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -24,10 +24,11 @@ extern Array read_json(const std::string& jsondata); // Old script.cpp SignatureHash function uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { + static const uint256 one("0000000000000000000000000000000000000000000000000000000000000001"); if (nIn >= txTo.vin.size()) { printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); - return 1; + return one; } CMutableTransaction txTmp(txTo); @@ -58,7 +59,7 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un if (nOut >= txTmp.vout.size()) { printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); - return 1; + return one; } txTmp.vout.resize(nOut+1); for (unsigned int i = 0; i < nOut; i++) From 34cdc41128eee5da0be9c5e17b3c24b1f91a1957 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 14:50:05 +0100 Subject: [PATCH 0134/2337] String conversions uint256 -> uint256S If uint256() constructor takes a string, uint256(0) will become dangerous when uint256 does not take integers anymore (it will go through std::string(const char*) making a NULL string, and the explicit keyword is no help). --- src/bitcoin-tx.cpp | 2 +- src/chainparams.cpp | 38 +++++++++++----------- src/main.cpp | 4 +-- src/qt/coincontroldialog.cpp | 8 ++--- src/rpcblockchain.cpp | 8 ++--- src/rpcwallet.cpp | 2 +- src/script/interpreter.cpp | 2 +- src/test/Checkpoints_tests.cpp | 4 +-- src/test/bloom_tests.cpp | 58 +++++++++++++++++----------------- src/test/sighash_tests.cpp | 2 +- src/test/transaction_tests.cpp | 4 +-- 11 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index f095551c48e..e9dac9ffb95 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -191,7 +191,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput) string strTxid = strInput.substr(0, pos); if ((strTxid.size() != 64) || !IsHex(strTxid)) throw runtime_error("invalid TX input txid"); - uint256 txid(strTxid); + uint256 txid(uint256S(strTxid)); static const unsigned int minTxOutSz = 9; static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 7e76a0bfa2d..844640061e8 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -54,19 +54,19 @@ static void convertSeed6(std::vector &vSeedsOut, const SeedSpec6 *data */ static Checkpoints::MapCheckpoints mapCheckpoints = boost::assign::map_list_of - ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) - ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) - ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) - (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) - (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) - (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")) - (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) - (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) - (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) - (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) - (250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) - (279000, uint256("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) - (295000, uint256("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")) + ( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) + ( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) + ( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) + (105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) + (134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) + (168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")) + (193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) + (210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) + (216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) + (225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) + (250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) + (279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) + (295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")) ; static const Checkpoints::CCheckpointData data = { &mapCheckpoints, @@ -78,7 +78,7 @@ static const Checkpoints::CCheckpointData data = { static Checkpoints::MapCheckpoints mapCheckpointsTestnet = boost::assign::map_list_of - ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) + ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) ; static const Checkpoints::CCheckpointData dataTestnet = { &mapCheckpointsTestnet, @@ -89,7 +89,7 @@ static const Checkpoints::CCheckpointData dataTestnet = { static Checkpoints::MapCheckpoints mapCheckpointsRegtest = boost::assign::map_list_of - ( 0, uint256("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")) + ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")) ; static const Checkpoints::CCheckpointData dataRegtest = { &mapCheckpointsRegtest, @@ -149,8 +149,8 @@ public: genesis.nNonce = 2083236893; hashGenesisBlock = genesis.GetHash(); - assert(hashGenesisBlock == uint256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); - assert(genesis.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); + assert(hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); + assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be")); vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); @@ -208,7 +208,7 @@ public: genesis.nTime = 1296688602; genesis.nNonce = 414098458; hashGenesisBlock = genesis.GetHash(); - assert(hashGenesisBlock == uint256("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); + assert(hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); vFixedSeeds.clear(); vSeeds.clear(); @@ -265,7 +265,7 @@ public: genesis.nNonce = 2; hashGenesisBlock = genesis.GetHash(); nDefaultPort = 18444; - assert(hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); + assert(hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. diff --git a/src/main.cpp b/src/main.cpp index c392138ff38..77d2dcb2048 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1738,8 +1738,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // two in the chain that violate it. This prevents exploiting the issue against nodes in their // initial block download. bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash. - !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) || - (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); + !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) || + (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); if (fEnforceBIP30) { BOOST_FOREACH(const CTransaction& tx, block.vtx) { const CCoins* coins = view.AccessCoins(tx.GetHash()); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 60e7d62a7a7..8422f316f98 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -213,7 +213,7 @@ void CoinControlDialog::showMenu(const QPoint &point) if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode) { copyTransactionHashAction->setEnabled(true); - if (model->isLockedCoin(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt())) + if (model->isLockedCoin(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt())) { lockAction->setEnabled(false); unlockAction->setEnabled(true); @@ -272,7 +272,7 @@ void CoinControlDialog::lockCoin() if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked) contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); - COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); + COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); model->lockCoin(outpt); contextMenuItem->setDisabled(true); contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); @@ -282,7 +282,7 @@ void CoinControlDialog::lockCoin() // context menu action: unlock coin void CoinControlDialog::unlockCoin() { - COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); + COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); model->unlockCoin(outpt); contextMenuItem->setDisabled(false); contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon()); @@ -388,7 +388,7 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) { if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode) { - COutPoint outpt(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()); + COutPoint outpt(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()); if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked) coinControl->UnSelect(outpt); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 4705c07b8c0..cfc559d1986 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -278,7 +278,7 @@ Value getblock(const Array& params, bool fHelp) ); std::string strHash = params[0].get_str(); - uint256 hash(strHash); + uint256 hash(uint256S(strHash)); bool fVerbose = true; if (params.size() > 1) @@ -383,7 +383,7 @@ Value gettxout(const Array& params, bool fHelp) Object ret; std::string strHash = params[0].get_str(); - uint256 hash(strHash); + uint256 hash(uint256S(strHash)); int n = params[1].get_int(); bool fMempool = true; if (params.size() > 2) @@ -619,7 +619,7 @@ Value invalidateblock(const Array& params, bool fHelp) ); std::string strHash = params[0].get_str(); - uint256 hash(strHash); + uint256 hash(uint256S(strHash)); CValidationState state; { @@ -658,7 +658,7 @@ Value reconsiderblock(const Array& params, bool fHelp) ); std::string strHash = params[0].get_str(); - uint256 hash(strHash); + uint256 hash(uint256S(strHash)); CValidationState state; { diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 21f6bcae3d7..470a48e4fb4 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1902,7 +1902,7 @@ Value lockunspent(const Array& params, bool fHelp) if (nOutput < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); - COutPoint outpt(uint256(txid), nOutput); + COutPoint outpt(uint256S(txid), nOutput); if (fUnlock) pwalletMain->UnlockCoin(outpt); diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 7f8b371d605..e979f61f6e7 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1030,7 +1030,7 @@ public: uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { - static const uint256 one("0000000000000000000000000000000000000000000000000000000000000001"); + static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); if (nIn >= txTo.vin.size()) { // nIn out of range return one; diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 4ea6a91d543..a9b6cd44a87 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -18,8 +18,8 @@ BOOST_AUTO_TEST_SUITE(Checkpoints_tests) BOOST_AUTO_TEST_CASE(sanity) { - uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"); - uint256 p134444 = uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"); + uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"); + uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"); BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111)); BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444)); diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index c32098efa09..f9cbcb0d9e5 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE(bloom_match) spendStream >> spendingTx; CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(uint256("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b")); + filter.insert(uint256S("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b")); BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match tx hash"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); @@ -151,11 +151,11 @@ BOOST_AUTO_TEST_CASE(bloom_match) BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0)); + filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0)); BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match COutPoint"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - COutPoint prevOutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0); + COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0); { vector data(32 + sizeof(unsigned int)); memcpy(&data[0], prevOutPoint.hash.begin(), 32); @@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(bloom_match) BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized COutPoint"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(uint256("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436")); + filter.insert(uint256S("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436")); BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random tx hash"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); @@ -173,11 +173,11 @@ BOOST_AUTO_TEST_CASE(bloom_match) BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random address"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1)); + filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1)); BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(COutPoint(uint256("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0)); + filter.insert(COutPoint(uint256S("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0)); BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about"); } @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); // Match the last transaction - filter.insert(uint256("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); + filter.insert(uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8); vector vMatched; @@ -209,7 +209,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); // Also match the 8th transaction - filter.insert(uint256("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); + filter.insert(uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); merkleBlock = CMerkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair); - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); // Match the first transaction - filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); + filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); vector vMatched; @@ -265,13 +265,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]); - BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")); + BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")); BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2")); + BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2")); BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2); - BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); + BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); @@ -290,7 +290,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE); // Match the first transaction - filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); + filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); vector vMatched; @@ -319,10 +319,10 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]); - BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")); + BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")); BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); + BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); @@ -341,14 +341,14 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); // Match the only transaction - filter.insert(uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); + filter.insert(uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); vector vMatched; @@ -379,7 +379,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); // Match the last transaction - filter.insert(uint256("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); + filter.insert(uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -387,7 +387,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6); vector vMatched; @@ -397,13 +397,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); // Also match the 4th transaction - filter.insert(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041")); + filter.insert(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041")); merkleBlock = CMerkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2); - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3); BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair); @@ -432,9 +432,9 @@ BOOST_AUTO_TEST_CASE(merkle_block_4_test_p2pubkey_only) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); // We should match the generation outpoint - BOOST_CHECK(filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0))); + BOOST_CHECK(filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0))); // ... but not the 4th transaction's output (its not pay-2-pubkey) - BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0))); + BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0))); } BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none) @@ -455,8 +455,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); // We shouldn't match any outpoints (UPDATE_NONE) - BOOST_CHECK(!filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0))); - BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0))); + BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0))); + BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0))); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 036f70ec0f6..662f765a0bd 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -24,7 +24,7 @@ extern Array read_json(const std::string& jsondata); // Old script.cpp SignatureHash function uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { - static const uint256 one("0000000000000000000000000000000000000000000000000000000000000001"); + static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); if (nIn >= txTo.vin.size()) { printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 2594f89ac3e..efa2af917e6 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) break; } - mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); + mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); } if (!fValid) { @@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) break; } - mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); + mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); } if (!fValid) { From 734f85c4f0b40efd3f6c0367683c1bab1a2a7b19 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 15:43:03 +0100 Subject: [PATCH 0135/2337] Use arith_uint256 where necessary Also add conversion from/to uint256 where needed. --- src/chain.h | 5 +++-- src/chainparams.cpp | 4 ++-- src/chainparams.h | 6 +++--- src/key.cpp | 3 ++- src/main.cpp | 9 +++++---- src/miner.cpp | 4 ++-- src/pow.cpp | 15 ++++++++------- src/pow.h | 3 ++- src/rpcmining.cpp | 4 ++-- src/test/pmt_tests.cpp | 12 +++++++++--- src/test/skiplist_tests.cpp | 12 ++++++------ 11 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/chain.h b/src/chain.h index d7741762c75..004e87ab527 100644 --- a/src/chain.h +++ b/src/chain.h @@ -6,6 +6,7 @@ #ifndef BITCOIN_CHAIN_H #define BITCOIN_CHAIN_H +#include "arith_uint256.h" #include "primitives/block.h" #include "pow.h" #include "tinyformat.h" @@ -117,7 +118,7 @@ public: unsigned int nUndoPos; //! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block - uint256 nChainWork; + arith_uint256 nChainWork; //! Number of transactions in this block. //! Note: in a potential headers-first mode, this number cannot be relied upon @@ -150,7 +151,7 @@ public: nFile = 0; nDataPos = 0; nUndoPos = 0; - nChainWork = uint256(); + nChainWork = arith_uint256(); nTx = 0; nChainTx = 0; nStatus = 0; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 844640061e8..3abc569dcd7 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -114,7 +114,7 @@ public: pchMessageStart[3] = 0xd9; vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 8333; - bnProofOfWorkLimit = ~uint256(0) >> 32; + bnProofOfWorkLimit = ~arith_uint256(0) >> 32; nSubsidyHalvingInterval = 210000; nEnforceBlockUpgradeMajority = 750; nRejectBlockOutdatedMajority = 950; @@ -259,7 +259,7 @@ public: nMinerThreads = 1; nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks nTargetSpacing = 10 * 60; - bnProofOfWorkLimit = ~uint256(0) >> 1; + bnProofOfWorkLimit = ~arith_uint256(0) >> 1; genesis.nTime = 1296688602; genesis.nBits = 0x207fffff; genesis.nNonce = 2; diff --git a/src/chainparams.h b/src/chainparams.h index 60c7b475856..f1ef6a11f19 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -10,7 +10,7 @@ #include "checkpoints.h" #include "primitives/block.h" #include "protocol.h" -#include "uint256.h" +#include "arith_uint256.h" #include @@ -45,7 +45,7 @@ public: const MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } + const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; } /** Used to check majorities for block version upgrade */ int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; } @@ -87,7 +87,7 @@ protected: //! Raw pub key bytes for the broadcast alert signing key. std::vector vAlertPubKey; int nDefaultPort; - uint256 bnProofOfWorkLimit; + arith_uint256 bnProofOfWorkLimit; int nSubsidyHalvingInterval; int nEnforceBlockUpgradeMajority; int nRejectBlockOutdatedMajority; diff --git a/src/key.cpp b/src/key.cpp index 50ccb09213c..2235c271d18 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -4,6 +4,7 @@ #include "key.h" +#include "arith_uint256.h" #include "crypto/hmac_sha512.h" #include "crypto/rfc6979_hmac_sha256.h" #include "eccryptoverify.h" @@ -81,7 +82,7 @@ bool CKey::Sign(const uint256 &hash, std::vector& vchSig, uint32_ do { uint256 nonce; prng.Generate((unsigned char*)&nonce, 32); - nonce += test_case; + nonce = ArithToUint256(UintToArith256(nonce) + test_case); int nSigLen = 72; int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce); nonce = uint256(); diff --git a/src/main.cpp b/src/main.cpp index 77d2dcb2048..d115f763f66 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include "main.h" +#include "arith_uint256.h" #include "addrman.h" #include "alert.h" #include "chainparams.h" @@ -3607,7 +3608,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (hashSalt.IsNull()) hashSalt = GetRandHash(); uint64_t hashAddr = addr.GetHash(); - uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)); + uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60))); hashRand = Hash(BEGIN(hashRand), END(hashRand)); multimap mapMix; BOOST_FOREACH(CNode* pnode, vNodes) @@ -3616,7 +3617,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, continue; unsigned int nPointer; memcpy(&nPointer, &pnode, sizeof(nPointer)); - uint256 hashKey = hashRand ^ nPointer; + uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer); hashKey = Hash(BEGIN(hashKey), END(hashKey)); mapMix.insert(make_pair(hashKey, pnode)); } @@ -4485,9 +4486,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle) static uint256 hashSalt; if (hashSalt.IsNull()) hashSalt = GetRandHash(); - uint256 hashRand = inv.hash ^ hashSalt; + uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt)); hashRand = Hash(BEGIN(hashRand), END(hashRand)); - bool fTrickleWait = ((hashRand & 3) != 0); + bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0); if (fTrickleWait) { diff --git a/src/miner.cpp b/src/miner.cpp index 3bd2a9a41fc..87cb158333e 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -481,7 +481,7 @@ void static BitcoinMiner(CWallet *pwallet) // Search // int64_t nStart = GetTime(); - uint256 hashTarget = uint256().SetCompact(pblock->nBits); + arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); uint256 hash; uint32_t nNonce = 0; uint32_t nOldNonce = 0; @@ -493,7 +493,7 @@ void static BitcoinMiner(CWallet *pwallet) // Check if something found if (fFound) { - if (hash <= hashTarget) + if (UintToArith256(hash) <= hashTarget) { // Found a solution pblock->nNonce = nNonce; diff --git a/src/pow.cpp b/src/pow.cpp index e91e3d893c3..90bbff0a33a 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -5,6 +5,7 @@ #include "pow.h" +#include "arith_uint256.h" #include "chain.h" #include "chainparams.h" #include "primitives/block.h" @@ -56,8 +57,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead nActualTimespan = Params().TargetTimespan()*4; // Retarget - uint256 bnNew; - uint256 bnOld; + arith_uint256 bnNew; + arith_uint256 bnOld; bnNew.SetCompact(pindexLast->nBits); bnOld = bnNew; bnNew *= nActualTimespan; @@ -79,7 +80,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) { bool fNegative; bool fOverflow; - uint256 bnTarget; + arith_uint256 bnTarget; if (Params().SkipProofOfWorkCheck()) return true; @@ -91,22 +92,22 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) return error("CheckProofOfWork() : nBits below minimum work"); // Check proof of work matches claimed amount - if (hash > bnTarget) + if (UintToArith256(hash) > bnTarget) return error("CheckProofOfWork() : hash doesn't match nBits"); return true; } -uint256 GetBlockProof(const CBlockIndex& block) +arith_uint256 GetBlockProof(const CBlockIndex& block) { - uint256 bnTarget; + arith_uint256 bnTarget; bool fNegative; bool fOverflow; bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); if (fNegative || fOverflow || bnTarget == 0) return 0; // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 - // as it's too large for a uint256. However, as 2**256 is at least as large + // as it's too large for a arith_uint256. However, as 2**256 is at least as large // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, // or ~bnTarget / (nTarget+1) + 1. return (~bnTarget / (bnTarget + 1)) + 1; diff --git a/src/pow.h b/src/pow.h index 89b219f808f..3337a30a5e8 100644 --- a/src/pow.h +++ b/src/pow.h @@ -11,11 +11,12 @@ class CBlockHeader; class CBlockIndex; class uint256; +class arith_uint256; unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits); -uint256 GetBlockProof(const CBlockIndex& block); +arith_uint256 GetBlockProof(const CBlockIndex& block); #endif // BITCOIN_POW_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 35760f9af08..603e2935dd9 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -64,7 +64,7 @@ Value GetNetworkHashPS(int lookup, int height) { if (minTime == maxTime) return 0; - uint256 workDiff = pb->nChainWork - pb0->nChainWork; + arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork; int64_t timeDiff = maxTime - minTime; return (int64_t)(workDiff.getdouble() / timeDiff); @@ -562,7 +562,7 @@ Value getblocktemplate(const Array& params, bool fHelp) Object aux; aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); - uint256 hashTarget = uint256().SetCompact(pblock->nBits); + arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); static Array aMutable; if (aMutable.empty()) diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index af3d90f2eb1..372cf3b306e 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -6,6 +6,7 @@ #include "serialize.h" #include "streams.h" #include "uint256.h" +#include "arith_uint256.h" #include "version.h" #include @@ -22,8 +23,7 @@ public: void Damage() { unsigned int n = rand() % vHash.size(); int bit = rand() % 256; - uint256 &hash = vHash[n]; - hash ^= ((uint256)1 << bit); + *(vHash[n].begin() + (bit>>3)) ^= 1<<(bit&7); } }; @@ -107,7 +107,13 @@ BOOST_AUTO_TEST_CASE(pmt_test1) BOOST_AUTO_TEST_CASE(pmt_malleability) { - std::vector vTxid = boost::assign::list_of(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(9)(10); + std::vector vTxid = boost::assign::list_of + (ArithToUint256(1))(ArithToUint256(2)) + (ArithToUint256(3))(ArithToUint256(4)) + (ArithToUint256(5))(ArithToUint256(6)) + (ArithToUint256(7))(ArithToUint256(8)) + (ArithToUint256(9))(ArithToUint256(10)) + (ArithToUint256(9))(ArithToUint256(10)); std::vector vMatch = boost::assign::list_of(false)(false)(false)(false)(false)(false)(false)(false)(false)(true)(true)(false); CPartialMerkleTree tree(vTxid, vMatch); diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index 646c7e6aded..c75e21a2adf 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -49,12 +49,12 @@ BOOST_AUTO_TEST_CASE(getlocator_test) std::vector vHashMain(100000); std::vector vBlocksMain(100000); for (unsigned int i=0; inHeight + 1); } @@ -62,12 +62,12 @@ BOOST_AUTO_TEST_CASE(getlocator_test) std::vector vHashSide(50000); std::vector vBlocksSide(50000); for (unsigned int i=0; inHeight + 1); } @@ -87,13 +87,13 @@ BOOST_AUTO_TEST_CASE(getlocator_test) // Entries 1 through 11 (inclusive) go back one step each. for (unsigned int i = 1; i < 12 && i < locator.vHave.size() - 1; i++) { - BOOST_CHECK_EQUAL(locator.vHave[i].GetLow64(), tip->nHeight - i); + BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i]).GetLow64(), tip->nHeight - i); } // The further ones (excluding the last one) go back with exponential steps. unsigned int dist = 2; for (unsigned int i = 12; i < locator.vHave.size() - 1; i++) { - BOOST_CHECK_EQUAL(locator.vHave[i - 1].GetLow64() - locator.vHave[i].GetLow64(), dist); + BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i - 1]).GetLow64() - UintToArith256(locator.vHave[i]).GetLow64(), dist); dist *= 2; } } From bfc6070342b9f43bcf125526e6a3c8ed34e29a71 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 10:22:19 +0100 Subject: [PATCH 0136/2337] uint256->arith_uint256 blob256->uint256 Introduce new opaque implementation of `uint256`, move old "arithmetic" implementation to `arith_uint256. --- src/Makefile.am | 31 +- src/Makefile.test.include | 2 +- src/arith_uint256.cpp | 357 ++++++++++++++++++ src/arith_uint256.h | 351 ++++++++++++++++- ...t256_tests.cpp => arith_uint256_tests.cpp} | 331 ++++++++-------- src/uint256.cpp | 281 ++------------ src/uint256.h | 343 ++++------------- 7 files changed, 990 insertions(+), 706 deletions(-) create mode 100644 src/arith_uint256.cpp rename src/test/{uint256_tests.cpp => arith_uint256_tests.cpp} (75%) diff --git a/src/Makefile.am b/src/Makefile.am index d6ac6e12776..bc2b1aff963 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -74,11 +74,12 @@ BITCOIN_CORE_H = \ alert.h \ allocators.h \ amount.h \ + arith_uint256.h \ base58.h \ bloom.h \ chain.h \ - chainparams.h \ chainparamsbase.h \ + chainparams.h \ chainparamsseeds.h \ checkpoints.h \ checkqueue.h \ @@ -87,8 +88,6 @@ BITCOIN_CORE_H = \ coins.h \ compat.h \ compressor.h \ - primitives/block.h \ - primitives/transaction.h \ core_io.h \ crypter.h \ db.h \ @@ -108,6 +107,8 @@ BITCOIN_CORE_H = \ net.h \ noui.h \ pow.h \ + primitives/block.h \ + primitives/transaction.h \ protocol.h \ pubkey.h \ random.h \ @@ -115,11 +116,11 @@ BITCOIN_CORE_H = \ rpcprotocol.h \ rpcserver.h \ script/interpreter.h \ + script/script_error.h \ script/script.h \ script/sigcache.h \ script/sign.h \ script/standard.h \ - script/script_error.h \ serialize.h \ streams.h \ sync.h \ @@ -132,13 +133,13 @@ BITCOIN_CORE_H = \ uint256.h \ undo.h \ util.h \ - utilstrencodings.h \ utilmoneystr.h \ + utilstrencodings.h \ utiltime.h \ version.h \ + walletdb.h \ wallet.h \ wallet_ismine.h \ - walletdb.h \ compat/sanity.h JSON_H = \ @@ -261,18 +262,19 @@ libbitcoin_common_a_SOURCES = \ # backward-compatibility objects and their sanity checks are linked. libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_util_a_SOURCES = \ - compat/strnlen.cpp \ - compat/glibc_sanity.cpp \ - compat/glibcxx_sanity.cpp \ + arith_uint256.cpp \ chainparamsbase.cpp \ clientversion.cpp \ + compat/glibc_sanity.cpp \ + compat/glibcxx_sanity.cpp \ + compat/strnlen.cpp \ random.cpp \ rpcprotocol.cpp \ sync.cpp \ uint256.cpp \ util.cpp \ - utilstrencodings.cpp \ utilmoneystr.cpp \ + utilstrencodings.cpp \ utiltime.cpp \ $(BITCOIN_CORE_H) @@ -352,19 +354,20 @@ bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if BUILD_BITCOIN_LIBS include_HEADERS = script/bitcoinconsensus.h libbitcoinconsensus_la_SOURCES = \ - primitives/transaction.cpp \ + arith_uint256.cpp \ crypto/hmac_sha512.cpp \ + crypto/ripemd160.cpp \ crypto/sha1.cpp \ crypto/sha256.cpp \ crypto/sha512.cpp \ - crypto/ripemd160.cpp \ eccryptoverify.cpp \ ecwrapper.cpp \ hash.cpp \ + primitives/transaction.cpp \ pubkey.cpp \ - script/script.cpp \ - script/interpreter.cpp \ script/bitcoinconsensus.cpp \ + script/interpreter.cpp \ + script/script.cpp \ uint256.cpp \ utilstrencodings.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 5f388e28063..21d91acc6a7 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -34,6 +34,7 @@ RAW_TEST_FILES = test/data/alertTests.raw GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h) BITCOIN_TESTS =\ + test/arith_uint256_tests.cpp \ test/bignum.h \ test/alert_tests.cpp \ test/allocator_tests.cpp \ @@ -67,7 +68,6 @@ BITCOIN_TESTS =\ test/test_bitcoin.cpp \ test/timedata_tests.cpp \ test/transaction_tests.cpp \ - test/uint256_tests.cpp \ test/univalue_tests.cpp \ test/util_tests.cpp diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp new file mode 100644 index 00000000000..0dba429a8d5 --- /dev/null +++ b/src/arith_uint256.cpp @@ -0,0 +1,357 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "arith_uint256.h" + +#include "utilstrencodings.h" + +#include +#include + +template +base_uint::base_uint(const std::string& str) +{ + SetHex(str); +} + +template +base_uint::base_uint(const std::vector& vch) +{ + if (vch.size() != sizeof(pn)) + throw uint_error("Converting vector of wrong size to base_uint"); + memcpy(pn, &vch[0], sizeof(pn)); +} + +template +base_uint& base_uint::operator<<=(unsigned int shift) +{ + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) { + if (i + k + 1 < WIDTH && shift != 0) + pn[i + k + 1] |= (a.pn[i] >> (32 - shift)); + if (i + k < WIDTH) + pn[i + k] |= (a.pn[i] << shift); + } + return *this; +} + +template +base_uint& base_uint::operator>>=(unsigned int shift) +{ + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) { + if (i - k - 1 >= 0 && shift != 0) + pn[i - k - 1] |= (a.pn[i] << (32 - shift)); + if (i - k >= 0) + pn[i - k] |= (a.pn[i] >> shift); + } + return *this; +} + +template +base_uint& base_uint::operator*=(uint32_t b32) +{ + uint64_t carry = 0; + for (int i = 0; i < WIDTH; i++) { + uint64_t n = carry + (uint64_t)b32 * pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; +} + +template +base_uint& base_uint::operator*=(const base_uint& b) +{ + base_uint a = *this; + *this = 0; + for (int j = 0; j < WIDTH; j++) { + uint64_t carry = 0; + for (int i = 0; i + j < WIDTH; i++) { + uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i]; + pn[i + j] = n & 0xffffffff; + carry = n >> 32; + } + } + return *this; +} + +template +base_uint& base_uint::operator/=(const base_uint& b) +{ + base_uint div = b; // make a copy, so we can shift. + base_uint num = *this; // make a copy, so we can subtract. + *this = 0; // the quotient. + int num_bits = num.bits(); + int div_bits = div.bits(); + if (div_bits == 0) + throw uint_error("Division by zero"); + if (div_bits > num_bits) // the result is certainly 0. + return *this; + int shift = num_bits - div_bits; + div <<= shift; // shift so that div and num align. + while (shift >= 0) { + if (num >= div) { + num -= div; + pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result. + } + div >>= 1; // shift back. + shift--; + } + // num now contains the remainder of the division. + return *this; +} + +template +int base_uint::CompareTo(const base_uint& b) const +{ + for (int i = WIDTH - 1; i >= 0; i--) { + if (pn[i] < b.pn[i]) + return -1; + if (pn[i] > b.pn[i]) + return 1; + } + return 0; +} + +template +bool base_uint::EqualTo(uint64_t b) const +{ + for (int i = WIDTH - 1; i >= 2; i--) { + if (pn[i]) + return false; + } + if (pn[1] != (b >> 32)) + return false; + if (pn[0] != (b & 0xfffffffful)) + return false; + return true; +} + +template +double base_uint::getdouble() const +{ + double ret = 0.0; + double fact = 1.0; + for (int i = 0; i < WIDTH; i++) { + ret += fact * pn[i]; + fact *= 4294967296.0; + } + return ret; +} + +template +std::string base_uint::GetHex() const +{ + char psz[sizeof(pn) * 2 + 1]; + for (unsigned int i = 0; i < sizeof(pn); i++) + sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); + return std::string(psz, psz + sizeof(pn) * 2); +} + +template +void base_uint::SetHex(const char* psz) +{ + memset(pn, 0, sizeof(pn)); + + // skip leading spaces + while (isspace(*psz)) + psz++; + + // skip 0x + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + + // hex string to uint + const char* pbegin = psz; + while (::HexDigit(*psz) != -1) + psz++; + psz--; + unsigned char* p1 = (unsigned char*)pn; + unsigned char* pend = p1 + WIDTH * 4; + while (psz >= pbegin && p1 < pend) { + *p1 = ::HexDigit(*psz--); + if (psz >= pbegin) { + *p1 |= ((unsigned char)::HexDigit(*psz--) << 4); + p1++; + } + } +} + +template +void base_uint::SetHex(const std::string& str) +{ + SetHex(str.c_str()); +} + +template +std::string base_uint::ToString() const +{ + return (GetHex()); +} + +template +unsigned int base_uint::bits() const +{ + for (int pos = WIDTH - 1; pos >= 0; pos--) { + if (pn[pos]) { + for (int bits = 31; bits > 0; bits--) { + if (pn[pos] & 1 << bits) + return 32 * pos + bits + 1; + } + return 32 * pos + 1; + } + } + return 0; +} + +// Explicit instantiations for base_uint<160> +template base_uint<160>::base_uint(const std::string&); +template base_uint<160>::base_uint(const std::vector&); +template base_uint<160>& base_uint<160>::operator<<=(unsigned int); +template base_uint<160>& base_uint<160>::operator>>=(unsigned int); +template base_uint<160>& base_uint<160>::operator*=(uint32_t b32); +template base_uint<160>& base_uint<160>::operator*=(const base_uint<160>& b); +template base_uint<160>& base_uint<160>::operator/=(const base_uint<160>& b); +template int base_uint<160>::CompareTo(const base_uint<160>&) const; +template bool base_uint<160>::EqualTo(uint64_t) const; +template double base_uint<160>::getdouble() const; +template std::string base_uint<160>::GetHex() const; +template std::string base_uint<160>::ToString() const; +template void base_uint<160>::SetHex(const char*); +template void base_uint<160>::SetHex(const std::string&); +template unsigned int base_uint<160>::bits() const; + +// Explicit instantiations for base_uint<256> +template base_uint<256>::base_uint(const std::string&); +template base_uint<256>::base_uint(const std::vector&); +template base_uint<256>& base_uint<256>::operator<<=(unsigned int); +template base_uint<256>& base_uint<256>::operator>>=(unsigned int); +template base_uint<256>& base_uint<256>::operator*=(uint32_t b32); +template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b); +template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b); +template int base_uint<256>::CompareTo(const base_uint<256>&) const; +template bool base_uint<256>::EqualTo(uint64_t) const; +template double base_uint<256>::getdouble() const; +template std::string base_uint<256>::GetHex() const; +template std::string base_uint<256>::ToString() const; +template void base_uint<256>::SetHex(const char*); +template void base_uint<256>::SetHex(const std::string&); +template unsigned int base_uint<256>::bits() const; + +// This implementation directly uses shifts instead of going +// through an intermediate MPI representation. +arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow) +{ + int nSize = nCompact >> 24; + uint32_t nWord = nCompact & 0x007fffff; + if (nSize <= 3) { + nWord >>= 8 * (3 - nSize); + *this = nWord; + } else { + *this = nWord; + *this <<= 8 * (nSize - 3); + } + if (pfNegative) + *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0; + if (pfOverflow) + *pfOverflow = nWord != 0 && ((nSize > 34) || + (nWord > 0xff && nSize > 33) || + (nWord > 0xffff && nSize > 32)); + return *this; +} + +uint32_t arith_uint256::GetCompact(bool fNegative) const +{ + int nSize = (bits() + 7) / 8; + uint32_t nCompact = 0; + if (nSize <= 3) { + nCompact = GetLow64() << 8 * (3 - nSize); + } else { + arith_uint256 bn = *this >> 8 * (nSize - 3); + nCompact = bn.GetLow64(); + } + // The 0x00800000 bit denotes the sign. + // Thus, if it is already set, divide the mantissa by 256 and increase the exponent. + if (nCompact & 0x00800000) { + nCompact >>= 8; + nSize++; + } + assert((nCompact & ~0x007fffff) == 0); + assert(nSize < 256); + nCompact |= nSize << 24; + nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0); + return nCompact; +} + +static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) +{ + // Taken from lookup3, by Bob Jenkins. + a -= c; + a ^= ((c << 4) | (c >> 28)); + c += b; + b -= a; + b ^= ((a << 6) | (a >> 26)); + a += c; + c -= b; + c ^= ((b << 8) | (b >> 24)); + b += a; + a -= c; + a ^= ((c << 16) | (c >> 16)); + c += b; + b -= a; + b ^= ((a << 19) | (a >> 13)); + a += c; + c -= b; + c ^= ((b << 4) | (b >> 28)); + b += a; +} + +static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) +{ + // Taken from lookup3, by Bob Jenkins. + c ^= b; + c -= ((b << 14) | (b >> 18)); + a ^= c; + a -= ((c << 11) | (c >> 21)); + b ^= a; + b -= ((a << 25) | (a >> 7)); + c ^= b; + c -= ((b << 16) | (b >> 16)); + a ^= c; + a -= ((c << 4) | (c >> 28)); + b ^= a; + b -= ((a << 14) | (a >> 18)); + c ^= b; + c -= ((b << 24) | (b >> 8)); +} + +uint64_t arith_uint256::GetHash(const arith_uint256& salt) const +{ + uint32_t a, b, c; + a = b = c = 0xdeadbeef + (WIDTH << 2); + + a += pn[0] ^ salt.pn[0]; + b += pn[1] ^ salt.pn[1]; + c += pn[2] ^ salt.pn[2]; + HashMix(a, b, c); + a += pn[3] ^ salt.pn[3]; + b += pn[4] ^ salt.pn[4]; + c += pn[5] ^ salt.pn[5]; + HashMix(a, b, c); + a += pn[6] ^ salt.pn[6]; + b += pn[7] ^ salt.pn[7]; + HashFinal(a, b, c); + + return ((((uint64_t)b) << 32) | c); +} diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 3bb384ca8ae..9e32b124c25 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -1,19 +1,350 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #ifndef BITCOIN_ARITH_UINT256_H #define BITCOIN_ARITH_UINT256_H -// Temporary for migration to opaque uint160/256 -#include "uint256.h" +#include +#include +#include +#include +#include +#include -class arith_uint256 : public uint256 { +class uint_error : public std::runtime_error { public: - arith_uint256() {} - arith_uint256(const base_uint<256>& b) : uint256(b) {} - arith_uint256(uint64_t b) : uint256(b) {} - explicit arith_uint256(const std::string& str) : uint256(str) {} - explicit arith_uint256(const std::vector& vch) : uint256(vch) {} + explicit uint_error(const std::string& str) : std::runtime_error(str) {} }; -#define ArithToUint256(x) (x) -#define UintToArith256(x) (x) +/** Template base class for unsigned big integers. */ +template +class base_uint +{ +protected: + enum { WIDTH=BITS/32 }; + uint32_t pn[WIDTH]; +public: + + base_uint() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + base_uint(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + base_uint& operator=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + base_uint(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + explicit base_uint(const std::string& str); + explicit base_uint(const std::vector& vch); + + bool operator!() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } + + const base_uint operator~() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + return ret; + } + + const base_uint operator-() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + ret++; + return ret; + } + + double getdouble() const; + + base_uint& operator=(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + base_uint& operator^=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] ^= b.pn[i]; + return *this; + } + + base_uint& operator&=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] &= b.pn[i]; + return *this; + } + + base_uint& operator|=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] |= b.pn[i]; + return *this; + } + + base_uint& operator^=(uint64_t b) + { + pn[0] ^= (unsigned int)b; + pn[1] ^= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator|=(uint64_t b) + { + pn[0] |= (unsigned int)b; + pn[1] |= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator<<=(unsigned int shift); + base_uint& operator>>=(unsigned int shift); + + base_uint& operator+=(const base_uint& b) + { + uint64_t carry = 0; + for (int i = 0; i < WIDTH; i++) + { + uint64_t n = carry + pn[i] + b.pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; + } + + base_uint& operator-=(const base_uint& b) + { + *this += -b; + return *this; + } + + base_uint& operator+=(uint64_t b64) + { + base_uint b; + b = b64; + *this += b; + return *this; + } + + base_uint& operator-=(uint64_t b64) + { + base_uint b; + b = b64; + *this += -b; + return *this; + } + + base_uint& operator*=(uint32_t b32); + base_uint& operator*=(const base_uint& b); + base_uint& operator/=(const base_uint& b); + + base_uint& operator++() + { + // prefix operator + int i = 0; + while (++pn[i] == 0 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator++(int) + { + // postfix operator + const base_uint ret = *this; + ++(*this); + return ret; + } + + base_uint& operator--() + { + // prefix operator + int i = 0; + while (--pn[i] == (uint32_t)-1 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator--(int) + { + // postfix operator + const base_uint ret = *this; + --(*this); + return ret; + } + + int CompareTo(const base_uint& b) const; + bool EqualTo(uint64_t b) const; + + friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; } + friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; } + friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; } + friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; } + friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; } + friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; } + friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; } + friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; } + friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; } + friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; } + friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; } + friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; } + friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; } + friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; } + friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; } + friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; } + friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); } + friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); } + + std::string GetHex() const; + void SetHex(const char* psz); + void SetHex(const std::string& str); + std::string ToString() const; + + unsigned char* begin() + { + return (unsigned char*)&pn[0]; + } + + unsigned char* end() + { + return (unsigned char*)&pn[WIDTH]; + } + + const unsigned char* begin() const + { + return (unsigned char*)&pn[0]; + } + + const unsigned char* end() const + { + return (unsigned char*)&pn[WIDTH]; + } + + unsigned int size() const + { + return sizeof(pn); + } + + /** + * Returns the position of the highest bit set plus one, or zero if the + * value is zero. + */ + unsigned int bits() const; + + uint64_t GetLow64() const + { + assert(WIDTH >= 2); + return pn[0] | (uint64_t)pn[1] << 32; + } + + unsigned int GetSerializeSize(int nType, int nVersion) const + { + return sizeof(pn); + } + + template + void Serialize(Stream& s, int nType, int nVersion) const + { + s.write((char*)pn, sizeof(pn)); + } + + template + void Unserialize(Stream& s, int nType, int nVersion) + { + s.read((char*)pn, sizeof(pn)); + } + + // Temporary for migration to blob160/256 + uint64_t GetCheapHash() const + { + return GetLow64(); + } + void SetNull() + { + memset(pn, 0, sizeof(pn)); + } + bool IsNull() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } +}; + +/** 160-bit unsigned big integer. */ +class arith_uint160 : public base_uint<160> { +public: + arith_uint160() {} + arith_uint160(const base_uint<160>& b) : base_uint<160>(b) {} + arith_uint160(uint64_t b) : base_uint<160>(b) {} + explicit arith_uint160(const std::string& str) : base_uint<160>(str) {} + explicit arith_uint160(const std::vector& vch) : base_uint<160>(vch) {} +}; + +/** 256-bit unsigned big integer. */ +class arith_uint256 : public base_uint<256> { +public: + arith_uint256() {} + arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {} + arith_uint256(uint64_t b) : base_uint<256>(b) {} + explicit arith_uint256(const std::string& str) : base_uint<256>(str) {} + explicit arith_uint256(const std::vector& vch) : base_uint<256>(vch) {} + + /** + * The "compact" format is a representation of a whole + * number N using an unsigned 32bit number similar to a + * floating point format. + * The most significant 8 bits are the unsigned exponent of base 256. + * This exponent can be thought of as "number of bytes of N". + * The lower 23 bits are the mantissa. + * Bit number 24 (0x800000) represents the sign of N. + * N = (-1^sign) * mantissa * 256^(exponent-3) + * + * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). + * MPI uses the most significant bit of the first byte as sign. + * Thus 0x1234560000 is compact (0x05123456) + * and 0xc0de000000 is compact (0x0600c0de) + * + * Bitcoin only uses this "compact" format for encoding difficulty + * targets, which are unsigned 256bit quantities. Thus, all the + * complexities of the sign bit and using base 256 are probably an + * implementation accident. + */ + arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); + uint32_t GetCompact(bool fNegative = false) const; + + uint64_t GetHash(const arith_uint256& salt) const; +}; #endif // BITCOIN_UINT256_H diff --git a/src/test/uint256_tests.cpp b/src/test/arith_uint256_tests.cpp similarity index 75% rename from src/test/uint256_tests.cpp rename to src/test/arith_uint256_tests.cpp index d05b28956c4..f5f71da6147 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -8,65 +8,65 @@ #include #include #include -#include "uint256.h" +#include "arith_uint256.h" #include #include "version.h" -BOOST_AUTO_TEST_SUITE(uint256_tests) - -const unsigned char R1Array[] = +BOOST_AUTO_TEST_SUITE(arith_uint256_tests) + +const unsigned char R1Array[] = "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256 -const double R1Sdouble = 0.7096329412477836074; -const uint256 R1L = uint256(std::vector(R1Array,R1Array+32)); -const uint160 R1S = uint160(std::vector(R1Array,R1Array+20)); +const double R1Sdouble = 0.7096329412477836074; +const arith_uint256 R1L = arith_uint256(std::vector(R1Array,R1Array+32)); +const arith_uint160 R1S = arith_uint160(std::vector(R1Array,R1Array+20)); const uint64_t R1LLow64 = 0x121156cfdb4a529cULL; -const unsigned char R2Array[] = +const unsigned char R2Array[] = "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; -const uint256 R2L = uint256(std::vector(R2Array,R2Array+32)); -const uint160 R2S = uint160(std::vector(R2Array,R2Array+20)); +const arith_uint256 R2L = arith_uint256(std::vector(R2Array,R2Array+32)); +const arith_uint160 R2S = arith_uint160(std::vector(R2Array,R2Array+20)); const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C"; -const unsigned char ZeroArray[] = +const unsigned char ZeroArray[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const uint256 ZeroL = uint256(std::vector(ZeroArray,ZeroArray+32)); -const uint160 ZeroS = uint160(std::vector(ZeroArray,ZeroArray+20)); - -const unsigned char OneArray[] = +const arith_uint256 ZeroL = arith_uint256(std::vector(ZeroArray,ZeroArray+32)); +const arith_uint160 ZeroS = arith_uint160(std::vector(ZeroArray,ZeroArray+20)); + +const unsigned char OneArray[] = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const uint256 OneL = uint256(std::vector(OneArray,OneArray+32)); -const uint160 OneS = uint160(std::vector(OneArray,OneArray+20)); +const arith_uint256 OneL = arith_uint256(std::vector(OneArray,OneArray+32)); +const arith_uint160 OneS = arith_uint160(std::vector(OneArray,OneArray+20)); -const unsigned char MaxArray[] = +const unsigned char MaxArray[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; -const uint256 MaxL = uint256(std::vector(MaxArray,MaxArray+32)); -const uint160 MaxS = uint160(std::vector(MaxArray,MaxArray+20)); +const arith_uint256 MaxL = arith_uint256(std::vector(MaxArray,MaxArray+32)); +const arith_uint160 MaxS = arith_uint160(std::vector(MaxArray,MaxArray+20)); -const uint256 HalfL = (OneL << 255); -const uint160 HalfS = (OneS << 159); +const arith_uint256 HalfL = (OneL << 255); +const arith_uint160 HalfS = (OneS << 159); std::string ArrayToString(const unsigned char A[], unsigned int width) { std::stringstream Stream; Stream << std::hex; - for (unsigned int i = 0; i < width; ++i) + for (unsigned int i = 0; i < width; ++i) { Stream<): + // constructor arith_uint256(vector): BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32)); BOOST_CHECK(R1S.ToString() == ArrayToString(R1Array,20)); BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32)); @@ -88,104 +88,104 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality BOOST_CHECK(~MaxL == ZeroL && ~MaxS == ZeroS); BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L); BOOST_CHECK( ((R1S ^ R2S) ^ R1S) == R2S); - - uint64_t Tmp64 = 0xc4dab720d9c7acaaULL; - for (unsigned int i = 0; i < 256; ++i) - { - BOOST_CHECK(ZeroL != (OneL << i)); - BOOST_CHECK((OneL << i) != ZeroL); - BOOST_CHECK(R1L != (R1L ^ (OneL << i))); - BOOST_CHECK(((uint256(Tmp64) ^ (OneL << i) ) != Tmp64 )); - } - BOOST_CHECK(ZeroL == (OneL << 256)); - for (unsigned int i = 0; i < 160; ++i) + uint64_t Tmp64 = 0xc4dab720d9c7acaaULL; + for (unsigned int i = 0; i < 256; ++i) { - BOOST_CHECK(ZeroS != (OneS << i)); - BOOST_CHECK((OneS << i) != ZeroS); - BOOST_CHECK(R1S != (R1S ^ (OneS << i))); - BOOST_CHECK(((uint160(Tmp64) ^ (OneS << i) ) != Tmp64 )); + BOOST_CHECK(ZeroL != (OneL << i)); + BOOST_CHECK((OneL << i) != ZeroL); + BOOST_CHECK(R1L != (R1L ^ (OneL << i))); + BOOST_CHECK(((arith_uint256(Tmp64) ^ (OneL << i) ) != Tmp64 )); } - BOOST_CHECK(ZeroS == (OneS << 256)); + BOOST_CHECK(ZeroL == (OneL << 256)); + + for (unsigned int i = 0; i < 160; ++i) + { + BOOST_CHECK(ZeroS != (OneS << i)); + BOOST_CHECK((OneS << i) != ZeroS); + BOOST_CHECK(R1S != (R1S ^ (OneS << i))); + BOOST_CHECK(((arith_uint160(Tmp64) ^ (OneS << i) ) != Tmp64 )); + } + BOOST_CHECK(ZeroS == (OneS << 256)); // String Constructor and Copy Constructor - BOOST_CHECK(uint256("0x"+R1L.ToString()) == R1L); - BOOST_CHECK(uint256("0x"+R2L.ToString()) == R2L); - BOOST_CHECK(uint256("0x"+ZeroL.ToString()) == ZeroL); - BOOST_CHECK(uint256("0x"+OneL.ToString()) == OneL); - BOOST_CHECK(uint256("0x"+MaxL.ToString()) == MaxL); - BOOST_CHECK(uint256(R1L.ToString()) == R1L); - BOOST_CHECK(uint256(" 0x"+R1L.ToString()+" ") == R1L); - BOOST_CHECK(uint256("") == ZeroL); - BOOST_CHECK(R1L == uint256(R1ArrayHex)); - BOOST_CHECK(uint256(R1L) == R1L); - BOOST_CHECK((uint256(R1L^R2L)^R2L) == R1L); - BOOST_CHECK(uint256(ZeroL) == ZeroL); - BOOST_CHECK(uint256(OneL) == OneL); + BOOST_CHECK(arith_uint256("0x"+R1L.ToString()) == R1L); + BOOST_CHECK(arith_uint256("0x"+R2L.ToString()) == R2L); + BOOST_CHECK(arith_uint256("0x"+ZeroL.ToString()) == ZeroL); + BOOST_CHECK(arith_uint256("0x"+OneL.ToString()) == OneL); + BOOST_CHECK(arith_uint256("0x"+MaxL.ToString()) == MaxL); + BOOST_CHECK(arith_uint256(R1L.ToString()) == R1L); + BOOST_CHECK(arith_uint256(" 0x"+R1L.ToString()+" ") == R1L); + BOOST_CHECK(arith_uint256("") == ZeroL); + BOOST_CHECK(R1L == arith_uint256(R1ArrayHex)); + BOOST_CHECK(arith_uint256(R1L) == R1L); + BOOST_CHECK((arith_uint256(R1L^R2L)^R2L) == R1L); + BOOST_CHECK(arith_uint256(ZeroL) == ZeroL); + BOOST_CHECK(arith_uint256(OneL) == OneL); - BOOST_CHECK(uint160("0x"+R1S.ToString()) == R1S); - BOOST_CHECK(uint160("0x"+R2S.ToString()) == R2S); - BOOST_CHECK(uint160("0x"+ZeroS.ToString()) == ZeroS); - BOOST_CHECK(uint160("0x"+OneS.ToString()) == OneS); - BOOST_CHECK(uint160("0x"+MaxS.ToString()) == MaxS); - BOOST_CHECK(uint160(R1S.ToString()) == R1S); - BOOST_CHECK(uint160(" 0x"+R1S.ToString()+" ") == R1S); - BOOST_CHECK(uint160("") == ZeroS); - BOOST_CHECK(R1S == uint160(R1ArrayHex)); + BOOST_CHECK(arith_uint160("0x"+R1S.ToString()) == R1S); + BOOST_CHECK(arith_uint160("0x"+R2S.ToString()) == R2S); + BOOST_CHECK(arith_uint160("0x"+ZeroS.ToString()) == ZeroS); + BOOST_CHECK(arith_uint160("0x"+OneS.ToString()) == OneS); + BOOST_CHECK(arith_uint160("0x"+MaxS.ToString()) == MaxS); + BOOST_CHECK(arith_uint160(R1S.ToString()) == R1S); + BOOST_CHECK(arith_uint160(" 0x"+R1S.ToString()+" ") == R1S); + BOOST_CHECK(arith_uint160("") == ZeroS); + BOOST_CHECK(R1S == arith_uint160(R1ArrayHex)); - BOOST_CHECK(uint160(R1S) == R1S); - BOOST_CHECK((uint160(R1S^R2S)^R2S) == R1S); - BOOST_CHECK(uint160(ZeroS) == ZeroS); - BOOST_CHECK(uint160(OneS) == OneS); + BOOST_CHECK(arith_uint160(R1S) == R1S); + BOOST_CHECK((arith_uint160(R1S^R2S)^R2S) == R1S); + BOOST_CHECK(arith_uint160(ZeroS) == ZeroS); + BOOST_CHECK(arith_uint160(OneS) == OneS); // uint64_t constructor - BOOST_CHECK( (R1L & uint256("0xffffffffffffffff")) == uint256(R1LLow64)); - BOOST_CHECK(ZeroL == uint256(0)); - BOOST_CHECK(OneL == uint256(1)); - BOOST_CHECK(uint256("0xffffffffffffffff") = uint256(0xffffffffffffffffULL)); - BOOST_CHECK( (R1S & uint160("0xffffffffffffffff")) == uint160(R1LLow64)); - BOOST_CHECK(ZeroS == uint160(0)); - BOOST_CHECK(OneS == uint160(1)); - BOOST_CHECK(uint160("0xffffffffffffffff") = uint160(0xffffffffffffffffULL)); + BOOST_CHECK( (R1L & arith_uint256("0xffffffffffffffff")) == arith_uint256(R1LLow64)); + BOOST_CHECK(ZeroL == arith_uint256(0)); + BOOST_CHECK(OneL == arith_uint256(1)); + BOOST_CHECK(arith_uint256("0xffffffffffffffff") = arith_uint256(0xffffffffffffffffULL)); + BOOST_CHECK( (R1S & arith_uint160("0xffffffffffffffff")) == arith_uint160(R1LLow64)); + BOOST_CHECK(ZeroS == arith_uint160(0)); + BOOST_CHECK(OneS == arith_uint160(1)); + BOOST_CHECK(arith_uint160("0xffffffffffffffff") = arith_uint160(0xffffffffffffffffULL)); // Assignment (from base_uint) - uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL); + arith_uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL); tmpL = ~OneL; BOOST_CHECK(tmpL == ~OneL); tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L); tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L); tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL); - uint160 tmpS = ~ZeroS; BOOST_CHECK(tmpS == ~ZeroS); + arith_uint160 tmpS = ~ZeroS; BOOST_CHECK(tmpS == ~ZeroS); tmpS = ~OneS; BOOST_CHECK(tmpS == ~OneS); tmpS = ~R1S; BOOST_CHECK(tmpS == ~R1S); tmpS = ~R2S; BOOST_CHECK(tmpS == ~R2S); tmpS = ~MaxS; BOOST_CHECK(tmpS == ~MaxS); // Wrong length must throw exception. - BOOST_CHECK_THROW(uint256(std::vector(OneArray,OneArray+31)), uint_error); - BOOST_CHECK_THROW(uint256(std::vector(OneArray,OneArray+20)), uint_error); - BOOST_CHECK_THROW(uint160(std::vector(OneArray,OneArray+32)), uint_error); - BOOST_CHECK_THROW(uint160(std::vector(OneArray,OneArray+19)), uint_error); + BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+31)), uint_error); + BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+20)), uint_error); + BOOST_CHECK_THROW(arith_uint160(std::vector(OneArray,OneArray+32)), uint_error); + BOOST_CHECK_THROW(arith_uint160(std::vector(OneArray,OneArray+19)), uint_error); } -void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) +void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) { - for (unsigned int T=0; T < arrayLength; ++T) + for (unsigned int T=0; T < arrayLength; ++T) { unsigned int F = (T+bitsToShift/8); - if (F < arrayLength) + if (F < arrayLength) to[T] = from[F] >> (bitsToShift%8); else to[T] = 0; - if (F + 1 < arrayLength) + if (F + 1 < arrayLength) to[T] |= from[(F+1)] << (8-bitsToShift%8); } } -void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) +void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) { - for (unsigned int T=0; T < arrayLength; ++T) + for (unsigned int T=0; T < arrayLength; ++T) { - if (T >= bitsToShift/8) + if (T >= bitsToShift/8) { unsigned int F = T-bitsToShift/8; to[T] = from[F] << (bitsToShift%8); @@ -200,39 +200,39 @@ void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int a BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" unsigned char TmpArray[32]; - uint256 TmpL; + arith_uint256 TmpL; for (unsigned int i = 0; i < 256; ++i) { shiftArrayLeft(TmpArray, OneArray, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); TmpL = OneL; TmpL <<= i; BOOST_CHECK(TmpL == (OneL << i)); BOOST_CHECK((HalfL >> (255-i)) == (OneL << i)); TmpL = HalfL; TmpL >>= (255-i); BOOST_CHECK(TmpL == (OneL << i)); - + shiftArrayLeft(TmpArray, R1Array, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); TmpL = R1L; TmpL <<= i; BOOST_CHECK(TmpL == (R1L << i)); shiftArrayRight(TmpArray, R1Array, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); TmpL = R1L; TmpL >>= i; BOOST_CHECK(TmpL == (R1L >> i)); shiftArrayLeft(TmpArray, MaxArray, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); TmpL = MaxL; TmpL <<= i; BOOST_CHECK(TmpL == (MaxL << i)); shiftArrayRight(TmpArray, MaxArray, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); TmpL = MaxL; TmpL >>= i; BOOST_CHECK(TmpL == (MaxL >> i)); } - uint256 c1L = uint256(0x0123456789abcdefULL); - uint256 c2L = c1L << 128; + arith_uint256 c1L = arith_uint256(0x0123456789abcdefULL); + arith_uint256 c2L = c1L << 128; for (unsigned int i = 0; i < 128; ++i) { BOOST_CHECK((c1L << i) == (c2L >> (128-i))); } @@ -240,39 +240,39 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" BOOST_CHECK((c1L << i) == (c2L << (i-128))); } - uint160 TmpS; + arith_uint160 TmpS; for (unsigned int i = 0; i < 160; ++i) { shiftArrayLeft(TmpArray, OneArray, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (OneS << i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (OneS << i)); TmpS = OneS; TmpS <<= i; BOOST_CHECK(TmpS == (OneS << i)); BOOST_CHECK((HalfS >> (159-i)) == (OneS << i)); TmpS = HalfS; TmpS >>= (159-i); BOOST_CHECK(TmpS == (OneS << i)); - + shiftArrayLeft(TmpArray, R1Array, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (R1S << i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (R1S << i)); TmpS = R1S; TmpS <<= i; BOOST_CHECK(TmpS == (R1S << i)); shiftArrayRight(TmpArray, R1Array, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (R1S >> i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (R1S >> i)); TmpS = R1S; TmpS >>= i; BOOST_CHECK(TmpS == (R1S >> i)); shiftArrayLeft(TmpArray, MaxArray, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS << i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS << i)); TmpS = MaxS; TmpS <<= i; BOOST_CHECK(TmpS == (MaxS << i)); shiftArrayRight(TmpArray, MaxArray, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS >> i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS >> i)); TmpS = MaxS; TmpS >>= i; BOOST_CHECK(TmpS == (MaxS >> i)); } - uint160 c1S = uint160(0x0123456789abcdefULL); - uint160 c2S = c1S << 80; + arith_uint160 c1S = arith_uint160(0x0123456789abcdefULL); + arith_uint160 c2S = c1S << 80; for (unsigned int i = 0; i < 80; ++i) { BOOST_CHECK((c1S << i) == (c2S >> (80-i))); } @@ -285,47 +285,47 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - { BOOST_CHECK(!ZeroL); BOOST_CHECK(!ZeroS); BOOST_CHECK(!(!OneL));BOOST_CHECK(!(!OneS)); - for (unsigned int i = 0; i < 256; ++i) + for (unsigned int i = 0; i < 256; ++i) BOOST_CHECK(!(!(OneL<(TmpArray,TmpArray+32)) == (~R1L)); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (~R1S)); + for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; } + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (~R1L)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (~R1S)); BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-ZeroS == ZeroS); BOOST_CHECK(-R1L == (~R1L)+1); BOOST_CHECK(-R1S == (~R1S)+1); - for (unsigned int i = 0; i < 256; ++i) + for (unsigned int i = 0; i < 256; ++i) BOOST_CHECK(-(OneL<(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); \ + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); \ for (unsigned int i = 0; i < 20; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (_A_##S _OP_ _B_##S)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (_A_##S _OP_ _B_##S)); #define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \ TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); \ TmpS = _A_##S; TmpS _OP_##= _B_##S; BOOST_CHECK(TmpS == (_A_##S _OP_ _B_##S)); -BOOST_AUTO_TEST_CASE( bitwiseOperators ) +BOOST_AUTO_TEST_CASE( bitwiseOperators ) { unsigned char TmpArray[32]; - + CHECKBITWISEOPERATOR(R1,R2,|) CHECKBITWISEOPERATOR(R1,R2,^) CHECKBITWISEOPERATOR(R1,R2,&) @@ -342,8 +342,8 @@ BOOST_AUTO_TEST_CASE( bitwiseOperators ) CHECKBITWISEOPERATOR(Max,R1,^) CHECKBITWISEOPERATOR(Max,R1,&) - uint256 TmpL; - uint160 TmpS; + arith_uint256 TmpL; + arith_uint160 TmpS; CHECKASSIGNMENTOPERATOR(R1,R2,|) CHECKASSIGNMENTOPERATOR(R1,R2,^) CHECKASSIGNMENTOPERATOR(R1,R2,&) @@ -360,20 +360,20 @@ BOOST_AUTO_TEST_CASE( bitwiseOperators ) CHECKASSIGNMENTOPERATOR(Max,R1,^) CHECKASSIGNMENTOPERATOR(Max,R1,&) - uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL; - TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | uint256(Tmp64))); - TmpS = R1S; TmpS |= Tmp64; BOOST_CHECK(TmpS == (R1S | uint160(Tmp64))); + uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL; + TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | arith_uint256(Tmp64))); + TmpS = R1S; TmpS |= Tmp64; BOOST_CHECK(TmpS == (R1S | arith_uint160(Tmp64))); TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L); TmpS = R1S; TmpS |= 0; BOOST_CHECK(TmpS == R1S); TmpL ^= 0; BOOST_CHECK(TmpL == R1L); TmpS ^= 0; BOOST_CHECK(TmpS == R1S); - TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ uint256(Tmp64))); - TmpS ^= Tmp64; BOOST_CHECK(TmpS == (R1S ^ uint160(Tmp64))); + TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ arith_uint256(Tmp64))); + TmpS ^= Tmp64; BOOST_CHECK(TmpS == (R1S ^ arith_uint160(Tmp64))); } BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > { - uint256 TmpL; + arith_uint256 TmpL; for (unsigned int i = 0; i < 256; ++i) { TmpL= OneL<< i; BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL); @@ -383,7 +383,7 @@ BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL)); BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL)); } - uint160 TmpS; + arith_uint160 TmpS; for (unsigned int i = 0; i < 160; ++i) { TmpS= OneS<< i; BOOST_CHECK( TmpS >= ZeroS && TmpS > ZeroS && ZeroS < TmpS && ZeroS <= TmpS); @@ -395,10 +395,10 @@ BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > } } -BOOST_AUTO_TEST_CASE( plusMinus ) +BOOST_AUTO_TEST_CASE( plusMinus ) { - uint256 TmpL = 0; - BOOST_CHECK(R1L+R2L == uint256(R1LplusR2L)); + arith_uint256 TmpL = 0; + BOOST_CHECK(R1L+R2L == arith_uint256(R1LplusR2L)); TmpL += R1L; BOOST_CHECK(TmpL == R1L); TmpL += R2L; @@ -412,13 +412,13 @@ BOOST_AUTO_TEST_CASE( plusMinus ) BOOST_CHECK( TmpL == (HalfL >> (i-1)) ); TmpL = (MaxL>>i); TmpL += 1; BOOST_CHECK( TmpL == (HalfL >> (i-1)) ); - TmpL = (MaxL>>i); + TmpL = (MaxL>>i); BOOST_CHECK( TmpL++ == (MaxL>>i) ); BOOST_CHECK( TmpL == (HalfL >> (i-1))); } - BOOST_CHECK(uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); - TmpL = uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL; - BOOST_CHECK(TmpL == uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); + BOOST_CHECK(arith_uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == arith_uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); + TmpL = arith_uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL; + BOOST_CHECK(TmpL == arith_uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); TmpL -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL); TmpL = R1L; BOOST_CHECK(++TmpL == R1L+1); @@ -439,8 +439,8 @@ BOOST_AUTO_TEST_CASE( plusMinus ) BOOST_CHECK(--TmpL == R1L-1); // 160-bit; copy-pasted - uint160 TmpS = 0; - BOOST_CHECK(R1S+R2S == uint160(R1LplusR2L)); + arith_uint160 TmpS = 0; + BOOST_CHECK(R1S+R2S == arith_uint160(R1LplusR2L)); TmpS += R1S; BOOST_CHECK(TmpS == R1S); TmpS += R2S; @@ -454,13 +454,13 @@ BOOST_AUTO_TEST_CASE( plusMinus ) BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); TmpS = (MaxS>>i); TmpS += 1; BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); - TmpS = (MaxS>>i); + TmpS = (MaxS>>i); BOOST_CHECK( TmpS++ == (MaxS>>i) ); BOOST_CHECK( TmpS == (HalfS >> (i-1))); } - BOOST_CHECK(uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); - TmpS = uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL; - BOOST_CHECK(TmpS == uint160(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); + BOOST_CHECK(arith_uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == arith_uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); + TmpS = arith_uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL; + BOOST_CHECK(TmpS == arith_uint160(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); TmpS -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpS == 0xbedc77e27940a7ULL); TmpS = R1S; BOOST_CHECK(++TmpS == R1S+1); @@ -521,8 +521,8 @@ BOOST_AUTO_TEST_CASE( multiply ) BOOST_AUTO_TEST_CASE( divide ) { - uint256 D1L("AD7133AC1977FA2B7"); - uint256 D2L("ECD751716"); + arith_uint256 D1L("AD7133AC1977FA2B7"); + arith_uint256 D2L("ECD751716"); BOOST_CHECK((R1L / D1L).ToString() == "00000000000000000b8ac01106981635d9ed112290f8895545a7654dde28fb3a"); BOOST_CHECK((R1L / D2L).ToString() == "000000000873ce8efec5b67150bad3aa8c5fcb70e947586153bf2cec7c37c57a"); BOOST_CHECK(R1L / OneL == R1L); @@ -536,8 +536,8 @@ BOOST_AUTO_TEST_CASE( divide ) BOOST_CHECK(MaxL / R2L == 1); BOOST_CHECK_THROW(R2L / ZeroL, uint_error); - uint160 D1S("D3C5EDCDEA54EB92679F0A4B4"); - uint160 D2S("13037"); + arith_uint160 D1S("D3C5EDCDEA54EB92679F0A4B4"); + arith_uint160 D2S("13037"); BOOST_CHECK((R1S / D1S).ToString() == "0000000000000000000000000db9af3beade6c02"); BOOST_CHECK((R1S / D2S).ToString() == "000098dfb6cc40ca592bf74366794f298ada205c"); BOOST_CHECK(R1S / OneS == R1S); @@ -553,7 +553,7 @@ BOOST_AUTO_TEST_CASE( divide ) } -bool almostEqual(double d1, double d2) +bool almostEqual(double d1, double d2) { return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits::epsilon(); } @@ -564,7 +564,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(R2L.GetHex() == R2L.ToString()); BOOST_CHECK(OneL.GetHex() == OneL.ToString()); BOOST_CHECK(MaxL.GetHex() == MaxL.ToString()); - uint256 TmpL(R1L); + arith_uint256 TmpL(R1L); BOOST_CHECK(TmpL == R1L); TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L); TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0); @@ -612,7 +612,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(R2S.GetHex() == R2S.ToString()); BOOST_CHECK(OneS.GetHex() == OneS.ToString()); BOOST_CHECK(MaxS.GetHex() == MaxS.ToString()); - uint160 TmpS(R1S); + arith_uint160 TmpS(R1S); BOOST_CHECK(TmpS == R1S); TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S); TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == 0); @@ -634,7 +634,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(MaxS.begin() + 20 == MaxS.end()); BOOST_CHECK(TmpS.begin() + 20 == TmpS.end()); BOOST_CHECK(R1S.GetLow64() == R1LLow64); - BOOST_CHECK(HalfS.GetLow64() ==0x0000000000000000ULL); + BOOST_CHECK(HalfS.GetLow64() ==0x0000000000000000ULL); BOOST_CHECK(OneS.GetLow64() ==0x0000000000000001ULL); BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20); BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20); @@ -654,17 +654,17 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G TmpS.Unserialize(ss,0,PROTOCOL_VERSION); BOOST_CHECK(MaxS == TmpS); ss.str(""); - - for (unsigned int i = 0; i < 255; ++i) + + for (unsigned int i = 0; i < 255; ++i) { BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i)); if (i < 160) BOOST_CHECK((OneS << i).getdouble() == ldexp(1.0,i)); } BOOST_CHECK(ZeroL.getdouble() == 0.0); BOOST_CHECK(ZeroS.getdouble() == 0.0); - for (int i = 256; i > 53; --i) + for (int i = 256; i > 53; --i) BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i))); - for (int i = 160; i > 53; --i) + for (int i = 160; i > 53; --i) BOOST_CHECK(almostEqual((R1S>>(160-i)).getdouble(), ldexp(R1Sdouble,i))); uint64_t R1L64part = (R1L>>192).GetLow64(); uint64_t R1S64part = (R1S>>96).GetLow64(); @@ -677,7 +677,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_AUTO_TEST_CASE(bignum_SetCompact) { - uint256 num; + arith_uint256 num; bool fNegative; bool fOverflow; num.SetCompact(0, &fNegative, &fOverflow); @@ -809,21 +809,21 @@ BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% cover // ~R1L give a base_uint<256> BOOST_CHECK((~~R1L >> 10) == (R1L >> 10)); BOOST_CHECK((~~R1S >> 10) == (R1S >> 10)); BOOST_CHECK((~~R1L << 10) == (R1L << 10)); BOOST_CHECK((~~R1S << 10) == (R1S << 10)); - BOOST_CHECK(!(~~R1L < R1L)); BOOST_CHECK(!(~~R1S < R1S)); - BOOST_CHECK(~~R1L <= R1L); BOOST_CHECK(~~R1S <= R1S); - BOOST_CHECK(!(~~R1L > R1L)); BOOST_CHECK(!(~~R1S > R1S)); - BOOST_CHECK(~~R1L >= R1L); BOOST_CHECK(~~R1S >= R1S); - BOOST_CHECK(!(R1L < ~~R1L)); BOOST_CHECK(!(R1S < ~~R1S)); - BOOST_CHECK(R1L <= ~~R1L); BOOST_CHECK(R1S <= ~~R1S); - BOOST_CHECK(!(R1L > ~~R1L)); BOOST_CHECK(!(R1S > ~~R1S)); - BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(R1S >= ~~R1S); - + BOOST_CHECK(!(~~R1L < R1L)); BOOST_CHECK(!(~~R1S < R1S)); + BOOST_CHECK(~~R1L <= R1L); BOOST_CHECK(~~R1S <= R1S); + BOOST_CHECK(!(~~R1L > R1L)); BOOST_CHECK(!(~~R1S > R1S)); + BOOST_CHECK(~~R1L >= R1L); BOOST_CHECK(~~R1S >= R1S); + BOOST_CHECK(!(R1L < ~~R1L)); BOOST_CHECK(!(R1S < ~~R1S)); + BOOST_CHECK(R1L <= ~~R1L); BOOST_CHECK(R1S <= ~~R1S); + BOOST_CHECK(!(R1L > ~~R1L)); BOOST_CHECK(!(R1S > ~~R1S)); + BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(R1S >= ~~R1S); + BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L); BOOST_CHECK(~~R1S + R2S == R1S + ~~R2S); BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L); BOOST_CHECK(~~R1S - R2S == R1S - ~~R2S); - BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L); - BOOST_CHECK(~R1S != R1S); BOOST_CHECK(R1S != ~R1S); + BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L); + BOOST_CHECK(~R1S != R1S); BOOST_CHECK(R1S != ~R1S); unsigned char TmpArray[32]; CHECKBITWISEOPERATOR(~R1,R2,|) CHECKBITWISEOPERATOR(~R1,R2,^) @@ -834,4 +834,3 @@ BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% cover } BOOST_AUTO_TEST_SUITE_END() - diff --git a/src/uint256.cpp b/src/uint256.cpp index 918c1a7cd7b..3b1334a0324 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -11,158 +11,25 @@ #include template -base_uint::base_uint(const std::string& str) +base_blob::base_blob(const std::vector& vch) { - SetHex(str); + assert(vch.size() == sizeof(data)); + memcpy(data, &vch[0], sizeof(data)); } template -base_uint::base_uint(const std::vector& vch) +std::string base_blob::GetHex() const { - if (vch.size() != sizeof(pn)) - throw uint_error("Converting vector of wrong size to base_uint"); - memcpy(pn, &vch[0], sizeof(pn)); + char psz[sizeof(data) * 2 + 1]; + for (unsigned int i = 0; i < sizeof(data); i++) + sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]); + return std::string(psz, psz + sizeof(data) * 2); } template -base_uint& base_uint::operator<<=(unsigned int shift) +void base_blob::SetHex(const char* psz) { - base_uint a(*this); - for (int i = 0; i < WIDTH; i++) - pn[i] = 0; - int k = shift / 32; - shift = shift % 32; - for (int i = 0; i < WIDTH; i++) { - if (i + k + 1 < WIDTH && shift != 0) - pn[i + k + 1] |= (a.pn[i] >> (32 - shift)); - if (i + k < WIDTH) - pn[i + k] |= (a.pn[i] << shift); - } - return *this; -} - -template -base_uint& base_uint::operator>>=(unsigned int shift) -{ - base_uint a(*this); - for (int i = 0; i < WIDTH; i++) - pn[i] = 0; - int k = shift / 32; - shift = shift % 32; - for (int i = 0; i < WIDTH; i++) { - if (i - k - 1 >= 0 && shift != 0) - pn[i - k - 1] |= (a.pn[i] << (32 - shift)); - if (i - k >= 0) - pn[i - k] |= (a.pn[i] >> shift); - } - return *this; -} - -template -base_uint& base_uint::operator*=(uint32_t b32) -{ - uint64_t carry = 0; - for (int i = 0; i < WIDTH; i++) { - uint64_t n = carry + (uint64_t)b32 * pn[i]; - pn[i] = n & 0xffffffff; - carry = n >> 32; - } - return *this; -} - -template -base_uint& base_uint::operator*=(const base_uint& b) -{ - base_uint a = *this; - *this = 0; - for (int j = 0; j < WIDTH; j++) { - uint64_t carry = 0; - for (int i = 0; i + j < WIDTH; i++) { - uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i]; - pn[i + j] = n & 0xffffffff; - carry = n >> 32; - } - } - return *this; -} - -template -base_uint& base_uint::operator/=(const base_uint& b) -{ - base_uint div = b; // make a copy, so we can shift. - base_uint num = *this; // make a copy, so we can subtract. - *this = 0; // the quotient. - int num_bits = num.bits(); - int div_bits = div.bits(); - if (div_bits == 0) - throw uint_error("Division by zero"); - if (div_bits > num_bits) // the result is certainly 0. - return *this; - int shift = num_bits - div_bits; - div <<= shift; // shift so that div and num align. - while (shift >= 0) { - if (num >= div) { - num -= div; - pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result. - } - div >>= 1; // shift back. - shift--; - } - // num now contains the remainder of the division. - return *this; -} - -template -int base_uint::CompareTo(const base_uint& b) const -{ - for (int i = WIDTH - 1; i >= 0; i--) { - if (pn[i] < b.pn[i]) - return -1; - if (pn[i] > b.pn[i]) - return 1; - } - return 0; -} - -template -bool base_uint::EqualTo(uint64_t b) const -{ - for (int i = WIDTH - 1; i >= 2; i--) { - if (pn[i]) - return false; - } - if (pn[1] != (b >> 32)) - return false; - if (pn[0] != (b & 0xfffffffful)) - return false; - return true; -} - -template -double base_uint::getdouble() const -{ - double ret = 0.0; - double fact = 1.0; - for (int i = 0; i < WIDTH; i++) { - ret += fact * pn[i]; - fact *= 4294967296.0; - } - return ret; -} - -template -std::string base_uint::GetHex() const -{ - char psz[sizeof(pn) * 2 + 1]; - for (unsigned int i = 0; i < sizeof(pn); i++) - sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); - return std::string(psz, psz + sizeof(pn) * 2); -} - -template -void base_uint::SetHex(const char* psz) -{ - memset(pn, 0, sizeof(pn)); + memset(data, 0, sizeof(data)); // skip leading spaces while (isspace(*psz)) @@ -177,7 +44,7 @@ void base_uint::SetHex(const char* psz) while (::HexDigit(*psz) != -1) psz++; psz--; - unsigned char* p1 = (unsigned char*)pn; + unsigned char* p1 = (unsigned char*)data; unsigned char* pend = p1 + WIDTH * 4; while (psz >= pbegin && p1 < pend) { *p1 = ::HexDigit(*psz--); @@ -189,110 +56,30 @@ void base_uint::SetHex(const char* psz) } template -void base_uint::SetHex(const std::string& str) +void base_blob::SetHex(const std::string& str) { SetHex(str.c_str()); } template -std::string base_uint::ToString() const +std::string base_blob::ToString() const { return (GetHex()); } -template -unsigned int base_uint::bits() const -{ - for (int pos = WIDTH - 1; pos >= 0; pos--) { - if (pn[pos]) { - for (int bits = 31; bits > 0; bits--) { - if (pn[pos] & 1 << bits) - return 32 * pos + bits + 1; - } - return 32 * pos + 1; - } - } - return 0; -} +// Explicit instantiations for base_blob<160> +template base_blob<160>::base_blob(const std::vector&); +template std::string base_blob<160>::GetHex() const; +template std::string base_blob<160>::ToString() const; +template void base_blob<160>::SetHex(const char*); +template void base_blob<160>::SetHex(const std::string&); -// Explicit instantiations for base_uint<160> -template base_uint<160>::base_uint(const std::string&); -template base_uint<160>::base_uint(const std::vector&); -template base_uint<160>& base_uint<160>::operator<<=(unsigned int); -template base_uint<160>& base_uint<160>::operator>>=(unsigned int); -template base_uint<160>& base_uint<160>::operator*=(uint32_t b32); -template base_uint<160>& base_uint<160>::operator*=(const base_uint<160>& b); -template base_uint<160>& base_uint<160>::operator/=(const base_uint<160>& b); -template int base_uint<160>::CompareTo(const base_uint<160>&) const; -template bool base_uint<160>::EqualTo(uint64_t) const; -template double base_uint<160>::getdouble() const; -template std::string base_uint<160>::GetHex() const; -template std::string base_uint<160>::ToString() const; -template void base_uint<160>::SetHex(const char*); -template void base_uint<160>::SetHex(const std::string&); -template unsigned int base_uint<160>::bits() const; - -// Explicit instantiations for base_uint<256> -template base_uint<256>::base_uint(const std::string&); -template base_uint<256>::base_uint(const std::vector&); -template base_uint<256>& base_uint<256>::operator<<=(unsigned int); -template base_uint<256>& base_uint<256>::operator>>=(unsigned int); -template base_uint<256>& base_uint<256>::operator*=(uint32_t b32); -template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b); -template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b); -template int base_uint<256>::CompareTo(const base_uint<256>&) const; -template bool base_uint<256>::EqualTo(uint64_t) const; -template double base_uint<256>::getdouble() const; -template std::string base_uint<256>::GetHex() const; -template std::string base_uint<256>::ToString() const; -template void base_uint<256>::SetHex(const char*); -template void base_uint<256>::SetHex(const std::string&); -template unsigned int base_uint<256>::bits() const; - -// This implementation directly uses shifts instead of going -// through an intermediate MPI representation. -uint256& uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow) -{ - int nSize = nCompact >> 24; - uint32_t nWord = nCompact & 0x007fffff; - if (nSize <= 3) { - nWord >>= 8 * (3 - nSize); - *this = nWord; - } else { - *this = nWord; - *this <<= 8 * (nSize - 3); - } - if (pfNegative) - *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0; - if (pfOverflow) - *pfOverflow = nWord != 0 && ((nSize > 34) || - (nWord > 0xff && nSize > 33) || - (nWord > 0xffff && nSize > 32)); - return *this; -} - -uint32_t uint256::GetCompact(bool fNegative) const -{ - int nSize = (bits() + 7) / 8; - uint32_t nCompact = 0; - if (nSize <= 3) { - nCompact = GetLow64() << 8 * (3 - nSize); - } else { - uint256 bn = *this >> 8 * (nSize - 3); - nCompact = bn.GetLow64(); - } - // The 0x00800000 bit denotes the sign. - // Thus, if it is already set, divide the mantissa by 256 and increase the exponent. - if (nCompact & 0x00800000) { - nCompact >>= 8; - nSize++; - } - assert((nCompact & ~0x007fffff) == 0); - assert(nSize < 256); - nCompact |= nSize << 24; - nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0); - return nCompact; -} +// Explicit instantiations for base_blob<256> +template base_blob<256>::base_blob(const std::vector&); +template std::string base_blob<256>::GetHex() const; +template std::string base_blob<256>::ToString() const; +template void base_blob<256>::SetHex(const char*); +template void base_blob<256>::SetHex(const std::string&); static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) { @@ -339,18 +126,20 @@ static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) uint64_t uint256::GetHash(const uint256& salt) const { uint32_t a, b, c; + const uint32_t *pn = (const uint32_t*)data; + const uint32_t *salt_pn = (const uint32_t*)salt.data; a = b = c = 0xdeadbeef + (WIDTH << 2); - a += pn[0] ^ salt.pn[0]; - b += pn[1] ^ salt.pn[1]; - c += pn[2] ^ salt.pn[2]; + a += pn[0] ^ salt_pn[0]; + b += pn[1] ^ salt_pn[1]; + c += pn[2] ^ salt_pn[2]; HashMix(a, b, c); - a += pn[3] ^ salt.pn[3]; - b += pn[4] ^ salt.pn[4]; - c += pn[5] ^ salt.pn[5]; + a += pn[3] ^ salt_pn[3]; + b += pn[4] ^ salt_pn[4]; + c += pn[5] ^ salt_pn[5]; HashMix(a, b, c); - a += pn[6] ^ salt.pn[6]; - b += pn[7] ^ salt.pn[7]; + a += pn[6] ^ salt_pn[6]; + b += pn[7] ^ salt_pn[7]; HashFinal(a, b, c); return ((((uint64_t)b) << 32) | c); diff --git a/src/uint256.h b/src/uint256.h index 8189b27cb3c..6d016ab1648 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -13,217 +13,37 @@ #include #include -class uint_error : public std::runtime_error { -public: - explicit uint_error(const std::string& str) : std::runtime_error(str) {} -}; - -/** Template base class for unsigned big integers. */ +/** Template base class for fixed-sized opaque blobs. */ template -class base_uint +class base_blob { protected: - enum { WIDTH=BITS/32 }; - uint32_t pn[WIDTH]; + enum { WIDTH=BITS/8 }; + uint8_t data[WIDTH]; public: - - base_uint() + base_blob() { - for (int i = 0; i < WIDTH; i++) - pn[i] = 0; + memset(data, 0, sizeof(data)); } - base_uint(const base_uint& b) + explicit base_blob(const std::vector& vch); + + bool IsNull() const { for (int i = 0; i < WIDTH; i++) - pn[i] = b.pn[i]; - } - - base_uint& operator=(const base_uint& b) - { - for (int i = 0; i < WIDTH; i++) - pn[i] = b.pn[i]; - return *this; - } - - base_uint(uint64_t b) - { - pn[0] = (unsigned int)b; - pn[1] = (unsigned int)(b >> 32); - for (int i = 2; i < WIDTH; i++) - pn[i] = 0; - } - - explicit base_uint(const std::string& str); - explicit base_uint(const std::vector& vch); - - bool operator!() const - { - for (int i = 0; i < WIDTH; i++) - if (pn[i] != 0) + if (data[i] != 0) return false; return true; } - const base_uint operator~() const + void SetNull() { - base_uint ret; - for (int i = 0; i < WIDTH; i++) - ret.pn[i] = ~pn[i]; - return ret; + memset(data, 0, sizeof(data)); } - const base_uint operator-() const - { - base_uint ret; - for (int i = 0; i < WIDTH; i++) - ret.pn[i] = ~pn[i]; - ret++; - return ret; - } - - double getdouble() const; - - base_uint& operator=(uint64_t b) - { - pn[0] = (unsigned int)b; - pn[1] = (unsigned int)(b >> 32); - for (int i = 2; i < WIDTH; i++) - pn[i] = 0; - return *this; - } - - base_uint& operator^=(const base_uint& b) - { - for (int i = 0; i < WIDTH; i++) - pn[i] ^= b.pn[i]; - return *this; - } - - base_uint& operator&=(const base_uint& b) - { - for (int i = 0; i < WIDTH; i++) - pn[i] &= b.pn[i]; - return *this; - } - - base_uint& operator|=(const base_uint& b) - { - for (int i = 0; i < WIDTH; i++) - pn[i] |= b.pn[i]; - return *this; - } - - base_uint& operator^=(uint64_t b) - { - pn[0] ^= (unsigned int)b; - pn[1] ^= (unsigned int)(b >> 32); - return *this; - } - - base_uint& operator|=(uint64_t b) - { - pn[0] |= (unsigned int)b; - pn[1] |= (unsigned int)(b >> 32); - return *this; - } - - base_uint& operator<<=(unsigned int shift); - base_uint& operator>>=(unsigned int shift); - - base_uint& operator+=(const base_uint& b) - { - uint64_t carry = 0; - for (int i = 0; i < WIDTH; i++) - { - uint64_t n = carry + pn[i] + b.pn[i]; - pn[i] = n & 0xffffffff; - carry = n >> 32; - } - return *this; - } - - base_uint& operator-=(const base_uint& b) - { - *this += -b; - return *this; - } - - base_uint& operator+=(uint64_t b64) - { - base_uint b; - b = b64; - *this += b; - return *this; - } - - base_uint& operator-=(uint64_t b64) - { - base_uint b; - b = b64; - *this += -b; - return *this; - } - - base_uint& operator*=(uint32_t b32); - base_uint& operator*=(const base_uint& b); - base_uint& operator/=(const base_uint& b); - - base_uint& operator++() - { - // prefix operator - int i = 0; - while (++pn[i] == 0 && i < WIDTH-1) - i++; - return *this; - } - - const base_uint operator++(int) - { - // postfix operator - const base_uint ret = *this; - ++(*this); - return ret; - } - - base_uint& operator--() - { - // prefix operator - int i = 0; - while (--pn[i] == (uint32_t)-1 && i < WIDTH-1) - i++; - return *this; - } - - const base_uint operator--(int) - { - // postfix operator - const base_uint ret = *this; - --(*this); - return ret; - } - - int CompareTo(const base_uint& b) const; - bool EqualTo(uint64_t b) const; - - friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; } - friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; } - friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; } - friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; } - friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; } - friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; } - friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; } - friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; } - friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; } - friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; } - friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; } - friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; } - friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; } - friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; } - friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; } - friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; } - friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); } - friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); } + friend inline bool operator==(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) == 0; } + friend inline bool operator!=(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) != 0; } + friend inline bool operator<(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) < 0; } std::string GetHex() const; void SetHex(const char* psz); @@ -232,122 +52,107 @@ public: unsigned char* begin() { - return (unsigned char*)&pn[0]; + return &data[0]; } unsigned char* end() { - return (unsigned char*)&pn[WIDTH]; + return &data[WIDTH]; } const unsigned char* begin() const { - return (unsigned char*)&pn[0]; + return &data[0]; } const unsigned char* end() const { - return (unsigned char*)&pn[WIDTH]; + return &data[WIDTH]; } unsigned int size() const { - return sizeof(pn); - } - - /** - * Returns the position of the highest bit set plus one, or zero if the - * value is zero. - */ - unsigned int bits() const; - - uint64_t GetLow64() const - { - assert(WIDTH >= 2); - return pn[0] | (uint64_t)pn[1] << 32; + return sizeof(data); } unsigned int GetSerializeSize(int nType, int nVersion) const { - return sizeof(pn); + return sizeof(data); } template void Serialize(Stream& s, int nType, int nVersion) const { - s.write((char*)pn, sizeof(pn)); + s.write((char*)data, sizeof(data)); } template void Unserialize(Stream& s, int nType, int nVersion) { - s.read((char*)pn, sizeof(pn)); - } - - // Temporary for migration to opaque uint160/256 - uint64_t GetCheapHash() const - { - return GetLow64(); - } - void SetNull() - { - memset(pn, 0, sizeof(pn)); - } - bool IsNull() const - { - for (int i = 0; i < WIDTH; i++) - if (pn[i] != 0) - return false; - return true; + s.read((char*)data, sizeof(data)); } }; -/** 160-bit unsigned big integer. */ -class uint160 : public base_uint<160> { +/** 160-bit opaque blob. + * @note This type is called uint160 for historical reasons only. It is an opaque + * blob of 160 bits and has no integer operations. + */ +class uint160 : public base_blob<160> { public: uint160() {} - uint160(const base_uint<160>& b) : base_uint<160>(b) {} - uint160(uint64_t b) : base_uint<160>(b) {} - explicit uint160(const std::string& str) : base_uint<160>(str) {} - explicit uint160(const std::vector& vch) : base_uint<160>(vch) {} + uint160(const base_blob<160>& b) : base_blob<160>(b) {} + explicit uint160(const std::vector& vch) : base_blob<160>(vch) {} }; -/** 256-bit unsigned big integer. */ -class uint256 : public base_uint<256> { +/** 256-bit opaque blob. + * @note This type is called uint256 for historical reasons only. It is an + * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if + * those are required. + */ +class uint256 : public base_blob<256> { public: uint256() {} - uint256(const base_uint<256>& b) : base_uint<256>(b) {} - uint256(uint64_t b) : base_uint<256>(b) {} - explicit uint256(const std::string& str) : base_uint<256>(str) {} - explicit uint256(const std::vector& vch) : base_uint<256>(vch) {} - - /** - * The "compact" format is a representation of a whole - * number N using an unsigned 32bit number similar to a - * floating point format. - * The most significant 8 bits are the unsigned exponent of base 256. - * This exponent can be thought of as "number of bytes of N". - * The lower 23 bits are the mantissa. - * Bit number 24 (0x800000) represents the sign of N. - * N = (-1^sign) * mantissa * 256^(exponent-3) - * - * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). - * MPI uses the most significant bit of the first byte as sign. - * Thus 0x1234560000 is compact (0x05123456) - * and 0xc0de000000 is compact (0x0600c0de) - * - * Bitcoin only uses this "compact" format for encoding difficulty - * targets, which are unsigned 256bit quantities. Thus, all the - * complexities of the sign bit and using base 256 are probably an - * implementation accident. - */ - uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); - uint32_t GetCompact(bool fNegative = false) const; + uint256(const base_blob<256>& b) : base_blob<256>(b) {} + explicit uint256(const std::vector& vch) : base_blob<256>(vch) {} + /** A cheap hash function that just returns 64 bits from the result, it can be + * used when the contents are considered uniformly random. It is not appropriate + * when the value can easily be influenced from outside as e.g. a network adversary could + * provide values to trigger worst-case behavior. + * @note The result of this function is not stable between little and big endian. + */ + uint64_t GetCheapHash() const + { + uint64_t result; + memcpy((void*)&result, (void*)data, 8); + return result; + } + + /** A more secure, salted hash function. + * @note This hash is not stable between little and big endian. + */ uint64_t GetHash(const uint256& salt) const; }; -// Temporary for migration to opaque uint160/256 -inline uint256 uint256S(const std::string &x) { return uint256(x); } +/* uint256 from const char *. + * This is a separate function because the constructor uint256(const char*) can result + * in dangerously catching uint256(0). + */ +inline uint256 uint256S(const char *str) +{ + uint256 rv; + rv.SetHex(str); + return rv; +} +/* uint256 from std::string. + * This is a separate function because the constructor uint256(const std::string &str) can result + * in dangerously catching uint256(0) via std::string(const char*). + */ +inline uint256 uint256S(const std::string& str) +{ + uint256 rv; + rv.SetHex(str); + return rv; +} #endif // BITCOIN_UINT256_H From 92cdb1aace3c7343e9c9472061508d3b01d9883d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 17:29:51 +0100 Subject: [PATCH 0137/2337] Add conversion functions arith_uint256<->uint_256 --- src/arith_uint256.cpp | 16 ++++++++++++++++ src/arith_uint256.h | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 0dba429a8d5..f0b6a6a3bde 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -5,6 +5,7 @@ #include "arith_uint256.h" +#include "uint256.h" #include "utilstrencodings.h" #include @@ -355,3 +356,18 @@ uint64_t arith_uint256::GetHash(const arith_uint256& salt) const return ((((uint64_t)b) << 32) | c); } + +uint256 ArithToUint256(const arith_uint256 &a) +{ + uint256 b; + // TODO: needs bswap32 on big-endian + memcpy(b.begin(), a.pn, a.size()); + return b; +} +arith_uint256 UintToArith256(const uint256 &a) +{ + arith_uint256 b; + // TODO: needs bswap32 on big-endian + memcpy(b.pn, a.begin(), a.size()); + return b; +} diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 9e32b124c25..5cb04f3c3ca 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -13,6 +13,8 @@ #include #include +class uint256; + class uint_error : public std::runtime_error { public: explicit uint_error(const std::string& str) : std::runtime_error(str) {} @@ -345,6 +347,12 @@ public: uint32_t GetCompact(bool fNegative = false) const; uint64_t GetHash(const arith_uint256& salt) const; + + friend uint256 ArithToUint256(const arith_uint256 &); + friend arith_uint256 UintToArith256(const uint256 &); }; +uint256 ArithToUint256(const arith_uint256 &); +arith_uint256 UintToArith256(const uint256 &); + #endif // BITCOIN_UINT256_H From dba2e9141a4f07154829bdaed35adaf7af7908d3 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 15:50:31 +0100 Subject: [PATCH 0138/2337] Add tests for new uint256 --- src/Makefile.test.include | 1 + src/test/uint256_tests.cpp | 268 +++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 src/test/uint256_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 21d91acc6a7..2f10702d86f 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -68,6 +68,7 @@ BITCOIN_TESTS =\ test/test_bitcoin.cpp \ test/timedata_tests.cpp \ test/transaction_tests.cpp \ + test/uint256_tests.cpp \ test/univalue_tests.cpp \ test/util_tests.cpp diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp new file mode 100644 index 00000000000..5b33846ba94 --- /dev/null +++ b/src/test/uint256_tests.cpp @@ -0,0 +1,268 @@ +// Copyright (c) 2011-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "arith_uint256.h" +#include "uint256.h" +#include "version.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +BOOST_AUTO_TEST_SUITE(uint256_tests) + +const unsigned char R1Array[] = + "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" + "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; +const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; +const uint256 R1L = uint256(std::vector(R1Array,R1Array+32)); +const uint160 R1S = uint160(std::vector(R1Array,R1Array+20)); + +const unsigned char R2Array[] = + "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" + "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; +const uint256 R2L = uint256(std::vector(R2Array,R2Array+32)); +const uint160 R2S = uint160(std::vector(R2Array,R2Array+20)); + +const unsigned char ZeroArray[] = + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; +const uint256 ZeroL = uint256(std::vector(ZeroArray,ZeroArray+32)); +const uint160 ZeroS = uint160(std::vector(ZeroArray,ZeroArray+20)); + +const unsigned char OneArray[] = + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; +const uint256 OneL = uint256(std::vector(OneArray,OneArray+32)); +const uint160 OneS = uint160(std::vector(OneArray,OneArray+20)); + +const unsigned char MaxArray[] = + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; +const uint256 MaxL = uint256(std::vector(MaxArray,MaxArray+32)); +const uint160 MaxS = uint160(std::vector(MaxArray,MaxArray+20)); + +std::string ArrayToString(const unsigned char A[], unsigned int width) +{ + std::stringstream Stream; + Stream << std::hex; + for (unsigned int i = 0; i < width; ++i) + { + Stream<): + BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32)); + BOOST_CHECK(R1S.ToString() == ArrayToString(R1Array,20)); + BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32)); + BOOST_CHECK(R2S.ToString() == ArrayToString(R2Array,20)); + BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32)); + BOOST_CHECK(ZeroS.ToString() == ArrayToString(ZeroArray,20)); + BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32)); + BOOST_CHECK(OneS.ToString() == ArrayToString(OneArray,20)); + BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32)); + BOOST_CHECK(MaxS.ToString() == ArrayToString(MaxArray,20)); + BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32)); + BOOST_CHECK(OneS.ToString() != ArrayToString(ZeroArray,20)); + + // == and != + BOOST_CHECK(R1L != R2L && R1S != R2S); + BOOST_CHECK(ZeroL != OneL && ZeroS != OneS); + BOOST_CHECK(OneL != ZeroL && OneS != ZeroS); + BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS); + + // String Constructor and Copy Constructor + BOOST_CHECK(uint256S("0x"+R1L.ToString()) == R1L); + BOOST_CHECK(uint256S("0x"+R2L.ToString()) == R2L); + BOOST_CHECK(uint256S("0x"+ZeroL.ToString()) == ZeroL); + BOOST_CHECK(uint256S("0x"+OneL.ToString()) == OneL); + BOOST_CHECK(uint256S("0x"+MaxL.ToString()) == MaxL); + BOOST_CHECK(uint256S(R1L.ToString()) == R1L); + BOOST_CHECK(uint256S(" 0x"+R1L.ToString()+" ") == R1L); + BOOST_CHECK(uint256S("") == ZeroL); + BOOST_CHECK(R1L == uint256S(R1ArrayHex)); + BOOST_CHECK(uint256(R1L) == R1L); + BOOST_CHECK(uint256(ZeroL) == ZeroL); + BOOST_CHECK(uint256(OneL) == OneL); + + BOOST_CHECK(uint160S("0x"+R1S.ToString()) == R1S); + BOOST_CHECK(uint160S("0x"+R2S.ToString()) == R2S); + BOOST_CHECK(uint160S("0x"+ZeroS.ToString()) == ZeroS); + BOOST_CHECK(uint160S("0x"+OneS.ToString()) == OneS); + BOOST_CHECK(uint160S("0x"+MaxS.ToString()) == MaxS); + BOOST_CHECK(uint160S(R1S.ToString()) == R1S); + BOOST_CHECK(uint160S(" 0x"+R1S.ToString()+" ") == R1S); + BOOST_CHECK(uint160S("") == ZeroS); + BOOST_CHECK(R1S == uint160S(R1ArrayHex)); + + BOOST_CHECK(uint160(R1S) == R1S); + BOOST_CHECK(uint160(ZeroS) == ZeroS); + BOOST_CHECK(uint160(OneS) == OneS); +} + +BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > +{ + uint256 LastL; + for (int i = 255; i >= 0; --i) { + uint256 TmpL; + *(TmpL.begin() + (i>>3)) |= 1<<(7-(i&7)); + BOOST_CHECK( LastL < TmpL ); + LastL = TmpL; + } + + BOOST_CHECK( ZeroL < R1L ); + BOOST_CHECK( R2L < R1L ); + BOOST_CHECK( ZeroL < OneL ); + BOOST_CHECK( OneL < MaxL ); + BOOST_CHECK( R1L < MaxL ); + BOOST_CHECK( R2L < MaxL ); + + uint160 LastS; + for (int i = 159; i >= 0; --i) { + uint160 TmpS; + *(TmpS.begin() + (i>>3)) |= 1<<(7-(i&7)); + BOOST_CHECK( LastS < TmpS ); + LastS = TmpS; + } + BOOST_CHECK( ZeroS < R1S ); + BOOST_CHECK( R2S < R1S ); + BOOST_CHECK( ZeroS < OneS ); + BOOST_CHECK( OneS < MaxS ); + BOOST_CHECK( R1S < MaxS ); + BOOST_CHECK( R2S < MaxS ); +} + +BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize +{ + BOOST_CHECK(R1L.GetHex() == R1L.ToString()); + BOOST_CHECK(R2L.GetHex() == R2L.ToString()); + BOOST_CHECK(OneL.GetHex() == OneL.ToString()); + BOOST_CHECK(MaxL.GetHex() == MaxL.ToString()); + uint256 TmpL(R1L); + BOOST_CHECK(TmpL == R1L); + TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L); + TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == uint256()); + + TmpL.SetHex(R1L.ToString()); + BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0); + BOOST_CHECK(memcmp(TmpL.begin(), R1Array, 32)==0); + BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0); + BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0); + BOOST_CHECK(memcmp(OneL.begin(), OneArray, 32)==0); + BOOST_CHECK(R1L.size() == sizeof(R1L)); + BOOST_CHECK(sizeof(R1L) == 32); + BOOST_CHECK(R1L.size() == 32); + BOOST_CHECK(R2L.size() == 32); + BOOST_CHECK(ZeroL.size() == 32); + BOOST_CHECK(MaxL.size() == 32); + BOOST_CHECK(R1L.begin() + 32 == R1L.end()); + BOOST_CHECK(R2L.begin() + 32 == R2L.end()); + BOOST_CHECK(OneL.begin() + 32 == OneL.end()); + BOOST_CHECK(MaxL.begin() + 32 == MaxL.end()); + BOOST_CHECK(TmpL.begin() + 32 == TmpL.end()); + BOOST_CHECK(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32); + BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32); + + std::stringstream ss; + R1L.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+32)); + TmpL.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(R1L == TmpL); + ss.str(""); + ZeroL.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+32)); + TmpL.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ZeroL == TmpL); + ss.str(""); + MaxL.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+32)); + TmpL.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(MaxL == TmpL); + ss.str(""); + + BOOST_CHECK(R1S.GetHex() == R1S.ToString()); + BOOST_CHECK(R2S.GetHex() == R2S.ToString()); + BOOST_CHECK(OneS.GetHex() == OneS.ToString()); + BOOST_CHECK(MaxS.GetHex() == MaxS.ToString()); + uint160 TmpS(R1S); + BOOST_CHECK(TmpS == R1S); + TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S); + TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == uint160()); + + TmpS.SetHex(R1S.ToString()); + BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0); + BOOST_CHECK(memcmp(TmpS.begin(), R1Array, 20)==0); + BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0); + BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0); + BOOST_CHECK(memcmp(OneS.begin(), OneArray, 20)==0); + BOOST_CHECK(R1S.size() == sizeof(R1S)); + BOOST_CHECK(sizeof(R1S) == 20); + BOOST_CHECK(R1S.size() == 20); + BOOST_CHECK(R2S.size() == 20); + BOOST_CHECK(ZeroS.size() == 20); + BOOST_CHECK(MaxS.size() == 20); + BOOST_CHECK(R1S.begin() + 20 == R1S.end()); + BOOST_CHECK(R2S.begin() + 20 == R2S.end()); + BOOST_CHECK(OneS.begin() + 20 == OneS.end()); + BOOST_CHECK(MaxS.begin() + 20 == MaxS.end()); + BOOST_CHECK(TmpS.begin() + 20 == TmpS.end()); + BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20); + BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20); + + R1S.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+20)); + TmpS.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(R1S == TmpS); + ss.str(""); + ZeroS.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+20)); + TmpS.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ZeroS == TmpS); + ss.str(""); + MaxS.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+20)); + TmpS.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(MaxS == TmpS); + ss.str(""); +} + +BOOST_AUTO_TEST_CASE( conversion ) +{ + BOOST_CHECK(ArithToUint256(UintToArith256(ZeroL)) == ZeroL); + BOOST_CHECK(ArithToUint256(UintToArith256(OneL)) == OneL); + BOOST_CHECK(ArithToUint256(UintToArith256(R1L)) == R1L); + BOOST_CHECK(ArithToUint256(UintToArith256(R2L)) == R2L); + BOOST_CHECK(UintToArith256(ZeroL) == 0); + BOOST_CHECK(UintToArith256(OneL) == 1); + BOOST_CHECK(ArithToUint256(0) == ZeroL); + BOOST_CHECK(ArithToUint256(1) == OneL); + BOOST_CHECK(arith_uint256(R1L.GetHex()) == UintToArith256(R1L)); + BOOST_CHECK(arith_uint256(R2L.GetHex()) == UintToArith256(R2L)); + BOOST_CHECK(R1L.GetHex() == UintToArith256(R1L).GetHex()); + BOOST_CHECK(R2L.GetHex() == UintToArith256(R2L).GetHex()); +} + +BOOST_AUTO_TEST_SUITE_END() From edc720479d0749a000d5a6970da6d2d72657cf38 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 15:44:57 +0100 Subject: [PATCH 0139/2337] Remove arith_uint160 We never do 160-bit arithmetic. --- src/arith_uint256.cpp | 17 -- src/arith_uint256.h | 10 -- src/test/arith_uint256_tests.cpp | 290 +++---------------------------- 3 files changed, 23 insertions(+), 294 deletions(-) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index f0b6a6a3bde..12f9e7d1b18 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -216,23 +216,6 @@ unsigned int base_uint::bits() const return 0; } -// Explicit instantiations for base_uint<160> -template base_uint<160>::base_uint(const std::string&); -template base_uint<160>::base_uint(const std::vector&); -template base_uint<160>& base_uint<160>::operator<<=(unsigned int); -template base_uint<160>& base_uint<160>::operator>>=(unsigned int); -template base_uint<160>& base_uint<160>::operator*=(uint32_t b32); -template base_uint<160>& base_uint<160>::operator*=(const base_uint<160>& b); -template base_uint<160>& base_uint<160>::operator/=(const base_uint<160>& b); -template int base_uint<160>::CompareTo(const base_uint<160>&) const; -template bool base_uint<160>::EqualTo(uint64_t) const; -template double base_uint<160>::getdouble() const; -template std::string base_uint<160>::GetHex() const; -template std::string base_uint<160>::ToString() const; -template void base_uint<160>::SetHex(const char*); -template void base_uint<160>::SetHex(const std::string&); -template unsigned int base_uint<160>::bits() const; - // Explicit instantiations for base_uint<256> template base_uint<256>::base_uint(const std::string&); template base_uint<256>::base_uint(const std::vector&); diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 5cb04f3c3ca..b69eef67699 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -304,16 +304,6 @@ public: } }; -/** 160-bit unsigned big integer. */ -class arith_uint160 : public base_uint<160> { -public: - arith_uint160() {} - arith_uint160(const base_uint<160>& b) : base_uint<160>(b) {} - arith_uint160(uint64_t b) : base_uint<160>(b) {} - explicit arith_uint160(const std::string& str) : base_uint<160>(str) {} - explicit arith_uint160(const std::vector& vch) : base_uint<160>(vch) {} -}; - /** 256-bit unsigned big integer. */ class arith_uint256 : public base_uint<256> { public: diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index f5f71da6147..e0c4b272599 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -19,16 +19,13 @@ const unsigned char R1Array[] = "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256 -const double R1Sdouble = 0.7096329412477836074; const arith_uint256 R1L = arith_uint256(std::vector(R1Array,R1Array+32)); -const arith_uint160 R1S = arith_uint160(std::vector(R1Array,R1Array+20)); const uint64_t R1LLow64 = 0x121156cfdb4a529cULL; const unsigned char R2Array[] = "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; const arith_uint256 R2L = arith_uint256(std::vector(R2Array,R2Array+32)); -const arith_uint160 R2S = arith_uint160(std::vector(R2Array,R2Array+20)); const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C"; @@ -36,22 +33,18 @@ const unsigned char ZeroArray[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; const arith_uint256 ZeroL = arith_uint256(std::vector(ZeroArray,ZeroArray+32)); -const arith_uint160 ZeroS = arith_uint160(std::vector(ZeroArray,ZeroArray+20)); const unsigned char OneArray[] = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; const arith_uint256 OneL = arith_uint256(std::vector(OneArray,OneArray+32)); -const arith_uint160 OneS = arith_uint160(std::vector(OneArray,OneArray+20)); const unsigned char MaxArray[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; const arith_uint256 MaxL = arith_uint256(std::vector(MaxArray,MaxArray+32)); -const arith_uint160 MaxS = arith_uint160(std::vector(MaxArray,MaxArray+20)); const arith_uint256 HalfL = (OneL << 255); -const arith_uint160 HalfS = (OneS << 159); std::string ArrayToString(const unsigned char A[], unsigned int width) { std::stringstream Stream; @@ -68,26 +61,19 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality BOOST_CHECK(1 == 0+1); // constructor arith_uint256(vector): BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32)); - BOOST_CHECK(R1S.ToString() == ArrayToString(R1Array,20)); BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32)); - BOOST_CHECK(R2S.ToString() == ArrayToString(R2Array,20)); BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32)); - BOOST_CHECK(ZeroS.ToString() == ArrayToString(ZeroArray,20)); BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32)); - BOOST_CHECK(OneS.ToString() == ArrayToString(OneArray,20)); BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32)); - BOOST_CHECK(MaxS.ToString() == ArrayToString(MaxArray,20)); BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32)); - BOOST_CHECK(OneS.ToString() != ArrayToString(ZeroArray,20)); // == and != - BOOST_CHECK(R1L != R2L && R1S != R2S); - BOOST_CHECK(ZeroL != OneL && ZeroS != OneS); - BOOST_CHECK(OneL != ZeroL && OneS != ZeroS); - BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS); - BOOST_CHECK(~MaxL == ZeroL && ~MaxS == ZeroS); + BOOST_CHECK(R1L != R2L); + BOOST_CHECK(ZeroL != OneL); + BOOST_CHECK(OneL != ZeroL); + BOOST_CHECK(MaxL != ZeroL); + BOOST_CHECK(~MaxL == ZeroL); BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L); - BOOST_CHECK( ((R1S ^ R2S) ^ R1S) == R2S); uint64_t Tmp64 = 0xc4dab720d9c7acaaULL; for (unsigned int i = 0; i < 256; ++i) @@ -99,15 +85,6 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality } BOOST_CHECK(ZeroL == (OneL << 256)); - for (unsigned int i = 0; i < 160; ++i) - { - BOOST_CHECK(ZeroS != (OneS << i)); - BOOST_CHECK((OneS << i) != ZeroS); - BOOST_CHECK(R1S != (R1S ^ (OneS << i))); - BOOST_CHECK(((arith_uint160(Tmp64) ^ (OneS << i) ) != Tmp64 )); - } - BOOST_CHECK(ZeroS == (OneS << 256)); - // String Constructor and Copy Constructor BOOST_CHECK(arith_uint256("0x"+R1L.ToString()) == R1L); BOOST_CHECK(arith_uint256("0x"+R2L.ToString()) == R2L); @@ -123,30 +100,11 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality BOOST_CHECK(arith_uint256(ZeroL) == ZeroL); BOOST_CHECK(arith_uint256(OneL) == OneL); - BOOST_CHECK(arith_uint160("0x"+R1S.ToString()) == R1S); - BOOST_CHECK(arith_uint160("0x"+R2S.ToString()) == R2S); - BOOST_CHECK(arith_uint160("0x"+ZeroS.ToString()) == ZeroS); - BOOST_CHECK(arith_uint160("0x"+OneS.ToString()) == OneS); - BOOST_CHECK(arith_uint160("0x"+MaxS.ToString()) == MaxS); - BOOST_CHECK(arith_uint160(R1S.ToString()) == R1S); - BOOST_CHECK(arith_uint160(" 0x"+R1S.ToString()+" ") == R1S); - BOOST_CHECK(arith_uint160("") == ZeroS); - BOOST_CHECK(R1S == arith_uint160(R1ArrayHex)); - - BOOST_CHECK(arith_uint160(R1S) == R1S); - BOOST_CHECK((arith_uint160(R1S^R2S)^R2S) == R1S); - BOOST_CHECK(arith_uint160(ZeroS) == ZeroS); - BOOST_CHECK(arith_uint160(OneS) == OneS); - // uint64_t constructor BOOST_CHECK( (R1L & arith_uint256("0xffffffffffffffff")) == arith_uint256(R1LLow64)); BOOST_CHECK(ZeroL == arith_uint256(0)); BOOST_CHECK(OneL == arith_uint256(1)); BOOST_CHECK(arith_uint256("0xffffffffffffffff") = arith_uint256(0xffffffffffffffffULL)); - BOOST_CHECK( (R1S & arith_uint160("0xffffffffffffffff")) == arith_uint160(R1LLow64)); - BOOST_CHECK(ZeroS == arith_uint160(0)); - BOOST_CHECK(OneS == arith_uint160(1)); - BOOST_CHECK(arith_uint160("0xffffffffffffffff") = arith_uint160(0xffffffffffffffffULL)); // Assignment (from base_uint) arith_uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL); @@ -154,17 +112,10 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L); tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L); tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL); - arith_uint160 tmpS = ~ZeroS; BOOST_CHECK(tmpS == ~ZeroS); - tmpS = ~OneS; BOOST_CHECK(tmpS == ~OneS); - tmpS = ~R1S; BOOST_CHECK(tmpS == ~R1S); - tmpS = ~R2S; BOOST_CHECK(tmpS == ~R2S); - tmpS = ~MaxS; BOOST_CHECK(tmpS == ~MaxS); // Wrong length must throw exception. BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+31)), uint_error); BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+20)), uint_error); - BOOST_CHECK_THROW(arith_uint160(std::vector(OneArray,OneArray+32)), uint_error); - BOOST_CHECK_THROW(arith_uint160(std::vector(OneArray,OneArray+19)), uint_error); } void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) @@ -239,74 +190,27 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" for (unsigned int i = 128; i < 256; ++i) { BOOST_CHECK((c1L << i) == (c2L << (i-128))); } - - arith_uint160 TmpS; - for (unsigned int i = 0; i < 160; ++i) - { - shiftArrayLeft(TmpArray, OneArray, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (OneS << i)); - TmpS = OneS; TmpS <<= i; - BOOST_CHECK(TmpS == (OneS << i)); - BOOST_CHECK((HalfS >> (159-i)) == (OneS << i)); - TmpS = HalfS; TmpS >>= (159-i); - BOOST_CHECK(TmpS == (OneS << i)); - - shiftArrayLeft(TmpArray, R1Array, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (R1S << i)); - TmpS = R1S; TmpS <<= i; - BOOST_CHECK(TmpS == (R1S << i)); - - shiftArrayRight(TmpArray, R1Array, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (R1S >> i)); - TmpS = R1S; TmpS >>= i; - BOOST_CHECK(TmpS == (R1S >> i)); - - shiftArrayLeft(TmpArray, MaxArray, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS << i)); - TmpS = MaxS; TmpS <<= i; - BOOST_CHECK(TmpS == (MaxS << i)); - - shiftArrayRight(TmpArray, MaxArray, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS >> i)); - TmpS = MaxS; TmpS >>= i; - BOOST_CHECK(TmpS == (MaxS >> i)); - } - arith_uint160 c1S = arith_uint160(0x0123456789abcdefULL); - arith_uint160 c2S = c1S << 80; - for (unsigned int i = 0; i < 80; ++i) { - BOOST_CHECK((c1S << i) == (c2S >> (80-i))); - } - for (unsigned int i = 80; i < 160; ++i) { - BOOST_CHECK((c1S << i) == (c2S << (i-80))); - } } BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - { - BOOST_CHECK(!ZeroL); BOOST_CHECK(!ZeroS); - BOOST_CHECK(!(!OneL));BOOST_CHECK(!(!OneS)); + BOOST_CHECK(!ZeroL); + BOOST_CHECK(!(!OneL)); for (unsigned int i = 0; i < 256; ++i) BOOST_CHECK(!(!(OneL<(TmpArray,TmpArray+32)) == (~R1L)); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (~R1S)); - BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-ZeroS == ZeroS); + BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-R1L == (~R1L)+1); - BOOST_CHECK(-R1S == (~R1S)+1); for (unsigned int i = 0; i < 256; ++i) BOOST_CHECK(-(OneL<(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); \ - for (unsigned int i = 0; i < 20; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (_A_##S _OP_ _B_##S)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); #define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \ - TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); \ - TmpS = _A_##S; TmpS _OP_##= _B_##S; BOOST_CHECK(TmpS == (_A_##S _OP_ _B_##S)); + TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); BOOST_AUTO_TEST_CASE( bitwiseOperators ) { @@ -343,7 +244,6 @@ BOOST_AUTO_TEST_CASE( bitwiseOperators ) CHECKBITWISEOPERATOR(Max,R1,&) arith_uint256 TmpL; - arith_uint160 TmpS; CHECKASSIGNMENTOPERATOR(R1,R2,|) CHECKASSIGNMENTOPERATOR(R1,R2,^) CHECKASSIGNMENTOPERATOR(R1,R2,&) @@ -362,13 +262,9 @@ BOOST_AUTO_TEST_CASE( bitwiseOperators ) uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL; TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | arith_uint256(Tmp64))); - TmpS = R1S; TmpS |= Tmp64; BOOST_CHECK(TmpS == (R1S | arith_uint160(Tmp64))); TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L); - TmpS = R1S; TmpS |= 0; BOOST_CHECK(TmpS == R1S); TmpL ^= 0; BOOST_CHECK(TmpL == R1L); - TmpS ^= 0; BOOST_CHECK(TmpS == R1S); TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ arith_uint256(Tmp64))); - TmpS ^= Tmp64; BOOST_CHECK(TmpS == (R1S ^ arith_uint160(Tmp64))); } BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > @@ -383,16 +279,6 @@ BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL)); BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL)); } - arith_uint160 TmpS; - for (unsigned int i = 0; i < 160; ++i) { - TmpS= OneS<< i; - BOOST_CHECK( TmpS >= ZeroS && TmpS > ZeroS && ZeroS < TmpS && ZeroS <= TmpS); - BOOST_CHECK( TmpS >= 0 && TmpS > 0 && 0 < TmpS && 0 <= TmpS); - TmpS |= R1S; - BOOST_CHECK( TmpS >= R1S ); BOOST_CHECK( (TmpS == R1S) != (TmpS > R1S)); BOOST_CHECK( (TmpS == R1S) || !( TmpS <= R1S)); - BOOST_CHECK( R1S <= TmpS ); BOOST_CHECK( (R1S == TmpS) != (R1S < TmpS)); BOOST_CHECK( (TmpS == R1S) || !( R1S >= TmpS)); - BOOST_CHECK(! (TmpS < R1S)); BOOST_CHECK(! (R1S > TmpS)); - } } BOOST_AUTO_TEST_CASE( plusMinus ) @@ -437,49 +323,6 @@ BOOST_AUTO_TEST_CASE( plusMinus ) } TmpL = R1L; BOOST_CHECK(--TmpL == R1L-1); - - // 160-bit; copy-pasted - arith_uint160 TmpS = 0; - BOOST_CHECK(R1S+R2S == arith_uint160(R1LplusR2L)); - TmpS += R1S; - BOOST_CHECK(TmpS == R1S); - TmpS += R2S; - BOOST_CHECK(TmpS == R1S + R2S); - BOOST_CHECK(OneS+MaxS == ZeroS); - BOOST_CHECK(MaxS+OneS == ZeroS); - for (unsigned int i = 1; i < 160; ++i) { - BOOST_CHECK( (MaxS >> i) + OneS == (HalfS >> (i-1)) ); - BOOST_CHECK( OneS + (MaxS >> i) == (HalfS >> (i-1)) ); - TmpS = (MaxS>>i); TmpS += OneS; - BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); - TmpS = (MaxS>>i); TmpS += 1; - BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); - TmpS = (MaxS>>i); - BOOST_CHECK( TmpS++ == (MaxS>>i) ); - BOOST_CHECK( TmpS == (HalfS >> (i-1))); - } - BOOST_CHECK(arith_uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == arith_uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); - TmpS = arith_uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL; - BOOST_CHECK(TmpS == arith_uint160(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); - TmpS -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpS == 0xbedc77e27940a7ULL); - TmpS = R1S; - BOOST_CHECK(++TmpS == R1S+1); - - BOOST_CHECK(R1S -(-R2S) == R1S+R2S); - BOOST_CHECK(R1S -(-OneS) == R1S+OneS); - BOOST_CHECK(R1S - OneS == R1S+(-OneS)); - for (unsigned int i = 1; i < 160; ++i) { - BOOST_CHECK((MaxS>>i) - (-OneS) == (HalfS >> (i-1))); - BOOST_CHECK((HalfS >> (i-1)) - OneS == (MaxS>>i)); - TmpS = (HalfS >> (i-1)); - BOOST_CHECK(TmpS-- == (HalfS >> (i-1))); - BOOST_CHECK(TmpS == (MaxS >> i)); - TmpS = (HalfS >> (i-1)); - BOOST_CHECK(--TmpS == (MaxS >> i)); - } - TmpS = R1S; - BOOST_CHECK(--TmpS == R1S-1); - } BOOST_AUTO_TEST_CASE( multiply ) @@ -495,28 +338,12 @@ BOOST_AUTO_TEST_CASE( multiply ) BOOST_CHECK((R2L * OneL) == R2L); BOOST_CHECK((R2L * MaxL) == -R2L); - BOOST_CHECK((R1S * R1S).ToString() == "a7761bf30d5237e9873f9bff3642a732c4d84f10"); - BOOST_CHECK((R1S * R2S).ToString() == "ba51c008df851987d9dd323f0e5de07760529c40"); - BOOST_CHECK((R1S * ZeroS) == ZeroS); - BOOST_CHECK((R1S * OneS) == R1S); - BOOST_CHECK((R1S * MaxS) == -R1S); - BOOST_CHECK((R2S * R1S) == (R1S * R2S)); - BOOST_CHECK((R2S * R2S).ToString() == "c28bb2b45a1d85ab7996ccd3e102a650f74ff100"); - BOOST_CHECK((R2S * ZeroS) == ZeroS); - BOOST_CHECK((R2S * OneS) == R2S); - BOOST_CHECK((R2S * MaxS) == -R2S); - BOOST_CHECK(MaxL * MaxL == OneL); - BOOST_CHECK(MaxS * MaxS == OneS); BOOST_CHECK((R1L * 0) == 0); BOOST_CHECK((R1L * 1) == R1L); BOOST_CHECK((R1L * 3).ToString() == "7759b1c0ed14047f961ad09b20ff83687876a0181a367b813634046f91def7d4"); BOOST_CHECK((R2L * 0x87654321UL).ToString() == "23f7816e30c4ae2017257b7a0fa64d60402f5234d46e746b61c960d09a26d070"); - BOOST_CHECK((R1S * 0) == 0); - BOOST_CHECK((R1S * 1) == R1S); - BOOST_CHECK((R1S * 7).ToString() == "f7a987f3c3bf758d927f202d7e795faeff084244"); - BOOST_CHECK((R2S * 0xFFFFFFFFUL).ToString() == "1c6f6c930353e17f7d6127213bb18d2883e2cd90"); } BOOST_AUTO_TEST_CASE( divide ) @@ -535,21 +362,6 @@ BOOST_AUTO_TEST_CASE( divide ) BOOST_CHECK(R2L / MaxL == ZeroL); BOOST_CHECK(MaxL / R2L == 1); BOOST_CHECK_THROW(R2L / ZeroL, uint_error); - - arith_uint160 D1S("D3C5EDCDEA54EB92679F0A4B4"); - arith_uint160 D2S("13037"); - BOOST_CHECK((R1S / D1S).ToString() == "0000000000000000000000000db9af3beade6c02"); - BOOST_CHECK((R1S / D2S).ToString() == "000098dfb6cc40ca592bf74366794f298ada205c"); - BOOST_CHECK(R1S / OneS == R1S); - BOOST_CHECK(R1S / MaxS == ZeroS); - BOOST_CHECK(MaxS / R1S == 1); - BOOST_CHECK_THROW(R1S / ZeroS, uint_error); - BOOST_CHECK((R2S / D1S).ToString() == "0000000000000000000000000c5608e781182047"); - BOOST_CHECK((R2S / D2S).ToString() == "00008966751b7187c3c67c1fda5cea7db2c1c069"); - BOOST_CHECK(R2S / OneS == R2S); - BOOST_CHECK(R2S / MaxS == ZeroS); - BOOST_CHECK(MaxS / R2S == 1); - BOOST_CHECK_THROW(R2S / ZeroS, uint_error); } @@ -608,70 +420,17 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(MaxL == TmpL); ss.str(""); - BOOST_CHECK(R1S.GetHex() == R1S.ToString()); - BOOST_CHECK(R2S.GetHex() == R2S.ToString()); - BOOST_CHECK(OneS.GetHex() == OneS.ToString()); - BOOST_CHECK(MaxS.GetHex() == MaxS.ToString()); - arith_uint160 TmpS(R1S); - BOOST_CHECK(TmpS == R1S); - TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S); - TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == 0); - TmpS.SetHex(HalfS.ToString()); BOOST_CHECK(TmpS == HalfS); - - TmpS.SetHex(R1S.ToString()); - BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0); - BOOST_CHECK(memcmp(TmpS.begin(), R1Array, 20)==0); - BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0); - BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0); - BOOST_CHECK(memcmp(OneS.begin(), OneArray, 20)==0); - BOOST_CHECK(R1S.size() == 20); - BOOST_CHECK(R2S.size() == 20); - BOOST_CHECK(ZeroS.size() == 20); - BOOST_CHECK(MaxS.size() == 20); - BOOST_CHECK(R1S.begin() + 20 == R1S.end()); - BOOST_CHECK(R2S.begin() + 20 == R2S.end()); - BOOST_CHECK(OneS.begin() + 20 == OneS.end()); - BOOST_CHECK(MaxS.begin() + 20 == MaxS.end()); - BOOST_CHECK(TmpS.begin() + 20 == TmpS.end()); - BOOST_CHECK(R1S.GetLow64() == R1LLow64); - BOOST_CHECK(HalfS.GetLow64() ==0x0000000000000000ULL); - BOOST_CHECK(OneS.GetLow64() ==0x0000000000000001ULL); - BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20); - BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20); - - R1S.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+20)); - TmpS.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(R1S == TmpS); - ss.str(""); - ZeroS.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+20)); - TmpS.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ZeroS == TmpS); - ss.str(""); - MaxS.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+20)); - TmpS.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(MaxS == TmpS); - ss.str(""); - for (unsigned int i = 0; i < 255; ++i) { BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i)); - if (i < 160) BOOST_CHECK((OneS << i).getdouble() == ldexp(1.0,i)); } BOOST_CHECK(ZeroL.getdouble() == 0.0); - BOOST_CHECK(ZeroS.getdouble() == 0.0); for (int i = 256; i > 53; --i) BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i))); - for (int i = 160; i > 53; --i) - BOOST_CHECK(almostEqual((R1S>>(160-i)).getdouble(), ldexp(R1Sdouble,i))); uint64_t R1L64part = (R1L>>192).GetLow64(); - uint64_t R1S64part = (R1S>>96).GetLow64(); for (int i = 53; i > 0; --i) // doubles can store all integers in {0,...,2^54-1} exactly { BOOST_CHECK((R1L>>(256-i)).getdouble() == (double)(R1L64part >> (64-i))); - BOOST_CHECK((R1S>>(160-i)).getdouble() == (double)(R1S64part >> (64-i))); } } @@ -807,23 +566,20 @@ BOOST_AUTO_TEST_CASE(bignum_SetCompact) BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% coverage { // ~R1L give a base_uint<256> - BOOST_CHECK((~~R1L >> 10) == (R1L >> 10)); BOOST_CHECK((~~R1S >> 10) == (R1S >> 10)); - BOOST_CHECK((~~R1L << 10) == (R1L << 10)); BOOST_CHECK((~~R1S << 10) == (R1S << 10)); - BOOST_CHECK(!(~~R1L < R1L)); BOOST_CHECK(!(~~R1S < R1S)); - BOOST_CHECK(~~R1L <= R1L); BOOST_CHECK(~~R1S <= R1S); - BOOST_CHECK(!(~~R1L > R1L)); BOOST_CHECK(!(~~R1S > R1S)); - BOOST_CHECK(~~R1L >= R1L); BOOST_CHECK(~~R1S >= R1S); - BOOST_CHECK(!(R1L < ~~R1L)); BOOST_CHECK(!(R1S < ~~R1S)); - BOOST_CHECK(R1L <= ~~R1L); BOOST_CHECK(R1S <= ~~R1S); - BOOST_CHECK(!(R1L > ~~R1L)); BOOST_CHECK(!(R1S > ~~R1S)); - BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(R1S >= ~~R1S); + BOOST_CHECK((~~R1L >> 10) == (R1L >> 10)); + BOOST_CHECK((~~R1L << 10) == (R1L << 10)); + BOOST_CHECK(!(~~R1L < R1L)); + BOOST_CHECK(~~R1L <= R1L); + BOOST_CHECK(!(~~R1L > R1L)); + BOOST_CHECK(~~R1L >= R1L); + BOOST_CHECK(!(R1L < ~~R1L)); + BOOST_CHECK(R1L <= ~~R1L); + BOOST_CHECK(!(R1L > ~~R1L)); + BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L); - BOOST_CHECK(~~R1S + R2S == R1S + ~~R2S); BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L); - BOOST_CHECK(~~R1S - R2S == R1S - ~~R2S); BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L); - BOOST_CHECK(~R1S != R1S); BOOST_CHECK(R1S != ~R1S); unsigned char TmpArray[32]; CHECKBITWISEOPERATOR(~R1,R2,|) CHECKBITWISEOPERATOR(~R1,R2,^) From 30007fda76aa7ba4e4090f7a16298874a7722926 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 15:47:29 +0100 Subject: [PATCH 0140/2337] Remove now-unused methods from arith_uint256 and base_uint - Methods that access the guts of arith_uint256 are removed, as these are incompatible between endians. Use uint256 instead - Serialization is no longer needed as arith_uint256's are never read or written - GetHash is never used on arith_uint256 --- src/arith_uint256.cpp | 62 -------------------------------- src/arith_uint256.h | 56 ----------------------------- src/test/arith_uint256_tests.cpp | 31 +--------------- 3 files changed, 1 insertion(+), 148 deletions(-) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 12f9e7d1b18..11df3b05c05 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -278,68 +278,6 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const return nCompact; } -static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) -{ - // Taken from lookup3, by Bob Jenkins. - a -= c; - a ^= ((c << 4) | (c >> 28)); - c += b; - b -= a; - b ^= ((a << 6) | (a >> 26)); - a += c; - c -= b; - c ^= ((b << 8) | (b >> 24)); - b += a; - a -= c; - a ^= ((c << 16) | (c >> 16)); - c += b; - b -= a; - b ^= ((a << 19) | (a >> 13)); - a += c; - c -= b; - c ^= ((b << 4) | (b >> 28)); - b += a; -} - -static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) -{ - // Taken from lookup3, by Bob Jenkins. - c ^= b; - c -= ((b << 14) | (b >> 18)); - a ^= c; - a -= ((c << 11) | (c >> 21)); - b ^= a; - b -= ((a << 25) | (a >> 7)); - c ^= b; - c -= ((b << 16) | (b >> 16)); - a ^= c; - a -= ((c << 4) | (c >> 28)); - b ^= a; - b -= ((a << 14) | (a >> 18)); - c ^= b; - c -= ((b << 24) | (b >> 8)); -} - -uint64_t arith_uint256::GetHash(const arith_uint256& salt) const -{ - uint32_t a, b, c; - a = b = c = 0xdeadbeef + (WIDTH << 2); - - a += pn[0] ^ salt.pn[0]; - b += pn[1] ^ salt.pn[1]; - c += pn[2] ^ salt.pn[2]; - HashMix(a, b, c); - a += pn[3] ^ salt.pn[3]; - b += pn[4] ^ salt.pn[4]; - c += pn[5] ^ salt.pn[5]; - HashMix(a, b, c); - a += pn[6] ^ salt.pn[6]; - b += pn[7] ^ salt.pn[7]; - HashFinal(a, b, c); - - return ((((uint64_t)b) << 32) | c); -} - uint256 ArithToUint256(const arith_uint256 &a) { uint256 b; diff --git a/src/arith_uint256.h b/src/arith_uint256.h index b69eef67699..ec8e15997fa 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -232,26 +232,6 @@ public: void SetHex(const std::string& str); std::string ToString() const; - unsigned char* begin() - { - return (unsigned char*)&pn[0]; - } - - unsigned char* end() - { - return (unsigned char*)&pn[WIDTH]; - } - - const unsigned char* begin() const - { - return (unsigned char*)&pn[0]; - } - - const unsigned char* end() const - { - return (unsigned char*)&pn[WIDTH]; - } - unsigned int size() const { return sizeof(pn); @@ -268,40 +248,6 @@ public: assert(WIDTH >= 2); return pn[0] | (uint64_t)pn[1] << 32; } - - unsigned int GetSerializeSize(int nType, int nVersion) const - { - return sizeof(pn); - } - - template - void Serialize(Stream& s, int nType, int nVersion) const - { - s.write((char*)pn, sizeof(pn)); - } - - template - void Unserialize(Stream& s, int nType, int nVersion) - { - s.read((char*)pn, sizeof(pn)); - } - - // Temporary for migration to blob160/256 - uint64_t GetCheapHash() const - { - return GetLow64(); - } - void SetNull() - { - memset(pn, 0, sizeof(pn)); - } - bool IsNull() const - { - for (int i = 0; i < WIDTH; i++) - if (pn[i] != 0) - return false; - return true; - } }; /** 256-bit unsigned big integer. */ @@ -336,8 +282,6 @@ public: arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); uint32_t GetCompact(bool fNegative = false) const; - uint64_t GetHash(const arith_uint256& salt) const; - friend uint256 ArithToUint256(const arith_uint256 &); friend arith_uint256 UintToArith256(const uint256 &); }; diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index e0c4b272599..68953675318 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -370,7 +370,7 @@ bool almostEqual(double d1, double d2) return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits::epsilon(); } -BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize +BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex size() GetLow64 GetSerializeSize, Serialize, Unserialize { BOOST_CHECK(R1L.GetHex() == R1L.ToString()); BOOST_CHECK(R2L.GetHex() == R2L.ToString()); @@ -383,42 +383,13 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL); TmpL.SetHex(R1L.ToString()); - BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0); - BOOST_CHECK(memcmp(TmpL.begin(), R1Array, 32)==0); - BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0); - BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0); - BOOST_CHECK(memcmp(OneL.begin(), OneArray, 32)==0); BOOST_CHECK(R1L.size() == 32); BOOST_CHECK(R2L.size() == 32); BOOST_CHECK(ZeroL.size() == 32); BOOST_CHECK(MaxL.size() == 32); - BOOST_CHECK(R1L.begin() + 32 == R1L.end()); - BOOST_CHECK(R2L.begin() + 32 == R2L.end()); - BOOST_CHECK(OneL.begin() + 32 == OneL.end()); - BOOST_CHECK(MaxL.begin() + 32 == MaxL.end()); - BOOST_CHECK(TmpL.begin() + 32 == TmpL.end()); BOOST_CHECK(R1L.GetLow64() == R1LLow64); BOOST_CHECK(HalfL.GetLow64() ==0x0000000000000000ULL); BOOST_CHECK(OneL.GetLow64() ==0x0000000000000001ULL); - BOOST_CHECK(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32); - BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32); - - std::stringstream ss; - R1L.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+32)); - TmpL.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(R1L == TmpL); - ss.str(""); - ZeroL.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+32)); - TmpL.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ZeroL == TmpL); - ss.str(""); - MaxL.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+32)); - TmpL.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(MaxL == TmpL); - ss.str(""); for (unsigned int i = 0; i < 255; ++i) { From 6bd0dc2a845b4d17d5ffabbdadda80d47d6c2dc3 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 13:07:07 +0100 Subject: [PATCH 0141/2337] arith_uint256: remove initialization from byte vector Remove initialization from vector (as this is only used in the tests). Also implement SetHex and GetHex in terms of uint256, to avoid duplicate code as well as avoid endianness issues (as they work in term of bytes). --- src/arith_uint256.cpp | 39 ++------------------------------ src/arith_uint256.h | 2 -- src/test/arith_uint256_tests.cpp | 35 +++++++++++++++------------- 3 files changed, 21 insertions(+), 55 deletions(-) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 11df3b05c05..1243823da52 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -17,14 +17,6 @@ base_uint::base_uint(const std::string& str) SetHex(str); } -template -base_uint::base_uint(const std::vector& vch) -{ - if (vch.size() != sizeof(pn)) - throw uint_error("Converting vector of wrong size to base_uint"); - memcpy(pn, &vch[0], sizeof(pn)); -} - template base_uint& base_uint::operator<<=(unsigned int shift) { @@ -154,39 +146,13 @@ double base_uint::getdouble() const template std::string base_uint::GetHex() const { - char psz[sizeof(pn) * 2 + 1]; - for (unsigned int i = 0; i < sizeof(pn); i++) - sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); - return std::string(psz, psz + sizeof(pn) * 2); + return ArithToUint256(*this).GetHex(); } template void base_uint::SetHex(const char* psz) { - memset(pn, 0, sizeof(pn)); - - // skip leading spaces - while (isspace(*psz)) - psz++; - - // skip 0x - if (psz[0] == '0' && tolower(psz[1]) == 'x') - psz += 2; - - // hex string to uint - const char* pbegin = psz; - while (::HexDigit(*psz) != -1) - psz++; - psz--; - unsigned char* p1 = (unsigned char*)pn; - unsigned char* pend = p1 + WIDTH * 4; - while (psz >= pbegin && p1 < pend) { - *p1 = ::HexDigit(*psz--); - if (psz >= pbegin) { - *p1 |= ((unsigned char)::HexDigit(*psz--) << 4); - p1++; - } - } + *this = UintToArith256(uint256S(psz)); } template @@ -218,7 +184,6 @@ unsigned int base_uint::bits() const // Explicit instantiations for base_uint<256> template base_uint<256>::base_uint(const std::string&); -template base_uint<256>::base_uint(const std::vector&); template base_uint<256>& base_uint<256>::operator<<=(unsigned int); template base_uint<256>& base_uint<256>::operator>>=(unsigned int); template base_uint<256>& base_uint<256>::operator*=(uint32_t b32); diff --git a/src/arith_uint256.h b/src/arith_uint256.h index ec8e15997fa..b6ba3a10874 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -57,7 +57,6 @@ public: } explicit base_uint(const std::string& str); - explicit base_uint(const std::vector& vch); bool operator!() const { @@ -257,7 +256,6 @@ public: arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {} arith_uint256(uint64_t b) : base_uint<256>(b) {} explicit arith_uint256(const std::string& str) : base_uint<256>(str) {} - explicit arith_uint256(const std::vector& vch) : base_uint<256>(vch) {} /** * The "compact" format is a representation of a whole diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 68953675318..565b02ae642 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -8,41 +8,48 @@ #include #include #include +#include "uint256.h" #include "arith_uint256.h" #include #include "version.h" BOOST_AUTO_TEST_SUITE(arith_uint256_tests) +/// Convert vector to arith_uint256, via uint256 blob +inline arith_uint256 arith_uint256V(const std::vector& vch) +{ + return UintToArith256(uint256(vch)); +} + const unsigned char R1Array[] = "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256 -const arith_uint256 R1L = arith_uint256(std::vector(R1Array,R1Array+32)); +const arith_uint256 R1L = arith_uint256V(std::vector(R1Array,R1Array+32)); const uint64_t R1LLow64 = 0x121156cfdb4a529cULL; const unsigned char R2Array[] = "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; -const arith_uint256 R2L = arith_uint256(std::vector(R2Array,R2Array+32)); +const arith_uint256 R2L = arith_uint256V(std::vector(R2Array,R2Array+32)); const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C"; const unsigned char ZeroArray[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const arith_uint256 ZeroL = arith_uint256(std::vector(ZeroArray,ZeroArray+32)); +const arith_uint256 ZeroL = arith_uint256V(std::vector(ZeroArray,ZeroArray+32)); const unsigned char OneArray[] = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const arith_uint256 OneL = arith_uint256(std::vector(OneArray,OneArray+32)); +const arith_uint256 OneL = arith_uint256V(std::vector(OneArray,OneArray+32)); const unsigned char MaxArray[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; -const arith_uint256 MaxL = arith_uint256(std::vector(MaxArray,MaxArray+32)); +const arith_uint256 MaxL = arith_uint256V(std::vector(MaxArray,MaxArray+32)); const arith_uint256 HalfL = (OneL << 255); std::string ArrayToString(const unsigned char A[], unsigned int width) @@ -112,10 +119,6 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L); tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L); tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL); - - // Wrong length must throw exception. - BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+31)), uint_error); - BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+20)), uint_error); } void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) @@ -155,7 +158,7 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" for (unsigned int i = 0; i < 256; ++i) { shiftArrayLeft(TmpArray, OneArray, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); TmpL = OneL; TmpL <<= i; BOOST_CHECK(TmpL == (OneL << i)); BOOST_CHECK((HalfL >> (255-i)) == (OneL << i)); @@ -163,22 +166,22 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" BOOST_CHECK(TmpL == (OneL << i)); shiftArrayLeft(TmpArray, R1Array, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); TmpL = R1L; TmpL <<= i; BOOST_CHECK(TmpL == (R1L << i)); shiftArrayRight(TmpArray, R1Array, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); TmpL = R1L; TmpL >>= i; BOOST_CHECK(TmpL == (R1L >> i)); shiftArrayLeft(TmpArray, MaxArray, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); TmpL = MaxL; TmpL <<= i; BOOST_CHECK(TmpL == (MaxL << i)); shiftArrayRight(TmpArray, MaxArray, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); TmpL = MaxL; TmpL >>= i; BOOST_CHECK(TmpL == (MaxL >> i)); } @@ -205,7 +208,7 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - unsigned char TmpArray[32]; for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; } - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (~R1L)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (~R1L)); BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-R1L == (~R1L)+1); @@ -218,7 +221,7 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - // element of Aarray and Barray, and then converting the result into a arith_uint256. #define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); #define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \ TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); From be22b3da1df15757ef15e4c4963507bcdff6a872 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 23 Dec 2014 17:43:32 +0100 Subject: [PATCH 0142/2337] Update seed IPs, based on bitcoin.sipa.be crawler data --- contrib/seeds/README.md | 11 +- contrib/seeds/makeseeds.py | 120 +++- share/seeds/nodes_main.txt | 1115 +++++++++++++++++------------------- src/chainparamsseeds.h | 1102 ++++++++++++++++------------------- 4 files changed, 1127 insertions(+), 1221 deletions(-) diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md index f9a0c277e2e..bc88201f0fa 100644 --- a/contrib/seeds/README.md +++ b/contrib/seeds/README.md @@ -1,11 +1,8 @@ ### Seeds ### -Utility to generate the pnSeed[] array that is compiled into the client -(see [src/net.cpp](/src/net.cpp)). +Utility to generate the seeds.txt list that is compiled into the client +(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and [share/seeds](/share/seeds)). -The 600 seeds compiled into the 0.8 release were created from sipa's DNS seed data, like this: +The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this: - curl -s http://bitcoin.sipa.be/seeds.txt | head -1000 | makeseeds.py - -The input to makeseeds.py is assumed to be approximately sorted from most-reliable to least-reliable, -with IP:port first on each line (lines that don't match IPv4:port are ignored). + curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index 1d01fd7d209..b831395f2c7 100755 --- a/contrib/seeds/makeseeds.py +++ b/contrib/seeds/makeseeds.py @@ -1,32 +1,118 @@ #!/usr/bin/env python # -# Generate pnSeed[] from Pieter's DNS seeder +# Generate seeds.txt from Pieter's DNS seeder # -NSEEDS=600 +NSEEDS=512 + +MAX_SEEDS_PER_ASN=2 + +MIN_BLOCKS = 337600 + +# These are hosts that have been observed to be behaving strangely (e.g. +# aggressively connecting to every node). +SUSPICIOUS_HOSTS = set([ + "130.211.129.106", "178.63.107.226", + "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6", + "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211", + "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214", + "54.94.195.96", "54.94.200.247" +]) import re import sys -from subprocess import check_output +import dns.resolver + +PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):8333$") +PATTERN_AGENT = re.compile(r"^(\/Satoshi:0.8.6\/|\/Satoshi:0.9.(2|3)\/|\/Satoshi:0.10.\d{1,2}\/)$") + +def parseline(line): + sline = line.split() + if len(sline) < 11: + return None + # Match only IPv4 + m = PATTERN_IPV4.match(sline[0]) + if m is None: + return None + # Do IPv4 sanity check + ip = 0 + for i in range(0,4): + if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255: + return None + ip = ip + (int(m.group(i+2)) << (8*(3-i))) + if ip == 0: + return None + # Skip bad results. + if sline[1] == 0: + return None + # Extract uptime %. + uptime30 = float(sline[7][:-1]) + # Extract Unix timestamp of last success. + lastsuccess = int(sline[2]) + # Extract protocol version. + version = int(sline[10]) + # Extract user agent. + agent = sline[11][1:-1] + # Extract service flags. + service = int(sline[9], 16) + # Extract blocks. + blocks = int(sline[8]) + # Construct result. + return { + 'ip': m.group(1), + 'ipnum': ip, + 'uptime': uptime30, + 'lastsuccess': lastsuccess, + 'version': version, + 'agent': agent, + 'service': service, + 'blocks': blocks, + } + +# Based on Greg Maxwell's seed_filter.py +def filterbyasn(ips, max_per_asn, max_total): + result = [] + asn_count = {} + for ip in ips: + if len(result) == max_total: + break + try: + asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0]) + if asn not in asn_count: + asn_count[asn] = 0 + if asn_count[asn] == max_per_asn: + continue + asn_count[asn] += 1 + result.append(ip) + except: + sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n') + return result def main(): lines = sys.stdin.readlines() + ips = [parseline(line) for line in lines] - ips = [] - pattern = re.compile(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):8333") - for line in lines: - m = pattern.match(line) - if m is None: - continue - ip = 0 - for i in range(0,4): - ip = ip + (int(m.group(i+1)) << (8*(i))) - if ip == 0: - continue - ips.append(ip) + # Skip entries with valid IPv4 address. + ips = [ip for ip in ips if ip is not None] + # Skip entries from suspicious hosts. + ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS] + # Enforce minimal number of blocks. + ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS] + # Require service bit 1. + ips = [ip for ip in ips if (ip['service'] & 1) == 1] + # Require at least 50% 30-day uptime. + ips = [ip for ip in ips if ip['uptime'] > 50] + # Require a known and recent user agent. + ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])] + # Sort by availability (and use last success as tie breaker) + ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True) + # Look up ASNs and limit results, both per ASN and globally. + ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS) + # Sort the results by IP address (for deterministic output). + ips.sort(key=lambda x: (x['ipnum'])) - for row in range(0, min(NSEEDS,len(ips)), 8): - print " " + ", ".join([ "0x%08x"%i for i in ips[row:row+8] ]) + "," + for ip in ips: + print ip['ip'] if __name__ == '__main__': main() diff --git a/share/seeds/nodes_main.txt b/share/seeds/nodes_main.txt index f2558cf3c4f..3dba6d8a648 100644 --- a/share/seeds/nodes_main.txt +++ b/share/seeds/nodes_main.txt @@ -1,607 +1,518 @@ # List of fixed seed nodes for main network -# IPv4 nodes (in old chainparams.cpp 0xDDCCBBAA format) -# n.b. when importing a new list, there is no need to use this format, just use IPv4 dotted addresses directly -0x7e6a692e # 46.105.106.126 -0x7d04d1a2 # 162.209.4.125 -0x6c0c17d9 # 217.23.12.108 -0xdb330ab9 # 185.10.51.219 -0xc649c7c6 # 198.199.73.198 -0x7895484d # 77.72.149.120 -0x047109b0 # 176.9.113.4 -0xb90ca5bc # 188.165.12.185 -0xd130805f # 95.128.48.209 -0xbd074ea6 # 166.78.7.189 -0x578ff1c0 # 192.241.143.87 -0x286e09b0 # 176.9.110.40 -0xd4dcaf42 # 66.175.220.212 -0x529b6bb8 # 184.107.155.82 -0x635cc6c0 # 192.198.92.99 -0xedde892e # 46.137.222.237 -0xa976d9c7 # 199.217.118.169 -0xea91a4b8 # 184.164.145.234 -0x03fa4eb2 # 178.78.250.3 -0x6ca9008d # 141.0.169.108 -0xaf62c825 # 37.200.98.175 -0x93f3ba51 # 81.186.243.147 -0xc2c9efd5 # 213.239.201.194 -0x0ed5175e # 94.23.213.14 -0x487028bc # 188.40.112.72 -0x7297c225 # 37.194.151.114 -0x8af0c658 # 88.198.240.138 -0x2e57ba1f # 31.186.87.46 -0xd0098abc # 188.138.9.208 -0x46a8853e # 62.133.168.70 -0xcc92dc3e # 62.220.146.204 -0xeb6f1955 # 85.25.111.235 -0x8cce175e # 94.23.206.140 -0x237281ae # 174.129.114.35 -0x9d42795b # 91.121.66.157 -0x4f4f0905 # 5.9.79.79 -0xc50151d0 # 208.81.1.197 -0xb1ba90c6 # 198.144.186.177 -0xaed7175e # 94.23.215.174 -0x204de55b # 91.229.77.32 -0x4bb03245 # 69.50.176.75 -0x932b28bc # 188.40.43.147 -0x2dcce65b # 91.230.204.45 -0xe2708abc # 188.138.112.226 -0x1b08b8d5 # 213.184.8.27 -0x12a3dc5b # 91.220.163.18 -0x8a884c90 # 144.76.136.138 -0xa386a8b8 # 184.168.134.163 -0x18e417c6 # 198.23.228.24 -0x2e709ac3 # 195.154.112.46 -0xeb62e925 # 37.233.98.235 -0x6f6503ae # 174.3.101.111 -0x05d0814e # 78.129.208.5 -0x8a9ac545 # 69.197.154.138 -0x946fd65e # 94.214.111.148 -0x3f57495d # 93.73.87.63 -0x4a29c658 # 88.198.41.74 -0xad454c90 # 144.76.69.173 -0x15340905 # 5.9.52.21 -0x4c3f3b25 # 37.59.63.76 -0x01fe19b9 # 185.25.254.1 -0x5620595b # 91.89.32.86 -0x443c795b # 91.121.60.68 -0x44f24ac8 # 200.74.242.68 -0x0442464e # 78.70.66.4 -0xc8665882 # 130.88.102.200 -0xed3f3ec3 # 195.62.63.237 -0xf585bf5d # 93.191.133.245 -0x5dd141da # 218.65.209.93 -0xf93a084e # 78.8.58.249 -0x1264dd52 # 82.221.100.18 -0x0711c658 # 88.198.17.7 -0xf12e7bbe # 190.123.46.241 -0x5b02b740 # 64.183.2.91 -0x7d526dd5 # 213.109.82.125 -0x0cb04c90 # 144.76.176.12 -0x2abe1132 # 50.17.190.42 -0x61a39f58 # 88.159.163.97 -0x044a0618 # 24.6.74.4 -0xf3af7dce # 206.125.175.243 -0xb994c96d # 109.201.148.185 -0x361c5058 # 88.80.28.54 -0xca735d53 # 83.93.115.202 -0xeca743b0 # 176.67.167.236 -0xec790905 # 5.9.121.236 -0xc4d37845 # 69.120.211.196 -0xa1c4a2b2 # 178.162.196.161 -0x726fd453 # 83.212.111.114 -0x625cc6c0 # 192.198.92.98 -0x6c20132e # 46.19.32.108 -0xb7aa0c79 # 121.12.170.183 -0xc6ed983d # 61.152.237.198 -0x47e4cbc0 # 192.203.228.71 -0xa4ac75d4 # 212.117.172.164 -0xe2e59345 # 69.147.229.226 -0x4d784ad0 # 208.74.120.77 -0x18a5ec5e # 94.236.165.24 -0x481cc85b # 91.200.28.72 -0x7c6c2fd5 # 213.47.108.124 -0x5e4d6018 # 24.96.77.94 -0x5b4b6c18 # 24.108.75.91 -0xd99b4c90 # 144.76.155.217 -0xe63987dc # 220.135.57.230 -0xb817bb25 # 37.187.23.184 -0x141cfeb2 # 178.254.28.20 -0x5f005058 # 88.80.0.95 -0x0d987f47 # 71.127.152.13 -0x242a496d # 109.73.42.36 -0x3e519bc0 # 192.155.81.62 -0x02b2454b # 75.69.178.2 -0xdfaf3dc6 # 198.61.175.223 -0x888128bc # 188.40.129.136 -0x1165bb25 # 37.187.101.17 -0xabfeca5b # 91.202.254.171 -0x2ef63540 # 64.53.246.46 -0x5773c7c6 # 198.199.115.87 -0x1280dd52 # 82.221.128.18 -0x8ebcacd9 # 217.172.188.142 -0x81c439c6 # 198.57.196.129 -0x39fcfa45 # 69.250.252.57 -0x62177d41 # 65.125.23.98 -0xc975ed62 # 98.237.117.201 -0x05cff476 # 118.244.207.5 -0xdabda743 # 67.167.189.218 -0xaa1ac24e # 78.194.26.170 -0xe255a22e # 46.162.85.226 -0x88aac705 # 5.199.170.136 -0xe707c658 # 88.198.7.231 -0xa9e94b5e # 94.75.233.169 -0x2893484b # 75.72.147.40 -0x99512705 # 5.39.81.153 -0xd63970ca # 202.112.57.214 -0x45994f32 # 50.79.153.69 -0xe519a8ad # 173.168.25.229 -0x92e25f5d # 93.95.226.146 -0x8b84a9c1 # 193.169.132.139 -0x5eaa0a05 # 5.10.170.94 -0xa74de55b # 91.229.77.167 -0xb090ff62 # 98.255.144.176 -0x5eee326c # 108.50.238.94 -0xc331a679 # 121.166.49.195 -0xc1d9b72e # 46.183.217.193 -0x0c6ab982 # 130.185.106.12 -0x7362bb25 # 37.187.98.115 -0x4cfedd42 # 66.221.254.76 -0x1e09a032 # 50.160.9.30 -0xa4c34c5e # 94.76.195.164 -0x3777d9c7 # 199.217.119.55 -0x5edcf260 # 96.242.220.94 -0x3ce2b548 # 72.181.226.60 -0xd2ac0360 # 96.3.172.210 -0x2f80b992 # 146.185.128.47 -0x3e4cbb25 # 37.187.76.62 -0x3995e236 # 54.226.149.57 -0xd03977ae # 174.119.57.208 -0x953cf054 # 84.240.60.149 -0x3c654ed0 # 208.78.101.60 -0x74024c90 # 144.76.2.116 -0xa14f1155 # 85.17.79.161 -0x14ce0125 # 37.1.206.20 -0xc15ebb6a # 106.187.94.193 -0x2c08c452 # 82.196.8.44 -0xc7fd0652 # 82.6.253.199 -0x7604f8ce # 206.248.4.118 -0xffb38332 # 50.131.179.255 -0xa4c2efd5 # 213.239.194.164 -0xe9614018 # 24.64.97.233 -0xab49e557 # 87.229.73.171 -0x1648c052 # 82.192.72.22 -0x36024047 # 71.64.2.54 -0x0e8cffad # 173.255.140.14 -0x21918953 # 83.137.145.33 -0xb61f50ad # 173.80.31.182 -0x9b406b59 # 89.107.64.155 -0xaf282218 # 24.34.40.175 -0x7f1d164e # 78.22.29.127 -0x1f560da2 # 162.13.86.31 -0xe237be58 # 88.190.55.226 -0xbdeb1955 # 85.25.235.189 -0x6c0717d9 # 217.23.7.108 -0xdaf8ce62 # 98.206.248.218 -0x0f74246c # 108.36.116.15 -0xdee95243 # 67.82.233.222 -0xf23f1a56 # 86.26.63.242 -0x61bdf867 # 103.248.189.97 -0xd254c854 # 84.200.84.210 -0xc4422e4e # 78.46.66.196 -0xae0563c0 # 192.99.5.174 -0xbdb9a95f # 95.169.185.189 -0xa9eb32c6 # 198.50.235.169 -0xd9943950 # 80.57.148.217 -0x116add52 # 82.221.106.17 -0x73a54c90 # 144.76.165.115 -0xb36b525e # 94.82.107.179 -0xd734175e # 94.23.52.215 -0x333d7f76 # 118.127.61.51 -0x51431bc6 # 198.27.67.81 -0x084ae5cf # 207.229.74.8 -0xa60a236c # 108.35.10.166 -0x5c67692e # 46.105.103.92 -0x0177cf45 # 69.207.119.1 -0xa6683ac6 # 198.58.104.166 -0x7ff4ea47 # 71.234.244.127 -0x2192fab2 # 178.250.146.33 -0xa03a0f46 # 70.15.58.160 -0xfe3e39ae # 174.57.62.254 -0x2cce5fc1 # 193.95.206.44 -0xc8a6c148 # 72.193.166.200 -0x96fb7e4c # 76.126.251.150 -0x0a66c752 # 82.199.102.10 -0x6b4d2705 # 5.39.77.107 -0xeba0c118 # 24.193.160.235 -0x3ba0795b # 91.121.160.59 -0x1dccd23e # 62.210.204.29 -0x6912f3a2 # 162.243.18.105 -0x22f23c41 # 65.60.242.34 -0x65646b4a # 74.107.100.101 -0x8b9f8705 # 5.135.159.139 -0xeb9b9a95 # 149.154.155.235 -0x79fe6b4e # 78.107.254.121 -0x0536f447 # 71.244.54.5 -0x23224d61 # 97.77.34.35 -0x5d952ec6 # 198.46.149.93 -0x0cb4f736 # 54.247.180.12 -0xdc14be6d # 109.190.20.220 -0xb24609b0 # 176.9.70.178 -0xd3f79b62 # 98.155.247.211 -0x6518c836 # 54.200.24.101 -0x83a3cf42 # 66.207.163.131 -0x9b641fb0 # 176.31.100.155 -0x17fef1c0 # 192.241.254.23 -0xd508cc82 # 130.204.8.213 -0x91a4369b # 155.54.164.145 -0x39cb4a4c # 76.74.203.57 -0xbbc9536c # 108.83.201.187 -0xaf64c44a # 74.196.100.175 -0x605eca50 # 80.202.94.96 -0x0c6a6805 # 5.104.106.12 -0xd07e9d4e # 78.157.126.208 -0x78e6d3a2 # 162.211.230.120 -0x1b31eb6d # 109.235.49.27 -0xaa01feb2 # 178.254.1.170 -0x4603c236 # 54.194.3.70 -0x1ecba3b6 # 182.163.203.30 -0x0effe336 # 54.227.255.14 -0xc3fdcb36 # 54.203.253.195 -0xc290036f # 111.3.144.194 -0x4464692e # 46.105.100.68 -0x1aca7589 # 137.117.202.26 -0x59a9e52e # 46.229.169.89 -0x19aa7489 # 137.116.170.25 -0x2622c85e # 94.200.34.38 -0xa598d318 # 24.211.152.165 -0x438ec345 # 69.195.142.67 -0xc79619b9 # 185.25.150.199 -0xaf570360 # 96.3.87.175 -0x5098e289 # 137.226.152.80 -0x36add862 # 98.216.173.54 -0x83c1a2b2 # 178.162.193.131 -0x969d0905 # 5.9.157.150 -0xcf3d156c # 108.21.61.207 -0x49c1a445 # 69.164.193.73 -0xbd0b7562 # 98.117.11.189 -0x8fff1955 # 85.25.255.143 -0x1e51fe53 # 83.254.81.30 -0x28d6efd5 # 213.239.214.40 -0x2837cc62 # 98.204.55.40 -0x02f42d42 # 66.45.244.2 -0x070e3fb2 # 178.63.14.7 -0xbcb18705 # 5.135.177.188 -0x14a4e15b # 91.225.164.20 -0x82096844 # 68.104.9.130 -0xcfcb1c2e # 46.28.203.207 -0x37e27fc7 # 199.127.226.55 -0x07923748 # 72.55.146.7 -0x0c14bc2e # 46.188.20.12 -0x26100905 # 5.9.16.38 -0xcb7cd93e # 62.217.124.203 -0x3bc0d2c0 # 192.210.192.59 -0x97131b4c # 76.27.19.151 -0x6f1e5c17 # 23.92.30.111 -0xa7939f43 # 67.159.147.167 -0xb7a0bf58 # 88.191.160.183 -0xafa83a47 # 71.58.168.175 -0xcbb83f32 # 50.63.184.203 -0x5f321cb0 # 176.28.50.95 -0x52d6c3c7 # 199.195.214.82 -0xdeac5bc7 # 199.91.172.222 -0x2cf310cc # 204.16.243.44 -0x108a2bc3 # 195.43.138.16 -0x726fa14f # 79.161.111.114 -0x85bad2cc # 204.210.186.133 -0x459e4c90 # 144.76.158.69 -0x1a08b8d8 # 216.184.8.26 -0xcd7048c6 # 198.72.112.205 -0x6d5b4c90 # 144.76.91.109 -0xa66cfe7b # 123.254.108.166 -0xad730905 # 5.9.115.173 -0xdaac5bc7 # 199.91.172.218 -0x8417fd9f # 159.253.23.132 -0x41377432 # 50.116.55.65 -0x1f138632 # 50.134.19.31 -0x295a12b2 # 178.18.90.41 -0x7ac031b2 # 178.49.192.122 -0x3a87d295 # 149.210.135.58 -0xe219bc2e # 46.188.25.226 -0xf485d295 # 149.210.133.244 -0x137b6405 # 5.100.123.19 -0xcfffd9ad # 173.217.255.207 -0xafe20844 # 68.8.226.175 -0x32679a5f # 95.154.103.50 -0xa431c644 # 68.198.49.164 -0x0e5fce8c # 140.206.95.14 -0x305ef853 # 83.248.94.48 -0xad26ca32 # 50.202.38.173 -0xd9d21a54 # 84.26.210.217 -0xddd0d736 # 54.215.208.221 -0xc24ec0c7 # 199.192.78.194 -0x4aadcd5b # 91.205.173.74 -0x49109852 # 82.152.16.73 -0x9d6b3ac6 # 198.58.107.157 -0xf0aa1e8b # 139.30.170.240 -0xf1bfa343 # 67.163.191.241 -0x8a30c0ad # 173.192.48.138 -0x260f93d4 # 212.147.15.38 -0x2339e760 # 96.231.57.35 -0x8869959f # 159.149.105.136 -0xc207216c # 108.33.7.194 -0x29453448 # 72.52.69.41 -0xb651ec36 # 54.236.81.182 -0x45496259 # 89.98.73.69 -0xa23d1bcc # 204.27.61.162 -0xb39bcf43 # 67.207.155.179 -0xa1d29432 # 50.148.210.161 -0x3507c658 # 88.198.7.53 -0x4a88dd62 # 98.221.136.74 -0x27aff363 # 99.243.175.39 -0x7498ea6d # 109.234.152.116 -0x4a6785d5 # 213.133.103.74 -0x5e6d47c2 # 194.71.109.94 -0x3baba542 # 66.165.171.59 -0x045a37ae # 174.55.90.4 -0xa24dc0c7 # 199.192.77.162 -0xe981ea4d # 77.234.129.233 -0xed6ce217 # 23.226.108.237 -0x857214c6 # 198.20.114.133 -0x6b6c0464 # 100.4.108.107 -0x5a4945b8 # 184.69.73.90 -0x12f24742 # 66.71.242.18 -0xf35f42ad # 173.66.95.243 -0xfd0f5a4e # 78.90.15.253 -0xfb081556 # 86.21.8.251 -0xb24b5861 # 97.88.75.178 -0x2e114146 # 70.65.17.46 -0xb7780905 # 5.9.120.183 -0x33bb0e48 # 72.14.187.51 -0x39e26556 # 86.101.226.57 -0xa794484d # 77.72.148.167 -0x4225424d # 77.66.37.66 -0x3003795b # 91.121.3.48 -0x31c8cf44 # 68.207.200.49 -0xd65bad59 # 89.173.91.214 -0x127bc648 # 72.198.123.18 -0xf2bc4d4c # 76.77.188.242 -0x0273dc50 # 80.220.115.2 -0x4572d736 # 54.215.114.69 -0x064bf653 # 83.246.75.6 -0xcdcd126c # 108.18.205.205 -0x608281ae # 174.129.130.96 -0x4d130087 # 135.0.19.77 -0x1016f725 # 37.247.22.16 -0xba185fc0 # 192.95.24.186 -0x16c1a84f # 79.168.193.22 -0xfb697252 # 82.114.105.251 -0xa2942360 # 96.35.148.162 -0x53083b6c # 108.59.8.83 -0x0583f1c0 # 192.241.131.5 -0x2d5a2441 # 65.36.90.45 -0xc172aa43 # 67.170.114.193 -0xcd11cf36 # 54.207.17.205 -0x7b14ed62 # 98.237.20.123 -0x5c94f1c0 # 192.241.148.92 -0x7c23132e # 46.19.35.124 -0x39965a6f # 111.90.150.57 -0x7890e24e # 78.226.144.120 -0xa38ec447 # 71.196.142.163 -0xc187f1c0 # 192.241.135.193 -0xef80b647 # 71.182.128.239 -0xf20a7432 # 50.116.10.242 -0x7ad1d8d2 # 210.216.209.122 -0x869e2ec6 # 198.46.158.134 -0xccdb5c5d # 93.92.219.204 -0x9d11f636 # 54.246.17.157 -0x2161bb25 # 37.187.97.33 -0x7599f889 # 137.248.153.117 -0x2265ecad # 173.236.101.34 -0x0f4f0e55 # 85.14.79.15 -0x7d25854a # 74.133.37.125 -0xf857e360 # 96.227.87.248 -0xf83f3d6c # 108.61.63.248 -0x9cc93bb8 # 184.59.201.156 -0x02716857 # 87.104.113.2 -0x5dd8a177 # 119.161.216.93 -0x8adc6cd4 # 212.108.220.138 -0xe5613d46 # 70.61.97.229 -0x6a734f50 # 80.79.115.106 -0x2a5c3bae # 174.59.92.42 -0x4a04c3d1 # 209.195.4.74 -0xe4613d46 # 70.61.97.228 -0x8426f4bc # 188.244.38.132 -0x3e1b5fc0 # 192.95.27.62 -0x0d5a3c18 # 24.60.90.13 -0xd0f6d154 # 84.209.246.208 -0x21c7ff5e # 94.255.199.33 -0xeb3f3d6c # 108.61.63.235 -0x9da5edc0 # 192.237.165.157 -0x5d753b81 # 129.59.117.93 -0x0d8d53d4 # 212.83.141.13 -0x2613f018 # 24.240.19.38 -0x4443698d # 141.105.67.68 -0x8ca1edcd # 205.237.161.140 -0x10ed3f4e # 78.63.237.16 -0x789b403a # 58.64.155.120 -0x7b984a4b # 75.74.152.123 -0x964ebc25 # 37.188.78.150 -0x7520ee60 # 96.238.32.117 -0x4f4828bc # 188.40.72.79 -0x115c407d # 125.64.92.17 -0x32dd0667 # 103.6.221.50 -0xa741715e # 94.113.65.167 -0x1d3f3532 # 50.53.63.29 -0x817d1f56 # 86.31.125.129 -0x2f99a552 # 82.165.153.47 -0x6b2a5956 # 86.89.42.107 -0x8d4f4f05 # 5.79.79.141 -0xd23c1e17 # 23.30.60.210 -0x98993748 # 72.55.153.152 -0x2c92e536 # 54.229.146.44 -0x237ebdc3 # 195.189.126.35 -0xa762fb43 # 67.251.98.167 -0x32016b71 # 113.107.1.50 -0xd0e7cf79 # 121.207.231.208 -0x7d35bdd5 # 213.189.53.125 -0x53dac3d2 # 210.195.218.83 -0x31016b71 # 113.107.1.49 -0x7fb8f8ce # 206.248.184.127 -0x9a38c232 # 50.194.56.154 -0xefaa42ad # 173.66.170.239 -0x876b823d # 61.130.107.135 -0x18175347 # 71.83.23.24 -0xdb46597d # 125.89.70.219 -0xd2c168da # 218.104.193.210 -0xcd6fe9dc # 220.233.111.205 -0x45272e4e # 78.46.39.69 -0x8d4bca5b # 91.202.75.141 -0xa4043d47 # 71.61.4.164 -0xaab7aa47 # 71.170.183.170 -0x202881ae # 174.129.40.32 -0xa4aef160 # 96.241.174.164 -0xecd7e6bc # 188.230.215.236 -0x391359ad # 173.89.19.57 -0xd8cc9318 # 24.147.204.216 -0xbbeee52e # 46.229.238.187 -0x077067b0 # 176.103.112.7 -0xebd39d62 # 98.157.211.235 -0x0cedc547 # 71.197.237.12 -0x23d3e15e # 94.225.211.35 -0xa5a81318 # 24.19.168.165 -0x179a32c6 # 198.50.154.23 -0xe4d3483d # 61.72.211.228 -0x03680905 # 5.9.104.3 -0xe8018abc # 188.138.1.232 -0xdde9ef5b # 91.239.233.221 -0x438b8705 # 5.135.139.67 -0xb48224a0 # 160.36.130.180 -0xcbd69218 # 24.146.214.203 -0x9075795b # 91.121.117.144 -0xc6411c3e # 62.28.65.198 -0x03833f5c # 92.63.131.3 -0xf33f8b5e # 94.139.63.243 -0x495e464b # 75.70.94.73 -0x83c8e65b # 91.230.200.131 -0xac09cd25 # 37.205.9.172 -0xdaabc547 # 71.197.171.218 -0x7665a553 # 83.165.101.118 -0xc5263718 # 24.55.38.197 -0x2fd0c5cd # 205.197.208.47 -0x22224d61 # 97.77.34.34 -0x3e954048 # 72.64.149.62 -0xfaa37557 # 87.117.163.250 -0x36dbc658 # 88.198.219.54 -0xa81453d0 # 208.83.20.168 -0x5a941f5d # 93.31.148.90 -0xa598ea60 # 96.234.152.165 -0x65384ac6 # 198.74.56.101 -0x10aaa545 # 69.165.170.16 -0xaaab795b # 91.121.171.170 -0xdda7024c # 76.2.167.221 -0x0966f4c6 # 198.244.102.9 -0x68571c08 # 8.28.87.104 -0x8b40ee59 # 89.238.64.139 -0x33ac096c # 108.9.172.51 -0x844b4c4b # 75.76.75.132 -0xd392254d # 77.37.146.211 -0xba4d5a46 # 70.90.77.186 -0x63029653 # 83.150.2.99 -0xf655f636 # 54.246.85.246 -0xbe4c4bb1 # 177.75.76.190 -0x45dad036 # 54.208.218.69 -0x204bc052 # 82.192.75.32 -0x06c3a2b2 # 178.162.195.6 -0xf31fba6a # 106.186.31.243 -0xb21f09b0 # 176.9.31.178 -0x540d0751 # 81.7.13.84 -0xc7b46a57 # 87.106.180.199 -0x6a11795b # 91.121.17.106 -0x3d514045 # 69.64.81.61 -0x0318aa6d # 109.170.24.3 -0x30306ec3 # 195.110.48.48 -0x5c077432 # 50.116.7.92 -0x259ae46d # 109.228.154.37 -0x82bbd35f # 95.211.187.130 -0xae4222c0 # 192.34.66.174 -0x254415d4 # 212.21.68.37 -0xbd5f574b # 75.87.95.189 -0xd8fd175e # 94.23.253.216 -0x0a3f38c3 # 195.56.63.10 -0x2dce6bb8 # 184.107.206.45 -0xc201d058 # 88.208.1.194 -0x17fca5bc # 188.165.252.23 -0xe8453cca # 202.60.69.232 -0xd361f636 # 54.246.97.211 -0xa0d9edc0 # 192.237.217.160 -0x2f232e4e # 78.46.35.47 -0x134e116c # 108.17.78.19 -0x61ddc058 # 88.192.221.97 -0x05ba7283 # 131.114.186.5 -0xe1f7ed5b # 91.237.247.225 -0x040ec452 # 82.196.14.4 -0x4b672e4e # 78.46.103.75 -0xe4efa36d # 109.163.239.228 -0x47dca52e # 46.165.220.71 -0xe9332e4e # 78.46.51.233 -0xa3acb992 # 146.185.172.163 -0x24714c90 # 144.76.113.36 -0xa8cc8632 # 50.134.204.168 -0x26b1ce6d # 109.206.177.38 -0x264e53d4 # 212.83.78.38 -0xd3d2718c # 140.113.210.211 -0x225534ad # 173.52.85.34 -0xe289f3a2 # 162.243.137.226 -0x87341717 # 23.23.52.135 -0x9255ad4f # 79.173.85.146 -0x184bbb25 # 37.187.75.24 -0x885c7abc # 188.122.92.136 -0x3a6e9ac6 # 198.154.110.58 -0x1924185e # 94.24.36.25 -0xb73d4c90 # 144.76.61.183 -0x946d807a # 122.128.109.148 -0xa0d78e3f # 63.142.215.160 -0x5a16bb25 # 37.187.22.90 -0xcb09795b # 91.121.9.203 -0x8d0de657 # 87.230.13.141 -0x630b8b25 # 37.139.11.99 -0xe572c6cf # 207.198.114.229 -0x2b3f1118 # 24.17.63.43 -0x4242a91f # 31.169.66.66 -0x32990905 # 5.9.153.50 -0x058b0905 # 5.9.139.5 -0xe266fc60 # 96.252.102.226 -0xbe66c5b0 # 176.197.102.190 -0xcc98e46d # 109.228.152.204 -0x698c943e # 62.148.140.105 -0x44bd0cc3 # 195.12.189.68 -0x865c7abc # 188.122.92.134 -0x771764d3 # 211.100.23.119 -0x4675d655 # 85.214.117.70 -0x354e4826 # 38.72.78.53 -0xb67ac152 # 82.193.122.182 -0xaeccf285 # 133.242.204.174 -0xea625b4e # 78.91.98.234 -0xbcd6031f # 31.3.214.188 -0x5e81eb18 # 24.235.129.94 -0x74b347ce # 206.71.179.116 -0x3ca56ac1 # 193.106.165.60 -0x54ee4546 # 70.69.238.84 -0x38a8175e # 94.23.168.56 -0xa3c21155 # 85.17.194.163 -0x2f01576d # 109.87.1.47 -0x5d7ade50 # 80.222.122.93 -0xa003ae48 # 72.174.3.160 -0x2bc1d31f # 31.211.193.43 -0x13f5094c # 76.9.245.19 -0x7ab32648 # 72.38.179.122 -0x542e9fd5 # 213.159.46.84 -0x53136bc1 # 193.107.19.83 -0x7fdf51c0 # 192.81.223.127 -0x802197b2 # 178.151.33.128 -0xa2d2cc5b # 91.204.210.162 -0x6b5f4bc0 # 192.75.95.107 +# IPv4 nodes (generated using contrib/seeds/makeseeds.py) +1.33.197.110 +1.34.180.245 +1.202.128.218 +2.35.195.25 +5.100.123.19 +5.175.145.169 +5.199.133.193 +5.199.151.10 +5.228.1.230 +14.200.200.145 +18.228.0.188 +18.228.0.200 +23.30.243.153 +23.88.232.49 +23.99.105.9 +23.226.137.208 +23.227.177.161 +23.227.191.50 +23.229.45.32 +23.236.144.69 +23.253.148.113 +23.253.241.22 +23.255.227.231 +24.20.205.222 +24.23.120.252 +24.94.98.96 +24.98.95.201 +24.111.90.55 +24.119.119.105 +24.138.25.149 +31.3.214.45 +31.186.87.46 +31.186.101.98 +31.186.250.186 +31.204.153.107 +37.44.16.231 +37.44.44.11 +37.120.168.204 +37.143.86.26 +37.187.75.24 +37.188.68.169 +37.192.95.150 +37.201.246.116 +37.205.10.140 +46.10.210.17 +46.19.138.154 +46.28.204.123 +46.28.205.67 +46.38.235.229 +46.163.76.230 +46.166.162.91 +46.173.190.50 +46.227.66.132 +46.229.238.187 +46.236.116.209 +47.55.14.65 +50.7.252.229 +50.46.159.91 +50.78.49.181 +50.78.231.57 +50.79.153.65 +50.116.34.44 +50.126.86.253 +50.142.41.23 +50.199.113.193 +50.200.78.107 +50.206.138.177 +50.252.52.49 +54.165.25.75 +54.169.107.40 +54.179.190.56 +54.187.82.121 +54.246.85.246 +58.74.7.205 +58.96.183.121 +61.62.58.38 +61.63.91.72 +61.63.91.112 +61.72.211.228 +62.43.40.154 +62.43.130.178 +62.80.185.213 +62.109.49.26 +62.173.139.58 +62.181.238.186 +62.210.114.127 +63.141.228.138 +63.153.213.78 +63.223.84.145 +63.251.88.112 +64.31.110.50 +64.34.121.45 +64.114.6.42 +64.140.125.98 +64.156.193.100 +65.30.47.116 +65.35.132.177 +65.96.193.165 +65.111.189.26 +66.68.10.30 +66.114.33.250 +66.130.46.63 +66.175.215.135 +66.190.253.165 +66.194.38.254 +66.244.98.111 +67.162.238.30 +67.169.255.17 +67.183.173.25 +67.219.233.140 +67.227.240.115 +67.247.222.71 +68.43.114.66 +68.52.33.36 +68.198.245.241 +69.12.226.165 +69.13.198.188 +69.15.179.62 +69.39.239.47 +69.47.45.87 +69.62.217.206 +69.64.42.31 +69.64.81.61 +69.67.219.200 +69.90.132.157 +69.94.30.177 +69.136.175.241 +70.61.97.228 +70.123.118.132 +71.59.152.182 +71.198.248.151 +71.200.242.89 +71.225.179.157 +72.14.187.51 +72.38.34.180 +72.52.72.187 +72.91.144.182 +72.167.49.217 +72.201.243.55 +72.223.60.249 +72.228.153.102 +73.26.101.228 +73.50.158.200 +73.181.204.170 +74.57.199.180 +74.63.222.226 +74.81.231.21 +74.193.126.82 +74.207.235.164 +75.83.197.114 +75.144.114.9 +76.112.5.247 +76.174.20.247 +77.37.240.142 +77.57.202.107 +77.172.123.53 +77.221.91.253 +77.235.48.48 +77.245.78.2 +78.8.58.249 +78.27.191.182 +78.129.236.141 +78.131.88.47 +78.157.205.6 +79.132.230.144 +79.143.188.155 +79.160.221.140 +79.161.111.114 +80.100.189.3 +80.147.140.121 +80.203.75.133 +80.220.99.227 +80.222.20.169 +80.241.1.7 +81.23.191.243 +81.38.11.202 +81.80.9.71 +81.110.213.165 +81.133.155.237 +81.171.34.37 +81.181.155.180 +82.39.156.137 +82.73.161.95 +82.130.45.40 +82.165.153.47 +82.168.128.133 +82.179.225.118 +82.194.245.158 +82.199.102.10 +82.211.30.243 +82.217.133.145 +82.221.128.35 +82.221.131.177 +82.233.225.205 +83.0.249.146 +83.89.31.249 +83.128.29.231 +83.128.253.142 +83.143.130.56 +83.150.2.99 +83.150.9.196 +83.161.64.45 +83.212.103.212 +83.212.111.114 +83.246.75.8 +83.254.81.31 +83.254.150.54 +84.2.34.104 +84.15.61.60 +84.17.25.135 +84.42.144.19 +84.212.210.135 +84.215.165.231 +84.238.140.176 +84.240.31.184 +85.25.214.137 +85.139.163.132 +85.199.4.228 +85.214.61.209 +85.214.108.77 +86.123.16.17 +87.48.42.199 +87.104.168.104 +87.229.73.171 +87.236.196.77 +88.97.56.98 +88.134.178.89 +88.150.233.19 +88.168.133.3 +88.208.18.246 +88.208.33.202 +89.18.28.21 +89.85.220.84 +89.163.227.28 +89.184.83.60 +89.231.96.83 +89.236.49.117 +91.90.66.209 +91.106.194.97 +91.134.75.115 +91.152.193.36 +91.152.219.35 +91.197.10.234 +91.209.77.101 +91.210.106.147 +91.214.200.205 +91.223.115.38 +91.234.48.232 +91.250.86.18 +92.27.7.209 +92.255.207.73 +93.74.163.234 +93.84.114.106 +93.152.166.29 +93.171.216.221 +93.185.177.71 +94.19.12.244 +94.42.115.50 +94.79.177.206 +94.136.147.119 +94.143.245.5 +94.188.50.39 +94.190.227.112 +94.198.135.29 +94.226.107.86 +94.242.219.90 +94.242.229.168 +94.244.160.84 +95.31.10.209 +95.85.25.41 +95.105.161.136 +95.154.165.45 +95.154.200.216 +95.167.109.125 +95.211.125.231 +95.211.216.235 +96.33.25.17 +96.43.130.178 +97.118.8.236 +98.102.6.125 +98.202.20.45 +98.217.125.225 +98.234.210.111 +98.237.20.123 +98.255.144.176 +99.113.64.43 +99.229.22.8 +103.1.212.19 +103.30.42.189 +103.224.165.48 +103.243.94.140 +104.131.107.107 +104.131.116.184 +104.143.0.156 +104.219.184.9 +106.185.38.174 +107.6.4.145 +107.150.8.27 +107.150.33.20 +107.170.228.129 +107.170.240.173 +108.51.20.86 +108.61.149.222 +108.61.151.172 +108.161.129.247 +108.170.140.21 +109.60.211.216 +109.73.42.36 +109.73.172.138 +109.163.235.239 +109.190.196.220 +109.201.135.216 +109.228.152.2 +109.228.154.81 +109.230.220.125 +109.234.156.218 +109.235.49.27 +109.235.69.84 +112.124.71.0 +113.146.68.251 +115.29.17.82 +115.70.176.17 +117.41.162.184 +118.27.8.170 +119.230.7.211 +119.246.71.52 +121.172.8.100 +122.128.109.148 +123.231.224.63 +128.175.195.31 +128.199.164.96 +128.199.254.244 +129.97.69.76 +129.123.7.7 +129.123.7.39 +129.186.17.17 +131.247.169.190 +133.242.209.63 +134.102.94.38 +134.119.17.145 +137.116.160.176 +137.226.34.42 +138.210.217.170 +141.255.166.194 +143.215.129.126 +144.76.244.19 +146.148.52.162 +146.148.80.57 +146.185.19.30 +146.185.142.86 +146.185.253.51 +148.251.6.214 +149.154.155.235 +149.210.133.244 +151.224.248.252 +153.121.75.229 +153.127.251.67 +154.20.2.139 +157.13.61.5 +158.58.173.48 +159.253.23.132 +162.209.110.218 +162.213.254.205 +162.239.254.100 +162.242.150.39 +162.243.81.138 +162.243.235.56 +162.244.79.16 +162.245.217.119 +162.248.102.117 +162.251.108.53 +162.254.149.139 +162.255.116.78 +166.70.94.106 +167.88.45.124 +167.88.120.210 +173.26.49.43 +173.30.14.6 +173.80.114.197 +173.167.214.243 +173.208.219.108 +173.220.67.156 +173.236.101.34 +173.246.107.34 +173.255.237.241 +174.2.213.209 +174.51.23.224 +174.51.123.159 +174.57.212.121 +174.109.33.28 +175.126.124.91 +175.126.124.92 +176.10.116.242 +176.36.35.126 +176.36.99.222 +176.124.110.47 +176.194.33.44 +176.223.201.198 +178.62.26.83 +178.62.36.48 +178.62.212.141 +178.62.254.59 +178.78.250.3 +178.155.86.226 +178.175.134.35 +178.248.111.4 +178.254.1.170 +178.254.34.161 +179.43.114.14 +182.213.208.28 +184.68.2.46 +184.72.238.42 +184.94.226.34 +184.94.227.58 +184.107.139.58 +184.107.206.45 +185.10.48.117 +185.21.216.156 +185.38.47.224 +185.45.192.129 +185.53.129.230 +185.53.131.114 +185.55.53.61 +185.55.53.63 +185.61.119.2 +185.61.148.203 +186.2.167.23 +188.92.75.178 +188.122.92.134 +188.138.9.208 +188.165.209.148 +188.226.206.239 +190.10.8.124 +190.10.10.147 +192.0.130.142 +192.3.89.159 +192.73.234.138 +192.75.95.107 +192.95.100.102 +192.155.84.181 +192.169.233.206 +192.198.93.86 +192.227.135.216 +193.0.109.3 +193.77.50.208 +193.109.68.62 +193.150.121.37 +193.224.69.98 +194.79.8.37 +194.141.86.10 +195.12.180.94 +195.56.63.10 +195.116.93.93 +195.154.174.226 +195.159.111.98 +195.169.138.2 +195.189.126.35 +195.197.175.190 +197.242.93.82 +198.11.214.147 +198.49.41.21 +199.33.124.186 +199.204.186.146 +199.233.238.115 +199.241.189.66 +202.60.68.242 +202.60.69.232 +203.183.151.39 +203.219.14.204 +204.44.123.109 +204.44.123.162 +204.45.120.178 +206.190.134.44 +206.248.184.127 +207.244.73.8 +208.66.30.27 +209.81.9.223 +209.105.243.229 +209.126.70.159 +209.140.30.169 +209.165.128.235 +209.190.2.242 +210.66.254.236 +210.73.27.33 +211.72.66.229 +212.25.37.124 +212.71.235.114 +212.71.252.109 +212.114.48.31 +212.174.151.118 +213.66.205.194 +213.129.248.139 +213.136.87.34 +213.165.82.133 +213.167.17.6 +213.179.158.253 +213.189.53.125 +213.222.208.93 +216.49.158.161 +216.55.143.154 +216.131.91.100 +216.245.206.181 +216.250.138.230 +217.11.225.189 +217.23.6.133 +217.75.88.178 +217.172.143.140 +217.195.169.209 +217.196.248.106 +219.138.161.162 +222.167.248.90 +223.18.254.55 # Onion nodes bitcoinostk4e4re.onion:8333 diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 575e1293342..6b6e5103f5f 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -8,606 +8,518 @@ * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly. */ static SeedSpec6 pnSeed6_main[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x69,0x6a,0x7e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x04,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x0c,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x0a,0x33,0xdb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xc7,0x49,0xc6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x48,0x95,0x78}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x71,0x04}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0x0c,0xb9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x80,0x30,0xd1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x4e,0x07,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x8f,0x57}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x6e,0x28}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xaf,0xdc,0xd4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0x9b,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5c,0x63}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x89,0xde,0xed}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xd9,0x76,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0xa4,0x91,0xea}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4e,0xfa,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x00,0xa9,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc8,0x62,0xaf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xba,0xf3,0x93}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xef,0xc9,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xd5,0x0e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x70,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc2,0x97,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0xf0,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0x57,0x2e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x09,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x85,0xa8,0x46}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xdc,0x92,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0x6f,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xce,0x8c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x81,0x72,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x42,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x4f,0x4f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x51,0x01,0xc5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x90,0xba,0xb1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xd7,0xae}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe5,0x4d,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x32,0xb0,0x4b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x2b,0x93}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe6,0xcc,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x70,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xb8,0x08,0x1b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0xa3,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x88,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0xa8,0x86,0xa3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x17,0xe4,0x18}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9a,0x70,0x2e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xe9,0x62,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x03,0x65,0x6f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xd0,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xc5,0x9a,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xd6,0x6f,0x94}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x49,0x57,0x3f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x29,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x45,0xad}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x34,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x3b,0x3f,0x4c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0xfe,0x01}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x59,0x20,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x3c,0x44}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x4a,0xf2,0x44}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x46,0x42,0x04}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0x58,0x66,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x3e,0x3f,0xed}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xbf,0x85,0xf5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x41,0xd1,0x5d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x08,0x3a,0xf9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x64,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x11,0x07}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x7b,0x2e,0xf1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xb7,0x02,0x5b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x6d,0x52,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xb0,0x0c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x11,0xbe,0x2a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x9f,0xa3,0x61}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x06,0x4a,0x04}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x7d,0xaf,0xf3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc9,0x94,0xb9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x50,0x1c,0x36}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x5d,0x73,0xca}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x43,0xa7,0xec}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x79,0xec}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x78,0xd3,0xc4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc4,0xa1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd4,0x6f,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5c,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x20,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x0c,0xaa,0xb7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x98,0xed,0xc6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xcb,0xe4,0x47}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x75,0xac,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x93,0xe5,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4a,0x78,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xec,0xa5,0x18}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc8,0x1c,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x2f,0x6c,0x7c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x60,0x4d,0x5e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x6c,0x4b,0x5b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x9b,0xd9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0x87,0x39,0xe6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x17,0xb8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x1c,0x14}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x50,0x00,0x5f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x7f,0x98,0x0d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0x2a,0x24}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x9b,0x51,0x3e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x45,0xb2,0x02}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3d,0xaf,0xdf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x81,0x88}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x65,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xca,0xfe,0xab}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x35,0xf6,0x2e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xc7,0x73,0x57}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0xbc,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x39,0xc4,0x81}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xfa,0xfc,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x7d,0x17,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x75,0xc9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0xf4,0xcf,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa7,0xbd,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0xc2,0x1a,0xaa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa2,0x55,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0xaa,0x88}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x07,0xe7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4b,0xe9,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x48,0x93,0x28}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x27,0x51,0x99}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x70,0x39,0xd6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4f,0x99,0x45}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xa8,0x19,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x5f,0xe2,0x92}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xa9,0x84,0x8b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x0a,0xaa,0x5e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe5,0x4d,0xa7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x90,0xb0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x32,0xee,0x5e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xa6,0x31,0xc3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xb7,0xd9,0xc1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xb9,0x6a,0x0c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x62,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xdd,0xfe,0x4c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xa0,0x09,0x1e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4c,0xc3,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xd9,0x77,0x37}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xf2,0xdc,0x5e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xb5,0xe2,0x3c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x03,0xac,0xd2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x80,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x4c,0x3e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe2,0x95,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x77,0x39,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf0,0x3c,0x95}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4e,0x65,0x3c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x02,0x74}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0x4f,0xa1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x01,0xce,0x14}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xbb,0x5e,0xc1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc4,0x08,0x2c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x06,0xfd,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0x04,0x76}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x83,0xb3,0xff}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xef,0xc2,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x40,0x61,0xe9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xe5,0x49,0xab}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc0,0x48,0x16}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x40,0x02,0x36}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xff,0x8c,0x0e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x89,0x91,0x21}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x50,0x1f,0xb6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x6b,0x40,0x9b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x22,0x28,0xaf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x16,0x1d,0x7f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0x0d,0x56,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xbe,0x37,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xeb,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x07,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xce,0xf8,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x24,0x74,0x0f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x52,0xe9,0xde}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x1a,0x3f,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xf8,0xbd,0x61}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xc8,0x54,0xd2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x42,0xc4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x63,0x05,0xae}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa9,0xb9,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x32,0xeb,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x39,0x94,0xd9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6a,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xa5,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x52,0x6b,0xb3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0x34,0xd7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x7f,0x3d,0x33}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x1b,0x43,0x51}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xe5,0x4a,0x08}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x23,0x0a,0xa6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x69,0x67,0x5c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xcf,0x77,0x01}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3a,0x68,0xa6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xea,0xf4,0x7f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfa,0x92,0x21}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x0f,0x3a,0xa0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x39,0x3e,0xfe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x5f,0xce,0x2c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc1,0xa6,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x7e,0xfb,0x96}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x27,0x4d,0x6b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xc1,0xa0,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0xa0,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0xcc,0x1d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x12,0x69}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x3c,0xf2,0x22}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x6b,0x64,0x65}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0x9f,0x8b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x9a,0x9b,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x6b,0xfe,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xf4,0x36,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x4d,0x22,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x2e,0x95,0x5d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf7,0xb4,0x0c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbe,0x14,0xdc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x46,0xb2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x9b,0xf7,0xd3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc8,0x18,0x65}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xcf,0xa3,0x83}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1f,0x64,0x9b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0xfe,0x17}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xcc,0x08,0xd5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9b,0x36,0xa4,0x91}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4a,0xcb,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x53,0xc9,0xbb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc4,0x64,0xaf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xca,0x5e,0x60}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x68,0x6a,0x0c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x9d,0x7e,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd3,0xe6,0x78}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x31,0x1b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x01,0xaa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc2,0x03,0x46}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0xa3,0xcb,0x1e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe3,0xff,0x0e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xcb,0xfd,0xc3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6f,0x03,0x90,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x69,0x64,0x44}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x75,0xca,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xa9,0x59}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x74,0xaa,0x19}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xc8,0x22,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xd3,0x98,0xa5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xc3,0x8e,0x43}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x96,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x03,0x57,0xaf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x98,0x50}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xd8,0xad,0x36}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc1,0x83}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x9d,0x96}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x15,0x3d,0xcf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa4,0xc1,0x49}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x75,0x0b,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xff,0x8f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x51,0x1e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xef,0xd6,0x28}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xcc,0x37,0x28}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x2d,0xf4,0x02}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3f,0x0e,0x07}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0xb1,0xbc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe1,0xa4,0x14}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x68,0x09,0x82}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcb,0xcf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x7f,0xe2,0x37}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x37,0x92,0x07}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xbc,0x14,0x0c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x10,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd9,0x7c,0xcb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xd2,0xc0,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x1b,0x13,0x97}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5c,0x1e,0x6f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x9f,0x93,0xa7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xbf,0xa0,0xb7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3a,0xa8,0xaf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x3f,0xb8,0xcb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1c,0x32,0x5f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc3,0xd6,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x5b,0xac,0xde}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x10,0xf3,0x2c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x2b,0x8a,0x10}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa1,0x6f,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0xd2,0xba,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x9e,0x45}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xb8,0x08,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x48,0x70,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x5b,0x6d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xfe,0x6c,0xa6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x73,0xad}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x5b,0xac,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x17,0x84}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x37,0x41}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x86,0x13,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x12,0x5a,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x31,0xc0,0x7a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x87,0x3a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xbc,0x19,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x85,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x21,0xc5,0x6e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x22,0xb4,0xf5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0xca,0x80,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x23,0xc3,0x19}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x64,0x7b,0x13}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd9,0xff,0xcf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x08,0xe2,0xaf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0x67,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc6,0x31,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8c,0xce,0x5f,0x0e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf8,0x5e,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xca,0x26,0xad}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x1a,0xd2,0xd9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xd7,0xd0,0xdd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc0,0x4e,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcd,0xad,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x98,0x10,0x49}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3a,0x6b,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0x1e,0xaa,0xf0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa3,0xbf,0xf1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xc0,0x30,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x93,0x0f,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xe7,0x39,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0x95,0x69,0x88}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x21,0x07,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x45,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xec,0x51,0xb6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x62,0x49,0x45}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x1b,0x3d,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xcf,0x9b,0xb3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x94,0xd2,0xa1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x07,0x35}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xdd,0x88,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xf3,0xaf,0x27}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x98,0x74}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x85,0x67,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x47,0x6d,0x5e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xa5,0xab,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x37,0x5a,0x04}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc0,0x4d,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xea,0x81,0xe9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe2,0x6c,0xed}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x14,0x72,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x64,0x04,0x6c,0x6b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x45,0x49,0x5a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x47,0xf2,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x42,0x5f,0xf3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x5a,0x0f,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x15,0x08,0xfb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x58,0x4b,0xb2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x41,0x11,0x2e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x78,0xb7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x0e,0xbb,0x33}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x65,0xe2,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x48,0x94,0xa7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x42,0x25,0x42}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x03,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xcf,0xc8,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xad,0x5b,0xd6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc6,0x7b,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4d,0xbc,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdc,0x73,0x02}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xd7,0x72,0x45}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf6,0x4b,0x06}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x12,0xcd,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x81,0x82,0x60}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x87,0x00,0x13,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xf7,0x16,0x10}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x18,0xba}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa8,0xc1,0x16}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x72,0x69,0xfb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x23,0x94,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3b,0x08,0x53}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x83,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x24,0x5a,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xaa,0x72,0xc1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xcf,0x11,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x14,0x7b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x94,0x5c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x23,0x7c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6f,0x5a,0x96,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0xe2,0x90,0x78}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc4,0x8e,0xa3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x87,0xc1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xb6,0x80,0xef}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x0a,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0xd8,0xd1,0x7a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x2e,0x9e,0x86}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x5c,0xdb,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x11,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x61,0x21}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xf8,0x99,0x75}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xec,0x65,0x22}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x0e,0x4f,0x0f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x85,0x25,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xe3,0x57,0xf8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x3f,0xf8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x3b,0xc9,0x9c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0x71,0x02}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xa1,0xd8,0x5d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x6c,0xdc,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x4f,0x73,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x3b,0x5c,0x2a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xc3,0x04,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xf4,0x26,0x84}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x1b,0x3e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x3c,0x5a,0x0d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd1,0xf6,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xff,0xc7,0x21}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x3f,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xed,0xa5,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x3b,0x75,0x5d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x53,0x8d,0x0d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xf0,0x13,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x69,0x43,0x44}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0xed,0xa1,0x8c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x3f,0xed,0x10}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x40,0x9b,0x78}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x4a,0x98,0x7b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbc,0x4e,0x96}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xee,0x20,0x75}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x48,0x4f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0x40,0x5c,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x06,0xdd,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x71,0x41,0xa7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x35,0x3f,0x1d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x1f,0x7d,0x81}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa5,0x99,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x59,0x2a,0x6b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x4f,0x4f,0x8d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1e,0x3c,0xd2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x37,0x99,0x98}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe5,0x92,0x2c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xbd,0x7e,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xfb,0x62,0xa7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x6b,0x01,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xcf,0xe7,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xbd,0x35,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0xc3,0xda,0x53}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x6b,0x01,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0xb8,0x7f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc2,0x38,0x9a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x42,0xaa,0xef}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x82,0x6b,0x87}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x53,0x17,0x18}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0x59,0x46,0xdb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x68,0xc1,0xd2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0xe9,0x6f,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x27,0x45}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xca,0x4b,0x8d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3d,0x04,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xaa,0xb7,0xaa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x81,0x28,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xf1,0xae,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe6,0xd7,0xec}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x59,0x13,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x93,0xcc,0xd8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xee,0xbb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x67,0x70,0x07}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x9d,0xd3,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc5,0xed,0x0c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe1,0xd3,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x13,0xa8,0xa5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x32,0x9a,0x17}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x48,0xd3,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x68,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x01,0xe8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xef,0xe9,0xdd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0x8b,0x43}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa0,0x24,0x82,0xb4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x92,0xd6,0xcb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x75,0x90}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x1c,0x41,0xc6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x3f,0x83,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x8b,0x3f,0xf3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x46,0x5e,0x49}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe6,0xc8,0x83}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x09,0xac}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc5,0xab,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa5,0x65,0x76}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x37,0x26,0xc5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0xc5,0xd0,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x4d,0x22,0x22}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x40,0x95,0x3e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x75,0xa3,0xfa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0xdb,0x36}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x53,0x14,0xa8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x1f,0x94,0x5a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xea,0x98,0xa5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x4a,0x38,0x65}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa5,0xaa,0x10}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0xab,0xaa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x02,0xa7,0xdd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xf4,0x66,0x09}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x1c,0x57,0x68}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xee,0x40,0x8b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x09,0xac,0x33}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x4c,0x4b,0x84}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x25,0x92,0xd3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x5a,0x4d,0xba}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x02,0x63}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x55,0xf6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb1,0x4b,0x4c,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xd0,0xda,0x45}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc0,0x4b,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc3,0x06}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xba,0x1f,0xf3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x1f,0xb2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x0d,0x54}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x6a,0xb4,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x11,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x51,0x3d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xaa,0x18,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x6e,0x30,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x07,0x5c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x9a,0x25}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0xbb,0x82}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x22,0x42,0xae}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x15,0x44,0x25}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x57,0x5f,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xfd,0xd8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x38,0x3f,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0xce,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x01,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0xfc,0x17}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x45,0xe8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x61,0xd3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xed,0xd9,0xa0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x23,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x11,0x4e,0x13}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc0,0xdd,0x61}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0x72,0xba,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xed,0xf7,0xe1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc4,0x0e,0x04}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x67,0x4b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa3,0xef,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa5,0xdc,0x47}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x33,0xe9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0xac,0xa3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x71,0x24}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x86,0xcc,0xa8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xce,0xb1,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x53,0x4e,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8c,0x71,0xd2,0xd3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x34,0x55,0x22}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x89,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x17,0x34,0x87}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xad,0x55,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xaf,0x91,0xa9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x85,0xc1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x97,0x0a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xe4,0x01,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0e,0xc8,0xc8,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xbc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xc8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1e,0xf3,0x99}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x58,0xe8,0x31}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x63,0x69,0x09}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe2,0x89,0xd0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe3,0xb1,0xa1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe3,0xbf,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe5,0x2d,0x20}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xec,0x90,0x45}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xfd,0x94,0x71}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xfd,0xf1,0x16}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xff,0xe3,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x14,0xcd,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x17,0x78,0xfc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x5e,0x62,0x60}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x62,0x5f,0xc9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x6f,0x5a,0x37}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x77,0x77,0x69}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x8a,0x19,0x95}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x03,0xd6,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0x57,0x2e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0x65,0x62}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0xfa,0xba}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xcc,0x99,0x6b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x2c,0x10,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x2c,0x2c,0x0b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x78,0xa8,0xcc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8f,0x56,0x1a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x4b,0x18}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7a,0x5c,0x88}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x9a,0x6e,0x3a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x18,0x24,0x19}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x3d,0xb7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbc,0x44,0xa9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc0,0x5f,0x96}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc9,0xf6,0x74}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x0a,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x0a,0xd2,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x8a,0x9a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcc,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcd,0x43}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x26,0xeb,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa3,0x4c,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa2,0x5b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xad,0xbe,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe3,0x42,0x84}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xee,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xec,0x74,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x37,0x0e,0x41}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x07,0xfc,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x2e,0x9f,0x5b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4e,0x31,0xb5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4e,0xe7,0x39}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4f,0x99,0x41}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x22,0x2c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x7e,0x56,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x8e,0x29,0x17}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc7,0x71,0xc1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc8,0x4e,0x6b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xce,0x8a,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xfc,0x34,0x31}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa5,0x19,0x4b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa9,0x6b,0x28}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xb3,0xbe,0x38}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xbb,0x52,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x55,0xf6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x4a,0x07,0xcd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x60,0xb7,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3e,0x3a,0x26}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3f,0x5b,0x48}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3f,0x5b,0x70}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x48,0xd3,0xe4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x28,0x9a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x82,0xb2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x50,0xb9,0xd5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x6d,0x31,0x1a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xad,0x8b,0x3a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xb5,0xee,0xba}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x72,0x7f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x8d,0xe4,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x99,0xd5,0x4e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xdf,0x54,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xfb,0x58,0x70}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x1f,0x6e,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x22,0x79,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x72,0x06,0x2a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x8c,0x7d,0x62}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x9c,0xc1,0x64}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x1e,0x2f,0x74}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x23,0x84,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x60,0xc1,0xa5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x6f,0xbd,0x1a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x44,0x0a,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x72,0x21,0xfa}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x82,0x2e,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xaf,0xd7,0x87}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xbe,0xfd,0xa5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xf4,0x62,0x6f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa2,0xee,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa9,0xff,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xb7,0xad,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xdb,0xe9,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xe3,0xf0,0x73}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xf7,0xde,0x47}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x2b,0x72,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x34,0x21,0x24}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc6,0xf5,0xf1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0c,0xe2,0xa5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0d,0xc6,0xbc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0f,0xb3,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x27,0xef,0x2f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x2f,0x2d,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x3e,0xd9,0xce}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x2a,0x1f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x51,0x3d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x43,0xdb,0xc8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5a,0x84,0x9d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5e,0x1e,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x88,0xaf,0xf1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x7b,0x76,0x84}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3b,0x98,0xb6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc6,0xf8,0x97}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc8,0xf2,0x59}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xe1,0xb3,0x9d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x0e,0xbb,0x33}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x26,0x22,0xb4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x48,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x5b,0x90,0xb6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xa7,0x31,0xd9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc9,0xf3,0x37}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xdf,0x3c,0xf9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xe4,0x99,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x1a,0x65,0xe4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x32,0x9e,0xc8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xb5,0xcc,0xaa}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x39,0xc7,0xb4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x3f,0xde,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x51,0xe7,0x15}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc1,0x7e,0x52}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xcf,0xeb,0xa4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x53,0xc5,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x90,0x72,0x09}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x70,0x05,0xf7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xae,0x14,0xf7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x25,0xf0,0x8e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x39,0xca,0x6b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xac,0x7b,0x35}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xdd,0x5b,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xeb,0x30,0x30}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf5,0x4e,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x08,0x3a,0xf9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x1b,0xbf,0xb6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xec,0x8d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x83,0x58,0x2f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x9d,0xcd,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x84,0xe6,0x90}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x8f,0xbc,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa0,0xdd,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa1,0x6f,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x64,0xbd,0x03}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x93,0x8c,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xcb,0x4b,0x85}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdc,0x63,0xe3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xde,0x14,0xa9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf1,0x01,0x07}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x17,0xbf,0xf3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x26,0x0b,0xca}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x50,0x09,0x47}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x6e,0xd5,0xa5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x85,0x9b,0xed}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x22,0x25}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb5,0x9b,0xb4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x27,0x9c,0x89}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x49,0xa1,0x5f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x82,0x2d,0x28}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa5,0x99,0x2f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa8,0x80,0x85}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xb3,0xe1,0x76}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc2,0xf5,0x9e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd3,0x1e,0xf3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd9,0x85,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x83,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xe9,0xe1,0xcd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x00,0xf9,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x59,0x1f,0xf9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x80,0x1d,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x80,0xfd,0x8e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x8f,0x82,0x38}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x02,0x63}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x09,0xc4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa1,0x40,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd4,0x67,0xd4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd4,0x6f,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf6,0x4b,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x51,0x1f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x96,0x36}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x02,0x22,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x0f,0x3d,0x3c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x11,0x19,0x87}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2a,0x90,0x13}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xd2,0x87}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd7,0xa5,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xee,0x8c,0xb0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf0,0x1f,0xb8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xd6,0x89}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x8b,0xa3,0x84}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc7,0x04,0xe4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x3d,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x6c,0x4d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x7b,0x10,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x30,0x2a,0xc7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0xa8,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xe5,0x49,0xab}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xec,0xc4,0x4d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x61,0x38,0x62}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x86,0xb2,0x59}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x96,0xe9,0x13}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xa8,0x85,0x03}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x12,0xf6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x21,0xca}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x12,0x1c,0x15}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x55,0xdc,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa3,0xe3,0x1c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xb8,0x53,0x3c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xe7,0x60,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xec,0x31,0x75}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x5a,0x42,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x6a,0xc2,0x61}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x86,0x4b,0x73}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0xc1,0x24}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0xdb,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc5,0x0a,0xea}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd1,0x4d,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd2,0x6a,0x93}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd6,0xc8,0xcd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdf,0x73,0x26}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xea,0x30,0xe8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xfa,0x56,0x12}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x1b,0x07,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xff,0xcf,0x49}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x4a,0xa3,0xea}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x54,0x72,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x98,0xa6,0x1d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xab,0xd8,0xdd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xb9,0xb1,0x47}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x13,0x0c,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x2a,0x73,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4f,0xb1,0xce}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x88,0x93,0x77}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x8f,0xf5,0x05}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbc,0x32,0x27}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbe,0xe3,0x70}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xc6,0x87,0x1d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe2,0x6b,0x56}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xdb,0x5a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xe5,0xa8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf4,0xa0,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x1f,0x0a,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x55,0x19,0x29}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x69,0xa1,0x88}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0xa5,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0xc8,0xd8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa7,0x6d,0x7d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0x7d,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0xd8,0xeb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x21,0x19,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2b,0x82,0xb2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x76,0x08,0xec}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x66,0x06,0x7d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xca,0x14,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xd9,0x7d,0xe1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xea,0xd2,0x6f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x14,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x90,0xb0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x71,0x40,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xe5,0x16,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x01,0xd4,0x13}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x1e,0x2a,0xbd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe0,0xa5,0x30}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xf3,0x5e,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x6b,0x6b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x74,0xb8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x8f,0x00,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdb,0xb8,0x09}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xb9,0x26,0xae}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x06,0x04,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x08,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x21,0x14}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0xe4,0x81}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0xf0,0xad}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x33,0x14,0x56}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x95,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x97,0xac}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xa1,0x81,0xf7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xaa,0x8c,0x15}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x3c,0xd3,0xd8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0x2a,0x24}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0xac,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa3,0xeb,0xef}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbe,0xc4,0xdc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc9,0x87,0xd8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x98,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x9a,0x51}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe6,0xdc,0x7d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x9c,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x31,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x45,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x70,0x7c,0x47,0x00}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x92,0x44,0xfb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x1d,0x11,0x52}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x46,0xb0,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x75,0x29,0xa2,0xb8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x1b,0x08,0xaa}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xe6,0x07,0xd3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xf6,0x47,0x34}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xac,0x08,0x64}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x80,0x6d,0x94}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x8e,0xd7,0xa0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x16,0x5a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x09,0xcb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xe6,0x0d,0x8d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8b,0x0b,0x63}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xc6,0x72,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x11,0x3f,0x2b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xa9,0x42,0x42}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x99,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x8b,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xfc,0x66,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xc5,0x66,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x98,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x94,0x8c,0x69}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x0c,0xbd,0x44}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xe7,0xe0,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xaf,0xc3,0x1f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xa4,0x60}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xfe,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x61,0x45,0x4c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x7b,0x07,0x07}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x7b,0x07,0x27}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0xba,0x11,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0xf7,0xa9,0xbe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0xf2,0xd1,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x66,0x5e,0x26}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x77,0x11,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x74,0xa0,0xb0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x22,0x2a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0xd2,0xd9,0xaa}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0xff,0xa6,0xc2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8f,0xd7,0x81,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xf4,0x13}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x94,0x34,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x94,0x50,0x39}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x13,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x8e,0x56}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0xfd,0x33}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0xfb,0x06,0xd6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x9a,0x9b,0xeb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x85,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0xe0,0xf8,0xfc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x79,0x4b,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x7f,0xfb,0x43}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x14,0x02,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9d,0x0d,0x3d,0x05}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0x3a,0xad,0x30}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x17,0x84}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x6e,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd5,0xfe,0xcd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xef,0xfe,0x64}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf2,0x96,0x27}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x51,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0xeb,0x38}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf4,0x4f,0x10}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf5,0xd9,0x77}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf8,0x66,0x75}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfb,0x6c,0x35}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfe,0x95,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xff,0x74,0x4e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x46,0x5e,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x58,0x2d,0x7c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x58,0x78,0xd2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x1a,0x31,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x1e,0x0e,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x50,0x72,0xc5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xa7,0xd6,0xf3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd0,0xdb,0x6c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xdc,0x43,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xec,0x65,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf6,0x6b,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xff,0xed,0xf1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x02,0xd5,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x33,0x17,0xe0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x33,0x7b,0x9f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x39,0xd4,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x6d,0x21,0x1c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x7e,0x7c,0x5b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x7e,0x7c,0x5c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x0a,0x74,0xf2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x23,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x63,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7c,0x6e,0x2f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xc2,0x21,0x2c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xdf,0xc9,0xc6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x1a,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x24,0x30}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xd4,0x8d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xfe,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4e,0xfa,0x03}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x9b,0x56,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xaf,0x86,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xf8,0x6f,0x04}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x01,0xaa}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x22,0xa1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0x2b,0x72,0x0e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0xd5,0xd0,0x1c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x44,0x02,0x2e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x48,0xee,0x2a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe2,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe3,0x3a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0x8b,0x3a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0xce,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x0a,0x30,0x75}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x15,0xd8,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x26,0x2f,0xe0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x2d,0xc0,0x81}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x81,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x83,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x37,0x35,0x3d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x37,0x35,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3d,0x77,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3d,0x94,0xcb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xba,0x02,0xa7,0x17}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x5c,0x4b,0xb2}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7a,0x5c,0x86}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x64,0x17,0x77}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x75,0x46}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x26,0x48,0x4e,0x35}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc1,0x7a,0xb6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0xf2,0xcc,0xae}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x5b,0x62,0xea}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x03,0xd6,0xbc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xeb,0x81,0x5e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x47,0xb3,0x74}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6a,0xa5,0x3c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x45,0xee,0x54}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xa8,0x38}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0xc2,0xa3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x57,0x01,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xde,0x7a,0x5d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xae,0x03,0xa0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xd3,0xc1,0x2b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x09,0xf5,0x13}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x26,0xb3,0x7a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x9f,0x2e,0x54}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6b,0x13,0x53}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x51,0xdf,0x7f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x97,0x21,0x80}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcc,0xd2,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x09,0xd0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0xd1,0x94}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe2,0xce,0xef}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x08,0x7c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x0a,0x93}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x00,0x82,0x8e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x03,0x59,0x9f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x49,0xea,0x8a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x4b,0x5f,0x6b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x64,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x9b,0x54,0xb5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xa9,0xe9,0xce}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5d,0x56}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xe3,0x87,0xd8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x00,0x6d,0x03}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x4d,0x32,0xd0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6d,0x44,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x96,0x79,0x25}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xe0,0x45,0x62}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x4f,0x08,0x25}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x8d,0x56,0x0a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x0c,0xb4,0x5e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x38,0x3f,0x0a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x74,0x5d,0x5d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9a,0xae,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9f,0x6f,0x62}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xa9,0x8a,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xbd,0x7e,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xc5,0xaf,0xbe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc5,0xf2,0x5d,0x52}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x0b,0xd6,0x93}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x31,0x29,0x15}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x21,0x7c,0xba}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xcc,0xba,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xe9,0xee,0x73}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xf1,0xbd,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x44,0xf2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x45,0xe8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xb7,0x97,0x27}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xdb,0x0e,0xcc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2c,0x7b,0x6d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2c,0x7b,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2d,0x78,0xb2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xbe,0x86,0x2c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0xb8,0x7f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xf4,0x49,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x42,0x1e,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x51,0x09,0xdf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x69,0xf3,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x46,0x9f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x8c,0x1e,0xa9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xa5,0x80,0xeb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xbe,0x02,0xf2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x42,0xfe,0xec}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x49,0x1b,0x21}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x48,0x42,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x19,0x25,0x7c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xeb,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xfc,0x6d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x72,0x30,0x1f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0xae,0x97,0x76}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x42,0xcd,0xc2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x81,0xf8,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x88,0x57,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa5,0x52,0x85}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa7,0x11,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xb3,0x9e,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xbd,0x35,0x7d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xde,0xd0,0x5d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x31,0x9e,0xa1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x37,0x8f,0x9a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x83,0x5b,0x64}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf5,0xce,0xb5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xfa,0x8a,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x0b,0xe1,0xbd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x06,0x85}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x4b,0x58,0xb2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0x8f,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xc3,0xa9,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xc4,0xf8,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdb,0x8a,0xa1,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xde,0xa7,0xf8,0x5a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0x12,0xfe,0x37}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xae,0x94,0xd5,0xc2,0x72,0x24}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xea,0xb9,0x5b,0x63,0x1d,0x94,0xe2,0xed,0xec,0xa1}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xce,0x36,0xa1,0xc1,0xd6,0x64,0x43,0xfb,0xb3,0xe7}, 8333}, From e179eb3d9bfec7e67908242c71c87b716a41c97c Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 29 Dec 2014 00:25:18 +0100 Subject: [PATCH 0143/2337] Make the command-line-args dialog better Instead of using a fixed-width font in a label, which virtually guarentees a horizontal scrollbar, use a proper text-document that can re-layout based on user input. --- src/qt/forms/helpmessagedialog.ui | 20 ++++++-- src/qt/utilitydialog.cpp | 84 +++++++++++++++++++++++++------ 2 files changed, 85 insertions(+), 19 deletions(-) diff --git a/src/qt/forms/helpmessagedialog.ui b/src/qt/forms/helpmessagedialog.ui index 81dbd90b12d..9ace9afd793 100644 --- a/src/qt/forms/helpmessagedialog.ui +++ b/src/qt/forms/helpmessagedialog.ui @@ -6,8 +6,8 @@ 0 0 - 800 - 400 + 585 + 225 @@ -34,6 +34,13 @@ + + + + true + + + @@ -47,19 +54,22 @@ 0 0 - 659 - 348 + 447 + 68 - + IBeamCursor Qt::PlainText + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + true diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index e6cec8173e9..9ee408179d0 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include /** "Help message" or "About" dialog box */ @@ -52,28 +54,82 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : // Replace newlines with HTML breaks licenseInfoHTML.replace("\n\n", "

"); - ui->helpMessageLabel->setTextFormat(Qt::RichText); + ui->aboutMessage->setTextFormat(Qt::RichText); ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); text = version + "\n" + licenseInfo; - ui->helpMessageLabel->setText(version + "

" + licenseInfoHTML); - ui->helpMessageLabel->setWordWrap(true); + ui->aboutMessage->setText(version + "

" + licenseInfoHTML); + ui->aboutMessage->setWordWrap(true); + ui->helpMessage->setVisible(false); } else { setWindowTitle(tr("Command-line options")); - QString header = tr("Usage:") + "\n" + - " bitcoin-qt [" + tr("command-line options") + "] " + "\n"; + QTextCursor cursor(ui->helpMessage->document()); + cursor.insertText(version); + cursor.insertBlock(); + cursor.insertText(tr("Usage:") + '\n' + + " bitcoin-qt [" + tr("command-line options") + "]\n"); + + cursor.insertBlock(); + QTextTableFormat tf; + tf.setBorderStyle(QTextFrameFormat::BorderStyle_None); + tf.setCellPadding(2); + QVector widths; + widths << QTextLength(QTextLength::PercentageLength, 20); + widths << QTextLength(QTextLength::PercentageLength, 80); + tf.setColumnWidthConstraints(widths); + QTextTable *table = cursor.insertTable(2, 2, tf); QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT)); + bool first = true; + QTextCharFormat bold; + bold.setFontWeight(QFont::Bold); + // note that coreOptions is not translated. + foreach (const QString &line, coreOptions.split('\n')) { + if (!first) { + table->appendRows(1); + cursor.movePosition(QTextCursor::NextRow); + } + first = false; - QString uiOptions = tr("UI options") + ":\n" + - " -choosedatadir " + tr("Choose data directory on startup (default: 0)") + "\n" + - " -lang= " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" + - " -min " + tr("Start minimized") + "\n" + - " -rootcertificates= " + tr("Set SSL root certificates for payment request (default: -system-)") + "\n" + - " -splash " + tr("Show splash screen on startup (default: 1)"); + if (line.startsWith(" ")) { + int index = line.indexOf(' ', 3); + if (index > 0) { + cursor.insertText(line.left(index).trimmed()); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText(line.mid(index).trimmed()); + continue; + } + } + cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor); + table->mergeCells(cursor); + cursor.insertText(line.trimmed(), bold); + } - ui->helpMessageLabel->setFont(GUIUtil::bitcoinAddressFont()); - text = version + "\n" + header + "\n" + coreOptions + "\n" + uiOptions; - ui->helpMessageLabel->setText(text); + table->appendRows(6); + cursor.movePosition(QTextCursor::NextRow); + cursor.insertText(tr("UI options") + ":", bold); + cursor.movePosition(QTextCursor::NextRow); + cursor.insertText("-choosedatadir"); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText(tr("Choose data directory on startup (default: 0)")); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText("-lang="); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText(tr("Set language, for example \"de_DE\" (default: system locale)")); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText("-min"); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText(tr("Start minimized")); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText("-rootcertificates="); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText(tr("Set SSL root certificates for payment request (default: -system-)")); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText("-splash"); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText(tr("Show splash screen on startup (default: 1)")); + + ui->helpMessage->moveCursor(QTextCursor::Start); + ui->scrollArea->setVisible(false); } } From 1a9576de9dbb1910cb8462e513938d45ef7b5a23 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 18 Dec 2014 14:49:19 +0100 Subject: [PATCH 0144/2337] Use libsecp256k1's RFC6979 implementation --- src/Makefile.am | 2 -- src/crypto/rfc6979_hmac_sha256.cpp | 47 ------------------------------ src/crypto/rfc6979_hmac_sha256.h | 36 ----------------------- src/key.cpp | 45 +++++++++++++--------------- src/test/crypto_tests.cpp | 35 ---------------------- 5 files changed, 21 insertions(+), 144 deletions(-) delete mode 100644 src/crypto/rfc6979_hmac_sha256.cpp delete mode 100644 src/crypto/rfc6979_hmac_sha256.h diff --git a/src/Makefile.am b/src/Makefile.am index bc2b1aff963..5a5b9cc3d8c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -209,14 +209,12 @@ crypto_libbitcoin_crypto_a_SOURCES = \ crypto/sha256.cpp \ crypto/sha512.cpp \ crypto/hmac_sha256.cpp \ - crypto/rfc6979_hmac_sha256.cpp \ crypto/hmac_sha512.cpp \ crypto/ripemd160.cpp \ crypto/common.h \ crypto/sha256.h \ crypto/sha512.h \ crypto/hmac_sha256.h \ - crypto/rfc6979_hmac_sha256.h \ crypto/hmac_sha512.h \ crypto/sha1.h \ crypto/ripemd160.h diff --git a/src/crypto/rfc6979_hmac_sha256.cpp b/src/crypto/rfc6979_hmac_sha256.cpp deleted file mode 100644 index a8c971c3ba9..00000000000 --- a/src/crypto/rfc6979_hmac_sha256.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2014 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "crypto/rfc6979_hmac_sha256.h" - -#include - -#include - -static const unsigned char zero[1] = {0x00}; -static const unsigned char one[1] = {0x01}; - -RFC6979_HMAC_SHA256::RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen) : retry(false) -{ - memset(V, 0x01, sizeof(V)); - memset(K, 0x00, sizeof(K)); - - CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Write(key, keylen).Write(msg, msglen).Finalize(K); - CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V); - CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(one, sizeof(one)).Write(key, keylen).Write(msg, msglen).Finalize(K); - CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V); -} - -RFC6979_HMAC_SHA256::~RFC6979_HMAC_SHA256() -{ - memset(V, 0x01, sizeof(V)); - memset(K, 0x00, sizeof(K)); -} - -void RFC6979_HMAC_SHA256::Generate(unsigned char* output, size_t outputlen) -{ - if (retry) { - CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Finalize(K); - CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V); - } - - while (outputlen > 0) { - CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V); - size_t len = std::min(outputlen, sizeof(V)); - memcpy(output, V, len); - output += len; - outputlen -= len; - } - - retry = true; -} diff --git a/src/crypto/rfc6979_hmac_sha256.h b/src/crypto/rfc6979_hmac_sha256.h deleted file mode 100644 index f3a54a5d118..00000000000 --- a/src/crypto/rfc6979_hmac_sha256.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2014 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_RFC6979_HMAC_SHA256_H -#define BITCOIN_RFC6979_HMAC_SHA256_H - -#include "crypto/hmac_sha256.h" - -#include -#include - -/** The RFC 6979 PRNG using HMAC-SHA256. */ -class RFC6979_HMAC_SHA256 -{ -private: - unsigned char V[CHMAC_SHA256::OUTPUT_SIZE]; - unsigned char K[CHMAC_SHA256::OUTPUT_SIZE]; - bool retry; - -public: - /** - * Construct a new RFC6979 PRNG, using the given key and message. - * The message is assumed to be already hashed. - */ - RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen); - - /** - * Generate a byte array. - */ - void Generate(unsigned char* output, size_t outputlen); - - ~RFC6979_HMAC_SHA256(); -}; - -#endif // BITCOIN_RFC6979_HMAC_SHA256_H diff --git a/src/key.cpp b/src/key.cpp index 2235c271d18..d8319db1a35 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -6,7 +6,6 @@ #include "arith_uint256.h" #include "crypto/hmac_sha512.h" -#include "crypto/rfc6979_hmac_sha256.h" #include "eccryptoverify.h" #include "pubkey.h" #include "random.h" @@ -74,23 +73,28 @@ CPubKey CKey::GetPubKey() const { return result; } +extern "C" +{ +static int secp256k1_nonce_function_test_case(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int attempt, const void *data) +{ + const uint32_t *test_case = static_cast(data); + uint256 nonce; + secp256k1_nonce_function_rfc6979(nonce.begin(), msg32, key32, attempt, NULL); + nonce = ArithToUint256(UintToArith256(nonce) + *test_case); + memcpy(nonce32, nonce.begin(), 32); + return 1; +} +} + bool CKey::Sign(const uint256 &hash, std::vector& vchSig, uint32_t test_case) const { if (!fValid) return false; vchSig.resize(72); - RFC6979_HMAC_SHA256 prng(begin(), 32, (unsigned char*)&hash, 32); - do { - uint256 nonce; - prng.Generate((unsigned char*)&nonce, 32); - nonce = ArithToUint256(UintToArith256(nonce) + test_case); - int nSigLen = 72; - int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce); - nonce = uint256(); - if (ret) { - vchSig.resize(nSigLen); - return true; - } - } while(true); + int nSigLen = 72; + int ret = secp256k1_ecdsa_sign(hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), test_case == 0 ? secp256k1_nonce_function_rfc6979 : secp256k1_nonce_function_test_case, test_case == 0 ? NULL : &test_case); + assert(ret); + vchSig.resize(nSigLen); + return true; } bool CKey::VerifyPubKey(const CPubKey& pubkey) const { @@ -101,7 +105,7 @@ bool CKey::VerifyPubKey(const CPubKey& pubkey) const { std::string str = "Bitcoin key verification\n"; GetRandBytes(rnd, sizeof(rnd)); uint256 hash; - CHash256().Write((unsigned char*)str.data(), str.size()).Write(rnd, sizeof(rnd)).Finalize((unsigned char*)&hash); + CHash256().Write((unsigned char*)str.data(), str.size()).Write(rnd, sizeof(rnd)).Finalize(hash.begin()); std::vector vchSig; Sign(hash, vchSig); return pubkey.Verify(hash, vchSig); @@ -112,15 +116,8 @@ bool CKey::SignCompact(const uint256 &hash, std::vector& vchSig) return false; vchSig.resize(65); int rec = -1; - RFC6979_HMAC_SHA256 prng(begin(), 32, (unsigned char*)&hash, 32); - do { - uint256 nonce; - prng.Generate((unsigned char*)&nonce, 32); - int ret = secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, &vchSig[1], begin(), (unsigned char*)&nonce, &rec); - nonce = uint256(); - if (ret) - break; - } while(true); + int ret = secp256k1_ecdsa_sign_compact(hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec); + assert(ret); assert(rec != -1); vchSig[0] = 27 + rec + (fCompressed ? 4 : 0); return true; diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 47bfd710cde..d5e595cd8ad 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "crypto/rfc6979_hmac_sha256.h" #include "crypto/ripemd160.h" #include "crypto/sha1.h" #include "crypto/sha256.h" @@ -248,38 +247,4 @@ BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) { "b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"); } -void TestRFC6979(const std::string& hexkey, const std::string& hexmsg, const std::vector& hexout) -{ - std::vector key = ParseHex(hexkey); - std::vector msg = ParseHex(hexmsg); - RFC6979_HMAC_SHA256 rng(&key[0], key.size(), &msg[0], msg.size()); - - for (unsigned int i = 0; i < hexout.size(); i++) { - std::vector out = ParseHex(hexout[i]); - std::vector gen; - gen.resize(out.size()); - rng.Generate(&gen[0], gen.size()); - BOOST_CHECK(out == gen); - } -} - -BOOST_AUTO_TEST_CASE(rfc6979_hmac_sha256) -{ - TestRFC6979( - "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f00", - "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a", - boost::assign::list_of - ("4fe29525b2086809159acdf0506efb86b0ec932c7ba44256ab321e421e67e9fb") - ("2bf0fff1d3c378a22dc5de1d856522325c65b504491a0cbd01cb8f3aa67ffd4a") - ("f528b410cb541f77000d7afb6c5b53c5c471eab43e466d9ac5190c39c82fd82e")); - - TestRFC6979( - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - boost::assign::list_of - ("9c236c165b82ae0cd590659e100b6bab3036e7ba8b06749baf6981e16f1a2b95") - ("df471061625bc0ea14b682feee2c9c02f235da04204c1d62a1536c6e17aed7a9") - ("7597887cbd76321f32e30440679a22cf7f8d9d2eac390e581fea091ce202ba94")); -} - BOOST_AUTO_TEST_SUITE_END() From 7873633b5752621548b8d38fc175f5a5f2f1e5d6 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 6 Jan 2015 00:28:47 +0100 Subject: [PATCH 0145/2337] Squashed 'src/secp256k1/' changes from bccaf86..50cc6ab 50cc6ab Merge pull request #178 941e221 Add tests for handling of the nonce function in signing. 10c81ff Merge pull request #177 7688e34 Add magnitude limits to secp256k1_fe_verify to ensure that it's own tests function correctly. 4ee4f7a Merge pull request #176 70ae0d2 Use secp256k1_fe_equal_var in secp256k1_fe_sqrt_var. 7767b4d Merge pull request #175 9ab9335 Add a reference consistency test to ge_tests. 60571c6 Rework group tests d26e26f Avoid constructing an invalid signature with probability 1:2^256. b450c34 Merge pull request #163 d57cae9 Merge pull request #154 49ee0db Add _normalizes_to_zero_var variant eed599d Add _fe_normalizes_to_zero method d7174ed Weak normalization for secp256k1_fe_equal 0295f0a weak normalization bbd5ba7 Use rfc6979 as default nonce generation function b37fbc2 Implement SHA256 / HMAC-SHA256 / RFC6979. c6e7f4e [API BREAK] Use a nonce-generation function instead of a nonce cf0c48b Merge pull request #169 603c33b Make signing fail if a too small buffer is passed. 6d16606 Merge pull request #168 7277fd7 Remove GMP field implementation e99c4c4 Merge pull request #123 13278f6 Add explanation about how inversion can be avoided ce7eb6f Optimize verification: avoid field inverse a098f78 Merge pull request #160 38acd01 Merge pull request #165 6a59012 Make git ignore bench_recover when configured with benchmark enabled 1ba4a60 Configure options reorganization 3c0f246 Merge pull request #157 808dd9b Merge pull request #156 8dc75e9 Merge pull request #158 28ade27 build: nuke bashisms 5190079 build: use subdir-objects for automake 8336040 build: disable benchmark by default git-subtree-dir: src/secp256k1 git-subtree-split: 50cc6ab0625efda6dddf1dc86c1e2671f069b0d8 --- .gitignore | 1 + .travis.yml | 14 +- Makefile.am | 4 +- build-aux/m4/bitcoin_secp.m4 | 20 +- configure.ac | 113 ++++---- include/secp256k1.h | 51 +++- src/bench_sign.c | 5 +- src/bench_verify.c | 4 +- src/ecdsa_impl.h | 59 +++-- src/ecmult_gen_impl.h | 2 +- src/ecmult_impl.h | 4 +- src/field.h | 19 +- src/field_10x26_impl.h | 111 +++++++- src/field_5x52_impl.h | 96 +++++-- src/field_gmp.h | 18 -- src/field_gmp_impl.h | 184 ------------- src/field_impl.h | 16 +- src/group.h | 7 +- src/group_impl.h | 66 ++--- src/hash.h | 41 +++ src/hash_impl.h | 291 +++++++++++++++++++++ src/secp256k1.c | 73 ++++-- src/tests.c | 492 +++++++++++++++++++++++++++-------- 23 files changed, 1167 insertions(+), 524 deletions(-) delete mode 100644 src/field_gmp.h delete mode 100644 src/field_gmp_impl.h create mode 100644 src/hash.h create mode 100644 src/hash_impl.h diff --git a/.gitignore b/.gitignore index f0a54077a54..b9f7d243ecb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ bench_inv bench_sign bench_verify +bench_recover tests *.exe *.so diff --git a/.travis.yml b/.travis.yml index 28cd61dbc9b..40f8dae23f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,24 +4,22 @@ compiler: - gcc install: - sudo apt-get install -qq libssl-dev - - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" -o "$FIELD" = "gmp" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi + - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi - if [ -n "$EXTRAPACKAGES" ]; then sudo apt-get update && sudo apt-get install --no-install-recommends --no-upgrade $EXTRAPACKAGES; fi env: global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES= + - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES= matrix: - SCALAR=32bit - SCALAR=64bit - - FIELD=gmp - - FIELD=gmp ENDOMORPHISM=yes - - FIELD=64bit_asm - - FIELD=64bit_asm ENDOMORPHISM=yes - FIELD=64bit - FIELD=64bit ENDOMORPHISM=yes + - FIELD=64bit ASM=x86_64 + - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 - FIELD=32bit - FIELD=32bit ENDOMORPHISM=yes - - BIGNUM=none - - BIGNUM=none ENDOMORPHISM=yes + - BIGNUM=no + - BIGNUM=no ENDOMORPHISM=yes - BUILD=distcheck - EXTRAFLAGS=CFLAGS=-DDETERMINISTIC - HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" diff --git a/Makefile.am b/Makefile.am index 390d2c9ffa4..985c172eba2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,8 +33,8 @@ noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h noinst_HEADERS += src/util.h noinst_HEADERS += src/testrand.h noinst_HEADERS += src/testrand_impl.h -noinst_HEADERS += src/field_gmp.h -noinst_HEADERS += src/field_gmp_impl.h +noinst_HEADERS += src/hash.h +noinst_HEADERS += src/hash_impl.h noinst_HEADERS += src/field.h noinst_HEADERS += src/field_impl.h noinst_HEADERS += src/bench.h diff --git a/build-aux/m4/bitcoin_secp.m4 b/build-aux/m4/bitcoin_secp.m4 index 1373478c9c5..4a398d6c93a 100644 --- a/build-aux/m4/bitcoin_secp.m4 +++ b/build-aux/m4/bitcoin_secp.m4 @@ -1,12 +1,6 @@ dnl libsecp25k1 helper checks AC_DEFUN([SECP_INT128_CHECK],[ has_int128=$ac_cv_type___int128 -if test x"$has_int128" != x"yes" && test x"$set_field" = x"64bit"; then - AC_MSG_ERROR([$set_field field support explicitly requested but is not compatible with this host]) -fi -if test x"$has_int128" != x"yes" && test x"$set_scalar" = x"64bit"; then - AC_MSG_ERROR([$set_scalar scalar support explicitly requested but is not compatible with this host]) -fi ]) dnl @@ -18,11 +12,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ __asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); ]])],[has_64bit_asm=yes],[has_64bit_asm=no]) AC_MSG_RESULT([$has_64bit_asm]) -if test x"$set_field" == x"64bit_asm"; then - if test x"$has_64bit_asm" == x"no"; then - AC_MSG_ERROR([$set_field field support explicitly requested but no x86_64 assembly available]) - fi -fi ]) dnl @@ -43,7 +32,7 @@ else )]) LIBS= fi -if test x"$has_libcrypto" == x"yes" && test x"$has_openssl_ec" = x; then +if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then AC_MSG_CHECKING(for EC functions in libcrypto) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include @@ -69,11 +58,4 @@ if test x"$has_gmp" != x"yes"; then CPPFLAGS="$CPPFLAGS_TEMP" LIBS="$LIBS_TEMP" fi -if test x"$set_field" = x"gmp" && test x"$has_gmp" != x"yes"; then - AC_MSG_ERROR([$set_field field support explicitly requested but libgmp was not found]) -fi -if test x"$set_bignum" = x"gmp" && test x"$has_gmp" != x"yes"; then - AC_MSG_ERROR([$set_bignum field support explicitly requested but libgmp was not found]) -fi ]) - diff --git a/configure.ac b/configure.ac index 40e121e8064..f691156ff74 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ AC_CANONICAL_HOST AH_TOP([#ifndef LIBSECP256K1_CONFIG_H]) AH_TOP([#define LIBSECP256K1_CONFIG_H]) AH_BOTTOM([#endif //LIBSECP256K1_CONFIG_H]) -AM_INIT_AUTOMAKE([foreign]) +AM_INIT_AUTOMAKE([foreign subdir-objects]) LT_INIT dnl make the compilation flags quiet unless V=1 is used @@ -23,7 +23,7 @@ if test "x$CFLAGS" = "x"; then fi AC_PROG_CC_C99 -if test x"$ac_cv_prog_cc_c99" == x"no"; then +if test x"$ac_cv_prog_cc_c99" = x"no"; then AC_MSG_ERROR([c99 compiler support required]) fi @@ -82,9 +82,9 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], AC_ARG_ENABLE(benchmark, - AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is yes)]), + AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is no)]), [use_benchmark=$enableval], - [use_benchmark=yes]) + [use_benchmark=no]) AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]), @@ -96,15 +96,18 @@ AC_ARG_ENABLE(endomorphism, [use_endomorphism=$enableval], [use_endomorphism=no]) -AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=gmp|64bit|64bit_asm|32bit|auto], +AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto], [Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto]) -AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|none|auto], +AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto], [Specify Bignum Implementation. Default is auto])],[req_bignum=$withval], [req_bignum=auto]) AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto], [Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto]) +AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|no|auto] +[Specify assembly optimizations to use. Default is auto])],[req_asm=$withval], [req_asm=auto]) + AC_CHECK_TYPES([__int128]) AC_MSG_CHECKING([for __builtin_expect]) @@ -113,40 +116,54 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])], [ AC_MSG_RESULT([no]) ]) -if test x"$req_field" = x"auto"; then +if test x"$req_asm" = x"auto"; then SECP_64BIT_ASM_CHECK if test x"$has_64bit_asm" = x"yes"; then - set_field=64bit_asm + set_asm=x86_64 fi + if test x"$set_asm" = x; then + set_asm=no + fi +else + set_asm=$req_asm + case $set_asm in + x86_64) + SECP_64BIT_ASM_CHECK + if test x"$has_64bit_asm" != x"yes"; then + AC_MSG_ERROR([x86_64 assembly optimization requested but not available]) + fi + ;; + no) + ;; + *) + AC_MSG_ERROR([invalid assembly optimization selection]) + ;; + esac +fi +if test x"$req_field" = x"auto"; then + if test x"set_asm" = x"x86_64"; then + set_field=64bit + fi if test x"$set_field" = x; then SECP_INT128_CHECK if test x"$has_int128" = x"yes"; then set_field=64bit fi fi - - if test x"$set_field" = x; then - SECP_GMP_CHECK - if test x"$has_gmp" = x"yes"; then - set_field=gmp - fi - fi - if test x"$set_field" = x; then set_field=32bit fi else set_field=$req_field case $set_field in - 64bit_asm) - SECP_64BIT_ASM_CHECK - ;; 64bit) - SECP_INT128_CHECK - ;; - gmp) - SECP_GMP_CHECK + if test x"$set_asm" != x"x86_64"; then + SECP_INT128_CHECK + if test x"$has_int128" != x"yes"; then + AC_MSG_ERROR([64bit field explicitly requested but neither __int128 support or x86_64 assembly available]) + fi + fi ;; 32bit) ;; @@ -157,11 +174,9 @@ else fi if test x"$req_scalar" = x"auto"; then - if test x"$set_scalar" = x; then - SECP_INT128_CHECK - if test x"$has_int128" = x"yes"; then - set_scalar=64bit - fi + SECP_INT128_CHECK + if test x"$has_int128" = x"yes"; then + set_scalar=64bit fi if test x"$set_scalar" = x; then set_scalar=32bit @@ -171,6 +186,9 @@ else case $set_scalar in 64bit) SECP_INT128_CHECK + if test x"$has_int128" != x"yes"; then + AC_MSG_ERROR([64bit scalar explicitly requested but __int128 support not available]) + fi ;; 32bit) ;; @@ -187,15 +205,18 @@ if test x"$req_bignum" = x"auto"; then fi if test x"$set_bignum" = x; then - set_bignum=none + set_bignum=no fi else set_bignum=$req_bignum case $set_bignum in gmp) SECP_GMP_CHECK + if test x"$has_gmp" != x"yes"; then + AC_MSG_ERROR([gmp bignum explicitly requested but libgmp not available]) + fi ;; - none) + no) ;; *) AC_MSG_ERROR([invalid bignum implementation selection]) @@ -203,20 +224,23 @@ else esac fi +# select assembly optimization +case $set_asm in +x86_64) + AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations]) + ;; +no) + ;; +*) + AC_MSG_ERROR([invalid assembly optimizations]) + ;; +esac + # select field implementation case $set_field in -64bit_asm) - AC_DEFINE(USE_FIELD_5X52_ASM, 1, [Define this symbol to use the assembly version for the 5x52 field implementation]) - AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation]) - ;; 64bit) - AC_DEFINE(USE_FIELD_5X52_INT128, 1, [Define this symbol to use the __int128 version for the 5x52 field implementation]) AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation]) ;; -gmp) - AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed]) - AC_DEFINE(USE_FIELD_GMP, 1, [Define this symbol to use the FIELD_GMP implementation]) - ;; 32bit) AC_DEFINE(USE_FIELD_10X26, 1, [Define this symbol to use the FIELD_10X26 implementation]) ;; @@ -233,7 +257,7 @@ gmp) AC_DEFINE(USE_FIELD_INV_NUM, 1, [Define this symbol to use the num-based field inverse implementation]) AC_DEFINE(USE_SCALAR_INV_NUM, 1, [Define this symbol to use the num-based scalar inverse implementation]) ;; -none) +no) AC_DEFINE(USE_NUM_NONE, 1, [Define this symbol to use no num implementation]) AC_DEFINE(USE_FIELD_INV_BUILTIN, 1, [Define this symbol to use the native field inverse implementation]) AC_DEFINE(USE_SCALAR_INV_BUILTIN, 1, [Define this symbol to use the native scalar inverse implementation]) @@ -258,7 +282,7 @@ esac if test x"$use_tests" = x"yes"; then SECP_OPENSSL_CHECK - if test x"$has_openssl_ec" == x"yes"; then + if test x"$has_openssl_ec" = x"yes"; then AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" SECP_TEST_LIBS="$CRYPTO_LIBS" @@ -272,7 +296,7 @@ if test x"$use_tests" = x"yes"; then fi fi -if test x"$set_field" = x"gmp" || test x"$set_bignum" = x"gmp"; then +if test x"$set_bignum" = x"gmp"; then SECP_LIBS="$SECP_LIBS $GMP_LIBS" SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS" fi @@ -281,9 +305,11 @@ if test x"$use_endomorphism" = x"yes"; then AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization]) fi +AC_MSG_NOTICE([Using assembly optimizations: $set_asm]) AC_MSG_NOTICE([Using field implementation: $set_field]) AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) AC_MSG_NOTICE([Using scalar implementation: $set_scalar]) +AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism]) AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) AC_CONFIG_FILES([Makefile libsecp256k1.pc]) @@ -291,9 +317,8 @@ AC_SUBST(SECP_INCLUDES) AC_SUBST(SECP_LIBS) AC_SUBST(SECP_TEST_LIBS) AC_SUBST(SECP_TEST_INCLUDES) -AM_CONDITIONAL([USE_ASM], [test x"$set_field" == x"64bit_asm"]) AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) -AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" != x"no"]) +AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"]) dnl make sure nothing new is exported so that we don't break the cache PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" diff --git a/include/secp256k1.h b/include/secp256k1.h index dca7ca00e7e..cfdae31eaf8 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -77,42 +77,73 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( int pubkeylen ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); +/** A pointer to a function to deterministically generate a nonce. + * Returns: 1 if a nonce was succesfully generated. 0 will cause signing to fail. + * In: msg32: the 32-byte message hash being verified (will not be NULL) + * key32: pointer to a 32-byte secret key (will not be NULL) + * attempt: how many iterations we have tried to find a nonce. + * This will almost always be 0, but different attempt values + * are required to result in a different nonce. + * data: Arbitrary data pointer that is passed through. + * Out: nonce32: pointer to a 32-byte array to be filled by the function. + * Except for test cases, this function should compute some cryptographic hash of + * the message, the key and the attempt. + */ +typedef int (*secp256k1_nonce_function_t)( + unsigned char *nonce32, + const unsigned char *msg32, + const unsigned char *key32, + unsigned int attempt, + const void *data +); + +/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. */ +extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979; + +/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ +extern const secp256k1_nonce_function_t secp256k1_nonce_function_default; + + /** Create an ECDSA signature. * Returns: 1: signature created - * 0: nonce invalid, try another one + * 0: the nonce generation function failed * In: msg32: the 32-byte message hash being signed (cannot be NULL) * seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid) - * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG) + * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used + * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) * In/Out: siglen: pointer to an int with the length of sig, which will be updated * to contain the actual signature length (<=72). * Requires starting using SECP256K1_START_SIGN. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign( +int secp256k1_ecdsa_sign( const unsigned char *msg32, unsigned char *sig, int *siglen, const unsigned char *seckey, - const unsigned char *nonce -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); + secp256k1_nonce_function_t noncefp, + const void *ndata +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Create a compact ECDSA signature (64 byte + recovery id). * Returns: 1: signature created - * 0: nonce invalid, try another one + * 0: the nonce generation function failed * In: msg32: the 32-byte message hash being signed (cannot be NULL) * seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid) - * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG) + * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used + * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) * Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL) * recid: pointer to an int, which will be updated to contain the recovery id (can be NULL) * Requires starting using SECP256K1_START_SIGN. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign_compact( +int secp256k1_ecdsa_sign_compact( const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, - const unsigned char *nonce, + secp256k1_nonce_function_t noncefp, + const void *ndata, int *recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Recover an ECDSA public key from a compact signature. * Returns: 1: public key successfully recovered (which guarantees a correct signature). diff --git a/src/bench_sign.c b/src/bench_sign.c index 66e71e1ac42..2276f00b9a6 100644 --- a/src/bench_sign.c +++ b/src/bench_sign.c @@ -10,7 +10,6 @@ typedef struct { unsigned char msg[32]; - unsigned char nonce[32]; unsigned char key[32]; } bench_sign_t; @@ -18,7 +17,6 @@ static void bench_sign_setup(void* arg) { bench_sign_t *data = (bench_sign_t*)arg; for (int i = 0; i < 32; i++) data->msg[i] = i + 1; - for (int i = 0; i < 32; i++) data->nonce[i] = i + 33; for (int i = 0; i < 32; i++) data->key[i] = i + 65; } @@ -28,9 +26,8 @@ static void bench_sign(void* arg) { unsigned char sig[64]; for (int i=0; i<20000; i++) { int recid = 0; - CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, data->nonce, &recid)); + CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, NULL, NULL, &recid)); for (int j = 0; j < 32; j++) { - data->nonce[j] = data->key[j]; /* Move former key to nonce */ data->msg[j] = sig[j]; /* Move former R to message. */ data->key[j] = sig[j + 32]; /* Move former S to key. */ } diff --git a/src/bench_verify.c b/src/bench_verify.c index b123c4087d6..a58ca84347b 100644 --- a/src/bench_verify.c +++ b/src/bench_verify.c @@ -14,7 +14,6 @@ typedef struct { unsigned char msg[32]; unsigned char key[32]; - unsigned char nonce[32]; unsigned char sig[72]; int siglen; unsigned char pubkey[33]; @@ -42,9 +41,8 @@ int main(void) { for (int i = 0; i < 32; i++) data.msg[i] = 1 + i; for (int i = 0; i < 32; i++) data.key[i] = 33 + i; - for (int i = 0; i < 32; i++) data.nonce[i] = 65 + i; data.siglen = 72; - CHECK(secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, data.nonce)); + secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, NULL, NULL); data.pubkeylen = 33; CHECK(secp256k1_ec_pubkey_create(data.pubkey, &data.pubkeylen, data.key, 1)); diff --git a/src/ecdsa_impl.h b/src/ecdsa_impl.h index 8825d05fed9..674650c1e9f 100644 --- a/src/ecdsa_impl.h +++ b/src/ecdsa_impl.h @@ -109,25 +109,53 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se return 1; } -static int secp256k1_ecdsa_sig_recompute(secp256k1_scalar_t *r2, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) return 0; - int ret = 0; secp256k1_scalar_t sn, u1, u2; secp256k1_scalar_inverse_var(&sn, &sig->s); secp256k1_scalar_mul(&u1, &sn, message); secp256k1_scalar_mul(&u2, &sn, &sig->r); secp256k1_gej_t pubkeyj; secp256k1_gej_set_ge(&pubkeyj, pubkey); secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1); - if (!secp256k1_gej_is_infinity(&pr)) { - secp256k1_fe_t xr; secp256k1_gej_get_x_var(&xr, &pr); - secp256k1_fe_normalize_var(&xr); - unsigned char xrb[32]; secp256k1_fe_get_b32(xrb, &xr); - secp256k1_scalar_set_b32(r2, xrb, NULL); - ret = 1; + if (secp256k1_gej_is_infinity(&pr)) { + return 0; } - return ret; + unsigned char c[32]; + secp256k1_scalar_get_b32(c, &sig->r); + secp256k1_fe_t xr; + secp256k1_fe_set_b32(&xr, c); + + // We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) + // in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p), + // compute the remainder modulo n, and compare it to xr. However: + // + // xr == X(pr) mod n + // <=> exists h. (xr + h * n < p && xr + h * n == X(pr)) + // [Since 2 * n > p, h can only be 0 or 1] + // <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr)) + // [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p] + // <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p) + // [Multiplying both sides of the equations by pr.z^2 mod p] + // <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x) + // + // Thus, we can avoid the inversion, but we have to check both cases separately. + // secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. + if (secp256k1_gej_eq_x_var(&xr, &pr)) { + // xr.x == xr * xr.z^2 mod p, so the signature is valid. + return 1; + } + if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_consts->p_minus_order) >= 0) { + // xr + p >= n, so we can skip testing the second case. + return 0; + } + secp256k1_fe_add(&xr, &secp256k1_ecdsa_consts->order_as_fe); + if (secp256k1_gej_eq_x_var(&xr, &pr)) { + // (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. + return 1; + } + return 0; } static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) { @@ -159,13 +187,6 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256 return !secp256k1_gej_is_infinity(&qj); } -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { - secp256k1_scalar_t r2; - int ret = 0; - ret = secp256k1_ecdsa_sig_recompute(&r2, sig, pubkey, message) && secp256k1_scalar_eq(&sig->r, &r2); - return ret; -} - static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) { secp256k1_gej_t rp; secp256k1_ecmult_gen(&rp, nonce); @@ -177,6 +198,12 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_ secp256k1_fe_get_b32(b, &r.x); int overflow = 0; secp256k1_scalar_set_b32(&sig->r, b, &overflow); + if (secp256k1_scalar_is_zero(&sig->r)) { + /* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */ + secp256k1_gej_clear(&rp); + secp256k1_ge_clear(&r); + return 0; + } if (recid) *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); secp256k1_scalar_t n; diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index 5a5b16ce14c..48436316e12 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -73,7 +73,7 @@ static void secp256k1_ecmult_gen_start(void) { secp256k1_gej_double_var(&numsbase, &numsbase); if (j == 62) { /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ - secp256k1_gej_neg_var(&numsbase, &numsbase); + secp256k1_gej_neg(&numsbase, &numsbase); secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej); } } diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h index 65367710469..345cfae7332 100644 --- a/src/ecmult_impl.h +++ b/src/ecmult_impl.h @@ -70,8 +70,8 @@ static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const sec (neg)((r), &(pre)[(-(n)-1)/2]); \ } while(0) -#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg_var) -#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg_var) +#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg) +#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg) typedef struct { /* For accelerating the computation of a*P + b*G: */ diff --git a/src/field.h b/src/field.h index 53aa29e13fd..14e2b813c17 100644 --- a/src/field.h +++ b/src/field.h @@ -22,9 +22,7 @@ #include "libsecp256k1-config.h" #endif -#if defined(USE_FIELD_GMP) -#include "field_gmp.h" -#elif defined(USE_FIELD_10X26) +#if defined(USE_FIELD_10X26) #include "field_10x26.h" #elif defined(USE_FIELD_5X52) #include "field_5x52.h" @@ -50,9 +48,20 @@ static void secp256k1_fe_stop(void); /** Normalize a field element. */ static void secp256k1_fe_normalize(secp256k1_fe_t *r); +/** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */ +static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r); + /** Normalize a field element, without constant-time guarantee. */ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r); +/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field + * implementation may optionally normalize the input, but this should not be relied upon. */ +static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r); + +/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field + * implementation may optionally normalize the input, but this should not be relied upon. */ +static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r); + /** Set a field element equal to a small integer. Resulting field element is normalized. */ static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a); @@ -62,8 +71,8 @@ static int secp256k1_fe_is_zero(const secp256k1_fe_t *a); /** Check the "oddness" of a field element. Requires the input to be normalized. */ static int secp256k1_fe_is_odd(const secp256k1_fe_t *a); -/** Compare two field elements. Requires both inputs to be normalized */ -static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b); +/** Compare two field elements. Requires magnitude-1 inputs. */ +static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b); /** Compare two field elements. Requires both inputs to be normalized */ static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b); diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index d20229cda6b..9ef60a807ac 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -31,6 +31,7 @@ static void secp256k1_fe_verify(const secp256k1_fe_t *a) { r &= (d[8] <= 0x3FFFFFFUL * m); r &= (d[9] <= 0x03FFFFFUL * m); r &= (a->magnitude >= 0); + r &= (a->magnitude <= 32); if (a->normalized) { r &= (a->magnitude <= 1); if (r && (d[9] == 0x03FFFFFUL)) { @@ -103,6 +104,37 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { #endif } +static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; + +#ifdef VERIFY + r->magnitude = 1; + secp256k1_fe_verify(r); +#endif +} + static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; @@ -159,6 +191,73 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { #endif } +static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + + /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ + uint32_t z0, z1; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; + z0 |= t9; z1 &= t9 ^ 0x3C00000UL; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + return (z0 == 0) | (z1 == 0x3FFFFFFUL); +} + +static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { + uint32_t t0 = r->n[0], t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t x = t9 >> 22; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; + + /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ + uint32_t z0 = t0 & 0x3FFFFFFUL, z1 = z0 ^ 0x3D0UL; + + /* Fast return path should catch the majority of cases */ + if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) + return 0; + + uint32_t t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8]; + t9 &= 0x03FFFFFUL; + t1 += (x << 6); + + t1 += (t0 >> 26); t0 = z0; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; + z0 |= t9; z1 &= t9 ^ 0x3C00000UL; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + return (z0 == 0) | (z1 == 0x3FFFFFFUL); +} + SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { r->n[0] = a; r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; @@ -196,18 +295,6 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { } } -SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - VERIFY_CHECK(b->normalized); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); -#endif - const uint32_t *t = a->n, *u = b->n; - return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4]) - | (t[5]^u[5]) | (t[6]^u[6]) | (t[7]^u[7]) | (t[8]^u[8]) | (t[9]^u[9])) == 0; -} - static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { #ifdef VERIFY VERIFY_CHECK(a->normalized); diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index 63176d6de40..4db9e6f5ff5 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -16,12 +16,10 @@ #include "num.h" #include "field.h" -#if defined(USE_FIELD_5X52_ASM) +#if defined(USE_ASM_X86_64) #include "field_5x52_asm_impl.h" -#elif defined(USE_FIELD_5X52_INT128) -#include "field_5x52_int128_impl.h" #else -#error "Please select field_5x52 implementation" +#include "field_5x52_int128_impl.h" #endif /** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F, @@ -45,6 +43,7 @@ static void secp256k1_fe_verify(const secp256k1_fe_t *a) { r &= (d[3] <= 0xFFFFFFFFFFFFFULL * m); r &= (d[4] <= 0x0FFFFFFFFFFFFULL * m); r &= (a->magnitude >= 0); + r &= (a->magnitude <= 2048); if (a->normalized) { r &= (a->magnitude <= 1); if (r && (d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) { @@ -102,6 +101,30 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { #endif } +static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + +#ifdef VERIFY + r->magnitude = 1; + secp256k1_fe_verify(r); +#endif +} + static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; @@ -146,6 +169,60 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { #endif } +static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + + /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ + uint64_t z0, z1; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; z0 = t0; z1 = t0 ^ 0x1000003D0ULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3; + z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); +} + +static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { + uint64_t t0 = r->n[0], t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t x = t4 >> 48; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + + /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ + uint64_t z0 = t0 & 0xFFFFFFFFFFFFFULL, z1 = z0 ^ 0x1000003D0ULL; + + /* Fast return path should catch the majority of cases */ + if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL)) + return 0; + + uint64_t t1 = r->n[1], t2 = r->n[2], t3 = r->n[3]; + t4 &= 0x0FFFFFFFFFFFFULL; + + t1 += (t0 >> 52); t0 = z0; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3; + z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); +} + SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { r->n[0] = a; r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; @@ -183,17 +260,6 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { } } -SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - VERIFY_CHECK(b->normalized); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); -#endif - const uint64_t *t = a->n, *u = b->n; - return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])) == 0; -} - static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { #ifdef VERIFY VERIFY_CHECK(a->normalized); diff --git a/src/field_gmp.h b/src/field_gmp.h deleted file mode 100644 index b390fd9de8d..00000000000 --- a/src/field_gmp.h +++ /dev/null @@ -1,18 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_FIELD_REPR_ -#define _SECP256K1_FIELD_REPR_ - -#include - -#define FIELD_LIMBS ((256 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS) - -typedef struct { - mp_limb_t n[FIELD_LIMBS+1]; -} secp256k1_fe_t; - -#endif diff --git a/src/field_gmp_impl.h b/src/field_gmp_impl.h deleted file mode 100644 index 73a55c4f00d..00000000000 --- a/src/field_gmp_impl.h +++ /dev/null @@ -1,184 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_FIELD_REPR_IMPL_H_ -#define _SECP256K1_FIELD_REPR_IMPL_H_ - -#include -#include -#include "num.h" -#include "field.h" - -static mp_limb_t secp256k1_field_p[FIELD_LIMBS]; -static mp_limb_t secp256k1_field_pc[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS]; - -static void secp256k1_fe_inner_start(void) { - for (int i=0; i<(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; i++) - secp256k1_field_pc[i] = 0; - secp256k1_field_pc[0] += 0x3D1UL; - secp256k1_field_pc[32/GMP_NUMB_BITS] += (((mp_limb_t)1) << (32 % GMP_NUMB_BITS)); - for (int i=0; in[FIELD_LIMBS] != 0) { -#if (GMP_NUMB_BITS >= 40) - mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * r->n[FIELD_LIMBS]); - mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * carry); -#else - mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * r->n[FIELD_LIMBS]) + - mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), r->n[FIELD_LIMBS] << (32 % GMP_NUMB_BITS)); - mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * carry); - mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), carry << (32%GMP_NUMB_BITS)); -#endif - r->n[FIELD_LIMBS] = 0; - } - if (mpn_cmp(r->n, secp256k1_field_p, FIELD_LIMBS) >= 0) - mpn_sub(r->n, r->n, FIELD_LIMBS, secp256k1_field_p, FIELD_LIMBS); -} - -static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { - secp256k1_fe_normalize(r); -} - -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { - r->n[0] = a; - for (int i=1; in[i] = 0; -} - -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *r) { - for (int i=0; in[i] = 0; -} - -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { - int ret = 1; - for (int i=0; in[i] == 0); - return ret; -} - -SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { - return a->n[0] & 1; -} - -SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { - int ret = 1; - for (int i=0; in[i] == b->n[i]); - return ret; -} - -SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { - for (int i=FIELD_LIMBS; i>=0; i--) { - if (a->n[i] > b->n[i]) return 1; - if (a->n[i] < b->n[i]) return -1; - } - return 0; -} - -static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { - for (int i=0; in[i] = 0; - for (int i=0; i<256; i++) { - int limb = i/GMP_NUMB_BITS; - int shift = i%GMP_NUMB_BITS; - r->n[limb] |= (mp_limb_t)((a[31-i/8] >> (i%8)) & 0x1) << shift; - } - return (mpn_cmp(r->n, secp256k1_field_p, FIELD_LIMBS) < 0); -} - -/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { - for (int i=0; i<32; i++) { - int c = 0; - for (int j=0; j<8; j++) { - int limb = (8*i+j)/GMP_NUMB_BITS; - int shift = (8*i+j)%GMP_NUMB_BITS; - c |= ((a->n[limb] >> shift) & 0x1) << j; - } - r[31-i] = c; - } -} - -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { - (void)m; - *r = *a; - secp256k1_fe_normalize(r); - for (int i=0; in[i] = ~(r->n[i]); -#if (GMP_NUMB_BITS >= 33) - mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x1000003D0ULL); -#else - mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x3D0UL); - mpn_sub_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS)); -#endif -} - -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { - mpn_mul_1(r->n, r->n, FIELD_LIMBS+1, a); -} - -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) { - mpn_add(r->n, r->n, FIELD_LIMBS+1, a->n, FIELD_LIMBS+1); -} - -static void secp256k1_fe_reduce(secp256k1_fe_t *r, mp_limb_t *tmp) { - /** - * B1 B2 B3 B4 - * + C * A1 A2 A3 A4 - * + A1 A2 A3 A4 - */ - -#if (GMP_NUMB_BITS >= 33) - mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x1000003D1ULL); -#else - mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x3D1UL) + - mpn_addmul_1(tmp+(32/GMP_NUMB_BITS), tmp+FIELD_LIMBS, FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS)); -#endif - mp_limb_t q[1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS]; - q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] = mpn_mul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o); -#if (GMP_NUMB_BITS <= 32) - mp_limb_t o2 = tmp[2*FIELD_LIMBS-(32/GMP_NUMB_BITS)] << (32%GMP_NUMB_BITS); - q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] += mpn_addmul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o2); -#endif - r->n[FIELD_LIMBS] = mpn_add(r->n, tmp, FIELD_LIMBS, q, 1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS); -} - -static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) { - VERIFY_CHECK(r != b); - secp256k1_fe_t ac = *a; - secp256k1_fe_t bc = *b; - secp256k1_fe_normalize(&ac); - secp256k1_fe_normalize(&bc); - mp_limb_t tmp[2*FIELD_LIMBS]; - mpn_mul_n(tmp, ac.n, bc.n, FIELD_LIMBS); - secp256k1_fe_reduce(r, tmp); -} - -static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { - secp256k1_fe_t ac = *a; - secp256k1_fe_normalize(&ac); - mp_limb_t tmp[2*FIELD_LIMBS]; - mpn_sqr(tmp, ac.n, FIELD_LIMBS); - secp256k1_fe_reduce(r, tmp); -} - -static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { - mp_limb_t mask0 = flag + ~((mp_limb_t)0), mask1 = ~mask0; - for (int i = 0; i <= FIELD_LIMBS; i++) { - r->n[i] = (r->n[i] & mask0) | (a->n[i] & mask1); - } -} - -#endif diff --git a/src/field_impl.h b/src/field_impl.h index 24d3104ed18..4e2c24aa153 100644 --- a/src/field_impl.h +++ b/src/field_impl.h @@ -13,9 +13,7 @@ #include "util.h" -#if defined(USE_FIELD_GMP) -#include "field_gmp_impl.h" -#elif defined(USE_FIELD_10X26) +#if defined(USE_FIELD_10X26) #include "field_10x26_impl.h" #elif defined(USE_FIELD_5X52) #include "field_5x52_impl.h" @@ -66,6 +64,13 @@ static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) { return secp256k1_fe_set_b32(r, tmp); } +SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { + secp256k1_fe_t na; + secp256k1_fe_negate(&na, a, 1); + secp256k1_fe_add(&na, b); + return secp256k1_fe_normalizes_to_zero_var(&na); +} + static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in @@ -130,10 +135,7 @@ static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { /* Check that a square root was actually calculated */ secp256k1_fe_sqr(&t1, r); - secp256k1_fe_negate(&t1, &t1, 1); - secp256k1_fe_add(&t1, a); - secp256k1_fe_normalize_var(&t1); - return secp256k1_fe_is_zero(&t1); + return secp256k1_fe_equal_var(&t1, a); } static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) { diff --git a/src/group.h b/src/group.h index ecfebcdc0c0..6dea6bb5acb 100644 --- a/src/group.h +++ b/src/group.h @@ -60,7 +60,6 @@ static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a); static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a); static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a); -static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a); /** Get a hex representation of a point. *rlen will be overwritten with the real length. */ static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a); @@ -81,11 +80,11 @@ static void secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, co /** Set a group element (jacobian) equal to another which is given in affine coordinates. */ static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a); -/** Get the X coordinate of a group element (jacobian). */ -static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a); +/** Compare the X coordinate of a group element (jacobian). */ +static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a); /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ -static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a); +static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a); /** Check whether a group element is the point at infinity. */ static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a); diff --git a/src/group_impl.h b/src/group_impl.h index 1ab5d5fe7bf..fef06df2892 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -29,13 +29,7 @@ static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a) { static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) { *r = *a; - secp256k1_fe_normalize(&r->y); - secp256k1_fe_negate(&r->y, &r->y, 1); -} - -static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a) { - *r = *a; - secp256k1_fe_normalize_var(&r->y); + secp256k1_fe_normalize_weak(&r->y); secp256k1_fe_negate(&r->y, &r->y, 1); } @@ -163,17 +157,19 @@ static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a) { secp256k1_fe_set_int(&r->z, 1); } -static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a) { - secp256k1_fe_t zi2; secp256k1_fe_inv_var(&zi2, &a->z); secp256k1_fe_sqr(&zi2, &zi2); - secp256k1_fe_mul(r, &a->x, &zi2); +static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a) { + VERIFY_CHECK(!a->infinity); + secp256k1_fe_t r; secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); + secp256k1_fe_t r2 = a->x; secp256k1_fe_normalize_weak(&r2); + return secp256k1_fe_equal_var(&r, &r2); } -static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) { +static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) { r->infinity = a->infinity; r->x = a->x; r->y = a->y; r->z = a->z; - secp256k1_fe_normalize_var(&r->y); + secp256k1_fe_normalize_weak(&r->y); secp256k1_fe_negate(&r->y, &r->y, 1); } @@ -195,9 +191,8 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { secp256k1_fe_t z6; secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); secp256k1_fe_mul_int(&z6, 7); secp256k1_fe_add(&x3, &z6); - secp256k1_fe_normalize_var(&y2); - secp256k1_fe_normalize_var(&x3); - return secp256k1_fe_equal(&y2, &x3); + secp256k1_fe_normalize_weak(&x3); + return secp256k1_fe_equal_var(&y2, &x3); } static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) { @@ -208,9 +203,8 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) { secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7); secp256k1_fe_add(&x3, &c); - secp256k1_fe_normalize_var(&y2); - secp256k1_fe_normalize_var(&x3); - return secp256k1_fe_equal(&y2, &x3); + secp256k1_fe_normalize_weak(&x3); + return secp256k1_fe_equal_var(&y2, &x3); } static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) { @@ -261,20 +255,16 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); secp256k1_fe_t s1; secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_normalize_var(&u1); - secp256k1_fe_normalize_var(&u2); - if (secp256k1_fe_equal(&u1, &u2)) { - secp256k1_fe_normalize_var(&s1); - secp256k1_fe_normalize_var(&s2); - if (secp256k1_fe_equal(&s1, &s2)) { + secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + if (secp256k1_fe_normalizes_to_zero_var(&h)) { + if (secp256k1_fe_normalizes_to_zero_var(&i)) { secp256k1_gej_double_var(r, a); } else { r->infinity = 1; } return; } - secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i); secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h); secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2); @@ -300,23 +290,20 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * } r->infinity = 0; secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z); - secp256k1_fe_t u1 = a->x; + secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1); secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); - secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_var(&s1); + secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1); secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_normalize_var(&u1); - secp256k1_fe_normalize_var(&u2); - if (secp256k1_fe_equal(&u1, &u2)) { - secp256k1_fe_normalize_var(&s2); - if (secp256k1_fe_equal(&s1, &s2)) { + secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + if (secp256k1_fe_normalizes_to_zero_var(&h)) { + if (secp256k1_fe_normalizes_to_zero_var(&i)) { secp256k1_gej_double_var(r, a); } else { r->infinity = 1; } return; } - secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i); secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h); secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2); @@ -355,9 +342,9 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c */ secp256k1_fe_t zz; secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ - secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize(&u1); /* u1 = U1 = X1*Z2^2 (1) */ + secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */ secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ - secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ + secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */ secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ secp256k1_fe_t z = a->z; /* z = Z = Z1*Z2 (8) */ @@ -371,8 +358,7 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c secp256k1_fe_add(&rr, &t); /* rr = R = T^2-U1*U2 (3) */ secp256k1_fe_sqr(&t, &rr); /* t = R^2 (1) */ secp256k1_fe_mul(&r->z, &m, &z); /* r->z = M*Z (1) */ - secp256k1_fe_normalize(&r->z); - int infinity = secp256k1_fe_is_zero(&r->z) * (1 - a->infinity); + int infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); secp256k1_fe_mul_int(&r->z, 2 * (1 - a->infinity)); /* r->z = Z3 = 2*M*Z (2) */ r->x = t; /* r->x = R^2 (1) */ secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ @@ -384,7 +370,7 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c secp256k1_fe_mul(&t, &t, &rr); /* t = R*(2*R^2-3*Q) (1) */ secp256k1_fe_add(&t, &n); /* t = R*(2*R^2-3*Q)+M^4 (2) */ secp256k1_fe_negate(&r->y, &t, 2); /* r->y = R*(3*Q-2*R^2)-M^4 (3) */ - secp256k1_fe_normalize(&r->y); + secp256k1_fe_normalize_weak(&r->y); secp256k1_fe_mul_int(&r->x, 4 * (1 - a->infinity)); /* r->x = X3 = 4*(R^2-Q) */ secp256k1_fe_mul_int(&r->y, 4 * (1 - a->infinity)); /* r->y = Y3 = 4*R*(3*Q-2*R^2)-4*M^4 (4) */ diff --git a/src/hash.h b/src/hash.h new file mode 100644 index 00000000000..d1e65b968a9 --- /dev/null +++ b/src/hash.h @@ -0,0 +1,41 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_HASH_ +#define _SECP256K1_HASH_ + +#include +#include + +typedef struct { + uint32_t s[32]; + unsigned char buf[64]; + size_t bytes; +} secp256k1_sha256_t; + +static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash); +static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t size); +static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32); + +typedef struct { + secp256k1_sha256_t inner, outer; +} secp256k1_hmac_sha256_t; + +static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t size); +static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size); +static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32); + +typedef struct { + unsigned char v[32]; + unsigned char k[32]; + int retry; +} secp256k1_rfc6979_hmac_sha256_t; + +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen); +static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen); +static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng); + +#endif diff --git a/src/hash_impl.h b/src/hash_impl.h new file mode 100644 index 00000000000..f35c5f7a821 --- /dev/null +++ b/src/hash_impl.h @@ -0,0 +1,291 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_HASH_IMPL_H_ +#define _SECP256K1_HASH_IMPL_H_ + +#include "hash.h" + +#include +#include + +#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) +#define Sigma0(x) (((x) >> 2 | (x) << 30) ^ ((x) >> 13 | (x) << 19) ^ ((x) >> 22 | (x) << 10)) +#define Sigma1(x) (((x) >> 6 | (x) << 26) ^ ((x) >> 11 | (x) << 21) ^ ((x) >> 25 | (x) << 7)) +#define sigma0(x) (((x) >> 7 | (x) << 25) ^ ((x) >> 18 | (x) << 14) ^ ((x) >> 3)) +#define sigma1(x) (((x) >> 17 | (x) << 15) ^ ((x) >> 19 | (x) << 13) ^ ((x) >> 10)) + +#define Round(a,b,c,d,e,f,g,h,k,w) do { \ + uint32_t t1 = (h) + Sigma1(e) + Ch((e), (f), (g)) + (k) + (w); \ + uint32_t t2 = Sigma0(a) + Maj((a), (b), (c)); \ + (d) += t1; \ + (h) = t1 + t2; \ +} while(0) + +#define ReadBE32(p) (((uint32_t)((p)[0])) << 24 | ((uint32_t)((p)[1])) << 16 | ((uint32_t)((p)[2])) << 8 | ((uint32_t)((p)[3]))) +#define WriteBE32(p, v) do { (p)[0] = (v) >> 24; (p)[1] = (v) >> 16; (p)[2] = (v) >> 8; (p)[3] = (v); } while(0) + +static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) { + hash->s[0] = 0x6a09e667ul; + hash->s[1] = 0xbb67ae85ul; + hash->s[2] = 0x3c6ef372ul; + hash->s[3] = 0xa54ff53aul; + hash->s[4] = 0x510e527ful; + hash->s[5] = 0x9b05688cul; + hash->s[6] = 0x1f83d9abul; + hash->s[7] = 0x5be0cd19ul; + hash->bytes = 0; +} + +/** Perform one SHA-256 transformation, processing a 64-byte chunk. */ +static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* chunk) { + uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; + uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; + + Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0)); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4)); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8)); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12)); + Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16)); + Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20)); + Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24)); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28)); + Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32)); + Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36)); + Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40)); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44)); + Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48)); + Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52)); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56)); + Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60)); + + Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0)); + + s[0] += a; + s[1] += b; + s[2] += c; + s[3] += d; + s[4] += e; + s[5] += f; + s[6] += g; + s[7] += h; +} + +static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t len) { + const unsigned char* end = data + len; + size_t bufsize = hash->bytes % 64; + if (bufsize && bufsize + len >= 64) { + // Fill the buffer, and process it. + memcpy(hash->buf + bufsize, data, 64 - bufsize); + hash->bytes += 64 - bufsize; + data += 64 - bufsize; + secp256k1_sha256_transform(hash->s, hash->buf); + bufsize = 0; + } + while (end >= data + 64) { + // Process full chunks directly from the source. + secp256k1_sha256_transform(hash->s, data); + hash->bytes += 64; + data += 64; + } + if (end > data) { + // Fill the buffer with what remains. + memcpy(hash->buf + bufsize, data, end - data); + hash->bytes += end - data; + } +} + +static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32) { + static const unsigned char pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + unsigned char sizedesc[8]; + WriteBE32(sizedesc, hash->bytes >> 29); + WriteBE32(sizedesc + 4, hash->bytes << 3); + secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64)); + secp256k1_sha256_write(hash, sizedesc, 8); + WriteBE32(out32, hash->s[0]); + hash->s[0] = 0; + WriteBE32(out32 + 4, hash->s[1]); + hash->s[1] = 0; + WriteBE32(out32 + 8, hash->s[2]); + hash->s[2] = 0; + WriteBE32(out32 + 12, hash->s[3]); + hash->s[3] = 0; + WriteBE32(out32 + 16, hash->s[4]); + hash->s[4] = 0; + WriteBE32(out32 + 20, hash->s[5]); + hash->s[5] = 0; + WriteBE32(out32 + 24, hash->s[6]); + hash->s[6] = 0; + WriteBE32(out32 + 28, hash->s[7]); + hash->s[7] = 0; +} + +static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t keylen) { + unsigned char rkey[64]; + if (keylen <= 64) { + memcpy(rkey, key, keylen); + memset(rkey + keylen, 0, 64 - keylen); + } else { + secp256k1_sha256_t sha256; + secp256k1_sha256_initialize(&sha256); + secp256k1_sha256_write(&sha256, key, keylen); + secp256k1_sha256_finalize(&sha256, rkey); + memset(rkey + 32, 0, 32); + } + + secp256k1_sha256_initialize(&hash->outer); + for (int n = 0; n < 64; n++) + rkey[n] ^= 0x5c; + secp256k1_sha256_write(&hash->outer, rkey, 64); + + secp256k1_sha256_initialize(&hash->inner); + for (int n = 0; n < 64; n++) + rkey[n] ^= 0x5c ^ 0x36; + secp256k1_sha256_write(&hash->inner, rkey, 64); + memset(rkey, 0, 64); +} + +static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size) { + secp256k1_sha256_write(&hash->inner, data, size); +} + +static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32) { + unsigned char temp[32]; + secp256k1_sha256_finalize(&hash->inner, temp); + secp256k1_sha256_write(&hash->outer, temp, 32); + memset(temp, 0, 32); + secp256k1_sha256_finalize(&hash->outer, out32); +} + + +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen) { + static const unsigned char zero[1] = {0x00}; + static const unsigned char one[1] = {0x01}; + + memset(rng->v, 0x01, 32); + memset(rng->k, 0x00, 32); + + secp256k1_hmac_sha256_t hmac; + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_write(&hmac, zero, 1); + secp256k1_hmac_sha256_write(&hmac, key, keylen); + secp256k1_hmac_sha256_write(&hmac, msg, msglen); + secp256k1_hmac_sha256_finalize(&hmac, rng->k); + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(&hmac, rng->v); + + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_write(&hmac, one, 1); + secp256k1_hmac_sha256_write(&hmac, key, keylen); + secp256k1_hmac_sha256_write(&hmac, msg, msglen); + secp256k1_hmac_sha256_finalize(&hmac, rng->k); + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(&hmac, rng->v); + rng->retry = 0; +} + +static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen) { + static const unsigned char zero[1] = {0x00}; + if (rng->retry) { + secp256k1_hmac_sha256_t hmac; + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_write(&hmac, zero, 1); + secp256k1_hmac_sha256_finalize(&hmac, rng->k); + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(&hmac, rng->v); + } + + while (outlen > 0) { + secp256k1_hmac_sha256_t hmac; + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(&hmac, rng->v); + int now = outlen; + if (now > 32) { + now = 32; + } + memcpy(out, rng->v, now); + out += now; + outlen -= now; + } + + rng->retry = 1; +} + +static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng) { + memset(rng->k, 0, 32); + memset(rng->v, 0, 32); + rng->retry = 0; +} + + +#undef Round +#undef sigma0 +#undef sigma1 +#undef Sigma0 +#undef Sigma1 +#undef Ch +#undef Maj +#undef ReadBE32 +#undef WriteBE32 + +#endif diff --git a/src/secp256k1.c b/src/secp256k1.c index 0328db88fc4..58bcd8d009e 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -17,6 +17,7 @@ #include "ecmult_gen_impl.h" #include "ecdsa_impl.h" #include "eckey_impl.h" +#include "hash_impl.h" void secp256k1_start(unsigned int flags) { secp256k1_fe_start(); @@ -69,26 +70,54 @@ end: return ret; } -int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, const unsigned char *nonce) { +static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { + (void)data; + secp256k1_rfc6979_hmac_sha256_t rng; + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32); + for (unsigned int i = 0; i <= counter; i++) { + secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + } + secp256k1_rfc6979_hmac_sha256_finalize(&rng); + return 1; +} + +const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; +const secp256k1_nonce_function_t secp256k1_nonce_function_default = nonce_function_rfc6979; + +int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) { DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(signature != NULL); DEBUG_CHECK(signaturelen != NULL); DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(nonce != NULL); + if (noncefp == NULL) { + noncefp = secp256k1_nonce_function_default; + } secp256k1_scalar_t sec, non, msg; secp256k1_scalar_set_b32(&sec, seckey, NULL); - int overflow = 0; - secp256k1_scalar_set_b32(&non, nonce, &overflow); secp256k1_scalar_set_b32(&msg, msg32, NULL); - int ret = !secp256k1_scalar_is_zero(&non) && !overflow; + int overflow = 0; + int ret = 0; + unsigned int count = 0; secp256k1_ecdsa_sig_t sig; - if (ret) { - ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL); + while (1) { + unsigned char nonce32[32]; + ret = noncefp(nonce32, msg32, seckey, count, noncedata); + if (!ret) { + break; + } + secp256k1_scalar_set_b32(&non, nonce32, &overflow); + memset(nonce32, 0, 32); + if (!secp256k1_scalar_is_zero(&non) && !overflow) { + if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL)) { + break; + } + } + count++; } if (ret) { - secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig); + ret = secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig); } secp256k1_scalar_clear(&msg); secp256k1_scalar_clear(&non); @@ -96,22 +125,36 @@ int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, i return ret; } -int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid) { +int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) { DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig64 != NULL); DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(nonce != NULL); + if (noncefp == NULL) { + noncefp = secp256k1_nonce_function_default; + } secp256k1_scalar_t sec, non, msg; secp256k1_scalar_set_b32(&sec, seckey, NULL); - int overflow = 0; - secp256k1_scalar_set_b32(&non, nonce, &overflow); secp256k1_scalar_set_b32(&msg, msg32, NULL); - int ret = !secp256k1_scalar_is_zero(&non) && !overflow; + int overflow = 0; + int ret = 0; + unsigned int count = 0; secp256k1_ecdsa_sig_t sig; - if (ret) { - ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid); + while (1) { + unsigned char nonce32[32]; + ret = noncefp(nonce32, msg32, seckey, count, noncedata); + if (!ret) { + break; + } + secp256k1_scalar_set_b32(&non, nonce32, &overflow); + memset(nonce32, 0, 32); + if (!secp256k1_scalar_is_zero(&non) && !overflow) { + if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid)) { + break; + } + } + count++; } if (ret) { secp256k1_scalar_get_b32(sig64, &sig.r); diff --git a/src/tests.c b/src/tests.c index 7ebb19ff99c..cff32f1d068 100644 --- a/src/tests.c +++ b/src/tests.c @@ -36,12 +36,19 @@ void random_field_element_test(secp256k1_fe_t *fe) { } void random_field_element_magnitude(secp256k1_fe_t *fe) { + int n = secp256k1_rand32() % 9; secp256k1_fe_normalize(fe); - int n = secp256k1_rand32() % 4; - for (int i = 0; i < n; i++) { - secp256k1_fe_negate(fe, fe, 1 + 2*i); - secp256k1_fe_negate(fe, fe, 2 + 2*i); + if (n == 0) { + return; } + secp256k1_fe_t zero; + secp256k1_fe_clear(&zero); + secp256k1_fe_negate(&zero, &zero, 0); + secp256k1_fe_mul_int(&zero, n - 1); + secp256k1_fe_add(fe, &zero); +#ifdef VERIFY + CHECK(fe->magnitude == n); +#endif } void random_group_element_test(secp256k1_ge_t *ge) { @@ -91,6 +98,121 @@ void random_scalar_order(secp256k1_scalar_t *num) { } while(1); } +/***** HASH TESTS *****/ + +void run_sha256_tests(void) { + static const char *inputs[8] = { + "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "For this sample, this 63-byte string will be used as input data", + "This is exactly 64 bytes long, not counting the terminating byte" + }; + static const unsigned char outputs[8][32] = { + {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}, + {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad}, + {0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50}, + {0xf3, 0x0c, 0xeb, 0x2b, 0xb2, 0x82, 0x9e, 0x79, 0xe4, 0xca, 0x97, 0x53, 0xd3, 0x5a, 0x8e, 0xcc, 0x00, 0x26, 0x2d, 0x16, 0x4c, 0xc0, 0x77, 0x08, 0x02, 0x95, 0x38, 0x1c, 0xbd, 0x64, 0x3f, 0x0d}, + {0x68, 0x19, 0xd9, 0x15, 0xc7, 0x3f, 0x4d, 0x1e, 0x77, 0xe4, 0xe1, 0xb5, 0x2d, 0x1f, 0xa0, 0xf9, 0xcf, 0x9b, 0xea, 0xea, 0xd3, 0x93, 0x9f, 0x15, 0x87, 0x4b, 0xd9, 0x88, 0xe2, 0xa2, 0x36, 0x30}, + {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1}, + {0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42}, + {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8} + }; + for (int i = 0; i < 8; i++) { + secp256k1_sha256_t hasher; + secp256k1_sha256_initialize(&hasher); + secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); + unsigned char out[32]; + secp256k1_sha256_finalize(&hasher, out); + CHECK(memcmp(out, outputs[i], 32) == 0); + if (strlen(inputs[i]) > 0) { + secp256k1_sha256_initialize(&hasher); + int split = secp256k1_rand32() % strlen(inputs[i]); + secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); + secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); + secp256k1_sha256_finalize(&hasher, out); + CHECK(memcmp(out, outputs[i], 32) == 0); + } + } +} + +void run_hmac_sha256_tests(void) { + static const char *keys[6] = { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", + "\x4a\x65\x66\x65", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + }; + static const char *inputs[6] = { + "\x48\x69\x20\x54\x68\x65\x72\x65", + "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f", + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", + "\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", + "\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e" + }; + static const unsigned char outputs[6][32] = { + {0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7}, + {0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43}, + {0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe}, + {0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b}, + {0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54}, + {0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2} + }; + for (int i = 0; i < 6; i++) { + secp256k1_hmac_sha256_t hasher; + secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); + secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); + unsigned char out[32]; + secp256k1_hmac_sha256_finalize(&hasher, out); + CHECK(memcmp(out, outputs[i], 32) == 0); + if (strlen(inputs[i]) > 0) { + secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); + int split = secp256k1_rand32() % strlen(inputs[i]); + secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); + secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); + secp256k1_hmac_sha256_finalize(&hasher, out); + CHECK(memcmp(out, outputs[i], 32) == 0); + } + } +} + +void run_rfc6979_hmac_sha256_tests(void) { + static const unsigned char key1[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00}; + static const unsigned char msg1[32] = {0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a}; + static const unsigned char out1[3][32] = { + {0x4f, 0xe2, 0x95, 0x25, 0xb2, 0x08, 0x68, 0x09, 0x15, 0x9a, 0xcd, 0xf0, 0x50, 0x6e, 0xfb, 0x86, 0xb0, 0xec, 0x93, 0x2c, 0x7b, 0xa4, 0x42, 0x56, 0xab, 0x32, 0x1e, 0x42, 0x1e, 0x67, 0xe9, 0xfb}, + {0x2b, 0xf0, 0xff, 0xf1, 0xd3, 0xc3, 0x78, 0xa2, 0x2d, 0xc5, 0xde, 0x1d, 0x85, 0x65, 0x22, 0x32, 0x5c, 0x65, 0xb5, 0x04, 0x49, 0x1a, 0x0c, 0xbd, 0x01, 0xcb, 0x8f, 0x3a, 0xa6, 0x7f, 0xfd, 0x4a}, + {0xf5, 0x28, 0xb4, 0x10, 0xcb, 0x54, 0x1f, 0x77, 0x00, 0x0d, 0x7a, 0xfb, 0x6c, 0x5b, 0x53, 0xc5, 0xc4, 0x71, 0xea, 0xb4, 0x3e, 0x46, 0x6d, 0x9a, 0xc5, 0x19, 0x0c, 0x39, 0xc8, 0x2f, 0xd8, 0x2e} + }; + + static const unsigned char key2[32] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + static const unsigned char msg2[32] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; + static const unsigned char out2[3][32] = { + {0x9c, 0x23, 0x6c, 0x16, 0x5b, 0x82, 0xae, 0x0c, 0xd5, 0x90, 0x65, 0x9e, 0x10, 0x0b, 0x6b, 0xab, 0x30, 0x36, 0xe7, 0xba, 0x8b, 0x06, 0x74, 0x9b, 0xaf, 0x69, 0x81, 0xe1, 0x6f, 0x1a, 0x2b, 0x95}, + {0xdf, 0x47, 0x10, 0x61, 0x62, 0x5b, 0xc0, 0xea, 0x14, 0xb6, 0x82, 0xfe, 0xee, 0x2c, 0x9c, 0x02, 0xf2, 0x35, 0xda, 0x04, 0x20, 0x4c, 0x1d, 0x62, 0xa1, 0x53, 0x6c, 0x6e, 0x17, 0xae, 0xd7, 0xa9}, + {0x75, 0x97, 0x88, 0x7c, 0xbd, 0x76, 0x32, 0x1f, 0x32, 0xe3, 0x04, 0x40, 0x67, 0x9a, 0x22, 0xcf, 0x7f, 0x8d, 0x9d, 0x2e, 0xac, 0x39, 0x0e, 0x58, 0x1f, 0xea, 0x09, 0x1c, 0xe2, 0x02, 0xba, 0x94} + }; + + secp256k1_rfc6979_hmac_sha256_t rng; + unsigned char out[32]; + + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32); + for (int i = 0; i < 3; i++) { + secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); + CHECK(memcmp(out, out1[i], 32) == 0); + } + secp256k1_rfc6979_hmac_sha256_finalize(&rng); + + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 32, msg2, 32); + for (int i = 0; i < 3; i++) { + secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); + CHECK(memcmp(out, out2[i], 32) == 0); + } + secp256k1_rfc6979_hmac_sha256_finalize(&rng); +} + /***** NUM TESTS *****/ #ifndef USE_NUM_NONE @@ -494,9 +616,9 @@ void random_fe_non_square(secp256k1_fe_t *ns) { } int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { - secp256k1_fe_t an = *a; secp256k1_fe_normalize(&an); + secp256k1_fe_t an = *a; secp256k1_fe_normalize_weak(&an); secp256k1_fe_t bn = *b; secp256k1_fe_normalize_var(&bn); - return secp256k1_fe_equal(&an, &bn); + return secp256k1_fe_equal_var(&an, &bn); } int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) { @@ -523,16 +645,16 @@ void run_field_misc(void) { random_fe_non_zero(&y); /* Test the fe equality and comparison operations. */ CHECK(secp256k1_fe_cmp_var(&x, &x) == 0); - CHECK(secp256k1_fe_equal(&x, &x)); + CHECK(secp256k1_fe_equal_var(&x, &x)); z = x; secp256k1_fe_add(&z,&y); secp256k1_fe_normalize(&z); /* Test the conditional move. */ secp256k1_fe_cmov(&z, &x, 0); - CHECK(secp256k1_fe_equal(&x, &z) == 0); + CHECK(secp256k1_fe_equal_var(&x, &z) == 0); CHECK(secp256k1_fe_cmp_var(&x, &z) != 0); secp256k1_fe_cmov(&y, &x, 1); - CHECK(secp256k1_fe_equal(&x, &y)); + CHECK(secp256k1_fe_equal_var(&x, &y)); /* Test that mul_int, mul, and add agree. */ secp256k1_fe_add(&y, &x); secp256k1_fe_add(&y, &x); @@ -656,108 +778,148 @@ void run_sqrt(void) { /***** GROUP TESTS *****/ -int ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) { - if (a->infinity && b->infinity) - return 1; - return check_fe_equal(&a->x, &b->x) && check_fe_equal(&a->y, &b->y); +void ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) { + CHECK(a->infinity == b->infinity); + if (a->infinity) + return; + CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); + CHECK(secp256k1_fe_equal_var(&b->y, &b->y)); } void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) { - secp256k1_ge_t bb; - secp256k1_gej_t bj = *b; - secp256k1_ge_set_gej_var(&bb, &bj); - CHECK(ge_equals_ge(a, &bb)); -} - -void gej_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) { - secp256k1_ge_t aa, bb; - secp256k1_gej_t aj = *a, bj = *b; - secp256k1_ge_set_gej_var(&aa, &aj); - secp256k1_ge_set_gej_var(&bb, &bj); - CHECK(ge_equals_ge(&aa, &bb)); + CHECK(a->infinity == b->infinity); + if (a->infinity) + return; + /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */ + secp256k1_fe_t z2s; + secp256k1_fe_sqr(&z2s, &b->z); + secp256k1_fe_t u1, u2, s1, s2; + secp256k1_fe_mul(&u1, &a->x, &z2s); + u2 = b->x; secp256k1_fe_normalize_weak(&u2); + secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z); + s2 = b->y; secp256k1_fe_normalize_weak(&s2); + CHECK(secp256k1_fe_equal_var(&u1, &u2)); + CHECK(secp256k1_fe_equal_var(&s1, &s2)); } void test_ge(void) { - char ca[135]; - char cb[68]; - int rlen; - secp256k1_ge_t a, b, i, n; - random_group_element_test(&a); - random_group_element_test(&b); - rlen = sizeof(ca); - secp256k1_ge_get_hex(ca,&rlen,&a); - CHECK(rlen > 4 && rlen <= (int)sizeof(ca)); - rlen = sizeof(cb); - secp256k1_ge_get_hex(cb,&rlen,&b); /* Intentionally undersized buffer. */ - n = a; - secp256k1_fe_normalize(&a.y); - secp256k1_fe_negate(&n.y, &a.y, 1); - secp256k1_ge_set_infinity(&i); - random_field_element_magnitude(&a.x); - random_field_element_magnitude(&a.y); - random_field_element_magnitude(&b.x); - random_field_element_magnitude(&b.y); - random_field_element_magnitude(&n.x); - random_field_element_magnitude(&n.y); + int runs = 4; + /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4). + * The second in each pair of identical points uses a random Z coordinate in the Jacobian form. + * All magnitudes are randomized. + * All 17*17 combinations of points are added to eachother, using all applicable methods. + */ + secp256k1_ge_t *ge = malloc(sizeof(secp256k1_ge_t) * (1 + 4 * runs)); + secp256k1_gej_t *gej = malloc(sizeof(secp256k1_gej_t) * (1 + 4 * runs)); + secp256k1_gej_set_infinity(&gej[0]); + secp256k1_ge_clear(&ge[0]); + secp256k1_ge_set_gej_var(&ge[0], &gej[0]); + for (int i = 0; i < runs; i++) { + secp256k1_ge_t g; + random_group_element_test(&g); + ge[1 + 4 * i] = g; + ge[2 + 4 * i] = g; + secp256k1_ge_neg(&ge[3 + 4 * i], &g); + secp256k1_ge_neg(&ge[4 + 4 * i], &g); + secp256k1_gej_set_ge(&gej[1 + 4 * i], &ge[1 + 4 * i]); + random_group_element_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]); + secp256k1_gej_set_ge(&gej[3 + 4 * i], &ge[3 + 4 * i]); + random_group_element_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]); + for (int j = 0; j < 4; j++) { + random_field_element_magnitude(&ge[1 + j + 4 * i].x); + random_field_element_magnitude(&ge[1 + j + 4 * i].y); + random_field_element_magnitude(&gej[1 + j + 4 * i].x); + random_field_element_magnitude(&gej[1 + j + 4 * i].y); + random_field_element_magnitude(&gej[1 + j + 4 * i].z); + } + } - secp256k1_gej_t aj, bj, ij, nj; - random_group_element_jacobian_test(&aj, &a); - random_group_element_jacobian_test(&bj, &b); - secp256k1_gej_set_infinity(&ij); - random_group_element_jacobian_test(&nj, &n); - random_field_element_magnitude(&aj.x); - random_field_element_magnitude(&aj.y); - random_field_element_magnitude(&aj.z); - random_field_element_magnitude(&bj.x); - random_field_element_magnitude(&bj.y); - random_field_element_magnitude(&bj.z); - random_field_element_magnitude(&nj.x); - random_field_element_magnitude(&nj.y); - random_field_element_magnitude(&nj.z); + for (int i1 = 0; i1 < 1 + 4 * runs; i1++) { + for (int i2 = 0; i2 < 1 + 4 * runs; i2++) { + /* Compute reference result using gej + gej (var). */ + secp256k1_gej_t refj, resj; + secp256k1_ge_t ref; + secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2]); + secp256k1_ge_set_gej_var(&ref, &refj); - /* gej + gej adds */ - secp256k1_gej_t aaj; secp256k1_gej_add_var(&aaj, &aj, &aj); - secp256k1_gej_t abj; secp256k1_gej_add_var(&abj, &aj, &bj); - secp256k1_gej_t aij; secp256k1_gej_add_var(&aij, &aj, &ij); - secp256k1_gej_t anj; secp256k1_gej_add_var(&anj, &aj, &nj); - secp256k1_gej_t iaj; secp256k1_gej_add_var(&iaj, &ij, &aj); - secp256k1_gej_t iij; secp256k1_gej_add_var(&iij, &ij, &ij); + /* Test gej + ge (var). */ + secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2]); + ge_equals_gej(&ref, &resj); - /* gej + ge adds */ - secp256k1_gej_t aa; secp256k1_gej_add_ge_var(&aa, &aj, &a); - secp256k1_gej_t ab; secp256k1_gej_add_ge_var(&ab, &aj, &b); - secp256k1_gej_t ai; secp256k1_gej_add_ge_var(&ai, &aj, &i); - secp256k1_gej_t an; secp256k1_gej_add_ge_var(&an, &aj, &n); - secp256k1_gej_t ia; secp256k1_gej_add_ge_var(&ia, &ij, &a); - secp256k1_gej_t ii; secp256k1_gej_add_ge_var(&ii, &ij, &i); + /* Test gej + ge (const). */ + if (i2 != 0) { + /* secp256k1_gej_add_ge does not support its second argument being infinity. */ + secp256k1_gej_add_ge(&resj, &gej[i1], &ge[i2]); + ge_equals_gej(&ref, &resj); + } - /* const gej + ge adds */ - secp256k1_gej_t aac; secp256k1_gej_add_ge(&aac, &aj, &a); - secp256k1_gej_t abc; secp256k1_gej_add_ge(&abc, &aj, &b); - secp256k1_gej_t anc; secp256k1_gej_add_ge(&anc, &aj, &n); - secp256k1_gej_t iac; secp256k1_gej_add_ge(&iac, &ij, &a); + /* Test doubling (var). */ + if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 == ((i2 + 3)%4)/2)) { + /* Normal doubling. */ + secp256k1_gej_double_var(&resj, &gej[i1]); + ge_equals_gej(&ref, &resj); + secp256k1_gej_double_var(&resj, &gej[i2]); + ge_equals_gej(&ref, &resj); + } - CHECK(secp256k1_gej_is_infinity(&an)); - CHECK(secp256k1_gej_is_infinity(&anj)); - CHECK(secp256k1_gej_is_infinity(&anc)); - gej_equals_gej(&aa, &aaj); - gej_equals_gej(&aa, &aac); - gej_equals_gej(&ab, &abj); - gej_equals_gej(&ab, &abc); - gej_equals_gej(&an, &anj); - gej_equals_gej(&an, &anc); - gej_equals_gej(&ia, &iaj); - gej_equals_gej(&ai, &aij); - gej_equals_gej(&ii, &iij); - ge_equals_gej(&a, &ai); - ge_equals_gej(&a, &ai); - ge_equals_gej(&a, &iaj); - ge_equals_gej(&a, &iaj); - ge_equals_gej(&a, &iac); + /* Test adding opposites. */ + if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 != ((i2 + 3)%4)/2)) { + CHECK(secp256k1_ge_is_infinity(&ref)); + } + + /* Test adding infinity. */ + if (i1 == 0) { + CHECK(secp256k1_ge_is_infinity(&ge[i1])); + CHECK(secp256k1_gej_is_infinity(&gej[i1])); + ge_equals_gej(&ref, &gej[i2]); + } + if (i2 == 0) { + CHECK(secp256k1_ge_is_infinity(&ge[i2])); + CHECK(secp256k1_gej_is_infinity(&gej[i2])); + ge_equals_gej(&ref, &gej[i1]); + } + } + } + + /* Test adding all points together in random order equals infinity. */ + { + secp256k1_gej_t *gej_shuffled = malloc((4 * runs + 1) * sizeof(secp256k1_gej_t)); + for (int i = 0; i < 4 * runs + 1; i++) { + gej_shuffled[i] = gej[i]; + } + for (int i = 0; i < 4 * runs + 1; i++) { + int swap = i + secp256k1_rand32() % (4 * runs + 1 - i); + if (swap != i) { + secp256k1_gej_t t = gej_shuffled[i]; + gej_shuffled[i] = gej_shuffled[swap]; + gej_shuffled[swap] = t; + } + } + secp256k1_gej_t sum; + secp256k1_gej_set_infinity(&sum); + for (int i = 0; i < 4 * runs + 1; i++) { + secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i]); + } + CHECK(secp256k1_gej_is_infinity(&sum)); + free(gej_shuffled); + } + + /* Test batch gej -> ge conversion. */ + { + secp256k1_ge_t *ge_set_all = malloc((4 * runs + 1) * sizeof(secp256k1_ge_t)); + secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej); + for (int i = 0; i < 4 * runs + 1; i++) { + ge_equals_gej(&ge_set_all[i], &gej[i]); + } + free(ge_set_all); + } + + free(ge); + free(gej); } void run_ge(void) { - for (int i = 0; i < 2000*count; i++) { + for (int i = 0; i < count * 32; i++) { test_ge(); } } @@ -949,6 +1111,44 @@ void run_ecdsa_sign_verify(void) { } } +/** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */ +static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { + (void)msg32; + (void)key32; + memcpy(nonce32, data, 32); + return (counter == 0); +} + +static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { + /* Dummy nonce generator that has a fatal error on the first counter value. */ + if (counter == 0) return 0; + return nonce_function_rfc6979(nonce32, msg32, key32, counter - 1, data); +} + +static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { + /* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */ + if (counter < 3) { + memset(nonce32, counter==0 ? 0 : 255, 32); + if (counter == 2) nonce32[31]--; + return 1; + } + if (counter < 5) { + static const unsigned char order[] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, + 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 + }; + memcpy(nonce32, order, 32); + if (counter == 4) nonce32[31]++; + return 1; + } + /* Retry rate of 6979 is negligible esp. as we only call this in determinstic tests. */ + /* If someone does fine a case where it retries for secp256k1, we'd like to know. */ + if (counter > 5) return 0; + return nonce_function_rfc6979(nonce32, msg32, key32, counter - 5, data); +} + void test_ecdsa_end_to_end(void) { unsigned char privkey[32]; unsigned char message[32]; @@ -1006,13 +1206,7 @@ void test_ecdsa_end_to_end(void) { /* Sign. */ unsigned char signature[72]; int signaturelen = 72; - while(1) { - unsigned char rnd[32]; - secp256k1_rand256_test(rnd); - if (secp256k1_ecdsa_sign(message, signature, &signaturelen, privkey, rnd) == 1) { - break; - } - } + CHECK(secp256k1_ecdsa_sign(message, signature, &signaturelen, privkey, NULL, NULL) == 1); /* Verify. */ CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) == 1); /* Destroy signature and verify again. */ @@ -1021,13 +1215,7 @@ void test_ecdsa_end_to_end(void) { /* Compact sign. */ unsigned char csignature[64]; int recid = 0; - while(1) { - unsigned char rnd[32]; - secp256k1_rand256_test(rnd); - if (secp256k1_ecdsa_sign_compact(message, csignature, privkey, rnd, &recid) == 1) { - break; - } - } + CHECK(secp256k1_ecdsa_sign_compact(message, csignature, privkey, NULL, NULL, &recid) == 1); /* Recover. */ unsigned char recpubkey[65]; int recpubkeylen = 0; CHECK(secp256k1_ecdsa_recover_compact(message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1); @@ -1077,7 +1265,7 @@ void test_random_pubkeys(void) { CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0)); CHECK(size == 65); CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size)); - CHECK(ge_equals_ge(&elem,&elem2)); + ge_equals_ge(&elem,&elem2); /* Check that the X9.62 hybrid type is checked. */ in[0] = (r & 1) ? 6 : 7; res = secp256k1_eckey_pubkey_parse(&elem2, in, size); @@ -1086,7 +1274,7 @@ void test_random_pubkeys(void) { else CHECK(!res); } if (res) { - CHECK(ge_equals_ge(&elem,&elem2)); + ge_equals_ge(&elem,&elem2); CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0)); CHECK(memcmp(&in[1], &out[1], 64) == 0); } @@ -1280,6 +1468,12 @@ void test_ecdsa_edge_cases(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }; + static const unsigned char nonce2[32] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, + 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40 + }; const unsigned char key[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1294,10 +1488,74 @@ void test_ecdsa_edge_cases(void) { }; unsigned char sig[72]; int siglen = 72; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce) == 0); + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0); + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0); msg[31] = 0xaa; siglen = 72; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce) == 1); + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1); + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1); + siglen = 10; + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1); + } + + /* Nonce function corner cases. */ + { + unsigned char key[32]; + unsigned char msg[32]; + unsigned char sig[72]; + memset(key, 0, 32); + memset(msg, 0, 32); + key[31] = 1; + msg[31] = 1; + int siglen = 72; + int recid; + /* Nonce function failure results in signature failure. */ + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_fail, NULL) == 0); + CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_fail, NULL, &recid) == 0); + /* The retry loop successfully makes its way to the first good value. */ + unsigned char sig2[72]; + int siglen2 = 72; + siglen = 72; + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_retry, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, nonce_function_rfc6979, NULL) == 1); + CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); + int recid2; + CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_retry, NULL, &recid) == 1); + CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, nonce_function_rfc6979, NULL, &recid2) == 1); + CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); + /* The default nonce function is determinstic. */ + siglen = 72; + siglen2 = 72; + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1); + CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); + CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, NULL, NULL, &recid) == 1); + CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, NULL, NULL, &recid2) == 1); + CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); + /* The default nonce function changes output with different messages. */ + secp256k1_ecdsa_sig_t s[512]; + for(int i=0; i<256; i++) { + siglen2 = 72; + msg[0] = i; + CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2)); + for (int j=0; j Date: Tue, 6 Jan 2015 00:42:20 +0100 Subject: [PATCH 0146/2337] Move arith_uint256 out of consensus and util --- src/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index bc2b1aff963..1ef88f06807 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -233,6 +233,7 @@ univalue_libbitcoin_univalue_a_SOURCES = \ libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_common_a_SOURCES = \ allocators.cpp \ + arith_uint256.cpp \ amount.cpp \ base58.cpp \ chainparams.cpp \ @@ -262,7 +263,6 @@ libbitcoin_common_a_SOURCES = \ # backward-compatibility objects and their sanity checks are linked. libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_util_a_SOURCES = \ - arith_uint256.cpp \ chainparamsbase.cpp \ clientversion.cpp \ compat/glibc_sanity.cpp \ @@ -354,7 +354,6 @@ bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if BUILD_BITCOIN_LIBS include_HEADERS = script/bitcoinconsensus.h libbitcoinconsensus_la_SOURCES = \ - arith_uint256.cpp \ crypto/hmac_sha512.cpp \ crypto/ripemd160.cpp \ crypto/sha1.cpp \ From d58c5d6f21fd2421bc8cbb224849e8c38b617775 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 5 Jan 2015 21:39:40 -0500 Subject: [PATCH 0147/2337] tests: run sanity checks in tests too If these are going to fail in bitcoind, they should fail in the tests as well. --- src/Makefile.test.include | 1 + src/test/sanity_tests.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/test/sanity_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 2f10702d86f..710956a72be 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -58,6 +58,7 @@ BITCOIN_TESTS =\ test/netbase_tests.cpp \ test/pmt_tests.cpp \ test/rpc_tests.cpp \ + test/sanity_tests.cpp \ test/script_P2SH_tests.cpp \ test/script_tests.cpp \ test/scriptnum_tests.cpp \ diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp new file mode 100644 index 00000000000..464a8fbb8cf --- /dev/null +++ b/src/test/sanity_tests.cpp @@ -0,0 +1,18 @@ +// Copyright (c) 2012-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "compat/sanity.h" +#include "key.h" + +#include +BOOST_AUTO_TEST_SUITE(sanity_tests) + +BOOST_AUTO_TEST_CASE(basic_sanity) +{ + BOOST_CHECK_MESSAGE(glibc_sanity_test() == true, "libc sanity test"); + BOOST_CHECK_MESSAGE(glibcxx_sanity_test() == true, "stdlib sanity test"); + BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "openssl ECC test"); +} + +BOOST_AUTO_TEST_SUITE_END() From fe925e221ffcde1c810830a8985fa984254ca328 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 5 Jan 2015 20:34:00 +0000 Subject: [PATCH 0148/2337] Use EXTRA_LIBRARIES instead of noinst_LIBRARIES so we can avoid building unused code --- src/Makefile.am | 4 ++-- src/Makefile.qt.include | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index d6ac6e12776..81b16d1ea9a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,7 +37,7 @@ $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: -noinst_LIBRARIES = \ +EXTRA_LIBRARIES = \ crypto/libbitcoin_crypto.a \ libbitcoin_util.a \ libbitcoin_common.a \ @@ -46,7 +46,7 @@ noinst_LIBRARIES = \ libbitcoin_cli.a if ENABLE_WALLET BITCOIN_INCLUDES += $(BDB_CPPFLAGS) -noinst_LIBRARIES += libbitcoin_wallet.a +EXTRA_LIBRARIES += libbitcoin_wallet.a endif if BUILD_BITCOIN_LIBS diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 898337ad6fe..5812f9aff0b 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -1,5 +1,5 @@ bin_PROGRAMS += qt/bitcoin-qt -noinst_LIBRARIES += qt/libbitcoinqt.a +EXTRA_LIBRARIES += qt/libbitcoinqt.a # bitcoin qt core # QT_TS = \ From f0b8afc88ba47a442c7493a3bf190acf9275fb60 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 6 Jan 2015 20:11:16 -0500 Subject: [PATCH 0149/2337] tests: fix spurious windows test failures after 012598880c on rare occasions, rand() was returning duped values, causing duplicate transactions. BuildMerkleTree happily used these, but CPartialMerkleTree caught them and returned a null merkle root. Rather than taking changes with rand(), use the loop counter to guarantee unique values. At sipa's request, also remove the remaining uses of rand(). --- src/test/pmt_tests.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 372cf3b306e..4406b08e569 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -8,6 +8,7 @@ #include "uint256.h" #include "arith_uint256.h" #include "version.h" +#include "random.h" #include @@ -21,8 +22,8 @@ class CPartialMerkleTreeTester : public CPartialMerkleTree public: // flip one bit in one of the hashes - this should break the authentication void Damage() { - unsigned int n = rand() % vHash.size(); - int bit = rand() % 256; + unsigned int n = insecure_rand() % vHash.size(); + int bit = insecure_rand() % 256; *(vHash[n].begin() + (bit>>3)) ^= 1<<(bit&7); } }; @@ -31,6 +32,7 @@ BOOST_AUTO_TEST_SUITE(pmt_tests) BOOST_AUTO_TEST_CASE(pmt_test1) { + seed_insecure_rand(false); static const unsigned int nTxCounts[] = {1, 4, 7, 17, 56, 100, 127, 256, 312, 513, 1000, 4095}; for (int n = 0; n < 12; n++) { @@ -40,7 +42,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) CBlock block; for (unsigned int j=0; j vMatch(nTx, false); std::vector vMatchTxid1; for (unsigned int j=0; j Date: Wed, 7 Jan 2015 10:11:23 -0500 Subject: [PATCH 0150/2337] Fix smartfees test for change to relay policy --- qa/rpc-tests/smartfees.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 924d1601025..0c07ef8a53d 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -16,20 +16,20 @@ class EstimateFeeTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, - ["-debug=mempool", "-debug=estimatefee"])) + ["-debug=mempool", "-debug=estimatefee", "-relaypriority=0"])) # Node1 mines small-but-not-tiny blocks, and allows free transactions. # NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes, # so blockmaxsize of 2,000 is really just 1,000 bytes (room enough for # 6 or 7 transactions) self.nodes.append(start_node(1, self.options.tmpdir, ["-blockprioritysize=1500", "-blockmaxsize=2000", - "-debug=mempool", "-debug=estimatefee"])) + "-debug=mempool", "-debug=estimatefee", "-relaypriority=0"])) connect_nodes(self.nodes[1], 0) # Node2 is a stingy miner, that # produces very small blocks (room for only 3 or so transactions) node2args = [ "-blockprioritysize=0", "-blockmaxsize=1500", - "-debug=mempool", "-debug=estimatefee"] + "-debug=mempool", "-debug=estimatefee", "-relaypriority=0"] self.nodes.append(start_node(2, self.options.tmpdir, node2args)) connect_nodes(self.nodes[2], 0) From 84d919974bfa22c9332faa36768d52cbbcc594f5 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 7 Jan 2015 11:21:53 +0100 Subject: [PATCH 0151/2337] [QA] fix zapwallettxes test - remove shell test script and add a python equivalent --- qa/pull-tester/rpc-tests.sh | 3 +- qa/rpc-tests/zapwallettxes.py | 82 +++++++++++++++++ qa/rpc-tests/zapwallettxes.sh | 165 ---------------------------------- 3 files changed, 84 insertions(+), 166 deletions(-) create mode 100755 qa/rpc-tests/zapwallettxes.py delete mode 100755 qa/rpc-tests/zapwallettxes.sh diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 15cac145957..efeee455306 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -26,6 +26,7 @@ testScripts=( 'mempool_spendcoinbase.py' 'mempool_coinbase_spends.py' 'httpbasics.py' + 'zapwallettxes.py' # 'forknotify.py' ); if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then @@ -33,7 +34,7 @@ if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then do if [ -z "$1" ] || [ "$1" == "${testScripts[$i]}" ] || [ "$1.py" == "${testScripts[$i]}" ] then - echo -e "running testscript \033[1m${testScripts[$i]}...\033[0m" + echo -e "Running testscript \033[1m${testScripts[$i]}...\033[0m" ${BUILDDIR}/qa/rpc-tests/${testScripts[$i]} --srcdir "${BUILDDIR}/src" fi done diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py new file mode 100755 index 00000000000..a773575906f --- /dev/null +++ b/qa/rpc-tests/zapwallettxes.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework import BitcoinTestFramework +from util import * + + +class ZapWalletTXesTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 3) + + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.is_network_split=False + self.sync_all() + + def run_test (self): + print "Mining blocks..." + self.nodes[0].setgenerate(True, 1) + self.sync_all() + self.nodes[1].setgenerate(True, 101) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 50) + + txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) + txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) + self.sync_all() + self.nodes[0].setgenerate(True, 1) + self.sync_all() + + txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) + txid3 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) + + tx0 = self.nodes[0].gettransaction(txid0) + assert_equal(tx0['txid'], txid0) #tx0 must be available (confirmed) + + tx1 = self.nodes[0].gettransaction(txid1) + assert_equal(tx1['txid'], txid1) #tx1 must be available (confirmed) + + tx2 = self.nodes[0].gettransaction(txid2) + assert_equal(tx2['txid'], txid2) #tx2 must be available (unconfirmed) + + tx3 = self.nodes[0].gettransaction(txid3) + assert_equal(tx3['txid'], txid3) #tx3 must be available (unconfirmed) + + #restart bitcoind + self.nodes[0].stop() + bitcoind_processes[0].wait() + self.nodes[0] = start_node(0,self.options.tmpdir) + + tx3 = self.nodes[0].gettransaction(txid3) + assert_equal(tx3['txid'], txid3) #tx must be available (unconfirmed) + + self.nodes[0].stop() + bitcoind_processes[0].wait() + + #restart bitcoind with zapwallettxes + self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"]) + + aException = False + try: + tx3 = self.nodes[0].gettransaction(txid3) + except JSONRPCException,e: + print e + aException = True + + assert_equal(aException, True) #there must be a expection because the unconfirmed wallettx0 must be gone by now + + tx0 = self.nodes[0].gettransaction(txid0) + assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed + + +if __name__ == '__main__': + ZapWalletTXesTest ().main () diff --git a/qa/rpc-tests/zapwallettxes.sh b/qa/rpc-tests/zapwallettxes.sh deleted file mode 100755 index 4312d84e944..00000000000 --- a/qa/rpc-tests/zapwallettxes.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2014 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -# Test -zapwallettxes= - -if [ $# -lt 1 ]; then - echo "Usage: $0 path_to_binaries" - echo "e.g. $0 ../../src" - echo "Env vars BITCOIND and BITCOINCLI may be used to specify the exact binaries used" - exit 1 -fi - -set -f - -BITCOIND=${BITCOIND:-${1}/bitcoind} -CLI=${BITCOINCLI:-${1}/bitcoin-cli} - -DIR="${BASH_SOURCE%/*}" -SENDANDWAIT="${DIR}/send.sh" -if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi -. "$DIR/util.sh" - -D=$(mktemp -d test.XXXXX) - -D1=${D}/node1 -CreateDataDir "$D1" port=11000 rpcport=11001 -B1ARGS="-datadir=$D1" -$BITCOIND $B1ARGS & -B1PID=$! - -D2=${D}/node2 -CreateDataDir "$D2" port=11010 rpcport=11011 -B2ARGS="-datadir=$D2" -$BITCOIND $B2ARGS & -B2PID=$! - -function CleanUp { -$CLI $B2ARGS stop > /dev/null 2>&1 -wait $B2PID -$CLI $B1ARGS stop > /dev/null 2>&1 -wait $B1PID - -rm -rf $D -} - -# 110 blocks, 10 mature == 500 XBT -$CLI $B1ARGS setgenerate true 110 -$CLI $B2ARGS setgenerate true 110 - -CheckBalance "$B1ARGS" 500 -CheckBalance "$B2ARGS" 500 - -# Send 10 XBT -TXID1_DEFAULT=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10) -TXID2_DEFAULT=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10) - -CheckBalance $B1ARGS 490 -CheckBalance $B2ARGS 490 - -# Move 10 XBT to testaccount -TMP=$($CLI $B1ARGS move "" "testaccount" 10) -TMP=$($CLI $B2ARGS move "" "testaccount" 10) - -CheckBalance $B1ARGS 10 "testaccount" -CheckBalance $B2ARGS 10 "testaccount" - -# Send 1 XBT from testaccount -TXID1_TESTACCOUNT=$($CLI $B1ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1) -TXID2_TESTACCOUNT=$($CLI $B2ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1) - -CheckBalance $B1ARGS 9 "testaccount" -CheckBalance $B2ARGS 9 "testaccount" - -CheckBalance $B1ARGS 489 -CheckBalance $B2ARGS 489 - -# Confirm transactions -$CLI $B1ARGS setgenerate true 1 -$CLI $B2ARGS setgenerate true 1 - -# Create unconfirmed transaction -TXID1_UNCONFIRMED=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1) -TXID2_UNCONFIRMED=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1) - -# check balance (we created another 50 and spent 1 in the meantime) -CheckBalance $B1ARGS 538 -CheckBalance $B2ARGS 538 - -# Safety check, if unconfirmed transactions are there -$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1 -if [[ $? -ne 0 ]] ; then - echoerr "gettransaction1_1: $TXID1_UNCONFIRMED failed" - CleanUp - exit 1 -fi -$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1 -if [[ $? -ne 0 ]] ; then - echoerr "gettransaction2_1: $TXID2_UNCONFIRMED failed" - CleanUp - exit 1 -fi - -# stop nodes -$CLI $B2ARGS stop > /dev/null 2>&1 -wait $B2PID -$CLI $B1ARGS stop > /dev/null 2>&1 -wait $B1PID - -# restart nodes with -zapwallettxes -$BITCOIND -zapwallettxes=1 $B1ARGS & -B1PID=$! -$BITCOIND -zapwallettxes=2 $B2ARGS & -B2PID=$! - -# check if confirmed transactions are there -$CLI $B1ARGS gettransaction $TXID1_DEFAULT > /dev/null 2>&1 -if [[ $? -ne 0 ]] ; then - echoerr "check confirmed transaction 1: $TXID1_DEFAULT failed" - CleanUp - exit 1 -fi -$CLI $B2ARGS gettransaction $TXID2_DEFAULT > /dev/null 2>&1 -if [[ $? -ne 0 ]] ; then - echoerr "check confirmed transaction 2: $TXID2_DEFAULT failed" - CleanUp - exit 1 -fi -$CLI $B1ARGS gettransaction $TXID1_TESTACCOUNT > /dev/null 2>&1 -if [[ $? -ne 0 ]] ; then - echoerr "check confirmed transaction 3: $TXID1_TESTACCOUNT failed" - CleanUp - exit 1 -fi -$CLI $B2ARGS gettransaction $TXID2_TESTACCOUNT > /dev/null 2>&1 -if [[ $? -ne 0 ]] ; then - echoerr "check confirmed transaction 4: $TXID2_TESTACCOUNT failed" - CleanUp - exit 1 -fi - -# check if unconfirmed transaction is gone -$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1 -if [[ $? -eq 0 ]] ; then - echoerr "check unconfirmed transaction 1: $TXID1_UNCONFIRMED failed" - CleanUp - exit 1 -fi -$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1 -if [[ $? -eq 0 ]] ; then - echoerr "check unconfirmed transaction 2: $TXID2_UNCONFIRMED failed" - CleanUp - exit 1 -fi - -# check zapwallet mode 1, testaccount balance must be 9 (keeping transaction metadata) -CheckBalance $B1ARGS 9 "testaccount" - -# check zapwallet mode 2, testaccount balance must be 10 (dropping transaction metadata) -CheckBalance $B2ARGS 10 "testaccount" - -echo "Tests successful, cleaning up" -CleanUp -exit 0 From a19eeaced85cfff3faab19f532b1a0d97b637705 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 6 Jan 2015 13:24:13 +0000 Subject: [PATCH 0152/2337] Bugfix: configure: Check for openssl/ec.h --- configure.ac | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configure.ac b/configure.ac index c4c21eaf4f6..2abfd0d419f 100644 --- a/configure.ac +++ b/configure.ac @@ -678,6 +678,14 @@ else fi fi +CFLAGS_TEMP="$CFLAGS" +LIBS_TEMP="$LIBS" +CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS" +LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS" +AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),) +CFLAGS="$CFLAGS_TEMP" +LIBS="$LIBS_TEMP" + BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) AC_MSG_CHECKING([whether to build bitcoind]) From 916130348ca803d762db912307b247f60f9aacd6 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 6 Jan 2015 17:05:46 +0100 Subject: [PATCH 0153/2337] Introduce 10 minute block download timeout This will disconnect peers that do not transfer a block in 10 minutes, plus 5 minutes for every previously queued block with validated headers (accomodating downstream bandwidth down to a few kilobytes per second - below that the node would have trouble staying synchronized anyway). --- src/main.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index e1a09733528..e7a33929660 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -139,9 +139,14 @@ namespace { uint256 hash; CBlockIndex *pindex; //! Optional. int64_t nTime; //! Time of "getdata" request in microseconds. + int nValidatedQueuedBefore; //! Number of blocks queued with validated headers (globally) at the time this one is requested. + bool fValidatedHeaders; //! Whether this block has validated headers at the time of request. }; map::iterator> > mapBlocksInFlight; + /** Number of blocks in flight with validated headers. */ + int nQueuedValidatedHeaders = 0; + /** Number of preferable block download peers. */ int nPreferredDownload = 0; @@ -323,6 +328,7 @@ void MarkBlockAsReceived(const uint256& hash) { map::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); if (itInFlight != mapBlocksInFlight.end()) { CNodeState *state = State(itInFlight->second.first); + nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders; state->vBlocksInFlight.erase(itInFlight->second.second); state->nBlocksInFlight--; state->nStallingSince = 0; @@ -338,7 +344,8 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex // Make sure it's not listed somewhere already. MarkBlockAsReceived(hash); - QueuedBlock newentry = {hash, pindex, GetTimeMicros()}; + QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL}; + nQueuedValidatedHeaders += newentry.fValidatedHeaders; list::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); state->nBlocksInFlight++; mapBlocksInFlight[hash] = std::make_pair(nodeid, it); @@ -4527,6 +4534,15 @@ bool SendMessages(CNode* pto, bool fSendTrickle) LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id); pto->fDisconnect = true; } + // In case there is a block that has been in flight from this peer for (1 + 0.5 * N) times the block interval + // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to + // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link + // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes + // to unreasonably increase our timeout. + if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (2 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { + LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id); + pto->fDisconnect = true; + } // // Message: getdata (blocks) From b7a4ecc1535e4e154b2ca5da16afecc096e152e8 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 6 Jan 2015 13:12:39 +0000 Subject: [PATCH 0154/2337] Bugfix: Only check for boost when building code that requires it --- configure.ac | 64 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index 2abfd0d419f..740f7e8e0d6 100644 --- a/configure.ac +++ b/configure.ac @@ -171,6 +171,24 @@ if test "x$CXXFLAGS_overridden" = "xno"; then fi CPPFLAGS="$CPPFLAGS -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" +AC_ARG_WITH([utils], + [AS_HELP_STRING([--with-utils], + [build bitcoin-cli bitcoin-tx (default=yes)])], + [build_bitcoin_utils=$withval], + [build_bitcoin_utils=yes]) + +AC_ARG_WITH([libs], + [AS_HELP_STRING([--with-libs], + [build libraries (default=yes)])], + [build_bitcoin_libs=$withval], + [build_bitcoin_libs=yes]) + +AC_ARG_WITH([daemon], + [AS_HELP_STRING([--with-daemon], + [build bitcoind daemon (default=yes)])], + [build_bitcoind=$withval], + [build_bitcoind=yes]) + AC_LANG_PUSH([C++]) use_pkgconfig=yes @@ -500,6 +518,19 @@ if test x$use_upnp != xno; then ) fi +BITCOIN_QT_INIT + +dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus +BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4]) + +if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then + use_boost=no +else + use_boost=yes +fi + +if test x$use_boost = xyes; then + dnl Check for boost libs AX_BOOST_BASE AX_BOOST_SYSTEM @@ -537,6 +568,10 @@ if test x$use_reduce_exports != xno; then CPPFLAGS="$TEMP_CPPFLAGS" fi +elif test x$use_reduce_exports = xauto; then + use_reduce_exports=yes +fi + if test x$use_reduce_exports != xno; then CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS" AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"]) @@ -549,6 +584,8 @@ if test x$use_tests = xyes; then fi + if test x$use_boost = xyes; then + AX_BOOST_UNIT_TEST_FRAMEWORK dnl Determine if -DBOOST_TEST_DYN_LINK is needed @@ -568,8 +605,12 @@ if test x$use_tests = xyes; then [AC_MSG_RESULT(no)]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" + + fi fi +if test x$use_boost = xyes; then + BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB" dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however @@ -626,25 +667,7 @@ if test x$boost_sleep != xyes; then AC_MSG_ERROR(No working boost sleep implementation found.) fi -AC_ARG_WITH([utils], - [AS_HELP_STRING([--with-utils], - [build bitcoin-cli bitcoin-tx (default=yes)])], - [build_bitcoin_utils=$withval], - [build_bitcoin_utils=yes]) - -AC_ARG_WITH([libs], - [AS_HELP_STRING([--with-libs], - [build libraries (default=yes)])], - [build_bitcoin_libs=$withval], - [build_bitcoin_libs=yes]) - -AC_ARG_WITH([daemon], - [AS_HELP_STRING([--with-daemon], - [build bitcoind daemon (default=yes)])], - [build_bitcoind=$withval], - [build_bitcoind=yes]) - -BITCOIN_QT_INIT +fi if test x$use_pkgconfig = xyes; then @@ -703,9 +726,6 @@ if test x$build_bitcoin_libs = xyes; then fi AC_MSG_RESULT($build_bitcoin_libs) -dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus -BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4]) - AC_LANG_POP if test "x$use_ccache" != "xno"; then From 2ecd2941edc8d07090b6b4aeaae7bc4c9c333066 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 7 Jan 2015 20:19:56 +0000 Subject: [PATCH 0155/2337] Bugfix: configure: Correctly detect "nothing to build" condition --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 740f7e8e0d6..173c93c538e 100644 --- a/configure.ac +++ b/configure.ac @@ -839,7 +839,7 @@ else AC_MSG_RESULT([no]) fi -if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then +if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnonononono; then AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui or --enable-tests]) fi From c6a5ad481975c482f33a7f7ecd210f15e2667b62 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 8 Jan 2015 12:49:32 +0100 Subject: [PATCH 0156/2337] Fix tests after #5413 Pull #5413 was not rebased after deterministic signing was merged (#5227), so the testcases had to be regenerated using UPDATE_JSON_TESTS. --- src/test/data/script_invalid.json | 4 ++-- src/test/data/script_valid.json | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index bae750b79fc..42b79e7470e 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -668,13 +668,13 @@ "P2SH(P2PK) with non-push scriptSig" ], [ - "11 0x47 0x3044022057c4ba463d3b8e6848b3896be14c6953caf0528cd390ad15104a109c94b558ba02206fa3922154e1d0bfca92ce5f9adbe4991be33f3f5b7f6bf501e895b7e37fd72f01", + "11 0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "CLEANSTACK,P2SH", "P2PK with unnecessary input" ], [ - "11 0x47 0x304402203407c26745ea95ee31fbb5074e730ff9be235d5a8d8e0a2c868358bf6a04797402205cc0e594dfd275583472168298d448be59c2530a4ea4d7c37311b82108f9f8bc01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", "CLEANSTACK,P2SH", "P2SH with unnecessary input" diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 4889c96d2cd..5253d5e39eb 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -817,19 +817,19 @@ "2-of-2 with two identical keys and sigs pushed" ], [ - "11 0x47 0x304402204ba8b04dfe8657608427b996bd7c151ff8cd8579b3316c7314549a6c59f6bfb7022058cf052927fbc5e51e26dd4711c470bbf7f3adc8aaaf7bfa304eff6bb6e6399e01", + "11 0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "P2SH", "P2PK with unnecessary input but no CLEANSTACK" ], [ - "11 0x47 0x304402202beaa2f6a4ec783091643797f9819b5ae39a03dfcf3b934746e96dd6b2ad5f7202200650a618fb2ce08b4edd160351172e016a041c81622d806390420d15cc6cece401 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", "P2SH", "P2SH with unnecessary input but no CLEANSTACK" ], [ - "0x47 0x3044022048505fd42afde400932558ea7fa76a52c2fff3130fa820a6a05647f64d5d780e022056a6bc823c95cedf68f6f67ad036533b48b9f3f706355a71f9f6e647e889f79201 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + "0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", "CLEANSTACK,P2SH", "P2SH with CLEANSTACK" From 13cdce4336818d0f6cefe6b3e61c45762d97d7c6 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 8 Jan 2015 14:38:06 +0100 Subject: [PATCH 0157/2337] Catch UTXO set read errors and shutdown --- src/init.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 03d67f0aa31..d6f1e1cb9f9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -111,7 +111,28 @@ bool ShutdownRequested() return fRequestShutdown; } +class CCoinsViewErrorCatcher : public CCoinsViewBacked +{ +public: + CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {} + bool GetCoins(const uint256 &txid, CCoins &coins) const { + try { + return CCoinsViewBacked::GetCoins(txid, coins); + } catch(const std::runtime_error& e) { + uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR); + LogPrintf("Error reading from database: %s\n", e.what()); + // Starting the shutdown sequence and returning false to the caller would be + // interpreted as 'entry not found' (as opposed to unable to read data), and + // could lead to invalid interpration. Just exit immediately, as we can't + // continue anyway, and all writes should be atomic. + abort(); + } + } + // Writes do not need similar protection, as failure to write is handled by the caller. +}; + static CCoinsViewDB *pcoinsdbview = NULL; +static CCoinsViewErrorCatcher *pcoinscatcher = NULL; void Shutdown() { @@ -154,6 +175,8 @@ void Shutdown() } delete pcoinsTip; pcoinsTip = NULL; + delete pcoinscatcher; + pcoinscatcher = NULL; delete pcoinsdbview; pcoinsdbview = NULL; delete pblocktree; @@ -990,11 +1013,13 @@ bool AppInit2(boost::thread_group& threadGroup) UnloadBlockIndex(); delete pcoinsTip; delete pcoinsdbview; + delete pcoinscatcher; delete pblocktree; pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex); - pcoinsTip = new CCoinsViewCache(pcoinsdbview); + pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview); + pcoinsTip = new CCoinsViewCache(pcoinscatcher); if (fReindex) pblocktree->WriteReindexing(true); From 2fa9a8ec86033b809a1c48f0396c3482c0d5d33c Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 9 Jan 2015 05:52:57 -0500 Subject: [PATCH 0158/2337] Make empty byte arrays pass CheckSignatureEncoding() Makes it possible to compactly provide a delibrately invalid signature for use with CHECK(MULTI)SIG. For instance with BIP19 if m != n invalid signatures need to be provided in the scriptSig; prior to this change those invalid signatures would need to be large DER-encoded signatures. Note that we may want to further expand on this change in the future by saying that only OP_0 is a "valid" invalid signature; BIP19 even with this change is inherently malleable as the invalid signatures can be any validly encoded DER signature. --- src/script/interpreter.cpp | 5 +++++ src/test/data/script_invalid.json | 2 +- src/test/data/script_valid.json | 5 +++++ src/test/multisig_tests.cpp | 4 ---- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index d0f75ab672e..8a06f3d1187 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -189,6 +189,11 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) { } bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { + // Empty signature. Not strictly DER encoded, but allowed to provide a + // compact way to provide an invalid signature for use with CHECK(MULTI)SIG + if (vchSig.size() == 0) { + return true; + } if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsDERSignature(vchSig)) { return set_error(serror, SCRIPT_ERR_SIG_DER); } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 42b79e7470e..9a8fe1ee889 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -504,7 +504,7 @@ "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded." ], [ - "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0", + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 1", "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", "STRICTENC", "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid." diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 5253d5e39eb..a187401cd4a 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -662,6 +662,11 @@ ["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", ""], ["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", ""], +["While not really correctly DER encoded, the empty signature is allowed by"], +["STRICTENC to provide a compact way to provide a delibrately invalid signature."], +["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC"], +["0 0", "1 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 1 CHECKMULTISIG NOT", "STRICTENC"], + ["CHECKMULTISIG evaluation order tests. CHECKMULTISIG evaluates signatures and"], ["pubkeys in a specific order, and will exit early if the number of signatures"], ["left to check is greater than the number of keys left. As STRICTENC fails the"], diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 69d85221881..9501169943d 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -116,10 +116,6 @@ BOOST_AUTO_TEST_CASE(multisig_verify) } } s.clear(); - s << OP_0 << OP_0; - BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err)); - BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); - s.clear(); s << OP_0 << OP_1; BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); From 98c222b5aa94543fce683b989356b0d8ad1f1d22 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 9 Jan 2015 20:57:17 +0100 Subject: [PATCH 0159/2337] [Qt] optimize helpmessage dialog - enlarge standard size - remove fixed 10px font - remove left mood image - ensure that table has no ugly line-breaks on OSX, Linux --- src/Makefile.qt.include | 3 +-- src/qt/bitcoin.qrc | 3 --- src/qt/forms/helpmessagedialog.ui | 30 ++---------------------------- src/qt/res/images/about.png | Bin 1136 -> 0 bytes src/qt/utilitydialog.cpp | 4 ++-- 5 files changed, 5 insertions(+), 35 deletions(-) delete mode 100644 src/qt/res/images/about.png diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index cdd8f8d08d1..31fe3a9f691 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -314,8 +314,7 @@ BITCOIN_QT_CPP += \ qt/walletview.cpp endif -RES_IMAGES = \ - qt/res/images/about.png +RES_IMAGES = RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png) diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index bcaf95d91ce..63af146fd02 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -46,9 +46,6 @@ res/icons/about_qt.png res/icons/verify.png - - res/images/about.png - res/movies/spinner-000.png res/movies/spinner-001.png diff --git a/src/qt/forms/helpmessagedialog.ui b/src/qt/forms/helpmessagedialog.ui index 9ace9afd793..37008f047e9 100644 --- a/src/qt/forms/helpmessagedialog.ui +++ b/src/qt/forms/helpmessagedialog.ui @@ -6,32 +6,14 @@ 0 0 - 585 - 225 + 780 + 400 - - - 10 - - Bitcoin Core - Command-line options - - - - - 0 - 0 - - - - :/images/about - - - @@ -50,14 +32,6 @@ true - - - 0 - 0 - 447 - 68 - - diff --git a/src/qt/res/images/about.png b/src/qt/res/images/about.png deleted file mode 100644 index fdede6617264cbb3ffec888fc35679c192344aaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1136 zcmXX`YfO_@7=BvlD3=lnEthh?D4iw9EZq!BXlYA@Fl@Cf6MK``89ys985PZ!-|0+I4;||@B6yv&p9XOJ@50p&->;y zX$v$wKan2*UhW>%K58uk*y&s^YBw=5`3=AlX!G@IX{Q?}R+0QQiZ^ijZ{)2ae-fdu z5ZQ#PRY+G*wF&(Kc8#L;rJ>&qiyMa*AR9!*3NE=J?M3D=3^URmH};NW_W<_I!25GZ zRuMmm{ST1#8LFlsyN8TlP&|Wx4A4v%}ibfIn3AWxh47v?NZe-cPU5EcAR4>B+C^%|EQAqmvjrzpPDLnP>u@&fZI^vgvYS0;FM$4RY=f(xD@qdbp zZC%Q7)t6$9k>JKr&?arq5M|>KaOChD}^*+lf-O=)sp-g;)I`Bzwr2GIQ$5*eu zt7T0QL*}o7X!fPL0iws=iU)+aBZTy4tE46q~wU!NF+lB&2!`$NF0rpDFZysw{TJCb9&W zJx+0XR7cw_;{F?hh0GAJGi`iz?NHizW^ diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 9ee408179d0..06560627f2d 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -73,8 +73,8 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : tf.setBorderStyle(QTextFrameFormat::BorderStyle_None); tf.setCellPadding(2); QVector widths; - widths << QTextLength(QTextLength::PercentageLength, 20); - widths << QTextLength(QTextLength::PercentageLength, 80); + widths << QTextLength(QTextLength::PercentageLength, 35); + widths << QTextLength(QTextLength::PercentageLength, 65); tf.setColumnWidthConstraints(widths); QTextTable *table = cursor.insertTable(2, 2, tf); From 488ed32f2ada1d1dd108fc245d025c4d5f252783 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 9 Jan 2015 16:39:12 -0500 Subject: [PATCH 0160/2337] consensus: guard against openssl's new strict DER checks New versions of OpenSSL will reject non-canonical DER signatures. However, it'll happily decode them. Decode then re-encode before verification in order to ensure that it is properly consumed. --- src/ecwrapper.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp index c29390eb98b..33dd9a9a293 100644 --- a/src/ecwrapper.cpp +++ b/src/ecwrapper.cpp @@ -117,10 +117,20 @@ bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) { } bool CECKey::Verify(const uint256 &hash, const std::vector& vchSig) { - // -1 = error, 0 = bad sig, 1 = good - if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) + // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first. + unsigned char *norm_der = NULL; + ECDSA_SIG *norm_sig = ECDSA_SIG_new(); + const unsigned char* sigptr = &vchSig[0]; + d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()); + int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der); + ECDSA_SIG_free(norm_sig); + if (derlen <= 0) return false; - return true; + + // -1 = error, 0 = bad sig, 1 = good + bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1; + OPENSSL_free(norm_der); + return ret; } bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec) From dad7764a9dedb1143b6ea8bfd37f71f7ff72f518 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 9 Jan 2015 20:52:55 -0500 Subject: [PATCH 0161/2337] depends: bump openssl to 1.0.1k --- depends/packages/openssl.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index ad64494c1f2..32eb1e65395 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -1,8 +1,8 @@ package=openssl -$(package)_version=1.0.1j +$(package)_version=1.0.1k $(package)_download_path=https://www.openssl.org/source $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=1b60ca8789ba6f03e8ef20da2293b8dc131c39d83814e775069f02d26354edf3 +$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" From 8dccba6a45db0466370726ed462b9da2eae43bce Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 9 Jan 2015 22:06:08 -0500 Subject: [PATCH 0162/2337] fail immediately on an empty signature --- src/ecwrapper.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp index 33dd9a9a293..0236e90c166 100644 --- a/src/ecwrapper.cpp +++ b/src/ecwrapper.cpp @@ -117,6 +117,9 @@ bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) { } bool CECKey::Verify(const uint256 &hash, const std::vector& vchSig) { + if (vchSig.empty()) + return false; + // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first. unsigned char *norm_der = NULL; ECDSA_SIG *norm_sig = ECDSA_SIG_new(); From 0fd9e2bf43d217d9a76003476661c8ab53606548 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sat, 10 Jan 2015 15:02:12 +0100 Subject: [PATCH 0163/2337] [Qt] don't allow amount changes when AmountSpinBox is read-only - before it was possible to use the steps to change e.g. amouns of authenticated or unauthenticated payment requests (AmountSpinBox is already set to read-only here) - this is now fixed - also move the reimplemented stepEnabled() function to the protected section of our class, where it belongs (see Qt doc) --- src/qt/bitcoinamountfield.cpp | 38 +++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index fdb9bcd6d6a..3e0ca0282bd 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -20,6 +20,7 @@ class AmountSpinBox: public QAbstractSpinBox { Q_OBJECT + public: explicit AmountSpinBox(QWidget *parent): QAbstractSpinBox(parent), @@ -72,23 +73,6 @@ public: setValue(val); } - StepEnabled stepEnabled() const - { - StepEnabled rv = 0; - if(text().isEmpty()) // Allow step-up with empty field - return StepUpEnabled; - bool valid = false; - CAmount val = value(&valid); - if(valid) - { - if(val > 0) - rv |= StepDownEnabled; - if(val < BitcoinUnits::maxMoney()) - rv |= StepUpEnabled; - } - return rv; - } - void setDisplayUnit(int unit) { bool valid = false; @@ -139,6 +123,7 @@ public: } return cachedMinimumSizeHint; } + private: int currentUnit; CAmount singleStep; @@ -179,6 +164,25 @@ protected: return QAbstractSpinBox::event(event); } + StepEnabled stepEnabled() const + { + StepEnabled rv = 0; + if (isReadOnly()) // Disable steps when AmountSpinBox is read-only + return StepNone; + if(text().isEmpty()) // Allow step-up with empty field + return StepUpEnabled; + bool valid = false; + CAmount val = value(&valid); + if(valid) + { + if(val > 0) + rv |= StepDownEnabled; + if(val < BitcoinUnits::maxMoney()) + rv |= StepUpEnabled; + } + return rv; + } + signals: void valueChanged(); }; From 1078fb08851442bcd7750c3d5015dc1fe7e4d927 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Thu, 8 Jan 2015 19:45:56 +0000 Subject: [PATCH 0164/2337] Make nicer pull request merge messages --- contrib/devtools/github-merge.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh index ec7a1f4c4b3..7e3dad49d2e 100755 --- a/contrib/devtools/github-merge.sh +++ b/contrib/devtools/github-merge.sh @@ -82,13 +82,15 @@ function cleanup() { } # Create unsigned merge commit. +PRTITLE=`curl -s https://api.github.com/repos/$REPO/pulls/$PULL | grep -e ' "title": ".*",'| awk -F'"' '{print $4}'` +MERGEMESSAGE="Merge #$PULL: $PRTITLE" ( - echo "Merge pull request #$PULL" + echo $MERGEMESSAGE echo "" git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head )>"$TMPDIR/message" if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then - if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then + if [ "d$(git log --pretty='format:%s' -n 1)" != "d$MERGEMESSAGE" ]; then echo "ERROR: Creating merge failed (already merged?)." >&2 cleanup exit 4 From 851296a72fc6930404abb94f4175acc1b1aab859 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sat, 10 Jan 2015 14:48:55 +0100 Subject: [PATCH 0165/2337] [Qt] add option to allow self signed root certs (for testing) - it is helpful to be able to test and verify payment request processing by allowing self signed root certificates (e.g. generated by Gavins "certificate authority in a box") - This option is just shown in the UI options, if -help-debug is enabled. --- src/qt/paymentrequestplus.cpp | 10 +++++++++- src/qt/utilitydialog.cpp | 7 +++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 35846bc153d..39171c89eb5 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -9,6 +9,8 @@ #include "paymentrequestplus.h" +#include "util.h" + #include #include @@ -150,7 +152,13 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c int result = X509_verify_cert(store_ctx); if (result != 1) { int error = X509_STORE_CTX_get_error(store_ctx); - throw SSLVerifyError(X509_verify_cert_error_string(error)); + // For testing payment requests, we allow self signed root certs! + // This option is just shown in the UI options, if -help-debug is enabled. + if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GetBoolArg("-allowselfsignedrootcertificates", false))) { + throw SSLVerifyError(X509_verify_cert_error_string(error)); + } else { + qDebug() << "PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true."; + } } X509_NAME *certname = X509_get_subject_name(signing_cert); diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 9ee408179d0..1e1583fb190 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -12,6 +12,7 @@ #include "clientversion.h" #include "init.h" +#include "util.h" #include @@ -108,6 +109,12 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : cursor.movePosition(QTextCursor::NextRow); cursor.insertText(tr("UI options") + ":", bold); cursor.movePosition(QTextCursor::NextRow); + if (GetBoolArg("-help-debug", false)) { + cursor.insertText("-allowselfsignedrootcertificates"); + cursor.movePosition(QTextCursor::NextCell); + cursor.insertText(tr("Allow self signed root certificates (default: 0)")); + cursor.movePosition(QTextCursor::NextCell); + } cursor.insertText("-choosedatadir"); cursor.movePosition(QTextCursor::NextCell); cursor.insertText(tr("Choose data directory on startup (default: 0)")); From c6b7b29f232c651f898eeffb93f36c8f537c56d2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 11 Jan 2015 11:08:53 +0100 Subject: [PATCH 0166/2337] Improve robustness of DER recoding code Add some defensive programming on top of #5634. This copies the respective OpenSSL code in ECDSA_verify in OpenSSL pre-1.0.1k (e.g. https://github.com/openssl/openssl/blob/OpenSSL_1_0_1j/crypto/ecdsa/ecs_vrf.c#L89) more closely. As reported by @sergiodemianlerner. --- src/ecwrapper.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp index 0236e90c166..5e3aec25baf 100644 --- a/src/ecwrapper.cpp +++ b/src/ecwrapper.cpp @@ -124,7 +124,18 @@ bool CECKey::Verify(const uint256 &hash, const std::vector& vchSi unsigned char *norm_der = NULL; ECDSA_SIG *norm_sig = ECDSA_SIG_new(); const unsigned char* sigptr = &vchSig[0]; - d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()); + assert(norm_sig); + if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL) + { + /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on + * error. But OpenSSL's own use of this function redundantly frees the + * result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a + * clear contract for the function behaving the same way is more + * conservative. + */ + ECDSA_SIG_free(norm_sig); + return false; + } int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der); ECDSA_SIG_free(norm_sig); if (derlen <= 0) From 90c71548c795787b008bc337cb9332f75d1bccdb Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 12 Jan 2015 15:29:51 +0100 Subject: [PATCH 0167/2337] depends: remove embedded OpenSSL timestamp for determinism Chery-picked from 0.10 branch. Rebased-From: c3200bcd1e7116e079aebabed3a01dc5385bfc9e --- depends/packages/openssl.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index 32eb1e65395..22b1017ffcc 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -23,7 +23,7 @@ $(package)_config_opts_i686_mingw32=mingw endef define $(package)_preprocess_cmds - sed -i.old "/define DATE/d" crypto/Makefile && \ + sed -i.old "/define DATE/d" util/mkbuildinf.pl && \ sed -i.old "s|engines apps test|engines|" Makefile.org endef From 2ce63d395fe3d71e921ecd9f4263031b25efa14e Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 12 Oct 2014 03:26:42 +0000 Subject: [PATCH 0168/2337] MOVEONLY: Move struct CBlockTemplate to miner.h (from main.h) --- src/main.h | 12 ------------ src/miner.cpp | 1 - src/miner.h | 11 ++++++++--- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/main.h b/src/main.h index 1e00114768d..a8346d1b8f4 100644 --- a/src/main.h +++ b/src/main.h @@ -45,7 +45,6 @@ class CScriptCheck; class CValidationInterface; class CValidationState; -struct CBlockTemplate; struct CNodeStateStats; /** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/ @@ -513,17 +512,6 @@ extern CCoinsViewCache *pcoinsTip; /** Global variable that points to the active block tree (protected by cs_main) */ extern CBlockTreeDB *pblocktree; -struct CBlockTemplate -{ - CBlock block; - std::vector vTxFees; - std::vector vTxSigOps; -}; - - - - - class CValidationInterface { protected: diff --git a/src/miner.cpp b/src/miner.cpp index 87cb158333e..cc97d16f0fe 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -6,7 +6,6 @@ #include "miner.h" #include "amount.h" -#include "primitives/block.h" #include "primitives/transaction.h" #include "hash.h" #include "main.h" diff --git a/src/miner.h b/src/miner.h index 3c08b030f6b..593ddcd3716 100644 --- a/src/miner.h +++ b/src/miner.h @@ -6,16 +6,21 @@ #ifndef BITCOIN_MINER_H #define BITCOIN_MINER_H +#include "primitives/block.h" + #include -class CBlock; -class CBlockHeader; class CBlockIndex; class CReserveKey; class CScript; class CWallet; -struct CBlockTemplate; +struct CBlockTemplate +{ + CBlock block; + std::vector vTxFees; + std::vector vTxSigOps; +}; /** Run the miner threads */ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); From 3ff735c99ae75c21397079f49859b81e89a2f5f8 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 12 Jan 2015 09:53:10 -0800 Subject: [PATCH 0169/2337] Increase block download timeout base from 10 to 20 minutes. This harmonizes the block fetch timeout with the existing ping timeout and eliminates a guaranteed eventual failure from congestion collapse for a network operating right at its limit. It's unlikely that we wouldn't suffer other failures if we were really anywhere near the network's limit, and a complete avoidance of congestion collapse risk requires (I think) an exponential back-off. So this isn't a major concern, but I think it's also useful for reducing the complexity of understanding out timeouts. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7cc69c318b1..0f536cbc6bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4534,12 +4534,12 @@ bool SendMessages(CNode* pto, bool fSendTrickle) LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id); pto->fDisconnect = true; } - // In case there is a block that has been in flight from this peer for (1 + 0.5 * N) times the block interval + // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes // to unreasonably increase our timeout. - if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (2 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { + if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id); pto->fDisconnect = true; } From 1d84aead218e075b21d545f35e6a8efdae8e0169 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 12 Jan 2015 22:26:29 +0000 Subject: [PATCH 0170/2337] Coin Control: Use U+2248 "ALMOST EQUAL TO" rather than a simple tilde (which may be mistaken for a negative sign) --- src/qt/coincontroldialog.cpp | 16 ++++++++-------- src/qt/coincontroldialog.h | 2 ++ src/qt/sendcoinsdialog.cpp | 8 ++++---- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 8422f316f98..f597eeeaf39 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -304,19 +304,19 @@ void CoinControlDialog::clipboardAmount() // copy label "Fee" to clipboard void CoinControlDialog::clipboardFee() { - GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", "")); + GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace(ASYMP_UTF8, "")); } // copy label "After fee" to clipboard void CoinControlDialog::clipboardAfterFee() { - GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", "")); + GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace(ASYMP_UTF8, "")); } // copy label "Bytes" to clipboard void CoinControlDialog::clipboardBytes() { - GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", "")); + GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, "")); } // copy label "Priority" to clipboard @@ -334,7 +334,7 @@ void CoinControlDialog::clipboardLowOutput() // copy label "Change" to clipboard void CoinControlDialog::clipboardChange() { - GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", "")); + GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace(ASYMP_UTF8, "")); } // treeview: sort @@ -600,16 +600,16 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) l2->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAmount)); // Amount l3->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nPayFee)); // Fee l4->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAfterFee)); // After Fee - l5->setText(((nBytes > 0) ? "~" : "") + QString::number(nBytes)); // Bytes + l5->setText(((nBytes > 0) ? ASYMP_UTF8 : "") + QString::number(nBytes)); // Bytes l6->setText(sPriorityLabel); // Priority l7->setText(fDust ? tr("yes") : tr("no")); // Dust l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change if (nPayFee > 0 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000)) { - l3->setText("~" + l3->text()); - l4->setText("~" + l4->text()); + l3->setText(ASYMP_UTF8 + l3->text()); + l4->setText(ASYMP_UTF8 + l4->text()); if (nChange > 0) - l8->setText("~" + l8->text()); + l8->setText(ASYMP_UTF8 + l8->text()); } // turn labels "red" diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 09744430660..5a91876f1f9 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -25,6 +25,8 @@ namespace Ui { class CoinControlDialog; } +#define ASYMP_UTF8 "\xE2\x89\x88" + class CoinControlDialog : public QDialog { Q_OBJECT diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index ffee56131de..1f9bd575453 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -657,19 +657,19 @@ void SendCoinsDialog::coinControlClipboardAmount() // Coin Control: copy label "Fee" to clipboard void SendCoinsDialog::coinControlClipboardFee() { - GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", "")); + GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace(ASYMP_UTF8, "")); } // Coin Control: copy label "After fee" to clipboard void SendCoinsDialog::coinControlClipboardAfterFee() { - GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", "")); + GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace(ASYMP_UTF8, "")); } // Coin Control: copy label "Bytes" to clipboard void SendCoinsDialog::coinControlClipboardBytes() { - GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", "")); + GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, "")); } // Coin Control: copy label "Priority" to clipboard @@ -687,7 +687,7 @@ void SendCoinsDialog::coinControlClipboardLowOutput() // Coin Control: copy label "Change" to clipboard void SendCoinsDialog::coinControlClipboardChange() { - GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", "")); + GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace(ASYMP_UTF8, "")); } // Coin Control: settings menu - coin control enabled/disabled by user From 785bb81c6bc672b55ca20910d2d9599986903753 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 13 Jan 2015 08:38:57 +0100 Subject: [PATCH 0171/2337] [Qt] remove size grip to get rid of the right margin IMO nobody needs a size grip and it looks bad --- src/qt/bitcoingui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 2810eae0528..1e4eecc10d5 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -162,6 +162,9 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : // Create status bar statusBar(); + + // Disable size grip because it looks ugly and nobody needs it + statusBar()->setSizeGripEnabled(false); // Status bar notification icons QFrame *frameBlocks = new QFrame(); From 80dd50ccba97fc7cd0d005f51622d6a2ad8dad84 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Tue, 13 Jan 2015 11:51:45 +0100 Subject: [PATCH 0172/2337] [Qt] group variables below initial if-clauses in AmountSpinBox::stepEnabled --- src/qt/bitcoinamountfield.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index 3e0ca0282bd..4c00aca9858 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -166,11 +166,12 @@ protected: StepEnabled stepEnabled() const { - StepEnabled rv = 0; if (isReadOnly()) // Disable steps when AmountSpinBox is read-only return StepNone; - if(text().isEmpty()) // Allow step-up with empty field + if (text().isEmpty()) // Allow step-up with empty field return StepUpEnabled; + + StepEnabled rv = 0; bool valid = false; CAmount val = value(&valid); if(valid) From 080da96c7c2c89bdf96ba4c0058f6ebba102610f Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sun, 11 Jan 2015 19:42:47 +0100 Subject: [PATCH 0173/2337] [Qt] prepare paymentservertests for new unit tests - add a second PaymentRequest Test CA certificate to paymentrequestdata.h (serial number f0:da:97:e4:38:d7:64:16) as caCert2_BASE64 - rename existing Test CA certificate to caCert1_BASE64 - rename existing payment request data to know they belong to caCert1_BASE64 - update comments to reflect the changes and add a missing comment to one of the payment requests --- src/qt/test/paymentrequestdata.h | 52 +++++++++++++++++++++++------- src/qt/test/paymentservertests.cpp | 28 +++++++++------- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index 37544cdebbb..9caff462f75 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -6,16 +6,16 @@ // Data for paymentservertests.cpp // -// Base64/DER-encoded fake certificate authority certificate. +// Base64/DER-encoded fake certificate authority certificates. // Convert pem to base64/der with: -// cat file.pem | openssl x509 -inform PEM -outform DER | openssl enc -base64 -// +// openssl x509 -in cert.pem -inform PEM -outform DER | openssl enc -base64 + // Serial Number: 10302349811211485352 (0x8ef94c91b112c0a8) // Issuer: CN=PaymentRequest Test CA // Subject: CN=PaymentRequest Test CA // Not Valid After : Dec 8 16:37:24 2022 GMT // -const char* caCert_BASE64 = +const char* caCert1_BASE64 = "\ MIIB0DCCATmgAwIBAgIJAI75TJGxEsCoMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\ BAMTFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTIxMjEwMTYzNzI0WhcNMjIx\ @@ -29,11 +29,36 @@ RtQcf0AJ9olzUMY4syehxbzUJP6aeXhZEYiMvdvcv9D55clq6+WLLlNT3jBgAaVn\ p3waRjPD4bUX3nv+ojz5s4puw7Qq5QUZlhGsMzPvwDGCmZkL\ "; +// Serial Number: f0:da:97:e4:38:d7:64:16 +// Issuer: CN=PaymentRequest Test CA +// Subject: CN=PaymentRequest Test CA +// Not Valid After : Jan 8 18:21:06 2025 GMT +// +const char* caCert2_BASE64 = +"\ +MIIC1TCCAb2gAwIBAgIJAPDal+Q412QWMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\ +BAMMFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTUwMTExMTgyMTA2WhcNMjUw\ +MTA4MTgyMTA2WjAhMR8wHQYDVQQDDBZQYXltZW50UmVxdWVzdCBUZXN0IENBMIIB\ +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1S9wVLfTplJuT/1OaaBgl/Mb\ +I392v8S9kHbzYz7B4OTMslaO7piz0v3SO3TKMh0dswjiRdHrIgpO7XdIUQiU/ugg\ +xDw0kuNehfz1ycaGedlFFtFHTNXqLyIUF3dlwHhQwaomM6RXoJmxLny5BhYHEcmk\ +yWwr3Cdjd9gAZpblugVJB9C1e40uyL8ao4PHdLzOqO27iSe6riP8SwwisJZEbMaz\ +AZpgNEEMbIXPJEFvm5HTRXSMtQCOTSZYMFF0M2yrtmlECnz7hWP19b9bcoDzZQB4\ +ylIsFG/7q2jV7MC/e2STZv+niJiHL08RUdoFpAgzaxMgqj63C7B55HgNDNHJYQID\ +AQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBGejPxLxj9\ ++crv6gUeEBMZPiUx7pUgcI22Wm5yymP96B4fwI3Y0DBehq20d76vbWGPN17Z6pH3\ +ge7PVY1SYqXtS6hXTo4olCm/BZADli+2Bs2xCiaa+Ltve4ufVej+bKJXN/YnrhvO\ +Kq+klQkuuHywU+GJV/NQeBqToIrSOBgi477NgLFCCCmmx2QWsxHoCFGfuRCBVseT\ +z2k/tMuALCDXGeZBRPTsGHu1y4cj84swAeoDK5QSQcI+Ub7GKc+zkoj02sdDLiMo\ +3wokYPcIy47oclhmb4xubHc+y7nF610yZBoC/zgbhbawnZ65hDDWkdQ/SVAnWZD7\ +9PFfmNnYPTQH\ +"; + // // This payment request validates directly against the -// above certificate authority. +// caCert1 certificate authority. // -const char* paymentrequest1_BASE64 = +const char* paymentrequest1_cert1_BASE64 = "\ Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\ BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMjEyMTAx\ @@ -55,7 +80,7 @@ SiWVbw0tX/68iSQEGGfh9n6ee/8Myb3ICdw=\ // // Signed, but expired, merchant cert in the request // -const char* paymentrequest2_BASE64 = +const char* paymentrequest2_cert1_BASE64 = "\ Egt4NTA5K3NoYTI1NhrsAwrpAzCCAeUwggFOoAMCAQICAQMwDQYJKoZIhvcNAQEL\ BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzAyMjMy\ @@ -75,9 +100,9 @@ tejrSPOBNSJ3Mi/q5u2Yl4gJZY2b\ "; // -// 10-long chain, all intermediates valid +// 10-long certificate chain, all intermediates valid // -const char* paymentrequest3_BASE64 = +const char* paymentrequest3_cert1_BASE64 = "\ Egt4NTA5K3NoYTI1Nhq8JAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\ BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\ @@ -184,9 +209,9 @@ chhR/aHOuEMTxmc12K4rNlgYtHCsxLP9zd+6u0cva3TucZ6EzS8PKEib/+r12/52\ "; // -// Long chain, with an invalid (expired) cert in the middle +// Long certificate chain, with an expired certificate in the middle // -const char* paymentrequest4_BASE64 = +const char* paymentrequest4_cert1_BASE64 = "\ Egt4NTA5K3NoYTI1NhqeJAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\ BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\ @@ -291,7 +316,10 @@ HXQjsfdR58qZQS9CS5DAtRUf0R8+43/wijO/hb49VNaNXmY+/cPHMkahP2aV3tZi\ FAyZblLik9A7ZvF+UsjeFQiHB5wzWQvbqk5wQ4yabHIXoYv/E0q+eQ==\ "; -const char* paymentrequest5_BASE64 = +// +// Validly signed, but by a CA not in our root CA list +// +const char* paymentrequest5_cert1_BASE64 = "\ Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\ BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzA0MTkx\ diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index 70254cd75d7..684d2195878 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -65,38 +65,44 @@ void PaymentServerTests::paymentServerTests() OptionsModel optionsModel; PaymentServer* server = new PaymentServer(NULL, false); X509_STORE* caStore = X509_STORE_new(); - X509_STORE_add_cert(caStore, parse_b64der_cert(caCert_BASE64)); + X509_STORE_add_cert(caStore, parse_b64der_cert(caCert1_BASE64)); PaymentServer::LoadRootCAs(caStore); server->setOptionsModel(&optionsModel); server->uiReady(); - // Now feed PaymentRequests to server, and observe signals it produces: - std::vector data = DecodeBase64(paymentrequest1_BASE64); - SendCoinsRecipient r = handleRequest(server, data); + std::vector data; + SendCoinsRecipient r; QString merchant; + + // Now feed PaymentRequests to server, and observe signals it produces + + // This payment request validates directly against the + // caCert1 certificate authority: + data = DecodeBase64(paymentrequest1_cert1_BASE64); + r = handleRequest(server, data); r.paymentRequest.getMerchant(caStore, merchant); QCOMPARE(merchant, QString("testmerchant.org")); - // Version of the above, with an expired certificate: - data = DecodeBase64(paymentrequest2_BASE64); + // Signed, but expired, merchant cert in the request: + data = DecodeBase64(paymentrequest2_cert1_BASE64); r = handleRequest(server, data); r.paymentRequest.getMerchant(caStore, merchant); QCOMPARE(merchant, QString("")); - // Long certificate chain: - data = DecodeBase64(paymentrequest3_BASE64); + // 10-long certificate chain, all intermediates valid: + data = DecodeBase64(paymentrequest3_cert1_BASE64); r = handleRequest(server, data); r.paymentRequest.getMerchant(caStore, merchant); QCOMPARE(merchant, QString("testmerchant8.org")); // Long certificate chain, with an expired certificate in the middle: - data = DecodeBase64(paymentrequest4_BASE64); + data = DecodeBase64(paymentrequest4_cert1_BASE64); r = handleRequest(server, data); r.paymentRequest.getMerchant(caStore, merchant); QCOMPARE(merchant, QString("")); // Validly signed, but by a CA not in our root CA list: - data = DecodeBase64(paymentrequest5_BASE64); + data = DecodeBase64(paymentrequest5_cert1_BASE64); r = handleRequest(server, data); r.paymentRequest.getMerchant(caStore, merchant); QCOMPARE(merchant, QString("")); @@ -104,7 +110,7 @@ void PaymentServerTests::paymentServerTests() // Try again with no root CA's, verifiedMerchant should be empty: caStore = X509_STORE_new(); PaymentServer::LoadRootCAs(caStore); - data = DecodeBase64(paymentrequest1_BASE64); + data = DecodeBase64(paymentrequest1_cert1_BASE64); r = handleRequest(server, data); r.paymentRequest.getMerchant(caStore, merchant); QCOMPARE(merchant, QString("")); From 324f64d148516357a548323d308243205e47695c Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 13 Jan 2015 21:30:01 +0100 Subject: [PATCH 0174/2337] jonasschnelli's GPG key --- contrib/gitian-downloader/jonasschnelli.pgp | Bin 0 -> 4460 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 contrib/gitian-downloader/jonasschnelli.pgp diff --git a/contrib/gitian-downloader/jonasschnelli.pgp b/contrib/gitian-downloader/jonasschnelli.pgp new file mode 100644 index 0000000000000000000000000000000000000000..96140fe171651577d56ce75c3ce50b81026dadac GIT binary patch literal 4460 zcmbu>Wl$83y2o+4VacUqK|pD6K?GSsYUwWNZYc?AP*_qVmhSE@k?scRTpAQvLK=jl z|8vjWJ9B65oBQ(j_L*ls^G!t~#Lx<^5I`kHDYsOJb#|~)en1G9JCOz2mvLhH4S}^c z0g3@glIK|FLu91)$De<38G>lrdf=DzBG=T-G;d5Le5Ve&0yE@hFWzL_F`RqjeDv?rJe;xH_r7zQX**2Rx-AnQO9MkMM9FVbx3 z%lo)9?>((VMO8xoYt(0f&+Zs6z+ec2H&>8{W;A!$BOJVDLA((kiH4v$d7?PtbpD&# z-p1h`$CD#;YAsppAvE4nx+p@K08^&_`tVM|WJ^deo5Vpkt-{z)+BYQOmZlf3Yfg1N zme97<(v{0zgMwjI`JD85mZ1GNt$AdcKIBjc?LDV=TgU=H<_lNaj?cwNKjEw8#oo-I-9vOX_ z>q!K{l$tnS73G2HVU@$= zJGotT#Oy�SmRv0jtnxmcnJY42gl_>o(Gm(mCl-G{snh(6X%@N2hYVtB7+#rPnsB zw(c)|PsUReL&o4dFH+k1R>n_=dEhenC6U@210_LjP$_4()GH4EOvlSvh$71Hqt}mj9#@A|?*3-$wy|N73XPth4DmxA zwxz?9d6RXdH_7AFPfX(y-Y>45NqUgx(FwhnU`d^L2uz z^=}_wT=z*eLIMi~{YC!9$5Qf=0H%N=v8mJNvLo{POWb8`|f-UHo#cs~0_ZI~ms;0%Gt^Xc2KYrZEc z`eY)C1>duxATinA{ENeLY#wjh1zKf64=iFu?1(4ysY0m&>&E-;svS)sv4pB^YU zmoc`aXAx<%rG!7yXI1l#8J+q?#@%C>oJ5<;#vcO&UVzek*rzFTOW9^jCOZ2 zU9@sKg}q?Ao~_dkNww-b^rtV!K{D{)$6wQ^Zxwa>Z8w7LC+DtykPru)F^l6?|lBTO}v({-r1x$+6neok=U4~bzv*g~! zVPxMOMNt|(zh#a*>+T!GnW(%F<7Kt7?~2V&zE{_C=#CbQ2RqJHU77p3bgsx4a)God z!%cTIkS8WM8DMF>xSScxyf$)W5&Ua;>Q`*UOX_b;!jF!?*@9&`ewowPvPTFKTO%0d zx*lV8`AtF7boU&tfcSLgCD6_WhbRs%>&lvv%rT11lbqvofFiu()ojOroi@IaegBMW zh{OtOZ)hQYNQr6UWUi{Ja&n7oX5Q46mbS5S78^q}nO(CzbRw9r;-~tvX+i%6E*)BgGDLWFOh`KEV(oWmp30kW;WBGT=)#m})=n)J zNuo`qx+JrhUSI1`Y&mv;P;BI=U*^tNHwUzoq|r*&@93O)8Hlc8(*zZ-T%Z6JPQejm zQfFW0O6#Jnu7X!NMe%)CKh?zI`<}f_tts9Yvt}3m$h7j?Qydn2P@)6q#Q|+9CeQZ! zXEV+eCh2`7b0MM&W@Dn-$>^iU$lmbc;wwniNpCxI$K2OEM{pWn(~sf`sWb3$l+>|` zshs2W`HK+#%w%%Y)5a8Vyc_z4QMNXwa=NI=K-*^2I@sMg5#;t3ibRY~9w{oyUiR0m# z4v~0XKTMKhAxnI-KM2Nwv&C1B$m1#X6lq7$Gh9nyABYc;VFt_i47rFgD?P0DkM5pM zTI&k^H2JvgC-vuqPfOHkfr-BhKeZ+a#j1v6u7+i-x9WVDk+Nfy3n`Znt$(ka-PFh% zyrs~%V*2FH&VFr#x-iZ;&q3to-4ZU%RWWxi(h*iALzF9>HPlJPTq8Lf*Ix8T%A?G@ zl8)iZx5z|aEe9jzTO1emP0@VSJ!SyYV) zOVXjH=_1<#Nuld}awFPbcuS8-P2V;w!(VNGAfcsoq+G5tN!h+riE3Xk9w?uq`*efm z*^mw9&5`V4VAqK&#fNsc+ZTI;samiemjC~%<_+hGig#Rh1P9iBTWXt#F>Nk8 z2;ZU;>I!sZiM>n&x&63GXFdJ=yNiyh!qqYVnKuk6%h=55T}Dl(*=r zZ0ITF+YY4YAAeSxjLJJSEWxG&&nAI4A*9QE4>|6~Yh$SE!|9aIV2 zLQD-*O=bJ6qm1~JB)7g;h0DX<$et4^c=)D97Rr$krh~QDfDt_1|R7fR5lTl__*Odn0eGPhtW83&{pV06M+M* zPlG#OEe*OJc1o5EKeQR`JzoMYh@Hqs^JHi6W1S`)FzeSZOmk;(QW+KQL|@)^L^lr` z+^J1?Eu&|brs`PprLw6Czwh!=2tpmq;Y8?~y0^DVnWWP(d{BgCUFql@37kDSB^%F> zXSEo*J(P49A&04m)^1B>*uNL!MZp0sUjrg9bePL%_i0@9eubT%m({=b=KiNz{;kjY z50F!_q(U6uVeFACdZgCVv9{BA$O3C#xnl+Es!TaV&kTOT(aHDzDm25==MA$EM`}x! z+MsIOjQGs7+*Km}N4v-9CrwA1QJDjUnm_lTu7?oh9SA7SaTa#WB)NWmD!acEMPSuP zqV`z@3bs65-R`{W*xY*JQBP^qnll;oO{e!6Ihrgzf!iVC1A3vjK$;D4-qNx3tXQk> z7HSVvr>1A#f2;&dnsi~o-_R@S+kgAJvbGf@g&=KS+{8Mfspp|iI=tqglw-bA8p5fa zh&~nm9PE-q>#t((wC4>Bj-T3Q%bT(BFzA+e*c-%E?&C;}?|lDxc7S_;$_llMOjx#8 z63vX>+PUSP?mi4`)Yw5V+LsG!$7kDT#?dlJ@ag!-H@{>?5wUvkv={XXFa5*1w~KkfM=5oqvYcnf_I}Xdh6YR7sgO3wz+Az4eY|nexSzhl9MmU9 zegiMPyM~h7tWvcli`FO-d2w?(&h1;Q`NPvQNCPbU68e`~9-CIy6u|5jaR{f)8?UD{ zD~68ti6T#k5qH>nyp?gTwjeQ+JG_d;mo(0@na1kA;b5$3!|879;XJQ_6IcEl~m?&c2ECTwfqChpKAFF z%HL}Fj~iqk0gr(gfxG2qtX(@FX?irfk(iXvwQA4Un@hf-T0T#pVEG_jWJBiKYHZ*( zmN(HTWiu!n5&Yy?wQ&r3;yA;-ZR3_r^y$ygvCGf;myS}yS4N1>aJ8}l$bOeWv;qYPeAS)Q3{t4g;O2N(6AhadM0S_ zuusPQrmgtoCWa+x1XuJ0cVQ2Nne@OZxpY*gM!LZwYO{fhGfOL)3A^l$1;$bMVAnDI z6nb?b$_9T%b1g8)-*?0t&GIWopl1~(Oo%kNrsVmd&UOnH8^SJEs$t=`*>jS4&F7xc zywoKDlDJ0gTnS^9u!Z^KIsbUv#%mUX|H`1H&TO*5>KZZ-#S3A+kEwYjrmH0*`(ZgU zX-v+j4nP^DT6~Au; Date: Mon, 12 Jan 2015 08:43:08 +0100 Subject: [PATCH 0175/2337] [Qt] add payment request unit test for non matching networks - verify that payment request network matches client network - add static verifyNetwork() function to PaymentServer to be able to use the same validation code in GUI and unit-testing code --- src/qt/paymentserver.cpp | 15 +++++++++++++-- src/qt/paymentserver.h | 3 +++ src/qt/test/paymentrequestdata.h | 24 ++++++++++++++++++++++++ src/qt/test/paymentservertests.cpp | 28 ++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 66331ee4b4c..8703966606a 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -521,8 +521,7 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins const payments::PaymentDetails& details = request.getDetails(); // Payment request network matches client network? - if (details.network() != Params().NetworkIDString()) - { + if (!verifyNetwork(request.getDetails())) { emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), CClientUIInterface::MSG_ERROR); @@ -745,3 +744,15 @@ void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) // currently we don't futher process or store the paymentACK message emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); } + +bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails) +{ + bool fVerified = requestDetails.network() == Params().NetworkIDString(); + if (!fVerified) { + qWarning() << QString("PaymentServer::%1: Payment request network \"%2\" doesn't match client network \"%3\".") + .arg(__func__) + .arg(QString::fromStdString(requestDetails.network())) + .arg(QString::fromStdString(Params().NetworkIDString())); + } + return fVerified; +} diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 2fc24395f62..9330e9a89cf 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -91,6 +91,9 @@ public: // This is now public, because we use it in paymentservertests.cpp static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); + // Verify that the payment request network matches the client network + static bool verifyNetwork(const payments::PaymentDetails& requestDetails); + signals: // Fired when a valid payment request is received void receivedPaymentRequest(SendCoinsRecipient); diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index 9caff462f75..67c9a41e610 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -337,3 +337,27 @@ ssymvca1S/1KeM3n8Ydi2fi1JUzAAr59xPvNJRUeqCLP9upHn5z7br3P12Oz9A20\ 5/4wL4ClPRPVnOHgij0bEg+y0tGESqmF1rfOfXDszlo2U92wCxS07kq79YAZJ1Zo\ XYh860/Q4wvc7lfiTe+dXBzPKAKhMy91yETY\ "; + +// +// Contains a testnet paytoaddress, so payment request network doesn't match client network +// +const char* paymentrequest1_cert2_BASE64 = +"\ +Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\ +BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\ +ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\ +IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\ +mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\ +wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\ +RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\ +KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\ ++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\ +3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\ +tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\ +yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\ +dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iPQoEdGVzdBIhCIDWwowE\ +Ehl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGNeMy6UFKgxKdXN0IFRlc3Rpbmcq\ +gAFwThsozZxkZxzCn4R8WxNiLFV6m0ye9fEtSbolfaW+EjBMpO03lr/dwNnrclhg\ +ew+A05xfZztrAt16XKEY7qKJ/eY2nLd0fVAIu/nIt+7/VYVXT83zLrWc150aRS7W\ +AdJbL3JOJLs6Eyp5zrPbfI8faRttFAdONKDrJgIpuW1E3g==\ +"; diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index 684d2195878..e6cdb58ef5d 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -115,6 +115,34 @@ void PaymentServerTests::paymentServerTests() r.paymentRequest.getMerchant(caStore, merchant); QCOMPARE(merchant, QString("")); + // Load second root certificate + caStore = X509_STORE_new(); + X509_STORE_add_cert(caStore, parse_b64der_cert(caCert2_BASE64)); + PaymentServer::LoadRootCAs(caStore); + + QByteArray byteArray; + + // For the tests below we just need the payment request data from + // paymentrequestdata.h parsed + stored in r.paymentRequest. + // + // These tests require us to bypass the following normal client execution flow + // shown below to be able to explicitly just trigger a certain condition! + // + // handleRequest() + // -> PaymentServer::eventFilter() + // -> PaymentServer::handleURIOrFile() + // -> PaymentServer::readPaymentRequestFromFile() + // -> PaymentServer::processPaymentRequest() + + // Contains a testnet paytoaddress, so payment request network doesn't match client network: + data = DecodeBase64(paymentrequest1_cert2_BASE64); + byteArray = QByteArray((const char*)&data[0], data.size()); + r.paymentRequest.parse(byteArray); + // Ensure the request is initialized, because network "main" is default, even for + // uninizialized payment requests and that will fail our test here. + QVERIFY(r.paymentRequest.IsInitialized()); + QCOMPARE(PaymentServer::verifyNetwork(r.paymentRequest.getDetails()), false); + // Just get some random data big enough to trigger BIP70 DoS protection unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1]; GetRandBytes(randData, sizeof(randData)); From 06b24240cdd37c3df1d476fe93bd0f1bf9dd0dd8 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Wed, 14 Jan 2015 10:10:39 +0800 Subject: [PATCH 0176/2337] Update OS X build instructions to use Qt 5 --- doc/build-osx.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/doc/build-osx.md b/doc/build-osx.md index c41820f2b1b..d6e93cb23d1 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -21,12 +21,6 @@ Xcode 4.3 or later, you'll need to install its command line tools. This can be done in `Xcode > Preferences > Downloads > Components` and generally must be re-done or updated every time Xcode is updated. -There's also an assumption that you already have `git` installed. If -not, it's the path of least resistance to install [Github for Mac](https://mac.github.com/) -(OS X 10.7+) or -[Git for OS X](https://code.google.com/p/git-osx-installer/). It is also -available via Homebrew. - You will also need to install [Homebrew](http://brew.sh) in order to install library dependencies. @@ -38,7 +32,9 @@ Instructions: Homebrew #### Install dependencies using Homebrew - brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt + brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt5 + +NOTE: Building with Qt4 is still supported, however, could result in a broken UI. As such, building with Qt5 is recommended. #### Installing berkeley-db4 using Homebrew @@ -46,7 +42,7 @@ The homebrew package for berkeley-db4 has been broken for some time. It will in Running this command takes you into brew's interactive mode, which allows you to configure, make, and install by hand: ``` -$ brew install https://raw.github.com/mxcl/homebrew/master/Library/Formula/berkeley-db4.rb -–without-java +$ brew install https://raw.github.com/homebrew/homebrew/master/Library/Formula/berkeley-db4.rb -–without-java ``` The rest of these commands are run inside brew interactive mode: @@ -73,7 +69,7 @@ After exiting, you'll get a warning that the install is keg-only, which means it 2. Build bitcoind: ./autogen.sh - ./configure + ./configure --with-gui=qt5 make 3. It is also a good idea to build and run the unit tests: @@ -115,7 +111,7 @@ All dependencies should be compiled with these flags: -arch x86_64 -isysroot $(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk -Once dependencies are compiled, see release-process.md for how the Bitcoin-Qt.app +Once dependencies are compiled, see [doc/release-process.md](release-process.md) for how the Bitcoin-Qt.app bundle is packaged and signed to create the .dmg disk image that is distributed. Running From 42f6a0c2b946af2cce86b721b349d35c4e21ce88 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 17 Dec 2014 09:00:16 +0100 Subject: [PATCH 0177/2337] [Qt] optimize PNG files - provide a python script - add optimized png files --- contrib/devtools/optimize-pngs.py | 49 ++++++++++++++++++++ src/qt/res/icons/about.png | Bin 5925 -> 4726 bytes src/qt/res/icons/about_qt.png | Bin 3107 -> 2338 bytes src/qt/res/icons/add.png | Bin 15199 -> 712 bytes src/qt/res/icons/address-book.png | Bin 16150 -> 1275 bytes src/qt/res/icons/bitcoin.png | Bin 350390 -> 312944 bytes src/qt/res/icons/clock1.png | Bin 2448 -> 1921 bytes src/qt/res/icons/clock2.png | Bin 2269 -> 1731 bytes src/qt/res/icons/clock3.png | Bin 2184 -> 1557 bytes src/qt/res/icons/clock4.png | Bin 1995 -> 1395 bytes src/qt/res/icons/clock5.png | Bin 2682 -> 1889 bytes src/qt/res/icons/configure.png | Bin 3891 -> 2865 bytes src/qt/res/icons/connect0.png | Bin 16890 -> 2290 bytes src/qt/res/icons/connect1.png | Bin 16870 -> 2242 bytes src/qt/res/icons/connect2.png | Bin 16566 -> 1966 bytes src/qt/res/icons/connect3.png | Bin 16566 -> 1966 bytes src/qt/res/icons/connect4.png | Bin 16117 -> 1490 bytes src/qt/res/icons/debugwindow.png | Bin 15930 -> 1327 bytes src/qt/res/icons/edit.png | Bin 2544 -> 1847 bytes src/qt/res/icons/editcopy.png | Bin 1295 -> 883 bytes src/qt/res/icons/editpaste.png | Bin 15778 -> 1024 bytes src/qt/res/icons/export.png | Bin 17005 -> 1750 bytes src/qt/res/icons/eye.png | Bin 2806 -> 2241 bytes src/qt/res/icons/eye_minus.png | Bin 3087 -> 2438 bytes src/qt/res/icons/eye_plus.png | Bin 3368 -> 2599 bytes src/qt/res/icons/filesave.png | Bin 2874 -> 2067 bytes src/qt/res/icons/history.png | Bin 16271 -> 762 bytes src/qt/res/icons/info.png | Bin 2895 -> 2028 bytes src/qt/res/icons/key.png | Bin 2434 -> 1759 bytes src/qt/res/icons/lock_closed.png | Bin 1686 -> 1197 bytes src/qt/res/icons/lock_open.png | Bin 1751 -> 1257 bytes src/qt/res/icons/open.png | Bin 2239 -> 1694 bytes src/qt/res/icons/overview.png | Bin 2215 -> 1662 bytes src/qt/res/icons/quit.png | Bin 15766 -> 1091 bytes src/qt/res/icons/receive.png | Bin 2874 -> 2067 bytes src/qt/res/icons/remove.png | Bin 16663 -> 1723 bytes src/qt/res/icons/send.png | Bin 17005 -> 1750 bytes src/qt/res/icons/synced.png | Bin 16891 -> 1619 bytes src/qt/res/icons/transaction0.png | Bin 1759 -> 1220 bytes src/qt/res/icons/transaction2.png | Bin 16891 -> 1619 bytes src/qt/res/icons/transaction_conflicted.png | Bin 15766 -> 1091 bytes src/qt/res/icons/tx_inout.png | Bin 2568 -> 1655 bytes src/qt/res/icons/tx_input.png | Bin 2590 -> 1783 bytes src/qt/res/icons/tx_mined.png | Bin 2166 -> 1578 bytes src/qt/res/icons/tx_output.png | Bin 2699 -> 1771 bytes src/qt/res/icons/verify.png | Bin 2984 -> 2034 bytes src/qt/res/movies/spinner-000.png | Bin 16636 -> 1835 bytes src/qt/res/movies/spinner-001.png | Bin 2785 -> 2376 bytes src/qt/res/movies/spinner-002.png | Bin 2814 -> 2376 bytes src/qt/res/movies/spinner-003.png | Bin 2775 -> 2355 bytes src/qt/res/movies/spinner-004.png | Bin 2850 -> 2349 bytes src/qt/res/movies/spinner-005.png | Bin 2728 -> 2305 bytes src/qt/res/movies/spinner-006.png | Bin 2734 -> 2304 bytes src/qt/res/movies/spinner-007.png | Bin 2633 -> 2283 bytes src/qt/res/movies/spinner-008.png | Bin 2611 -> 2312 bytes src/qt/res/movies/spinner-009.png | Bin 2074 -> 1810 bytes src/qt/res/movies/spinner-010.png | Bin 2666 -> 2305 bytes src/qt/res/movies/spinner-011.png | Bin 2751 -> 2338 bytes src/qt/res/movies/spinner-012.png | Bin 2828 -> 2352 bytes src/qt/res/movies/spinner-013.png | Bin 2896 -> 2377 bytes src/qt/res/movies/spinner-014.png | Bin 2867 -> 2358 bytes src/qt/res/movies/spinner-015.png | Bin 2860 -> 2405 bytes src/qt/res/movies/spinner-016.png | Bin 2825 -> 2429 bytes src/qt/res/movies/spinner-017.png | Bin 2833 -> 2408 bytes src/qt/res/movies/spinner-018.png | Bin 2147 -> 1831 bytes src/qt/res/movies/spinner-019.png | Bin 2808 -> 2380 bytes src/qt/res/movies/spinner-020.png | Bin 2800 -> 2366 bytes src/qt/res/movies/spinner-021.png | Bin 2833 -> 2368 bytes src/qt/res/movies/spinner-022.png | Bin 2823 -> 2356 bytes src/qt/res/movies/spinner-023.png | Bin 2710 -> 2311 bytes src/qt/res/movies/spinner-024.png | Bin 2732 -> 2315 bytes src/qt/res/movies/spinner-025.png | Bin 2635 -> 2298 bytes src/qt/res/movies/spinner-026.png | Bin 2643 -> 2291 bytes src/qt/res/movies/spinner-027.png | Bin 2099 -> 1816 bytes src/qt/res/movies/spinner-028.png | Bin 2665 -> 2308 bytes src/qt/res/movies/spinner-029.png | Bin 2761 -> 2356 bytes src/qt/res/movies/spinner-030.png | Bin 2832 -> 2346 bytes src/qt/res/movies/spinner-031.png | Bin 2871 -> 2380 bytes src/qt/res/movies/spinner-032.png | Bin 2839 -> 2345 bytes src/qt/res/movies/spinner-033.png | Bin 2829 -> 2401 bytes src/qt/res/movies/spinner-034.png | Bin 2851 -> 2422 bytes src/qt/res/movies/spinner-035.png | Bin 2837 -> 2406 bytes 82 files changed, 49 insertions(+) create mode 100755 contrib/devtools/optimize-pngs.py diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py new file mode 100755 index 00000000000..774968fc088 --- /dev/null +++ b/contrib/devtools/optimize-pngs.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +import os +import sys +import subprocess + +#optimize png, remove various color profiles, remove ancillary chunks (alla) and text chunks (text) +#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text + +folders = ["src/qt/res/movies", "src/qt/res/icons", "src/qt/res/images"] +basePath = subprocess.check_output("git rev-parse --show-toplevel", shell=True).rstrip('\n') +totalSaveBytes = 0 + +outputArray = [] +for folder in folders: + absFolder=os.path.join(basePath, folder) + for file in os.listdir(absFolder): + extension = os.path.splitext(file)[1] + if extension.lower() == '.png': + print("optimizing "+file+"..."), + file_path = os.path.join(absFolder, file) + fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : subprocess.check_output("openssl dgst -sha256 "+file_path, shell=True).rstrip('\n')}; + + pngCrushOutput = "" + try: + pngCrushOutput = subprocess.check_output("pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text "+file_path+" >/dev/null 2>&1", shell=True).rstrip('\n') + except: + print "pngcrush is not installed, aborting..." + sys.exit(0) + + #verify + if "Not a PNG file" in subprocess.check_output("pngcrush -n -v "+file_path+" >/dev/null 2>&1", shell=True): + print "PNG file "+file+" is corrupted after crushing, check out pngcursh version" + sys.exit(1) + + + fileMetaMap['sha256New'] = subprocess.check_output("openssl dgst -sha256 "+file_path, shell=True).rstrip('\n') + fileMetaMap['psize'] = os.path.getsize(file_path) + outputArray.append(fileMetaMap) + print("done\n"), + +print "summary:\n+++++++++++++++++" +for fileDict in outputArray: + oldHash = fileDict['sha256Old'].split("= ")[1] + newHash = fileDict['sha256New'].split("= ")[1] + totalSaveBytes += fileDict['osize'] - fileDict['psize'] + print fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n" + +print "completed. Total reduction: "+str(totalSaveBytes)+" bytes" \ No newline at end of file diff --git a/src/qt/res/icons/about.png b/src/qt/res/icons/about.png index eeef943355782e807af46ef65a7f10c9cd4a899c..83eb3c07ee560450b04816fe3713a4203e3b6213 100644 GIT binary patch literal 4726 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 diff --git a/src/qt/res/icons/about_qt.png b/src/qt/res/icons/about_qt.png index d3665e98925eb9b8e63aa0cae7da5bd93bbd1a0f..dd27a99d0a7e48c332e0c2750ef98a0d5e100c17 100644 GIT binary patch delta 2328 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 diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png index ef995cc0b54629c9b8f14c576789a9a00b2c5747..7e46672f2dfb20f3e168b5394550b39ccb1e8dff 100644 GIT binary patch delta 689 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 K+`>gMDgOoB>bU&? diff --git a/src/qt/res/icons/bitcoin.png b/src/qt/res/icons/bitcoin.png index 705a20260af0ebd2f2fbe3f3dfaf99f32db4be3b..435621af23b440792cd26ccfc419379613d10586 100644 GIT binary patch literal 312944 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μ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
FBy(2;%8CtnMRE>`te)hV=Fz%_ZW8UymI#A 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

2)j+z8iSV`RQImd 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 F{XdB=2n7HD diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png index 65adba5e21d6103a4e47579fe7fc9155f257abcc..ceae5ed0d9fad2e94cfb167a5771c38d0af5e865 100644 GIT binary patch delta 1889 zcmV-n2cGzl6M+wqB$0y@e+M&3L_t(|+TERLY!y`$$NzmT4`{^}D98>%X%&&u1}$6J zWLF>pqD6!jTb5#5QEXGg;(~?*F%2IO(GWz41gR302>HMC79kl~{@;e<(*W@-P}%XpNYW zCg_J^RO27iNwgzajj8AnR@6aw0;i=wsdfPKkro!%C??=_�HTRp=9J+#9e}8*Ib& z0NMrd+RiWnd#UY0c5rZ$u+T8>h4u}G_>bEZ#g=d{Vc+N{@OaC(7ursA@dLLj_WJ~U zVMuFY6E}kS9vwY|e=S&v3M{}J%tINLVGVZUXHUBRw)X(*fP=1F`w$h#MXICTbWFio zoO5}tk#10AbZ)31V zn=NsV6!dfxz-@5c(Qq}=jr_KzNI);v|44E&xfdA*Z>f0Xe>r-v1`&M*(;UqWwKB1N z*ujgQ+Ma8Ubx@oKU?e^}FDg#o8h;Gu`*WsX3d*U99Yq_#;4w;ms$IPUg2k}Lr3}1Wu4S`YRp(4kvYK1SDM(=zj8<~Y9C8GE z7|l<~DR`PW{XRv<%pn6USltrQ?>@|_yOl#OCXs<_f7p@R@gev*b81Uvr_3S)Ga2o- ziBG#p?`*~@GT1x1sc0DZgIS#*6v*w|uLedkr=)}g87OdjosSv~rP)A^$M2+tJi2=p z*|}C*M9Bs+Fp#l9QoKxd9j?t8JIKI$q>TZMJGLe}9@Dr1VhcHo*{y6ObI6V(HM(L8 z8Tgd6f70smZhsng#vbx8(#lMk(0q|rN9-ZTlUBa{f2UGIlT3e*fqO|iZ5nntCU?V! z2D!b{Y`dlLq02ThaD-e9IxHrVLXA9|v~)4Qq>4DWPrDO#k?D=4i+Q1c5eM%IIdU9n z>CXCtN#wz9Ax8$*k=wBVfDF=&gwP{TAS|7$e?N39nP-F0BX=fkH3NX<#DRxm069w9 z>dZxq#>W6M$Z)|x060Y)$cPE#7wIuOVqtde7xIIItz|%S(urtHAm2{ddXAf4$5};| zYb$Y;ON&Fv{4{dSan{Ipu8Qn_3xV2fssXwYAO9FwWOoS>REpk7`s2d^M&9VcA{Fa7 ze*>fwAAcNRzjUZ=QM`rHj_VhPlKvJzEGb6UW=Q0;kch}x< zVQ&ciTyAD<_679SfSl#R-ZbL;4L0Z40C0yQ@LX5cD#`3|W+jylQ<8}fJmP+a9GAAX za?vkpy*v)FASbv@*X7*h54kkqGf=76f7kmlfGmi8*@|%5mYew*N21o8>);5LmH)hG zw_--ff#by4O;z+PCDhW9M7~(2h2D8g3^npB@d!oFvqyv)`AdRmN5c+O7Qw3_2Bxz) zr!?$RYA|=x4=EveQk~)lb+|jE!1Pk7=JIZ}@|ll;mt2yi(PMXx;S5fj@{!zvf0z!_ zd>=w!I>ts0#@jW%&grMTMRJg9Z92pCM9A)E`d!U4Tr}?|vir19jn%)nV;IGRV6F@e zGWX(8l>d%uRbHd>UD`6h1)`I?1 z#_yvtJ1@^LCzk{mIEk$j)>r0qfByaDpst`JY>lebvMMIA(7ghQyn^-j3V9{fI*V5r zmNM4YTsLY`1bagr0tH;i`nkfbs{RJbZ0MIF*2f>b6s;7Mkn0%;;6?f`%VvSffj;BL zW3|A$T(4@IqDG*0rjNiW!dkESDyqfxzSh<6<5`z1p;yaP)pr)EKaJ}wf8)jp9!m8^ z3pI#S?Y;_&1%1=VU5JLM#}QqI#L#E03}(%-*ujtWI)hfubvSn!{quzgraF31r8`@# zjYLW3P3Ugq?wyE#9c`DJ_@)!_nnbG79@nW#B1vYp6kHa?QTe_XOXg^mp`)_3{?a9* z4gc4{DCyL+->}fr%SVYAe}N6sR`%KW|C;u~8km$*Wyq08k?f8MsA9@MaIMrv74-Ta z_*_pZiRZ8%>+uN6P>5N`$2^o{6<)&Ep0xdHJ7Cd;DKTlQmH3mHHr6NHYCppi2_Apq z-rFaxGO~>YR7))39zy@%M4+O`ll*5euWg%B4Nzl}EsUe63{|NJSFl7e4!gC%KI*YX zvoDf^$C=`XGHovk!ka7H7e&~NlTx4uu>!XQaC1N@sMHT*k%xI$h;l4KDQ06bhM~93 be3btHac-OWgfE~Y00000NkvXXu0mjfd2Xb0 delta 2418 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 diff --git a/src/qt/res/icons/clock2.png b/src/qt/res/icons/clock2.png index 196a79ce4a456b18775a2b12437ee6cc7058c467..159f69a8fce8a3a77c6dbc7a40cb2022c538392c 100644 GIT binary patch delta 1698 zcmV;T23`5x5yK6TB$0y@e+G3)L_t(|+TERNY*a-Q$N#&fTiB{C&=LxiBJ>dz3ngfa zQbYsrgUk~%$j3+R+QEI=75e^7@e?8YuMpc>^^ zjv`D%U?dsyQH@UggP1`22JKjjS$;*m70+T&2$V{_*p6Jkz(%kd@7YEjnOafkZQPr1 zNE&QndJL1j*tQ#$zz(OQnCBhbRMacR9ZKI}k^8tQsMdr#jD544z^gRl4y7(kcLO&E zCtLy^>e7;R;)b!^f2N_Qa1hU+5j$|iG4$X12CykOY00#Y(TGxHjL>38YU_}C;5&uQ zIgcjHX6i8{{lI%MNhNLwy95nsM2?9rL*jd_tPhV0y?-BKp^!F1YG<}y1#l+%O)Kt1 zzOX(+au41te@HT`@;C}CX*8q{TYC|f2b^nK-EEe28Vbhhe-0$c0iI=2(QZU+Xf>2f zP+phO($h>TnPXG0p=eh2veS`z0$2U3h}za{D4U8tlL+PSpu|1=9a8zFBxQ{Rtue59|FN-~hhC+;2YX{(@0-yyWGmF60>Q=Noc|+}VsLkYh;UIcxu5tWMx-WX@_} zDWgcb&yhLp+^5f#rWv`MHlm2kJRsAfS1*1)vNM<~vYy(6$ za@S}Rwvri_D%<(cjU2;-ktX~}W=jeX@+J}2d=(HNwl_VUOZy1b2`x$A$hyJbWOK$Q$C7r;-n61QNL; zUU>oee{f77kuSw7zn6@&K_HQ17z+S7ayHxd<&K9_ zz1+o~aYU8HT)QjJ6I8G9b}Kge95}>}Zfc`vDZZAeB=Y5JTIij}sIQSX^Lr?Ip1s7^ zf5=}EL`M=cP*DW$_!xLH*@*WgW~tQ{yQxQNNS+Kc|3M57`4l+J@@-xz1LBd7o|jUR zWz?{{Rci#NTKPn5L7YKm`@x66b4U`hGk#0SaZdg60m)HJWu@b>&-(0rE@n9F8Q#2~ z$?WTV)mQ&&jbRyMQ{x)nAa7z2MA+Zae}I!?bgs)J2JjYMA=Vk1g}y-Uvf9RR`I1pA z&GW$P8J4dxE66(Y__oJ^^B8vbiR`?*#3)?jVc=9;Vpu&_q&WNhvR7BoVdfoG?V>8~ zVM1T;N#qu$y;q4V>6CeSg<`2=+FEKwO*$vqVv47LE17n-SXEV`{F)6JQpL3Ke@8o) zRzAXk&hrHDPWjE!VHWY~q9mc6V_m6TwJA6)exOdPq;v0jt#G26f8W=O@qIk)Qe+m3 z>rAq_>IZRyX50{GP>Nq#C_&8b?rYR|p>Hm^3y~Ol9F|oPANrz}&TJf-P3+hw(`jXX z59d*(f4&gLT2l+!WJjxI;uq6Oe-B`$lDD@E|C-j_pyHd3;$4B@-($4<)TX2{wiGO0 zisR(_ZiZOYa~-BSuB`+I<=yt=M3xB$d;gAlTZfOLSc3h+we;xt|C%iHT8eY;K^=+( zLL_HmHQE^0K(JD+t^nH*9=3VN@&xwbNz|bdn^A#nXh198z_+%v{ifSte=!~JyL38Y z$P?#EWZDXsa68>}Q;f0s6Sto}Ly;F8sx_K$Pocy+9;gV)1^*e$ZaOUS4p50QkLyQq z(p6=6c-sIGtVFjoSVO`c&Dx|GPctq*6gz*q#lNw_b5Vs3oD%{)i5A@L!Oa0jPNn%+ sfpTm^JsPkRwRjL~uo$y-7{;Ug4>iC)q^g=*z5oCK07*qoM6N<$f-ST)?*IS* delta 2237 zcmV;u2txP64c!rtBwPe%K}|sb0I`n?{9y$E001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}m;0007FOGiWi0IH26G5`Po32#P5a{vGU2><{9CICMB zWFnCv7k>v|NklaX!gO(yto|GaHwHyW>qG+KKq+AJJ0TCqS zhzAge*q9)iV3c@;5Q2(AG(to|6Az%o7-;~}5RgzKAQ9wLlvWT6(sHbSygc6Zn>}V{ z_V>zn{%Lk*fAjt9?Db}6rUCe=-Y7sJ@{xlqq<_OiGn#M?jW~-FX!OfOKy&Qa9*p7WT;upSJ)O+z3nqf+&J$M?W+z?KcfpPd&8Z|M!jWTW^YYoB%Ww5bn zA-Zs*B`X6{w7^DFEe3K!MwN~EnsFoP2=3>G1v2rBPqn@ajg#?^yt;zPS9wcRnv$4QIaPmqoM-jAwMRpC`HyJzAT zi{m-NlQmtfY{JA$d0T5O!g~GXsuS5nxtytIEkfSz5m+~}DgJpWzLrB+Ay z>(*}3b3}xkgCB&!igBEq$AOCQx;y06!cZkR#ZBW-3+OAFMjnrc1!2nY8#jpyZ9@lV z$hr7J5MmU5;-+w^H=GrFUvLjxpwx`+J9Z>F=>0Ae?7CHPmy2J>XA;lksk({ zn0AhDQ;%F<=Z`IRU>C-q_qmiG8{3cm&8@E%18XJ!sL`R~~EL`LEsee$f#3N52 z3vJ|fsZ>2t7>is@6sc{+FPXH;qsV#aN)&j9+o5t*MUm;>l;3kZRIX7-k06gDvUlPl zw?hpIMv$wB%vId(v?vrt&PID8a|gFOEvgJ7cPBGjOV_PCJsw8xOJwcERc?1$)CO%0 z0Cy8vo4CDcQ=tK12$8Xy+kcrh6&nDC5*e*>c7r4JG+>||k?|L|Gi@q01T$N1#@CRr zN({6mGp=wu)21MeeD$X33rSX2`ouoN?MtHy45Sg8FL3+PsP<`OFSS2ca*OsF0>os5 zG=4dSzc;n*EH)pR34c< zg4?wx9U_P}#}+tE6!?nUwFh+}8!>Lw(_FGhF1K@O%^`W>76%BDMXF?LWR^kF98N5D z!FuFltI{x%CF!v{i!3&r+r5)qkx4mabm*8ot;vd^7Iw88=|@ zP%>dkE_|CHyS4kOeH=_vN`8firjJ$i;n=Ovc*U2SSvxGU@v%l_r&Z9VG8460$Cns* z#MZ$w)uYu4@rP}tYf+*BH-PcDW?T0QI*xP}HrZBe;v2gAR8l#DPYQ|YQ60eH<85~} zMbbP41Ai}uV7yL1b@YWmX_bY;1LNbaG*IZ*m|pI4&_RFf1TbR!1O3 zcyMoWbRbY{b!RO}ZXhloQ&vYHR%LQ?X>V>iAT};AFd#y8X>4R5FexA)(s(Lr00000 LNkvXXu0mjfDxCha diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png index 3d04655ed9500980d3a5ac74cbcbed52353a5650..d668e35ffc05949bee8efaaa43ede1f411efd382 100644 GIT binary patch delta 1522 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 diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png index 84a9fa2842bb25db5a99fe8d4f73f5a342f30a41..96f15ef7d9507feb506e640daec0c5c1d6345288 100644 GIT binary patch delta 1857 zcmV-H2fq0F6yXk#B$0y@e+LsuL_t(|+U=eDQgirI3{x{Ny@=0t$VjU5FaEC?*Y|GPoE4uUT=RIY6?c))>s}|2K2Y`<56#sBEc8T9pv?EYIUYk*W@e3 zgF1;G*U8t0f8$}*GgdDq^+(lUcDGh4{3)G8r)~D3<9olbdLfSO%BAejRLb5-C(#|o z_&{(Rk5&oERD?1ByyAfNo*Nc+Z3q4Qt^SF$<=HdohhuPYVFy3*$d7X-J; z(tV(Te=T`aybF@Y)re%>iI~ygWHD6r5Xrie-OxMj*a;>KQY0TLXh8C${vz2FqAsaN za>Y`SYziZfo@)(tm?;Ak$x6ZIb?2Il$Q8+^5mf0Ux$u-oHVsFbljPt25Xq)7y6z=A zY`IB;6UqO6{<^b{iUA_HO*#$K`-y zf0RfzS#r(SKMwx3ubHp&l)A0Tzk(+Wu|f}zj6O39b$pqrqT>%L^@)$~ zwm;veR7#FjI>@SBe_cG=RLMf$p|vYRf4WH-rV_olc8ym{DZ|(`UR`TfYlcf1Ch})0 za8d2L>qn&!6IuDa^A{AWq!iQ0a^6~^aJQ6V8gb6sFnO&s^Q_da0D9<%C2E*m7On)qDgTSuCaL#;vp5JcD9z zYbi}PLUP?bO=dMzl}mBDa94O^&xNXx^0fICPigGwU(?~BT?({187D6Atj72`Qlgb9 z?+vzDTzFm>C}moe9$$It{NyL4e@rW~bccseLQnrzO0^ozj(Xw9`?W`;SgX)K9q%Ok zsFZ63=5N5eN%>St_9ur!A=r-hbDxOz8<%{KkJ1NR*Fz(Cbb6+VNPt>Frlr8RSJHHhOQ-;n+|PZM{?i_&VLUsT0>yux&V{A zb||!uCGZjy1mlmJEqC8ke@G}n67~k<7aArv1N!8N+p`jU95S23$r1X>UGpwg2GQ6Qx~JW&Y0w(`BytxrMD zZ_q)B3ZEvSH{>3J*E_<`_jpd|p6)PzKMb1;F=f)TB@FyI5|Rtfg;CN}Xmf~?T37^+O*00000NkvXXu0mjfJ~oKg delta 2653 zcmZ`*c{J1w7yj89Yh^FYBx{zjFD=X=0M6aZHI0l@T60Fa8VBsrfyDsW!4wYCI+CwCQf zk1~O%OP6AQ<54IB7x#ls--Afu_FX{LGv#J0r75<3<^yY9b+l#eSFcZlbKpu9}$=5>iyPOCHS*Mqb2m{}m246kS<> z+i{E`(tb$PRHYW)cZ!oCyiKzm?M*;Nhd{jZ@$rNv%S45x_gwNl{7>_0&j{&{NLQT_ z&{oKT1>p64NDXecejo-k(o2c(LBBhKuFtl}yeIwzFF%P>(zvv9eQ94HLQ@#qRIT4B z=HgdOaN?)WsWzX7DAeP8?M=Avl8_#n+_%EGsD6CtY-||$8eKPRyE#rN17BW1sSjas z$UMFrzoctLYJ-_u>YSI?Qn*#N$LxQvV@0CDH{Rhz!8N5ngAiR1pH1MNv2^^qd)lPp zM?n^edduQ=6hl#E3=?9X?5{>X-CsF6HbO>el46>T%M`gx`{hs|zVN8k>#m_`9Og zu+)vm3>T&a@!7rYwU-ZbmXHpMJx&es#|98uV+=Z+DztC zgt9d_PY+iMp{kbtA&bLuQ*1k8!JKwVnRU~EeizA&)ZnIa# zO4QKQYjy{cpqcdMJ(>ehUjGU5rM^S>X5wc(X+%!7>gw6c93MaVkiP0) zp^c^v-SJde12^B6>+rLka{6;{WF)?8x1&S2?s?&Qm$JGsZG*K~g}zNz4mC$#Gq4yt#k}_EO`D2Eyd*r~ zK|zWCHz!*hf{*`oYaMLxpSq!S6{hcRPb7CQ48dm-e1Cfdk}Aos)pmKGiK%udb>7im7Vh*l{mMeH`@-LIdf-1^33{cpt%JnOM7DYlUi1G zLIlW9c(N9UN>9Nrw#yS9+r|&*v1@Z}^E3WV0Tmh9TyfnQ?(uT>j?rEHa&3H9vwq?S zr}qcF(6Mqi);6pJd$~U&A4QS|C6P#HB?_lkxF7U<>H7G_Zi#0+V3ntd@y8^QauSza zovpaNInnz3AWdF)_VbFsH~hmrPt_F0^_B{?4B{_2LJHT1pR|t>$vgIPs_dDGbCDrM zA8rb8#X0=jh!33z^I#_O|D=}AB^rps-t`_=ty=6CaS0tbyizmowY%)UU&moR^e~cj z*ExoeLuM6MzZ;!ao9Od)7w=;Yi5TOSu3z%5sPi3=P0yn(PAg1o zWfVG$3*0tX$P46I2u>gQnm|i`{fL^C#L5D>UC^666yk)Bxqouf@N0FV&wir~Cf(K) zJm_#GN7p_iDj-z8@m;ux*T(rn!}}d;XE4jfLN(XbSJ^pOScbi0A4g+7T}NyRA^jOa zZhck5{8BsazHDh%k5b&Jufx_h6t@dMaVt6Yygj34Hf?OhSFBXk2g5<3_)lYYfwyC| zYWR=^+jie;FStySSZUI->%fw}^U?W4>|mt5PTK4Z=gdEKPvKX?g*Kd(Io&am6HJ}A zpg;ZWo5nXb|A>5y%#)1H7;zlrTW(s6G9R|3Nwmpsf)z!42Qrx7`7VwXe4{pnzjrOt zvXoHNlF4C zh>Z_54U9sggCpYruyt@`a7;j4RE#MY78G?g7>taFz{JM=mjde;Yw2h~HNcnMt-)4_ z(NQsRV5bO7s3tNJto2{gJvb&76%}a;Hq?Sb!Eg*JA_xps1A}Ra>er6?0Z1zcO9I?K F{XcS0Cv diff --git a/src/qt/res/icons/configure.png b/src/qt/res/icons/configure.png index fe9c6ec5ecf27879b8513434a95e9a3b3a7a39e2..5333c83d5eb2f63f0df2e4f6980e4a8395f8b23d 100644 GIT binary patch literal 2865 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 literal 3891 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 diff --git a/src/qt/res/icons/connect1.png b/src/qt/res/icons/connect1.png index dffc692c76dd4d7b8b8e48a1d3309aae026cfb21..949e7a922d5fffe69214a2b9ac083ab55224d5e5 100644 GIT binary patch delta 2232 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 diff --git a/src/qt/res/icons/connect3.png b/src/qt/res/icons/connect3.png index 3594fb117c33fe9ce151c545f27538f9db53ea1a..143b2054fb648d6e227ab84672a01d38faa376d7 100644 GIT binary patch delta 1954 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 diff --git a/src/qt/res/icons/connect4.png b/src/qt/res/icons/connect4.png index 0c667c7e06d861ba666ac22954376740be38ca60..f96e3455ceead529fee2371c3e5509e2d51cb8e4 100644 GIT binary patch delta 1473 zcmV;y1wQ)qebNh%BYy>%NklWcC~HObPqL&mUnbLL*=(taE~A;RU{Dq?c!Z|>9_U+ z2Z2>Uoqh$yxqlA)B494?vhKpcENc(&B2Wz!<`VE*ftA3n2tZD!-vF-x6>$ZAsqW?- zz+VvtoveQXoj{e}V}4M;i-85e&KN;Xr#tkF8533Di-7NQ0Cci`2P}*d@H>I8a}ad0 zZU-u}3H)kJvj#>0>>)h^yd&R31^yUtas+`+){|loIDhc*K-&lgovdxZxS)W~2KE}{ z|LGoJmfygi1O73%Y4vXf(L4jsSFFRJW~Off7q|sp1bk``9qUJ0X*&Ww4*1I8xz;a$ zD>4OsC9pdJMjr+CX~EGBysscwvsQi!^?9YfYuCB^bZxfn{}z}y9Pm6~W0nj&te;~e za0gHVOn(4IIhgK_(lsS&qfu=h&XP}`4~^;RfG-N!pkIMj;I^~xh5%%u`e;?3Vfwfr z9q`f+SC1Qjhq9FR8m+!Jgg7)#PX+w(5ITPsm=mFd^&Ht0wBL`U0v_aiyB#Pax>6<^ zgYy54RKT|f(9r>4o)%D1mwefJAOH?qQUU+O=YLM#@+(^svW$`KezN#574T<#3|-a* z0HPR}rbKUzv_i*%D0!&!aT2jO74TUKuzP8Eo94h?qyV@Im=AmmbOApAhk)ZG3V(+B zJFR1fbWWG9nXfjyR$i6JC$BXz6{&z10xcdIUgu#5xkL}HCxA`Lp8Ju3-=sFn)Q8(4 zW`CUrJ6;9y(=B{12Yz(oOr&xM_Z^3iFZy+eVlbH!3_akv_5 zc6sMKn5A-xE)q42Zlu{kKfeGoGL05qqx8|hFy#X?T^M~A&=G;)(iX*AoXSl3p03>i z-~(W?n*_wY!0W(z618}n6_2QQu`DkF)_+7Wl=@z(_;m*1fqJpnEH>-KYOY^7O)qom z>xp)4;ZBdUt6|xMSv-^0=!o~MSpro z2_jC?r;OAJ;CT{7K#%J43Sce4)Sh(2VGM8a(cv{fEig5Mey`QJe#UEB;sCtL2S+~x z%01Xnt~R{dQ56T^=jkWz#=$?7B=Ae-sZBSwtd%dZSZPim@v;FY4(=tG+LdzPM~AkY zkPoqnrOY7neVeUhxL3xdj91({6MtKFpPi|RTePr<#CuJSk$RiPK@aIJw?oWN>O0w< zW57!!^187N&ko5{;67kE@V3IXvt49b{E*9l+kwThWw~sd5@e@Qek0IuGKIt|H>!h% zG?IZ|s6|dU|J~hiRL7nrLa$qjJMdBxuT&cDVYd;OZos|C4Z!aXrgOiMsDCvy;4X&| zHzm~D2;r4Vxd{Ae4@>eU1MXaUJOJ-8;Lc<+aKr=fBP5lY8SryUHQpnA)dt*v+mK?w z?V*`9Y4QO4NdxX&3URlgslygN?q!;m>rR&T*V)qEdpzY!3tojQ`M^^oc2OKAQFA_^ z&$|=`i1haII3^(SG{n>bFFHtTbu99G`Rz|P>|ag{xTyg*;HC!LfSVd{18%@g4Y&a} bb*}#c*UuHuKYK-q00000NkvXXu0mjfJ!ZI7 literal 16117 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 XeR+0EW_(JVp6EleBC@-%d-1@ z^L{h$Y38~3Ux>`iJJ0X;&Aj{0`_51*mCzJ7S_Bn9i=YB%RDS@C3ZPK|G%A2b1<z2yw>GEk=igbltwFb_DE5%}(D1Dai35frK!{6^qs zOW?cbH(-Ja5PuH*8NgXb@H=w>n5P2x1>aZh%_Wan1=Okle(v`>Jj3ryiwy}Bbb0tY z1A+hFl|Th3F8t2SQvvM4uMHS}XUA}Y3J@;*i@=Y-1{wC909*x(lktN!Kr7Im;uuG> z8YfWj*}*>zyZ~HbFoZl`hJ&j)-VzlcTli^u`@4ZrRev6P5b#zN$2@r%K+ z*Qx-1;oFd)$>6wurI}fz@Xb1W&jLqmOCVFrOs)bqs{qO1Z%+aLA=yv8BMD6U0!=D_ z1NdF`XMbG+;8ue+E>Hm+!FMHr3?Cm5DI(~31so;#SGw|D}VG*aA@!iB*-d16!u|IsPG+2@Mj?f z2pxWv60`s-fxivU=juWUAn><_4!@fO$IG2EDYA%ETGCrPr__E!2gL8X0_X0!;e_=K7W!udz<^?MJFyYUZb|*c@TXHLa!mpV2 zq<^cCq7xue_=_CEF9Dl#ISwH3w1c(&=l03loE`Y$_tnmH7_bPzG_YdEj06zJazcOroN`VSixq}k&DRd4tHae0I9 zN`Q%m1vz5t`#1^P`(6)i+LuT8t^`;U)g=*L>7hM)^9bL%0P^yKwkiv>#Y?9M9)Ihl zPg0*Z_$~yPlyc>(a|wX!djWe4cpjJue3{~$f`RWsfVCMcfA%549!pEPgMx2W0N}C; zD`LCnr!xPy)#>OMJXZwxwgs4CP@G?Zp}8D)_bqSZ7e6<+9BXpAr-e zzBK`W0rF9!q(vIrW!p*;Y_swS)qeuQw<*9hgCZU3VSA?%6cxTr0XC%l(uOMuEW!UU z2KZJ4koVi1HYiqOnSE7~V0#(~EWp16EQ;!_E1su(9Z0Z0D-u|M-wKS6?wv~(1lVLy zw5196nW+RB!EYDnt3~=gvBA$=0AMh1#-NA|2K%lg!Hy&nq=df%xL0Nj)qlna+_nJI z4T`zHiv6dOATJMaLKeW}buKMHUsn<+e9Hm|n6rk3U1v#xon0kR_-+K4QDuQ`O3)ve zukhUnusubO+Li=I@;;ImgaE)Wd1p;2KnWDS0|A;cDtxsP46QJqK;c^!V3$FGUoErn z!bk#OEU;YW6DWKi0szBhRDUdKkw*g~tCc_oVU_`h^s*m@0JBWS%e!osSOQs9yc9T4 zl(~8_3Gj(Qp%-@Bwvq%bz<$f$+}TuA_^AZ|>dLI5?J4y=?4yzdwsJ|PdDj#beij1E zHYoVMUiL9sI)*Ocp8%#78GKd(d~Q(mMP0V5mv`#7didpk3tX%4Q-2Boi~!CX6#h1O zo%%ix&^y;1%qaRLKT84b^90f~hvin)SAl0Mz}|qNx5=vHiAC<=TN6Nf?iT`seq7cf zPRh${osb2X8wm81GGKH&&|iVN6W|Mv&`$yDfvLa%h3HrSV3dc;|7qYOnSDD@!TA;7 zK}XQf${77!z#xScj(-3zS%m(NEcv<{7_5N86kuh>(9g+C-kHEqg%Z91Z)5NRlozlNG)uEmxpUq0F4TuQ2{h6fJOz-r~n!jKq8|8XjA}=3ZPK|G(qKG XGB!kEs^^`~00000NkvXXu0mjfdS*wy delta 2535 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 literal 1295 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEX7WqAsj$Z!;#Vf4nJ zcwPcw#uctzKY)UgC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6G%@pN$v zshIQj?(XiGREgss-%k!TahnivG+Q}Nq4ijdOOgP$?kD~u(So|HfzqCWNnD0m$}Su? zRw$gh)n(Szu}0|_?=6l%&I-q5RhC#&k8c}ih#vJhbmrXedEe*!{cC4%_T7hh?Kkz) z&&@Hm7M|JpGU|F2L-uLLj$(#KG7T2&3g?Jr?%mrFtE8lyjhKeM>G-14Qu z2kxEuv*KG@m9T?L4AUO&H#xT6{yNORjXwvR?fs(JaQMLDwa;J7Onq=}R&`Sxi-2G` z<9p_dRnz3G81KZqp0VKP=>r`%820r1|M9#?_CwCvqqE;LDkYhJ@Vl(|>%GW^jmNx? zJga7KTmSLxA3f%E>o;y-mgv*!pA060<^5RW4Ilo!cjip>YQIYkEm{hr95 zz-!4+$mcMJS>QRt5hP}5k(z-JRu*4a1$0gE0p$aC50oVYH>Td+U!2OTCFkIh z!xp#n&r$CEiA$Om9cK{ys8YZa|4_Oosk)(~f}vvFm8xsKN>{AId@vy*Or zUb^k){pil+4YI7)B)YyH;689$aHCq>)F~VeA3N&JKSaD%^eSLj{oTjq&V{Ou$f*__ zdomCGu03QBubIOx$7J^J{qxt2zZ;ul`9p#_8J?-_x&M8pWqd+)?Ck!I<^$z(WDj0@ zcU<#yIJ5eMnfsa6_xzm7Eb!^(jQPI5?0NS-MF|q5&>@F;yq9SMm4iS8rUw zJR>%Ie$2PZUe~`O1~T2IVxlxLC& z`XAgozp}kLaN*yNfDbMKX>#m&taiFvpE>+tvY9dS{C2q%)2?}(F`WtO8~A&f4{vWc zJM(ANYsawFCkzkVXjNXvSZ4U^+1cC!VrtgOH^S2!9{;Jn`!6F+F4y|fn^mj{haYr1 d5}DKA<=;>}=i8E71T2?;<(R9V%Q~loCIDX#BYy+ONklBn3 z!BRsIk}B2`Fjld$6a||UVi6ll3q=DdBp?VHqoSr#EHt8#VBW;v!m{!1*6i)hkhZ5pz%ig;O}8a0(|B?tt(RQ7$|bhJS=l!m{vP*cEnCz%KG# zM*c(SPkEt^Cn5Zau%z2|kR|lb3gLCaw4d2KsGW_&wnuW3oLC z(0^mXZwo6KmF=+t4@QKKWL&n#hza2>!Z~IC|9pqDnV=9qvJ@OADUi+wvOL(X7Gei zs(p0EC45l$T_Ayvxb@_lC~a9Hd@I*P22qOsXYuX0+pPcf3f#Cu|q~LbwQ=w;;5}B)b*Y_qTU}JTf7? zM3~L7D1S61ycPO{R}tvLb*6GGvdtooObGYh;`<3r$@gz?3v))ej;Gh$SL5ao?W!ya zSC~f68InDR_EeUIE39R73Gam&jF0ysJ`mo+b!KqgF0`X4{NE2$y}r?eS>XTDgzJ<< z%*T1*wgrV#IE7O_8hk(YDA^~~=` z+4+T@Bjo3l@Y)2IW5X=h*1C90(f76TF?1;skkYA}?n@G^>RNLYr_uLE4Z< zHHU>97E(BcQ#gfFIE7Oxc|h5!$JzDa0;hz z3V)|?3a4-iM^s?!t7%9OFNX@3g+EePKT!Rlk}n>)i#!&Pmvh4J2PfGYCg{QM35dXss zR&`5TBwE$27 zSRvnFg?t^{1H$kg5IVTai7&X1kAwU8c)^{j3=8*yd$Do1!IbYdNVtJ1g%b*=a0(~J Z_yf@>lz#v1ogn}K002ovPDHLkV1l$p>hu5r literal 15778 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 PKZJ+~i((!OiC_6I<-_re diff --git a/src/qt/res/icons/eye.png b/src/qt/res/icons/eye.png index 7036708de5d9828e2548e79f01674cb39577dc3b..f2f139dbb2f5b7f8b3b7c0fd59378d6ec68b7f63 100644 GIT binary patch literal 2241 zcmbuAX*ARg1I7PF8QB^pOJj{hn99~L_GM^nS+i#Ak)1ST#yTO*WO>Rm6j>hGItWFW zu}>s2cCyA`NMtF^$irJ--%sy3?>*<0C(F zj7(?hFw{ru1K!Q`C>`?s?#KC(y3DKzXJSVDEnvsuv%Q1jUlw5*F_soF*I#e zMnTTMlFZJPdCcvCr>sKF-{l+PZf9pF;n!LuAO+ZiP5@E>zy@#v`Tzg|Ab&popOdj& z2ZaLq=d=yl;(P#Mk}ys+9SAt8Nv2gU2XaZ_m({W0B~5STy38g+wNuSq{z|KATKd3F z(Dxc@%#zj;36@Ks$n`*lgZ-U*%uPR5d9F**2fhxagU0IBgEv~ zWv2~+#j8i$)IJe)N)E)t0N4_3ldIF|;a$iGrj|hPd5#+DpkstV+CpkQ&Sus_mOjgT zPP{BIwGFrNS>s{LRgVi@GUkG{pLHP3L-cEVBvEc=Hgp8$VmdpuNj)x@6RPP*oTJ(< zp}f!ASbdk8R@GsWpTrE>wyg$mLeUKn{7>?~$cKWlNx9}cZ_Xy|NQFz4M^KAnUsgSU zbR1{rpW8=Pj0IA`#wbGLjXM&PVpC)U-)Nr=A})T(vHuYTO))yd7~1mo77Xhix#zHd zRBa1{+iNvtj$sb^IQzFx)O8!s9Oho0=&);5J*O=5@xE<)ZhU$nIKrd*@)6UOnw_Rxs5xSL7StkUD zCng<5$D5f_v_H``{g*KxH43_qQ)~)*S^4egOw;C})dIKMqfr6Y{iAhffXJK-{^Ny! z6CqE&30St2KAWWS>NW;#M}4I4;3rw;N?$M0>&z{jfscL^t;g#0mE-XkcvCXZTBmJjy z9_{L+j{W0>JB0;4xhTzK)@)_>$#vcp6|<=K%4iHHuDc6tEuFBbyEPG!T;s-yNgIrf zCD-nh>Lzd-1(rij7Afo)aZBRtUgeD_2_6a#E9xU#nQnUbNwDb~KK$G}aT&27ZmcMx zQjw|Fx%cB9$#j4rcBE4v_t1>FXM0qAuK&!wpHW_!a}yyxXaw_aT+yldVXQ(GUMm5M zcUff05a12TjbqMJ^|DHcTKOf=Benj<`@TGu6MWdP(oQcrB3H>hjP`a!x?Q|^T2CtH ziNPjZ43#G?qsqa$c)hrU4|ZJPg>^Dn6CEDNxxglmPT{pLr~@l0Fd{RjG~1xQ+YuR* z+amkgf?bp?ciE5Y$zwLgU_HOHsOY(HE|R3dIECEnT=<5ztNCSCx-;vI<@;ZY@{O4( zcO$>iNjLXy`;YNNj;>H1X_EAOll-%tDC@K0hr{X_jRb7U&sdV6BTX>?#Xsdi#Z9`B zygcmFBp>P|aJ|N^bD$m+S$=!~X<96INosBQZkQhawzeqJ=Z3$KUtA)JeO+;x zJ#UFPs^Wn5QHXdUM&Z1u{ig%(a_e~h@KcbILgW3W)HU?4ki}qi_a?MYu-mcKg{^oI zWx3^eHtsyv3!--VzyX0CDlo`NS9WnrvYXw0UCm7-pDM0Ss%&kp3v2fIPq zw(c>MiSan9E^-)02P!E27qzniwm)?L-?;u5cErAU?whuZ+dWO-x6mjn;~GQHg#Q3` C!2b&X literal 2806 zcmcIm`9IT-AAfJOIWid??)xZLB}pa2)*QLE93c^rbIUai*@y@$8X2Y`XXWTq?&DpG zPmV%!e2lC3^U8ejC z5!mkTKIhxNOTv+sHWx*9Ctk!qZTA)>T3?C;0GpA20ja{=-PnD~Mq%8e@PvRUl5fN{ zfJ7o01cir0`uP&C84w}@3;Ac|06;9#25oUMwrGhNm+694>^1Mw&tR`yZ}Zgs(NI2u zyPi=&^?2=y6w%MOgf^<$v)1n+(}a%&jj-A5iEY)$*fWGPi8AARLg9^!krMjix^JNKQ56vt zwP#>5c$RC#t_}PKiGg&%id}4(RoTU@B_*ONYIq6;^x|4YyCy2dLfotAn|{pbIIC_c z6uN-=7JNu4j5t|&+YFSXy4Y41w`Vn2SnW!DXs2Z6J5HX=cSz?``Xs$cb+lB~TL|;m z9z6!B!%y|V55e12)j}{|AKaA3ONiM6QbEY{b<*h3xHAGW1C~286Z)ne4ScdlZJpsDqh`BK9D>Ail$m}2#T&VJg z#ny;#ysnJcs8HIUNUrQZ4quC4+nL3~oUGzGvrFp-xxs5};=*$5+TJgL)Xz#`3y{uI zy2oedfRj4q5r!zEdZbfvpMj4oQFn;`s#Z(gkCDC5-bgKvco=gA+A+^Q##D zlL9^RzJ;V!P_LZ5tWZb7B1nVtl<=wL{AuvI9TQJ^REFLD{m$HX(V>BTOl-pw*40W~ zZ*9Ud<#%G9M{hl$N_z6-CEIf>W^}<=@q~x+E6t1FN>h_3yhMR`x!<3bkon>u&Mx5| z^x^Rn=c~P-N-x;IVm08iD{x^;m4%%cSLM5af^cy}IK(H>tsh zqx9>|N*H&xyzwu4*4Zv9$Sf;M+>?5S=Sf#v){&j#41bfs;{6RH?wd?)@Q{TB99N{?g;w|v$Sl{ru5v(Wafv)8>hvmJglLtw*DrCqSJ`XLDtV7GA+un{IV<3ZZ7rL z_KVitl<(zb8lTUWRJAyybu;nk*I5`G81 z_3+G_C1l>m;p)uW5ZY|>q8K*_9v`JQ;Pcap*5L8?lfiZ*c*;0) z4a3-OJy9v8zbUAE-234i4tZ)Q5H<+!4C#yaLEBENo_Ea|96vo7Pq;hyJGV>7O(qZM zX^|gJw)C8TFZ59{I@}@q*9&-Ju|sypU(TPRrq-p4gwM@(bi|9FaConl5Y~w^6`%Ud zs_U@)aNIOm`GM|K^_XlssMv#jsI?Sm~w-9lX!@kxp><)@d5F$qr5x0K2JZF|YA9jzEnw+FF5ODEUf zJrosm2%68`i%}l^B3IPZFmWc3{{}t~ZP2O&*3L7yRZlK%-=0q|wv+;e7i^y|m73j| zmC@UjIw76ViVfWJ7qjC11)utIT1vBK486|*7oZ+;Y2~ysYd=%n+#orBo_Z%2$3$#; zQtm;NP0STxG@UyiyD!oKGyCI)IK%e>?|)7u8`XZN9nMziU;VY0j2T=E|DXSk zPZ>wEvaUV!Rm4HMoB0YZG-=|(tlo5RKV+>58tfqaQLsv!S$Fkz&0Y=iZ9%g1s``oj z>EAqQB?k#b9|v?NPL2H;Gd<_+O{QGC*?YOVs0Xmwm)$me{-jI+~nuWx1J%k8U`DN-PDn=Z7{R zSz8I+N^4j1>SSVi3kOB%413#r#96#>r+e1q}^Hc zV3Wp!aw*yXWn^Q|X0r2)73mqK8?#n2>PN?Q4RG>#*N2iLd#+AZ*k}IYSR?CB5rwB=u9xCz`{2__O#F zV_F$J#&ftWQjQ<)_?n`MGDV|@dOtQ69+&D!=Gks8Ym$fMJwNT)P6`)11J4-)$;K+8 z_hGA2y(3Ws@ttK&T3KbPBcPp&>-gpFo+yl=q)Gl;F4TkX{6`IJ2cm8^LY%z*WNEjf O0yY>2bgiXN(*FTDL<)ZZ diff --git a/src/qt/res/icons/eye_minus.png b/src/qt/res/icons/eye_minus.png index bdbe0736274abbdbd6297367ea5587234f62da42..795bf6436a47745229b6d8fe3c96569ce30c50e8 100644 GIT binary patch delta 2428 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 literal 3087 zcmbW3c{J327stP|VC*}SX~HDSPngNtpqUt3N~lOA(co zh+?9KlD#YmQ(2~jA_i%Cbe`w$=Q-#3oO3_-yzl#S&*%Pi&+D4AlbxiPiWmR@k`DF+ z*X>OC6ENZJyW;?{dpkkHtQ?NRwofeVT-vr44YBtK0|1A?KLM(;NnhVC?g+Oz8GbDI zd^nkS$rm7#$@>057sE)z5MTY^OMbT&EmQzNJkx=2@OV_wLUCOG2^(Z5t~=&C>Xj$m zcE8#+LP|<*j?_(I31@#3>=mZcd7V=vBVvzz;i)_(mFAEvb><)sHq(HOae3wbB>kzgT7lB%? z_w(G>nE_;CCMbR2kp0(XIVS4?p49g{XQCOWnh{ zN~<4k2#U%aUWlbIDK|I;{;iTPliHy^nU7&7Q?P-jisRXGq}T4Ti0kzCsQ~G)G*^UY z7&rVCJPh`{=o%azgfTm`1lVTx$#cM5IoYv%>&eHt|7?$OrT=^USzC`FkU*?DQxNA$ zSTptSCbI1)qHH@C_e*`5UpK`==xJZOwA(()}E-v8E5W@g?m{|JQ6dVg*6*N{hTt=V=$d%FZ0G8vOj6Ldw z2vz>3#|ZvF1(95q&b%`po{J?1d;kN@5b~XXC*z5`T}RO}a3Kki=*liX73|}~$MXM) zBL@+|cvY>TZ~=lnM)zF<_X0t-ol~Zy2?yOGy+2(&09 z#nR>zj402`t08$&PT6h%E<7O5lD$E?Aw2Bo65Xe7^S6%TEjiu8)PN1 zkZr~#v3L4lsKFEFbp>j+Nl(Te2x0=D?uS6Y2-Z!Yvsd+dKc;OmFk%0<63ylP$`OMa zGY^&EKK|n;XbW}X1>BZT#ZVyj?SnyS5Ja#0i}mu=r6X^s;|&+#W;>fIY19$y7QA&7 z&v5u0;gh-4%aQ}oJ51d_|HZg%{i(NhXhSu;wvMxlGt(jupUs}yL&K#ZyHvZyV}Fas-M`u$mk(pS@hpgzZx65UTZp0un$;Xw`d7u6?Jlj zX=mcL^w4Idng7TK;PjIxYU5>t4wP-}qgskxrdH(wgw-KvnCFk2SoI&|MJ z5%bD@6pLtv;eR+Mx9y)cehVMcdg`FD@R~ZVB#6$vyl9tt-_SA9=Flk?+6~{DF-g zF$N-}jR`ACLJf3HHf=o`P|FjK%l!J5d(%;V`OJq4!3NwcsfCBqeLrD0Yq-QJX1fja z;Z8(^uT?z%&b_+D#fidfzC`L)Gl;zZ5tUDIxs^`aJ!w6njbszOgq&(~=PVeNq`BXg z>V1_V1y4RM{yxKNS*d}_oQM<-%59I#HwURay_Gj7&mPrW!SDicpYsjaMvmjrA9qQ$ z?c{yhek&w%B9=}n7wWD;7^PQw!=n(*J`rHdrvsZ+riJUGXXe5)%1{3aMXU%#)UWa< zzW0LDRD7JoWZw&iv$W@VlrJ>~t_%|{m zcVwQqel@vTM6+FLrn}!?xwR<6g^Ls4R`^lWTg@#DK?KQ<&8B$gxy~59S1LA}lDCS7 z^yqC{h69Zv`Srt~r5_VxmtkrP!*vU6g^Xok2J!Q%W*Bww*vZ4|{j0wau6ZocELw?| zkc_eOyW(del;E?)at)Kp6xlC$Dowh4 z$lSFqx9<8ZYroBofeuDWsbjN2scyza=eYrs?pPeH#GMJY( zj~Ce9yb{Tqm7nWC?yKsw=bGxwKPc3UQ)oRlOdTl>4@;so>@rI&NG{rG9xoFjAN|}> zWn8u6?EK@UJaC%&8Vf59_3G@(~FW0s6Q7vS3%SZM#48F21H9y%eIyEElk!b zE!V1(*|wJ3wdSi3Gmyqi-ZAR|x7n!}qY!ojZY4QTwZ_?oQXiCXWfphQ7 zw5@vQ3j`^e>D^&4?R_%TLgcVwPDHDugLUbWIGR(Gp+7uo+fAq9Ah+pm7Ko-4t0`qQ z6uHcirJJ$W)Orm(1=2)H6iW-dcaZwsIj^m?{;pxGQVbe5_1cuC45%s+v8qk%Te4IS zkysDH;%cD%uDqGXP%WmomB&+eHE|Q>oWgqzkpaiDzjcxUESj^E8syjl#Kjxjgz#zv zcI-IR;Nr6sE1esE%pc%h@PRCBaPyqkwB{S+6Fk9W#>?%lb~%8R4|K=Lu5yd7w!T-V zY8~xoU9BdJY^o~dtoknmoH%4aIaQ{WHo$(sLu0fx8%w>LYX;hozY}DmjuX6fCzme` zUIN3;IhN8G_zl=LarwrP$alA=Nz~WMx?^#lmBmCxDV^Mdx^J|Sj25Z7f;n&T&G05J z^WNcVE7O?+o=atDsD@8wA;iM!V&nlHaz2#w`tqv27?}dk#N_r{mq-amGCS8e*rs+Q zLzwg$&#i1-=*nh6Of}=+(Eb}k{YbWmeC3`vnQieY4v`H>)j)pSu`P01CA+Q(LK7sw zyh9V66-qO{vSV`mgEDw`x1T0zB5wa~@#X2LiO9452jV@DjhTU1D$B-|EALaimd;Kxh4I|(_*Hfz8kv@?|_4i6QS11C+T0SQJCid diff --git a/src/qt/res/icons/eye_plus.png b/src/qt/res/icons/eye_plus.png index 2ba5e68c769678639b66780f7fb2b89cf2c62f18..eaab69297a672bc213e1e5041d949f648a7eff3c 100644 GIT binary patch literal 2599 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 diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png index a53390f5947b017d0c9842f7e798dc017e083a61..f4e6f58d05b8b507b3681be0db55e2121231f71f 100644 GIT binary patch delta 2054 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 Sgw#0z0000cjAS(B`%1=VrA8Y?-tj^ zSNs0R_#5F^GXAp6GKs&za`>+>QZ? z7CxTw+};+EaC<>`lrmrYG0qh&{8P#R#>AE+uDF*nUw=D$87^A*$CLrQ5nF2{+>SJc z$`o!Zd~IaHN2)B`j$`}9I?-^Cmr&X47_G8!JIb68uf*%X8FT!qvhccraD*cq;Rr`K z!b1^0%KUX>ucfpCN) z9N`E@cz*}NvR#*Cun6Iu3A;SF>MlhlW?<5#I`q4o6omh0*s2|z#TNaE*nsf4r8iue zg>bu}+KBME#g1gU^kv+QtNjYiK6~rVeU9)*>D)@+i~B>aG>+wGn` zJ!f(bWbW_#yZ6p~?(cVJ^2fYdQuOP@gkcE~1SJ{@^`-201@{*p$NoQm^=LW!)!$w? z-U&g5quifpZT{>|2+De$E-QDH8%JXVW0m40W1^&PtDT(K z)t2`qVw%jBj8hq9MtdGrO&3mbP-7<*l@XI_2n{L8(Isfz7#qM!xp1-DYOy&ncecbI z7h{jPVMHSKPjS^`OLDn{;&Nk&IFE5qVwF?{6EZm}&eTXzl~RMEqr`F9L1c17E{E9} zu(QGD!ridVIU*3GD~_IW5)Rt#q8Xc*i;J6>T35D2!X*lQg4boWhZ5PGL3S)f#Esh# zR4PMyb0Ue5kG9^+S90vsW`N##znukuoIrnV7AK(HP3z>-k!( zy{2}$^6OXxL8QHUI?EdD6jDk#nOX-y<=3&7GNQMuchTl>ak@p~ls?a$a?^ddaZ13= zzZ3!$(z4fz0s#-a>Aj$MpO zb{WDlRT-+n!X9%#6c|yL7Y_uc8pUtxAi82P0;NmK2u9SQrO;T9i(qMS2^K@bWJ+%wTi6 za2r7x^g4DxO4B4}LQNWzCKH8K8o~rCGn6V=ttM2kSw`VmJ7~7e;g*Ow z+}Z!9DS8RhBUK^oWEW>c#G+-FuD_9ur6zVC?Gh}szaiOihm+#ATehTYzlAzjs6lZ) z{%wol1lP)R1h*R~Qj2sO4WCxXGw4S5Ea3f74#bae?>k3*HD%-5P=QeXS$zj_GGgYfz#s&QKtMe2~Q%jz2VDV6R1dfyM;Iz8_r zKlQQ&_F(r`*mZO0**dk{!vn^)UA6__{&t6Iksf2=1rwNG&b3cVt$)5!E#p4yV_iJRM7uI_G7Fxs;>=WQ9gU~qi1=b0#}Z@ybIWb-Yu!u+C39}uq;L!bLK?RZ21FM^OtTLB-)euMdIbyjHuml zQ)>=;ibXk|xpB9N6_2==$Jk#yJNH=BpZhfrx)bx_hZBan6H*hl#Lw$YgYFD$Kc4&P z)>gIsp^`Y=*c6tdh?RMtoJ;U`Q2fpvSr|?!w+`WRjyyrG^KKwI<=p>QN1fB zHF{^l!$r%XXA6>Mm}bsu^@vuSc6`J5qGf-~Tb%AG`e-8M8)?tF($wx6zWfx_bhe^- z(bo5pzYv{@HIKU4@Uw3WtuLS5TCrcD_~7G~35gv|lcz+bj&6N<)3%Q1V+w{ty8adN zy}57foc;;@_@Lwrh<%P~u1F!8nI&?Q3jm+wpa`>$U13#NNv?hk$y!qBUQ8(dx z<5n%)#I((uq}ye3BuQy=?v1uu_jks}cD*p?c1OzShib&UXQ&(&nGrc&Pi9gcx zmGRZb&d-0Z&1jf9ReF1evT;q_t}zQGYz4nkBr*H{xfNctOmsKC^UgMry14c=L)w=E zrX@B;KTNi@|1S1STw`p~v5A&J$5#*E=S@G+?!MkxRa>)k(4mjceNZuF-{Whg=Pt&5 zp0eQFk!vMd-vE2sob9c(DZ2Q}(Vs(ezHU0N^8Lx1srlr~GadMWwqc$6y29LbCF?6@ z4>^7!SXw@ksiuqTzq|>y22Q>0-{T ztO3`H-~3cwNOHEh^0=gvE7p9w23~yk z$ZM;1#*Urut-18%lHaHGt0>h~c+*5f?4m_6fdhj#Hhi$<;#FwyqPMq~eY^TP_sYB> MzevCFsmhoB4X)Tl;s5{u diff --git a/src/qt/res/icons/info.png b/src/qt/res/icons/info.png index 085fa8ea7368c92da8447b056644090a3d523564..692b50c2a94eae5c6574ec4c11ee571441888554 100644 GIT binary patch literal 2028 zcmah~dpOhm8~%K^*~zkDYRX}$9HOC%ytFa393oU?{K_VkkW>yiWVS*ng|`-2**Zw& zFo#0z)#g>HRH)vU5Gz6l%+QuoKmPpv_50(wpX++A>%Q;nd9M4qo-98f_a)fnSOCBh zPY=e9h0a|pG;#r(oI_gxK-G9MT>TTfMy{p2%Gpn9b{S9SISItnA>fVDn@^!bCz;MCYT4LS)}c^x%teQdm5{n!Vj zLu`KNL|}K#7=#2yL=Xzpr5=zoS}x&3T#H3=8UrTV2N96mHF>j``hZ17@M?id`vz zF6}T72X4b8v6K@~fu2_gdlUi}5FwsNCfD*)!TZ4EdgF0xh?B!m!xU@V{54G8YW8)m zQ&pj*8^pd1?GU(n*js5{JaR1S*8c6r*JD@Dw>z5uU~B(o@Ute&IQohpMhge3-wf1n zxkc;L3l0b?N5)gvnZO$E0kvoky5Hq%q)|{oIeU?G&3g zNf&OJ3@Wyc7fUsF=OwH{+5sa^bwS*9;NkGg^Il>FA{jwy!N`1{Re9@z4_|(cCAf<- z=^It#xbm49XVSs`Q0g__woKb-=o^MRpc`_?q9cu$M6v0Yo|+Z@=3b$P;WJFvmCClj z$iMc9wT>`Sq@AzXdi}{CxGlqPfJNyC2Ci!!DT2g_1#Vi9!CFk+Krt;oMH^q4brgH@>|bq4B1C)Qm@M zK=uymbFHb_cg2l;{Ds{!+d4SxTc^h-9n=z6pyshfr}H0uq-)~C9`?v%bAbZonksh- zJWPAh%g!u0%ACf>5x^%Mm-0RINKZSuA(ev*3k_lCn~$!hgCR;VCpXNXGx3UF9Oe^v2dC9DiEHe zOi8y~9Z=S%4UimI_y#cTKOOP8&uc z#8RNJo_BQ9els~xmr*s}*HwUZeS+W?quNYzIL-QvD=K59afiQs{kK&)H3p5w`M&RhBY>#WuTrmQwiv^h!_+(0Rv$^afIVFJWkzC27%x99 ze-}V^hveaol!Uh>$%^Ae&4kHy^cX1DC)X(xlV;lQF5G+QV$L+eJ{4bSUus0Hs4f}v zzyB0QzGnXY?A756{qXq%MtuLB5c2@KsY2ME_b$>`lRI$3%Eo*0gGK83g=h>Gylfs^ z0=%qy9d=Ad8dlmxJ3zVKmnhG&D866CQ702(pLRyT$Pdjgw_Ne%Wg11ooh2;tZ~{9+ z(@Th^hFTd0Qox^@>$}ts8b(TejN1?gL%#OC-pz6?2l_C-qFXM)R+DX%jY-VEX@5T} zFgmMTPAt6THMF6wMl7hd>p}D%lS*lK!$iVD*OVOwO}8HwZGMg4W%fKn7_WhRXx97G zzBp)~)fLx^)C3h1bz&g6iGod>6h39mvVUVctEs2o`*fNGzlw%p~)F73*-$ zNuus7)oyHu{4nW_vgz#Zre4;sLMFImbP`!{|3@bM#_uK6v1)!)fWxPoD3K2O!N=F1 znD~+K1c{4n6VL6RfXPS=8N?mN;UKq1-A{r>3y(KQ^m?!-@K*7L3}O8Kh?X#4B>}95 h$h!X@EQ#1z{JlwK07i9bZsCgq&n-TTicRd3{{_yJf#d)H literal 2895 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 Ha?Jk#0c9^6 diff --git a/src/qt/res/icons/key.png b/src/qt/res/icons/key.png index d21f81364d8470085f9404210e4160f0a8fccf56..f301c4f38ca109163bab373167eeb83ed67f894c 100644 GIT binary patch literal 1759 zcma)+`9ItD1IOQ=2qKX>rkaY?F~uAubyTa&)s{{*rqq=+SWC5pW|mUq!?#W2sHS{d zwmHkt=@Lg3b)=|@WZh5SAHKir^?1BqugB~42Rze=UZ=2VEi?cC z>*4P9)yIbaF-qZMb~uLg0iaOs;pTkq`owYpiRtT$W9WP;rlk`2`Kw1PMv-DgH8VN! z$&;LxA*~!^Q+MMQ9MQx)^`5fDaE5n=zBjHWmj8Jv-E}C%si*pozR_MqgP~etxK?;m zo=w2q@7){A)E83wl`c$22#4~^#`A%rH&!T|=ZwO_17+*?vvt9Lk&vzu@Br=zCv}hw zSV-6a82qd2aJDKAWGY-j*mzk@hsz>nx$*IaoEbeU}&m6>NIO@_vz=C>$3w6x2fB)$l{%EL8S)h zvZ3q8n8=H^7BnoqfkwB4z}?pPUQi+C;viz)wkye(?O!fYegf>_JKQ=i{B*ea+q}?? zakTPY@CWpYR1A^0YQ=lY%z+LrLxcG8)<0h)5KEts5{WZB>uCdi!;1Kk8iq z1SXZ0@L|jwb^{60MeXkMZ{pjE#~M<5XpWOeU>$E*)v>iGaPXGcpUPZWFBnNd(>&Qm zckVNqQ?kCwAFf4nV+FH!^+YW&uI~863v|Q|vxF{qI2a3oaEF{YzAE)h*5)!}bNT2* zTSNq%PxT6yhh+m7>-0of+RG~YCvfYo>qhMjxiuBl3=Jx5V%?j-D**6ig zpG$Vn7gC#yfh0FX7Rqe26S}Z_OQU?b*_?w6DSh4i3I@nBxOhf0>=9tb#^5nebt~<7Y#@A){oZF; z8r?&c_%M=ntoU!@puwHU2bA_1ix84yjFDac5*rLR2o&4D#uz24|gkvf*)sMUUT zU07)HVY7yWaY@Lr#l4?spa^#Lb^?)0h~y<2hdz?@4CAkHc+-`4o~N1X0JtRXDZS*v zzcL1C2Ujb7E~?EYMdD<>eNR0NA!DxO0Ii>Ruej07Hj7RPu)xqnx2IPh;jbTarpD`b z7VsX{%Ik)S1Xu|d@u*tiGQ>Tl~%HvZ!M)IK0e%Lz^Qq9 zEANz|<)bC=TlzNp>$U8)uDi0u{@TgUj4`5S-`2ag&5X7dz9bU^AR%8+$yWPrUgp8P*&hVS1f-pcJiKgo{DujnImLZF7Bp5-0ubF z7AeVSFwdOr8gPSz=+Dl0OO}kZ;S6p^T4PlI58FzLLIX=j@3CkW^09YikT7V5Opu3xDnK{^6o7OA@_&ORbs?5kn7y8^ zPwL|#bdRe1C;d_F5kK%-@c(1I>|K%KqN{rz6|b=@!S7kA!KKQA>E9Tflo z)KK2YKpBbuq>`enzDC6K${?TNh6+-W1wko}BI}jYyhAep0QLEw1l{$>UzLg4XFWpB z9!rfsi;GD=1>kTv%S3E)Mr=&lDa+LKgfihF9RN_0qL7D!@a1!N!tY0VXtQ#oFx5xx zx9);lY*pDGxGl`k-t3Q{i#F7Ht-T=CrAu4!Bw$y>?l)EMKdn~nu`)yXCh6{}`P^^# z8GpDVk9KjlS$F*t`^FpTdmKoE83=>;Fh73|B0GNhMDifl?q%GG<=eduq7BaI;O$lq z^!vKr_94Z%37W!H$50^e`u`Jlh&E8BJ5t_Jr8FMQtWtAsWnBqG6%DX9X&l@c0uaEZ zd1vqj*3}*~I5T;NO_#g`+8%|*-Au(CG&Th^4l0JI?gLGI;tn^@g7oEtV8x)!aIzTv zo2}gDYmZ6u-~@1BppD8Q)loWKy(Gvp_*)i;(p^Hl5FPW@;~@lld?3Nxl2cF-sX*zr zfiX0PkV|YO&;y*4I-gF<_CofV^l3--EO_t_B8J!Wp1kze)rbdGeh}Qz%h%y|-*PWRa3SiaX8bdlm z-JIZP-V$kIRK@3hC%mj(g`eVRFz*yuU)wg%kp4h{#)5#PoGd&ZXaXy4tV=I0&XC>ZILhX9H$&#~UucC(cLD zyw(Ozr1(I7{eBDFp8km5Z1LXM6gdgwV~dOpK$XD*!AEQpU2cB?NBmwXT91{DazD;r zi-R>Z-~3po&p*Y-v%ZECx1g5aI3=(Nddc zW{Bw~G2>ef{V$zznmy}%bf}<8rhpTGQ`eI>7weZJ^f-g?@rpbiunsVVoyF_-1?=qkcxhSnIp@N z5{iFovj$-X&}W`3YF<0Tj3PaLbzcw=T|tK)EXFCdY$=^Am8zo0G*6dp@eNVv6H(Ty znnV^H4Iv?gs~ceyK5_s*Ie%=$@U|hb7CzCOK{bO#$-m%CELcWwORHCFnoac}aQp%z zJN`6k_8)sqfxmDrEW_~;*yXIr^`ixc6p8l~el~KGJraLS1z;<^a)f5ja>_n}eUc3n zh+|A>31!*0rlwhn;uFwgh_#Cwa|GQ4`;56G_bg{y+B*4RE79jsz{o(3r!#rt`lphj z{nd{-mR9ZdP{+6R(a8dkT=L=VfRJiEgy=!|S*>E8(Gdfd)zo8?%>F|?xYqrf0K523 z{+EsLd=rd+cAZszHqGmNaCjqrQX9EN{znuGk0{D3sCd#L?0=g7U9>2)yYh4VXSW^2 zM2W8^GgFnf`A)_Ut9usaQSF-epFN8fdUp(7{JI;obMB0=*&7g~Wv8rz^G7T;RT+<; zEyP(*jUX@q0}j^enVuP!DEm@xvQLIdh?uRLgPduBt5u!d3s`Sciyt;DAb9IDl9#jHnT3RJp0lh~0XP!d~=rggU z)M{rqZA`hZEitE^Ya}GH2G2P@V&Ta)B167^dr{dlQX=Wpor0{zb*p8U@%?eR;R@xt zr7JrnR|-EotjS4+LpEPiW)a>*Ca&+A_^)CJc!HmKbHm_{NeLD4T_7gvZzk<+$! zj)sHI@(I=%ml2r+bW;j44)KHNMavFas$tA(qb#O@LGepipIBuy#Av#bD8}DZcQJom z3`;U4YOvMC+!DE7bml4C0~L29f|}*~A>mfXVYD=ahJt8j(;Sj&>_H-SMEB)B>$JpK zr^36v_(D<6_q3$?bMLTs1K3hbk)zc6)r;+nhV<}QhvVu_xd*VOg`VUhlAx*0VQnY# zig+cO{dqmG%q9v6)x6e3ViC1Lp%Nt8{hYD05l^hgIZR9iSwRNfNiKk(cF15@TZ+6a?C3EMAe5sgj`81+Tj%zKb z)N0KW`bRZ=c> zn$lG)dUrs6uO>0`R~SQ7skpsqW^m~8Z2jUcL!NlOUCXh_k4>g2SichURK3T|*#`2( zU@bcR`<})gGmKIYNA&t+|?!Ruxn?7 zQ?8O|V#bNj$<&=@)$9YUUSR9po|deTAU1w4U1qQ+Ajn}A%c=(=kI4|e4@(lkdk%Sg zNUs1lEcLHjzRW>q4%L>21wugWoA+|w<@^2x n_vT96>;|r8|BL;c-3wY*@1FUjk4be#mCG=!<^?lOlW_ diff --git a/src/qt/res/icons/lock_closed.png b/src/qt/res/icons/lock_closed.png index 77914ab2ce4298a7a69f5d9246559ae730c5f499..1bd98b21a6d641c833a26af7a20f701dbd47529d 100644 GIT binary patch literal 1197 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 IbxsLQ02S^C4FCWD literal 1751 zcmb7FX;f2(623`HSR$J&fnXuIC`-i{0!T!KfJq@D224^meI$Y)i!50hMbI0;Q^1G? ztYRAkT0poWP#3}@2q{I1B1?;)pq8~rsbI7~V^C=Nqo@7Vcix;c^PQP*e$MwzUda9c zBSX9)002hJK>7h4LVu<{MpwV{;rHlZozS1j(bq+$er&F;H%JSN5CQ=6$3GKM!^qd@ zhBhKbxQLw^Cz9|5M*xXLLP|(U62|b;j*wCX@n0_N!UF(?!=(Fhj?3pugKD^3Yp6Xs z*!+&4)fddo=r4>6qho)-))GPlriVlQ2t}w0ztD7X5q+AL??@CmMf&lGqve%Oe4k>~ z0p|=}fzX{oghoH^$X$%iTu417ycUU{i;jtsv?>88x zd;n55l$f|09?O^>$X3k^G+j?*C4DGDM4rjjSDUKAw5;NZHodEQKmB0kdI=li4hp=~ z6tZGwKncZjmWsWzTL4cY=m1@Yu0_ccx2o<2Z1BVA0u21?s(+9LgH!k`YP`T_iE8r>7Yu)eeWVJFEdP$d3rQyzL&D3&$I9< zxz9X_cku8tw~FcjHulX{8VCxojkwP`E9_CMnz;*mI@^tpqne%E+K{(6;^+qiUrb=U zWx~1B$Z!K!>%`Xx|1vcHVP4Lz4T(V=3cw(@n>sGxB~O2LOH~SM8QE`B^n4svO_nyL zRl#-_dMBbFj|HbwuMxwZEgFFTvL%NYQ=2I3LI+NLo71Kzt;Y*KIUD{><)c~TCPAwI zm?fM6kK_=$@^gqTo?17WD@egp8P5>o3A{7#Y8ZPV2x`w;nXOe-!P?Y)$z#Y)q2=p< zwUxQZOvrT0@>FTa5dJLIwEtp-a`EQLST1 z8r`nC|`7PET+erHx_2#+Sw(TWQ)RJkW$Mr zW2`eRdTJmRCZ6bN_HB#Pl9q~dfNeW;fs_QN2G1Xv)HOmH&tY0`~9-$-BndT zm5B9Pp#+Zbw`ri=x7c(`TLT=I#PQlyqwsrr1~HQo=P$eRO;XWGocj1oW@$G~C<3T> zx7DMwwu}_SOl;rdyv3aX6IW<%3hA}ozRpuKr*{qPc^jOpRM_#}0YYb$)~~DH>EPU0 zff9<))V{F(D5Q6Yar7RAM{KmDZXErXR{@iPvM%xZSO}NP+-=+;MbyVkL`Us}#6fA| z9R|0cpZq8a)kIgG_=hB?zg`v&ipT$!Cc*yH`tjTL{}Aq*2|ellm5IMrOlpkyDOdt{iymv6wqE0XI|jTNOxNDE7E)vO0%j)=PyEE69vH*9 zpU3(>HPe=SD+9or^0}X}+4IXEAr4hE80^z0fR96-AGhflC07qq5(~nxj_UwBl;ftw zGSja0C+qad+XhPtzRL%^;_-v&;b!A6_QiM`Z$Z9%;1NfDM`$FRe-;?g(|dWozyQHn zawy-)50qHDzjPzg#$6`=bGK>RqNmhG$5;;qC_NX~EN-|@NPhE=HZRd`C$~cBpXat> z9{&8Un7WKqa+VZU)u}z%G&WN1;3_)C8kvoK_!22!)tOka5T|DOkF8!+jQvuXsVt#{ z1sBdQy#@uIY0g16`{H4Ewa6iKI|86jlgT@xI{Kz_;p*0!78ij%>QUCIENYRsK!8>A zbte!wyyL-LthGUAp07s+;S-c1u9<%Kavc)L?G9Gi@%9aO&i5zqn&5^0D;_H+AhrF$ z(w(V#jo!ac?vZY#r5-K}fWo9b=PU+%-Wk+!hR$y;!kGg!x+AIqbuQmB^ir=%z}ed!(gs%dKSQF%V)KuTi@HAFJ+LYl-nHYsyS& Q);%GB$=FY?_vfAY1CTBKbN~PV diff --git a/src/qt/res/icons/open.png b/src/qt/res/icons/open.png index 390d3dab64668931e0b73d7630889ed07bb66b97..4d958f0e18d42d7902b42a4f7562539eeb696405 100644 GIT binary patch delta 1679 zcmZ{kX;72*8pZ!_NYW&fKxC0k;UY^A*($4m5CmCnz$g$AQPYBgf-wpmmK5G3hzml2 ztL%{I4FW-`)RZU+<;_Ltpg^=mL53w(g(~}!fJ#X7{Z7xvXU?2+K0Nd5BJp)fcEH$^ zVL_DW%+a~Jlq)eY#+NL_OaCb=ORlG2ehiEw_sn^584qhz}4e>`=nzct48qr;JK zhWqns3SFyMOP?#{#RWqgDPqMidyYw;u61JAu`1+KWZpt6C=czO0C7qY zryX)xqz|huAjulI^gVwt0apwJSV$v}fSV?Nxe>eURxm!AG!nAOLl&@`(0)Q@HY(L# zZ-c*!v}k|^4TgHTo~@CHJ^{poS#lF#qkY?fK7r6>*Nyh80?zx5HZmC7U5tz?UzDVk z<`!<(l01GhV}qnKl1tIa#a<)lI1ao0LF|b|@$Zw!%1d~UPme)%=o5-c+wJ`Yu$U;t zG&SQ~^O*%+m69PcvhV9A|3XIIUCE0r7lJ&_xVx?N9zsq*^i^HGYvZt!wzHVuDg|Y|H6``C~Sq5n_MklS-gvD2(-5ZDAC5%La^486fRC?rFmj zKj;=uk|E-EKfCaH(o;}{OS3E2{$TB>tbJL{tLt49;! zKiu+Z_Uy0vWAf1j?G|=OYRZN$+IZphl($p|ZvLV}`u;@1U4PIzCNAR7=+oB@1&v#1 z{_WHO^(Lelv!*dvFv9@@usZs`2(+1t-46rJ!e-rut$O{Un#R7^Xv#hf)z7H!IC9Rd zUnm5P6LmQS!O&C1oR8&0sk{1LtrK-+lD9G{@MO2e*GMujo=p>nLx$LS?Xbsr#6ZSg z(`L~+Eee`4`u+4+{AQT1jTGLvQ5oUxwrP#(Z8(UVgk`JH1Ru?#pvisvvv}hkx zz2l7P$6$!gJ}%gai2Sihl3++#o;8h-b;>(7Bsmcf@c;z{cNmxqNF-E zrR`{D`z{0d%{{VfO&{O_E4&MxlQ*^bn=eTDj*sdO1!~4DwQP?eBQhvLO-%@n>Azf4 z8^EDMd(Y*VakY*NZiej)h(bZ-gypQms`;xeAN;bkU97nv4gF}?na)o1D@Li(43V4> zB>@v_KQcYEOcl+MuNZJRvYu`^QzcPo{_Zhyrul4YkI24sOIo>>7 z8r{<(cX~;rG{t%3ud4c}9Kz@g`wu5GjOvDVs$fZQzy(;|9Z|L6A);|e^Gj2_>p8?; zr}h4L&Td=BbOLRvQPoSm7rEv5C^ekrEnMYGe9L8x=W~3vjMy+l{N;s#vp-n%xTk8T zdxYNTgpq{P#N~Ikh>6wLSfh3m=`o(^kZdhyEqVP?b0O`N*Q$5FLShd&j0e4VwP(;& zZpaYTxcfQHQMN^)$e8w!TN;f2GqL}V>!Pb0x+~8P@$Q$ra0VLT!h$1%?glb=e**$N B^uhoD literal 2239 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 diff --git a/src/qt/res/icons/overview.png b/src/qt/res/icons/overview.png index 36e1003c3c119ef5bfea14386c924ce5c3edb693..411595413d6bb8b8b35f888a81d63469bf0182fc 100644 GIT binary patch literal 1662 zcmbVMX;71g7QG1}CcNYoDilHljAhZtW&klxAR%mGWf1`pS<=cP)GASySg83zSyT`K ztrQ*t#%f7l2oXj@#U+S<5`-WsGe9&g8c-Ht0)m0ykl3xC88~3 z5Bw{Vw-fVlf3w+&szUB_@oxnt6(Z8@KZ1!9ejV=DHm)ZaKD96Q&e&TVgCV71U4(uK zRAEG^Mbok3K7^p1d%0Y*%$?D@tdcu(>a;8Tdy9<48f|RaP0R3;*KBcM=L5UYtS_Mg z$}os6*rLK#1RahXW1ji1cF>cw%24mC*UZyh6X0UUN|bu)C(Ze{8>D_J9`_ddWw;(K0YlHE2`!(UL z(Uk^`3%5mA?Qq%Pk`dzCn=qcN_2{Q27KFKLvs(}3I#E>EEF6+seZT+7%kS}%*0X2f z(fPR+!J#b{%y?h_24l7-pOU`QK-)d??|;QVTaO)> zmXJJa_tx)&J#`aUb>>*hVh(37`i9f-p<5BSWsLka{wT)Vz53HOSI>5f@!L7k-{mqx z&Din1$58h?>_0eh0*r3-r7t!=)R{?Huu`XtlqdPpJ{e{u8813#zpvk#FMjfhFiNwX z`$|ezFEu5{Q4&+{E%22|oJiEE_5gw8DX8C)bXLlWtN0_u#gD@&Q!WgsO&+j8oulVw z4@`X5QZgMqY{ss}H@_J0P!sDZ-N#(Wu_f&hxKz6?o&B`4lB{gbY?=$!gv!4z0C`8- zJXziao|5Pxngkt+CBm$b>(Pi76L_zLnI0!hdCoh4(fB*xz}=iP@?#6R_!@hMF#&3` zp5;RC7Uh*+=tuWls@V`KWY2mjiv%|347_61>lH=k{-hHfd+k6z))jX%8@X(EIO_(H-sZnRK2;p zTV@W3`Lh(4^*Bx2=mAa4U3)+R&oP&OPMYa_FB*JXZ;~g8hSuqW+=J2xffsFnjLRV? z-VF(g{)XAoEBc=8q;adf9}0)2eYtSDMXDuB0}Ac1?Ut2eI~=arG>}0iCNJ1Cp^--A z;$q??S9OCVL!|Gt`6tZb3LlY=^7V1+&a1wAf#>$1;Cw*p{Y@uTS=sJAvM+?7tc;Qc zld59&58m4h^El)IO1a(;*^Ua^0mEx9jG96LO07u@e0SYQoB*a+WVN*^Z!3Bu52*VV zg8xWaOp64}KUkT!RWBAWt;`@Ch9%U5j$~}=@&0fYa9Cvb-El`@*5brsoD~kNX(_(+g8iVbOty; zZ3GMg#(-u)V!3<<)Ah{hf5K<(|9`OlLRpl$x=xbxXCx z3kiXLg)i84SpOL;FBBiVt6`CwS6;`9$R6LU{l6LiSz&L)gUDU?g%Lh#s#ITE2WtrO L5Al<*IeGs9`-{=D literal 2215 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 diff --git a/src/qt/res/icons/quit.png b/src/qt/res/icons/quit.png index 6e44a2d329adffe1a5ce13ccfa8b901f2f325765..55e34de4b8cbbab55e369eb954c5c2be72ade49e 100644 GIT binary patch delta 1071 zcmV+~1kn4Id&3BjBYy-6NklDrDF%)d~mlMryRQ>jAfVzD88KX`$XCQa_{-MhQ=d+=TFz4zgl z{C;=$-n+Sezdr}*2@n7rz##w!a0tKw9P$aA#ysgUsX{7|9)Cm&fqY{hE9~=p^uTF6 zBt0dyNLQqLQh!L_NFPbhNyUJGi|oS(_G#G9dye6R^n{d;1~`pJq?e@cBOL#idZhQH zRYlONY_n(R>ka7zX(1?Z8qdZ&A*SHpNj^m*{LHhBo};f>tlR3qY2-+69GxH5C(^P9 z*vmY(q_0`*Ie!)44EtO-fPub}s)DeqJf{y|&uyUF1kv&oz(BVW&>8lvXJ1=hfzxPs z4nPFD66}E*UVzhBBK=Sb!Wz0V>^?JD@&Wusyk!aC>t5d0?$Eu$w){F<5g9jE1 z6)ot-uz%UV0|Ofy62L142G1;);=Z9QkF$M)=60#940 zU)7qg6Q9$Fp@)Kf>hp-LK>8dZ^iZ%f76spj$bTyiC*eN8go2$hSkcN$scLN=O#l=M zw)G)*s5Ar#P|3lTNOcPdJvrD?$(%u;rwCgtT{#8lF~FA2504glEU?8ZAYz0b6KpRf zCow^f4Ys!$pBSLW2-|m2RWRtW!UphJ0gk^EyfkO?rHRi%EPQ5j;e(|;Hm_!L^9tLu zIDdec%>xJ=u_+$0;SgEz5E*F_%4rfv1X4@{LaLi`svD9y6_YuUuB@D{jD&psgnX2o zXqB9xs7kr03T1=(WrHY;RW6K0>9=y}H<}wLH#b204(0Y8Xi%fspvJNV)8Q!N3AJF# zF>L)7Ob$)Py4(M4~-&~8%3fOYJgU#X!fhz>=*5< z1GKY7!}b6T+Y`K!V8tQRVC<8vb|t}3Fx!b-x>0b*I2e9GHk^DB2xft=T)9c$TA4M= z1z7f-{o3SfL?b^u&zB6HBye$3jn8Q>ChU#0d6g~Z>wkYW7#|^4_@JfE+tFoT{wU%? pI@~r0;1GZVI0WDT4gt8negl8yUEJRibU*+A002ovPDHLkV1n?n{!st` literal 15766 zcmeI3dt4J&7RSe66k=h0@Di=WP+KcaCc`5kV~9dPff}Vq7m$a0(b#00)8~&-l2QB_7S-D1wV8ry5fgOHdV|6)4rjDokL}l9U>Pqzf#hQk9PxxvQ{TTo=i^`p)}2F0PK` zrGzVl3Q~^c;c-QJY8l&xH|*L;?##;E)hLrQjP1bw;Iy zuQLR>g4~M}gBetMoHXKuj_Zi4TtyTZBY8YWqQPt6zO>|EBAsD?9YqngC`lL*2;tG3 z)T%)rvOuqKE={e1F%720bVdW^hm7h+<`G81kVlM>a&UUg#8gcbiox8Yu2-uaHMPMQ zYoZVgARX1ykX%S&a1v%93iK*0)?|Eb$&fu3XNYt5B+NodfBkQh20(sMtfHuo$HglTpnWMztYd zC`v|zXs8$sLxP0}Dii`iT*?tK6oeYjDI6_E1d0rc0Vqetpf-2q*_z3Y8NYLQgFVlZ8s*(S`vpXPcq%I)hQEQ(^HjGHO78 z<7zZaBo>DYbHe#pgi6H^6N(VN62sK|2&F_6Aq-QgMdBPMM1=x$zb|wQp(=1}m4VRe zKN%Wuzc2JMJx(2SN)4cKtp3lY7$wYosp4=0)trSu(^9SLJjj+~Yle^Bo6z9S1Bq1X z4VYuQMe^?Lx4{!^@PKmoIJYgTR5^|^naZ&nFtrpOHafJdLC*m<{QoVWD?Z>pb`EnM zru(A}&Ayw|uZirbU;;=(=c#woQvjUHQTGT!n{@cC+4;*FnX z)R(qA%}USwO1p-L!t+`i$%D^D2gl7hKSw+JA)jxb-KO>T+hyJ8*SYuR`VXi3zfri$ z(0uj0_{P2khMHq%Up{!wqL?z5WY@@xgUJUu8O8s#wi)=E62!JgC!2V-y6)~>K*~|GpnKPV1ZAH?HsWivCxp+CA)Yap%PE+OL(9JcE&u)>I)W7tp_595+wsB%Vo|AbLV|#s(E8=?eMAw=xto5~Dk^EXX zJ7`0t-zM#YW!Glfj(Ugj+>6-l?_5tvvfIYjKG`&xxagxy|2XG^&4-TW-}Pvjb}M;3 z^mcLQdB0u(DYA*@vmTqSYEH|)dgXgbbN%5>LB)4Ewe}P{(*6AP7Z0=Vb{b0l75^Wc zC1!W_24`1x29+85+mf;_m8SFtkd>!)N7}c)dBR-1C;qtiBfmYnu=@k+uMZdR@NNlG z9)-%>jG2><++bZi1U((i?J0gC^q;IEUHjcNzszz!8;Rs8_FMXprYzIvEBaeiGt%9f zp})y*^lXXjpG}^;B#b*%ZsRv~xTW2M0{z^7Q%pWo^6Wkz(-wv7$Xe@yY3_TyH*HcK zD7W(KE~Rno%f_=hCvEw-+&YVszWU6xz-K0&k2twe{L1y>YcK4af%kao11p**VcQP< z5_Wac#+pU`I|FVdydrp=m3Cv@*&8}dz+!EeUbGk&*-D< z{#nB9^S4TUNd5eeH?1JK2rB0q?eUcQrk5YBlTSuG56#*p7r__|%5%scD}-#3_%@ zo1NGc&E*#aXI!p2v6uavq%Na@YzQG6?Dt)35(aBKpE$m5v*=a4I!ci}sp|3D8_!huE|Ghge(_zB_4AQ!$bPq#6KB4c zwd(Mv?Z^jvN`Aib&79pOk&b`U?Am_^TtC~PR-AlmTh_~>qK>(5oLE%a!KsT5PS*CO z*MD>L_?tB?%`0XcPswZlt|?{elGx;cuBWi&mv@YRs-z)KoYja-ePT`RjR}&K)yG?= z8@5!W)MzGH1-Do1YOtyMe7kr2fIsxvnVyn6o^F9qV8fF5&*7!J*)q25&i*{RZ+BV# ztlo9=GRwwYRV6=?<(X45-B7vtpkUv7%}WEXeJttuaze&p3oCjvE5(j_*R$FxZ9aX) cfp@(i|MjW-`cLY%i?EnA( diff --git a/src/qt/res/icons/receive.png b/src/qt/res/icons/receive.png index a53390f5947b017d0c9842f7e798dc017e083a61..f4e6f58d05b8b507b3681be0db55e2121231f71f 100644 GIT binary patch delta 2054 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 D*DN6N literal 16663 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 OfUBdY!!bMd#(x6@sjhPX diff --git a/src/qt/res/icons/send.png b/src/qt/res/icons/send.png index 18d05961940ce6f5a7dbcff459ad484a4a4c42a4..ac76cc1effca6e42666e20c0509a548527d61702 100644 GIT binary patch delta 1736 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 PKZJ+~i((!OiC_6I<-_re diff --git a/src/qt/res/icons/synced.png b/src/qt/res/icons/synced.png index d33914f0b4ac09d8b1a25890db6b3883731375c3..5ac28d36a39f62252745a5005d60b4677994facf 100644 GIT binary patch delta 1604 zcmV-K2D|zDg8|bFkRyKv8c9S!RCwC$-CKxNRUF6h?>J_T<(N)ohEZA2q~yeeq)kED z4B1OY*xgFIK}D2BLKnfJMu^cKin6R=UJ5Isi$y6&SmsMNvmkMX#KH=)vb>Fro*vE~ z7$=W&e(S8g_S$Fu5C6yWUwf?&d(Qstz4jRjg#uRjDO&^svoe1$D+4nyD+9AKFaxtP zFe?KyFe?MIGB5+PGO#=>64U?_fEM5i;9Q{Iz~VwW1y}-n59|R7hpFFzHNf@2(FT?c z)P=xXKyL}8!V&N~fRha@4AgMo84>Al^#^dHfu)Oe60pt#R{wef7-3-ku^NHxp0WDs z9bmYD`NOIMHl=@r)mN_>m_M);DP#53JOis7>xMvB1z-m--oV_kj!Q1X3ju3|fw_Y{ z9T=+s?DlbYWGG^t2JCZK@C`saa8Hugest(@mx1YEuZxTPE6`S=*J82PCkCcroevxo z7I+UZZIGT13H|;uFb(W8@r+ndM$ZwzR-xyq238){RU&^@ce%HgfTx7Mtp+yuf*u8I z5y7q&`rjw?Z8I>x3t9j^7yB#UV>1nG@Q}Pi1e+m_@o8GUhay;q`dCEl-v}Hivv)6W zjDeM2%+rA$0jmd?B#!Z}(0`*{)*pE>SBhuXGO_=~V*h6itn^||cX+fvR_I>?d?Ai8 z#lT80=z4$OA$dUmxnlp1z09jhvF3=2*`@5i07e4a#4%b8tn{s-uCzjOGRDJV|Bt-Q zuL{8yq#Tk@0Co!f4*=)n1`HSlTm)PPJdiw+xEr_6uJII8713H1(mEr-*0)*s$h5oyM3DJLo0rkKl;7`ZL=o^zWuf}2QNdZFg zd*XZ+dp{XGVod{n_O$rDFd}#QxhWy$zKbSh8houP3a&`T;nr%<(S> z5R$(X$G9z(uNx0ob3H>1+|Sos#xZP2IV9gC_Wu?b79AKc!*K_adNwp4;TWz-IV9IP zgyetAQoHJ|0IMO{Q50fN-(k^`klZcynj_Bhkt}XOr2)1y@J7u4p#cwyJ=TkJJQ4Ui ztB~vsjNDgY=t-zGqO)a%xEaN*v?%U{50)z!nJ;nO|nlG||+Me6!ep6Hps7*mJ^UCJTMj zKywMnKZ#?^3i`ay0jyJ)Oug9KH<}ufAB`y_`vOw}bBjZNUubGb9`6v6r{)1{p)h}` zcE{M@15FLd%VP`4zQC>(Cbb`E$^dPpLsU^h^6n5J*%w%YIJquhVn8&Pki1G9~ zs$h9Q16mzI^08G57BgBBlD`p;=Z=`LQUQw<4VWh$$9GwW+_K@vk02tt$yVu0YKnjsk=B_wGQ3@;@>wWzf! zqM%}ZAW}=fh}efOqO?{N5K&R6qDAWq5sTMHt;(GMLL71GUF}`>%Ve#P+2?=u-ZQ^* z_MZ7NtPGtOIKpbY6#xJuI6>?%_*Y{14jlsjT^k!&2me^ggQAoGz-csmO}-9T^$Y;$ z&0-#3#pebygt9~rP$Y|iJdzXT@N58J&PbpuF?kp=9wp+zd*u zThCVLT_GlXtqgw!1gc~To=hfT_3pCJ*9h_c{&*KIC=^Q#NT)K1$oT_{JrD|FgDQvx zZ$?je8@iLccw`d8)008wYs-%<>JnM9_5PYYsEnZ&_{jl6oc8G|EL zsz9j_;;>opfQMKtVt9!}6k#lh?oROph3=lzSfM)z(!JbcVnrk&g$7c+W4wDHa=FIt zZ-r*dgh_@{=?g6~goeB*BySPTof=C4-90H@G46D#2tJ~dg`OaZN~X|6uR|NTzZE(} zA%@!=C^4F2IQ#!L#UNqcN);ql!kaV2Xw$-5x2KUUfIfY5^tB)n_cSCqs8B+Na`Pd) zuDAXU*59BEK0Rg20ELED#u6H;0fH&KF*4s|>vMJuS@ zP(8EW9YiUMRjEM*4YYw%u0^tabwpdtOA z)?i@&3gba(93)~9UvJ&l1MjzNy^Hx~O}%afZ`UBxa2I00^$YJMu%~XwOyXN(1DSj0 z^9^+Bw9=h?elM$ce9Mc6wE zKjFa-m&E?3%eU&YzlZ&k2LqS%Pew(=!jd3>pqm&jbUp|b!-W8XZeqC5`5;sb7Xk>n ziQz)$gHSPC2q5Sth6|k!Ld9?)fS{WgE_6N!6~l!9f^K5C(D@)#3>N|jx{2XJ=Yvo& zTnHfOCWZ^04?@LoA%LKp7%p@^2o=MH0D^8}xX}3^R16ma2)c>kLg#}}F zoex6Aa3O%8n;0&1J_r@Vg#dzXVz|)xAXE$&0tmW^;X>zwP%&HxAm}EB3!M)_#c&~j zpqm&jbUp|b!-W8XZeqC5`5;sb7Xk>niQz)$gHSPC2q5StDlV&m_cb9Y{F0^`ejC#) zIyVn~lM^ot3gZGmsxts+vH{?aZus{u03?wB;GO^g7zF@eE6ZK{(`*2+DCDqxdC4vJ zx25IShJX0;Of_x6TyEI~O4#|X&6ShHHve8&VY)_lX^$xCBwB1xs9M8Jxbf3&fm7K95@O1XO_=eeV{O6#0#Kyh|S7VWZWj7ueWOAG-;VrR?RKV z4AIyTDt^%vkNRdRsjhle5l+vy-khLs%)V${FzQO-j%IWHQ0u)kLCuMKmReIrv0xdQ z6wUt9UMCV91didJ@8Q=nt@l=XyV)Jhr?_c8-=-|8t!_(;bS6zNYWqafN~k!?bQ`Z- zeMAivFVXW7#uT+X&x~1L?7B@^R>rxI7HKP(CO_8ID9gO4@0_J}u+{5i{CXVJqJOz(ZmLHvYqv_Y^_Ub*jd7r*I zL#Q~Gscbc0W+~pcM)_dQpLd2{QeU+g9uZyfL4n<_xqHJ`SojR*SL^C=tznD2e90r9 zeST}naDL7{YByvX(asiSw!Mg5r3@LTTakT}bNbB5X=fe3@qQ}9MO00BzJ7&nA)e6w zA(0(&efDy7Vuk*P2cI`zw5S2MY8URv&$-Xb+t2?M+{)fvmBPQ8x}dqLmUrS%K=Xw1 z{X6#_a=bN5u&pf@rw=D6@Vl2N3qQ|7$ zSL9jrvEadM{Nix?#$`%@y?ptuFRZMi?7oviYeq*)@m9KC7$7q}xg z8rJN{D5}h`e3*aYmF14bVUH8G9JjyL_}$}tT)s)!%g}mh*6)YvazhW_FH9JABv-MH z`O~FIT9(cFx|Kc+d97VuW*<=U|2%c<*mSug$zt4+ijXz)9}F*6*G0B;TD~aNWsJL% zcjo|i9511Jg<~k|`wc(O&I&GH9lB)t^@3em;jHP9-S%niRQjiJL8F@hK_ojg&S7q* z*Xb@>moo+Bl^LatucX(r{7iAK{+>%)gwy2QQ(ZD%OSwsl>%H5W&W+F)^NJ61fTo;KYF6=iyZpz}? zsrT4?`=jRKSAyB=Me@S2TO2Q6-C0SCjyjv4_awh~eB4RE%V#n_$?p+4@8rpa&_ts7 z$XjEbJ{nRx>dcD`WZn54f9w{m>3Z&aI<-EmrQ7B4`obK2YrRR6xIv>18=0GC^7BUD zE-1h}qBxyD6Svmn=u)}Qxa6yG$whvpTzb%=T=lxbp``8x+Sn+w%5SP8x`#e2n$Uv( z<6DAR4aX#H&fTc8@w!WPm%mcDm5j)p?s6uXP%2^PrSmQ7PJNp*;S<5blzhi0d*@6A zN#UD04wlg+-WkIlej008HPqqBv9`MQGTqh{B>|SX84EU%ozA2${%}-6v9~(E?I%w4 z`6({cnzPSs1F0c5O5LdU=4(143x5f@+rjbsb2i(?HFx_&jqQg|x+n8LVV}zs+eBRZ zVCTwtRxL_vO3jw08y{FV=h1X7OD|`ydUDj}jw88g_4$&e<0tXXnbibV49(r}Tr1nB zjUL-T_m7{Sb+h<1WzS8o8ke^0=pya)C&PD&vv2;gF{yb&__{(T-G1vWd);=xLzJwS zBZt{JePpRk`E2(hn}*8GHv>05t+I;`Q|Qwn$FlFG4zpf~)GC#ZJyeTl~(nsbUBYvYTo#PxdFYT7hqk(Ycwr%kkr|lgUs z!!#u$=UEj?V&TCP<(>%;39U0XLJfhpI>h^21tzsqUA4hXw~!EJ{o_ge74}bv0f8^$ zUOd=kdPcJS%R*-2_(O~5aETOcu#Z~;JSlwi{g}`SUq!jYrs5L%?H23cWcLm{y;M)n z_Aayf{@7Q|hZF4m*A+hJ$DFLYVVTukl0KUh8K(I>eaexojZIer)*M!JR*zY+>9dGc zLFUf8{3KQRlPmo!YL-8{6ZEUU)0ZqaXa4fvb#UgbPs=A4n`uMsqhs%g59+Inhm^|o z^_qwcF;$N%i6u9Amwhr`4tX`V;bm6Qq>1LP0V1;VH-56l`+;sYW3;xbOMUdZ(N*~s zQ^>O)@o_w$$g;^H@SJZ}#=hu}@9C^M!MNmqDX(*`FUxvq-EO~p<`3qrVb>>G@7=Th zYp17W>iUCE9j8Q&2|j$RK#*NG{(7KbW6u2&>wAT-4jz3B_TBYFhFhZHZdjw~xf?ET b>c#B_4cNl8 diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png index fd41da06804d10e5f0c8ad4904fbc5b29b39d9be..1091b86e68864c2a8c5c50e1aed9902b5eadd791 100644 GIT binary patch literal 1220 zcmZvcYfMvj7{>qS^z@Wc3lt&@K|sqCP%g@KkxPLhG6WinQm9yDDk7J%z(fSwQy4d` z3j`4%4yw2;83+XlFa%nn4o1Bo+k`Nnr7*#9D+Ls4(+;yQb1}d7@+5Db=i^(-hzung z?l1%Zki(A9k8N%2LmQx5^O65)834$&FnVD0rLo2Fh?2_V*8MBXXD$RO=_HFFhg-j~ zW*WDV#_fm8Lgsd7RJE5+I><%BAeidbYI1#8>zy3 zwQ`MRJ&*1W+t6!Bb2e zMN`ow=mhYFG7(1P8{F(Q8}vE!{ejm8VjK%SYDVMLtvO3y8W!qfB5_FtkH@mfBMbMqyhc=x zDp;l14DWM=iv{kboRs@O2~wk2zsRJG2efV7ram|4JozRxYplMsUDe{ivq41mx6%pUAn9kHy)qE;%RKXGF;GjI>d2I$#}}?ka*u z+75$1&?~tLQRsa4bt{%dXH!4INE^x~7-M!rc=bhVR2V;8J7YZg# zedeBdHaECt#OH3M4Mm|w8bJ{c-))cmP4Fv%TkqZBL`0E9!UBg}81i+(4uU++;6$K# zT#q({5)c``57R;m#{2a#3R7q%UZ*UH((_yiv&M@0;U!YrXiJsE6ed(!%nK%a@#RT67Gea6>jVFQI6T8I#@zk4qf`N}vI3Tq{5YgU!C zxk@$4%UaEGVM~DSlrCD)fJB)|_B?#&f*DEOiS4@e*xqbel3Sl7kC6GN2Co{a)^o-> z*E?*$5N;t{yxuIkY~+k)aP!s19xMI{RMGL~_bKX8U?}!}==e?~1I$LRfnq0#s zflmKcEhXX9fz|W7uvseP8~wX)+zFjlJO?A}@M>hKM|^(`l? z8}hY)5>m?DlPxiCDp(`g@xgNF?ZtTtO$Ypmh>F?r;WR}9#Rvn%b_&3xIn5HJ6A^JZ zSVYB40GnU{u>+6+?O$0&#qiPwDApNJ{|_eQ5f^YMd@u~01sexdakS=-tp7>*NV*b8 fQiD(8v6l}scYU2<)O@0A>pOw4kVtw{P(uDc4buT# literal 1759 zcmai#dr(u?7Kcxcgg^p>14zQ-HX#avW$*ziLU;%VLI5EG(I7|;iXx!MBQap3Bv+~s zc^JW#0fArsffm=#?TK1vDjKgjxvXZNGbXx#0jAz2TVsfs$ zu8xzhWs`gJxYv%576MXIw1K3K=Z?n1>BRj`vAY(npcJA*&?Y9#VUj`u@@YoQYX#Jh zI@-SmNloFFpMJW@0hTo6kKFe!-OnYu<7VuAGzn?1-P7K^|A2T#j#sWenQb4fyqo;> zldGub$(>*8fQY+F;JZvr(IiOj#cnPkAoe7cr<*7<9+>>|fyRc9BOis6JTr_l95VL& z{9Y&{cmi{qN>8IJ(Fbvck5e9OV-MSjeeM? z#G>6pQxLLk{t}uVI+S3|y8_U*TIHDJSdg_1k6JJ_(IckEQ}a|WoiT8d**vIz>TBMD z{Um*%HGpA6rJWUzig#|i@-3mF8EsDW6nGSq{NZ3svnXX7BX@1Zb(E2&8MY|4mfh)C z1(Zsit0Na|M`yTvTvO;FthuyV^iTxxlV7QORma#q34)6oJr=6`A)CNV$C|k5HG>9U zX#a6_W3i<_todr0?)#0-^}}WcY^@jZ#g!nOWUgjhkDJj%Njqbf?sWt%G9Cqsay=T~ zVyp}MUh&VrEd8!XUysRSY*CAM*adn$IxuUNxwX;*qzAqAq9AnzS7HSPWy1xKKkSA* z2?Sbf|HV#mm)?e9h?y$Bs#PV+pRT-)Ua)NY(v1D!Hy~k+$M8?qn}4*LwljH(n+xM< z4)D9qZTP^QHDm1&`51d8?%3R{ep^FuH7s%TTz$dsD%s$5v&+z2YTPsaFwagI%-+`? zRga#JS;~|&{cyg|q@AH{|9lP$=n7i$usQy0;^*6C==hpPV#>O#L5cjh-4m{Xq>rTf zUbS!;J$0hnb<)|*_95Qc&!mVovaV^No;nN3;>X+_6~B_zs4Pi7la4TvpIMSfa;&r! zP#x`dciT5|z~x@~o$#O1%@TS2RF}R3A_6USJnV}JKY1!i;j0kF^t*mkhe$1U%k;w+ z6NI)L(mGz;AJVb2Z35HPcPcNEEGU2>I?jwpSw5{>rL8O{6ghx9-&K^OD<+&#V)t%slQb1y6r$q6Wd^}<$?FuOSL`HtMiZy3r`*C);BIXy_)Fe z-%O|M>2!*f0972iNlQ4{OeFB`GMS&`j#(C!w^jko{C%KM`x+GNR{ zTY4Hr(NtQt_%O6vXd12!=N=`=DDV^>A!M9{-QC$sWw7+pWVDLuETDA-#!p`#xUElr zSxOS$hnB{yN}C64NzV-m`gq8hB=?7CYA2}yo*V`4noFgsy%ROtl*SbeXkH_8#8+tW za$xI(SC?Im!dU-a)vCEPS2ZSmK>rG@yAX`CuLVQlsZ_*WZC1nD4({-HF-CL)^z)j3 z@YyGn;Xw$wgz7@dQjvKV83JWi6V*fGat)4xF_*?#`58eSppAsl^XzebT^H^VSWc{b z7W(vDaj@A3pNeV_hMo7?_v*B{9Zl85a|{5=EuVniY&j+)uiT28VXrL%%XgeQ)3B^o zuu1?+Hb1#CW(ncrmFJZj9A{`zgX>(UI`zDvz{%Ec@jVg&KsH37-EdE$q|Wch!o(*? zCO&8V%`>|idA?*jOh2XSaoF<4+6Sug2=dBjitXSaHN9~3QpAi2!7iJ}$ zC9tY@uv@*^7vmL9{)5Eb>N%5s>ohRmmp9|7Chq0gYYoWu907H-+UJH672`AQc0dEYyKYiIN#I0gKG_|O1{3|#A z2h{M>md><&7VpT)HMNQww)PjFU;s4&I)fuk5ex6Wa ip?Y;867zTTp61@PBxEadHc<4R5x@+JfWHYq{`ouldGure diff --git a/src/qt/res/icons/transaction2.png b/src/qt/res/icons/transaction2.png index d33914f0b4ac09d8b1a25890db6b3883731375c3..5ac28d36a39f62252745a5005d60b4677994facf 100644 GIT binary patch delta 1604 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 b>c#B_4cNl8 diff --git a/src/qt/res/icons/transaction_conflicted.png b/src/qt/res/icons/transaction_conflicted.png index 6e44a2d329adffe1a5ce13ccfa8b901f2f325765..55e34de4b8cbbab55e369eb954c5c2be72ade49e 100644 GIT binary patch delta 1071 zcmV+~1kn4Id&3BjBYy-6NklDrDF%)d~mlMryRQ>jAfVzD88KX`$XCQa_{-MhQ=d+=TFz4zgl z{C;=$-n+Sezdr}*2@n7rz##w!a0tKw9P$aA#ysgUsX{7|9)Cm&fqY{hE9~=p^uTF6 zBt0dyNLQqLQh!L_NFPbhNyUJGi|oS(_G#G9dye6R^n{d;1~`pJq?e@cBOL#idZhQH zRYlONY_n(R>ka7zX(1?Z8qdZ&A*SHpNj^m*{LHhBo};f>tlR3qY2-+69GxH5C(^P9 z*vmY(q_0`*Ie!)44EtO-fPub}s)DeqJf{y|&uyUF1kv&oz(BVW&>8lvXJ1=hfzxPs z4nPFD66}E*UVzhBBK=Sb!Wz0V>^?JD@&Wusyk!aC>t5d0?$Eu$w){F<5g9jE1 z6)ot-uz%UV0|Ofy62L142G1;);=Z9QkF$M)=60#940 zU)7qg6Q9$Fp@)Kf>hp-LK>8dZ^iZ%f76spj$bTyiC*eN8go2$hSkcN$scLN=O#l=M zw)G)*s5Ar#P|3lTNOcPdJvrD?$(%u;rwCgtT{#8lF~FA2504glEU?8ZAYz0b6KpRf zCow^f4Ys!$pBSLW2-|m2RWRtW!UphJ0gk^EyfkO?rHRi%EPQ5j;e(|;Hm_!L^9tLu zIDdec%>xJ=u_+$0;SgEz5E*F_%4rfv1X4@{LaLi`svD9y6_YuUuB@D{jD&psgnX2o zXqB9xs7kr03T1=(WrHY;RW6K0>9=y}H<}wLH#b204(0Y8Xi%fspvJNV)8Q!N3AJF# zF>L)7Ob$)Py4(M4~-&~8%3fOYJgU#X!fhz>=*5< z1GKY7!}b6T+Y`K!V8tQRVC<8vb|t}3Fx!b-x>0b*I2e9GHk^DB2xft=T)9c$TA4M= z1z7f-{o3SfL?b^u&zB6HBye$3jn8Q>ChU#0d6g~Z>wkYW7#|^4_@JfE+tFoT{wU%? pI@~r0;1GZVI0WDT4gt8negl8yUEJRibU*+A002ovPDHLkV1n?n{!st` literal 15766 zcmeI3dt4J&7RSe66k=h0@Di=WP+KcaCc`5kV~9dPff}Vq7m$a0(b#00)8~&-l2QB_7S-D1wV8ry5fgOHdV|6)4rjDokL}l9U>Pqzf#hQk9PxxvQ{TTo=i^`p)}2F0PK` zrGzVl3Q~^c;c-QJY8l&xH|*L;?##;E)hLrQjP1bw;Iy zuQLR>g4~M}gBetMoHXKuj_Zi4TtyTZBY8YWqQPt6zO>|EBAsD?9YqngC`lL*2;tG3 z)T%)rvOuqKE={e1F%720bVdW^hm7h+<`G81kVlM>a&UUg#8gcbiox8Yu2-uaHMPMQ zYoZVgARX1ykX%S&a1v%93iK*0)?|Eb$&fu3XNYt5B+NodfBkQh20(sMtfHuo$HglTpnWMztYd zC`v|zXs8$sLxP0}Dii`iT*?tK6oeYjDI6_E1d0rc0Vqetpf-2q*_z3Y8NYLQgFVlZ8s*(S`vpXPcq%I)hQEQ(^HjGHO78 z<7zZaBo>DYbHe#pgi6H^6N(VN62sK|2&F_6Aq-QgMdBPMM1=x$zb|wQp(=1}m4VRe zKN%Wuzc2JMJx(2SN)4cKtp3lY7$wYosp4=0)trSu(^9SLJjj+~Yle^Bo6z9S1Bq1X z4VYuQMe^?Lx4{!^@PKmoIJYgTR5^|^naZ&nFtrpOHafJdLC*m<{QoVWD?Z>pb`EnM zru(A}&Ayw|uZirbU;;=(=c#woQvjUHQTGT!n{@cC+4;*FnX z)R(qA%}USwO1p-L!t+`i$%D^D2gl7hKSw+JA)jxb-KO>T+hyJ8*SYuR`VXi3zfri$ z(0uj0_{P2khMHq%Up{!wqL?z5WY@@xgUJUu8O8s#wi)=E62!JgC!2V-y6)~>K*~|GpnKPV1ZAH?HsWivCxp+CA)Yap%PE+OL(9JcE&u)>I)W7tp_595+wsB%Vo|AbLV|#s(E8=?eMAw=xto5~Dk^EXX zJ7`0t-zM#YW!Glfj(Ugj+>6-l?_5tvvfIYjKG`&xxagxy|2XG^&4-TW-}Pvjb}M;3 z^mcLQdB0u(DYA*@vmTqSYEH|)dgXgbbN%5>LB)4Ewe}P{(*6AP7Z0=Vb{b0l75^Wc zC1!W_24`1x29+85+mf;_m8SFtkd>!)N7}c)dBR-1C;qtiBfmYnu=@k+uMZdR@NNlG z9)-%>jG2><++bZi1U((i?J0gC^q;IEUHjcNzszz!8;Rs8_FMXprYzIvEBaeiGt%9f zp})y*^lXXjpG}^;B#b*%ZsRv~xTW2M0{z^7Q%pWo^6Wkz(-wv7$Xe@yY3_TyH*HcK zD7W(KE~Rno%f_=hCvEw-+&YVszWU6xz-K0&k2twe{L1y>YcK4af%kao11p**VcQP< z5_Wac#+pU`I|FVdydrp=m3Cv@*&8}dz+!EeUbGk&*-D< z{#nB9^S4TUNd5eeH?1JK2rB0q?eUcQrk5YBlTSuG56#*p7r__|%5%scD}-#3_%@ zo1NGc&E*#aXI!p2v6uavq%Na@YzQG6?Dt)35(aBKpE$m5v*=a4I!ci}sp|3D8_!huE|Ghge(_zB_4AQ!$bPq#6KB4c zwd(Mv?Z^jvN`Aib&79pOk&b`U?Am_^TtC~PR-AlmTh_~>qK>(5oLE%a!KsT5PS*CO z*MD>L_?tB?%`0XcPswZlt|?{elGx;cuBWi&mv@YRs-z)KoYja-ePT`RjR}&K)yG?= z8@5!W)MzGH1-Do1YOtyMe7kr2fIsxvnVyn6o^F9qV8fF5&*7!J*)q25&i*{RZ+BV# ztlo9=GRwwYRV6=?<(X45-B7vtpkUv7%}WEXeJttuaze&p3oCjvE5(j_*R$FxZ9aX) cfp@(i|MjW-`cLY%i?EnA( diff --git a/src/qt/res/icons/tx_inout.png b/src/qt/res/icons/tx_inout.png index cecd332ad1f6e461b217e30ff7d442556d851b8d..0a6e72a898966855e4c8ffa565c2298370e5ba8b 100644 GIT binary patch delta 1639 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 diff --git a/src/qt/res/icons/tx_input.png b/src/qt/res/icons/tx_input.png index 1b4cfd967cde489f11b093babc41f3bc88eb92b2..9e9ee92932c47eec1e34719cc090f2a76f28964e 100644 GIT binary patch delta 1768 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 R)0iA` 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 diff --git a/src/qt/res/icons/tx_output.png b/src/qt/res/icons/tx_output.png index 06d9d0adf27d7db1916b50e9bac7e57c60644dfc..6f66ab654791acecf1f24d5b95335155dfbd7852 100644 GIT binary patch literal 1771 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 diff --git a/src/qt/res/movies/spinner-001.png b/src/qt/res/movies/spinner-001.png index 4f6f9a487ba8f1714ad603c796a7efeafef0ca3d..d167f20541f8a33511136d109a9ff016f6ea338b 100644 GIT binary patch delta 2366 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 P00000NkvXXu0mjfWUPxF delta 2768 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 diff --git a/src/qt/res/movies/spinner-005.png b/src/qt/res/movies/spinner-005.png index cbdb5b5797524681c75a77b0990eee68675bf499..5d6f41e0dc04e99328c248c45e16ec8f391128bb 100644 GIT binary patch delta 2294 zcmV&7IK}$;lu@bcyv}p?{O9^Sbwl!!GZ+~7A#n>V8Ma~ z!?3sd+k+9qY?hM21B7=^vUWhlj*VdKfTH6W!K9H#Jq>uMpn#$D>JHQtY^V&NKaY^e z6Ff~aX*|mlJWV1~i6WdJRL#$GFpq!YY1Q^I5?fbNbYNpRv81t{J)EQp54F_MKph@D zG~nSX|Kb4ekbglUvDgXf^r>Nd)P|-953hC=Q3Z(MVfIi=EjKz0tYd5BCMVcN8UuVT zM3q@w>+s)a8Qv8%Be{c>9N?-3g6-Q44)Ydq4E8!l&j|kO8%76ut5KQ521<2MY~3zW z!ea~(_VJS7`<2WJ>`YGOZEC4CNVBQcvYi=(cCh=`g?}?TR@eTm3nO@z!%`^zztvIA zVkWie#YwK@;9DiQ14DB;hxyI~nx5uk=r@dP z?#a!5!8eNNZ9d8G@i(eXBiYohvz{>k453W$`TOR}z#nkLj{!GQM>UPqa+zwsUQZQy z3W?Sfel+dVYn3vei4xS{5cxLek_cMzmo@X6}9N~^I`c?__AF zDdxwF)99mw^K+I_-pMnoga(mf){Lse@vhHB+keO_JWhz8n?x`Vu$=3f%%QbxOg76# zgZZ=1uFo)y2%XP%GMjvXaQ8LK31$&p=~JhEKpze6mhZhh*$<-U%n^V#X0~&DTW>vw zSSqE{5ax1`dQC)6G0L1}`zNn7OL$bb)khG8o8E-t1XP?PQlQCNOS#h=x#z9Ja^iKm z>3<3QmMx;xJ}ohxLKP`}nwOP!|Z#2$k? zf{^GkFP$A@s4m-7nINR;Puq!8Hc>Zwy-0(3y5H&_3`_n^@^#Tqy*Oj}4AA++KI9uF zx?DC<2d~l~=;+@J(*4YEJ~8aAE|x6-V}JNss7q1}*hp^*4aXo-<;n#o^SL7E=%k@j zOd-V}(Q0PPozY<47ajty7_<;K?;0Xn$yB*B+E=*9ZZgxb<=;s@HM)s@%{_80bc`@s zQ^5BnguU(jjF-q|Kc91iaw@2%R-@7_Gq4qUakND$WsSsTVU_Zv&mh^11?~A(VYWPjDbT z3}KWAh;Hp3)dO;gzAYfS%*=RdSAXHT4x7;_^P+EE3AKZRypA3Tg$VLF-JIRJ%8D+u zPbW?y)lB#V>JtT5T#3&t%AxzHn5i*(up;50W0#)F2Ck72T#jx@ptC;O!MhQ zPP^#BG2(jSb{N|s&U=H^vPFG&zzV@xUfA=9I)pjAuNc@ks=7@)UimeLK?t-1a%4?zT*PtI7ty7lE-F#PbMk+glSAF)6!}UVqrIHG4N?oIb}lL_-n--a=eEVg%|ncp-oKCh7Bg^KUGk@FOh$$vQdY6!ZhB=9_EJGpau znH(mY7p-yeobcWLnk)@B2G5gEDhUiB6c-La#nv2k2&Eq*m`^%;g~dJXYs7X-ap8SH zRBC#G5rk+K`!$@Vm^@aI#S&JrluXuXezDcut-g&M!(OH=O})=|NRKtxnSg%R@NmOGnHQu)|4npG5% z6sT0daiKrrY&GZo$7wC;-~63~a`9Tx9aP4C>rZMd06IxmvLmz<)4E7VfSWvVzsB}dp#HYrSJ z0AbM8C2x0=$!()&_A*EFkQ7uPgfQHUCY~wW&)tmYL1G!t1XO~%Q$^vutfZ0~)NqA2 zbcecbk+(s2ts`_Xnb{;UAy7Zp(Unl3Yk&00f&~i}ELgB$!GZ+~7J5GZ2dO4okX%m7 Q4*&oF07*qoM6N<$g1oU?a{vGU delta 2721 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 Y52*c*sDI-w_(cGYcE@e++V~~^1CvJU-2eap diff --git a/src/qt/res/movies/spinner-006.png b/src/qt/res/movies/spinner-006.png index 55d4540c92f09c5b270ae22bbc9152ffc79fe5c7..c1f7d18899b406723aa1320256b4f687bbaa60c8 100644 GIT binary patch delta 2293 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 Z!`Cb9{|D;dTv|K|07N_qS7+=J{cle~-aG&R diff --git a/src/qt/res/movies/spinner-007.png b/src/qt/res/movies/spinner-007.png index b25f59a445b8c20f81780e707bc0df6ae3aba250..1e794b26262243c76c05f068c47a3c4d10bff53c 100644 GIT binary patch delta 2272 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 JYE3-i{sm;iw}t=! diff --git a/src/qt/res/movies/spinner-009.png b/src/qt/res/movies/spinner-009.png index 938c49f9d30b3d58c401b7cbc90ebe4dd83d9389..18fc3a7d16d21f082aabac4db2b4dcb0fe8e56e6 100644 GIT binary patch delta 1795 zcmV+e2mJV&5Rwj%BYy_jNklF9^ zJ(|xtwc^Pjn^hFBm!q7gnmVp0=guD}sEK8u^9U#75V+T*4j2n88#_F5RL9Gm&-tX9;G20QKyk zZ!}=0QbdEv$;RyDbd({^Pe6waRoqWAbyRYaLwwCKE>VjgzhUSLOvURQW)F_&0ygpo z8<^U`5b%)1U=~nBm7!I)nzx)X6+OJGQ^hJ)GmIFWa(@zdfjr7-(n0-~dCq`(DU;5Z zU+}aE3nzg^ROr08N-~@Pjn$lMn>ffg-InaAWL9uhI&M#q?nKwUF04!)>**eLnQ7!n z7pw0{vA^q<2r5#;+jNPj+&EsYHUaC!T}BYYnpYK&Y+I&uwFl!dw(s&bOJSo&ozwv1S>I}Kz*F6LSNw& zRbMcY^BU8;m8c%Pcteh+@`bh7XfS`+m{y{ul1UzUWRlu$nGtQwuLw?T#QDRP(&ONtqwk^b74=S;eo z)u4KrqFH_rwNmh`Oo|yGz!dSm%3N!zMIEZS)efST3ZC53!Spj!O>3$|O_2DCYRG1* zpz}7+hsBzh0j`Uzr{Q5^szO~VIYzGKw14pb1>BeTmzJu=RD+s8vBZfj_T@j2948ld zY|qFs)u8s0qMAE3FQ%6@n4wF&lc++>K~l^I8U<;iE{t%bMvf}PjAx%DOF5qkzx0x% zD%T=DxQz@|i0NU5&>jh*glDMMxS=-|Y=1`$5U>Ul zysXxk_3Xd4){EWjwgwX*MR@uVAV8_n0_;KfIhCD(d% z)m3OX1Q(ihir?`-wsQ?XH`&ee_M^V2dGoS?LS^?ZW65lH!d=BHc7w*TS<~k9b6ANv zpTNovfkKyg!fwbzjR!r)>tS3Tj%O~vX_i{%OgPAV?&-vp9cQMAxH2yz*e8usEOaK+GM1Gg?ibNK zT*mv1)WwZwJR2nkf5Fp&={Te=d}Jsht%*w%Fq3o=L)yegU*@rmtADx?FO7Uj9F8fD ztdKh-@^~~qcd6h9N+{(tRWum%?lrKT-Z&~Rlc@+J;@8Zl@3S^K0%iwu#B}_i@pPLv zo$R#jmCBBYGDSVV%htZGJKg5LSiqx0Erjf}WZkzlGk(=yfcIW%W6c35KL_QaF z&4MP%`HaaVbnc)0iD3vcSu lxpL*ol`B`ST)FBz`XA7USpC9_)(rpv002ovPDHLkV1hixYJ30y delta 2062 zcmZ{lc{J1u8^?b_8v8bdhC7sPkQrN+x{Q5qj6tF>8FMWWhUj9%U?`Dw8blflvW$== zSA;C1D@&p*HI~R0$}-7y&w2lN-#^|zp7VXa=RBYPo^w7Kf>h!3Gem$3kF-Mq03(g> zrx!N>0MP4}XgdJ7Ee`;(@c^)Qc$7;35C#W;WlsRmrvSjIpbU?0^P}5iSQ`sd0H{bk zqjA(gH!WR50l;eb-{GK}rR)L#57f#OiHVq8&5sNKn?YV1vaboja@FeHK~hCzGUX;Q z!A%4cCkw&KnVX4#O*(&r%1Xq=N}yz=IL}_ulYgRosV;t^7qj`(j~SRfCphLm5Ft+c142umX2*KHPRgJ3_~@F*!$DR4-q5guC*kZ$VQC5Zj{21>@qHmb z6ijQu(0N2>Ril+*KH(}2oe3H`(aN3Zj+3c!&(7=C%&4h-({`hJXZ&|RahFVH)5~ow zYCs*od9X2pbotB9ibDTqAG)GMf*hqj)$N+-=1NYg-pW$W z(&{sG;we2ve^qV?BZgn!3*u9Ycx<)C@1wX!T!fi_eL0#+?Ry@#c^Z|(i`P^UKY9ZT z4CB|GM#T5xa76{xcEN@McvR!nWM9!It&lAmr)@M{q{nKY#^j<(Q#dBs7pq}^p(eyR z@3sTms%$ch&cp2jQ-zCdk2vP(JA{feiYu8unML2;pZ8OntzxWzWQd&@pN;$*_ zHCuN#w!VK%UnuvvA831#uD62XVstZp<_)u1E0$H4b||+|21*VEG+l!)vjRS^T1Q1u z36vceBFLIIt`Qf09Sq^p@{QI_gg7V^3^^YwkV64=IbC9&r5)a9jaOAr4 ztFP9MIxT`RrD?D(u6TKC+b;?$Ju^hvv{kgDz2Ax0(j-_1>BQG;iZHl3aFug&7lZ9L zQ~MOKNJrbkDV1GZq>d~{2_u;gq|&G|W!fsg(;d)8tS2xgF6Pz5pc-)W;{2^GWbll} z_ifP_K3j5K{$a*+Eyv)RaJRpxZB09Mpphn^Yf-;8_bkaT88k$lPi>GQUKiTYY4wA< zUEW^n*{PMb$(x(0Bx^<{_$5yay)52lA@@-|X%I`$`6)Y)t8!$`NM?xJURY5z%c?xy zruMELWvkI1BHHOwXWW5sOa(EGF7pR_ zuEsoB2(?7q-AzTDV~_oK3ht54-9N1UvEah($G!EnY;K9pS7`P5n+I1gJm~BqnBI^- zx2L5egxAb2q?O1Bbh0}g-5u>o*CAfT@u4`8<8>C1_6#M;lbnaD*1YZHpBoO-p6T*| zI%izVF7Ik0nu&cRD4gR8qyJrU{gq$Xi(<+&J9L5R5>rbj^v!0M&Al{k5kZTP5lCG` zjuW9itS0$RpLV~}yy&VDwD3aSlSdK;6pIoA)U6bFj_BzI>c<)VX7+KFD?N86{(^)@ z#SFz%e3pNn>RhPL=>Fau7`&eZ>L9>0=Ha>R+T;HDg+xh+7R8cV)nP?Bmr3s!!?UK+aT5vIS_S=XVXGinoUVEgc6mj%ZDM&#(MJ@l)YX_)FlQFyU8u~*xsko zfBi)KZ&PI@?f)h`v{3Gr-n81-GwvVWRKD&2 diff --git a/src/qt/res/movies/spinner-010.png b/src/qt/res/movies/spinner-010.png index 7eb645eda5fc300f16c8d5e398204c8a8ed4fb0c..a79c845fe828742ad38f8418179b6e2987a968ba 100644 GIT binary patch delta 2294 zcmV+iLIS1q_p>cD;Yc^nrGbU^bqOxrl zF`b$foDrMGWz9}U?(0U2OvZXNZ;iWB+G?2Vt zm}md+fah?Y_dV}9@B6}G=lwo^9(aGx_qqJ;5124v!h{JECVxzrFk!-k2@@u|G$cSG zh+f3gok3(Vk`!W){+~#O5XB%0c#RU)v!6yTae^xLv6p?k&w8FEoye}eiveU%z*a8P z%um?e#w~7Q$IcbLU=wo~LtnzW7ELSh%wQ+S1oXt?C+hi(_2kp1>(K1O)6{ZZHA&ae zzM97Ay>9BmdP%vvt(4gx*;FPx(Z%h_CrsCz`j% z_bedDzsyh!rCigM(6=EKX!G9 zipd`4C||LK7b#>j`>EzX)Np|ts;K_J^K|cgq7xME=YLI_C}S3*=?R1pPB+JY#gaxo z8#twkY71?8z92HLP2GtZXn5Z^#V#5^ABsOu*1J!f<7F*{M4dx$$i5+JJiAXAJ zp+q+ZFpEl>6{#NM;m-D%vN_>0rJvbAmY0)~2qu@^inh3#*naxRuuv#86cu~8vTEQkK8%0&(9yYmH%boN$*fERZ z6`blA@2bavw zRi+!B?g*tqM*2fq9YPy-k;fTTQN>|~8|;5t8Odd#?6sO46M{)*jmN#bGu|fF@IC#b zP=E4i;DeB#>_2*Oe5Y$BI*&^(-(17pZJCGd0+|(R z9l=mGD(=#U{Jx!NyJGTcxTd=qL%rKK7dvjDM7bcpf1C%@eLRLY6!POMi6u>_rhi&w z{%142G1SoON1+zY_1f3iq;>Q;xb;9e-meIITpXAdzyO#|dH~SA^55Wt5LZo& z@hTa}5<$3jwk@F(z$o5nr>?HC-1&4_h-3mUQOvW9bvxTdf?8P%BY-H%gnxC;2B!KP z3Fq^J4AnKPra_=EM>%S9bA_d@uee|23Wf+oKO+>Ih=fEsH8QckuLdTJ5`_j1(Xu80 z!+1-!beX44V+4>bj6ri9?%GVjD%WW!8c5vdsN#r}lBg9cfysQSVB2%lCcCo*RIc%- zHuLnR+d7wM3dAks@~vtY<$p&u%V>($F;1K9?QC%5$|d62;t5 z|Lqc`(yw(yt1skzA^1R<)A5X9Cc8MoS&mXje;pDl(d^bG(75QTbv+%Wg90T`OOlHU zNntEm#9+}S{b^wgU+X~gd2jO0L9ElF&3rz-^F7=>&rNod)rWAmMSo5eeyGAwq7u8E8*Nirt9(1^;j3;ObjYI|DAc&%-(-GnVu zcFvP-@SX-TUX`D8k$)2UYA<(54^gv(}$4jEnywy{i*eQstKSy=UN1A0)V z@@!`Z0}XC54WZo4lq`43ag2Zp_X`!W@?y5i1F_x`msg9DLcg+O$FfyQh14- zyv1||x$T)m8ik~H)cd9+{;gouzM+UDpPYz5hO>&Mw$w-!8E#Z9*gEnJ%n+H!0@iH5En=-cXAqS|U zl=)00pDe<3d!^_{cep15NhT7o5z^I;sRwK!I1VB QL;wH)07*qoM6N<$g3wE7hX4Qo delta 2658 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 M+Q!-XzGWcsUySy^RR910 diff --git a/src/qt/res/movies/spinner-011.png b/src/qt/res/movies/spinner-011.png index fd4b63ca5aaa41c74f589827f2fbc875bcfaa3c8..57baf66895fd37dc05524402200845b504d9646d 100644 GIT binary patch delta 2328 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 diff --git a/src/qt/res/movies/spinner-012.png b/src/qt/res/movies/spinner-012.png index 10d26a3a53f37627768acbf534eab679c87984ae..9deae7853a77be114675325338015003f0df20d4 100644 GIT binary patch delta 2342 zcmV+>3EB3H7O)bKBYz0@Nklll1BURBNCa9^q>zwOQVGR` zRYVe~W{H@UfjRp$Qh5kfV7W@0Gz#J2BBDGa5F!ch zXC5&9kZGLE?3vumJp&2r{?E6}tl4+pv-duG|Mxxt6DCZUFn?jfgb5QSOqeiX!o+O? z8#e4%X^)L?G$ODO4rsTBdUovCiDW2an8RxnvXQr0$DjEt1-!@%de9pyT3c4wN(2wH zgw>RCh#H(;s}?8c_y>hN!C>Ors-jt}my+)52ph?z zbK6pNSBuqbSbtTN@k?y2)f+uAhI0Wb>f}03j*#A(6m(#tJ0nQ;_`8J+&Ihb$!}^Ms z>D3x`Fp5MT<4=6X1=bMd@r|)uH>jwSO8!DRp|?iG2qNfD28-CiNork>bc}e9?I(hVcZ29Pkrh z7IJQnQMl;U!{JCyC*N(wEWXQOpUh=`^s@BnnA` zjWE7TSAV(@jwT#JU?+y2EahA?dwY#}Di!TWGBer4VJ^1Nlj_LvlO;80JHTzfL7%fo&86OloNa-Z=NbtdHLU1W#wblXXZZ+BmzWy3pGL9P zr|(^)gb#F_tT*_zm=pwx9<1^qX+MJkHD5aec$c~+KX-+L6fle7bZ3gLvTH4OD9zF$ z`G30)NqK?qsg*RAQ$#HlRI--&WY7&e8Wuv?qRV(I7@#=k&h}9QZS$&tTZB#wA&FGt z2*u&XwWjFw(i$cxC)pN@LFpV5RJe(!S!~uFkQN#V{UQc(K$NsfJ@=5xVV@+Hw@Jk) zmL9^aMkd33l_^O%n^cvHxF85R$XCK&&wrAnyf%(whZy6hsAV4d@Sf<6^I0d9<8@3` zu4o9ai5B&~${26qF7X5{V>H=fn0QsW?>I;kV{bVFRf?G=s8i2JSh$Z0L3}B(%J;OL zc)VTVL3N=oj69L#m<-%Wk(i);KL{Mwv!e0NCQO~_z9SkI}-QL-4*J>5wWC z)XoE;tP~`j;s>e(Jn2!dfOq$h`;&xDXAcr?O$W_YOL6*S@gkdb?J$AE#r}##b9UUpQmVc_s zWabDyTIt0N#gfDb5{WicBRWW@vQf%O@)_XvLNf&0swLBKf54R&WrD)F<0_jt82>Z%PlzZ0mLWY;Uz$P{X&S{_#O$}K+XhPgqQEND-a zAn65Hu(9%#73o)b;x(I6=LE0J!? z$BvC5VsGfTDp{jx;sNu9(&j@$Tul`_XhlS0Wtm9CO;<^-ju11FauR~zr8`9Se<(3j zi%qRGmE!xcQ)B_BE1$r$i=~*8$I0WYNYE)Q@U1Kmr;OIAtL__5?SGjfKlL%|eKeY) z)IPu{@u#- zT=AY-`GZb1FY~O2*@qBKh)~D22nm#n;)=Liv6oKLF&Ws}^uO?PH#i;y>NTILsNZNnN8U=Xza} zhl^Ooe|-#dTwqGz(IeW&p5EXS#wx63G@jS#qy9eqFz~5uD?`NU!ikgZ^i!zlIL;Uz z1gc?R;CreuSB$+4(_EvJDH_eEh7~=_I3thH)8{Nh4exNTqJN{t!P^RU)Zjh0k$#3u zcQHbVsy08vaeCKkqf?3P$@eSZ6(f_Ejh2(*MtTNzuVT3IL$4F7{a&^zX1rllBSkhr z@7l>@DykZdBsTaNm%GNN6fo4F@#Y7h;AIZ8fqC>-cc>3yPcyUFm8_;8;eO9oE8#v2 z%)$(v_f8u!?tkNKX9+pPV^hQ1fBhiwtk)4R-rz_4kO)Gs5{iZm4F@*v;X6!XKCe>1 zGj#QO9U235UHGb^l$FdRnJ~2AT%NY^kgoaOYaHhU%UDD%3z*AuEMzk~IqfzJc2T%U z63$jXzj~hi6q3sr?m)vD?Azgql(xXUoYc9lI7>T|_#g3c zAI)Ek*}5ZeU&AN+a$h+x7?1lD5 zgaDCS{kVID4>TZlzyKuR2P?ij3n^HJ#T4%fZL(2>vd-B}9p#qWKOqC26aU)tA( zhYW%=FE+S!#_|Y=ssCpY<~^|ReH|lcBzc`XU|ta_qi5nx_5Y!OjuD9#Wv2IYTcP5K zF1A$t^{l6z}aQ~ zRPDTVRc6If$Ox&KR~(XnEb8sPaSMhB(JfBeoiHykz|LO~GKxe=VEE4>^W4`LIW_JU z9^*?RHH1zYTkFbwJ^MnAXOvi+h8*(Z=7AH08o?=1 zO59R?VOP48KAh&X$ZAR3-S7e5QF}Qy#7hu9`-W--3EERC3Q$Ro**`atE8Q#Z-W^zQ zFTXgKJRBIy8*FUn`3L+xAJu!Q%L)WZhIMl;WmuEI^W^BFAZ_fDo5`n5Mkh44X6a+5@3G;GBtDsfoWK|{1mz9@&fEL> zzG%zarm4b;RofxK68ZRodkM!raiDeQ?!6gi#k^SFF@1MK-Myi6xPqK?rV?L2C&sW5 zFZ2we4(uhxX62+nKYn}Lla;S{dTGaf`J^@S(>A-T&>Svs_OfWuedeAE8I?Y=vRZZW z&&wpEPhlDEb@!gMn<)R?hoCN*fZ1>PG}@%wH=b>wzXX7_1gG7^qdX<{^+y|6OT}ZV zzHX&8SoaWaxfMi?Rjo`HnDitK-yB%-ojzr38MNSD(T~+}6{iu@)L!#-B-ZwrdJP`r z@^j?=QeMoM7&~ZodYCj_@oO+bp@)5m1Eb53W>8(-)J$R{#3q^49ZH;~NBOe^62`D6 z08kQ@9jF#txawRk8Rn>H7%S|qxAo2RG&fff+>ejxIHH27Z8UcZb4r@pY%oiE@7RyS zgvs2meJo?SvR-~BE%m}XS!gLoq!~GT{H)?ZO$C0h$0uld-gJ|IYmpx*HFHpNauyB6G^JCI8}Qvn`Bad|63!`OEb$)K9+3C5xe2v9k=?x?I?{A3G7$iHF#PxpaORVM29 zeWh{3d}E#9^DUTUhjCn+BOVpf+0H4w9Nu@1rcwEpTT3SxwA~bMq5vt4wBmz?Y&Uj0 z)qM%|YZ-tCsyR})j4W*7YFJr$TNqhOL)FxN-8K}jMZ6y)erc0fzNM9bDw+hBrNecb zMgWKGegYHUXRFzeCD2Bedj2(jBUcke1Yhwfbp>rw+TPo{6m?&b`e1<7RS6DwK!Q3Y z>(`AmXsrCaPmc5Wi>y0Ahz@3{)+XjP$L@3;&u~`y5i1~^R<TP;6XchsdrtIy$&x|WkKan z;P#olO&BTnGBbTCgLmW%4-vsP!Wnr1LQUYhS2oJWwV@>5vfup+d^evmKtUwYwH|HK z%W#;5gdp1rd2&TyfA8hycEscFdiL9pE1`ug>RXCQph z?f$fW?zhygD9U8xS8hWH8tKt$t+7yJKCboSbdB-VaF?dk`BIZ?EU#hvakg~*G@{Vw zJFwNFxLzJ&ubra|t~5{i^#@M&br<7rmu}Hnqql{Ba6!^xAX6$tFRv|;ks896fR;Di}n9h*9$ASVK2hS@qY`qX=hi} zLLbg%5D7{)GwR5F`RX9dWq4c?O3nENr?xN3%-X1Bt={rDg%^^CB= zDaw9hbhzYAz257`pCskim8ZCfP}lM+wMis-Ga-MjIV;6Hk4jXW4;mMcX~Nd6h$otg z%;@})7ynZu(mQ483H!UJticfL!Xa%f5;E)^InNDb z6$a~QAzwd^En&0Y0>4>_oyI;vOWV*230mQHL^SK`t&U-Ets?PGys!vWb2;sqm2)2X zQM8t>+#gu$l{i}WDtMMQ)p3byq!k>;H1>m)P7X1cdTk2pNn`OvY<>1On&XN!9p{ABe6wNgQ=CRfRcWv`2;GDipi2a9_PKcci z^+o%XEw$K9H?n?jriM<>3a4-K-jqnSxHZkD{q+IXdsCfWb3%@seQRgFJ5faF)}cPX zBNjdnvoiHto3J|5$J53J$(PM!xA^5>aS5_FPF@4+7lzA*8d-xKsY2wBu2xTu__xyLN>Yn!;EQ-Zr7g+ke z-_R+(aV|3v^m(ig1eY9MQTGx~{Bihr%ik{pC-AR&-%$`8b zR8(Y~lD=CCGkiWl&r_w3rpQEjTqsdZR)oht%nZ+@jMuP|tZhY7ivltst%1Vz=+V(L z`s=M7m>x5m-(<#xqi@nK2}(w}T<_B8WuGjj)%%EPop!MB*pAZIhV^fOl?(T3abV80ceZf=aY_!1xJ-pDcJI2u%~;l zm*G{i*AV~|0*Tf@A~g^?L=@5xt!s$XQ$rvP5s2C3jVu2Z@b&k+P73?~fyeKi=8pn^ MttAfo$lNXV-)UD7@&Et; diff --git a/src/qt/res/movies/spinner-013.png b/src/qt/res/movies/spinner-013.png index 863a9d29082b50f458161296f2e830279241b233..0659d48decf354c0e224c2903526b64bf1757eec 100644 GIT binary patch delta 2367 zcmV-F3BdNy7ReHjBYz1HNkl=bRi$Z95iK3v>K?$i4EaHPfrBi7wBBP^ykoZCwL?Be5rBM_NF}x8I5=bD) zCfh$;x7pp_-Q3NdiW@t}$hHw{IWRgP`calRo1Bt;wBzPv^{~Q)>VhsnVq?T$fP)jXtTzt#d z6!97}m_jmFUHUWtB8bF-g$Uu>^x-JyaR(Xoe93D}p&e0|1|=(C$B6?gcA~kGt|T*< zQH*64ODSZ20DsYFwg)Bo{cz!?h{arYamm`S0ZwAD;~<(&B-4uwvdQIso@5Pw;2ri+ zN(JYr^M0`n#Q9138OL-H{ccoKNj|p_b1_K9(20JGCy&|W^9q|Nrj)NaLJf^H&>ZAN z-zULu!ls2l^ZW4;^GPzAW)G&Zn+jaGgHn>mKDzlxvw!kP8>G0Y;AMVnB+W#g3TdhN zkI(7rC-GL!wMo)h_V6pCXhtxN@-S$+IZRr>3fb94SuSc=W7O{45Ee~07Z?^GbtJW6 zNc=FsyeU9mJ`a;<16cu5?PRcv3Yw|+OhzLvF6fq6M0eFhyRkQHqQ4*_K(3V-GRfhW z#+hp%Mk{i?`Ze~%NBx_<`X{2>>`SMzBY)^L&rrKl<4I)_cXJO}44^m3bR-HV zDZHVB=zFvaLw6jj*{}Icw=-0I=oN|8Ckqh8TwP1|V>*YaeJ+P+(vY4X)->uu8jZS$ zeo9K%x@Ky+jm=CqmS#LVbQ+_hT&F4A65e0OoRCx9`rJ32j z8Zq(+h4Z?edsR(&mS6&!xYxiWTm*4A0$$(37$MW^Vtg$b`? zk}5mjlg|VNJGesmlD*c?$ve%W7R4$X`J!7tT-6ICh+SV_`YkLKCw5@Ccf3WWFP5#s zd+b#g4o2{-nExB9_<-pnq<>4!GufLgktci??bT%f=V+Ag)gndA9Iy1+f{|j0c(ux` zkz9pV-TiaD*xj_=;|@f#NVNWssx%Teh_6s3bQ6VxUSjcgqo)??6nE$uvQ%3CIB|E> zGh68{ZAXdNKzStqQ^m}3m6GzL7cs06cj?Ua)GK;R(D4O*v68}3vHCJwwa=2sJK{IpqVP1eiP^-%3;^C0wU;S(TCkHV_U)Zy zMw=UL0*O8$XgJRx=7?6mi3f}b6>k(PEN=GGQyEdIeYuuGjh4L%#u*b=EYYZV7n7*y z7|Rnf2+e$^(Xdx!RDVRArO{1L!4xIS*UC82C6JrcPx2F^h&p*rsO)m34e1`8=1)On>~iP7n)2n`>} zjf?$E3{!dsoxR`N0&)sg)kG}}(`=J#XEVi|W66|#e7{h_=mq?7$CT|0P-6-;FeDP)krK!$NM*J>;oYVgqF;W4v*7+kboxwvp^9hWQ*s7J7;el={aC z<6M1!95(BYJAB9Een-&N8sUBL(M&V-lv2PIMptcb}XM-|8Tihr?q59@TN2Ql8OfvkmGvxR0l(%hhA@a!I?#?-?AVCJ ziWLi&z|V~&(1#}}(Q$eGD2s&X$bthKHV>go`qxt|Sm@6vR`48qIDpH?+iCJF%VPD( z=N|^&{m@7vN&K9tJk8@QWGRbzj3wleOVUN}Q#dmG`+^-iQ68gV;WGUVBNHY}m@r|& lgb5QSOqeiX!o=l|{{pV_T(h>%{+|E<002ovPDHLkV1kygg2?~? literal 2896 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 S=_^qH00001aRa4 literal 2867 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 N002ovPDHLkV1lN2j_Uvb delta 2854 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 delta 2818 zcmV+d3;p!{5{VX&BYyw{XF*Lt006O%3;baP0000WV@Og>004R=004l4008;_004mL z004C`008P>0026e000+nl3&F}00002VoOIv0063uBQgL0010qNS#tmYNzwoSNzwtR zMT+EU4bpg)Z3+cKP8V6)5|s*rSnec`wOrGt`jX!@yV=4dmA`OC zi{=Ri+ke?HYvCY=exzv0Zf3WAM6E;;(>bI)Y_Bj<(1Q&+FrG1_5*c1iN`+p`WFuDt zSc=}IofpX;@E__ZrBh|$qrc2dkR&HQnTsA=KE# zPpK+a(arvKxD#(sPiz%EFpFXd&3mWv|6Te4-FX(E|05*7lqsnev;Z3>& z5iA#NaW5RMz;}uI78{;aCVur`-hOuu3U$^|U_DKP8H&|5*JEdN@K>rmq^|LJP_0KY zU9mb0x0+}i{}bQotHMd-KDKzseSaz(v;#vt=fx%NU)Itz8N+#@nQz1;KAv0-H^|hm zi2)WIu3i@o5>5)N^`<-cqd0IrAW=~wn}vMFcJ}c?&|kA2_lU>7LWWsMG=ZH$BQ-pu z)LbJlNurmPonV>Q+;?+^hLuhS15qS4|kxQGjT-STy;7xOc9`k_O#jvOJkm@~H01Shq^;H}iNAn6cIqfW@J zqQYjP5Fzv=mP^5lqJP<9r_BQw;HyRl!f%l-Y&%UNS}sUAY0GuniAHi#=t;U& zb2LS$-lQrF5haO~dgVDN)|sU`L`zBV$}_}y8)_V%`M!MF7TVYv3S8R9&1p8h^JA(IWBN@0b6DO)eG)9c@>P@Q6{$~S2SS=zbvP#!A*(2sZXzL*j5=58dL9Sc1k5*DF z=$P&RJt@KCJKQDYMsZlDu-@P+=7?9GK_~jyN_4nr=h$JLg#iw6Q5YVv47G?t92ulB zf;6QK${?9>LcWuO)_)%V=Lp8e8a}b)=xs2Cjnr_Bz09S*!ZbQs^yHnOzm+s$EEPgC z7c4L~cILfXYOG~9*@9FQuZjlO<+QbyXte0ObFwtZdQG14dWDO;EWsvsi-DEZJYjv{ z+%oZvy670xZko=1uR0Gi!9yyNx5d_v>$|S>JNY_gLaxCK?SDHj-f)m7+=NP}U88vB&zGU+vpw&nvl|HeY`cjN8cvYm#m2W+eK=FjKPE(cgQ_cEt5hQnf*9t z#YU@GLP~(^pMS{|MYQj4Zc*L)u}SfA-x2H{mLZd+ie}v`WoSUY$^_Pl_3UYg{xnG9 zeMM_$$ql8SAc}#?=*v2Gk*hsd4JJ`4ZdZS5kjV0JhkS9UFBCYKBl^DU(-~%xt`$wx zRTma@_!|Mg3OQI5-e*QBDmKpaLO~~3xmwT3yrSY>8CO#-3WcQ9ev0bLSk;F<6iC` zgT5LgK}!31Bz)H_9b~b<$3>sdyj%!TJm>cskCgT?F}(jtGP#3^6e#A_yIwP@8#@9f zS;9imi)K4w=*Az|?bX2wFT0(|v;gk(*Qe{eMt{$6Q@n{t`ZJGj8oKA?7}LDIXCnCl zlHA1D=6KipAr^6zV;o{DGwJB@)Z`bUEm2Mt5z6 z^;{;2WKCat5<~bQ?I@zcX8*bcaBvsTu_FK-shZE5WI1lssQqwL!gkhDNIR0WR@VqJ zsAdn9EsH3ClQIhUkRnXlYiU2R91i9(LVq~_`Q@gX0@m^+4wC&kbYsa6#a%QzVPGas?kn+&&@WWG+7zXo-4@2q&Mm5KCOw$lSCUe-!b%E#xG5Wg2!oWc$PqWiw^C@OT z%RI~YCL2u$o?;`VT*plftAqcsUh^IG4my&?FwSv|VjS&Iy5#qF*hqP zF*-0X-iqyC0000bbVXQnWMOn=I&E)cX=Zr diff --git a/src/qt/res/movies/spinner-017.png b/src/qt/res/movies/spinner-017.png index e2c2e2ef78d59eb31d0a9736049f1d5e42a5ffb5..f48f688db204ee4cc9b8b68cf02b36fb15ccf0ac 100644 GIT binary patch delta 2398 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⋘ZM!Cs@+aE^-`i`mlc2yyML(Yc!r6XS>z1`XFg+<%D1tI0mw)I}uv8q$fyO~I#3`iFvP#4++SNFyOYDI7 zLZ5=K#H~6S3FR8$P4?=0{EuQ)IvR3BjE1#|lvnsZDxlvAZ*s}bnc-!7R6xHJ*4-QW zCXtlRsE7*ae&J0{>3jT9;qgbK0(wGtlSBF*Um-mHTof=}VpOVe5^WJRwb}#= z`8sFu;-iTJ0nN|FLUHPNBN%3-q>8biKb6rV#Aju)rA^Dn#Q;4CS)3L%Un0Yf$Io#LC`WKqz`>`bxs(MyivrGH(#r06<4 z71pE)N(L!UK-7^F0j3Whg^Cq;oT5Rbg*WX>&$)R|+3a?jK@ni8KnE!MQmS+p4BJXy zepWWbYzVL`T4Bnj+l#Lizi%SXZVzP?Cl$)iSbCkAmTk$^!eW%gHf7i04<^#*Q^o4H z4=?G;S!0cPRVe2U6%%2%SAT>VCcI8JuZkPZ1?3mb4A5kr-|kKq<1J2_Hc()y_dbQ? zLeJ(_#T?BHv6nuL9Azt>4=)>qu0z|TD;wImgy(oz17;GBQ*L<}bFb-KRWCkkmBByB zixFeG$l_CrwpSlMj)mE&6rll6rIf?$VhQ&~h?&ZGiWDAgYu|PoeVEj`BQd z#Jq%$+CmK_Ofl)Sn}0_2a*EYV3MrcyH>izV_BxGXy~PV zhoL%ZF=~yvxlJMIvK{?Gu_0|6s>b1H38h6Y?!`?)^vZv&JrY?3|E!VQ00000NkvXX Hu0mjf_kwmM delta 2135 zcmV-d2&ng`4&xAzBYyw{XF*Lt006O%3;baP0000WV@Og>004R=004l4008;_004mL z004C`008P>0026e000+nl3&F}00002VoOIv0063uBQgL0010qNS#tmYNzwoSNzwtR zMT+o5)2u2A432NYj36Ka1hD9NmkbnXjz#s$yq8QLpc7k-FElU?FrLS-N00r8fJ8#~5 zbML&?{^#3t?mP3Fd+vJ9t%Vs`SlEDV$e!>5`W0j#PtlhmerFfeexd4CItwVr#>S?G zt@QKzh4d)M0)PI!gL(VPWw75br9*@6)@HLtwV2fivst1BSRsP?fEv*H>o!G-zw~20 zL(HP;l*M>z6m@Eo+ni8S*s27zInkU@`;qH_+N^4IFn>GN>QKL5um!aRwFUM6hnnYz z`lvqBLG5sLE8ZYo$s))Qk`zyNWF&_u(EA#C6yyQMGJlXB^q@PbfE{7dd6LQeruCgX zN9@gP_EGKNs`8bm(}BHIfS%0d5VxX6yodUj-w=_N%_o$`j97P_Ol;KFOye}Qabw!p z93$Jv#$D7(<{9=mEXks~DwyFnkgROJrphBon{wV!4ne-E4|_av*o4L$?l`e)CYY^w zoq{MZB7Y4z35uD@Tq<1Pg{kHY+xeUiIp^Ty35uD_rw#VtCBzE0Fo_OWKqebw!VC}~ znSejTO@L_;`q^9TXF8qk&TTXKHU`WfBiKSARUGC6+L;F(O^IVoo@F{|_dOpg=EwJi zG-}yPZ?l;FIq86Toh5Xs_k0E$VshG1jUqRD=znYuvom`gFpn{;!74X{^)X=v`AP7V z^|UdAnZ`Q8N|)W;$hq3Ffly36Z4zZ-+h0tI3D8-}HRdhWH*%~X^BqRda%LzoE!r#m zpo(|(?~HWfyb^P<;8aq4)D7nCk90;+@+vRr#k82GaN97eNEe=;6*DFTSgI`jkKX>b zJAZ`=!+XdUUv)*ym;gEar9@q&Zx$6`iNfd!`idni=EZ>tFq+E>o0SaH1^O`8M3W_q zQk0P6qwX=mVv@3zZ`afN23RGU3o+ZF4@_ZO9GCz}yr-B`SM#zC&~Dri&E?X;v0Psc z-ZxAXFg5D7mC6#uNPLvG-h)mNP1W#b#D9_*e8d5+lFMoa#ALgzFh{bnsb#9ym=>Ew zQwM47sQrUsRzaR*IlyWO!@nIdP(Jm{x{Bp$A3c zMCCN&VbV2>TtBF{MJ z5fQ1Ao1*SOy9oDe3XOwa6B~<%pi+%iaKkvLO{rc`sYZ+3v<%NxBHYV%Q!w@#HSf6E zK`miEX>-jN&?>=?(!Cm9Y{~?9AAjN?Kt}}KwP#wf&zUCSY`cS7`#Je8WXt7vwxN*=y;$6>b)KdJEr%PT}8ZQnc z`QGgt4HTEW`DVg*caZ3dXQOT4zFl}s>Dth1%iUg5b-q)A!8DOC@ z*)5+wabT)Idnxl$^1Kch)>mi#R2a5d8(~y*!jxUNBRdq&*DzftCV#+CE+~u_IL9ZkC;e(94AJ`2byAKjb=qi zGM~|)q{T>wlcv?oGnIRv%pxIYbCaTtM#5~E$ePL&Wh$Ocm~}$dp*FQ)ZG$Oc5s!F) znZ)C4cRY;wD>>#c0e?F36*upizrY)DV_J0M3x~8<8=KQHW-7&{WX7?I!|Y@}55|d^ z!bp}WX0-RNQl2%BSyv0{L@8&?N@masXvZ)<Nki^)LJgFlCdTy?WR$~Tx2<8 zqS{T2O1id}vRKZm5hiRklyRQ3oaHPhINDVIA+2+*-eiSOc`e3KZzSd!eI2Ofch)b> zLM^B*s7+dtP=5`a*-jKxm*2o{~g` z@C@5OZX~(fb9Oh$-o2YWzrXjM^WAgycfP;x?|06HP_<~1h=0M=O(B*Etl(wVF^e>} z!c^(UDo&xHp>dvFj3m;HK;v1>)n=GJ+eIc`_W>QlmwqrcG|EYIAJAvG6ach|*>0QD zNJ;}>YG|Ax8;_fSM)SB3sK&oZa@U-WO+aJ#i)2nuQAm`Vpbp}H(&d}( zE~iw)_Y$bj@_!RIQNXUeBmsJnLKOEv^^(Si5~xSWaMR+AqJTOH)VJNVd?Ab#T$3!{ zr%^jQIB%=vo6J8Xb6QJ&XNzc5yhNfBPcHf7^B5%*Glz#5LKeT_2MN@7=+${Bp@**g zg2}wZK0czFdNec|Y2acrl|L(isiE=P&Y(XiM3BZ)ynn?}G&IS#sBaC7arQ>zWdP%O zoo~3%4tTAtnx8orW*l?a(?NhOw%&=$*GmlduwCk2+GCB(BGy?j!^z}1zOxXd&%Pj= zaOc46#R6$W(ow4<*(vlPjfxIC9=Tm*i4%aT4CG(!+CI$M70N@cJScb=&cQagmP=?{ z;RLlDH-GtZ4zY+^LoakaOs&b`Ze%Tgpn(1i;X%eRmujvUKKC{whzK>zZYC(G`^Dh*e#Ozh-JE=``O9}DFgD7&+8nd5shP%k`#P5l|qda=4$#%<|Bix20?bI zZh!2V&F6m3s+`1N)53XNmJD_!w@T9qBXubMHTE%HH}34pdjTA4VK9LzBuTyPd%Ev9 zuUS$N&E*<0bW=+zLj=!##h_r4ghwR9{gNErCzB+MxSFZN8+>nG<_ex{VqNg4ekR+5 z!~L4s27^^87A*M<3^vtovG8*_#`s_XU4KD?aPKQIRCYY{=AV8~on!$wo9uTYr-d*0 z&EUi}H*rYVU6rYlD3v~xaT1Ms4)F$gZCH5G?3a8pk6KSIJUk%j>=Dz+1C>-pFqvV5 zx5;OQQy`%zhv;GTj@pe937hF+15HU}t+4kCOtZSH0c;j@^erVeg%NptCJD_g_J6(O zgdJ_SEu0Etxu6hB<5Po;t<9}esM#*Hv5KU>gsjXU+RAR;y`fOiXG3kQAyFt1j$soC zR&FhILM6b?%!r2p!djN^xXn7xnWC$Ldi2r$FCE@lep_;QZ7*93ac33`M;vHC;+ zbhlL_=`M5vr$QpkRS3O>MKrW8Zwfhy{W^LaPYaV5w^{S^>B7RNEp`cyetx%Ds3hlE z^Yifm;*^h(+!BJtyFoCLy$rSL=l2SKzJCaS?iRSkT~>t_Udn|8@a7Nzt$!8(-D%aa zgJ|XngWiF*!%XJC0$q5QRc=vbvH)lu(`^TuCCC$8@T7yx_)@ipBY)! z@`SYt2gtG+=vtx5@VJ$XL>%2eY-!93c*r&)7{LT#G`il}Zhum!l<4#+HUaI!dO`oEnQd)1kvt_#&7b4fwp3p#%oIAr z54qdwu5$T8IH&(HnG^GGVZ;#AhGicmDR+K_p4R)kze#i5UE44-UQ(FBN|sRA2I^KI z&^Rw}XxjDO$>VRubDWAatq zPT36#@mVGrzN9#&2(xJytmH)gEsZKks>jS0RUnLOcN(PrycGJ?q_kL#^^WMr7S0r* zX8)=|v8hTTrF^KGT)UglB~8^?ehOahW}A?u`WB#`(%yv~!i_7wndMiITuY9W+Iz^M!k}z* zuSD94pbyVUpE_fQVim*vY~l!?vWIep>%g4O$A&e43x%XSf=r>B?6c#{x2py;f7Ek-UKo#ynCciT{ z-&V)Hp`T5KXqF1)4u9LjB)>2~#Y-0++IdHtSz)@kNe5u z1rsyk)79&*e}z}taConpdqaO+jF)0bSZtNOOS%*8I#S3sv25Fatg?b$IHY-)VuA&= z#}4oqsW_-bQ)W5H)BMSK7da{P7wQM?wR*O250Os1uYXEqtRe9;YulJctdsB6Sk^)B z+rVK~GlG6Nyd@hP&63dw4UL1WX9g*RcZN&z6!LVq?hjl>qmH9|-JG)ej4F0e$$akP z&dzmJo`?Ao>7{=o#xjv{{E|Dki+;qR5C)y?N;QQ9{wkT#b4>JeUY-25IF-Rt zrRd{eOMjGhFW;$BivKFf?t)q-IeXN|9Cuws+Ec3H9b{POZ_BW*g)v&nlislYL|G_X zB*hYu>>5km1XQ6Hf0xYZQSNfncdC*v6{7#>uDj_yERyh~4bBRuJKmz$BssQxi@Sg- zqzm<=GWY#qhQh=Ep41S$6ZfHPaXje004R=004l4008;_004mL z004C`008P>0026e000+nl3&F}00002VoOIv0063uBQgL0010qNS#tmYNzwoSNzwtR zMT+dn@CFHw@PANVP0DL176fTK4154v zrqcn6Vnv7I;G=_6iq;QGZRudC6`WSIXseD=lu`kWh=hh`1T;V-yi9UKNCG zot{(OWtuS?p#b|uD6H%Q~u|AdGk?Lf}j*g;$dO9VbrIg&CQ8-I26A1`UGJk30Q?7U*lOxbb;$_90USXam zW~oE)lf_;I)sx~5zGV^19Lg0`->0+v9eS}x0U9_)3S-4(+MNb=Vt6E(Er_~Fr~1j@ zBgLE+bD!OBG)})Y=;-*VBZ(m-0)6R%L6Bn3(ZFuTh{i)EOE^L?jrIxRq=xg6z&-R} z48sUu(0_x@Kn-=o5CEE}AVt}F6|1RsP&!+n5g?0S^A4vlFlbUN(Qu`LnUQ_a_!+`% zHd8`PJLuh93h3)K88s4lguD(Cyiqm~?=_)N_=#sSA9Beyng*9yA}T8n5zRgco(s(2HftHws`)PJRcCnJHV&QLyX*YRPs)U%N&Z%JzS zm_T70R7))e^_-=cGZqJ@h!ym(L)ea(fU(TtH)LA)BdhPWZL@& ztYHVWwoOgDkis&~n9N5LC)v(CvdFw@q-#J7xqL{YN!v13(c4>!0MV@AoQbG=Sj~9! z7JsTlBaLO8FkP~{nMEKHOu%WJ4lC$cRx&8$u=kO}n^c*Qtme;=;bqXdlY%gU26=}Z zVp<&v8gVSkfz~C4QLP!F1V?99=lC`|SSkJs3t&qUuVH8O| z)5XC_XOrn%o?tl{$}=;Tam-{WiSE$!vww)Ml{)r4#e5{N*i`*&VT#fM@^c@XDdaK+ zr+Joi=hf6598}U=OFzYYWV0nK$qJqg`|g>;u@=f|BVC;~3m>IUA?%CvP#OT!!kGL` z>|u7;_s%3fYt`m5%bg^uk*?IXpM@RcNmpGe(p;`5o7gbD>U>vd_cbG&BO1+og@3qT zksG#Uy22tZU?IsS`_0c%p=BelI%n#SWUDCdH#}@2tjOZkN-{c8cip zRETHaGp3#$AHCVuqSZN;@g0l(&gFtQ!2h)8y{0u%DH6NePL_q%I(=BjIShgn@ivp% zu<+u@S8SPI*l%3;n4#!wzUAP7PJbp-_!;AgZj;W8W{$!{DWaR*Cu$1MD6E-Ic8{rm zuKZQ(y@o|r|HA6X-pMebwv5-Pbb)9ouW?MMk70(@Ent=C0PYfM_p#Xpn$W~9-lk4? z(udLZ61|%Yp>`L?T_FnfY!I_R?_wx%b`l*e9w8sQmv75a-W9`$6YLCIq<@NG_-a=p zBR+;uDM)dVfmSrHwHeJOIi#+Ey{^VD8#%|nh57&!v5*E}jp#t3u9`d-X#!NTQ)FP{ zjP?{XUIqJICR)oO4u{l6;TMy$+C?-~TpZuHOcV}^CSO#T1c5dY)rb{BcL7ehPP9zS z{_Jmsg%zSHXu>YgIqf>p1b+?+wS%o#XV!>HW>(MxKf1=3LTw}6>>(Nu!|TUA2)fsa zgIgwAZS5dhB2u~{oUKlymVQEQ(29L#g=kRxRd;JPrp@Rs=>Iw{+C$XOQK8n73a}m0 z+A=tA57B4}#FlBU)6BpK*`)>=7wjQ=g$kjzh8)+4b{AaaO;p=u>wh+(3sjRC<9ZTB zws5t}#~CY4t(kyDToP(WFx+LLIbv@15&JqwP=q3W;%WwvE?nO;sIqel={zA4eb=pM zC7{twlwrTM^W55u=xh_us$9PBnjsi1#&_x|AZQ=a28#KQP@l|0R?IJ3(2c1=Z3X$( znp@ptK@NyYd=&Ft$$!4on94+PCV#V47n)3(K_%Zz`SvTYh`l-`}54j9g1`ea? z$$H96Y5rck)#77Dn2TRmcrh}*m!lEG{p>bPTPA_gdM<;7GXe<7YZslt;-8P5TE1gtYC%NPcT_zpb2m zy`N2uIGz&S9W6^950G?II~_lr_z{0nW{6!Yl{_5@vpIyfsJ5Vf`Vo&09neT5n^7z! zpHkD7#eY26{`4(-F0*SS@I!vZV3Xf9Qi#E9$|<3q5sV;;&J45Uc{ z8O0wh%!q+O6T$1du)YnK_X@bz`|pzZS;-a4BDbgfm%(1&I0VqhQC=zNc&TR-y}YJ) z4L%lFu!7oC4)IG%_ZeM79P4Z+d4U(4`;b$6p?@(z^dGdh1bL6i#6%iR0G(N;hM(24 zl|>|YZvm;Xs)O3Mf)lJ|3jMt%VulQpt66esc9j&efd{#RXlD)*dzXjCL|&$k;%OBD zq6l&cokWs=W0c^dlspbo%3*4ppy&iq@bL&M#nk=~n3^kVn<+K@!%A#TV*SlGrJx^W2g|n>a{YmR0@r!>Qr8+mn6ZCG?IHD=!e_q(SZjNje22Hn2jGUO$)!~g&QC2Dj< zSaf7zbY(hYa%Ew3WdJfTF*GePF)c7PR5CF-G&VXhH!CnPIxsNaitS$j001R)MObuX zVRU6WZEs|0W_bWIFflYOF)=MLHB>S&Iy5#qF*hqPF*-0Xuh&)M00000NkvXXu0mjf DQa&vi diff --git a/src/qt/res/movies/spinner-020.png b/src/qt/res/movies/spinner-020.png index c12ae20016110cc3b8f365a02aceb88cf082a2da..1a07acc454029a36ac5fdd556e1811bae62c2a27 100644 GIT binary patch delta 2356 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 diff --git a/src/qt/res/movies/spinner-021.png b/src/qt/res/movies/spinner-021.png index d81ceade23fd840c7eefd465956d85e95a88a91f..9cea8f25433a8284bd1e90110ef18a4f952b40cc 100644 GIT binary patch delta 2358 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 delta 2827 zcmV+m3-t8B5|I{=BYyw{XF*Lt006O%3;baP0000WV@Og>004R=004l4008;_004mL z004C`008P>0026e000+nl3&F}00002VoOIv0063uBQgL0010qNS#tmYNzwoSNzwtR zMT+^vC z>6pF!5VV+W(nRqBW~ zD*>i58|O{3d~Uz>h$;d@9ZvxxZZ)DK@d>2gAb4vLRqzV6%4XuNMO5Pp4hZC_OfjSF z&?5>#jtHa)EHpDpha%B#KBHYAzk9%3JY z#G>NINuc*{1y26U1*+LeEMEKo_&G%Y^`_clxr={BR9^#dlfu_|fumf#$(a+CPW-g+ zF6;Oj0Dlga(jxfYNz$TCtS{op=W+JYN>GAi-_p$I?BWjGq*E;Tyq-nTCf5U%Gz!^9 z#Q>*VU)jTIJ`%`-Jcc{kBo!3qv5h)Y6t9LBY+|OwH?Pq^4b>D=O%-vp5_`|3Zq>UYXpZr1l zs(*+2J^YLdQbdp7(XX&k)6L~gGQ)h{&0l$+BHDW0^l&sCc*rJ|uaHPkV&j<3BpU1? zdOIu03;Ah~Vz%%{ltD(412;KLWibV0F$RZZfW$*KC+RYzxh{<07c_-5*ekrqBnfk! z%MbXNi*y*6dH-V1K6(|$L#l9?ha}=8BY#kR9?As4uekn+cMgRI-J|((7(7^xFEj`BumWu!%CMI>xZjzytQv z%ux<=oKkA^&${}cayrCwKE^ERTJEG>M-TdG;SjH~iUQJ%2d?$?=&F!w=Z`rpU4Kg} zbrRtPjZQ9cfa8=ZXw*e#;}|lB{>Ku?`vhSvZDHalh`mQdmdehNm2$l@eZO4f7cn zsn~(M>CO|*m8~3NyY5zfJjHwbkbgu*bC%C2!AlJtk)fy$Zhk84&l(n(s5Ol^5)J)Q zcfZT_XgAA+@_%#C1kqXpzfs924F`TcKtVInx)6&f7xrkj)eQ}T9G>M80j|=-F_u_e zy~6#}3TSRNmq4Lg3nzQI)~Ed{R>;oIa<;B8nK1*TofH`j;u(U?X3I^8GDH>X896}eqET*iScWEHM%gHGtRkwBLGu8q zp9DH>CECtOfiwe;jN2na)PF&xV1MGI#pWG`gEGOcG)5{YB1JUFB-#c@1H{`K0U4#Q~{uL%>bs+cQB)JU_k2Pg^(D)AJsfSJr7Kn9!GL9u~YXC6z1 zi^xu{+PuW|Bj`XSo_wC*PaL7HUvft^g$C+;Qi_Dt{=%GL@CQ#9pdGWcSsu zNT(&Oq*_?h2l6wnHHk?IDh`rZNCC6SVQko(+B6C&maf}D5-$j^f%y28&+Q?qpx_{$ zIV@r(vq&dN>UTLL2~YII8otbUfjme(Z^^4_jOcYEoyHP!$s>~#U8`B9a9=5chkIEe z{KUaV>4#;AsDDBt$t+&ca9WfU7jUNQ0W zkFZJ6mJvWXF0zMTvzWL+_rMC@

d6-C}`uYW7DNmn24X9Fw9V>He|{nA)w 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 QY5)KL07*qoM6N<$f~){i`v3p{ delta 2816 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 S*Hz;H00008=xQwB0fM~ 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 srwQ>*Mv{>{Kig- z8NEDGjv;wq=K#*(xB2JHg76yBxB&jviXP|e_%qS^mzOE+%$8$yUxpwi1VO31#$TIE z+psxawuAWE6SCZ3=(u-Yu4A5bSsR|$Yn`Fc(cI)F;X6tORh~a!B0B~SCI?sLqqPhq zR0;d6p-mjBO)-S|&4N1C;GUQF9Fp!H0-GR@;70e!`I)tf$&?kzNR~y85|1crkK5#F z7(mOfIDb&aw+CPf7HUEIIm%FgHEmwrWsxm_;%S6LEZC)T>{GS9j0c6@@H3PyVDohy zT;kLCbHQI?9B*ye#2G2p%`e=-;>Vre1b5%)5EwAr@JIC+Ld9wBrc`2}p6qNNV&418 z16G(P$0p67h2Yia<}Nbfaa_1#Ml8xpUSYi2V9m^uz?yIIkrvX_jtoCGy!`yMYxl~! zM`qg6?cyrPuuYC7h1eqE$+e5R2_&`WYX4@$*7jQFjrSe#qZ^_}!tguiqwW(PW+ zTzaX;b-YndNe4X2aEVBgz1p=T4EwI;R4QM)-EF>_owS0$k~VfT`gsl+1~pezIh{8j zP%vjwZnt_sBB6|gk?$Lh2BN=s5(Iz#^7QGE`5ufKN{l8B)zi;77X^vd+BIG2; zUQIDM!tH-*`xD``_2EzaZeSZjE=4MD)Sj#x7D@?e2`iYV_CcMu#33v-{309K%NMY z&#Ij8SxO9<9z2{zqh&;f=fe!fa4^aAv@$fWxZ@XHar-kRlg528X|iE}nQS)*D}Jkb zo2RwGv4ABkS(c%Ow|SzMC@*m1f;9JXV0KX}-@ekbyuf%2YVfYbvSaGDOrVh}#8^${ zCy?J+3SJI7o1pPFX65$Pv#T^nHMhc-cYW&`uc!z-LJ$_^H!RAX7Mx9)$a7evyRwwSDgY1w|;WN8^4ey8{uSV)uJ~&=fu;aA# zwC;Dk=2*B;Qjuwr>H0)i8eKHnhMdh2R5yf7W6i5HL93K|XPYof2~E+UC&O@l^h&>G zD2vLVvkG;0;!pc#mFFD3TyT^+;WmiL9LH*fw4S{?bSC-UQ^!dVg1$||l6GK;t0 z9WUg^`%R+XxlqtGlex7PMf3hnAS+IBa1v(^WXaD+swWkBlV;mw?kQ$`G-{*I?i4=W z-!Z}Q-5p9DX`B7^+k^uC_cl^-2>fO_EPr7mGKplkH|UU&_8yUBzsLX+e@eif0D5R$ z11()$Ewmv?PuIlYsEMwT23pqyjee89cKUySzr)DEfwBJ|sGs_4aSs3l@%BW!IvZc= FzW{%T(C7dF diff --git a/src/qt/res/movies/spinner-024.png b/src/qt/res/movies/spinner-024.png index b3be8d3e8e71e176ea13cafde759474f81da707b..c5dcf1eae90f61ddac48d4f9dd432e820aecc0be 100644 GIT binary patch delta 2304 zcmV+b3IF!26^jy(BYz0eNklCSi4ZumBb-nrM0e<<-AOsS_cwS+peUVl-OD;#ZrS9V^LBZA_58q zCmi7QgM{(i`|jhOM+>?C{q4Q`&N=&@bN2q9z4v)w!GZ+~7Jn>QuwcQ01q&7|d^Ml| zYI{{I06X_`AAJ}~Uq&*RF$|^;9SFkJ9+b4vgRZ>5VlpWrmvWABmCvZ6j56{#z-nfb z$WZ!WZ<{K1Bb+I0W+&y`;s$O_so@so5bBslni4WODMw4O&tZB%T123kjDvW z3$q){EVl5eSAPmNmWyQbQwCr&+@~Es)Ye=JcII%1GbWU*pW9sK5@5hO+lXZ%Y5a`Q zgtm@h8_Ox&+?Jr`9jRgm6Fm&QJINg23U1t#@;(pwTFG!Wa7mhq^>U46#1N?2?_@r2 z^!z)-`cBCJCb5@tAELr~cf=@5;guL0j zThn)*V=i4JuA4v-DAnley71Eiddr*7sTv;d7AdArgi4dZnUk@G{OgyJ>CusS5j)5e zc7IXIY|~MJ!AxL2sZ1f3d$83iyu8WzM9*)}z)zNV51tWU1+7g|Le=jKXQEl6|XF?dt^Q_~jOJzD=8SHB)lGr?SgxIp3}PVP!sbQb%N(8PLL}o! z<3lbs**ag!c6rCMrZe06Q0T@(On)PTLtJjOgKL;3?|AnA0~bAcj5%zgfa}!Yrkohs zF@lI7o>$n--|0%bhmEduY^(Jw|3fI)vDJpI+BICvB%QHz!->5;tJ|4>;iiJ4{FVj8 z(g}O(mb$R!F2<27@Yq6|zi2U*2S48&h5Csv8!aFYP{Cb_J8af>RxPO+C%21z`nW(fLu zQ0BgP&qORIk7PPZ8ArGvF@JG|*X1qTNIo-J;ua?%5b4hkgssoRUzVcNxn?rrnkB(L z29YVu5-gHs^c0Q!nRhbW^f(3zEq?{0WSv|B*l$|RtIRO{x@QTaM*Cz%=M_d6&Nu7H zNR!#NP_l&Wrpj_Jc9Jy0QO%1QwdJ4OZ}M>c3>O6Lo|Tp*Kw*QS8Gk#%HvY^hjhB#O zYCaVP^RckycjYbI;3ix|OHPnV0MSfkBRP#qW(r9o%#>wxus|cKn<9(aE5uV~ILY%Q zDtV>%Oq8r0>SBRmb5lbR!F3(0*a^iYfpkYSNrKdK z>SgkHuFBh9+159SmVbO&c|uqS=f=%xM#?ipy@h$`)BIZ}c{fZJCBsfQTQqj(7rZDh zd#3O`VF|^4M(7lnAK{yl&Z5J}(d^}KGLuRQslrYc63mZvsz`E4Ha)8yN!Ljimh)Yi zSF@b#6$Vb824ItpJ-)$KMw(b!34Ek`kXR!#ccu_Uk)V@L>3<7AB)`!$Oy^lgKm5G% zbSey-;T4a1`9$_L zJB2qi?h`3>=bFbT@tAnO&VJH~qYExn{7@SNMisz803CRi={nVb^`$<0cu;mi$u4x% zrHyE`jRf`?@_(=;9Ag)2Ng|F%3FlFU@Fb6r$P(6Zo?=6VswF%pKeOFSxG)dXqsen4 z_{ht%X)&L3iDIsEfods=48HEW9LKO`_lb6D-e_^KM2E+iyMO+iPmYq%A8WWMUC}?vtnt%EG_SIoqrAm@qC7qwNSpyDVYHt5B8N$At%RWpgb+xu;b2G* zbJ*iWu13qkzQgl!Zw<=d+bW$I&pJMCVV!0!OG%V{+0}O|!AW-}kV%1uD!ztyvyXF- zX*}Has(FU|2;u=I@hZF6$0^F{LZ{WWe@t-$H#-y z1;1n=i%4c3Q}`i+_*yHKPqy0b1qXJVs5r1;t2H+5^1rGqSg>Hhf&~i}ELgB$!GeXa a82$@_b6e$7Hot2C0000zb>vGB^qTF*;|gH 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 JPDHLkV1lb~S)~8~ literal 2635 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 diff --git a/src/qt/res/movies/spinner-026.png b/src/qt/res/movies/spinner-026.png index dd92fc4fc17984dbdd453e20c1362d514801eae3..1663ddf44c07535034a7280d005318bd39bf254c 100644 GIT binary patch delta 2280 zcmVI)8NN(4j+z4jnpl=(tND z5Y13VF@iX(^rbf;02mSO26|CUVksq5u$NuzrkbNP^BL7_;uU_yBF2$KPeQwoib9E-A!z1x;G` z7G-?pH9dE^Kz}LO7=xK+H^xy!J*|Gwye0pmj1)qH^BCX5vz+jo;vH#XCBuS^Y6zpL zQIX_rIZPh$!9&x;9R8^RO&d0@QO<;5aU=^lrV-6sQp;3KolVqA0T;dA@=YJ9p5^;k zIx~JU^9wIF|20=>qKLTD!N=5b-b<>Ncz>Fx&Z27I39fpf#ShuYJW}m} zfSFKw5CQbzell514b5J-q!!kb&>1wt$mFc-);?h?(~0nC%EC!u4ZCUbXqdJU6?ko? zaad+ktsG)8gS?J#4D=*}tz46(dX=KU9$$e$RLc6lAJ|hcB?zS#nH;7?=9@1wJCGLG z!baL9wtv#bHWK~t$vr9HUouqBFePyDQWobVwsDb{8RCOBosq_VnY?EoX@SvdB)^tC zSZjz;WsPBMkvYOUR9eLYVt8A^Uv5_INgIe}1s5cUHuFqi!h~AUDqk)wS_CGPpcd)zde8e2g8eNouRES#OcAmrP;)jDi~$TH%wdH-ye~?1cgKYZW1DEgxQijdSxGeW0BhMxIj=j})diyA{uz?& zMkr4r{okdu<`kGZtA%IzyknD}Q%f)oD8p=_cXSXjakzq z$-q4R>$1^f%%cYa0?&);v=jrqculfont!hB7WSbG8|PTVKn*j8NOp^C_B_Rm#=un3 zs_}7#lPi%)wXs&2(=(B855?Np#|+IfhbeAh$n6;VFpm*Ssc6-q$l=S;E992z|l}Gu&Z<<&5p^~#E5J9oWi)*7~G(m z$%LqOUqguDr=0Pb=06yz7B1s-C*kAnd@ge%K8f3IkP7Rs2c zs%aX+TCZDBcdW+C%IX|Op7CMeqK+q39gd11i}w`m;E=M376T7D#X?FB&a1?$s8@ke zlz9EfKV!18FYoUb3n`H!JfdQjVnk`jFi43~|Cyq8u=RnA<^Os85R^ZbgZJT{zN z%2LwpK(SCk-r)>JU4)XrTG2k<8_LS9MiwaWTy50yvFv|ji#84XLpYD}SGO)ff--A6 zR?@nCA?ln2Wq%hV$!u~kmn}S^EaZ!%T=Kp>Cpvv{f_U!b=Mo8VJBu`{ zE=943|Jc`AO*ds9UcnU!qAy~0J1)0$Iu`>L9;RC4uODbyIu@8nCD*BDu(ETLAUVxf zMI!KmsBeA4zDOeLTyFPymS{da-j95~qs$HnER`61IZXye-~rK~@P8DO?A|w=*&MK2 z>}!0)&y9fG}h=2OT93YiwHZ$5;RFVVT^*OB?J zka!eh9qvd7-8FD2s8?|`GhH;DcFZu-C4B5A2577X6JwdhVn(V#*y>h)Ya`Do;j*$< zVnSqzX5DTGCC5G*(tpAUHjwClF)q`IYCEf3{F6X-hwpN&@qSk`UH-_W?X-pd{_8Z2 z?KE+gddit4a@S%gk|`aLH;|y}U5#bC#MEvC0l);AjAaMoRdX&z)_+T;*aHGVG>k&Nl%)DT zS*mC?iuIBs%C86N-L-ppNhSwv(2$cEv?rV2lq`yOAS1ssDCh=5!sA;j#Z*%kv~-^eVg;5J+OB zo7Z%fceyX{FMs8Q@ncSVEP9^i&*U(IUb18@q>xV)%^sS&Gdm~a31gnb6p5>R%2rmf zko$-uiGf4_2Kq6XELKq^IiK%*^Plv4Qr{0>H;uo0T^jv@R$8g$5A5R#lPxsz4x3p>|E~61I7WJtPA&&&=97-_ z?xw>O?qL;sx2J_8yuy6O(I;3OiSj(hgq3KfGMC4Af=#@`A$IaRHd4%QSI&|pJp+kob9XfRQfd2y%S6f;p);<9M0000 literal 2643 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 diff --git a/src/qt/res/movies/spinner-027.png b/src/qt/res/movies/spinner-027.png index 9adefee2688dcedc2f1b10b1c50e435c823cc886..d0e6da4503848d90bd587325535ef4bdbd571fc5 100644 GIT binary patch delta 1802 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 L-3i+UYjWb>CVszM diff --git a/src/qt/res/movies/spinner-028.png b/src/qt/res/movies/spinner-028.png index 83e7cdd583c2fbfe97ee53c1fd7851eb23ddaf48..2a7aba50e2cfdc275f790b6fffbc989267590c6f 100644 GIT binary patch delta 2297 zcmV+h^lgS-0U@kV{6e__Gs*q$22?$x& z0}x6J5~>K6#ijrWAcqt#hnnoNVBzipu2@0k$d)VyBZ|c$xP{AMFe+{|N)RvtD=Nql zBDn~p_m3UoWajlu&-A<;R)60g`J-$4_4oCAzvKJ+b-;uP6MrU5m@r|&gb5QSOqek7 zi-1BX0YD_l45TNPUlzRp6vD|OkLfI=m~xKr9y=-Fb++(4bI9WMu1+$TIDXACDmcp( zRHxBGBTcBNT;_dNGnpauz}nTeslq6pp_CdIf}(MQt9->S3VEn2z26{)@fIg((M8gE zRI`Ru0z3N|4u2$xr})t)inm4$dwGnQ&P=lhGuUs4suMHBXU%(s_tJ$afNGs;Jy#BfsiAc6Ns(nzzpDSOPl((E*(H z_^_90ppJ5O@D9g0&-a|>G&MBqqWUdM>Cy2-Gdb?|F@L|HnAr@a7m4&H0t*mN22)tY z0qS&7{ei`VcC=v{N}1+++{L4$VRLK9MzVr^T=YQoJ09)m5HXBm!Gm36KaUWh!)68$ zLJEa^&9d3w}<-TQN_^qBV{4LWnC3ADQ|TMwX7xG zCp#HT5`TsK*A3Nwlhi&mtz=L@n#;RV7|cvwV>i!{LU%(4VIHS6iMFtve)8XCC^M*} zkr#;&E<%v~uhDrjIig9mfyHvYszM?~TtY?VBGV)wOQp#hDh~l z3Vqn1N%aN7rDfBM}z29?tk?^Nh?|Gq0wcsI#x)|7j2|-RDU>V7WJhz4P_8+{Z@it?LNYttx)S$eJJFIuLa{VH-8*j@!Bi>@ zDRtLaC^b$}$Q91J(Hr;Hlc#mL5>I0D7=OQPUn>eRWHFYMHadM0)dEBKk^VUqR{DXa zippN1{qW}cQ$Q7GIL01kI~1D|C=ty08Ik%kzaKnk<$8%WvD)zV9l*c1-sbGb+uv$1 zn}y=`D7`Vzcn@c98$ao$dX5}J+gG7T;H7V+gMX&pWyULv)0_2WyLB5=NocdeKYv%L z#lJYhod&FLf?#)DY4y@MLJvRAt!nJinyJ+D8pDAEVKk&|ql*lb`tB3nv62idSV$CJ zeL`?tLPfUtF1{2hsPl=nyXwn=RbIz>O?5uc=aV{Jn3A&_zWY%ag3; zIVKY6c#srUI_>=y-sGOv4Kax`0)HuE83Q#75g!xhbNo}SVJQ|9%)^2#riKECpa+KW zcl-8l;uISgtiDm*;y7M;;qqJ6^fqxKKj4VxO zw~qzFa`PhqgpkBWYF)0LXNs#r-kSuML#*&y;j|B;0ErwHUS0099BE^*ra!L`W-ucN zz(x+AX#8%CKDE-qU4kDsv&?>dyj{|6J8})^uD#f%@yN|W`f0?n#!Z{Z%X(XR?&d3j z9W1qPZyQTpu3jL^3ZS&R^y^B6bm>}(H)m3kIax|A%U^wEPsk6E6 z|H7xct98uPpTZpw+~6Q74m$o4%DF%T%^YN!kA}z*k-Xw#i=Fd0q+eIEP%5ykwWPH= zV}(evm_t6Ji1&-AVj)GS5_wN^tT%RWk?Zz@9w*)J0O3pG!=6`8&xy`6%Wz)$0RrX7Nr&eZq>=$fgH!1!(MuXU^k$WzZ-l5l% zmp!!3JuBHXCQXpPWBuvJ^3Ffbw8|Ve1q!P8zpWSWLzkjXVA delta 2657 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 Mfu0Gz6nj1VKiGNDK>z>% diff --git a/src/qt/res/movies/spinner-029.png b/src/qt/res/movies/spinner-029.png index 6cbdbb0fe108455a0adb5b9c4c49211e25e0a65b..c8ca15c1e1c24156c70573cdc1dc83d37746234d 100644 GIT binary patch delta 2346 zcmV+_3Dx$=6|@qNBYz0{NklI;(M6S)<}5SEIAg6f0fJG|LeiEoYq6MLIQzW|E2$nq~-I zKs5IJ;gQQZ-#+K;&E9xu?dSWCz1Z)5_V<17_rA~j?gJ)Fn13)~!h{JECQO(xVZwxo zpA39}c60~7Z%Sz(!E+4sy zI*xFh8=U4_6;w<3?Y*LEr3)`H)*)Jz7$po4s`-+)d4G`%66wu-L@|QF^y6i|;3Ai) zbxZXelkD+vE6$`u0y!M!2A>h?6!iUpADTVlDGEpw1SzuBKPTz5nD-}G*s0KGi}$fLBG z@sEjcqJJS_p$8M_PME6Y){z`exTIP{KV$c*1sh|?=d3;RXdG9VtXozoVI`iWeD8wl zUXqMCS0yZjGn)6gpkR6n{<>O>;!j*wBzl`QI@`1R)<`n>$icld9~T&@vr^EGf$UIp zPS^RJo=!=^LN}gcKiAy4{&#fuh8BLw2a5K-pnsP>uU5iF5_2hX>+%Amv|Oa;^cN*jb(-iA#v=mr{j*}41HR*V62Q_8KvA-8I6{bV8EP8q&OUA zjbkGnwcgf`WHxbDQ`mi**A0nUtPJIA1(!5U%d3@0V6jS#$1&`F*pTzh#tU}6&~fY} zSbvK{KcHFVk?j)ZTtnn&3$Yv!T0GC=>a)mab;ufv=w?V%=EpRug%(x&-YE9yK=cN) z42naotP^_Q5+c>@&u|Y!W>3a{h%`vw86=e4t}#`e3rwQi#pBm;l4Bkby-tQfWg~wD zEz7=h@N)i?^D6WYQA|^e_~Z`GL`f z%&9~;#lkg|rS3)@S>7youVD*M(bc}=#@VZ2qFRaL*k+L2;m-o0y^dgx=;_z?ws3GJFHT2gMTvWb6YJXh> zUkR-3p_A6#;D`i15)yrowL+q28DI#}VAct&l@qVmk@m3g@Y#=zWa0T+&+-=TQ!5bU zB&7PVLMVw3(2Hnq;k+%tMhD(jNZNkUBASWhvYJKAXIPVMATdRdKHel-uO*X4m4HkN z7GR7}#=6A>&2KrB-%w^(?yLAGGdsUyMYh|b~(Vk+zK2=x`&Co2Z9Cwm%3W>Ha-B@8N`HEgkcee2MziN=M z_6lCZFpYUkKS2z3ji>F4bGT4;eMT>$&k3@@3MMyPciyM((^;dfnZiB4*MHt}HIgzx za`=0_(%y**?&huw2w+|_5$1FH;iK^k?=3vAsz}FzL@z_Aw0N0b*KM7qRlHkj(dt zLSn7pl~*xduRYpR;M8T_b$^On^m?u0lK&>ccu(;6qm0tabO&LqTdLXNxYHy5DkNIQ zOTshza|cPzhD0Epw4JS+1x}!XK?Z3FgE%9kdRTC{)U&JE|N7FOxfGDcBE}M;)*a0f z8lGnmQGeDeXjh`Y{;`2#C_~7n(jLIna)@+wVT(k%P%A&Ib%D5n4}U2tRLLZ)_!3MS z?>afn+hpRW#&iOwggss34H7rQ+3ay4q&tyJ;!}kx?jCibdI0YTZ?npOwPdMRuOitmyjcxt205hr z6)bu>%2=qSK%x{j$b3m(L)3X6=Be(bXiV0(ldM%=?!;DwTK5)W4XL*zDpUhpkMnHe zN!n|7lNM4Hx*Y0R=}`x#TKKX^CCQ5{WgvkqZ3YTpgQAJGbbm2mRv%R{r^i`Nl0IjE zg+2=BsmvvwH(;mQ$n)qMs1oMz5LW$K3na1?nqg#Wc#C+QJIE{y=DeHEi9@{5P~g-N zKXXwXuVJh1J<`E0wo4tmm`*nWj5*&PciCNbjyXi>8W^SsLzTVb#d}n8S!`De(p+7#Y z`>BtOY?n>`cU1Iq6jR6?x+4)u5MaZHKw{~^1m^OIKz}nXa&l-AQ#r|e;#!;J9YhOD z?V{xPj_9$Tt!!fKZrf=(J{4pg_xRJwAf`~F z``3lXNyO_Q5y?VTUky5)n*hi<^8yR!sB`kj;bMJe!W_O97SCdOWwa9Ag>d2taB} zH1EolsjOl*hlM?vcYhkDf(xwUS$Y~Dpc{)03?+lVu#sX8@(C9>&oRpR7aLi^B*xN} zU~m5Y40Q-01Pjr`5kLZi=}Z@_(AH0M*UNq ztf&1~{zA(sSp5xAh5*n(;5qVUJJlc`q&*4%;^YA!ISl{~Pfoc805}K$ta|}~eh~nO z-OTeGxORHWjJ7m00f44lIq0e43PZX@0)YACKgHBwntgD(duMK9=omA*RT>{A@?LuI zYWMdq$56WbaxrrU5fNNbW&5}SK~@IwkHSTG9tvANbf}p0Zos+MKO`s<)~%$mmBx1W z8<`Ec-Ib86TCxR1B$zoC0iqiU?#a#vpA2a&41SD{{=Tg+^KobA5BmJ4{kfg;{hwuv zhh>YYeCM=-XWG4AXZ&ZNov?c&z{fx_7N9TKseThAhY7BN9zfne1@L52ZMI{el4(_m zeaWkJ6W<@OyTiP`@Eg1|{bht0ble(ji_#R+8?`$VdE9IczZYDmiMQ)#e`a5KPt^T@ z_$p#((jO{e{io|2YxU|?qPno~g1^LCA_{R%FeY2bW7>4ja;+vi;k-ZmULpz%$#eA~ zR@HmZwM2=j)op7HG({3D1^aY!<$5B@OuBmwp4(t_)-rSJv9B!$bjDv6#fE49%?sg4 z-7}MlM=3N_v=fvo-GZ=n>dU)4%lgF>9p-szI>lTvYnl0Bf4~%+)G_6diaxS4jx}#Q zB2qW2MwskjC;al`AQB6z%W?n4(@ya2^~OVw=c!9S-)XiHr-CH$TB;w zyQ!L^i_f{};ib{sm8QfOxuUK;DVV-~HX=T)$_g&zYE%4RFB-|HmXU$oiRG0aej!cG zNNTBogWel$cWP%6!=a^Pj!S!Xi3MzRTPpHWn2y3(z>z=CXY9F(Og_bGfu5JWE^SiW zq*>-{T%88M{*jxaIcUM&nUFCg6TO341c0G>(`4W`PDh(5heOx5|vLX{+I}rE9$%GxLR|7*GO2% zYZxG73>?DEd2)N)vx3X1#WY4CI`k((aVw4-7HNAKPJjm-G`+Q&^&~kDDDj_8l z*y5M5@b>dTI1=1lOEeS}z;lXDf~OkhzSl+evQ|A*eWY{-*KWF+m}5?*=9)mq6a<`N z2=JV}OW!#iLZ@R~OL;b*DC3#n>|IUyP=ohhb)UlKWUKH}!kup*DUdCb<;w$2(>;T2 zF+@=mL1;{s)_fh&X$O+J(^#{KDsu?OSGPvR z8=jc`LgFe?n=8v1LKduI1fRt=%Uex_q{SI_=C8Jb8fiFkP_o0U z5sax2M%g&gO`^935E}$G34OK{nRVIbL5s_4E?p;a59CtgN5UkkVik>#$^&KdiA;EJ zqZJp)p6ekF)27{?*KzN<)%;n$8NB-95KLSZpFNsI$E1q`Qp~UB>g3;5;IXVOtSd#z z^Q+H(N`J7YG3LU{MP~9ukqO{=3xcl!RInhmabp|}c6aXH08cDO$E|^$3_@pPiuDyV zNhuzm1vU=n1yHuwiXukR7K4Ho!_m1DVs&fNx$cYtFO@xvo*eWH%gnzH;pJj@^ph{( zC!E#zK^?;{He)R0BGaOq$F800Qo-ha)tgpdxnZF!HdA!I>p)SAZOfcKLC_^Xi>d8R z69>DG1{iL1RorI0vF*R*{nMn7Q-^1Z^!3MLmWgWPLcYg!lehv=;j0^&3b1sDjr7(g zTHW|)mIFrMedUaISGn?w-(NL)Z>#Bh1r)NOE`#3j>0Q8rSEB*T=$96RDNCf< z$f5lH^J^soyz;rXb!#HB;}M?rS2A4ipL#HEs3VVp`JT3;oCh-(mLPwrIDBis?KVL8 zT}MJha|0}r_d|DvC0hFTm@r$5N?k)cT%WJp8-AxIJKJ9xg_TV0y=W#f5w&(GUS0mF z?{7UTSdR=(`k6C(9bCuv!_I#dz}X@4D~_FC-lX5RXHoCaq8sSX40FBEskH-jrfBb} z%5cj$!UGE;%4OVMxj$| zKzKEN5qW9Z$*8sQE3_yu7Sjl9TAIoUOKQu<@C7|9ow3bHLC-Wbp@oi7irmqw;#8ZD zh`V}0$rRn?!`rESBIWJ9_GK;8h>jezGnD;yY%QDMs8hDL@ae~>=3gAbY}e|8hMf(T zhRa#3g&10YH>-ru_^3fOG?t=K+}|CUhTBq=Yei?wK zRFL0x(UaIJ%<1W!#-Y3=vXFTxoMfNHKJ5#9e8Ct|E>Zc&%K`&FP2Xlbhpe}$2d&jZ z80C%F($_7r=3xT~gx9qy+OYDOg&$aVKc{g%d)QC6KF)&kU=Ru8$MAm}8_YcFwz_iZ zCQdA&Y?*)F)O9B*Z50#SEBiYe{)~z;`sziAY!k`w5UrtRzQsfKI$`XGYbk<=5PsU{M=$mP^lXT|lOK30L z52S{)!ky;G~%B`Lv$(X%@ov{Enh-@XFyg=8CGw)UH8U0urXi9^@J-TlEPElt>`K zVnd)TdvIXbS?|A;X8$WX{X0X&ah} zxSFP>8br$xs;Ljx*4Naz2+`DsKo+vMJpacKauXBa7yJJWZPQM)Qv+abYHiYLtD_D^;u! zr-lgHgo!Z>#bT(|wwlmJ(KcyKYz(z#ViGkD)UBlViR?o+Db_f9~q5_Pa+^b zNPG)|ZvOx&%bvR|dw;9q-0$xXX1L5f_uPAa=kYz~2beHn!heJb6DCZUFk!-k2@@u6 zGiZRN@#k#`E5Y2!0KUao`Y@Wl#1q4P1Yx;dlkr zGm+s~32DD7b|RU4c2YqdS8?gC6C9<4Y$npJJ*wH6`JDBlp6A*}K3Uw^-V}X-6Kztn zVI5=>Syvyv%kg zsc(9ubEIK$`|C(H8&=eXi!;1REWtNQ#b7M-;4z-(pMM)LCyHmt=QZY$!FRY98$pduECegTgz-au#GhNedp+wI z&|-5KM1K%A29U{Owo%>&^SaCoodNNqd6G}f;QPu4GOKUfS)v4K^xvb|f7yWP> z%MBXWF!K4-iy>cSJ#i{3op2s!hXMasOoZWQm`IV=^naD{OxVFlgORU_1O@Lqf>&Fy zn{Z3kb*Dz6%!QlKmFLIBWDjo{jXTN@sU?0dU>aio#OO6m9IoOCrLKK@yum!vzt}3hqw3%!*LSLLLZ5c zdw-RZmk$1@6Ia&|W`wny!XmcuFaFMK66t}Xk%WxojE}`~hT4pjUTha7l`+KFjUx%h zNpOqDeb(os@Fm5>mX%+K8Fw8s)HA_7_`qk+yVZzE>3EMk(Isu8vuZ^r^MxSjoEUk_ z8KStwU}b_>>R({2YQBBGj)(nN_-!pS6@TwixPwAL(lr*S-6rAe6U2PYe10sxfIRGq z6}2&4OlNk`Po(?*svt7>W%$%S9&O*UF6-9^--_>p6A1G+3++i-`q-NE7px)d5g+pnqt* ztJS5PaeN{O*wq-U2XjcQF4XVRt`rNB_H(zY9U3c|%!_mYpd*`vt2^nhTv0n~MUwS? zRSfSmF;qX*xHoM4UbueBD6bk#)k;PLpnrX!F6T2UG|RCPIVsrI)2epH&woX)`%pmK z%?J;FaHLuINDzy)R5iJgjY(pCKQkb6UIiY;S;J48UTHej!XAB6mGB=32IC?x0FyvY zk;nL`vB4aqQxra^Cf(GC7L&a9l@li5ph%E(sEGvIAa=sXtE=um6a*Y0N_i<3&PqX2 z4UeJ$F{~Gfn=b0A`?tg~#eZ=D7(UGwYoR4r(Qt~@%RB0vqJwO4Z#)|SXY_rsfY{F6 zz!Z_6ny)4=Y6#R1iEe#UWBsBMJ;nLKN=9H|tB@|#t7I5pkZ3d)NmSGgZC;_gCN`MU z87C5S=eb8^Jim+gMdN)v0P|c~LM!VUh0GIK!1w5*Qg|p+MW(!j7=Pu8#)(AS2@Z+` zdamj!=^oK=t}sjaH;rbCNViEAb(k^gtNWFrr~?dAEXm?yd$M7cp=ENTfK{C&whil9 zq&%8V@_ED{p-DlFAVP>?3~>xKHi^_pG$|JsNmov5R{EsoCPJ{FVW$fz%wsK8RC0yw zEF;nXOkC4xG`VE!=6%@Pwd7ZuD>TAe0|O|7=Aqei;4y><3!!*HBBr__hf z4J&$ysYYCXobEK&NoM-xf2GNBR4 zMlZL2Q_)u)*~%<->#M+n6>hVtQ@u`*Rgj@1<^0%?np=#_m0d?L865Qz-zr&Qc=kPr zC4MVeK_Rhf%JC=`dyRC}?B*4EL#sPh-&1G$G+aAXeaTnP$ld)dz~g{smia*yui_$l_Vj8wi&M>+(gbI@qOt9^RowYaFHn0*wn zhhjeGxJP}mm2Y~y$^~9ds~w<#Cm43@P zhMol7*rV^=$Y6`%;NCEc5ZB_~131>iWE`i2TvF&ySO7W%K5`Gq{8ebsw*92&c#jHr zHRt$@Kk+!Rbb_0I?z;!C_;qaEy|tX;;ZEWiMOSRfNmWBg=7=td<=b)CBq0dhlCbeB z_W5)G(|;vSCbcVcCWj3iX|tN;e6Riezm(ogV+G}nN1S~*cUnjq?G!QG&l42z56~BAzgRB~WbG8EjVl)AO#AE-HGvPK zomW02Y!nw81dsb5{CZPFWudl3|1)v@clqSsc11a^mL3qHA(Oie0k>Saf6Jk zU*}a(VnznV7KVKqG6Pz=F-5}?{MNNxXz>UR^S)A zUJL%sVzK|}XKV3n#F7>j*cfT*tiJm-9ctGZ?_%P&|DvZp){@=fO(3S~qc zj@-j7r=e#$&p(O2ajY~dqg+<(Wn40IOHx8y1ho^^#X8K1X#{qdW{iuVR6<(kKuVwD ze`v$$dSxUVfgt z5eE#0zoGk67#CK34U#qMF9&$jfU}D|}3<5tnjDT2x~~f5d5cR(A9sN>h-B28GC;3Y(s>jvcH8=qG8@l4bDRS|_36x~5vWDf8MTsSB2v z0k)Y@6&JX^;Oe3f!MW5%x>lM*apo}hbaxr%;I4fAMVnD4Fom{ignmBP$sID3nP*|1 zH|J>bD4Tq9-ggDc)Kt@H&R@*Vy^%AM#>LM-BwASP-$GZ6T>SFB;<6i03+mc{5ytWvf z`&FQxaYPPRqwkM;>bX_cZDA`*t2vXaBRNV?GN!X$8s|`9kkOwY zIG%K4;&`85=WrEyffK>dk_B7s5{-XysbpNi!-RZUvnHj81>yPy`cy^7mHU!&q2 zT9bs)4TY3d%o(B_&WBK^R_CHYJ+uGNK*a3mhS-(C^Avi}#dx~uCGyy)M5E|M|Xp-s)__;;P_W3p?6rz^e-U5OgwMoxR!rkvw6k0ttWBf2_xZ{@bNR}hXs-wZ(>xYg-o7}6o zGPtpLR{(E%r*Wmy^_`d|Vz4V;X72I>tJYu$aYuTV=-`u<##uQpc8Q zAX>`Q?{0FDBAhsnuc04(kZtI>MJhe#2;OI<^*>hy?rIGxK(b@!Vd$9=VSQ@iSom7r z+wT!6o$$Ot_TgT0)3s!+H!RBcM_*-^LU`Qik#qOTqr5|RxUDCD{u!B>xg!dR@Ov=b zIU2geawn|n-(cF?=f2vy3M|&l8E_d^m9xGF9_c>>gWb!zMU;93S5T?(8szjwD|NZ> zt9)fo_(HBNmVdbwbtGgqn2uT$b1vjsxvx0N;MZ3wm%OWJ6h+aJ5RJ=P+(9a*dFTyS zz>nO*DSR`Ed@htJK~Hg<>_rJ-f;XS3m8|wwjEgK0lnX8DBO9Iuo&NdmT~#fAYz=!(pyRvs3zR@$FLRB(PdxFNF&jcIbjPut z$i~46Wc-DWZla~j@&r?fth|P};@I>axtH7G4#(GH@7XwUsUW^hkbTlY&?GA!Y}|XL-XEHU z7rC2i2K}TZweEp+Hf7B>eZGO*TQ~7uvWT}-5=)~&CAd^wM}rRD@(FEzNus)?m6=$C z>!yf~D>(%P=5g!b?PshB+hkW}L-xtD`9g535f8j@8{W8`1`Z>dN$s_`@utVt6Agc3 zyB6BF)I*cwz>sI9h{dFLj(>6cPmg<175i0MBBy(Q;s7Tq?lcvy9Y7YN?> zuDN4CA&>9cv43hLbpRwte(I7E3Wm!q{sYw}%oqROUqy(^?VA@13j7a``e57+W}_y> z(t|?qqXeP?$bkm{=p*!yI(m9Kh*PfmdMKnJO3z3ep@%{s7BfCy{8u3&k`NLU{r?M1 TFWgoR3IM#NJ*Lsz_xgVUOArx| diff --git a/src/qt/res/movies/spinner-031.png b/src/qt/res/movies/spinner-031.png index 3c3d50574109c495e3ba1bc6e78c36cb96aaff62..403443144ebe1f99e8ba286f5a906bf4ce2e8ea4 100644 GIT binary patch delta 2370 zcmV-I3BC5W7R(ZmBYz1KNklAh84s1&cyxd5I#R(?JQT5G-mngOyITRYXQd`yfFPWe|Z-OIjL1L5L9|LJUG4 zWRsBXA1upe_jfm&z2{QO-0zvmAGygn=X>rszxTOd!h{JECVxzrFk!-k2@@tvm@x7G z2rFPA1h5c+4I5y&x+sQ{KrVSK=W&*?g2g<+Gfd~FB+wfh5OQ@8ol6N0oH#j;)7@HV z;Sl?Hp4E(DD3&Yx{aUaPLI_r@*u}{%<+ukuxz$n1Q(Q;v|DFymLSb03(TQlfk<19v zxrbk}h?Ts;Uw?RvFt7hir?g#~7ux~Wb2s5WeHe-hLc>NBJ?P2xj3$#wEZ|8B`7WE*=ar-Bol!9i0y z6W!}G#ljBIyx2bDH+A65r7v5V~} z{o9Bm8yTDos;4FnlW&~9o2ZMXlM{^elDkRl4!XA{wi9Cn(a!usC(-Ztu}`nbe5Iqu z{R~u3v?u@6Nz}n4A1fz}p1evawS2=VzNL~XPEd`LmH>KeW+x+56HTC8C(#!2G|ag~ zZs1lj7=KP0X(Ta@>8$1*cC{tAg=THK~3;YKP@|2Tc7{n&-yX?--@v9EFj_ z7k?TfJg-CCwId*Y#5Wq+&G&cpOi-c*BAG^|IBGRnMiDL6uvb16s5;0~BpG{CqVZ0b z6JZ3=2^uTAl|t%;x4cBz8S2kL4fo!F_=A;)M0@2N^BBQ7;mMQAh(=92#ta~A*3YxTx>lAD9k(?3c@jG=c+d#_16WYoB z7ej@Jz-!9Wy77GOcfoaIlxVi+dl&?fET!5jL3D%iC_q=yN&J-lYPz>EMNIiU>J^87 z&TTujP{Hj6BoQpUC@lFY#;F=$wtwJ-)^eAZof%IyYuUt`EF#$$zk?SBDb$; zT9wj&ikNfxy(_|?&K;D(rmwj@q_tw6V7$uZP8X+eiqT4m_Tdv@loHq0y;+P~o#hUd zQ-~AAKr8c<-OQ04)u|jnWj&=7l;Lv!?=lmi*kRx z`YLTJ6UFRHHM5mP;jAnZN0`YfG5%N0JR|Jwq2lIsa+2Z7#+W0PZ>`rT!mQ+4BfJVb zOEk)1wkS$I*vJv|b$>H;8X4~eY7JoHNi|pvTv-oMV%VbVT@58zMWrd40?u4 zB}u{&q8xCF#!7*a7lG3FK=U%eWCi^X4&V~d#WJ}V48=@MqIJyH-Fs4iwcpL87#*OB zCSS7{`6%;s_TGb!10p)#Bf4P)LI^|ooyC#t)O@Q4c~)24A%B{!0nmJlB*KZHJBbWr z7+KuMy-Xol^>&`+_kP4Kl7n8`Nd6Q6(JgG`O*T_TC0|iP6U{hqP)@!=oetPo>i2%r zIdbV9l)YpVQ_dZ^hO$nno54T|+9_v!oy8;sp8bXl-pB^g74{CH9pdk-X18Ps{1$5y<9aE}z*R@v*KGWuS6_oTpo3-= zPphx@^u!N%S)**(e`{rlmq?0de-OPmX`zz6%<$PE%8|fAJ_>^B46pEWtXM#KiBc2I zoaGo_Qcek*c$IwSlE*}b5NFisY>OyvBcGZMxXw@dm|w$+xuN zq@H>jIYT`)9HNMuua2+YSb#9>L@}IHa=4o;ay!T*i+f0?FP*sxVfFZF!E)IPcTAWt oVZww76DCZUFk!-k2@^)*zn$+~voQl5O8@`>07*qoM6N<$f}jg&w*UYD literal 2871 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 diff --git a/src/qt/res/movies/spinner-032.png b/src/qt/res/movies/spinner-032.png index 7460f80da35c99c219143d16d0d9f92d2716c587..f9db080567c3f8101f3b541c7e1b5b0a5599d8e8 100644 GIT binary patch delta 2335 zcmV+)3E=jZ7O4`DBYz0+Nkl|v;~0> zncC7KrI1vdz(|c_Ls3X2#VIm~pgbH3PFw2?5=Mj&!!Sr`Ng}OKUs0QucPJtWkdP`N ziAl)zkEEFF{!Vf?d-kq6_jmr>d(S!Fdw%El{w-K!kwq3+WPg!G7FlGGMHX3P(bu1B z*uKs1?ARH~NT!oOJn?iR2pe`B*s*a;}o@Ro@u0sD&8fZN9j*kAfRUX2-8Ig@osY_^H**tp04FAFLOWr%m%t#xh12c z$nAuJ$?Wug15YH=A*> zjwxnAUCjGF0o~}PUYu;E*^Bo-Ad_%2fQB-cgIwz}(4`)Fbb;4%JV&w_P(z4fI*;=# zFOkQeDdq&1so+ZkTWk{UnZxic{c8MyyUbx=M=N9}-H2xpqnN-_syp4_b<#b|1shIs zIqMbB>wn}jE-=PK4?Zxk!T&N@w0a{*W+kss$QdrRGal44?Pq}bFozg|>7tym3iI9p zgb>FN?k0oP?4zy|on1pAG3LS?MLso#fR>S9z{|DcpeM6nF$l4|f*-E4E%Ss=B!XuneaLRs0_z&hFc8OqIR56DKs24uKGJ=uQD&P(P){8pt`x;hGP$;xFarz^S{YQmYF{9O;-Xi>ZUW>*H<59(x`I&y8 zefUUNsGgkGuNui4!tclFttDdLk6ohauz#ICdSM2$Sk#i|xv%w!ZoDo0{vO>mt)I;o z!u+Qh>67{rqJcX_)>&~=9K>@}_`R4|O*`mIxwwP%dQUW&Ga}>u%657vPAQGZM$cFEyUY@tTk$NNPh%6 zMW-lwO<3ZhTL?0hVz(y>d^G>uDN{7@GxUk0Xi=gbcS{7>Skw;c>kQNkbe>>o-(aIY z`zVfoipirGk5KnmUZj9`C?bP+?MC-7j*F6A(}~)cDC)2cM2eBU?nKkgFNytLl!}}+ zR-eq31p8B(8PkZ{zfssnC1Z3M3xAIZMs*Eo0Vv1Vpb&~$b`r|Nq60QP06>?C5v1?w za=4!m69o6_wK5HmljY)0#^|xXf>LP|~K4*e1sr#@H6l*jqG0=uWSS|3@6;k}EN1J)X^nW_9FtKo? zjFGw)cu>rPyy2G^oP!WwtQTY54tqs1=E0J-a9+k8F>;s*ORM z6ZVm-&-L!Z0Wq%nUCl6)_)nW)^&Vz>xZYCU=NWw;+`%T%BAKF9!HnY{ZY%5~sogFX ziZ*wqPDL%p05@s1dVcCr%YRhI{5C4A2LQPsrqmRA*qxn{I=%~Y^& zOCQ?YE+uCBiUyv#@u#;rjXyaZR9~N?fc{?B|J?3HE5XOQ?SI>j=r0{^y{-J=k3o@2GyG1faM>7t1)6t@HqD=V^m&TbC*049D2RPPVa( z45kulPWo~ZuXqXc3n6j4rHh@6O;oajnPvcW5XvgAI!v##!0k+f+2K=%>LDLp3NL6H zzxQHeYuw(BVULep$1m&4zjWqig_2{~j9cM$qP@H_0DoO#j&!Vf-QaL1D>%fLopd^# zBgsvC^iw)xMn|2w*;*Sm;`tHl_*9JP{l7x6hueE2IOQYIT4n@7!-g=LdF-W#6V%e! zMn^VN>=7QdF+q&kdNV4`YK)d#=}>wwiWJgV&t48w!mB(fnt{V8;oqF0nmTH`@CO&o ztP0HEj(>Q9b`nXHGWZcfEPd!lBKMQZd~$e>jpTELqnxCQt6b~Aa;hPZyZHuD%O5~F za1ul)Hk`x|OB|ya&m_{w;z?d)H~AEDnhTUuLpdLj6F9cj3%?~S=fFl7;3SMl;uy?O z?qU)>HT7Y9jmd7N=CsHni!8FpB8x1t$Rdj@vKUA!{SVxITaYnEYt#S$002ovPDHLk FV1kc(aWwz{ literal 2839 zcmZ`*c{J1w7ygMJWh{(U#Z*|an=(3$P8UX0IDzJm>SmfFBF#urm?jLY9SdzB^fKSc_jl#u$TrIm2 zDmpGUaO1vX&-0h&0*iYgM+MW}NC}1T5NC~CQc3uYVK|fXE>I)Q6 zhqi<3#T48c`mBvR7$cV4ZiDrtET@M&4V4)IaCld{9sGM%@!#?np&vpDg@lpEW(MA# zuV7=}EwScMYqdFw-^(}}9iDT_tLg1_6GwFeVh)>D&kLv&eDvy-`UM@w3)kJg9=ebz zp!WNm({%FGWdpbTDS zL#1+B()(5;2Tm9Dm8cqj3)dKKcGkUa5sYv)wAE7E94J^c)o(S(3rgn`FKxK^+;bA| zbSI4F_(Xka;-?kZE)*?R;&6?v&jL_(*yO*Xfx<4&A2o3M54Q` zr%!NrmRSh%=VuF)^p@mvY@g9+Kg)Az`s512UtGWDOORoMx*sINW7{;28pe_(Q~P<^ z&>UGVlsDK)0;|FVn^;x5KQ`Fd(M$;LXv(@Lv-A;yXs)xiXNbuGgBf9K8vv73$$=?nC(r2_H0GKVV9pRmkz7w0=~=EnA$8~maYw1 zv@2?0X-9>0v+6(hkfZnyhPVo&=>9neT2R@pC_O{7#lu{9f^Qb!V}Iw7T^P5o6bogX z+gD_2X*|eZa&n$uyYxDDI(g*U-PRyKw0d1d6egYuu^Yxy-E3?dsgH#~sp( zDC-&A5P!!LBn*!)jOujJQbo`#3;Es=c>>KjcUR`4tgsGQSFfQ}eC$YToQ;~zth6K? zZCewKAZDv1LP%ENOe1rJuHm5jFOpx*(+#8dB;TguTwSM}%Wa)A#-|}V2EtsW!Sffy zg9wyW0>hK-t%>$3LX}I%J4Z@}lYM^ytoRrxuO1>ULCS}D|#o0J*Ts>WFdG?vOU+NN2tVeAt3s6vq zHf+IE_ei!Fg@2f2aLoIb5dLxM9f=Oem(s{UH@$6=dilDkDWqKn$i8^)Q(#PsTI zH&f#Mi%@(}xz6)voeA2MOka6_HJ6OU+%hc5u2Ce+-br8_TCOCu$h=IlO_EbKz)%Z} zF4tA2R=U21r;IYP$~}T_>#V9xglIfkSLCOjGI_7~*OF7PcTq$3Y5rT$OK;DJ3+o8= zA>6veaUE^YtxYk$U7V5)wbsBu`*>lN&td1Y8 z=g0D!Kx4ta)^Us4@?y<{6H!@Cx~gsXWdPjtV(5e{n?_eNnE&HJ>sX~<;>)TKuc4B- z=-g|6ezR|5aqU-4-G~X_QQuc%zK&NNJcT%NB!j>xH*3x!?G5-E477JB$3oNk=3bJ7 zGO2e^ujTjE*MySBBJYlz>%jYTX|My~(oRpGr8A~oPswEHa}z&ZXSGkj?hXNQ?Rk~Y zS7juN>Kae_XQS?XYcrF$dsPQQ?M5O4xAT^NkPHRprqzSis+0|&Y**8j?tQ|Rl;-Xq zram~H+o&;evA zTFs?P6Rm6t|2jCd6y9%>VvTt($-K|_7EQoONCcCpZ*b>kRBS;dN279M;4u|mc((FA zgKR_{=Bb0smRiR*iGr}nGM4=lC95N#n+ayk#gt(U*m_2A`cqkQL1#h^ow2r7nWDKn zGPoWJ8asABZG-1_gL~hb!E}2GHEryt-~K7HjObQQ`SWu|*iZ39i4WEB9j9h zLU@x_*eA=0vr+f1&q!>UtI9FKKdBpV3%p8@ceDsMu|9>5xF00(+Ef&qQUKdMsQZZK z4>;}4&~nUzI#0q^nkZqv^ox|Al1*Y3ZzB>yk!kfRtbS?JB@787d<`?uJqp8&`JF78}{!&^VbRK zM{(tCQ#&UPzDG5@r90lw2k(#cjrKnv00x1=b)Zlk2m%L#BH{YTgG~j2A|a3|^6JI^ d5rjqf1qUSjf5E+R*ZBhhU}NckZn3yT_!qvGBdh=b diff --git a/src/qt/res/movies/spinner-033.png b/src/qt/res/movies/spinner-033.png index d327e8fb0814506f48e7789d89952659b303d39a..43f57719e7fc607fc0152da01246c9f95f80905d 100644 GIT binary patch delta 2391 zcmV-d38?ms7U2?*BYz1fNkl#)Jj2$NfaoEjR=GYgg1d8 zOh1r@%*;MBcV^C=OjxteH|BEA{pXzh`tN-%L?tRwiAq$W5`UGbL?tSI#X=%h(y?Q~ zg5_p~>7*Ca*h?u}d5I^&U6NnL`-vlYhwl{f`aP8#Wkw=HxsZohds?=P0&EE zkNMaX{u!*11ho$(oDLf1DTW9~H<>X^U=G8{iJbkmlSDqt+07S00R4zm51>{aWjn`k z;o=epd5y>Df-_RU#?hW!rm}&(oDBfz?>r#b$!058+<%^_~*)(kN+3|TFn5DgWH`0KAu0zMg~LVIHaF)&d|Z# z!7U#8+0F04ui|-fA^~JqR&vImhA#E8so$o`z=1!&NK%^;WIPY?TaFuqd5H;Lp3=rA zhW_s%UVp~cR7cpxeUt`ZaSxH@^{Nh@F#P|YqeIgG9ZYpVKD3m0!ERev!%>4LVj;JM z8)OXq*uu4dfG$u3f2rhC$|h{t|HTcYscQjY%5$6mih!Jg1o{sDLTrpnsTJAAriK6aM}8#2925b6CjdKA`So zWH?~PGS^4OSxKQHsGAdjHMfz=W@XZFmCaS4xb6XmC-hc9H~I*cuq6KT%dWJR4l!j9IV7LM*MYkP+5qD zX@APd=`-_EbPI`;D3&d!SN)M&A<~}(LDD3x_^$E1L7vCZdfcByWSMiOY zAVBB!&09%#?=x8X(%r_h}K*y8A@4^f?pF+0UVz5`nHEu71C){7ige zQHc69f=Y$vr|AdkWSO|wG5R;Mlj}sj{(q^EiOj{K5!}lo`hniYha%8rBs4se!e2%E z*e&EtGMjzk>T`7`OUO|q;x)ISY3C|R2 zVc;|QQhbBadVzk0{lX%(JmkUCKIN5rl+j&NDj~U9V=SVvhOECa4aq5Uc3fy26ED3DX}TqX~*W&xmKMvz|9`FiR*GoNj_0 zweYe4^wUO(Vn|{Wb+n3}VF&79vRHiTp~qU-m?C5jwLI7aI$A6?S`N~+qkq$d=}&|} zcm*pl;?X@$4_yn47IK%X3=8{y#<5)_$2;j-;Kw2pG&k(6F@2deU97LrxY5 z1lbjxw!*?B(SME8ny5`-AAbiq!$C^uDS*9`GBMK4*7>&{C}x5sT8K=56jr!Z(YJe1 z(^ei4EyXT3!Zl>cQ4q+zw8SJf26zuu zhRH%_k>#k(cb({Tr*(Ih(tA8}i{kY&Zu2R_O zJY|Y8k&9XS!_Z_gyLVB+;E#3?4W;G84 zHDd;Q#3tr@0Vjj`Sh3zZvva3EaY@meQch+N2Y4VCh1vd20x(3`4|tIgX0ys&s8F^L zZ)FgUfIORpr-h8<8gpsO0_6>gI_8C=?lW1eeqSH|WhOlW(0`p)ydmn}i~O1+%2f_) ziN_3>kA*&Nt6b(o9wo)#zIGKmbI((uP!Ja`4l=w^Cyc4`HP-s-!54Xx-eGTaH(laM;BNAn z#}3M<;%(+P57!c$*hnOa4ARLAdm~p=q7s#;L?tRwiONkS{{vMKTjgl#XVd@y002ov JPDHLkV1mlhm#+W- literal 2829 zcmZ{mX*kr48pi)(Xvq57cg@(h8O<;zDU6+rol3@xeV3VJi9!t7_p%f*_E0HX2{D%J zBP9FwN@;|bP>yq*>wGvL&WHQ{UH5f8zwb{1_NpN}t1v470PMy_7^_nf|DCf;r~M~$ zuI3a>9y;ba0ML-icI*N=-I4?&D{}w{lLml$F#z!E zF+$hn99Iz-y2vfk2?5^+q@Yr%vwvKSUbeQkhHq`XokqQ!Ke8XXw0|5qf2loq=*My7 zI@1yvl7jkgDIqc%(o-1O*_A(itx)jeRbjqxUo#804hzRZ^%QpHknbTGlww)m|;YDYxT9js1L> zE}om%>LJ`gK$v89Jh zp^K~PORn-u7c4=`Q5beo!`3XleusIoE6M6N)l`TYI=B!BHzz^pmih{M=d;Qd7a4}? z?Y~(HBu~|B`VcV1S&GD`vS9B1*6#QfmTZbz47FD>8`@95rvFJ$ln9M!ELgb4v=;t& zi(w}^c^!q3*N&iB^-@3Lf#(k6Z5Hb3MP_*Jncng-V6+{C4W!E*Rqj_?cY(BV3SKCJ z`K~r1V`F%{t(zf{&r_Z5{@#XG)V@i3J1BpXVmc$mmez?HQs7c1;O{MRtVNIyvwb~; z)99rka!SnmKZd~5kj_eI`@9awjVhU<=H*@)k!(zprFIuMhb)&GFKYhWh4qnZ#f> z{_iCj*Cnr-=H>-}%teNSt)VUHA1HrbY@0Up^vhAl*?2dSjuE6i+eMt3*n^*H+9k}+ z);@$-VdM%%X!!`TWa7=rSBy1L_;=mr`(rv1OR$ygMW`;-QVxPYt`*@>EYXy5aiyIL+i3pBr7=CQ zEmpKIr92dqNm82~06jD!zzw&91SB4rmA&=4wu^uGR1Z|S1{%EK`xhn)ZYx>kQm*<} z-hf~WW>t=6qa*~+hH{nww)V*U znKY)o1X1y^8$x@eN26l5H53ETMiXHpv0oIDO7b-^g{9;n=bP0Y@L{ZC)*Lp$pmNXC zxkJ8gtu3)Hk5#rjc5F_8gTiW=--NNTn)qsb5C*r3LVhUqBzwl78t*jo#FSbTV?X6r z(H~cEH9ow%zSvQ*4>c%G2+vjvi=D(gs1Pu(u6q0*u<>; z(>B5%IX)=hft0W|lbOC>d5%y&6|jIOFC?m4xto}=0?DAxtMxgWiG5B;rP6!4{?@(j zacr(fw@i{?THYlbX55_Ge(KU`;F09LNXK10GtLSZLd%{0Z+Xt|k={v^D@nr1WSHq1 z=S2&Un{Ej62eC^vyvT!>%^P|mjwN}+=3Z~BxiS^p+#e z)qpYMu`r^><&a@&=2CY_G(VWznyj8Cs{+5h_UHE=kR(P$uO>O-6lEaL6kt z4&^$?Q3bi){Q-jpe`lyEiQV=f+SMjt!Woase`^oChdb@A60u2n}b7Sca1DpJ-j6hy7cY3E-6K=YzO79(EPlug@hNM2P@P<^1&ZV z9}d}2*e{N5%;manN*C zW=9BfYs&A-&QibVVW_=XsAKH8QPZD4rnO$vtq&Jyh3beLA*f@=`ND%3eIs`zH`aaO zh?N(*A@SpdZyD3+3;x#?JNk@fSGDNPCbBMJ zVfy>9P`dSy0&~w=Bnl7uy-#r&9j z{BqQ5MI9u%i2hBA$WfS+9kBFI{iEkrAzxs_=1Rm3As(IT%MJH9ZlzHOg*`Rjw0Nqwo?do5S&~#9B zq=<;P0ldijb3@FsjuuL`Yj@HjOLS-7H;Joe|Dpu*N;pc<6USV z)sd%)A>w^djIZT)PYWr1zZg$B#EZ;XSIZcYaLfswa^Z;d^R-`MMQ-bj^G|BO;Z!v} zQGvo}%*K)u3sISp+^NUI*oza2Z>nnJJ89(BC}FQL8mwRJ&D>0$jb^L;t@} TH)*?kDgeg%S253Zanb(*#Nrsf diff --git a/src/qt/res/movies/spinner-034.png b/src/qt/res/movies/spinner-034.png index d8432751daef0c6ca1d9779d4efc29b449547604..c26656ff17a5afb2a3051b075737f8f2bb062dab 100644 GIT binary patch delta 2412 zcmV-y36u7t7WNX5BYz1!NklL zQmb88O(*2FXk@9=*ddqAuI94vkTO%N%i40{(sfv&*lB2FPG@GgG%z#EL*^+l28i

x_`uMV#NwrIy=l1vYEuM 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 diff --git a/src/qt/res/movies/spinner-035.png b/src/qt/res/movies/spinner-035.png index c89c959c948fa0176104c2af5a83f1097cfff592..e471f950a3e75bcaf83e38a85303360d718bbbed 100644 GIT binary patch delta 2396 zcmV-i38VIv7UmL=BYz1kNkl@WaA6B|n9)oj zpEWEY2|^WaG}%<4p`lUBd#oTf6rtKkZ-(i9u2RBi!a@yb6g#|Nx}RgrBQmtsHHmWq zP>l<0VhHxo0h-Mj5vay>4l$kZP+8Y3DiuIAG|ut_eM4hihftyeRO1>4xHA+~QzX;5 zt_xM;B#+S9`hOzqVhz{)K>d>6G0OU`L?`k%QKYTU=MYEpkAPm;a1t{I2Us^66ccqgCY{J&d9ri-#wQw$R8dR?4T`@O(xnB^ zSaCCylO2pzbud|%2-CRENnT(!iQL79ig(^7RoH#$oEG0c!vp5q+CltH7iJyBOvH|z zTiLC6=N!4BcRNVgYYjgq+Dye1&&xU>&$F4)O@GsI@iV>>-)dlkXjE*(>Fnu7meI{D znBCc`Gm&E~reE`Jx?8EPUL#I9!s|L*;w9#r!%9T5lzQbfj`E%6ePkzv*Ob0chK_2< z;UBsNX%^vuh8fNn9ggo+27A04#RjD>^pNgUqnV|v>fU2ypn*o~i0wuayxyIu4A*uN z?|(<7IGMsxG+e3I3Q2|n8XKsu0F2{J4e3;$oxt?qL$!xDN3=t$(nqm3%WW`gXD6%l=WcYpa{14^Lm{o^~*O z$rLHPubqL>w}%x5e5|NiCbzJK^{j4}uNqDY<%+!AAmjJxc!jZeoG3+f^HZ;1)bVTw zc%knr7=ObZ!Z0?7{!j&@6qC2nmBqZf!=S>mlZoXzL&>o^2U(aK@Ykw3$ zG7Ff^3MmR!WYMTL}YECH4&7S?=3YO8*2gc%sXcF`)YG&am$C<@M>P0W^rF-0W4 zcN?p54~jr@O-&2M&?wB|gpukfj`Ly?cbLgEc&Sm{yLdqKG;cEfd>KJD z#xaW9iPiPABFGZig;R_%+Ei~56~T!PrDLP{7JuS0)l{;VIXcR%yU6Nllo?&P5zc%? zE-km+qT}FRsyv*_k9ky)gmREA|CsB*@&%QFdQ9Dncn^z}J+DE4Q$ zB72@@d}v|g*NQZI314qVfAQ=T`dTlRHZBu&zDBW6d5A%6f+FKx$BS)d%WeEbEX3GH zzZUPND@tYm6R6_`k%|nAMh#E3aj)E^*a#&I@UfnQc~x1&6QG2Mjb0pA3|h-mB(!?q zWaZ?a_Yz$@acommFn^pQEs$n=sZK%Sj#j#aF|1eg@Hx3Y=4XXscWSIO)=_9ltGuiO z^&nY(?V61oWkp$umnC&Ei;Idk%NZP4D#ylX-NTY6_@VBX4r2swD~lOZz201=T+LeY z0?$}QFqIEoTa+g5R6tRr3oBU?zxdozv;>S{8dK}oMDog(Y})cWjUh8 zbP;H8b}3I9-iI99)KNV%ii^NZ}Trv3u3Q1rRk8xPxy8plD zhfSt$ngnTd)pq-Nq{|Qi>ae$s{SO>)ooz z|9Pkyibx9H88ticY~!+rk=RB`i|ItM-tQeM`p*>#%sU36rXd&bJjbb}l3&obg|Z0a zUZ1mOZGApr=8bWT)Yjny61tQ~cLCNG_eRNb93KX{hfO9Ay=$!Eg=QYkKl^PO+)<>t0qc#;9byS)S9k zb=?GSuje?$%w?!GuAT60E(Wqz89saRhy@J6Zsn_f>~!KDKZm5%rYd=T6Fec!)YyhJx1h zZBF{K-lJfuo*fJf&411ihLcRTvWGnsk<*k}3)vP)BFVugs&6(cwEqEcty^09ZLZY- O0000004R=004l4008;_004mL z004C`008P>0026e000+nl3&F}00002VoOIv0063uBQgL0010qNS#tmYNzwoSNzwtR zMT+S@AW@t@3q%jd+iIiaT_rS&6Zx{a1)>oJ=*l_C7Q@M2GflS zHgE#1Bhj^z3(9zMU;Q%j^Y}2fXDm3zL&uY$svnVTyS>1TD`+H zvX6^o(bb@hkD=sH&v6=JmnhV;pZ%oL7mq=!9^}!BVoIG_uXflhIwkC&n!Y3(wDL2G z5nSUafmkI9Iu-1qh!ipmT50qlhdVgXvHYC2!%ZfCpjKf*{J+%kF%$6Et(xpKw{=R{ zfyO-~7=KDIfbqa-YGU!bdg#T2yv%1*xAH}UrHZvowDYxl+TTSBXe5x$SngvOcbV=# zk?923VjoefNv81>A5v=SD~6VfJQZ#6&C|S_#hi$Mq)r2`5*KX(X5c4>6(-lCR6eF} zEV$;qS;SEqBBptY$sOMA7IpC2n@M9oXUVD*+UCyb_> z8C(o$)yM|&@JENHo7tQ;L9&Qdfa-R|(T7FQm`u51 z=yha-=+J&_RZj2mCU!(0!+Bq!$aHjG5)4Pn(3#DOVfQgMWRLUmU4=p^<2lnIlYcvS zlM2O%MP%Ex(P%uY@KTDIPJD}3vPdD|+ii*rd3aShhZeUO(=rTEOvVa+7G|-;vrKHe zhkkAR4r%;Zv9A{L4LfLhnWuQO{}A`JMK`>Uo8>%@MiA*6$VzeCTGrY@G?6{xaOGr+ zs%2u>URcMXh-_6and}zFu4It)>wh#yv01#V2v58DRmc;yyxoqt(6=21=V5qqc%vy~p48j*yThB)JBOfH_l=BuJ@ipqG zXD_GQb!yhY8v2kPR-eg04!5J<7I1ODm{@a~;ijIpVjJksU&UQ{p;-#%T7L~}VcrFC zi~)EDUjuyB!Wg9u#cfdd8V~ z)ZEk^&NZR-BQD_ViRMn~!s@(aTSxRx62s~mD51f;?c7L2`CHDxmhv;Gr zQJqG?|EQv$<3xLiCdvsKtsx3mg}MfMIZkwln9AH_)zpP^LR=_`A&wL6BD~x>>da(v zn(xdI7n7v2ACGw#2+FM657G={Jiq8t$~ zW7*%LuS+~Aw(Y7oO)F!B^{$1+Ulhme>$x|A{?b@0^tD7xZG1u8$8}bT=LhXZuHwYI zmiO8mE!X&kn27PAaFCRzNR_={*L4Fwa~12fn%CO6RvuC;g!S|fY3E`vpD0FMYuAB@ zMlX&i2Cd;WdViW8c%V}FcSEMGi&R!9G8oP?!XBDI%r{6#TrK2MOGsjgqK8Y&3Tc_h zi;C5$voK<9ZwkqLU_f;nkF>h4X-rpUl&ufhN#mJGnWE)x2HP9T(HN~vstOtqKQMgL zZicZ-@oYiJv9epKYjtXP*8YfBcA(t-{9V9J~>X%1n@H7Aaz*3k$>G1xfCeZ+{o+C z^x%8^$3PF1@PJb^0peJ!Oh?ptQY3mO>lE!T@@-sb#4(3`1}{+ODo;3*e|;03c#dPD zFjf3ee1A0y6vEfDoSrx@ z3Klze4Mc?mp5a}NP(vZV7w&btnbzX2SzF6lW`9KczF`m=JxM1?Aq=Q6+KFXVhMx}~F{D$Gy zng(`G3m1>K`5r?F2ie6I4x5X=cMPI#PP4KJ=vWN^`mM_aiht)p{^xunE~epSOm25S@!cXK`a4r7IMS&QIAs(64hHd8^m z!5v_5aW7+NqChxujwvKDj`vzM?aNt7KYIh2_QOX{p69Dps0R3ghhv?p3m@azA>MWf zb;{;hy;`09FJql1irI{hOv66}i6e*e9DlR&pCF_0r_EJtoS9 zh%B@PF22t87IBDL7TRYHMh|h^#gb+>RO?vH0Be1jj^Y@(@sP`O(tvU{u}MsZzJCRX z2H__S52cP@?z@c`#Qy+BVKFImpK+4_001R)MObuXVRU6WV{&C-bY%cCFflYOF)=ML zHB>S&Iy5#qF*hqPF*-0X-iqyC0000bbVXQnWMOn=I&E)cX=ZrD%PDHLkV1h|2KN Date: Wed, 14 Jan 2015 13:49:43 +0100 Subject: [PATCH 0178/2337] contrib: improve optimize-pngs.py - Check that image contents match pre- and post- crushing. - Also remove use of external tool to compute sha256 in favor of hashlib. - contrib: remove all use of shell=True in strip_pngs.py Using `shell=True` can be a security hazard. See e.g. https://docs.python.org/2/library/subprocess.html#subprocess.check_output --- contrib/devtools/optimize-pngs.py | 42 ++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py index 774968fc088..38aaa00f312 100755 --- a/contrib/devtools/optimize-pngs.py +++ b/contrib/devtools/optimize-pngs.py @@ -3,12 +3,28 @@ import os import sys import subprocess +import hashlib +from PIL import Image + +def file_hash(filename): + '''Return hash of raw file contents''' + with open(filename, 'rb') as f: + return hashlib.sha256(f.read()).hexdigest() + +def content_hash(filename): + '''Return hash of RGBA contents of image''' + i = Image.open(filename) + i = i.convert('RGBA') + data = i.tostring() + return hashlib.sha256(data).hexdigest() #optimize png, remove various color profiles, remove ancillary chunks (alla) and text chunks (text) #pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text +pngcrush = 'pngcrush' +git = 'git' folders = ["src/qt/res/movies", "src/qt/res/icons", "src/qt/res/images"] -basePath = subprocess.check_output("git rev-parse --show-toplevel", shell=True).rstrip('\n') +basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n') totalSaveBytes = 0 outputArray = [] @@ -19,31 +35,39 @@ for folder in folders: if extension.lower() == '.png': print("optimizing "+file+"..."), file_path = os.path.join(absFolder, file) - fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : subprocess.check_output("openssl dgst -sha256 "+file_path, shell=True).rstrip('\n')}; + fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : file_hash(file_path)}; + fileMetaMap['contentHashPre'] = content_hash(file_path) pngCrushOutput = "" try: - pngCrushOutput = subprocess.check_output("pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text "+file_path+" >/dev/null 2>&1", shell=True).rstrip('\n') + pngCrushOutput = subprocess.check_output( + [pngcrush, "-brute", "-ow", "-rem", "gAMA", "-rem", "cHRM", "-rem", "iCCP", "-rem", "sRGB", "-rem", "alla", "-rem", "text", file_path], + stderr=subprocess.STDOUT).rstrip('\n') except: print "pngcrush is not installed, aborting..." sys.exit(0) #verify - if "Not a PNG file" in subprocess.check_output("pngcrush -n -v "+file_path+" >/dev/null 2>&1", shell=True): + if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT): print "PNG file "+file+" is corrupted after crushing, check out pngcursh version" sys.exit(1) - - fileMetaMap['sha256New'] = subprocess.check_output("openssl dgst -sha256 "+file_path, shell=True).rstrip('\n') + fileMetaMap['sha256New'] = file_hash(file_path) + fileMetaMap['contentHashPost'] = content_hash(file_path) + + if fileMetaMap['contentHashPre'] != fileMetaMap['contentHashPost']: + print "Image contents of PNG file "+file+" before and after crushing don't match" + sys.exit(1) + fileMetaMap['psize'] = os.path.getsize(file_path) outputArray.append(fileMetaMap) print("done\n"), print "summary:\n+++++++++++++++++" for fileDict in outputArray: - oldHash = fileDict['sha256Old'].split("= ")[1] - newHash = fileDict['sha256New'].split("= ")[1] + oldHash = fileDict['sha256Old'] + newHash = fileDict['sha256New'] totalSaveBytes += fileDict['osize'] - fileDict['psize'] print fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n" -print "completed. Total reduction: "+str(totalSaveBytes)+" bytes" \ No newline at end of file +print "completed. Total reduction: "+str(totalSaveBytes)+" bytes" From 301cd2a3a96a3a16384bdc862858734f4aee1df6 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 12 Jan 2015 20:59:58 +0000 Subject: [PATCH 0179/2337] Use text-color icons for system tray Send/Receive menu entries --- src/qt/bitcoingui.cpp | 20 ++++++++++++++++++-- src/qt/bitcoingui.h | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 2810eae0528..3d41dc89f1f 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -76,12 +76,14 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : historyAction(0), quitAction(0), sendCoinsAction(0), + sendCoinsMenuAction(0), usedSendingAddressesAction(0), usedReceivingAddressesAction(0), signMessageAction(0), verifyMessageAction(0), aboutAction(0), receiveCoinsAction(0), + receiveCoinsMenuAction(0), optionsAction(0), toggleHideAction(0), encryptWalletAction(0), @@ -256,6 +258,10 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle) sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); tabGroup->addAction(sendCoinsAction); + sendCoinsMenuAction = new QAction(TextColorIcon(":/icons/send"), sendCoinsAction->text(), this); + sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip()); + sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip()); + receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this); receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)")); receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip()); @@ -263,6 +269,10 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle) receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); tabGroup->addAction(receiveCoinsAction); + receiveCoinsMenuAction = new QAction(TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this); + receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip()); + receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip()); + historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this); historyAction->setStatusTip(tr("Browse transaction history")); historyAction->setToolTip(historyAction->statusTip()); @@ -277,8 +287,12 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle) connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage())); connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); + connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); + connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); #endif // ENABLE_WALLET @@ -475,7 +489,9 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled) { overviewAction->setEnabled(enabled); sendCoinsAction->setEnabled(enabled); + sendCoinsMenuAction->setEnabled(enabled); receiveCoinsAction->setEnabled(enabled); + receiveCoinsMenuAction->setEnabled(enabled); historyAction->setEnabled(enabled); encryptWalletAction->setEnabled(enabled); backupWalletAction->setEnabled(enabled); @@ -522,8 +538,8 @@ void BitcoinGUI::createTrayIconMenu() // Configuration of the tray icon (or dock icon) icon menu trayIconMenu->addAction(toggleHideAction); trayIconMenu->addSeparator(); - trayIconMenu->addAction(sendCoinsAction); - trayIconMenu->addAction(receiveCoinsAction); + trayIconMenu->addAction(sendCoinsMenuAction); + trayIconMenu->addAction(receiveCoinsMenuAction); trayIconMenu->addSeparator(); trayIconMenu->addAction(signMessageAction); trayIconMenu->addAction(verifyMessageAction); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 7509a00734b..3216a7398ed 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -90,12 +90,14 @@ private: QAction *historyAction; QAction *quitAction; QAction *sendCoinsAction; + QAction *sendCoinsMenuAction; QAction *usedSendingAddressesAction; QAction *usedReceivingAddressesAction; QAction *signMessageAction; QAction *verifyMessageAction; QAction *aboutAction; QAction *receiveCoinsAction; + QAction *receiveCoinsMenuAction; QAction *optionsAction; QAction *toggleHideAction; QAction *encryptWalletAction; From 16a5c18cea7330bd68dc9d2f768eb518af88795b Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 13 Jan 2015 17:43:39 -0800 Subject: [PATCH 0180/2337] Add a -rpckeepalive and disable RPC use of HTTP persistent connections. It turns out that some miners have been staying with old versions of Bitcoin Core because their software behaves poorly with persistent connections and the Bitcoin Core thread and connection limits. What happens is that underlying HTTP libraries leave connections open invisibly to their users and then the user runs into the default four thread limit. This looks like Bitcoin Core is unresponsive to RPC. There are many things that should be improved in Bitcoin Core's behavior here, e.g. supporting more concurrent connections, not tying up threads for idle connections, disconnecting kept-alive connections when limits are reached, etc. All are fairly big, risky changes. Disabling keep-alive is a simple workaround. It's often not easy to turn off the keep-alive support in the client where it may be buried in some platform library. If you are one of the few who really needs persistent connections you probably know that you want them and can find a switch; while if you don't and the misbehavior is hitting you it is hard to discover the source of your problems is keepalive related. Given that it is best to default to off until they're handled better. --- src/init.cpp | 1 + src/rpcserver.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index d6f1e1cb9f9..f851fcbbca4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -380,6 +380,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -rpcport= " + strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 8332, 18332) + "\n"; strUsage += " -rpcallowip= " + _("Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times") + "\n"; strUsage += " -rpcthreads= " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n"; + strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 0) + "\n"; strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n"; strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n"; diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index a070ab5bbe7..9ebacdbe2e0 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -953,7 +953,7 @@ void ServiceConnection(AcceptedConnection *conn) ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE); // HTTP Keep-Alive is false; close connection immediately - if (mapHeaders["connection"] == "close") + if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", false))) fRun = false; // Process via JSON-RPC API From 56c1093dae0c523f9f643f00c67414691272a983 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 14 Jan 2015 12:45:11 +0100 Subject: [PATCH 0181/2337] fix tests for #5655 --- qa/rpc-tests/httpbasics.py | 3 +++ qa/rpc-tests/test_framework.py | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index 85e85e7f0fb..7a9857a7710 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -21,6 +21,9 @@ except ImportError: import urlparse class HTTPBasicsTest (BitcoinTestFramework): + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir, extra_args=[['-rpckeepalive']]*4) + def run_test(self): ################################################# diff --git a/qa/rpc-tests/test_framework.py b/qa/rpc-tests/test_framework.py index 6c4ec073c28..4c8a11b821d 100755 --- a/qa/rpc-tests/test_framework.py +++ b/qa/rpc-tests/test_framework.py @@ -33,8 +33,11 @@ class BitcoinTestFramework(object): print("Initializing test directory "+self.options.tmpdir) initialize_chain(self.options.tmpdir) + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir) + def setup_network(self, split = False): - self.nodes = start_nodes(4, self.options.tmpdir) + self.nodes = self.setup_nodes() # Connect the nodes as a "chain". This allows us # to split the network between nodes 1 and 2 to get From 1dd8ee72afc26191da51d8d3a5590eab7c9368f6 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 14 Jan 2015 16:36:48 +0100 Subject: [PATCH 0182/2337] improve tests for #5655 --- qa/rpc-tests/httpbasics.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index 7a9857a7710..8cbf1d7f4c4 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -22,7 +22,7 @@ except ImportError: class HTTPBasicsTest (BitcoinTestFramework): def setup_nodes(self): - return start_nodes(4, self.options.tmpdir, extra_args=[['-rpckeepalive']]*4) + return start_nodes(4, self.options.tmpdir, extra_args=[['-rpckeepalive=1'], ['-rpckeepalive=0'], [], []]) def run_test(self): @@ -74,6 +74,29 @@ class HTTPBasicsTest (BitcoinTestFramework): assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, False) #now the connection must be closed after the response + #node1 (2nd node) is running with disabled keep-alive option + urlNode1 = urlparse.urlparse(self.nodes[1].url) + authpair = urlNode1.username + ':' + urlNode1.password + headers = {"Authorization": "Basic " + base64.b64encode(authpair)} + + conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port) + conn.connect() + conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read(); + assert_equal('"error":null' in out1, True) + assert_equal(conn.sock!=None, False) #connection must be closed because keep-alive was set to false + + #node2 (third node) is running with standard keep-alive parameters which means keep-alive is off + urlNode2 = urlparse.urlparse(self.nodes[2].url) + authpair = urlNode2.username + ':' + urlNode2.password + headers = {"Authorization": "Basic " + base64.b64encode(authpair)} + + conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port) + conn.connect() + conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read(); + assert_equal('"error":null' in out1, True) + assert_equal(conn.sock!=None, False) #connection must be closed because bitcoind should use keep-alive by default if __name__ == '__main__': HTTPBasicsTest ().main () From 6715efb9ca5cabeb07ae4ba8390a6e1b7638f66c Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Thu, 8 Jan 2015 14:42:04 +0100 Subject: [PATCH 0183/2337] [Qt] Payment request expiration bug fix (re-done) - this is based on #4122 (which can be closed) Currently a payment request is only checked for expiration upon receipt. It should be checked again immediately before sending coins to prevent the user from paying to an expired invoice which would then require a customer service interaction. - add static verifyExpired() function to PaymentServer to be able to use the same validation code in GUI and unit-testing code - extend unit tests to use that function and also add an unit test which overflows, because payment requests allow expires as uint64, whereas we use int64_t for verification of expired payment requests --- src/qt/paymentserver.cpp | 25 +++++++---- src/qt/paymentserver.h | 2 + src/qt/sendcoinsdialog.cpp | 4 ++ src/qt/test/paymentrequestdata.h | 72 ++++++++++++++++++++++++++++++ src/qt/test/paymentservertests.cpp | 34 +++++++++++++- src/qt/walletmodel.cpp | 8 +++- src/qt/walletmodel.h | 5 ++- 7 files changed, 137 insertions(+), 13 deletions(-) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 8703966606a..0187e4c2299 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -518,8 +518,6 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins return false; if (request.IsInitialized()) { - const payments::PaymentDetails& details = request.getDetails(); - // Payment request network matches client network? if (!verifyNetwork(request.getDetails())) { emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), @@ -528,16 +526,15 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins return false; } - // Expired payment request? - if (details.has_expires() && (int64_t)details.expires() < GetTime()) - { - emit message(tr("Payment request rejected"), tr("Payment request has expired."), + // Make sure any payment requests involved are still valid. + // This is re-checked just before sending coins in WalletModel::sendCoins(). + if (verifyExpired(request.getDetails())) { + emit message(tr("Payment request rejected"), tr("Payment request expired."), CClientUIInterface::MSG_ERROR); return false; } - } - else { + } else { emit message(tr("Payment request error"), tr("Payment request is not initialized."), CClientUIInterface::MSG_ERROR); @@ -756,3 +753,15 @@ bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails } return fVerified; } + +bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails) +{ + bool fVerified = (requestDetails.has_expires() && (int64_t)requestDetails.expires() < GetTime()); + if (fVerified) { + const QString requestExpires = QString::fromStdString(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", (int64_t)requestDetails.expires())); + qWarning() << QString("PaymentServer::%1: Payment request expired \"%2\".") + .arg(__func__) + .arg(requestExpires); + } + return fVerified; +} diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 9330e9a89cf..db5f44ff1df 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -93,6 +93,8 @@ public: // Verify that the payment request network matches the client network static bool verifyNetwork(const payments::PaymentDetails& requestDetails); + // Verify if the payment request is expired + static bool verifyExpired(const payments::PaymentDetails& requestDetails); signals: // Fired when a valid payment request is received diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index ffee56131de..ce4a62d1b07 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -529,6 +529,10 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn case WalletModel::InsaneFee: msgParams.first = tr("A fee higher than %1 is considered an insanely high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000)); break; + case WalletModel::PaymentRequestExpired: + msgParams.first = tr("Payment request expired!"); + msgParams.second = CClientUIInterface::MSG_ERROR; + break; // included to prevent a compiler warning. case WalletModel::OK: default: diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index 67c9a41e610..50636d7c67f 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -361,3 +361,75 @@ gAFwThsozZxkZxzCn4R8WxNiLFV6m0ye9fEtSbolfaW+EjBMpO03lr/dwNnrclhg\ ew+A05xfZztrAt16XKEY7qKJ/eY2nLd0fVAIu/nIt+7/VYVXT83zLrWc150aRS7W\ AdJbL3JOJLs6Eyp5zrPbfI8faRttFAdONKDrJgIpuW1E3g==\ "; + +// +// Expired payment request (expires is set to 1 = 1970-01-01 00:00:01) +// +const char* paymentrequest2_cert2_BASE64 = +"\ +Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\ +BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\ +ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\ +IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\ +mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\ +wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\ +RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\ +KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\ ++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\ +3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\ +tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\ +yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\ +dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iQgoEdGVzdBIgCICt4gQS\ +GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYiNLUpQUgASoQVGVzdGluZyB0ZXN0\ +bmV0ISqAATXq9A5nmJgtmee/bQTeHeif4w1YYFPBlKghwx6qbVgXTWnwBJtOQhhV\ +sZdzbTl95ENR7/Y7VJupW9kDWobCK7zUUhLAzUlwmLlcx6itHw8LTUF5HK+AwsZm\ +Zs85lISGvOS0NZW/ENa6l+oQRnL87oqVZr/EDGiuqjz6T0ThQi0l\ +"; + +// +// Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max. int64_t) +// +const char* paymentrequest3_cert2_BASE64 = +"\ +Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\ +BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\ +ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\ +IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\ +mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\ +wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\ +RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\ +KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\ ++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\ +3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\ +tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\ +yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\ +dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iSgoEdGVzdBIgCICt4gQS\ +GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYyNfZpQUg//////////9/KhBUZXN0\ +aW5nIHRlc3RuZXQhKoABNwi8WnMW4aMvbmvorTiiWJLFhofLFnsoWCJnj3rWLnLh\ +n3w6q/fZ26p50ERL/noxdTUfeFsKnlECkUu/fOcOrqyYDiwvxI0SZ034DleVyFU1\ +Z3T+X0zcL8oe7bX01Yf+s2V+5JXQXarKnKBrZCGgv2ARjFNSZe7E7vGg5K4Q6Q8=\ +"; + +// +// Unexpired payment request (expires is set to 0x8000000000000000 > max. int64_t, allowed uint64) +// +const char* paymentrequest4_cert2_BASE64 = +"\ +Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\ +BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\ +ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\ +IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\ +mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\ +wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\ +RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\ +KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\ ++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\ +3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\ +tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\ +yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\ +dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iSwoEdGVzdBIgCICt4gQS\ +GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYt+HZpQUggICAgICAgICAASoQVGVz\ +dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\ +HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\ +d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\ +"; diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index e6cdb58ef5d..04935192c85 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -143,7 +143,38 @@ void PaymentServerTests::paymentServerTests() QVERIFY(r.paymentRequest.IsInitialized()); QCOMPARE(PaymentServer::verifyNetwork(r.paymentRequest.getDetails()), false); - // Just get some random data big enough to trigger BIP70 DoS protection + // Expired payment request (expires is set to 1 = 1970-01-01 00:00:01): + data = DecodeBase64(paymentrequest2_cert2_BASE64); + byteArray = QByteArray((const char*)&data[0], data.size()); + r.paymentRequest.parse(byteArray); + // Ensure the request is initialized + QVERIFY(r.paymentRequest.IsInitialized()); + // compares 1 < GetTime() == false (treated as expired payment request) + QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true); + + // Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max. int64_t): + // 9223372036854775807 (uint64), 9223372036854775807 (int64_t) and -1 (int32_t) + // -1 is 1969-12-31 23:59:59 (for a 32 bit time values) + data = DecodeBase64(paymentrequest3_cert2_BASE64); + byteArray = QByteArray((const char*)&data[0], data.size()); + r.paymentRequest.parse(byteArray); + // Ensure the request is initialized + QVERIFY(r.paymentRequest.IsInitialized()); + // compares 9223372036854775807 < GetTime() == false (treated as unexpired payment request) + QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), false); + + // Unexpired payment request (expires is set to 0x8000000000000000 > max. int64_t, allowed uint64): + // 9223372036854775808 (uint64), -9223372036854775808 (int64_t) and 0 (int32_t) + // 0 is 1970-01-01 00:00:00 (for a 32 bit time values) + data = DecodeBase64(paymentrequest4_cert2_BASE64); + byteArray = QByteArray((const char*)&data[0], data.size()); + r.paymentRequest.parse(byteArray); + // Ensure the request is initialized + QVERIFY(r.paymentRequest.IsInitialized()); + // compares -9223372036854775808 < GetTime() == true (treated as expired payment request) + QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true); + + // Test BIP70 DoS protection: unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1]; GetRandBytes(randData, sizeof(randData)); // Write data to a temp file: @@ -151,7 +182,6 @@ void PaymentServerTests::paymentServerTests() tempFile.open(); tempFile.write((const char*)randData, sizeof(randData)); tempFile.close(); - // Trigger BIP70 DoS protection QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); delete server; diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 6006a7bd7b6..57596b77bd7 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -6,6 +6,7 @@ #include "addresstablemodel.h" #include "guiconstants.h" +#include "paymentserver.h" #include "recentrequeststablemodel.h" #include "transactiontablemodel.h" @@ -294,11 +295,16 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran LOCK2(cs_main, wallet->cs_wallet); CWalletTx *newTx = transaction.getTransaction(); - // Store PaymentRequests in wtx.vOrderForm in wallet. foreach(const SendCoinsRecipient &rcp, transaction.getRecipients()) { if (rcp.paymentRequest.IsInitialized()) { + // Make sure any payment requests involved are still valid. + if (PaymentServer::verifyExpired(rcp.paymentRequest.getDetails())) { + return PaymentRequestExpired; + } + + // Store PaymentRequests in wtx.vOrderForm in wallet. std::string key("PaymentRequest"); std::string value; rcp.paymentRequest.SerializeToString(&value); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index d8df25f6606..9916d11f939 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -40,7 +40,7 @@ public: explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message): address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} - // If from an insecure payment request, this is used for storing + // If from an unauthenticated payment request, this is used for storing // the addresses, e.g. address-A
address-B
address-C. // Info: As we don't need to process addresses in here when using // payment requests, we can abuse it for displaying an address list. @@ -111,7 +111,8 @@ public: DuplicateAddress, TransactionCreationFailed, // Error returned when wallet is still locked TransactionCommitFailed, - InsaneFee + InsaneFee, + PaymentRequestExpired }; enum EncryptionStatus From 0c03a93e70c9491fde7c4ee283bb4b729212d3b0 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Thu, 15 Jan 2015 14:30:44 +0100 Subject: [PATCH 0184/2337] [Qt] add debug logging for -rootcertificates option - now logs if -rootcertificates="" was used to disable payment request authentication via X.509 certificates - also logs which file is used as trusted root cert, if -rootcertificates is set --- src/qt/paymentserver.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 8703966606a..d642fdae363 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -124,19 +124,22 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) // and get 'I don't like X.509 certificates, don't trust anybody' behavior: QString certFile = QString::fromStdString(GetArg("-rootcertificates", "-system-")); - if (certFile.isEmpty()) - return; // Empty store + // Empty store + if (certFile.isEmpty()) { + qDebug() << QString("PaymentServer::%1: Payment request authentication via X.509 certificates disabled.").arg(__func__); + return; + } QList certList; - if (certFile != "-system-") - { + if (certFile != "-system-") { + qDebug() << QString("PaymentServer::%1: Using \"%2\" as trusted root certificate.").arg(__func__).arg(certFile); + certList = QSslCertificate::fromPath(certFile); // Use those certificates when fetching payment requests, too: QSslSocket::setDefaultCaCertificates(certList); - } - else - certList = QSslSocket::systemCaCertificates (); + } else + certList = QSslSocket::systemCaCertificates(); int nRootCerts = 0; const QDateTime currentTime = QDateTime::currentDateTime(); From af95b17d0da91a9a1bd92bb1e0428c72ec52ebbb Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 9 Jan 2015 11:39:45 +0100 Subject: [PATCH 0185/2337] [Qt] resize oversized icons --- src/qt/res/icons/add.png | Bin 712 -> 15685 bytes src/qt/res/icons/filesave.png | Bin 2067 -> 17065 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png index 7e46672f2dfb20f3e168b5394550b39ccb1e8dff..791822dc24777f308ff9e361ae6ca1d9c2ef8740 100644 GIT binary patch literal 15685 zcmeI3e^3fPSn59Bt-8N*?q%>jXPfcT5Oy**gCyS>~l z-a)AaF=OHkV~v>#{-(95(-^=eCTOjkw$@2vY6cTg9LI}vEEpnKZNylUzI%5Z#|yl% zZ94sDcLsK!_j#Z1v-^3U=e_-BU&+sXHZfsd0)}CUIoYNHa9$<;O`i(>_YQUygVPLm zb_tJRIbGsk%z>=U!x*OTW-Y}+vH3ZY=A25(##tGq&*=uUG0d>k=cedNMvz&VGS-zL zAN+l%T*lfmmoLGC2<;(tMv+k zAhkrUd%OJmCW=ol)!l`9Op2Gsw{s5p)4~~_JoJLhpyf{}GnWeo0il^O8S!Kj&$k|HxX2j>B|#TYdPe4^o~s9>3qIWAtH zTr`toGJ*jm%i2h_T0;=b5(@M;tyXAht4*ONtab&HW+$k$bgf=(1?uC%$4Q$wx=L)7 zu(SuHq=h){|&%BodpHFmp#(&`w6#-^dvG-K7Jr_m$QQQ_mH^E@or<|s$h9P#e| z-4qkZj7ycx@}M}Yqly-kZg3+jWL_LQI^uA!!41hxd3Z)_w+#76zeRSi$Oa|G1lyLR zXmKku(qcC-HUmCpbo90&k>N0Q`~p50<&b_<_~bdf<%|o}P$8+{tjR@q&MtT<53{Tc z)WkP7dPs6?46JRy#eLtw{ts4xr`G*;kCg7n zz=JJYXfen3)W}vaz6TBBuMi3P7t|6J>>I*>j~g4!9GYJ&_MxLHIA5Et5)bgc0*-KO zv>%Qw`G(kNKO8$6y28Z@Ms+wHG#nKr{#b@K^Fr`m#~9OeI*rbN!^3byKI>x~#U>W) zy1clT=s~7n4D6UNuw=5pC`ULjv{+GZV8Ip)je_?(@M?)i-Yv&=-X6< zw4@{u5VR@bLi2&V5-tb`+LUmi`9NL?7X$=tO1RK`Ag_cA0)jRrTxdR!SHcAWL7NgT zG#|(-;evpmO$is859F0_K|s)^gbU3F@=CZMAZSyKwb$K1O#nLxX^qcuY?N%f;J^wXg-iv!UX|An-VTGAIK}=f`Fh+2^X3VpTo4enDd9r%fxHqf2ngDgaH07?UI`Zj1Z_&V(0m}T zgbMSOV4R;Mm6{eiE@rnlcYIIt*T#(pH|`p2eW%y3<@S$q=ItF=tGM*Hw{|~j zE`053S5mz{zIFPlz~;~?wrI-n_t|T^WjU|@?%F?MhNkyn)4sSk+Whj+|uhlE!4eP*Z=Op#QLY~cC4@FVd+jts5x?A&N@HhCC*LJJ@Th31>S3aB7(AmDb>*$6p zXZ9rxtqwRE50zC-9hmdt4?m(yQxp&$T$6@v?Z&UYd^TygeD;nRpBAmTj~TmL zdJ9cAOik}LE>sq;II;6%?TV>+QvlkBRt0+4gxcyCJ{H_2fctP_a*+Aw+W0-GJ0Ctj zWD49kA{(e3-q`PM^3T5&-;vPt)%!h39rTwE`|rhi&*rHc4(s^}rvRdHf{&4o7q z*Nu;qtuCmz<^Q57Irj3piksV}ys|#8aMMem(3I}1K=4$*C^os{>aNZ>Z1wYp@E;s~ SbU)}1EGH}1)cQ>6hJOLQ>y`8X delta 689 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 VdN^#c1Kj~s;qS9+N8@%H`!5ZNi5dU^ From 652eb904df301efff271274624faba16b7539311 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 9 Jan 2015 11:46:30 +0100 Subject: [PATCH 0186/2337] [Qt] change transaction table column width make enought space for the new icons --- src/qt/res/icons/add.png | Bin 15685 -> 784 bytes src/qt/res/icons/filesave.png | Bin 17065 -> 2359 bytes src/qt/transactionview.h | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png index 791822dc24777f308ff9e361ae6ca1d9c2ef8740..1442b4e85e99d1d716c6baa611991b68d701c3ac 100644 GIT binary patch delta 761 zcmV=*)1Sm_h0a6j-m&=$BK_!IKYXa1gVv4cOdS(Yz07QLS{P2gw>*Wo{ay?}Nc*tsm) zxs?XI#@(dtnf1G&!>VP<(9Y@1&aqY`_^kakwj%=mSAW`e&a*{;A65wZeh$6CSAl+o z!TV<50zLmye{lX>K@>UpeIQ@z*~Zzq$ThO!PTWWcPaYNbpFuPWufzB zp>BMfZ+vuXU%;)s2CqswJUg^SnYXrd?b`kw`!?R)waMa+y|-->57QXt?EydSn3wiD zuIzXAEPs7#(~Y%p@Q3!7W_b3Y35X_lYrGqF8My;&0h_?OE%bS3{oo3)Z0}tFp4;m} z=QNLir@#xFBV7Vs*%FL3;JvNz+OW25TU#5}_GVcpApS=^o5B>^p5`>u*Mes4{hwkJ zxFh(o76NIhTh!pITFmJSzJ}I^Ye9a@;Opp-6LMGZO@aG@Z=uHqUBP$IgR!pQ33~Kf zn;XOouI)RtK~4N!ind_VCS&n}Ya2an6d6CbwnEirzwv`>JL`f<8@3lv)%;2VMc;BF ra7Ew(7q}vDfhz(RxFT?YS2(`_m4OLqKqX2J00000NkvXXu0mjfxO{tJ literal 15685 zcmeI3e^3fPSn59Bt-8N*?q%>jXPfcT5Oy**gCyS>~l z-a)AaF=OHkV~v>#{-(95(-^=eCTOjkw$@2vY6cTg9LI}vEEpnKZNylUzI%5Z#|yl% zZ94sDcLsK!_j#Z1v-^3U=e_-BU&+sXHZfsd0)}CUIoYNHa9$<;O`i(>_YQUygVPLm zb_tJRIbGsk%z>=U!x*OTW-Y}+vH3ZY=A25(##tGq&*=uUG0d>k=cedNMvz&VGS-zL zAN+l%T*lfmmoLGC2<;(tMv+k zAhkrUd%OJmCW=ol)!l`9Op2Gsw{s5p)4~~_JoJLhpyf{}GnWeo0il^O8S!Kj&$k|HxX2j>B|#TYdPe4^o~s9>3qIWAtH zTr`toGJ*jm%i2h_T0;=b5(@M;tyXAht4*ONtab&HW+$k$bgf=(1?uC%$4Q$wx=L)7 zu(SuHq=h){|&%BodpHFmp#(&`w6#-^dvG-K7Jr_m$QQQ_mH^E@or<|s$h9P#e| z-4qkZj7ycx@}M}Yqly-kZg3+jWL_LQI^uA!!41hxd3Z)_w+#76zeRSi$Oa|G1lyLR zXmKku(qcC-HUmCpbo90&k>N0Q`~p50<&b_<_~bdf<%|o}P$8+{tjR@q&MtT<53{Tc z)WkP7dPs6?46JRy#eLtw{ts4xr`G*;kCg7n zz=JJYXfen3)W}vaz6TBBuMi3P7t|6J>>I*>j~g4!9GYJ&_MxLHIA5Et5)bgc0*-KO zv>%Qw`G(kNKO8$6y28Z@Ms+wHG#nKr{#b@K^Fr`m#~9OeI*rbN!^3byKI>x~#U>W) zy1clT=s~7n4D6UNuw=5pC`ULjv{+GZV8Ip)je_?(@M?)i-Yv&=-X6< zw4@{u5VR@bLi2&V5-tb`+LUmi`9NL?7X$=tO1RK`Ag_cA0)jRrTxdR!SHcAWL7NgT zG#|(-;evpmO$is859F0_K|s)^gbU3F@=CZMAZSyKwb$K1O#nLxX^qcuY?N%f;J^wXg-iv!UX|An-VTGAIK}=f`Fh+2^X3VpTo4enDd9r%fxHqf2ngDgaH07?UI`Zj1Z_&V(0m}T zgbMSOV4R;Mm6{eiE@rnlcYIIt*T#(pH|`p2eW%y3<@S$q=ItF=tGM*Hw{|~j zE`053S5mz{zIFPlz~;~?wrI-n_t|T^WjU|@?%F?MhNkyn)4sSk+Whj+|uhlE!4eP*Z=Op#QLY~cC4@FVd+jts5x?A&N@HhCC*LJJ@Th31>S3aB7(AmDb>*$6p zXZ9rxtqwRE50zC-9hmdt4?m(yQxp&$T$6@v?Z&UYd^TygeD;nRpBAmTj~TmL zdJ9cAOik}LE>sq;II;6%?TV>+QvlkBRt0+4gxcyCJ{H_2fctP_a*+Aw+W0-GJ0Ctj zWD49kA{(e3-q`PM^3T5&-;vPt)%!h39rTwE`|rhi&*rHc4(s^}rvRdHf{&4o7q z*Nu;qtuCmz<^Q57Irj3piksV}ys|#8aMMem(3I}1K=4$*C^os{>aNZ>Z1wYp@E;s~ SbU)}1EGH}1)cQ>6hJOLQ>y`8X diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png index e94870163cfbc1da86766476bc0c89c1c7d66667..779cca1d52043c8b92a65b13e55319053260e7ec 100644 GIT binary patch delta 2350 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 U;5(gw2><{907*qoM6N<$f-m_<8~^|S literal 17065 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 Date: Fri, 16 Jan 2015 05:59:36 -0800 Subject: [PATCH 0187/2337] Restore RPC HTTP keepalives to default. This avoids a regression for issues like #334 where high speed repeated connections eventually run the HTTP client out of sockets because all of theirs end up in time_wait. Maybe the trade-off here is suboptimal, but if both choices will fail then we prefer fewer changes until the root cause is solved. --- src/init.cpp | 2 +- src/rpcserver.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index f851fcbbca4..b58d1746e8b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -380,7 +380,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -rpcport= " + strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 8332, 18332) + "\n"; strUsage += " -rpcallowip= " + _("Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times") + "\n"; strUsage += " -rpcthreads= " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n"; - strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 0) + "\n"; + strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1) + "\n"; strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n"; strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n"; diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 9ebacdbe2e0..cb87142902d 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -953,7 +953,7 @@ void ServiceConnection(AcceptedConnection *conn) ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE); // HTTP Keep-Alive is false; close connection immediately - if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", false))) + if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true))) fRun = false; // Process via JSON-RPC API From 2d9b0b7f03a268e557c6dce1dfa29401b5c9178b Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 16 Jan 2015 12:17:57 -0500 Subject: [PATCH 0188/2337] Fix priority calculation in CreateTransaction Make this projection of priority in 1 block match the calculation in the low priority reject code. --- src/wallet.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index 6c5af3bdc7d..6c24faf61c8 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1439,10 +1439,14 @@ bool CWallet::CreateTransaction(const vector >& vecSend, BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { CAmount nCredit = pcoin.first->vout[pcoin.second].nValue; - //The priority after the next block (depth+1) is used instead of the current, + //The coin age after the next block (depth+1) is used instead of the current, //reflecting an assumption the user would accept a bit more delay for //a chance at a free transaction. - dPriority += (double)nCredit * (pcoin.first->GetDepthInMainChain()+1); + //But mempool inputs might still be in the mempool, so their age stays 0 + int age = pcoin.first->GetDepthInMainChain(); + if (age != 0) + age += 1; + dPriority += (double)nCredit * age; } CAmount nChange = nValueIn - nValue - nFeeRet; From f5ad78b34af8f50e12fab63b331768b96ec2c779 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 16 Jan 2015 16:03:48 -0500 Subject: [PATCH 0189/2337] qt: fonts: allow SubstituteFonts to filter based on user's language SubstituteFonts() has been moved to after app identification so that QSettings are accessible. --- src/qt/bitcoin.cpp | 29 ++++++++++++++++++----------- src/qt/guiutil.cpp | 2 +- src/qt/guiutil.h | 2 +- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 1adf4e00cb4..73c684e4893 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -89,17 +89,9 @@ static std::string Translate(const char* psz) return QCoreApplication::translate("bitcoin-core", psz).toStdString(); } -/** Set up translations */ -static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator) +static QString GetLangTerritory() { QSettings settings; - - // Remove old translators - QApplication::removeTranslator(&qtTranslatorBase); - QApplication::removeTranslator(&qtTranslator); - QApplication::removeTranslator(&translatorBase); - QApplication::removeTranslator(&translator); - // Get desired locale (e.g. "de_DE") // 1) System default language QString lang_territory = QLocale::system().name(); @@ -109,6 +101,22 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans lang_territory = lang_territory_qsettings; // 3) -lang command line argument lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString())); + return lang_territory; +} + +/** Set up translations */ +static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator) +{ + + // Remove old translators + QApplication::removeTranslator(&qtTranslatorBase); + QApplication::removeTranslator(&qtTranslator); + QApplication::removeTranslator(&translatorBase); + QApplication::removeTranslator(&translator); + + // Get desired locale (e.g. "de_DE") + // 1) System default language + QString lang_territory = GetLangTerritory(); // Convert to "de" only by truncating "_DE" QString lang = lang_territory; @@ -498,8 +506,6 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(bitcoin); Q_INIT_RESOURCE(bitcoin_locale); - GUIUtil::SubstituteFonts(); - BitcoinApplication app(argc, argv); #if QT_VERSION > 0x050100 // Generate high-dpi pixmaps @@ -521,6 +527,7 @@ int main(int argc, char *argv[]) QApplication::setOrganizationName(QAPP_ORG_NAME); QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN); QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT); + GUIUtil::SubstituteFonts(GetLangTerritory()); /// 4. Initialization of translations, so that intro dialog is in user's language // Now that QSettings are accessible, initialize translations diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index c675235cc26..b57025857e7 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -383,7 +383,7 @@ void openDebugLogfile() QDesktopServices::openUrl(QUrl::fromLocalFile(boostPathToQString(pathDebug))); } -void SubstituteFonts() +void SubstituteFonts(const QString& language) { #if defined(Q_OS_MAC) // Background: diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index a77036a1944..bcbb540c37e 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -107,7 +107,7 @@ namespace GUIUtil void openDebugLogfile(); // Replace invalid default fonts with known good ones - void SubstituteFonts(); + void SubstituteFonts(const QString& language); /** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text representation if needed. This assures that Qt can word-wrap long tooltip messages. From 52954e6efd373c14736237c4c79769bf00f5dfb8 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 14 Jan 2015 15:26:40 -0500 Subject: [PATCH 0190/2337] qt: fix broken unicode chars on osx 10.10 The default font changed again. The real fix is to compile qt against a >= 10.8 sdk, but this is simple enough to backport to 0.10 to avoid having to do that there. Note: NSAppKitVersionNumber is a double and there's no official value for NSAppKitVersionNumber10_10. Since == isn't reliable for doubles, use Apple's guidelines for testing versions here: https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKit/ Chinese and Japanese fonts have been hard-coded as well, otherwise they fail to show up at all. --- src/qt/guiutil.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index b57025857e7..8ad9b30624b 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -67,6 +67,9 @@ static boost::filesystem::detail::utf8_codecvt_facet utf8; #if defined(Q_OS_MAC) extern double NSAppKitVersionNumber; +#if !defined(NSAppKitVersionNumber10_8) +#define NSAppKitVersionNumber10_8 1187 +#endif #if !defined(NSAppKitVersionNumber10_9) #define NSAppKitVersionNumber10_9 1265 #endif @@ -393,12 +396,28 @@ void SubstituteFonts(const QString& language) // If this fallback is not properly loaded, some characters may fail to // render correctly. // +// The same thing happened with 10.10. .Helvetica Neue DeskInterface is now default. +// // Solution: If building with the 10.7 SDK or lower and the user's platform // is 10.9 or higher at runtime, substitute the correct font. This needs to // happen before the QApplication is created. #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8 - if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_9) - QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande"); + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8) + { + if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9) + /* On a 10.9 - 10.9.x system */ + QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande"); + else + { + /* 10.10 or later system */ + if (language == "zh_CN" || language == "zh_TW" || language == "zh_HK") // traditional or simplified Chinese + QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Heiti SC"); + else if (language == "ja") // Japanesee + QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Songti SC"); + else + QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Lucida Grande"); + } + } #endif #endif } From 73cd4edb4f1ff98c20549a609e96fa40834f5e73 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 16 Jan 2015 16:27:12 -0500 Subject: [PATCH 0191/2337] qt: avoid hard-coding font names They may not contain all necessary characters for a language --- src/qt/splashscreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 366ed3df3de..e6a7fcaec5d 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -42,7 +42,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) QString copyrightText = QChar(0xA9)+QString(" 2009-%1 ").arg(COPYRIGHT_YEAR) + QString(tr("The Bitcoin Core developers")); QString titleAddText = networkStyle->getTitleAddText(); - QString font = "Arial"; + QString font = QApplication::font().toString(); // create a bitmap according to device pixelratio QSize splashSize(480*devicePixelRatio,320*devicePixelRatio); From 1a25a7edf82706c3152e2d978d320ec465a34de1 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 17 Jan 2015 16:34:27 +0100 Subject: [PATCH 0192/2337] [QA] fix httpbasic keep-alive test --- qa/rpc-tests/httpbasics.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index 8cbf1d7f4c4..24533741e55 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -35,13 +35,13 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() - conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read(); assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! #send 2nd request without closing connection - conn.request('GET', '/', '{"method": "getchaintips"}', headers) + conn.request('POST', '/', '{"method": "getchaintips"}', headers) out2 = conn.getresponse().read(); assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! @@ -52,13 +52,13 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() - conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read(); assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! #send 2nd request without closing connection - conn.request('GET', '/', '{"method": "getchaintips"}', headers) + conn.request('POST', '/', '{"method": "getchaintips"}', headers) out2 = conn.getresponse().read(); assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! @@ -69,7 +69,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() - conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read(); assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, False) #now the connection must be closed after the response @@ -81,7 +81,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port) conn.connect() - conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read(); assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, False) #connection must be closed because keep-alive was set to false @@ -93,10 +93,10 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port) conn.connect() - conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read(); assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, False) #connection must be closed because bitcoind should use keep-alive by default + assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default if __name__ == '__main__': HTTPBasicsTest ().main () From 28ee7e8b8c658bab4a5e13a13254950e226453a7 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 19 Jan 2015 15:33:55 +0100 Subject: [PATCH 0193/2337] Get rid of DetectShutdownThread The main thread spends time waiting for the DetectShutdownThread. So why not just run this waiting loop function in the main thread? One thread-stack less saves 4MB of virtual memory on 32-bit, and 8MB on 64-bit. --- src/bitcoind.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 8a1745b50d7..a0a96c2dfa6 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -33,7 +33,7 @@ static bool fDaemon; -void DetectShutdownThread(boost::thread_group* threadGroup) +void WaitForShutdown(boost::thread_group* threadGroup) { bool fShutdown = ShutdownRequested(); // Tell the main threads to shutdown. @@ -56,7 +56,6 @@ void DetectShutdownThread(boost::thread_group* threadGroup) bool AppInit(int argc, char* argv[]) { boost::thread_group threadGroup; - boost::thread* detectShutdownThread = NULL; bool fRet = false; @@ -144,7 +143,6 @@ bool AppInit(int argc, char* argv[]) #endif SoftSetBoolArg("-server", true); - detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup)); fRet = AppInit2(threadGroup); } catch (const std::exception& e) { @@ -155,20 +153,12 @@ bool AppInit(int argc, char* argv[]) if (!fRet) { - if (detectShutdownThread) - detectShutdownThread->interrupt(); - threadGroup.interrupt_all(); // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of // the startup-failure cases to make sure they don't result in a hang due to some // thread-blocking-waiting-for-another-thread-during-startup case - } - - if (detectShutdownThread) - { - detectShutdownThread->join(); - delete detectShutdownThread; - detectShutdownThread = NULL; + } else { + WaitForShutdown(&threadGroup); } Shutdown(); From f0172bf91ef521a0155cf1f0ae9fde1ab02157b3 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 20 Jan 2015 00:20:44 -0500 Subject: [PATCH 0194/2337] osx: bump build sdk to 10.9 --- .travis.yml | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 4 ++-- depends/hosts/darwin.mk | 4 ++-- doc/README_osx.txt | 9 +++++---- doc/release-process.md | 6 +++--- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8b9ede3e1c8..3c995be9a53 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ matrix: - compiler: ": 32-bit + dash" env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash" - compiler: ": Cross-Mac" - env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.7 GOAL="deploy" + env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.9 GOAL="deploy" - compiler: ": Win64" env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2" - compiler: ": Win32" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 0732d35301a..3ca42248d4e 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -23,7 +23,7 @@ remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: -- "MacOSX10.7.sdk.tar.gz" +- "MacOSX10.9.sdk.tar.gz" script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin11" @@ -72,7 +72,7 @@ script: | BASEPREFIX=`pwd`/depends mkdir -p ${BASEPREFIX}/SDKs - tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.7.sdk.tar.gz + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.9.sdk.tar.gz # Build dependencies for each host for i in $HOSTS; do diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index c1070d8775f..2958dc50cc8 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,5 +1,5 @@ -OSX_MIN_VERSION=10.6 -OSX_SDK_VERSION=10.7 +OSX_MIN_VERSION=10.7 +OSX_SDK_VERSION=10.9 OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk LD64_VERSION=241.9 darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) diff --git a/doc/README_osx.txt b/doc/README_osx.txt index d56234f7d94..6c0c21c190b 100644 --- a/doc/README_osx.txt +++ b/doc/README_osx.txt @@ -29,14 +29,15 @@ originally done in toolchain4. To complicate things further, all builds must target an Apple SDK. These SDKs are free to download, but not redistributable. -To obtain it, register for a developer account, then download xcode4630916281a.dmg: -https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg +To obtain it, register for a developer account, then download the XCode 6.1.1 dmg: +https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg + This file is several gigabytes in size, but only a single directory inside is -needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk +needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk Unfortunately, the usual linux tools (7zip, hpmount, loopback mount) are incapable of opening this file. To create a tarball suitable for gitian input, mount the dmg in OSX, then create it with: - $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk + $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk The gitian descriptors build 2 sets of files: Linux tools, then Apple binaries diff --git a/doc/release-process.md b/doc/release-process.md index eb2eb619bd7..363465d827e 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -44,11 +44,11 @@ Release Process Register and download the Apple SDK: (see OSX Readme for details) - https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg + https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg - Using a Mac, create a tarball for the 10.7 SDK and copy it to the inputs directory: + Using a Mac, create a tarball for the 10.9 SDK and copy it to the inputs directory: - tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk + tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk ###Optional: Seed the Gitian sources cache From 88a797320ad0234c71e25e3aeffb3fb95563e1de Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 19 Jan 2015 19:08:05 -0500 Subject: [PATCH 0195/2337] osx packaging: move background image to .background to match gitian builds Also increase temp dmg filesize to account for a bigger background image --- contrib/macdeploy/macdeployqtplus | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 541136001fc..0eb6b2c84dd 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -767,7 +767,7 @@ if config.dmg is not None: for path, dirs, files in os.walk("dist"): for file in files: size += os.path.getsize(os.path.join(path, file)) - size += int(size * 0.1) + size += int(size * 0.15) if verbose >= 3: print "Creating temp image for modification..." @@ -791,7 +791,8 @@ if config.dmg is not None: print "+ Applying fancy settings +" if fancy.has_key("background_picture"): - bg_path = os.path.join(disk_root, os.path.basename(fancy["background_picture"])) + bg_path = os.path.join(disk_root, ".background", os.path.basename(fancy["background_picture"])) + os.mkdir(os.path.dirname(bg_path)) if verbose >= 3: print fancy["background_picture"], "->", bg_path shutil.copy2(fancy["background_picture"], bg_path) @@ -849,8 +850,8 @@ if config.dmg is not None: if bg_path is not None: # Set background file, then call SetFile to make it invisible. # (note: making it invisible first makes set background picture fail) - bgscript = Template("""set background picture of theViewOptions to file "$bgpic" - do shell script "SetFile -a V /Volumes/$disk/$bgpic" """) + bgscript = Template("""set background picture of theViewOptions to file ".background:$bgpic" + do shell script "SetFile -a V /Volumes/$disk/.background/$bgpic" """) params["background_commands"] = bgscript.substitute({"bgpic" : os.path.basename(bg_path), "disk" : params["disk"]}) s = appscript.substitute(params) From 997cab78cb47ac52973c734031f69a2f74fa257b Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 19 Jan 2015 19:10:44 -0500 Subject: [PATCH 0196/2337] osx packaging: switch background image to background.tiff Also do a bit of cleanup: - Make the background name a variable so it's easier to change - Add proper make dependencies --- Makefile.am | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 56497706029..c59648fd02d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,6 +16,7 @@ BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EX OSX_APP=Bitcoin-Qt.app OSX_DMG=Bitcoin-Qt.dmg +OSX_BACKGROUND_IMAGE=background.tiff OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus OSX_FANCY_PLIST=$(top_srcdir)/contrib/macdeploy/fancy.plist OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns @@ -30,7 +31,7 @@ WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ $(top_srcdir)/doc/README_windows.txt OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \ - $(top_srcdir)/contrib/macdeploy/background.png \ + $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) \ $(top_srcdir)/contrib/macdeploy/DS_Store \ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh @@ -95,7 +96,7 @@ $(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) deploydir: $(OSX_DMG) else APP_DIST_DIR=$(top_builddir)/dist -APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/background.png $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications +APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE) $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications $(APP_DIST_DIR)/Applications: @rm -f $@ @@ -106,11 +107,11 @@ $(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt $(OSX_DMG): $(APP_DIST_EXTRAS) $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "Bitcoin-Qt" -no-pad -r -apple -o $@ dist -$(APP_DIST_DIR)/.background/background.png: +$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) $(MKDIR_P) $(@D) - $(INSTALL) $(top_srcdir)/contrib/macdeploy/background.png $@ -$(APP_DIST_DIR)/.DS_Store: - $(INSTALL) $(top_srcdir)/contrib/macdeploy/DS_Store $@ + $(INSTALL) $< $@ +$(APP_DIST_DIR)/.DS_Store: contrib/macdeploy/DS_Store + $(INSTALL) $< $@ $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2 From 48bebcca79f31793e6ca5ab9a1788cc3fa3ca59d Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 19 Jan 2015 19:13:55 -0500 Subject: [PATCH 0197/2337] osx packaging: update DS_Store after background changes --- contrib/macdeploy/DS_Store | Bin 15364 -> 10244 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contrib/macdeploy/DS_Store b/contrib/macdeploy/DS_Store index 7527dc671fbe8730abc2497c2717778a19a024c6..099960712af26791175d9f0cdd3d52c251ea9ee4 100644 GIT binary patch literal 10244 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 bCy)5Kssx1QY`Qmk9g|T$FB3 From 95ef87c75ee879181c71bcd1933d8cc01f9d0fa3 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 19 Jan 2015 22:02:50 +0100 Subject: [PATCH 0198/2337] add new osx dmg background picture --- contrib/macdeploy/background.png | Bin 12073 -> 48690 bytes contrib/macdeploy/background.psd | Bin 163518 -> 982442 bytes contrib/macdeploy/background.tiff | Bin 0 -> 202136 bytes contrib/macdeploy/background@2x.png | Bin 0 -> 138890 bytes contrib/macdeploy/fancy.plist | 2 +- 5 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 contrib/macdeploy/background.tiff create mode 100644 contrib/macdeploy/background@2x.png diff --git a/contrib/macdeploy/background.png b/contrib/macdeploy/background.png index fce12e380793b5ba9e893d7e1ed4ac75e69fd02d..f88a2ae74bdb33afc2806b6403ea8c0191b096ca 100644 GIT binary patch delta 48299 zcmZ^KRa9I}6D`4=5D4xPAh=s_cMtCF5L^%L?(QCf2X}V}?(P~~2kzwi?|r;)Gi!}> zS6A)Ydv~33y}DP(IH?cT@zODr?DWP=EX*XF+zia@Y~0MubR;ZH%&d&eOpGkt^vujW zY@9sI9JL_b4dwkpooxA%NZJ5+Bw@hSvt7r*4|miy_OR&!Jc97y^DX{GUbCRs1bXo z5!?5$)Y-%Gt~3L1KiYTSqrtt`wx1|_xA=aq6>#_qK%g(b!j*L;zLhru^-rL{P5#Hy z^LfdAEJ(YlOR1Ms|408@^!zHe4Xck*rA9gC(~Cc(a6eDUrBk35%`E9~28A*~l~lKo!Top|5PpK!flUKTiw_!f3+noekN25bUNZ(@G> zd4>9EL{uBjadv+}C_GFf-$)Xa-1ptuV_9J&8N&nw4@9D!TstFe>G(h-Y4AY3q9jp< zi^g$`ft~qiY>bwE)W47r#nFsojy7a-smw?98DIyZ3O7ix^-vF2)3ya$Y``(}ufdz9 zD^()gp4=+ZNxF_D&|AN|r7ApJVY*28wKl)<{&dujz2l0qaeqQ3hqX@_4@B-ygRzJ= z0;UM^iSIu#HHWfQDsFZj=F^n@p84)NVmRFp_#|vR!X5OgIX7Ln7p|qmx#L3rK1p|j zrS$`}i#S#}k!`D`B29UnA;n4bel`Js46E(>Qs*>rhCOCuyvaMm0ufI{C zvrEk58%epoesSAE2tTp<`idI0VSII(V^4iVYj7zndq&^5BIuD9oGQ8}jhI!}3BA4= z9~M{479tjgI^+C(x0C49agiN3EuqusKU`IRS9Gor%#Dv+EIwy)ZT*8;Y(0y-$P@V$ zi1`ekmxX^x*tE5DwgJt0*l^R9utppz)8o$lDFj_@Hcg-t?*Y8iHoNW^19FZqvel6^ z=Jik2wR;~%Gf-#Lzs46BlqFKfvQkPY4XYqP>fZ+qEG5)W>orP0*)13uxuTjpR+HTZm_$`=fy4h}7d6sJR3meL6=)wMEG+Gs{4-`n#q@`#$@>174%FX@eF*OF_pU z4Xx$)GtPw?3=Ag^%1*31e7L}*9UAtSB(C|jA>8X=%s-=0?<*JlM{w&qNmbLwpOhp1 zKgP#!oQ(;TK0ToRZ*AD&E5AXQ_&-BMs7r$R;;d9b4u0_DE2uIQ5B>;NGP#Nf_qd{8 z@K&#Q?3Z*qKjdc?Nh$`IsJ@YE!v1+0v|3v<=DPq?+d6H<626)U!KKY7`Je}{UE^;{ zEPs9^533s!TvX=%VA}%_Gu5%`Zd52G{8VZl+14+4mH0Y!U5Q_eMYFCFS;oL*;u84d z)P~WF{o=Hi$n82`gQ>15M6rS9@^8V&Mmm`ZTSU&dnI(E+QNZj>Uw8#$y*Yfa@Rzc& zc}F$?L>+~3fhCr}Q@wC{b@@}nm(4Z)`RD(_b%i5~+-qj(eB9Ms#GKe$vnRyby1-V8 zXwH$dBrE9J!Kc$$R?U>xohUp{{PHN*3gvi{yN9RAkH*Fb z_a6W>v)Z&J?|hmsVv*Ljgdk~&&j+>%%LDMJx6B2uu^f{z&za)z9tNmipBH1xbU&7@ zKw`0Nglu~k)Zx*`Wf02BJJs(`a2tp%n; zZp_x%CUc{=Flidxs8?IE_{mP&Zp{d$zL>9^vYwSKy;j`fs*vJ))W=ERiEPgmbz|?E z`SP*nxu}&0_&7F@5x2B}1BsyE0eF}Q1)r*A%VM{VW!RElkjpaFA^+&%P_GPR~Zj)s9$$Wjejdb z_2E_ZKe>IbSvlQvMlYKqi#P9w&>wbjp+6>GCT_jQ(5OINixYwlwk56UALD+hODFIY zFyzYYfNKE$`wJ1XRde^x%Fzo$BYycD{&UDjd$tv93S3xReP10&hvU{z*z`=v*Y1D8 zS+hHVByL64;@Iatr6p_WvV@}N7aaFC%@|o4QB4(`LUB|9|CK=~Y8bPn3u@9?_&!cK z#pv|N#$+S=2bL;xjp7Lra z2#X6U*P|yLJ8lD27$;`?$Skw0!+xdPUw3!(o_V((^+O}YQuQ2V&Id}tDO8D{QvmMq zn6CGiE?|IGuLpRuRPb6+_nBAE_PJjMVd%MU2WL;M4XE$RceqnPiziE0`z*F~-WD^0 z_VwTPe>H7X2>1-*ny)={K7bDF-wr@859&8ZS@O}C=L}~^uo`8VBD_yMp-yDU=&)|X ziWawvgMvE{9`hQ_>G8A*k{uHHz{rmAI&QIJ0jBr~Y(dnepO>gPhvdmec+U%uzRwnT zry(sFKl~rFzVG_F@mIB9j~?f$>$=Rd=3GUoDDb)H#);Uiem0s03VbVuv153fKCUxH(_(;(N_(*j(Hsf<>=u0aAm`yy10d z{Gt?UCRnZ9Cc3hFKn%Iu(q`dj8!G&hVDWUo=pl(v$`FN*eTcM+$bupL28mn{+DvtMJ$A*K5Z2>#HH+cXEMi^3#CD z`YZ0njXVPQMZK3Q8O9E0;H5nD+a4(z@Ytuo|Fmb)Dbjr2xcc^7{rsp#%t%G`R(}>*!&y9Df_{gxIhza z^B|lMXqv-jY}vb8v@N*)Mxj3R26~y|dssV0+q@#&yut>qurHSg^j~+dIeqbvO6=Sz zzG3LisT-W8jAD31$BtG|C6cZUpRL_C>}o|s=W5*_6T60sAj(NJve=BrT-B;!(kuU< z2#IED9a1`#@oEwPpQHcR%h%Esnio~zYCl95@Z@vK)pzeuNRkZ7Zs-J zRNW@~rGB7N-;>f9zWXJbh_0OoS}d86af-rj+{Z;d4gy&r@f2q>37g{YJ5;qe!dxkM z2d9~rc{g79q-7RwdpsXlX5`qR_P(YPRRlbC8RWv4aRwd%yVEYiX(M%Ov)^Mes$Oxx zc_vCgmF+x}Zl2?D`m0G^sr~IT*1exx?>Zrspk(_s+xcp6LD%d2_hQFO>oJUBR27l{H1AV#X$tZ1b1~!CKp2zc@k%PDH>87fBRg6N#K#Fe4sOGXi!UMu?UE>x4Z6 zGJ^8QIqj|6?g^VU_8$U9F@>@Gp3jG=;L3NQNgKwC##T0;0-jO?YfB`X>M*WcRMb?2L|x6|%{U^+d!kV(u2X1J3jsq-&Sw78ZkY6L@w42f{RPMW4) z+&utO=20~YWv&k_g2EyxXK3Pj%7;`(TOwB`PI{EKO-ZU5oKccuMf%Y%@h;w1k@`B= z`A=1LG=cTMBh;FHP4GUZK7Y>Yy?5(+Ssx>1VdYsOe8};cDmkDv?7k6w%w?(BI7tz%>Fza9o_Kw{l66J^44K zseL~L-;Vm-YSo`za~p}FIZsAtc^}b!gNiuvq+5$0>D^G5O`D@`(rNEvhyI9iVmw5HD<@ob&hFC_Y}s@yuP>r4~# z&!Br%pq~>`+bQ0DuJ&X8{`e2NhQQFU`53+FzUDYI0Cf4Ru5R2cFxf;m9I=7zvD>;G3K!IU3y3<2}{UjBl`Gr)`S7X&&OcU@ql5u#V-m z^I8C=e72n~UsfOFhD_pt(P12zx&A6i0B zvWVXwhnigL=Na0>zBT&axGd^&;>OVV#+s)gk3Jpd=KAn~!z6DMQC+I=b`<+&VJXEs z^zW;YjGgXvQJYWMo4AA`(7+VGdzQ=7zPc>#AZ8Q)b$skv*L#lA(dQ@G&{tsMbx{s< zQv}CXW;B~{oRr5KffL#JdOq}ijG;aD7DV-JyZt5yYvTAmX~^f?@z5sbc&GHEZ{0eh zdk>QQx2yhZ?|09eiP=s0kQeSLkNY>Ti_is<_`o;gy0akyr*Ws8o2(f=0-$R*wrdkK z>Cwxbs^@y_wQ-Z9-tnxKSPE1dD-!n6oc+=kac80kUbR!}6*!8_LJI$QeE-Xo>Z2?^ zn41J0>Sj1@@d*@$z`JVaG-B6bsa`e?Vd~1KT?{kjodenEI}$|1bihrUi714?73Lx;cb44_1T^f&h&7;J)uvsRi- z)iaa2%PH>z)~3JeE{+@52b=!Gm?=(a>uf zy)f8%k4dH9OcD2h&A0oeoBXDN9X1lD^%#{mw_Giv$dU3w8akV*(#F!181@w&JlM+ zFH1x63+60&S2u}^+fz(F2dueIjU#5evSE@856&Ze-~RmC)1Sa8{My|rq~@LD7XtRB{9G9 z9!KVO#~iPA6VF(-*L`!-^mGxuyL`wle#7*yk6f^PC?=jy?kf+d$dz2Tf%mCS#krh& z1cd3aYQ--?H-##M?V$EXkmZ;!F}d^s(A|{Jh0{aKxcBQW@h0p#-D~TIX_s=>P*&O8 z*An~Z61md1A*nqdX>1B&#At)*QO&B$G~<}3*!M>?mc-4@2MPP}=hV(eF;QujgmZ+p zhTW;u+i(SMBdsiOuiHKH+Nie=-5EFoHi0So*TEqjpF8$hHwB)neztmxFA{2JITY-M*z#mPiJCn50s2h99M(gkc<<4puv+?1p;fr#mtxq1ui#PvC4^&GLW zJytRkO&Uy;mvYtJ7uI?tMkrb?b)P&Vpd$HTDMJLr^1riVUI!!CyA05ED^m&=-_ZHNyTly~eK-?mP+4W6Dwm#0waxGV)BW1-f%3rmO zKd)Y`o9elk_*eDw(DC1u1Iu)iB8DafSvTLdKA@$&JyqvEtKL7oY`(wEGuk2bp4bN) zew9aJ=U$X%P3}(t@Vk64BcW`BE}jmHxr`M?==x)FCOpi)?t~ezXdDp)LbNOQS)S3D z6mYyH3r0@t4dJzHf?{dTKslFBIb)1n-Vxr6osT=mQ(oMwSn(E`Cl_86Aa^uWOeoPzIPBjs5H{fVD$599g3d*fnd2bU+0D}fLdRZcTq z4B@f*STyPz$Q4)r?K(ARY3WG#h}}4JV)X78!tl(o)-b=sbWlyMD;1% z0rK9rxoSV7&059DeKIN@%vqIVXo7%Y5uzV`D4Ybyo%aql=e->q3$~0GhPTLtD_r-l z1>~wVI!*vS;@8to_D<~yzn+6E_fdD!>z`fE?{6p7ZzowOHn*f2w>Dre7|Z-+Q%1Xi zDxCC>^(P%6o$vx4X@TZW6WlJzqhqBnw1uiMPP1!c#04Us3kO9iRVt>GkNuGOKA_yH zPqm9*NK8APl$YA^vWCL%F4z7d^L-lAKR~}(-M0Y3E+z<1rK7&b1`_p#i2T7I+MKWE zyRZiHXos5#PT&=Txcbw$muAC-gYe@kHa`H?BzD>k;qn<)PD#^*+#jsQkEY&x83`z6 zmjZAF*Hj0BjvF1z415d^;k>Pn{guZz(c=Zsr<33@& zYO@6UfsNY@v+|j5JA9WOQ+{Z|U%dwCw)*g+Gltbb|3Y`1oBO_YsGX`aJ1N}B6)p1z z>fk`1G*x&f%MKX@JzgX9qi=Q%UGnWbF#W0POF3*J`rS2&;?N{|+PmuO=WzjUSzoWr z@qs=oqk=}y>7?}eW@5)7qF~ZXr`(sIVlp?0oNW?V765zRz#f(A4nDNEtUER)uv~$j z%vT!I>@AhP>*gO(!#e+OOWzCD#m@JaJ-89B~jTYr4OvRY-Z8T$ept!5(C zyg$=a=uw%audhMlg@%P;t(8mEJ)-~m8sSV>e|7Z%bM=E-G%IDb`AOR%0z?g8r0 z7AbZbgEihH;btX_tVXiuZ^3&YzgQX!;U(6l^Kw2KlHnY>pQ6fg=)Il#M<_+im)>^n z+fd}C^;+>o`bf`5c#@U4;Q+8Xu^Yu|*KxPN*>NnVi_c7s`&5%Z(Y5Bj8%+#uU_@XJ zD`8`-;95Y6;?p?_bS!(KZ&w*C40D$ zVZJ$PMK)z{i>%C_J+e874Tr?znXEqyX(izfjgLEmQVfdLGz7^^(a-4?`r;h67kxI*~btO32(~! zfGVy0DbkFUfOPCt&Z`d0EgfeCHo;xO{xc`K6-*VEc|QDfNoFfptoMrRQoRk0j4DLl zY=ixd#&^(u5+h)PDs^%_Jb42~xCbzRFMGnXttDo};x&q;YDs(=wE^&(H^2;C;QdAb z0P6-dz7N7xv+{HR*2g}oHyW`(3Z8EMg&1Vv3t}w$wb^ndqD;KeM3Uov7ceRzZ12@_4j{!&wX>WfefLjR_k?)j}`Adta6_;>K)NlSA1}&R-i0GQdn8Nb} z#X3A`7sdsGFP_@f#v*ib?oox9Z`^oB_ z6Gw2dZXKt(i7+E`Ax-9KZ(h3CAAl#^jjI?p*<9d^Q(&Q8nR=7x%rO~SY-Y`qmb1$P z>}+H^KI6`IbzCP`w_mJSiv`zcOmA6{UH{{Z#E;!@92I&~lY8Zp{4ZxvL&WY=UK>te zZzR}A+B~IC!Pe1Y?oICdtF_)u#t0&T*IDh9`yi|McG7j%lJ)^1Bx((1R6=-k-%m znD^0pp+4vL@5@wO*X8$TeZc)@qKWPYz>_39^c!sE;dfo(gY`l-SaiHR5dYd6M-9o4 zxa>NF!6uT0f4fz9zm1^XSgSQnoXX^91#R~tF)RU7g=2m|mGRma;4l5=HT^8H?}Hog z0J?l{qX^e~U1@M)_}5s`{#lq2Z4za(9Bba;*@;P`)Mp08j|L+8{BBofA@)!Q5i{vy zJV7YunrjxFpB#&O8gaiiO{wR+tly{g_R%E2jhpk=%XO3vKRitV{MGdJ^FPv&zpJTU zSYfSJ@z=i~pZKw_|0pb&3h(mAAruf55XUULoRL&rtLuRX+BYkjx0DykMCE|R_> zhq}&xU~NO`7ah~>Xn}{9EsyTe*6!%Wxb+-{VgA5)~F$ z6YRk5sDjUlilf$sxG{)(EJEr_fYVMm72v!1;IsKtA9P|})$-hN3CjEjA*I=_8964` zofD2@^i8tw&$^p;x>PyNJIDgV0pcH#u5CB(=Z;C`X?jiC?3=ek{y7U^yUwhAmC<_} zX;#4-j9JUqNjYGGt1T`7yU>LkSI%bj6vC!d-oCn+MD${3reyB?4X!dS20*$Q%c=@j zJn0fDbl;))V#LgOh+TvC(092-3G6yfav#dp-Yc&DF;V1y-A1#|%xQe5%*^+^UpC(a zvt(Z|_r{c1NT%WjOY@xPxza|zyb<%)f5+`QzLA_+_&P2^bRB1|=gu_Jm_FbA?-7A#A1?i-sx1M}+opxTMr>>za_xEKM4izfc7Ir~T0WZ;z4 z@y3$s;V*{36$bEj2=IGEo;SB$tD^b-4a|9qGAH7C^JV(6Y2dK+OCo*YJ_tkJeHVZ8 zv1fuAl>d4ZNOYSAmazzUapBkPbFT%#Wr(;pecF^TZbV?A(6PzIn@?j2V)*KGZ6yR% zH=UnpT;%9snqdl?L(yn2P$ng(8aLm(nH@Vq5Nb+2bHqFlE^sR%z$TXAS>7%(%Y4+Q(149gy6`HDER)UySy^~r@A@8CQst~TL{=i#}xYM z$*yyl{wMXQK|1)sMLIl9B{A-gxIN!FCF{LTBDYR@G$l-QsWa`FF-ot-Gbe|idmg`i%vJfExlD^t zmwWR_6mHU)cqN2c)I1H<$$HqeqcKl74GGe{{FTwMLUZ4#<-|#U|7L<7`iQF~%m;lU zUE}sPPp8GWOu_UJ0MmmJ8Jdz6U%Z#V546{rF6>SU6p6|AFkz~AC8BXaeE5ya8+ch> zh6(8p5%Hs=S~QuU8Jd|X=y!(gYI$&Htpf!Ns)J%PTfQc}IBfSzFH5c(n-5=i3z--L za?*;7(Qc#@pXYwNZs_<(9@Td&isL7T)56bTS}goLih|YxmGLj0Yq)tb0e#rMp}=|? z3o187U0C>)krn;TEm7S)tnr#CW2Yc^;Fz8bqJ+u1+lDfMU%@-5Ax9 z!)8=V7qx@6;2Xc@z(VI_X`^&O3V;Jo7kP)eHIYEf+q8d&#MlTLW+>yU#eTK^_=L~3 z!6Y=cZpChgZUt=Ax5QWEx7X<(=jmb`j~z19;qtBqB(`zmHib?@(mzUXY|z}k;3JYbx1{dbASSxvwk!6 zD2W%0GLDD(Nt+QWB{XHXh&qf#w(IAy73BsrMSqhltFg(3-BO6`?G|!Az0E!wT_jUE z>l#ICD5IV&nDLw@@@gBc@A{UN;9KL1r948blELdq(Z;~Pq!k4sr_~JYTxXD{Y=v9d zlR+JzlY}2k_1X0vBlGXSM1W6E!v43=6>5oX`ZU5mM#mJBP58qrev{E~(dL+5(EM?8 zogu~cQj)ef=$o2FOA^;8nw2F>HbM(uO75DCAzkk5>m(gyChs?Tq7FEG7m=a|NoC$m z1zl<=dZ9V}8q5@gVQvW16WJE>tL3N>uyOseTk4?q13kOLoo7i}4}tHDtZ_MU)jYuY zuE!Mh;mtwoc!B%0P``6@0X{JI>QW|Um!_(enr#vdj$%yBrJ%^Lqj@Ol*ZyD827|*R z8HRZ7TvWpOuWl3^uxjo209M*D7R6tT=;x1pz#l?XwtNLDg!MCcCyJlOs*2$dN5g{Z z#(x^#gH5Tj(!v6=fGsl!S(%NsoK+?2K*D8>Zz=z-vh!K@29L~iXOZs7LSdWzf=NQ- z&euAzLEL@VUpy59qBIVk`eak|HGMe;7mVJ8%4e)Kq`BizT^JS5yH8skY*kU4cXGi6u9UFgjyLPow4z@;2?|75 zGKtK$$4Ti$XO@QfK#~&xa{3(fi*f39g<4>tsBSar6_W~60D3gCZ9jvFFBa!zVnysO)mLAfX@&ny zLx>P`Oa%ZsYCkD>@6hJ8CXqte2jw}jyC|Z3wFflE!e#lCUt4upe4QSP5i;cx$*(+_ zC7ydFtt@c~kkP*e%bTQB!Dvt~qg0Sb=02n2$wlN6lnp#4Yp=$AP)o4Q^ZpzS?>sBf zKqwQwJ|SAXL8S3-hteA2Gmm8D5<)CCQmLI@NObtUa)?xs4TzC!J!1+g+7P(yrEULw@Xou!j={!O9&yP<fjM0FXlt#y)sWM6QLB`(##<@lK3<@ib~n$%6Ti-{6E(4 z5&+hPb~i~I99!x)*6E;U(rW{rLy6e_Grvd=QA{CKqHRyk>`tkD~3UIs3GQsBlHHOBwc=0Tv^8` z<-sh8>E~D6Pk~(J8%9e#b5!>CK?vrZM*u`4$#Sl@ExiwYU0KCPT@@p_Pw;tFqs0=l zP>6JyWzRAdm2`uJPYW86=S*@%v8d8`1%tWS+Z%FmK9a(w0Xm5S;chE|tJ2v9F(03t1nAy8v3RKWP)-Cg4~k-b$*>JOyQYrT{FMqhmWCKsjedWJxU)Y&Qp}8 z@IJyPB-bNMFcD`xpz_*`anBPmAjJc45PmAf`~EqBR(`^y zSFp&RWN7P+T!?1lZWHG2Jj2&vcVpBmQU4gW4>f-@hD}T{L2*qv$6m{x`Aw~rrSPs# zo$};7=VB85FTZ+k*jCh`7PdoZ!u!b4xfd2y@WYT%%Rk^I2X>2C1~u#TVIj7AV#7sB6-MWDBq8 znwbcbKedM1gjmsEpB}>~#lLr!_FERki>IIoneFmU7o@BZ9hJ4_()afd+xq)ybs`?A zZdBrNT_DU)G0uaVaN!kf#h}Bo*g2B8iH}FD2`)dKKd|`2s@>X3G2skiN}WlE^g~vd zwx8{c#6C(G^kyrUFmgCODqVcBBJmCTSLfG-pMIj2}H4 z6&etBi|uZCd5itvhYuxgC$wLJx__ofN#Oh`(ds>IBDp{0J|+F0(M=~qs++ioG(8`Y zNZ2Y?r%*iz3PYWrHL5NxCYVM;5 z-v9_Yb#=6TZ|0fWrWUWwM>knvypuW@w%D(uu`}4ZLQy)w)|D!qm@WI&W~tJ(4zVJx zQk1OOGO>85MrP*l!5z~<{bkOw(FScnC;A25b~)Zm$e!ApsSpL$Fv5m+RnevhVg14p z=bKCW0S!_{VTNiDxp=79vw=z}hC5_Tb|e5HmZdRgQd77V(A6zAf_Y2E^GiHgG*&=> zDZ>|LvGR-27Y%#@Wo@VGSp@RFGD!89^z@26&-P%R2dlMME;h42OVn&Be%XFdy7t*m z-c~WY@NveWuN5B4;mSLpdKna>|o!|T)Q)Cye#e2XG47;Gv1d@>C_lw7b( zNl~n6>j(G6jQbHf#?t9vz>r2E`kJm7vXavqluCA3>AGg*mY&0wLnII7eoDGRmbE~T z`mJzx-3Jh@3LumseXMMy3zeg25ZMI~G?JWy4b^xmO76sF5*waWZWRDmv9Dr2_#*-taTT;{AkvIVY{C729&b zkYSY2UulrrOO3)Vj%gOKUlOd@ghno=L7233PC-i#R_U;af=hfD8ojap%L5!= zG5&COql${jOf^}l&mH4oC@t4CbF5V1|2!0c+zG7-TZp5jeX=-0M;HJaKg#4sWN~M= z$`?E6P_jykK+bN%vg#6mGAxmk5KxFwh<|TwyE30Nnx#V6+IHIU?cpZ7XC#%+CLG%=dEc%H>YYk#WuGmC7E zE-{XH--!kinz@YvvACD3uj9dvz(k+RT*4D!pz-fbv7r@mMgQ_7X&7$27O}7j#?O4E z8)^7QPdKPQxuD52@;tr<<%(szPwT$_U=~|$t@>02Jr7GGd_W7hZv3JWEgqv)!*2a6 ze*ocPO_SK{`v5oB=+`9i%PM=9wQ)h~ZjQTCJ=$F;eRJR$lSF3*hO+z5m3Up*Emu?V zU2asPg~z`z;MB+j;n67=g&|?ArWctVQ>tvhYV%>F<(+f^U2mTbsdqMy^j!F)3h zJ4jhRj*ll!o&!j3cO?->q~brEiAYMb*B1x5McxY?e(=44wU9(5bv{mMy!=|HvRxn- z?>)!9S^%pA7rU3iUVq0P9e!W)@yF$-1u0pH2p4r9ej~{7E0GHGs>>2|o@yUXQ{)?o zxi4sa8&=^v)81{KzM^8u2E64p-fIWgZwVN=F%04?AL@XES0bcy$zNz?1zQ3sY7>a@ z!K-5Qka{PJK_~v{sl#Gif+1HP9wH7zGg!3ocA>c|NjrSbIKtM9TEnzvM`Zd}iT~yi zMO^3+P*GCTgt8({3A4252e>@)B{uh#jfZ8bL{c=hU^BF-*hT1P>8zm*#33}{=Oqbi z!W+d1`T(Jsj#`vBEX7X+*32pgSCGM?)z(UXS=z{pK=fHiq_cFLuFz~%z0H)4!4#vF zXfaU3ACqJFgQ>qMZS~t&;nbuiO}aIL{j%k{LsHiuBj-$bSAktJXE=5eBe*OJFFE`} z;~{<2F*tIk?+h7vNE$Pl+bNmo$-afuO$EpOjlhnDVHtgKT!=qwyakpOBcCd7RFr{M zmz?y8{vE!TxNMP8bL8$|L;A=eRTDAECX-C4Lrsft`1MsP^crCw(ppv})dfh~B{1D#pp&&GjrFP2ahU*f(LGVrFG z%xe#~rKI5Ee4**3csI$3JC>*=pQ#iNPy~Vo@Lm|t{^|%lL7O|P-v8MbQ-4(TI71!%CSvOl(w@D%`KWQgz#+3aBi%fEsJ`oq zL(nMlh20I}?g7Bm)PK%*LF07gNkl0`m5ZngG)c1?SPwVAbx&G5I3*b`JsMGxwgckp z|B}EQH}&(tXM05&vrxXOyG9K>CS?)JB(bAUHx{*DQm zeBuq|BJV_JC`9#T^gz7->U;Z8K0wx&^)y*s_u92=;J;6^>X53s%b)%Z3$8=S{(Tvm#ghVpW*>Ga0(BlNe34L6DlBPMt<5T$ugBr&xHy z1?91hy)Ht^hHp*Ey>_@P8U{hgm8*CH)lDT?rw$guhFpTLQv}BXhVxZKK$7;?6Bp9R zP`uNQO6*qQqd!whN9s9dGvM@q6k&?s){WpvDtzjjPUd$cr_DZ}?w^wNDTYW?n6-(b zu+W*mv0e8I>6JIDWbij?=E-NNLm04{)*Y{FIw(Y{tYW`+eJ++*i!&ek=qjVAU2wNQ zP?&~+xUWiwar`4NGk-@hstO0Gx0>+l?oB(RX&7Q_2jh1bX|99vBEaxZl;f5&t;h-? zi3^rN;YgLAjHoPZ9g(3L&-NUr3lg^HfG)}%jL~1+Z!KvYYz+&7wb)_Ui|zU(evRNJ zkZjX-6y_`=sp7;2aaJtdB8pz%HPXV?W=g@X6x3AZnTxk?ZRP&MnMudHL27HjGafd-uHYKs39$mm7%{)+!AQrt0TBHYIp>- zVf@TriUOKca@oeR*7UZ@>-mGQsTvWdkznGJ9uI=G!O?&VQOe)8nHwoHOx;{_|ICYuVil+9|H6B)f^p;eS3(BLbuo0v==WihS&W~QzHP%OLoRwS_*N0k0#T{iV^jIL^tWQ^=xgkEx zsu^q=Z5B`CV1^OhyX!>=Ps&2t=VujTm7Hl2fsuainJ**8FXCdhEOk(i+nun!N5 zd{n@Q%wbgLEpbjag8RVE?n+&gK!iJT>!7NQheq_%vCBH>+%nBiDUrwpJ(`Qno`xB%ejHAggDwmvp~#;8vd z-~MhJ09Ag+4jkuiBJpZk&M6?n4`uXJAzp?CLP>BM&4K;1YUj8WWCr5{<)q=@%#-}F zb3qQW+WKcB$amj^lIC-go@P3;czG5wJk$zt2ra@+`J1UZuS$7GH+387Md73tFe;jF zGbQA)j1XPg`9&Rp(AqdD&xGF>?$yrcwl4v+vOJUXU*r+gH$Kut-cGip1||c}TPTsl z>Sa@EA3TjMUR!gc$15HJ$zEZZQ-34EvpZOx(?c|d`fpg*QZ@JDj;kmQIA8C1sPTDG z>$4uxx1J0~iQ%3M{z!huwct!}>3$p>s#PYvycKCkTg|6Q?Ioq>#ZrzA=8W^NB{2c4 zo1>yF=l?|g4a86I*X{kPZ0jR5NNQM$2kng)Ek$vwig*>Z-dIH<8&mWL;c`|PFERx! z>;#e-(hepv7zOq)!E3U3hrD}KE)hOAri`1R)zdHA_Oq~Rh$VI{_Q*U#-3T(Ntc1rz~(N z);MQRFPm|mrt~YpO<6}&oO}uFzX7|Ogf_=Yn=Ne9G2&8|+KcEpSL(G9^~!+swScix zNnpv&D%NKOVpy#4B2@$=4AQNN1Rg`zO*<%Fk+iQr5!SJgsrKX$Euci<`F?O-(^N&_ z%hfNdIwiRE^*Y^o)L1&-wkR6eIDeKLH!J@oQiAjabv&pJPgm^8g|CQR4*ECBMUZ8S zU!CVEI5XP@&xBN>)JWGF&7y!H9p&F7eHqOIt6yY@=)*cndi}WS;O#IyYyUqNu1=J6nWUI7xSC&y{8!`G=zNDX&o?8*yM-pcxD1*knPf3Y*kb( zM`oXUXpx~4U;D!{nZ(B9tG)?6y)5joI@SvNe`8js#Na01>b2T7>7vqAvyWf9yMl@h ze=A$gSXg2p9EzT%7l|V(SQGh9G^4-*rOxf=;Ust_P^BA?_LHwqZ3G5^Tao;+!%%fr zw~U>XHx_vU4*YPHi18o5WwRKP&T#D~OKw~DX`0m7*HLobsa1P1ZYLMaeB!KBDlyT> zt%x&ek+z@9g_g@nGW!u31xk|xF*${55`KJ7@S^#U{aYAJdHU|qGdhvg(ZN^YQGYC< zrLTj9=hWibk{Cx>fzi?&0>9o(uV{ecXC!zO!qUzgF1ej%;7RE8zxsYtmRnJMPh z<6uj8-q=z*NT@VO7DOx)3Yfpdlff~P(Z^3@;Zsi_*JY@}4cI$_#pasv6;%brTVm*l zFa7Br67IqZs5M0RBD#g^p)!NsZX07|JR^Y^v&S=pb%+G$OQ@%r%Q zKM?wA7(|$N=3yb`8CS5|lr39NNBZ!wE+bw#uJ$(#BPshOB;zAp=0|jkyR}hSIIww3 zU8*t*f~>~&9}QJn`Lq`(_41H&53_Ge&mDSujRd$Z)L+aHmi!4k32C5Mb%UWTlrF-K zNQ5+RAig1pqRopa-3hO65`B91X)h-O=L%tEk=E4tAhxDAT?&7IZkwFT90#qgRMNK| zRP(WOrchOeN>QgS;UIfTF>I-b@Q}QKXVgLzqva!Z9Ap=VQi=tYcwCx;pAbfjk|{x? z-N2#6QRdx{JqbG=uH00~2))T4TKEi_L#KV|{bd-R>2Kk9P9V(<4T!V}-pE2X2v=zG z+zrCER2Eq0z?Y?sAk0peKv8YPBf7M`F7OkfeXt!y)S^b;Xf21YCzakIeN1AlZQ4B% zdKk1IQ17dy9cxCaN-4vCL>%KJ4qdwieE@JO5YyVmiA}tIGx5tPGPb!px5y)qSD#IS z%!JTrg{bZ^n2}W*9ySY{*&27#m{~M;QM0t!0?W2w7)j%Te}!B!vV3lE?2C%j?k?A@ zQ5()k{XYP-Kuf>S`f}E!>wUHw_YvD81zxE}8s+k>RA6Vcm?Z@^8K;Gdd1JM8mo1`= zPcgWDe`KJ>g2vl>6L=#YAPBGdpQMbE&M6&oMzi_b zO~~hG&&0H^HN0x|3HL9xf@!eKRS-S8mh%9@Qi7duxZGV&CqF1RMOhPVIXAhKibh80~p7@58~mq(m@T*WIeIf0is6FB4?Zx?O{jSY_ah_X*R(eW+3%YIH`oJ2N`w7~Ta&3Cr=<^gcd?@A>; zma_0dfv*Z{EhA{SS-6He+Wf+5+(!eHe@KGcOCwR-(^0`$cJDMT!WaZf6H6OMI|g_M zLXImQSlEb}+-zafo|#s`4F+Y_RQBT8Bm`A?AeD_{o*KRn_JrOFDTnun&^AC=*tgbYV5_%@hx5e-)QO z@OC8SE+Mv=y9{YSoik6%~=?r=!1_=5J!?^&eZO6b$uohV5W^OD}hW zPE-&(;nG4o6vXG#yY@|yHR8}ezZGZTku4*px+MftJ`pCT1!4YjfQ3q)RFA`uq-n?B zQ|_l^8@YX15?BHn_&K!8->t(sfBXmlmA$^BB~IEzh3Uf3IbdPR-D#KF;&9wP;mn^4 ze2sir&CDB;Aa?mJ)!q{Ee?|&=2_5?h6;7KLV0M^N;JSx)$~VPTz5y~3E41)5I<2&3 zj4l4K>4p24_b?iyBPUUa#1a+hW_v^iZq1u!-UO?0FXIl=+=xnhAa;1fe{&#-9FW`f zVlnXg8Lc5Bry*T4ZQoQ=^69WtYWo@}DnE>e#4=r8{A!?nU`dv~86j_zr-<25lStGA zWvD?(a6?W}G!$=gwv7N?M}Z{I=;Lp5jwVeNM-{oGIo^$4>r5^a(ykmJ&gu?I*O^Ll z(UE4+ZYB6JF!Zc=5bI>Ce_5mMvNgI^0z-8I8)+1PT-r7Jj#Mk&2jnyghQ0lgm95xC zNW6g`@r|#_3`6JGR0d*TzGdhuTru03(izngHvh$~)tccQW6~!Dyw0wP_XT7i$#UoY z_0N?;6)4~Sk;P?@J7MW;BfkNs1SewwzGxMHD$x<}d4oG9TGa4ie_`~JyFT24cSS=$ zCQ2>UnR~?RB-VwvD*(n$G)sU-a^#+#(i{S9wZ0`Ax+a4~MwnntnL#l^fa14k+YJHj znNW=l94L}U$dz88EKyWu(wbTvl6R}f@N~IM`?7Da#3tnf5|_;wwunxlG;zQZ05jo7 z*MBMko;UHrN0$r?e>f64^lGgT|yHy@B(FM&Ms)DspRvcHz0+@phlNNE4WL- zb*&v#HhiSp>u2N;i(BgBNHgw|M{c4!{Fmh%BEfmTq)#9iYY5u3CE4)|81C^ILPA0ZA0f8AK6fC8lq)={3wmM@HJ z(UJ9Vj8S3yO12)p9$I26kYWYMrR{I@TpyUvgFJ*q!SNmtnNNwV;iE@jOH*q-3-PB)NFZ%S5a26nZ&ds~aqYnMB2`akTy-zBfMj#tN9O zyIB>dB0%4Anf=Ksy6~^I8R|Xd5r2{ZSH1KI6%LasZ&!e^x_tN4bph4^>xH50vylYv z5{qRK{Iv6ov zvGgKfC^WIPnRS*X>XmZ#&61z;FH5H%XosN%{4VY5@0ZXD;B4uo%A7BK1-C(*kVD^- z90A51h0qTq-vT=qIQ1|aoiL&O_?vm=h5#-StSA9(+6#CSqu)`?{(-UE>Ae!ZIy)qZ z); znwW|O6(Q)3ua$aU#Ox>HtgtHq*BGD$5tb=xD$fK53(D{<_;1J&VBEz@t%OX~De&gg z+f#aQD){@hv6AmF$YT%S`e;{yB)SVD^cmh=6!oaTT(|`8HKYQET z-uA!;KJe*JfBM57_ONwwwKG{5CMXGSLEI=<3P7*bK(AG~ zknvC3Kc4FDaIiC_A3!)a@6}sKGjXV{1A&W#%EV#9cQ%58nO<+@2I&ZrY^zI5j?aGf zf3tV*xINp;s?Bb^zK8~kQtNh)WP)*a0^%IUXfsBq*F_31KZ0R{ABsbE?}8$O&q4B( zm5%lKp=~)3lYZo%{^_5d_q^xbbkj}o!$0wV|HO-5{Nnf^h&=(@+(t^H1!e@cK|W}V z->!_bI2-CIpckww?<2vP83nQUAsD*@e_oMfpkxjZYcV%U7o;6kH5q% zK$g?@^Pn_>B}zmh+~XeixEmXH^|DBn2D+1RFC(KJXa+$8z(Ja?To3D&B4QhCb5&BI zpqE0q4`GELMRmoKQ!dntu{udbz2=E_(Bgb2HnTwVhrrXo=V??*^{cc2rst=2Gsbe zqOqETH9!b;%|)gk0pWuUL1G9+g%9}=Y{$&@cM6Chd z3uMsW=1RM!(-2fEGzJf?05ylKT3`a25#-?Yt9p)O^Oyy$ zgn0f4;5}YspKpcC78(QCf60&T^`^j9dixofJA{YEOZnaAu8#p5q9bmVBW&XwvHw$o z)m*ajKMN6MW{_Kcio?*j7dJ5%BPDUm(*G6ZD-5IAF+NAkLWgXjieBa<0tkC#XvL6w zr1?;^ObiwC*}b1!N$Aa>z~W}rhlPkQ6-fjZMrtUllWia}H<_M`vi$ASp z1U?bP2N3MR8cQvff8b&Ac}MLeRi|E2*#3TZI_2_aa0Bop1uQCmbw=vc=_BYgA8vm| z%*eU^&F|ai6T@Egq8I(zul64H=oZxHq=)+4J zUo|^%v?ohhErgNGj|9ObkU2Pl9(Mp{1(eU|BrQUmtazZEe=Jzd89N+|yY+!7*Fgq< zN_w_ZK$sZ&F+dlsvJw+5Or_qETr-L0ePqzXNSI+jauS+X=#vCS7qwUvS&UJqogQ^$ z6#27m|I8p|lwGiwz3gQ#c)<()>%acf{0jW$l>k;g90Q$xK==e@E*-8Q8!A{^~-Hx`gY@;zD(&x9F56up6#hhtu2__)TZXsO>~UjK#Oi_zBqtp-b5$~F8xBS9UoOM$3OhTKRorRPrdHCYtfD} z`Z-1xsls6L9Ingh;;I6m2g+?MtMl=M-+{^646aV(3{(oBy-P2eNgjoXy=2R%?Hg0$ zban2~e^hy<(M;{)94=|9+!ZC>zyxJ6{?j5ke}@s~USBzBl6`snWJc9tcxJ(s>B|u| zongiBM0U8#U}uXW4kYyvol@bctwx2! zdXnH6$2sYcL1wXg{M^s|+{<3}vYk&if0LTPmR5;$WPXh~b=(+rZ~)I(YT9CX7x#c( z`#|Qm0d2h-=)9=y(Z+wwRWbw@;Ra}0bO6C&3)oS^=-k%!8rW$q1&^}~3hwI0U98N< z934s)Snn>qp0^9gXyC88+%hY70#yA4#mi7>k|7&Ops;VRfwJ^)-16zT!@h*Pf2lxs zDroh)-A+N+&Q1)B5hagb|Mg$L=%S1M^MC(m!U>o?5e%G%?k7RXI^5SNC`Z`C2EBrrRHs_iUANTL zOt?ut-O%Nav`E?iPvQ>gKv}E`Nw;8D} zG$6aFKQex^q_mI1ZD73zpXMV){GJs_41NfS^lbXUu&AQ$Wvp@Ixccg=&pZFTTR#11 zR6?fGE+9S!_-*;R7pK4USu~EOiFE0J$N+XHvQC#;=3dSB7>beEZs=9ye|oe-VSPJp zE1Bsa^(t_p@+Gg)RkD0Cdr6Vsek7&W@&;70oy2wmkuqdEqvpBp%8~n0Hf_C9LrweI zswCs=s-IS0v3$enjELz3G$TxdFye6NMC?$Oy?YMn<+CGW@VF;e`f2K%qGuE`P(k*B zVaJQ^9v}YjhtE0ZoIk(nf6txm0pdA~vVAlU1;Ni?S`ldtMr0R;q@FF25+EGcmtdtU zWdh5ZsD&+-W(f4#QVRwAHsK#aCRp2QseKygyLWnRO@*=Y65ka&RK;#kv6OPyJY`IW z1wC6Z@cL&U+B~~OpAEeIDwO2BvF!%x)=4VFhspKU*P2WiRJDnee>nk>oGm{3*DXJ4y1lI+a2ViIK3UvRF3o2gPI~dT?Z+l5g2N$ zMQ~-GYg6MTn?670n?M$WY$7?<1{?Zw0rgmF=qJ1#zKz$u_O(}Dd8O7{KZM6;H^-qm z+d1c)^O`?+e~la^-a;+UZM$2fKP)x2C(^hFcSG_yz{R3vA@3vb**%>@lNzs7Mj^n435f8u6zM6wl9&-SwL0TUdXWsoI4 zpx2u_e(j=*E_(ah-yRO1;}MT|#Q*r8|MTk}`gLWGiJp2L_cJ4QC4}U6OpCZ8xTq-} zBrCTwUK^D`H=sh4o)^p^%dDHOXF$*&2U!eJs`!`UZ70TK1l`CD;*)9CE?19{q$uW( zD-5+!e1W}=d z6FO~#eHFcCk}bqyn06Nfy}bI>uRgpi`*i&M-~atnp8Vu@zVol@ZZVVQW?&`>Kuh#1 z-@u$@&vEJABTPk)zBY>0I_U@PvGrh}BmsuKf4TfRN1KCz^1PSEL5xzpe<%QrY#8xP zqd<$4bq$;bKTvrqNL3jG zzOBe?DNxkxm|*f1S#92GWXj+Bz26Im;qjHPeC4^%eeNIp!5`RdCxKOzv>Ue5zOUNV zf0?%FMfzQcJ&$T`=!8tZj0%c9Sq-qFa`OOnDDP-(-xwHYDCOHj-Ihn|RZ>u{e1PHN z(B%tHsP%S-Wh~r1qlAm>7q)XJ;zki4jP}>vu&_p;X)z)zqm0Xl0mjK+A*hk2BotH* z!xXQa12w8b`qlbM77k&DRc22TV&{Lfe?FZi`iZI>*w3GM;)(zDU;h;j+v9o9d)`Z4 z@)8eDZETmmCW{y}P`II@$WfH`&LO!^)Fy_W!YX}aX%P*bXH^3f=M}_;4zY;iLyAlB zM|2&i1DgfE#In5fL-Q8MR?G~2?ylM$0n3Pqt|fCynKauDqu4T90eC0edL#`FP#yUiX3@ zdBMP=W;(j8devfM`+yA!P3T5lTR<0Ie4Qng0VKOUqTScm1*2s_1Us~=+;T+PK-2&orM`eTv~i{tVuF8}@C`+aI9 z>5Z?dAYPk5fGbRsko7)oJGFQQe@1ZDlP?@;#qXdSqQN)moOOgNRn91me~pHAh3F|6 zf(;5-tf__o1YiH%ILt%ap^6$UqblSmA?#^LlDh3>rlEu&BNTSj?K=%6ms3Ju!~n;J z;gn@Kex=C$KyxZT;^>e~&o~ZfN0XZX$(!5K5vgdu-W)V6P_9HXZaLA6pgh^t;sw z_uVerTs0?dWp4$`_`5x;I%%$1>bJ~?l<*CwDbki9RLHQ_MLgrD5o<)`#)>Mk1Hz<2 z*CJG((lUXe&azrNsg{y{CJ7gN7%leh7U4_qqfSD=XyHprpx(K~Wihj@vCtOVc_%8%rfY|d&=~tzsGW?P^*xSVawUuK+H?5*)#f(Zd{}i#Eb^FMLfSe^kP*<=ezi5z~*;k8M@` zUSxD&6w(RU1r$^s1b4$w4RYi~iqJELR3I6r0NzcE`}3dw{B}g#%XsFuvmITl)Jw9i zhvsXEP&C9iVN$4j7%86~H6S`<`-pK?;?`oJ0~|D^|0I|flUKqBJZ&tWtcuod7yTuw zrP=ZGD4W+qf2N#yXkZyr#jGfULq<4PrAbO1*$BHZC1O zgb+%yK{pmd5oXYsGq^tgwh^Hr1DyV6fiiGt}UMGAt5Yp2h-h~p1UNp ze?P)nva@JFEi8pjkU}Mjo)T74KCzwy$S{_KnYpU|mMRIGik%O!nW{4(A0Jfw%f1f5hv zKR3pecSD47!f|_?o!R4xbKi+%(GRF#e@SBkVdF{E4SgfE${j2u82gQ}y^JJ>*ZHCU{LlY9|NQem_`wezMrQrK_r34SUiPxbf6L?he_Paa zjJrdJOs)v>(ID{ULNBD1@y!9F_UXpp#Jju*y1MR45-~Ic9)-jZv5+$9DWheUL10Sc z{z?yP|8C?5eB%yV?bUT^#7d>?fxo^~@N?m@=oQY#VrM}V4!tA2A(*jL@X zpbQy&Hx`uQDQTp|Cfr1(?dhsEfA5QIH`rX!{{de58^3YQHP?LRGoQIVZ1JJhbAR-s zAN`uwye4rU887PS|8LhzqUvv-V>2UoffSnAisOnuc3BuYM~L&B`Wi0j@e0tTj-RHEvwx+*+VtaKuN^&c9+s1vO#Z`CW;E93Gj`(=B~viq%CO_f0l+aj>br? zyuOovfQtEJ05PZruOi>bpB)K;p?g33(%l6eNX0!vys;F9bpzuVQJBFFY9>T?!$v7` z|9!WKm>+ZHPmU9gN(~88f1T$yK88lI2K3v%{oB9(>%V?TEcK<(B zLI`d#itjTET}H(7Sw%Q*f8b}DJ;GS(QqEo41>vD+T7sUG(cTS`WlgTVhUFo673qjh z`-4S7A`>!_?x{CO`o_qFw4%CZCgZ-3T2OtnFpZo%`NYsz#RlekV8V&Q9);}kR2QG3 zbqQ>|j|xewV3W0f)=DqP7(P;Y89Y5xgraMrPxun0XX#CMt=X~6e|>qb0O%Q}kW(!? zi!4P=k&r{`n(RI0>tP~Le~5utH6W6io3$|u-&rWx_`aQ#jWO`D1~q&Y#Epea#}giCgNPe~ zL@32dUv}OFDXI{jimNowdq^aOf8|$x<-5Q8yZwe;&>~0C@;P6SutPZp6sFKs20$Tp z>NI2L2xs4x1>G3H ztFkk_L2IRq4{1h}4h1v75B@w++l+Jj^}C*M!U?Z<#Vbxe`Q$ntr(0Wm(rtCy!-*_C zW zuOtlcKY9$IeYrzYFW3CGZbGAB1rr3B0CPL-JQ+ z!2K^3c;Q8K7BE8qf3TRkKt&mrelFUz(6&%h2fMoEe?oR)bbb2 zG;G9@FI(cPW0y>UoVXqclNufsV2PAcHHN?*pcBm{Ro(3}_!8D1u8a_^6RAFp&~w`^ zP(sTfe=fQrnF?l-OZ8M@Qiguq1bFhN>A|29lQc)K&I+@sLxUc68Ql2=ixYxU-XS45 zPwqVM;{a>N^Pm6xH(z;W-LhxnPT-1tv-KswHt=|x6LuBr`$;!MwAKW*@rj-iJ^1W7 zwX~pmBA`eB;JNlXV1?$Mhb;f&1CGu$ghn4je*n#2i?0(X@{G1E-mK$&%5b*(e)bUc zND5W4Tf}ZW9O4+QAmAXB>WT{6_L)_HF(e-;CbRWMWS|J51BnKz^Q%G(2A0=d!vVlU z6^p@+qDt9fuLxt=t|ZL{yYaa;$B+HkkNwQg{0tnVnpqx{**Y2*yDXijI%IZ7f!L*& ze@@gTQfuLWrkP9=yZ}c$epd5+B_>1{<<(5iOWLq7=og}Q9g=M`x7eIQDwK2Moh(Kn z>jXl(PwiAeYDLr-zz)1Z6Lm%oCCvCbQ07?KVX>BLv`t7UI0UBCckxVH;pJh4T1hF| z*w8Q0`%-8VJutnqlB~N6LDq3KTanzhe`(XAd%s9(v$nmjg=$Oi$_<_4p7*@xZ~o?Q ze*3q7dx?A$HN)=pdQdnLutY#^Fz|=;0A17`G8)kYLOv0UVh5NA zSQfTaFj#5QHGn!s+AHntUS7S|z3z3%C6_$(p${#M8oE$wws}#1#Kp4dE{Q&39wfgl zv`<=UKDzFn_4HijPlnnyC>T7af7y54t5jVp`uU)4Mx@L{$T_P0lz^*aXx(#&kS0_O zi&!xCVzLNE``=MjT|t7h=`+Hha*HFCfr+LD&}$B5u7Y0$>L#OfMFj9-?XV<&>5WpX zelu+V#sdUpB>AcAlmwm~3&-dU#<7s_oi_Xdmb!|vl@*mRx{v4M%rnn?f9qS{nk>7j zVo+(P*>65FN|CV}1DAZO442NqibJM3&Yj`gNkUS=`e15yaHNW0J~J={lW&p^N<#@G z{0+ZTr#3K+O2{RZXlMyavz|w(mB-Em_BaqwKY0l|o>M8}Np;dj^VYW6oan4+2piIE&7>LYtPa`Kg`YF8jB&*Ea?f=`xcnItlyV4r?|IS-ahp1?^0 zV~ZHyrI-AnP_LSuU)jHy>=goaCC%5mv3=^cU^%|>m9MyusW(++DXwrKXedZyl1y@^%~7#j0^&1b@$@5H#>y z`}j1tjuTYs$Z&CJ#dvqZ2GOH)B#VT1p2UPq!A^>z8!Ks-tg30brQRx_2=~J*H!fiS z`-L8#%WKLAq4QiFE`{iRd_+`gx)`kP@Cd@r`$IG2(Y+i|f4-0#&7-uoh#ZK*iQNv> zSH0?0=bU>^(d+8IleMOJXL(tQ0-^$b`Em8$%%}8wCu03#Aody2TV%)CCHfV3`aZKO zW7msxEjyK986`jsuD6l<;t52Vs(!jzVUhG-E2SEcDR`JCb<~bf3>MZlLR8A%1%ZLq zE*}9Cm*KP-f6X;w%0zUiT6RUx3F6bA;Ux<>%1$DO2N_38Qo(F=iHO}GW1M-B1%q@Y z(+bz&HAvo!UIWQSQIGjJ>&&xSe|5qMCtQB{<>#DxZn^Y*+)L^emNxuNp%qDaJ+$Q1 ziyt$Ox?Z`F!1X^QC1ox$}SRNF&&s* zfqpwO2CybI6HBuB3bh|PihAuUS1H-mjGA_1-^2v$j2>rlqY|H%z>hzRr_SIC&9jiA zL55r^cD!2PP7$~^0b>xxXptEBYzUzZgroKj#tq+j7|3iYTKT!M5bo5uxh#SwKJnc9 z-S2+oe@D+e^USNRy6RDndQ?bLvziQnRyYf9oH53mBRXhwHgvH8*B3KxM07o?AAx{S zCWx(R15HdI>#MR1r*z+|W!zl1Y@rHH8!VK&;v&K6(s+hM#&z5-=_ZI5Zvcxw%72|< z6BW~+8i4J= zMB!GEPMqEel0yTuXS*QpztgV~I(Mw+hIOt*wJXQkRQoZCKwSn=6wW72z4Dc>{F<-% z8vUW?Jm)zVU;M|%9(zoZTmqbq)*2J06M(X#9u`JU)2yP1Z%}qi=L8WIoC2NNrTN|d ze>5d5(!<#p;a-NlY*21oD|#s;@|+4ZVw4fOK)kxKO%BabP)K7DWn6ts4dm-zihev> zyaWDJxaMpGEgD`C&nIQ2L#e-`HIsKzMO48oC?2>)wxD&G!70+QqjV~9Xr-O8`wON* z<||4^VO$1>O2pZ~52zZzd zzSCm)wMFPorXPr~QnFiuL8h?MTqCJV*3ix!t|L;8u!>rvvcg%w)D4{wP$%iYho%^K zU3S5~;JYPc%IlQ3m7zzF_`VDu*0zLlBC_086kuS@IKiH|qr4?xWrJEFf5VeW$7h$OSej0suw7Mo-J+# z2gDzRQe|BCaTt}3=gD>`xja$@v3J#1pGk!K3>dp`y~R{IxxT!Ge@icVO6vlp$-woA zScD2Y1bs#xhZ}N@d>M99oDxd5b6F87;~Wt7I=IC0Y#5M-D5zdEc+_z#bOl0SPs|7~ zFixEazcDxzhaOK+`5zxP#7NT~$FkBIY)77O5J;M}lp&ra z?Qz6WB@;iY@@h0~T_mQe9O4--RN)$mCm2ZBS8KmZaLf1BcXA_7)F`_iK540V;!rk9 zRZAJPYF&q9>*(m5L`ub#swbZ3GfNv`&x2385(bcF9VPj!iBgExY45I;2;tFY3bCeY zp~(e6e<*}=tHvt_nJK!dWFRQ|x&R^S-~v5=jNBe^VPeMW@_Ya?KubhKFksZ@B7q5@ zYv0}{CAWjOj%rw76PrgLkTMeL9c`pq?o2+{HE0``l*F6pHs!&$|ngHILu|e`WZ+G)z>JSzvfR^VntShrqJ<6>59H z4+#~(1hlGc(99w`jnna3X8NfU*GLV?tbSMw6{GH4G;@QnK4@jY?U~({ZPj;Rs#(4w zmBrf@vi^cF(rXh>FR8TPRU!8wwj&8OOF1C~N_21mbjHNb4ciVp6%cw`#3~)bP-&SA zf70Yykijo#BaX7A>qpySc4FEdGPi-`fn{jdqM8O*Rv0e1u&fGq0*b^Y(g~b&6NczMW`Ofx+^6yeX<{X?_FcNQlWbfC zIDRil1&JRQ4BsmdM#llE+(!nct?Jkzf8>+r>&BhuoQuh0V|bEH`W}GlW95OIORCIw zWzIG+L_Ni8-1KmT8pZHd8Ar4nEnOI=WEpz-l`Aazu=Ps=3^TO1V#Lf_Ri47 zI-heyH3M;t9cEH!QQB*ILweX_AVi_nP(kU6jS3yr$lw#Jjo0#t^uCc!wO!$de~#JY zjC^Ai_Q=$?WY`|)T%R#|FvApe8!u(H_l03y7wt6sHc=bZ*&K6O`XSx*Z7AnRr)zI7 zCbSbW*3FxkKwDkF)n=#=8wDiwdC&)dl26Wgg`iwzl;8InC$V6j!o4*BMf*(P4m+q5 zY)2Q;%Z^q*P(q0%Q>~IlvN;otfBi*{X;$ism7emt-tV4fiUhs~FiCanC64V|5u!U) z(#z`+dR6VLUH69$*`T4OfkcX@zv?r`c1}WMQkJXCVHmgAv(*aP2k%8MH-{-?3$O5y zEP?2=jKBjFcGk35K4zTfPD43q9L*=|RCkW{ z-XVv~CM0qLJ!Xt=YfbdvKA{LX<)853GAM>K z!d#7J5H1!&!60gHAaDt*BcPs1st&9Gy~0H7CTa92*!|kuc2d9Eu`*X5nhRFH^A*^kpUo8j zy`))C1KNnx1IrQ$m4X7%a9Xi<0OIDR@y+HGn=@A|G{l;J6@C!9@X>^0(=CoKzGTdF zHnB*vEXB_Zzus2~3!=lB8|DV)ifR_P#hP{iUZOqpMVN!MBrs&O<%_=AV&W=>-edRi zF_IL=+TODYY4PDj_f$I|hW%#6R*-P0sZgj0Kq?3yB z{{0&Y11RlU4DEe?-bS(@5tX7E_CO6k&|x$vwYD%Og-(xQa8Xq1YxecU@Q*c9=zV1- z7{4Img`?$N zL(#;?e-Z3N1D@R<+o!ScZ07vP+?(nO4GRH;g{drF6I?xI@M&JC#TVUQ%A4bX;@J}+ zOZb_K!IwE2+~gm6QjY`o-BG6du_oIJZ#O5+LCN~V;heVx6!qj?$GX+ z7Gtoxt0fH;i>_Pom)l=WQ5K=Vgp+S%@@3Nc;#8sv)@lIn$bq>OkYnpu>(5>)QtQ ze@Phg$BY!hZl!JtQ|?Z5Rd4J73`Y4tVYj9xphvw7aOFnnRnk>#i%{#R02B3Kh#W}? z;h^eS1L`a}4&IfQz;AA8{@0dVsPw1to#qZ3@ z=3WscFy2b>Gn&>?zjLv0)o~`ymc-JK(jRLwlUKn2S22l|Fdpdob>W!!*DV9u#(8<8 z=&{fX9f1pJ4ME=QlmfT9 zPmeYA=uwZ%LLgxi@b)uxeSpz_5`b481$RN7NiagHtk7M!kBGv|9`pk44-K4O64 z(4%X>2K8P57F6xH`JU&Jezjavr!|p!76#(qUOb2rJ0t8%PZ>SC01ptYFam||P4%Z9 z1?#e8K;S&pCxuk+4}*spfy&IMf6{m0%`6W^&&h&N%Py0O4rFEmxs_WVhu0cQlu=ET2kaykh4|UbR6|J`Yc8J46}!9~h$Nl5bKmn}XN&G7 zF`fG(smaLa6SXaS(Y1_@)rd7Vbj#`5S-Pgos-RNzO%s4S69>er2td!7f8kKMEX{Ir z4AIo1Udx8|v{rm!Ad-+UAbw3Eqgb>{l{zmC6-e4@lGIN)EXDlFzJXUM(+C3g(F@lk=Ft5vUKgYA4wt3QuYlm zDoqP+a4ihDoHaqSj;kBfe~MU&a$9xGNI#)%)6y_iNmIA{IfQwEwXwg!3{qFGz%oD~ z|8$l8Z2dbNG_13O^)+Mx33`15AO(d?Rv#H2Tu=ZD$FxX7ic&_24rs@*u*}AqjTIZq zpYUsPpm_qyE`vUy?vFL@xsh@hKvC3q9C3*s1>SY*zScwUpfi z9l@4NIZ}M0%l68D!cmbFtw=min4UdBhC#mD!0cnYA-&<=Wc9f0P9y7K2<&_$(W=+% zOHi&N-E53FwUPUte`*jeg#@WouK1CC=)NVHKE~)hhBP0r_ae4ebqOtHpeGrx^FKmY^a~BSa zopucp%(EPl+<_5=0eZI;>!8#YHX}Zi{%Egr+|ZBV1(P}mCI*!(Hjvw>DXTNej?lp8^sFqp>WkQ&lbE*_N zg1HXKn?%#ZcHoZ1lgZo7|9?nNrYCULe0`J)8t@@v=u)*G+E;!3mRjLJUvka1V~9PX z$gCKQFGCFSsc6V*qSNw3TchAl8B4Z+Q)%Z9`%vVtl|PB54@ z8b0D*_kzNRMipwMNUa(`h({r3=Jvvy}twOEnimc8k1usE2?6dnWUZkF{#`&HCqdeqe~d}VCM=FO?K8?5RMSk<+imWk#4QeU z4-Ni*_P%vVlHBH12$$dgg&oHE&U8v5bs@p*S;vmu{loTp>ynizQ6vZgJDV$-07fl_ zG+UjxYfuJHWSD^4$FE$ICN+6&!5(^4d@e_IC2jUaff3r(r8{y=@sM{bS9(&ZJ7s5A ze`LLe@H{1{GlhLeu&7F*7J#2E07ieIUrUrQ#cJxP_XP)pD>f2G*6CD7Qug z{~GG^xr>NV9H!B737Z4J#Qel;tx3adbOVlW0OQMkg1f(}u4j-Nn8R>L+|@Be_DxgQVWf)$jclDxCgN0w4eaM+txXcw~f~u&DNt! z2s|!^Z|Y47<`^w-D{Zeo`v>TLCy|c*zxB#fQmz{g=N?Th5W6!ItR(@ zjHOWmV4-d@u~R=N&qjv2je=8l;r#Pdf z9s$L4l1-$AC*VebCC!%VD8BNc)Va+6|7_(Q`=Dt?FE)rbvnsxE0Kmb{=u+x^eF>0u zB}_$aZ(y7uxt4Zj%;gciih#f|Cy;av4~Mb{?Amm3m`+kwm6@CS)0|3tVfd=IL}WmR zHWW#hdZ0o`YKX>Av1r3Re*nRpa>)f7V(3XjpJU{|gqiZeODN4?K}>I=@#)Cvcc^IR53+F$Qzp#8$AJ9m5}l$>bAGQl8F{H&mZfck@o9M8iNsiAE>t`d zxX0fks9X;t3&kb+9S4|NY7sQ6y;Kl^no4{{M>o^=pBW^mj&EDJf)~r{^HR$Z51xhP%;=NTC4MGsUGNeRDE|m5;S_IoW~{xm zSaYF@^^3DPr&K(}p6?W`EL6**T5MOZ_2C3{Dnn|_yZS%L#l!P;A@g?Nq49w3m`8Eg zg}zy_r;KSfQ$Ajyf7axFZGQoR`ta-_0<=!bkcKNa8>p{;_~=(aO#p}MDP&e)t_X^C zgK6HkL(O;03Z=TO9y}9^OVQ}J_aKGSo)i2NDu6DD*?;Bcc;GDA{4^%> zC8!PSx;{x<55v5&-N0>Yv=Y`JetaSglZTWb6aJ+<|G^o>e-f`+Y!*Fn*y6L$AS4*e z;T4wxtclNS>M72vWOnUpyq1^7oh90C|2F6V+Q^7nMLoFFMCMq2Q?~YUPiCq=4(^YB zn&eRN`jWNhNo`cfd;_HSpj9Lw*n5d&n%%F%Rh6+|WmLtOSV+PeG{0CnkDW(`!e3Tq zt+||IjDo`uf5sCj3B!ctjcig1fhyw7fOr}=upU~XIpU$32+dH#>uodq@pWuLUuZ@W zK%AWiB%`D_^ShiMjKvW$7r9r%eIO)R#4BD&8nk`7K6`%OT&?vae&E_Nw7DSbe zgx!I`r%tCf5sfdYr!R_)%D`q{wMx5&mKPJqa<$f0f9vJ+Sh|=2YC4t0w;yAa5m`ZI ze1v;DYIpIxw3nhF73Y)v4y#te3BToj4a$_Dmg?ju0MFOKBpaZR*pInFbXP%K3Z3Jl zswz9HdlqWC=N}1JZB5SNKX0>61@E(^VsP4EKvsdvV}dg6F&5cFvcr!!CPSa|N`!@v zN)OrW@0WR(2!9M8RcoRfGEoPvOZavn9PnXoBZqZtCo}SdNx3BbfF>yN@!%7#fy;WT ze4lhZ1@e6PXgp~_74(h(2!PSlZ%R7N9ScqMg%|;%zNBs~7shpx+uAg9TM1Ikz2+3O z=^UZeAt||yJ4yjo!--2l(w}1VhH8)x%yX+x#d5QBw|^%8`M(_UE`9jX8Wp zooqsB!Ioasrs2m|sP0#@rkLi&gO&T3STK&#&1eUytR9Mkh_hJ=ag_p28Z3!C$ayes z@Ir9KK}+E)m+%tlB$qY`bol(+KC*{+W1)qmWsx+B&}xFS-7%i8wk0RZrn{6*Y0x@O zvmgm0<$vo11=Uw?G=ok=^33)m7EZ?_OKX}ldP0+jE}YeFh8JzT2dt)QRO&$Qy=P@L zF5msx4uGEBFW0n;g+FLG|$=$8kdehvL~18n}_`UJs;X+ z8nPkO0m#&_b(+%>VhV6^`_!w6`!_5Sq8Lh3}DKOZ1qv$wEvtS1V^|pgm!B; zf`6l8>-B61hfe2ZZMQ1W*$q>sc(CQkj%e)HpI3@*Hc`uXTM&0wrAbo+()`v@cM2Iq zrBOOrLK?fww3MiL(Vr|j;Jh?qR>gEsz?O^WOs#d3@C5Vaajb`P$h+>-UEC~BMSx<^ zYws_Y>zfbTpR{{Y$Pl9yR$-YUEY#AegnZBvr6Ebt5 z!^Wy8{`iujp1A!dThFI>q>bS?W(Ij4$i~AtsVQ|S@FphbnS`}Ez%_J60 zv7heL8feT^i(ev!!hKH95ahDKKQbt?#<@{y?^ja6JCd1r7MfcWU|NHD;5${x}9mT8LN`!u6}pFs|pQ%iE03)0zb>3S07L&af-8&11XdNL8qqu&>nty@75C z6#mkJuuf?@J7o^=qBxsiZqSDm3KM&XxC1DSEH5U>R9=xKRzqw!m++cRT%XD8{Gxrp z1AWhbrZeKZ+)wXwCO>8ut$&$7UUYQ`Z@3t8{H2}2$n3=x&#zE7c8O5KQ6sv$zYZ(3 zMUyZ1SbstBPY#ohhfQrDdS#ClDiL#UG*e_@fZ*t1tPShXcp=vXODFLFLUG1?holNmYD`utMP1t)7CC#1lgIJfyPA|7LHe6u^ zsc5rJgH!`ZF@MxpHlHZy3D#D9oX7Y|6LRFu<%ex&a?Ic1ieem8FmzJ|zzo;sCc4&B zj*H_8K;-X@b`HhNSdee64_{4Wv+y9Y!ydCx6AJfh8||wW6cboG5C4u?Z}u zg?%kxxV>f()^zBOF;B|XMxH4ktENJRVj;;ip}S_q!?q)%Cmax?j^73l;AxUxAJ=kn zdr$|gc8aFN?Xi)H019lF&MO=p&o=|RM$vap^`YoKeHMn}L-_hkwb?`RCrgc3Ws)L) zxqycG;(z};QEX2xHjw?4y-X4>ByaS!Ls6QAX$mqmi8f5K@Q&m`xaK*`rlpG!8dT6> z@>tUo5SH%ocp_4$&vM)7t@09a{dfa3?R|;XM*nWc0>1 z6oEIRNTP*V`VO}(0^d+u#D#vwU`kwSe^)n7MSrz*x`6|8Q-0>nHE80OL4JwNxG0znCyMiVgqu}jtj(?mF@z+8bb+$*~w z7m6rMf|EF2%)zeivh18(h8nZ=w7GI`Y*J?xIFIe(+UFku-WLYuYVPt<4blsIUA^&V;u19Xn!x; zdg0t0t=*hgL>YAGxp?7V-^VQ?%pnhvOX2Wa`&KZ zsfDsWGxr5{hW_Qfd`7Luk<8livP2c{0I&%-XxXE~`EeC_d@rzPGrp(V*xBV8lw@1@ z#G5W(3lkpATM^S1bs0R?7|t6hXMZ3LSRiZv_xa_ju9V9_9THt*g20cin4VaAf1wq@ zmaF`gX8$G&#Xob=DJf~hxoc%hJ3qhhRF-y$h+aKOOq{haqv-D8Mr|+RH*|B>2@_ml zTHfExf(6v1 zHl6A3^j|Ny8?28u6YX=`^lT>#^|tq**3;|~cD6nW7e!^|y^nOx4li>SuPX7yc5*eg z70-n9a0ITzm8C%aqRQWLHitN$$v@1NqqwfA-Ect(M3lQq}J= z)=JNny4B<1*d=!uN7bKPp8$uZx@srimEv*wXz8|p&IyR2TMK$t{_SW=@oI$=jwr?L z8w`^-6l7U&o-9P7YkwE7op%alH`7G959lSEZna63ca8*1iMN~Jti z+<5xx)-B|#58;DT{T0bQT zeN5I9W))GU?U=uL{X70Rqz} zKsw%_kO@$^=3iumDMF4chlCbap6-*#JXt%M!uic+)PH0P>Q4mZ2~Kl9T1qE^%OAbA zsdlTe68K7Be*h)c`xq@Kj)H9A2_G;iJoKnJl}Woq729on*MjnAe-|`Ri%!X3_c~@( zmT}&H4Xb6#t($0-D}-lZG6+bpU;k(}ZjS6fT;`+5;fUMx4a_PanaA0{a24G5l)qItp71fbTwFU!jjG2GW& zpf3c0nNXA3Ht1hpOF>3Jkri)I0LB@wQU|aC^YtqQ92@}|Gm_c)uBc-cIndM%yFE$> z2?|`FM#){zvpp1nkTD~iFX5f@K4ATd4KQtFYO6p;T{WPa$!xIni_bg+@z17vq{3&l z;eUg&-dW9>SUd491FhmIFW(!eNG$>{sFPB0E_k|I_%MKJmp~luqX`2s{ZSIRu=&$C zO$xl02brY5sra!6p_rVnctseeTsz1L#9J3bQcMOt3Lspxr?4@fLTJ<&j%Sk$}At6N&HlXW+}BH)A?E}Sl*kH zJ|-Sm)nj`oF@kEL^eQK=8&!4wc0dJKXjM;n^?Ft&5RHPOnM#VQiYY9OINf7w3&W}@ z(V&I1LVhScoAM-FwHMwBM_>}Vp(&Q=%)i{-x(g5ERexg+ z+GswVMk(`;BvyuLlIzoD4qVLEvzY8Db3i$Ia@)2n6R}N(=EmgbHZPR9*s?DeH<_kGrSfoJomY%Q3l`ybxAH6MqM%W&dLg!iv0TU}Ktl(7oSz$&c72rL_HLGf4*+MSc;*R8i5x8_Iglqy7sj1 z{=wJRW^;Yo3mpNfty7%~TWSg0NCWkzUc=Lisb+*3`f;=Q8;2lJ;J^>!`G0b$HlYse z14g&Yv+|`PGtRcSYC|y|`HGoQ7sxy+vF)h)xGZMjQHJ>pNSg7eFd-&w5{M@eqA+$K zoqeF6z$`(aeL^KAY~6Q238XcIfD*a>5g0P3SG8q3vLYJyOui4vzAsEq$TD2Jz6mNnk+Ui`+-;idnr}4W_G%`aYgMWUs4vdT3DY!dP z>D-iaI?`w)NAJtp@|GIbltB`B2-d>htDJ+Wr+vS4wh0z`UQ_i%avwk%Ro7cgCW*Qt znCza6!keMy5#7Z3G+zK@{axcVc@-C3<^q&pcM{#nh=rs?0%ifnwladJte);w^Ge45 zso2ne1gGkq_w1H?C&V*ThmVg zIpwc4M%XIHMB0}Y~W5Hn;rHj}_I>~EYg$QIN> zTsa|3{btTQQpjmmqv$ZkE}ltO;RnEOGZv=!heo+UY%5&VGC zHLmd5oELS}W@?|{vZkTX{Za_wu=$?Qa-@YEuJN-zhkpvSrQJK*EWtvQr<4N3+CIqO74bVH z7|dLSoiP!YS}~`8GYO)E9R^ifOK~;!n~!quj}?g9Ym>bg)!dcXbf%fN@zGR*kM$p> zu^L3A@qb)GScbPzkcM0@et5bi*NAJTNz(Bfue=FGh|Hm+7iPXI6^DmlxQ<*~U_J$& z5jS@`pe;}<)Gh=RU5=Ynctor(<{^;7dm^GJkkD_e+|Q2!yzWWO{XC8ph#m<6?M$Iz zecexI2?m5L`ss|U%(BkNXjFOS zgVT?d9uU`Z!tnm1X$G4vpK}?mX*FLwpJ*xDLm)#;L{-(T=I1#rbZ}G>SvwihKmI-D zxqsCioZajS=0Rs|b%LBj63{kkkY;hRF~#$6DV!kB8?3M6{mz9s()|OZYw2|)NU_n{ z-^L@VnA|0FQ%teK;=KZqz+kv=^M=O)BdfecG#S3=!u&I?*r)T-8g;~SPueYi+Na|~ zsaiH23e!Fn5=E9KfZ=9mE`LW7WNVBC_eji?p4;Gh!VF)EWT3zgL~0pd z=;&vhHxfwJ_Ip?xNL9Ny<8TYJ>P@ph=WrCJSKKPg0@k9Qr-;PBN@6V7$4FEQj!oy7 zkRI7FH7cjuG)XNb;i|n!+;1!tXn&pCu{p59_Qp#5{ImSiec>0f!!lu}-s0Wku|Q)D zuk!O%MF4Z0Nt01%%1FN5EPzBlez7QtDiJ!|@*S*YYf`zT0b@@&u8c&(a_Q1yk6HLy zKycX{p~QYp_io#M($zYh!0cJrMq@&FRc!K3JHttaWZ~Agqom9gGTCALc7LDbK-6P| zC+Ak?VO_QinYF`hoModI>G|A*OI>^7m#owaY-ru1&T{}*C3k*HaDUOWheiCA5g50t z6%P0tiGb_N59Z&k3Fp_H)ODJH*NFLJwm~9b^u}?by3Xg6r8c^w!EVkXDc+nOfnl1g zfD+}yiy3Hu=nShVe}Cb0F@HYWzPjSH!+3I#(vi(pn;WH`O>Cy#*mPVynN363j*K86?=UMxWOsiSuSKtm!3H7vMe)-MqBY*sqxOd^goB=~g z8Oh<8liw@D25zcoAV#BuN+$To`r9=h9JVu2#482`Z*_}{a8%qGJ+;om@rk=|zfs20 zKt4W32oz5@Y(?c(s#Odj9wH}9UCMHv%{k~oONe-%RbTJLZxlKBT=CK3HA?U+b7KMf zRN@Wl>DrHhp^m?@(tkd=4cku#3-<9r{0!LDF(t=kIQ0E}2?PjX$I-fqo z5@!^^VK5idPk!OlP>wK6_Oko8ve=#*_rVpxJsjzF7v`-HmoF*fwQIKQR;O4@m~0Vx zNq#}w-a*&10|B%{8u%_RVpmx4QWtIr8dZmJDZXn(qfvTci@73f4%&%C3U zBoE8$%S{x{rar+_na@tP$t@SALB3Xi(d}lm7anpF1RL0%cqXUWRQ}6kc|EC2?`x^B zuu*bUe5G{wlgr7*>xqWxrzFR3`tmJf{0Lp=nJ+G$7^jxPp^C!dkX4Cuh~dC9#K)Xx zbg2?&_4OMP*?$VD%Nx3lL6DnyMTK5-F@TiKZ(js=jC?OGN(QetgC!wRB zq*iDZ)BvT&fkJ{z?f=1ScAK<8lDC5@!sQbC{lPGR34b}&3JOt{x}x-!slS1YZ9O+9 zi{7}AE{I7baH6fW?D?r>hvV+h3Qi>zi{0{fNApAGo>dvk4$ZkgYYQI2V_kIM?z!wv z-%7FNkf+AY%8{+bf>+oq8Pha)IbXzbsA!V9pk6!&3``H14o&0?Zez$R#eC z%S&R2PJbH1Gp9V6i&Ri~YW$Vyg0O2L7GlB(ukwcNVr%70Xjey&?CM}pMWI8V9Kb{8@Fnkc~m zN=nm@4dg?(B!E*zjxUza)y7}Oonf*tCyK?suZ{Tq=miuyER=d@krXLEcvnQP{Y(k-q;^O=T6B~$<)P5yUlp+R`xfM8$p4b9)ZliJY^G<+#8V@>^&&)wIVl|MvPU~b> zmZz=^B@@*X)*MN2V=*u@l`Q-uH@UqulYcFRvTU>d*93PqGzm}Et>Lld!RMHEQXf;O z7zgXvCXcG}G1?}T7y+{4 z0mzV(LkG3CST7V_7!oa!3*Ch>;K@5hDpf(-7;h>JllTB#oRt(p6rtCdV9`_TobKN0v!I0VfrB@VT#T=g{5BjAtq%#pxzJ`r2!&nnX z#H_Fv+>n-hc8%KA(&?-We@ze1P7t{an#z6;D$ll<%fAuQ{cD0dEPqTA2PZ48GK=mA7ivZ8{xb~O8Jpzh&fZXJ8UIMGQq8~E#E$9ANvXzlHs)?AJTUhB!y^AIaQF zVYX+DG;bOg$wr2XM)~vN_uNBg=o>HpP5n7%V=hTDFE`h}Tm(vj+`kR-?|MvxWri{v z?Bkh?T?Z3h#Pcg@%JK`ff4f2Y4s2u!Ymo$_rt89qcXOzRdV z&>wi=nWRuSJk>VR8^AjI7RIP?n&*t+%6N2BNj_hSq)}FDXkg^^^f)eavd|3^FW0iA z^RoXA`|=i?MSqBvs%`DN@O5yZmU7@_x?c;CgBUDb7);7;)=jPn<*|;%QJa;!IDxRb z1?kWvMH{H`!Z~_DhVkkFxUH(z{!T&uBY{=tnIs`#U;L{;D1rZ?OLtP2OmO;mJ3ZuJ{{z4%A`eX?|`FiLzJti1vT0`G`h%781h0F(M1 zZ4nP3oPW*Cn4+}qKX^=8{MZPZa8%?8DjZ_O+*Nk*H)NPFKDQOB`4uQ^S<3NXze$W! z_2$#$oJ%VJwSzgsq5hHGi&>CyOInjeq6srvLpA%4ROO z8}RDUgc({Zmj0;lz3vL-3%B3dkf!WnXoZu}u}HTi;7gaw18W8mmZJZn=_4TqN~D6N zZYl`@E(4TYY-h#<;NC!qMbfnpI=(`z_ zs*=wyClZ;V6hO@z;bB%mooy#)* zh8zK;1@<=y?pz|f5<}SM(?UdbeUf(aI^WV1*5)E~#2Bn*+KpY5w$8hMm!6-*|LkMC z=sIJ_X!D?=6#mbwcy6KuVN2=JE)z0So8VBjpeCJVy>M1RxCx#;kGR%ap4iP9?0?uM zt<6Hh9CkbxmN5T4Pw}Gu6)G5kCkGbPDGw+#8}TZE^?>Ur<5BIN_IG?`)Z~#HTu`C6 z7GY!0I&0{^3CmFn?!QEjSQ|In4r(SaMR6EKL@zJB$Q3K6a&Gy!E-8k5mHdg({6fQu zUygOWC(P1LqakXU#RP|XLp%{7c_H8~DzQ{@I1{qx0A7xtBXQn`kbeRFv1a07)QGxQmcZakq?3sw*O!B9$a^GwV&V{XQT)zBDe38^BmdYI2r`21Sk4 zZR~B(_qy%~b_*GBKfeqPVTE>1S$tVs>Ted@WA#3IpPO_bsUv6f+JCS-XO!jTi6{eJ zu(M?%orf2}x%%lCVOlDiXc{SPt;nMgZz?5l=#5J!o;dv?dB5|R;ykHC(@+Oe+NNXP z3(+keQhqM}3(EcvaG{EkXdLta*2qU$Z3D{3$_V*4-n#(wi^GVk7Nk@V=%=9l0v1sn zDWVrDMO(c7$`Zd;_J0Un1RihQ>h{l`I$QkDiLU<#GWQ5Cxm%yw0O3tE3nU1&e99<; z=qo7NW_yMj*>+EsC$tmDI3Q@bpKH}2cDwQ6l`?6G_)Pq!G#R_XU6zXbWil2(6c=yCZIgFw)1I|1r(+}TVkJO z!7#@a*c5FrtLSxGV<^;nQ^zh`XDHF;o?ZF`i55$_nIw^3fxex`3cf}{sq0eZxp!{_ z0E!Hf*FxDnIDgJ-n9jMlSQ|+S6L%JFBzBB9dXf7v2vUs1u)`f*K=FHeQc!;beNJ~P zJDXPXTVpbpuo+SY>&fOHow>KHd|UT;Aw!~&b4hpGP94Vw%;x=sa8tQ4R*93JaO7}~ zKlvStD;D;-YKUBPPHz~&Fua+pol<_9=fU=vGpb*D(0>r7v(PH4Hht=zMZqE%1!)mu zC>V2g&M4N&o>FwLSoiiHMJEd-NLjDbV9x_aQ`Izs?Sf{f=<2jf91Bf9NH}&l{$zmt z7~Hv;Cn%~HY$A20pOr(;Cod(xtSKV`z?fRhiKq7bsU6VahT;(7P^YY!c+@p3U^ibK zGC%s8M1QvN1YNb$3Rw}|F>QE_c;>loE&%uBjp!r|Fgu7i?g&;xhf@kMrFs;?hJ_&e ziJPhv(4&R|Tsb_BhDYIo%4m7&fY_zw?#ly9m8uED`J>`6A|M@rj%IGA-CjUv#^7!~ z1i+4ay&?MlahbayGiPBEL@vJ@SdxsOjI$ZNJ%7TmT%FHERuYGuh`B;0IR@T_sqVAE z3uUG_=*rmchigALz7I2!-7mzHu5&QAW!l5T|8%h88SmKIR>xX@XQdwf2^J9at$8|b zLTp#N&Wh}B4;sYRm)h}ynu z+G?Spir4B|mSy*ve^Q9sDFc<_MM5}n^-yLD9u%X;$YIEe8x`W2QP=; z8yl)WGIIyhO43s?#fBFq4fiyrNP(aftS6g3b2M1@|m}#drWFO!t1)ovN8mp`*<2!U9W_64$1vZn&%-$A9HW z@yom_?yHb|O6ufQPwu>zSHkH2`i~o*{Kn|XpBmhAt*d9u9tkO(E~UTb_REkDsYAu# ze&JGwX?larU2~X&1Gzs3qu74P&CyI3C+!5Yd6#efbYoaDID6BuWY*w2v)7?m)GZtD z8l-Ht@FmrrTo3n_ztuR89ym6em4D<*X5E1lr1JCg?L||$i>r?LKd5*GTnFeEzE}f( zj*jRoPXQYF;?ZDO;Yb!f&L`$*2PxqHjfn0u_ZV+1AjY&pzOm=gLz>RLF=AKp1Bsa7 z0luCXNF(LoB2&t#Cx0_WZLDSZez7zsD^E2#FByGh$YiB6Gl=ZA(^bpOa({8&L0-xV z0r=q`3iQ5bnYrb|5RG3VrIrM)1M7>4E1N*aJP$KB}ojqN~4)>YfN3{#-)m1I+e zr*XBrdsIK{aF>ju>6=gfFA46~fG)_1nHCd-Q@;!Z%ZAGC9Jm6hGznSLkh2CWMxs z3unkD4AWq#Bub$Shk8~!VZCz&RAM1L+PbkQs%=v^J5zS`vG?H|w>yO5pz(imaKC|+ zijif_yjIJr3u;Ynm0v^kWVpyVZX#!F6Mu>1nZCFmlwxkWeY!A|G=Iu@4HZVo*Due% zxMkqUQQ!*pLL-b9AnltYspd3CNm+LOdO?)o+(3C3uHX`o=3FXswsBhyZ7AEfP`6ai z2(QVFO>STY(bIq(CRvFs<&JR#(pyf#B~)0pmar>_zI zRKgE4?#g4i_l0i>IDbg7k2du@xqS;;j>zQ!h#iHBpW8Z(F1K4;jm5l%;_#f&M-Uuf zD?}JJ(KXeq0aoSUt#LUDXWI(uf8n2oWR`b94*13}qkR?FJ7~2_rM>$oD`(i}XnOeK zchBzss^H$0zL=VR&Zz*wbB&$hS1a8Zc}>G7iFqdn^SbY8t$&M5l-#}8p!~8)2+(3c z#|0opz5M^R<2;2=Wh&8NnpTXnxp$tzPPJb0PcJ00j-LdjjmKUMh;C0yAnYW}rsPf! zm2xdH^{{1(SPM(#0CjLHV@1G?=cGR+MwA|4Yj!Av7I66a8x7TXZO?6nn@9BJ!78si zB(6MXOQQ~8qJIvF>W(*luouIeeSwDi)EW-GajUtXoiHqLZHvKM4rSIV;k=VAf(XyE zVOYN*Zkppn*9GcP zpp;oFJFR5^ONDwikQit(6@?L|4fTrF#d)G254?jS#a8OpFWHAWx_~9!ZSrL9;>w{W z2Z&C-O7vU=W~xcGvq__wSa_SVvpHbu2X@hdd#I#4H*+CGWw}aqwcF*gX;^L5-&jf1 zc53#^27e!aZO?Io9k8c`=hA|<%cV`N@MtL4_B~_3HRNF-A>1@;gTh?ju`E@dd3noPSWA%fPzdMY)uj+vy2dN-vxhC$k%7 zdzr$Vts;TCluW3)W2kMMx(lGQj`z!lral^@hIISPQA(i4Qy)YCrYbmon2J)4(38s| zPOzXTT{bSGRmN#hh0J;I(qUP;-5>p9rLe+pIuUd1rZud*|9K`%A-Eqh0cK<=HU830 zE`RNDB}zv$1w+JX61TuJ6QsMn_K*{19bZaR(rl0Qu3^@;bTL7VDroS?NDGXWoWu=# zcx3_cS101j?@b*gwvetUO?6UEK?X^nKmr)jWjgQNrb6&~tSJF_s*(DaqBuPT^ANn@ zv4;6=OK^24H(J^Oq?>91Oet4iir=N3?Pr`=zMSnmeh%9g)ql&+ z-wf`3${h&PaBCq;+q7l?38IhMM~i3+Q^FvOrdsv&qsXJw3h%21_dqZu11V{2%W{t+ zpVA-=SDYeoWR`gw-K$h>mpV=b@{;>8HO-~?o!TR7D9re^g@$5r41SW&WeGBNgKGQB z#As#QJFLVqN_|hdJA^O65NlhYH-FYf+TZ9sUMq2T90qWe?ehSa4B!W2e-Yei^29WI zu!b7fdyP|Sd=D1ha6w8OBz{~6Sd?{3Hc=n)kt-2N24IdCih_PL5g`qT zwr5gRLrDSv+lx~vH3FUVC2pq$3Pc?O@B-+DJArG z{ZjePy<;wE3Yte)X)~Cz>Ggh{D;i28#{S*O*#A{nCY}I?Wx)l(azoX1<)s!lx-UlR zEtB;#CJxw%>l?D4r`C%@Oz_i&TveMM*q1OvmzU;tepcvgn{(pjb_rI$TV^cn`c;#W z_hoZxQ)cv>IqssOLaW%E5`XZh%x$!Vg-5e!&@%Nqv&OJNd8)=6oM2^|-CU2p?FPU3 zV{=KCJxpH(U$jk{l&`RzpT9$JC(~_=>I8(IGf5h~ZhK@2%9!(n*bOc$X(8}AxL%q_ zlt7raY09@dfLyDQSA<_RV@-8z+K{B>+d1=An}@6nvGN;%O%GkYRevyK2ngXv;0oI5 z_rwi?St%q`6cF0h=QUNJ9Vme`*@(5GSu%en1>n!$i_HBLOt8Sfl6qhvQ0Ba6BVCnF zu|F{4+&rhx2d(D2a#F$bH?M1-E4Meplf{8b0~xg|t=kw7;%Qn7sc16CbD&o?N}anW zq>nmJO6jT;L-@%}v2_tfRbgnXJkD8UR{4Yu z>ZCJ9tF$jxz%C%8Q9*S4)?D+kpK$)42=23v)=0&wS+u2z!_@KV>x zQ$iSKd0)nYxr9P?klp@Gq020qZ=`X${#+*@AuE-)tADBW3F~UD#IiU&aS@!*l)K!3 zCM6{CqIkdYfh6dUY1okB-R2oCGN!!7l7V3pRJrkGL{$7%v@{$Dvp9c728zyFt))ustCr{sS5TUVOwqxK z>-5j&04A}PEbj;3NPdT8JAPLVy-&HY+dzzJ;3uB{Ct;Z+-`L0YBMxdG_HSzQDiE5o zY|JH`ofXGc18kAubLBajNMmxdEH0rWk$+wez`3A~wKPkg7`Eqn(;YDSK>G!-aPhUw z7AeQXxchL4m2w6PCP-1cVrc~+t)B^FzEx@<9Ccid%b=oy;DfO?#$BmK<^h|`J^uXt zwZZ)wc#$h#b87UV#Tn(6s7&xpi@`16!9t$hcgFQ`DDZ)rOadg`Ss}qYO%XYtI)8g< zR){T2j_$!1nY#(5mXkms?sXdZ7^dZs^Y7VxO~c4H+&$^ybc#rDd3q3>4VGGr>2=yz zJn%8#1)FAp*37ngfS5)-cnPZ z;052gmJNcIF5|s_Mkb)Uih4zs^nVZp4hebo09lhUELhBO>ABvKruiW0dnAknA==DA zrDD;;HN;^lWXD0J=DN)LQ1`4`Ai-DBa&w9_J={*fhj75%?#I&jMzh*e-#S8m{(f(8 zpO08-{F`vTHS11Dp4hHA0vpUjws5@y|7xsuWQu=I7VmNe4w0pE>%Qjo-G8^f8VLfo z5ZC$a*5w-X(3X(`A&?No`3JOWlZ}a`#41l~a>|Zb)ne?c$U0`B$`D*o9KN^&555uK z!e4CW2ROVA{Lx+i+XnYJUkP#59oM{54+ukAlI~D@sp_1G$`Tee1(BUtgY2Kq`WlJ0 z7ugQQq>C(YjE9r~^jMf9t;e{QaKb{_lVP`+`023=eo$`beb3+E6M6ag%tPWo%6z z^5j8Zj$v)V)Uw+sPPbe+b*QW)N;=(CLf722*PB5fPOm@rR2s#YF@I}{{X=1z--+Ak zkghUyky6n)8Gk}6_xUYMfUmRA-E@pE-pg-h!Bdn57I-OB%(~CEAf* z=J+zS0G3+jWIM-(L~scG$0l2Wn`S72lfX%9P4N#hJ(F9T`|Hsc58GG+F=W4U9SyuQnO;vKzd!!%`h+OT7k`4$& zvsvi`LwLyc!FkKqVA7BPN7J{v)CK^Ac#ejyQ22?+^a7GXglK>NAqlXE zFj!EK@t-SeMJ=p#pLCMa;2I1(2bcDOIT#RUC4fjOKvH~mpYYQ+p4UK;c?CS9!gaSw= z;BDn5AjB^y0E1oZ>rZSCq>kNxF5}-~d+7PN*$L>_dB8mpHUK~D+5YYf(C&Xf(FG!~ z8n70^5nzgyixS+%6K3a%R8x{=1t9#kj<#SyAxS|YAqi1I31LBTNg*LAQAuSbAyE-U zMde2-qK`%X9^>EjRaB7>m3k~8sGfbp+=9tFO4q|F$pqF~ZIY2}kI`;Vyqmz_aIYB;4aU+>Pb2t{97km5rn8#rFk! z{@SgQ9m3Je&Q=8hhq3%gU$Eo9nO{)kzuWg;eQp0=XeIzGM&Lp?{z+K=ZUQ9m;`JY* z4}APXdF)&PjX?ma5k4~-4+8NRsVP0u^Zv1!;T**bffDU4bRal zOLp@I@eIT9Pa)Z?a!OqO;jwfGN!hZ@z_By*z+T4Nb==!b6uxguHCx+EH(+DdL+f;7 z8jwA|w5J?IAW%`{0}c>KVH$XKCjo)JF@iw1P=7W2{rnfeKO_A2fPWs+Fwj_#2vmH< zb*5pzgC4$ja4_q))ue=r?AR!4Ig1s0)4uv$*5kCRaqZWy!-Luu*wi`r{kqlaU=|8C z>~*M>yp z$Hb&hU%kCIs$~+XHwM4LyI@yScST$vmGw0Vv;VWQe9er)^B&_kvZ2z9ryP|s_uEsN z_i{P2{1Mo?ufobWo!`tU!zMau^)c;^-5ycaRsZz31Pg& zm3D+mOGbM`P`Oh_s|hSmvtHB59AwIjEOh$B!1Ih9y*NnH)iyo!R2sYJYxeWW`FtpI zjk<~sNph7?IE8`ERID7~lV*v5LDpT}U=PY|Sgb^Kp%pgz#w@h?%$E9D(gJpI-EsNX zD`<%WZDkU}Q602xz_8weI;@*dX++r9IVmcYb(46$^1EYG;Y})Cmt1x>Yz4Rz>3*o> zHTxvCm!r_5uV1HAW^d^6?TW2HJh~cOTY<+m4$ACCN!gY-3nGXxJM)Edx@*^y9Mg{W z4VIIb;`VwAd#GmS?=`!pH(zk0rdy5#PJk_&w(>|mDjHzbyguCVK|>5P%x z|E^0K?7W{4Q~{TFXI1`nAt72 zf68~e9lWP6_PxmCY62&;;*7s^9s47B*lF41DZf^h9A8PC(bAEt?Isxi0W>D#Vt%To z>U3P*$t2QQ=QjTbSmNwb@p{|7g|0sP`2Oxj8MtiknisuDmUg#lEK|UI2rc&%eNfY{ zlDC#YI*#}1OuQZROABl={dc;12H&Rq8k;Rdjm_=6 z=!xIwlybJajwjJ8N%ed@<~u;(+Pz(^$Y@#}{A51)*n_-a^iCZ2n3LZPFLP>Vc$s;V zu~B!AF;x63Ke2&kj>UrCbdP&9=@h0g-+0nQ_vlc#Unwb6+1M$!yV0ZCJZEDuGTL8o z^JOXDKFS>mM|BkR7_<!zs^UbO`0XJnZXwa+@wm&+GwsB6eLrO`)DYifw#^I zJ##yyt#Za&9byZh6VEa3I9~%tN}e$fS$;0^xa48J0h~Agx;A_)O-RQ3x8+!I(~Xj; zI@kRDsBjnZFWFI<$n!D>zL&=NP6n?dJcN}?YC2>2coiyZp~PQ+4gBa_Z+Y{;ek`g! z0-8qJ&r8tVw>Q(UYO}gh3FTub{cwZ6W=W>lK&yQIY6FzVUelahH@yE zi(WY;9I1gJTL1Ogr!5T`iC&Dh=nY*(Y4oF8R*<>q;HaB5;;*Mn(%yyFn@@k`U%MwX z9w9(@9#$1~^1ilKqEQu2TQ}X~+H$XqQPNGp>d6>Uif3hq{yk^`ik21U1*Uf|TB+3R zF%b7zdrC>CZy*crvwPMn=fRyHs5Mk?s#u@N-kp42lGw;zVSC!%W1VdNM&yYHJ2a0H zGTsi3>~ZI^mndma5*e)a_YNHY-q^3Rn#8mvQp1=DN!|A?f7M1sA6*$-_L4)-ZZgbh z-)p|8?)wH{#Nr*~x4%(U+xPK?=gpfxMKlKTG8+$0=fxDS;~};YKDxbfN&BX}T0_-) zi?=Gxi}F&FI!sw17>nY_40bQXb%`3o2L9xs;NvbD2Gu+$+iHo}fiN_hIc;ob{>V(1 zOb8-t;A>}kI}MlV+-Oa*F~I0$@U2NbiYm<+vww?8ly6C=ilssSvQ=B@?-K9%5AL!| zT=})#d%1!k{e{qIUzZ2CGtrI9dVI&9)cIE}$pmS7sa6PO*$#08{_k!FgkAfncD(-b2CPJ=G$X&_%22F%E%=DQdz!Fx#uCicnn zj_yR|eQ1`bwl?YV0|{;mjZCpIlU_Of^NXWoOnQHeH?A$XE0o{ddzfw=8bU_Gk z1SWokX{5`l+dB$57epY61orZMc+J8j``$$~Nhl;=kCk6QPfV(tvCXAAPcX$Tx;b?n z{AvWJWDls1SHxgcH;tn6vjV|qQPuvED{mvVgMIJ@B|NfB`(Xoir0?GrQ5X6w_w%m! zy2m&)<&_p!&vIx79y+Hnqah_->KS3Qg^=cxWr3no`IC8ypo7XR*_|#nAt`4M%2hhA zQ@!Nkj6wPHM$+$bJ0-*7)sqPzR7J13(3LfO?V%VKL1g#zy`Xl5 zSo3VyxW9R~NZ8--dckgm4Qz(b$?cvQX;A9s{?5`XhU};m<0l6L^_Pn{GBPrpDvBx3 zENzu7qXP7rBjPo?Lu3Xk``T(?Q%)h?;Kfe)Gk0kgM6%msy-iGsiRWimO>o8llqc{8 zzPe`Y;h1iJ`SL@rNeAJy{7heU&t&2!C9PwT<>skjZGFZrml?U_6WyoTT(-?NU2ogJeFLTohS! zrXn9}qbMkq+}4`s_ZR^s-y0DIJiJ?h;n)9X@9x5R`(LeOpep|elz+K?#9nuhgxiSN6V(Z@i{yrXG zX3@grZo$ye(NSuK_S#>Eb~nt{TuH6i5TpJX@-i z52fg7ZLLUjoC`@o4kqTIyu8+-1l%PrHJ=Ccuj+`uutxZ0zso9rIIHM=<=Y4zKNn=- zSK~Uv?Z}GAB7Xe%vBSW-xMm324(+*tF`96#z-4=WX8z@N#`^&C%J}Z#4t;z%XxZe^K*P?bFurt5>gl z(az)ita!Sps3_BBf2piNbhXe!X^?1LGg)`yH}&|jnVHkG<1I+fEj*o}qKXYet$2ql zDuRMYfo%i*tw%O;RI)qm^({OS9Dw~HHu(hO-lLhx2zskH2a6a>emULfqx;9}I;~J_ zz3G5$2Av-0xk^Co5p>P))#WW70bD{t0x>c14?%QY8O;|P(EIQ`vsU&ao!@ezqPBDL zm6-NZfZn82eD7qle0E3qmIv_&;q>!+X2Q@gE`fgzOl#`Q_4{;%l zW8b!Jsx)__Aa~JX&W>l{<8keD_y_ZV$>YHVE*vVyShah&}Z|RUM~d z3ru6_Ca8!F0l&-z5f9`0eI4`y%8r{qWCU4ye%tz6nJ?7;-)j5+67bJG|E+!a7mM;= zEz3W8{8zvimnzFkhGd6CnX8Ud=0vwpFIMsldF_SM;^HV_C{IsMBr->b>j4u0$fL!7 z{ra_b&X-L@XtpH)KilMYOduGWm<*!~+uwMEioI+-D54#dt-=$cQ5I4@J4;8qs{rLm zLoOu~u>u2kKn~N#sRNG(oXbq>_c7ht-KV%2G+?l<&l9gWUQ;t5i@+&+XIQ5 zYYvb`;Y?csWh;ySL~KksqumV*l$obBF^Qyb0q?u6tVHIkybcXz-wp@}fWctDqya`~ zaBg)6r>Gx>E8X8XzEW20X3|+*f|Wl-^GIl3y?+9DE5Kox@{}Xa8!+i_Lv0Hm;JOv& zB9-MOG9MDmO4=>3LA$GK>F{PT)`QK-N~^Z3_C^Bq$@KqFBC$Ab?DR1y$Jyd_);L9sVOq5qXLBKMYDmiC>kYOmRu03URzA|h+l696awWh(C@L9{- zyn>ybTq_6S$IG`E!iEyqlcxlDp%azW1AESQLcom2%-xgpLG&peW@a+|$&yb6TiB9r z*$fG)c2jF%v(OsO$D~Xyel_>qwUTR_EGtA06GjPK)CafQi{-(av=t&F!g-sy@1Fja zmkE9t@_R8*D8*&%P-(EfY4XE4en6IujZM7w$Ly@;H40$ycerd+{Y+Q`1_o~&EfRYM zW4qJNvFUc;GSwm4GD@ykuxVQUGUW^*YyXK9s5k8hIC_t4Z zuPPd*HNQ1ZVqFW>O5m)-;avY(diGYXBv@XXAn!Mk`7UBIVblpnt84eDc2$!d6H?Jk z+skcnBNy4oGLK6c73Swmc-X?xL%>bJcYU}&8$JwJG`v5Bsla)p&q~S)xt(CECeWy@ zmHza!KUo-J^5!Cc>Qb~C}>(!_L|;IVcrHIcgfD(UNN5nnLbN70uCX(%&Va^ z>Cl**^5nIM$b40lfjKwTx9wSEHb?Q={J6qo{sIAUKcvxuLG4aO3G8Ul#rxEBg#gKy z>x&Hp%(h_Xmzl&FJA=Ia8M0-VJ%#Ohz$l2IzZvClMcDkeBkpBlNdFW!Jcr<2CcE5-P@S(q0ueXp@nRRp^1a!B9j=I{P z{q!$SW$MkUe|vls(pO!cJh(MDlb}vbdS#ChphG)byn)u?s8%i^kd?QN3}a3$o`x^G zxoROTe>5UZm5yTcKG8bQ3mV5B`DX@R@KUqKEO4J{nM9pRS3XmsdORzT!EqfXB>G`p zi&>iKp1#I2d7H55?Gx)9ZESRh_DBCOnuvXz2!&ggU6;Eo%nxc zzRT60^m_u59K|UGzL?AN5A@gV2#N7uxV~I7uhT?6Bo4Vw31tCvs$_; zznk82&J%lDu0F7gxV#A*hJ9vpZ4gr#NXx{o>W2qU*I-ub{DLCuSp>xcIw@3;{YsPI zsl1SgHdW*PsWrbvV<69QB$e^Df>PIaRl|70pnA4BGy4B7C*Ns0Ye|lzdmBU<4nh;4w#eDj` zOpcIrKKx_0dzuR{i`wzsw$9Fw?9}~TDw~ALHJi0#E0;E{2d6tIlEda;X`>rUQ?NVs zXIDqRr=0q#l~uDRsb3u|^gZjl62~v1%P!AG)FSm(*2jIbeRK`kyofqGo|``I%}RN{ zYPflEZ01$~rMs<(8b0a6fpD^fl-KLt@g4+Ksm5Pr9uMM2=Wf!RVPke`JHv1Tm>Clc zY;Iz5#&K>5s((;$t68vQr@a8yV%TT9n?fQ|)-1g6L5%c-Zqd;uetsCPwD<7 z3-3+lqyHhlw=jo0ZGYw^Y_QsSTcr87Gl8eA@z?md?}s@!=}nUqnA(2vlwcYT_vC3% z`p3v=v&;bXNl3xop5Z}XlFpaFdHZ>?^ZAy*mALcbjJ^!OBe}(i10u!@6Fl=-4~2X^ zue>^^GE;M4^ZCB~ZhV2#eQ6K!<0zRZ3trpZBj?9yROiAwBWp-}a#PR=?c7ZH`73@) zz_E8H346?4?_!+RZEJosxg9DFQ(NjdnXbzS?C?GK*>X3ds|f|$%o@niGQW3hkQKB! z-h9%p2ca*x3yAaz3$FL$X8a1^*O)i?_D_whuTtesLs)OurzH0;?S#;;btllOSjfn} zQ!AAxtT$m`1HwPou2P5bHMw5^@KRF8qroqf+nX`qpy(G#liL=ox#-rAj)yNAGd|ueq zbf<=v7eUedFwYIEe^8BA_sCC2&1^^8ocr|-oce3u0EDamPMsE?jlc?IZVPw3wtZ6X zoR*cTmenA<{iTfgRKkMrHsxvg1SK%Hy)LTd=h2lG!!GKRm&k+Y$VGv7_qL^v1Ggsd zILX87fwmWi$x6uXbitv&xWD1VkV_jy(G`ox8gESJ}u@3PRLr8RRhW$+p`8@QEq(rp3%(a;M7 z-hX1KgQcZWTR(hoeeLId)_Wo?M^cRk8z{KqMcx~=R>7oGqWT%`HAMlgy zr0XiM;i5;==!S;Iff|zLvmj&XhBWC5CzLwQ3F4ircSDPlXyN8(UxiUC7`dSkP@ns+ zvC%~XFv0%}0EYg*0Q`T5+{k%xK%R#V2s9tkL}spDgu1ypfuLC+`E=Fs?KhZ4q#pzl zS$Tz<0#u}c31P)o^W%WfW`LpY3aI$z&QW9d)DLPr;C(gGkX~U$fegjs(BEdh!LSj2 zC{*pL&uvt+^)oM!AtM0@ui0Ilji>#5edD`xaEQFEOM{>nEA7aq3;gaTqYJYb3}$SM z-EMFh!7ueH2#A|IHmwne3O-AXNc2RNV?yqy%iR~zw|h!hbWDuvY@<&*Pvy=6z#<@g z5{oEby73jrK)@&XDbs7duQnQFjlB-vZjg55*5^3L`@|^Xjfk4%XGq;6-Y?7?3?CtW70u!54!_fZX znCNJ(z}j|^;;73nRP?>Nzjt+Ym6+7t(byd~S2hBj< zuey3{FXJH-C|Sx_!Vbu(w6(PX$;Fu_KNOn*dbr&zDkg?IxW#?(wOZo>D#4ozUErVH zXnMPZjtChC7=fU{zX80P^67m82W=r?t?R6jki$+jjt68K(y^_IMC<1 z1=k)q;3p(>zhD!KO)B1~<}w}@U2wInG)n*W1_N0(%T}Q`r!%Dj(PVFq(3#v2k&<$3 zDad&qu-FmJb9PK$WHilqk5z4Mbge3Ywtr&cuI6=6q@saAighO-Rox8>$dK6ni3odY zpyD2O{~}BKe_nI{=h8Z0_Wv`%`|kk%f^Z8+A=1;M15bU$)1x=XHBSpB(MlzUUnv6L zkF!^sr+)ZwADbduWL)ijc>DrPkxZ_YDO2Aeuyr>wjh|oHU_dO4D1ekpkZkB!_oWQZ)=>Eqs~n%`2z1@8%;# zJ0w8HxWANcsw}ohoe;+JY=5{;%v7x?HaDKzIa|J90tjYN6qVa$-0wXKlz)_A>d8#H zcn`(_#d7k~tZgvm&%ce#{#?TQskSCmbx*jA{2i3YEJCQnZA@QV96>SO|CIA%!9Y^9 zr{~aDaGrj@%|NM0VIk&n?VP`YSV{?!KVw*j2vh0B?_3s>XtZavdfT^pvAZr-4OOAl%>1p8w zYtK35kHTf3$Da2cr>Y^G(2$ZE@!~j%!R{Px^(@4d!b{wbl-Gpy%f0feoOgig$gmau za_~O8+;vNX3U#vae$B$2B5{3BKoY;5fszErwOa}cTQ%g6q$!m8+Uvs9rKO@X!*M%w z)ykejn)`|SGlz$D;+wDZq4RkU_woxJ6&ODrH$;pGd6_3|j#%gu?egO>J$jt#lTf0u z$+T9vjZJtbBzC>3v9JWJ2QHC{LYs7@>=lALrH0cX^Pb%)zDi#%v3#GX*}{l1R99n(kshz{#rHq{uzkX%V$ z=c$IfdUa<@Zy82OL&=7ajnRl!Ref0T*rS?inzhZ5IpfS{8=HmsA@GW%Z(Rl9{vD^? z_i`0C7rmm8Lm}@D9woi^{b8CVzNgQOV#_b&5-13_%jSE6N(e4}h{tSFF?s#cwI{7F z_v#rl8{(@}>Im{mtv7uzXU#XZ#;Qr*o!Z;BNF}z9>MYJJm~T+~^r;Y2w^h;23JhDnFsyy*i)Qk3Mn`D~$ERMOSK2E1x z$k44J8(p0jQdU(zklcCKG|tnzuQYrrqMMm4F7s(%fA zcnm#$VpSl=T6+T$h1N3sS=Q3S;$^W$DmXK)8K52nl(NX@T=eq(KtaD`2ZKF?fg2%W z4BrcKyAbw~d#f|R+Pe#Evz6cVmUMPHLD9)sY`Ez3nAl=311*6J6+_%eG*#Q0Oz)`? z_p_jk+FPON94Th6#qN7qO{3-lC@ITpM>3?$h$~v`q+C)N=wQW?n2F!mxf)mtZZf%l zNVA}@K}Q0Cuc;7K`>fY7f&%v`mjQ(}JPbG7>ShqbPLRjf4@!+APF+6^N^dplUf~ZR z?vjEQ4;(6fX`_&DRLXVCdEOvE#(NU+sk77C8f_e?X`J_H`0&T2Y@<#)p;tpv;b?MY zwo6tzpLUH`n$Fyj{-ZQ!n`#-?$sz2@2PRPkZZ4W^_aUtfo(SOjQEGVzy<|}^yRTw@ zymyL#MNAZ?{~9h68{c@KpH+BI=!yPxc3fDJ%dMXkv&kW-ZsuL~d{o?^ItED8U1>o+ zwpz1+N)LXNc1p^tn@uL>T}V(DlC#GvSLP4gjTv=5^2t6(hzDdhT%(HH{4@2Nbx69q zXMvW9-}?cR#58vg-;4o{$)##v&&b)FHSt}V1S=#o;wiNr?8lccF9tjTh5{#y^3Z&U zuZISE$ecS+-lwxX!No=U%OS1mRLz9$ck3m@nKAmd5ktoLyb}QIvtgGh_jLK7v z?{xagMzXLZlfJL}Q=hq=-tv7JQnMSQ;?(RabXAml2la5KD;j{-y-i(v+NkG&=K7K4 zB0L>Y;htIfs{is260;5kep``RaT5B3X%Xpk@BX!`?^h<&HKc8zv4t(t_I&+2;)8O> z#l^No#593)9fzs>G`ohLFN?YTzyW}LGa1%feM}s!wr(;<(AS03ulk7hQ_uPwV{2(i zubAxp7#(GkUEkb9Y7UKzAkI#Fu-XDn=$%Cs+=t4k z_$46k-+7n|?OqT1~j3}nO9ceK5j=gz3f<0@n$j~77w^bfv_3I{Z#m-1|$Vj{k z&$Fy*DFw6pfV<9L@&JtmO11v})0dxURGuc4qKlu?m(l0)pC!4hvALa*Y6A5cKffM|@?x5nqla_ei_ndj&iDTBXA zLBGX=tJyK~gyGmiTN6+zc_c|KiJ>M-hUP}&fJ9Y^hhu&*p*%LAk0y3&qP(q;FGW8; zXeS}-`(%+tUxA*5MV6^{XuT!t^hlV-yMk)f2Cw0OXUl-@!=hr>vO4$8 zhfOF>84HPhvy7ZH^EI z#~LrZ*0t+>?5@FM*K@7+1zHdl6(J~hfzJQ)eKV8HBq>sL_pk0to6OAjUEk|{-}QZO zMo%oSU=mY4>5Q3HFqZZe%Vuc`sOt356HCj|5rWSVeWV2}t@nVbv8xFwLNeoV2Jkrf zZ#qkF=1%d5PU(Bv zh%!r=uf$pFnzr2UtXMv4u6_9;`xr;x@#At&UOIMZov+Rrw3(OIxjligOHb)*b9k$q zV{uR5!oFr6CAjF6z7r_Ge0o{Axy0*tnnw&BQDC6E^;!Juz!Vd0V`ONK5PHq`5{ zDJ&W@W=x@_xUjgm05J*z%RE8b(gIJQpOT4|&m?ES?sxfuF0aQ-`P!u{<1}6PdA@8g82EBn=ZyR*S zf)(nya1@@M4D`pA_?@<(*FV?mb&pfzUasY5E-5h&F0$jhil7(;mZG`E!^RFT8e3F+f~9Dz#iGkZiJ6c`8C20>3)-|?Mj(rVV#{31n6X8} z#ts{$&&3coF(0qPRlV%6a*4;(<>9c8t@irsY{79hpU>^G+er5c7keD4M#Z>#a$!8G zEoicZ| zfRk#*DSfr75wjIBQ$T5W4I68-liP?C*CesSvvfZ~YHhU%KZn#3T0AAo zL)V(0O>9c_Ga5k6W+xlWlVeTL*b=YX>o4;@z5fDHoABz^O@^h8k}ic=JW@Qc7vPqiMARel(?l>nf96UI9a@` zS++XoxG7$5(COFX8V`%38n^8Uc@W~`&hXZo>uk%+L0Dw-e zA+CVg;R-A=yXtH;&Y?-=@q7}?`+03?0_L3hX-=EN?eaL2@Zq6}_z>R{a^ZN-^_qE$ z<#wAVx`KAE%X6aH;kVTgL(DEaI^038c^SH(<_YnRP{3U6bvvB?Ukoo))cJVjr}5*E zIsJc<^yDh12g9(RL|9>RHB8ysD|&0Jw)%pJ1;*O0q|gn~cu5Kr13-*D3uA-NBqU;$ z^XI%tq5D5)_DWu&kaqD@uuHJ3T^wjvWT9PxUG3sPyCMti66|Uh2ig@`XqRADyExFU z$U?gWyV}Kpc10H2CD_$24zw$>&@REQc5$Fxk%e{%cD0KG?TRe4OR%e59B5Z$p}nSW+7(%7mta@BIMA-hLc0XJ+Qor(MHbp6*wro$v@5dEF2SyLaiCq1 zg?0&cwTlDoiY&BCu&Z4hXjf#RU4mWh;y}A13+)o@Y8MCE75R|bl^fsA?et&|_Y!Q@ z=DWSe(r$05AAa)bhMrglpC5a1XV(XP^+7yl5Ue~9tf<1~T^^&<6LdN~^>q|L_jE0B z`{}tePg~(yN-?m>fznX0lBd&8n?~kNK7B4gz1T$NXI>U$wake-Gn>RpSUD?TMQj)w zfqOHv;=3H79#+O|%uYF}MPN^nx4Oa^toO~XI+p^vA}M9(W!1=HGIJqO0GT_P8-Mk9 zs^Q6VeX*2y=JZT-2R$l1c~$i;chKeG*&{rM$1W*5V}`PG{v^u7RDhp2zq;!9HJk4q z4;Y1U zXFburs77T9Cyz1gyD9-TX@t@ohuQ4#)>m1*8|aaLrusceu!-*EcoY4Ox$`{1DgEZS zNi$-fiEf8E6?{&>9pv!xrEcq-SoGY**#G49W7{-#*sD5KUQ-^>bc*gNGOmO+o9V1p zvPmd*uGg2c*b2K_ftUO3)-xyv{>iudy}r}10jr$!+vTaz*w={y<^ZRO-eAyM=k|IO zRbebo3n3JA@QxaMj;p3tAJ9Py0B*7PRMXP7DmbudxJt~VU3o1W$iq7EU;Z^db zwv9jLb(rh7c>>s!?DQ<>DSB{tAN=OAxzKwX*LEMSeqLRcE9uim@OWMD3ssP1{=}F= zQndMK{>)E|;JJ2;Jul_YN5!6xq35(6{5gmJ;z!A45Y+_6a+SJ-I}?w)i$kZe!s=>- zxbd6GA(9HYLYyp0?IE1%^dK`oBJon<6F&|Nq>VwlT@JSUS%ReQI^MbMl zZL9--!f6`#9LaxE{O~vy9*`&LJ{(R|5nWU{kKmAO4(Wwoz)V)Vw{?*vjUoz4!ny+Q+X(&Q&54ghEQ| zYRtI&r|D0_X&-81pw>-8_6;C9t$jaz4h_-Ps#lxI1d)wX(W&2ttz{lOH`=WAeN^bS=ud_%B~xm}d} zCr*t8APJl0^$@Rff?gl`6alB+T;{rASCgQ5Roo6I!8<_gwF%LA%@|DOz!IW5jNi`h z75mnigQp>A+Dws{UVTW_u#qRT?$&|_wd6)y|%;5eK+`E?qeFP`0yH_oudlS{T z?tUPMd$KUyYn1yFc^u{5O81UB5A@qaIQtxR4!VC4_kUPiPkNs=6Ze-cb~%^e{$1Sn zch}dsa8FjWd!5sUx|mKp>mPL5YjJPEeV%{r9JIOVC&P5))#&c4boW6hAmXwTuWuO_ ziFvSnh#80Mj5bemE^#}9!Gdy}9c1%6uv50qXY(vWlf!AIRIF>#K5!0JehwL^i+8A7 zlC2WH<5Vs)spso)SUhDM=Dic`C0eYsYvQn~n;3iY_b~Dw$6@_%NB{E@#-3=>(bJRk zMR(|s%V{4<42^w$FhVS5+c&!MhEjR4J@n>DN)0xXR@<>fAA6|LQ?NVD1&K=hqZ8`T z(&2I99A~u?JrWc(A6kYE6~ygvxcK==E{|cSzb=O#nM{`h-70#Gn{IcvvhL>$W%*6r zS=!duS$ek)EN$U!2$5oPo0&5oqXWiHJ9e|8_qazm|26!W8t`ZexOl6;O6JTp+w1*{ zl_=?S$v{7+GwaTdV#lz4XqgLGF&o8BVpfbernA}Ti=DyF#z3W()uC-&!hXkAvP;>O z>>74GyP1XA-Ryq$5PO6@$^OosWB+2Wu{YU!Y#rOczF=F}cD9@CM|UAh>L_)Sj*^a* z21qAJ#nNbLoHSXQDb112kSe7b$s^TEzmqPOu9Q|uH%oU&_e&2;PfO29uSjo6A4waf zuchy$7E_uj&(z&?v}vHJ&@|dK!8F4(*L0St#&n)(x#<$q)uun1?le7UdcyRa={3`P zrVXYord??)twUPRwBynW(nhD1q|HuSkXD`MPrESfinJTj?o4|q?U}Tf(%wnikoIlb zzVyuWZt3Rqg7lNpr=`zJx2K<%eqs7m={Kj}m;OZhi|OyAZ%p5w-kQ-dqff>O8Dld_ zGfvN_$ykzcX~qp1_hdYt@z0F+GQP;zotc^0GjmYpsLW}ZXJnq6d4A?qnSaV`%v_uK zR_3P6U0GRKM`fLmbxPLkEL&DE>(Z>7vL4KeWWAmBMb_Tz4%x?M7iUk&UXbm{z9{>K z><6-+&3-$3bN2q6{G0(fV{>NbIC7TdH00c!^Gr@t&KEiRbGzgY$~`4_Ztl6cD|7#t z`%vybbJyqY=+L1<-wtCsoZ7+FVMT{OcKBHH7!cXjF3rKrp7E_Ge5>heIBSGs)F zHLL5uu9Leux?a-tuC6b1-PA3uTfc54-R#{i?sj*#e|Gz#duI1R-AlWl+x^P!f9d{4 z_w7Bp_88t{evhR+Zt3xl9vgb5^&Hr>(pLLdfnFRpS`~A-M#lo zz3siP=>16VkNcSV9N%Y7pY!|N)#vp-yN*8Q=&48hj=t&W7moh+n4ZU2k2&|4)yF)0 z%-6?uJ9gZ$u47jp8#(qHa}V7eC<{yb>?;EsdG4?b`3orB*Uk~w7bkVQlOG~~_WO~;QozV`TAj&C}_bi&9J zTqpeLgtt!2IC0F0o)hmp@q>cAf(ZqS3;tZNacIw>GlyO@^vR*y3i}r>D7?1trNUOr z2#ectw`E;X*P`h~7Zp8I^nLO1#rEP`ir*d9aoCh$pFN!=1x#8~)*lZX?P@ zTsGqQ5eG+(8tEVT(8#Yx^&eF^>ef*ojP5?VeDqbLUmlY&X5yI8n7@zNH+JOM;MhmT zMo%g@Y0*g!ob=VngHCpyeD}$lPU(A!?UXxC*)YyLu5#S%<2H;xZoF;$o#Q{V_Om*y z_gFVi7&7792@g)#HqkQCKk@O2drHQZTu`!hQre`cldhQb#^kP(=S{wO@~2b!PN|vl z=PBE#j+lD>)V0$xrp=gk?X(X{k1n;B-e0m_Qb+hZc zbElmfK6lTe*^BO7B)d;@H`Zm>Rn|T2>FQbJdC_}}cd7R+-wD1;eH+djd*1cuZTHXc z-xH7mX9b=Lc1LIG_4>i}zpvl8c--P!7Vlj$f61duyDarAeSO*S%PwEGdHIy(YtBzU z-+un{zdP=CD}T4~f(aMgaiMf!)rHT8`h_kDeX(Ndiu+dPu3WV8-xpafT6NLRi%+}w znM;noWW^<$en0j1f4;QSrT$Alxa_3M!hcBrgX<4(Tt4jbn=Ws?!g0l`S6Z&T;mQM7 z*{^!_|BC+akN+oMU48W%4I>+FyC(A*&o%E~JO0}HR&`mmeATAw%C382wR!awt9M?1 z&h@X{F#Lw_jk!10-?-tAGynM1P5p1W=B5KT*WUczEfa5PytU7*m*2YQPmVvmeVg^R zhr&mPuMD@`?z;WMJEq?8#GM20yy33QyB6Q|<=yk|ere6z*s`Ie4$<-VOK7 zx$njMN8Nw_1AQK7__OKH^?&~Q!G#aL`Ikw5dFr8phwff6nvkUO4@QcV9g9#W(&rpY-O_hodvDfzZ@oY7{SQA__`!w`9Up%6k^7_XK3@Fs{&g$XXRN>C zll)I^__WWbcQy}cZrm_(!#_4o+W7is6`!r!WZ$&q^T6i^zPRMej$hue`Pj|(e^va| z-@l&n^_$W ze)mqDI(4U?PTiFxT@EJ$c`fUb4dic6lln4K7b&faB!7b8f3EzZG#*%HDDxOVm_BJt zGNor^W@YE(c90SSF~60j1?Dp;T}m^hn=-O8voq52h9R&^TKaKai!vshYU|ebyp_e7 z-LJjl;fekF_n7ls)v)3Ii{2{98nCKj`^N9=fe}6LeB|PRldhZVnEd=*!I4M2J?}H; z_m5uk!aMbwc1#(x`tIL9cKwU*e!g?f#w1Gh+lt;kcr%>A>K;zTGm4S6Sp{qi^}s{@pF%rx%RqS>1KWt|QOhQhZF^iRXR%>ednNMIE2r;|V?5 z+;aS?iuwTy#~18gF1=T@>#?z~jeL5;w)(5?b)Narqw8kvfAWl$@n3F{*|Zhw|9;u} z_uqf@Bj=jOKmKgthPR))@tdAc22Lq^qN?@EeUZ)Mr?0x@>kWIC-9E2w-O$b*FL-Rs zzk5%Rw*PBklWpj_1Do%O`u{S2V8K%}pLzS}y6Z=7{?hf0r(oA9i_hA5)1wD^pV@N! zmV?Lca1D9(=6O>cpZ9XV`ru#RnZN0;k8OMSahaV|eek)*{;~g@uO59{W>>X@?ppc! zD>q!!t9jm@5x>9wBUj#wQ+_?&_`0o9~=H{p^bAuCgIRmd)fB`OP?|%b&SnVN=?xG*5JseWmf!zxzC9g zthp^Z`NgN-%{q44swF4wJm;xs)4lr|_V!-}GP-@|I)D9U&y{_ScG_Mn+SX;;Bat^+ z#>wpUCl3_fciqF^1Qs+0W*oES$lXs}Hlk_h1y^@&J?B1|*&|afAF^gZ!CCJ6|8|C@ zG;n$Ur{5S~8Vx*q-F2_JW=@~JaP`}NT>awRYrZHNa`~wP28@^AQn_^9^yy~}UxTED zL)HujzJI@G^@_k%!)HHNGI(9XmG%4kzjNldZ2OE}n;*aTz`Ltot(d;C^&SZB!3!S` zEMIb3kBz%J6a>up%Z;Q^7+1^jC|7cye55HP<buuWcTKNQq=~4@ni^$x+VacZA9wkz z&a><5o_X+wPd6^Qve$y6oD0Sty=~EhXD?f__r8{Q%0@2SQ&o5W)#u;&wdKvTqp!D4 z-(7m@!w){(@X&Kl-!S~)t?$lQIP#QdLjCW)ck_kUy*>7_)Bj!FdDfZ_K0R1j+v}~J z4?ezm-C1=9_cWgW)#+m{IO(p>DmOd(eEYyrPprRq?5Y{RuPfa1>@&SvdVTxo&Kp9{ z$!z3hZ$6VXy(Mz#x3g|K^)FB4Z~4ozPwFnYp!0$ctH1nU{9S+fi*sh{v%BsXGQ?le z_2!DM3i(s!%=sJy-aKc{_ctqKzq4~0Ca5K{HBA!~}Khvav6mMV;;DgdUPJ-2k`^eSH7i;(5hL)JjtR1D(l1gtQ- zw0Qbi{a@*Sul(N5jul6pGve-5;k$R0J+SZb{;Lo6bxwM9-*dP*`T_e1oBOY-*jau5 zjc;7u|K6|eer>Y@kJFtyo+%yDa`b>5&*O5`fE};KF7ijpEZlLt!KlEmL``I8Hi0>? zOjm{JXETQ7wR{cGi^V#+^C3ppABbVb+8`#W(BSeGxG!#*R9sfZj>k5h zdgz0U8BQl2fzxuw7F*2Pxx&Z=P3P@W9KYL5S{Z3y-JYi1n@|q_WJ(y4<4(dXrH&S< zZ=4qCcs(s9Ny|ejHpTK*b7ShNlX@lYb-ta#GTx~3(%hq37J<;I!57U|{G+X`03y+S zJS2Xn!PB*ywyur9T8%(0rihO((gVSlQ&0pgT!ohS@(5nHOL${G@hmA#q9!f^-?>v!)gg$4xFg3!Hv8rr#Y}+B}c9%oYqf`J$Kx>>Z3P z=-Zb~a^VzI{{(jp)-{8*IBuQ0)^tt)BX?~r?Z_0V>#&3yTUz6m{SHdO3hJ=rhHIR+ z>FWA05uAn9y#S6bk1e?Jly_1>mR%PZj6U~1BS_5a1wbc&}T3d9VveJYnnKfx9;wG57w-BCMK+1PbK`^%UmRF z8iVt4?CvTzJrh9`?($SGRm1u7BF`eP{@ESyRU4k|ZdwQD8ip%R6R54DGN$3nSKsaR z0pcQkNX~I?X47je=v@MU5&}7HI;426tIkPYHWS_}y!a}AYdX)fda0kfHKN z!jgE(sI)S7ka%&JR8vgtqfxCr(^aEd51Z|?tBz9eSQ-}(sjqQ!FC{Jlx2?v_y{RU6 zYOH6+BTWhfJuxqA_)b?zhLGj7{(aCunwy!CF=r zSy@r*qs}<>pxLZCvsv{)$YL|O51y0zB=P)8{EN-14~WT_M~T0jY8TIAnt!>6w1Ov5 zf9Csxc0KHeQ|sN^wA6ao6ljSt7lNQT>h&^%N>l`wxiyuTQV}Fm!{D1Rg|6kE;M`c4 ze+mz)K<%KgRH`(~U#Fzk3;Ya3 zxnh|ZqvTxTT3ju;B=KsefC=cWaZ~BX^8~RHX=L&2KU8yV_j?!$)x%s$suO-F6-d-4 zt8y+T5zXSsG!juLA%gb(3LQvE0@q>Zw+{c`E;c#+cNqyOq*FO_)iAm|2 zrZqXFq}`CDqSoefmUvZJ`R->Ls_u&hl36oXn$7J%}q3H^e1Af6w(-qW@ z$?Qoq$NMoINzc)bNytOdY=lwW_~CEH1V3J>pz!x+>&JNHjT(h9vueLR&#D4rW_7Ck z6@iE@H}A(}_gAAN>tP0kw6h;G6)lXh(IN=)=|Gto8m%AG_)PWN9BTI2Y(Do6b))sJ zrxh*wO!YfFxNyu3Eqw{%kgvTLUN8KEm{YW7k?sjtf-MAeC0}*k>-#G`DIYX%ns;bo z&%jN7bG)yAxQ(D^EtAYhgHKFaHJAOdwvvNl{V(fT56rvMs=#zkj8w`pg3b&0IleRP z!T9h9@G^%_doDH#11Z~$YYNS(!fK)ViD}lv6)I;9-mHhfl@!j1D?QU#H+2t;`gMpv zbB)Z<8`X7A4xbb4%Plpo=;g+{yYp8NV*I0*6?AJZ0p~c}W`14lk8hWlgtx22`mGpU z^PL!EuiL72Y<6`ZXcQ^>ca$;jrclQ;RsWc}m#N@~*Tp1!*srLIX|u9Uw{xW9wMz$! zX{-+Btg1>dTLeKKu=WXNtG32nrWp=x_*FrDJA4pkocu{W==5%&$ovzl{yJC;K^+V^ z&(K5l@o_kjtA4WU15Vy^)ND~M0OZ48?{_L7-e36dj={7+ zls3N6kmY@sltZ}xzhf|(^}&}o^+RK@^qX$t>x@6^7%UIv^S1Fvj={3f`{hkfjM2)C ziCuC0BdpHUC+Vt$gm%2gL-bb@yS`g@Mv%m-iLC&Bs}6pibTzSazun5yBwkId{=L(A zNa9rqA>1fLcO@zOqQ_YiFwUaApz1h4H_l2Y+<*Dwtht79)>>6*)+!w(Jeh{#2X)s3 z=+w8|zA+a)TLN{Y>uMr88-QESm!7E)8lkhQr`H@5M;Mj8TM*EyGpW z8tlQ{WOgpbBX&T{2=l;!KnYc(Ot2-oG%k!r%!otRMYwbE9BYsR@eR|yw1Z`;-{o*% zaY=2h3^0nM?ptEB{aDgbn_ar6FzO1@m8M3uun8U|Y=WnP`s%6nl&LU;l0A#>Yeg@U zp0!VGUn}5|T@PtsM!V{iw%8N2p8qDZsv)%dE(XWW9re?J@9G1E6TM3fy;^+$;wIr@ zwcfZw%S4aM_|JHUjRzTUS$2n6i*LZC;5e%a&*7Wa46`GcJDlvnTY%{W&9HNa&L=H?Ip5bP`Q`f^rdmPEY z3fliP(TP`UI}KS7ctSN+i1g42*e*J4nGgHIF{ft^`s9K<($(YECw(_DrXzCRnQ~xOqg8!r8*oz;wKl)K=wonu{PFrK8$7 z-3Zs~jJ}>|dNkBR%%e{s_87aCqePp#!fqq3#>=Gr#Hjem0XXBpzKHZJhBFm7!|C@B zP+y=1i$$D>UGDUf+KO6NwZUo-)g?AxAf6{dwCHi@JlGpQuYL_ zK{H)7HX6bO446%dgN?OCMR1bKk8>vAaKZJAvubXjzRqZ-XuXllFm2r?;~qCLGf@-k z@pfQy(Qu8^v%C}W*7-$7> zVLSzSy^CCGtE{37XnCzS=nd3*eV~&*v5*w_Av#6~6ZsJ!y1wD?;bGlsb#KR0y5>dMi;1}&8|LlKNxGqi+Jk}bAs4N}x-m9L&yS=gVKn>Fh4q%xmD7}zGn`HzPuRmeK!IpoLzO-hcp?RG zCbySy6&U?jv!I6LAsF{VOw+PBB%Mm6_K`#yR9NOc*EIu2X(T8J)-};pvAGYSC?j!< znHMt|E;a*-Qip2=<|KlwD3NDBA+O?}F|T1iV_w5!d2uGrt#!^Ke_D6EZ_ABiVJsjv z(vA;}6NaG)0*Enw4x0*BQ8O#RcNQ4#=hHuKLZHn-cfyccwU-IwRHbjw<|q{%qvSCv z<}wmTsD-JI#dp+(987dlKy!>z)UgDu`Yq5gin!=^IbIM6~-sfSsG zu|bwfWAX?K7C=9~QYCC0Tg5xh)Q{13o_RM!>zWY7hQZWN$}D*ZrRJY7fZ_!3$u^x) zNg6vDM@}Gv3@CL*+ZZ$zwlQQXG!B>wlZQ(Qb&$_hw9);ViI&rjmeYZ5)>N2wWi`O5 z7$N#z$mo~J;`gw1coQ5b)_+^;X16@;kL}E=ts-w{)>LJ z=tpA}E4ebXHC7P)=y(@L^rPc*B!+IGwxXl;3PnFUc|pU#uy_Yon;}JyP3i8mwUiSgZx>sJH@4pRRc^a+O71|wMTEXxV z3plmGEAMv2D{s(0DOCENd*yx4z4E?K@XEW2V&HSwUU}KmFgr$597sfYsh)Y|?eNS~ zJ@jyT?csRljR!?uOr~n@)UaW+>c;a#K!O;JdwIx-fH?SwyasoQ?;fS0aPr}!{Xu4o zfXT;?UiUEpJIsB^hho?e>f-UpbFUhAZsbMh(+iJ1i0B7B_IfuUmhw3)kG=CJzpKSR zT#r2o36eba`sKFYWAFc`E(uRQ+wYJlJo#uw)VOW}zz?mQAd2wh`%(U> zeDXZmlW(NzBPl%j;)^LzGU3U`4IDVp*1{6i#N?$VKvOO*0j@1$#g~_2j%LOMCSGXj zB_=BLKkLbtyxtUdis8&KtT`F{gW^jje6`2mAb99(lUJWO4`_WWVf_hk9{IQ7z?aJS z2nRkmuL=h~&HM-lzC~d4&TXTFRf`3@9A3+L_b>eqiNPV`Sby? z5k~VP6dPfbT|s;M05X(ZOHY*xF8Sb8v8v_Kp zu3zvYxIU^Yq#<4T1Uy!yt7_q~DqX&YsEwZ^Dg9VoAAU%#5C1`~cm8#7ebo2I0z4kDL=(m zxbKThvSxl#STlE7FE!WLMT1)}T^8#0dD&>|!fQXftmp;HVfqSpOz;Y(mvzz+41~ac z_T)`|E;Bz12uJX6-}!c)!MWDn?`4e*dN10wV;+A>gX_<|9Bp09#lj0 zj=SwTgL7@wrqsBQkGcBM;}Y3-^ac&C$3=tTnsf#ylq}h!_t^K_@6l`Y1CL8wc-#JG zy=`NjXKgKL(rj>wB~5^nPbHzabU>y!H&Z=ZllE3>Uu7{AEYhEWsO_=@IQhI10JX!B z3@(`|&n!XY6sMK|dWdsNVh(+LxQMv_y>l~*{ujM%hiN-PiPeXDFs1RJki+(~96H>r z{A+rr%2+!!M0r$xd6Z<2=u|QiPKoVyN~Ci(e_5vrDn2Z~+*1Wr{J=JTn#|UCj5n#3W_2Do*Wn-dp{-QWWP-|v>iszs>Mi3`6iDLvkn!}qo zMvyl89iltVJ7fHZuiV7X0c`91t3#?+Jh?bVFm`&oSUuHzbLpxK4U{oJ@|LdHo?iWS zuERZ(FnJ>v`E@35_a1ha5ok8c4EJE)}|#i0)4<1;UZbL5}! zNQBuG9*N>;ZuLBKv9pI>Bc)j9pVB`U9*M#uQFtV(_2}?Ueiwae8p4oEnK+tT_tGQL zr;fkN=%*dcE&9~jTk}$l43ues_;K9-)nmGUgWid%w~*pFN4_z6ZF!z>uOro$3omSP z@aJVN2hz~HPdm`_FW!T0u+QLCWW8w7{Z~8A-MRLRrW=m>>*SH3!}v*;WdO*(Agdq|aNAiyp4`8q&k{xJ2U8O!69{*Pthz19yka(+Z{FRN=JO5312mKGeRJSeXAcO0d@!d%@7Bjp?NShYo$FAw8?Ge*(3fs@& z9h591;T$BKgJLfz{ZGAeH0IJHoP+2s>20kIC%+EH=;I>ZF)H3M+Q!Rh+d9HPykoT1 ziC4;z0TS;Rb^7BkQ6gXF*!x6vuLF$1#5+aVx`vDR%D&Or%N z?ZP=oI0w=3bnzpG%kTz6Keh+ZIauYm^J2rm9Bdn?!R7%sp#DQ`8{nfo;T+_xuhMxQ z{Ab@intY}fPEg?e*n2s-|CgGZ2#qw1}cjdO+`!q)@mpW(_mL)j%1XsYJt z3{{gykf~bp2zrzqkFYGH;-A5ckq^-ie^rm5VVtYgOX1m*jUG(<_$XL_5M)4F$qb0s*0{?O5wEcOAv(qoR$|O1C4$}!6q$cw z2L{|+PJxs$!4@1r=v8h_@o~!YO z?kP=0^~9NU#dC!gHgR$V7j(IMGB+^wHSU_261irS_&8jn-=T1JI z$jV|f`DS)HXVFh787uKGHqUp@r2I_AJWBlKL4r~&dINL9`DyoAXjU|MP`pK>jIB^u0Vs1z@goX|UcO196*y8V@UV z6_P1uNY;5O=$^7c{ii4ns0N;f;cH^K6oAiCe6@QHpqO>_ZZnf2{5b}6{j}uX8aI_r z)-hf>45KVR`ws=b0M%3!s)xChR44pUDv+p8R^?nwN<51vBNE93s%)TQVnp&(+{+UY zlu!DwVLUqJXAGfK0dF-K&A#}?yg(T%97=z{0buRk;9J`r0mf4)AqL9N-F6GwiNb&J zKDEbhHMF4C#b0j#t<37)H4mTpV0#CAAHvrQmZ>dh#vK&Lw160mU(`O+0-`qVQ`>=B zJ^BnjoYs@#^eh@)Tr_Iru%c0;&#CtM@uGD{!HA+_h0BVEvjzF}#Cf2@aSmS*8-=-_ zVf;Fpox|Uk?Pp84&2XSUIszfe372hqJs^u`w~Z+t zJ#yr*kp<2oi>;ujXw;~JF*b*#!0xPe6pb7)e6(Z4Xhc-24kLk>tjjmx0`YpS%5~-K z$~EzsDjhzt`0BF)<#|!Q=zTy=)FS54m+tv;kJ<*r0SL{d(31K94hhuaa*r;(bw)sE zidOFQ2YgO@(6!i^5d8CWlv5pw$mZCC9w5N`Q*p=PrMxu-oPTCItJUt45gvCOMuWIQ zjf_j&(bxdbte@?t7YBJgHHbtdW-d;IbhUF{P4+Byy1hQ*R!WvH)IyD_OEpxEq6K2cQMaj__*S7a{HlSi8}< zAAw)`Wcu7VpwN+!_bB8)3h|47Qr@h*W>%f5lw6U5-XJu^R^trlpgGlkTb;8a=rro1 zMm{N2j;FrP2~G2ADo&Vpa5z2QI+rI7Hk}S|wxeFrNrQI(*xYhCawXn+Pf&+4o8XB( zbLA%2QZ<}c0CY~P)edGhSscyo@q5)a^81yy6DjPFaMe~Ov#grsY)AMn&59FI70b;Da~>0k);UTC78>9_`0I`ytoRcg z5F8L3_}}3`cd~uyFRb74S@WfztknJ8_DOp4XIs|4kiKD`+plD|LT2%WS8#rS)PRXr+9MEVXWtHXTTU9@r$U-<0<9JZizqCjrVDfx`XKZ{ z=!0k>g(c8xfv||eB5JxoSD_C=AA~-L7E)LOtriH2C@i9;3v?CwAoM}#gJ>azCD3ZY zuhSy7XWv)qont9?nWfr~cBuVphuZgsUBUU{PjEnRKycuHlLIUF>i=#sJgwX-p7q=j z{1Eye^g+)7p$~d)2>T%PLFj{?141A4+z|Fb=!4J)JqLt7=(!>6gU|<|4|)y=eb945 z*ax8xLLc-T5c;6!hOiGpAA~;WIUw{w&kbQ8ggyv;&~rfOgPt40J_vmf`k?24&<8y? zgnbbDAoM}c0ih3iZV3DE>(d9}0sX(}_bI3r91t8J4u}>^&w*cG3#P|j^gx9Cgg)pw zAoM}c4PhUIJ_vo#b3o{Wo*TkG2z?OxpyzT%PLFj{? z141A4+z|Fb=!4J)JqLt7=(!>6gU|<|4|)y=eb945*ax8xLLc-T5c;6!hOiGpAA~;W zIUw{w&kbQ8lJ!A&Knp)m!2!X6|6LA<7DCT~8^S&aeGvMf=YY@$JvW4X5c(kW zLC*o94|;A0`yli|=!2dELLc&wUb?>{S*pLDtS5)luklME`oA75@vkcre}V(4IgqF;Jq)^}=vAV|k$zH0 zDm^_?r^&sb*#n{BomR5=-}CH4mffSobIo60UcYU}qw>nw-!3_O$F}t^|MePANskZM zdY0CI(LEa^F|0i8YvuxUb zefQ1m8)lO1(OYyOpU9@DL;9L+VUjs=lP+MLEJe)Uuy2{P@Vh_i;2+DBv{F*TFxKrB{#I#EJ_1e^+ zgTEz9oBHfzyP1^v^3^){o3iwB<}Se5E&rzjH_7bQU2G3y3$M~a-;mkD-E1#-_MH(d zeP`ao_AyC%_DWs!e}k9OUci~-3LW@$nK}2e7AAGuY6MH$y6pp;t-f3r`!$(ezmM%_ z(!l*ju(W?*3*c;RJn9W;WagM;@2&ThU;7yA{N-MpV2WK#FtMzFNI z`vJh2|59D-mt_{<&<_%z9~@w zX8l?Tx+np&+S|DnHs0E@Hh*}_O!LPLzq?{0IW9lsBBwNbqxReujiBo*n(sW$P z$-qeob98*#FmZzM2uAako08`u0Zlz`nK;Mk=Che8=0h=~x;|mU)fn(KJV$az=Yl3(bFD zZ=C36H_)uO)NNbBY88Q4M)pCV$3|LL8-8Wdy4sb)KUG)bHa(zAgw?pu`Dz^2 z^LkG5UHix@pKRNiu%5Sb+b6F)a;) zB;p*-U+X!X;*B$k?yi)D1jTv6!j6erAZmfA1)>&+S|DnHs0E@Hh*}_Ofv5$d7W{A3 z0`Ybd@pcl-@Z#;<;_W1OKf8E4iP8Y9lz#zlCrM{HtOLtq9r<4;_1Y2piIi_DIKlGq zrBr#bzg*;_C$|;AXuVi1dC-9b?k#F#u zw1WM=OM8>wrWeTai{`iZJu7IHrSBHLtv(!(rF-+=RUh`t(#G-csSho(>ELAofIXt1NvxXOsG{MV4;O`$B#AMwZr%{8D}RS~h{cuhgf_vh2=6Ri8Exf!o!GW+L!A_2CmDa0ebF*7d1swsJkuxRXB@ zT+2z^tvoakg?p6yt2u%Dl!vQ`z82;FN+NH+a(_8dcTl0f46{7fkt4b4pfNY5*eh<+SMf`rBLJ+@)T!|Qdzegp8KR~QR z48Py062l+9SBT;FkSP(v@1qJa{2l@&V)*@5g_xv!eH?vSeV+QV3`pp)GoY=fM^C4o zem!3d4AXNm#$X-W!^Yk)yD^g5$gCZnc3!B{~|4e7z4pa#`7YPCV( z4OPKVNetD;ShEb3&QKi<71dCMjkViQ@r^dYU@i=X#9(3!#>Z%v3?|E9%yec>Z~t^= zQ8krhH=(NOzsw6M9bHfmE!xW;Q`k~F=i8E zwgO}C*3j`abcth~Wie)>(V~7Fr5|7E$6fmIm>9ERxGKhM7#PuD^OrkjD`s~5)vyqA zFuSR%^n&RmQ%C7_>3Mt~litGbTKv6f%92{8Ch6~NAS+58!KmRSTv5Gsc#g2;#$ zL6LPu(BpkfVwJ5jGw)+*VMNxIk!F?U=)MSR_*sgPIZq=kpiGtmk$tK>wi}Wj9wYH4c`L}Y?q_LDax|Zp9|66_@;{=2 z37>euz*b+dE=`g?v~m_ULzc+GcP){qi>{LRQ;SG9N0B*-!nJ8H%Q81KK}?O6kY7V2 zV%g7HBj2+Qm61p#%MT%_(b~!~&EcpV4Vzn7c7A1Jvn)4<%@AsNBof-kGV*a@cm;e$ zLj+kjwML-VtOG~@l;>dK#UNQzD8B{y%Phmv2z?BF7n2&5*TS;$eJBx`0~rRyTIJkG zgPF0)2$hM9D|fJLvyT@O%HPjASR#=I#>ykex_mF|KxhJChG*+86cRyhQ6z%~w#u%SlB=vX3zzW;vV8AP)(k z?qtF;s9;O;emTv`Dx;Vbi<%EGsXW?3cdd+>Q8Q3phEJBuNfTIPAF4{Lk}kh#KOR~r zKIYb%AU1H5RRRb_qsmORmI}bMuLW_XsHFvpvrkSV{Xs^doyxUoKg*!#ER3`v#HnnN z(_sTh*362C5fZbSHR5ulqf}`zahx9pS>b%rd#DJgBPQ)%}1L#xgH7=}jpR7r<71C@1398*V zz%qy+VsaW}(f~?9HfKWEluFP-8laeC1TiYshbWD(ZmBp0v9o5mdH10i z#pM85f%-@}C;EFBk0>xH2SUI?(-6dgagIV9l?~9*bWjjtzy`=yqRPGKk|A*`LaD{zg(@1; z)MBLys8UJ+WPCwm2sI12%PhQG3B_WRk771(gfkHaQBy5%MjBp{Y^B;5h6JgOAp&oW zbww(AC`HM@R)TeQl(6%sL+*G zc_+RKt5wx8>x9pvhZS~#zO+iHES{`fUa;0&5x~R94q(1VUkAugLz^J%W=JqBOLFrr zh1#zbIf7`=iWUXgLQo-GkWm;&6Sg{G#|u$pjfR60hRzNZ(hNZ(A?$xfSVq5u3`2w5 ztoG&+2-!9vuoB%QIjWRm-kn5rOtuD+K`UW%kmzVamdL9arH8oC_yrl_saz8*Z(YLZ zqAF41Y*q-hf>mGxT@;=}Ec^-CfEJZuBui$c8jr3&1d6&%EFu*qY?Q`;N(du0AU=Yq zazs3^f)E8G3|&yF+msxkjXW2ki8O$fD~xMlA%^gm>!UQiBe1lG1Q^ZxDf_7 zl7$#6Ly6dk7#7eAO>IJ@Y-NNCgcOx4xscFwg;fbEM5Fl3Ms6q(*%T&a;%cjq%Rnw` zgw7CsihML`QJzY4GZ?j1QDG%YD26nzSWt@e5a{JmnxdKrDS0I^n3@?bD^-9%3?z^` zfCCXc>6o>Tp@S1f8tMz15et_}$V(wcCqb3F9I}VCS~*cjK#Gd|$`fR$MMo&e3GWY4 z{8m|2BDK<}4L0J0f!O{~HlkV?1G18AQN{Ny+5$ABiXK`iT1JE4sx62<^#t1sKr0Xb{eGp`o)h zAH+BfsndZN3^^*?HU&vl`U+z?^TA)00gx5Z5tAIT3&V*YAu}2>pj7mXQLFZ2lnE?2 z-Jv!G*DCLU1lq2D;6~HlNQT8Iz3pH{tDM;sqHgccAwkFum^RBkRYFa2cn6d6BPgUX zME!D5(4`rjCKjfMD3#>hoIo%Qm^i_b95TwtSP3z9u|^=OsKsD#Q3jU;M3Wz)o_$#9 z`*KN!+ms~fMVuLl(jUv`btye`<|9sE7(OHFHtr;|@bH>Pa-B734gII3Yv}M2?yZv6bTv zt-hYzER9@AHXllw`%v-1)RV(p32|Giy{a_#L7J7#Xvom*OAkSl$fU}?Hccv!K&%)u zlH^GYjB2t(gGc6yvPDEH9NLgiQx>WwaTry51XD_?Ync8B0|RiSaerF|mC{unN{%Qp zypxd>(R1U4p(_r;sIzQMQ7Ne*us{Qm?;$NKrBw~^L6+Ho*ghI`Qq?N=p(6(#LwA~0 z=0c3+#8Lz>GQJJCgSP5O%?vA~vPR%Xg{QQwdl(G?X#ku?@zpqLA-j16WBH0?La=C% zW@W608e_5ACZc#9A5?azbq`M=Fis~w-g{H{LWmQF5Mg6#5mGJW@*@@?Bh1wqI;imm zk-9$Ujkal6(~(0I^-pSq1jDKXp*6&Qwf?D>Si{Jf3X7EA`~xD)N7iVAsQQ3sndRVX zliWaKXMRV$OyC}hiICt;4Sa~vL^n~TK_EgiEefHm{7}-vSQv#wAUvPa1!;_D57L@| zuO>TXvYv8NQHUT=*DM-M&_Q0AXvT$)h$F}a2u0C%QsoKmLorc}h;gKp$j*mU;e#ow zAa!SzJTa#Pw4&7cRV1kCoZ3>LB;sEsjY(9!Qu`yIGLAYVr_2XfmHB{1MTCS2aU@BE z;19wujRs8AY8a(e0ksHKB&dI3&;cMy3eymjYbiz-kPnbj1Qbs`mNG_(B5XtWt@{+{Fl3B(FjnY#}Y zUxXT0JLBdvO=!3dJxrfRxf?n)ci2S-CT~YofRE%Q)51GOzu;G@Jg&x zH00+aFTOMilp6Q3-3)6z(0~M?WBtM!q4k}{wndIO<}j9(A~1jwEq_Q+R0WtUWEX;M z3?G!!qCT41GRhbPQIVO^N=AGDAM+cLB$6y;=%j_Ph|pS>8F-@;fnOh%YVuJ^TCy&;JRc6f4z({16%R?cb1;#zU64zGN3I?TN zW(AgxtUqjYE8$@Fg(}V9YrZc8?N4g}Blj_^uH+**w?Vojds&7B{s)y7m{X)xOJe!E ztbE~w$V3!gFfzf~E6;?cRp9L4Gh;Yn35CkZu$e<4pu{skK2*d$mWvY0(WNEiU_~uH z#DOTag1{JxM@zhf15L(Kzm{TST!FNxRB)=`D+3CBYQ701rW1*5TWShXh>|wLisH-j zw_>G>3WL_5Y!wAG{t9!c4FQ;uF=z!3(C<>CDVfA@2cMBmjB?c9NGA#ecOi{Uc zFS}K#-rvBBua3w(pIb043Eo9+BU$O?U5vsKZX+I_b& zto>abyIUC+_X<~jK0XL3{oEYY^!De}Rw1QdiIlps@oXu(kX^#=V$0cb(>Q61>0;9u z_!oX7?U%Mmd!${`XVNxPZ_`<(IVL7;WhXETd=5{0 zbWd94Cl%97R`+6bz%bnrxtNhdOv3?~ZY*b!iB?BnAG2tPSvT=Ex$@a~P8a~0TS8JL zTIMt~xaK#N7@ryoz=B%n8ulc98MX#1MG-1!j^9$!twq5YAD~~BR4%%AD3{PSmTSdU zy(Vh+2~CtsF_O!buVGIyJ}PX`l^jAFhLS1eT696Ok+unqo3%W#^p*$>;G!)NR+$P3 zDm2;}0l#RdcNmC-(V>jCjR^IuD!)qLJQ{wYZJol}kJ0^#$kwm*GT`ADqgFNp9UwxI zKtG2(8$Z+w)|jZyV*aUQ0rG60bOwZJ_v9B{Uf~ z^nJ{r+={*rk@7HCkLN*xI-&VFYg9rAk4zfSB9?~9JBat#k1bi%kHab$-TEj-YRvqO z%7eoxc_)jx31T9Loai*ayZkWn3+L}c1X`$Q3Zw6-^MpL8^ADt%2eodh6;8n$QdE5S zSlnZg*8j)>l3W8ZVO`1drdzFW^8Lfe5PI8aiDIOU;-MB{Gs=J^h(LsuO|*jFmJ=W* zuOpZikDzSQXr|JE70pV@sL^_WGzW9h+1x)e8u4M6pz{`0Ttrm_FvifM9^(~;8I5qF z#CVUT`S?vDCE$SK#i;Yigj*E!C(NK87(@^)nKXEB4g&+l<&%4+Her@2W@RW7IIP8Z zc0kAX12Iy$(zpad1BaP7>4SqN2W$O20CGkr%4qsv}wZN*MKT8rqo~zU1)NGVUU`Q zBoIo8!j+Y7_3?8OBQ5$>=WAe_6U{D6SxxXd2kW&t#D&as8MjbWySL!`6Q_3IJ z6DTRQmgzkoY2qSN^`|_@@@SzVf+8BA#y(Yx4kWm5Zf7uDU>iAbh7WMHfB@iWi8(kp zgT5)_k5x>EtP_z zm|~GOz>H$939=@BA~NPZK@Bai^A$qq19!lqs|6)P@eO8*f)(Bw`L4Dv=;kHRk;np) z-Bzu?gh{1Jy~sg6;-kzofFlr$6@tN)9yP`(ECU(4wPp${am}!|AQNRb$JBwdXg4KhM0e(d?9ZQ4GL5x7e>wyft8em_m7oj z8t}OZ>o2N85qdNhpmd66B;bZ{v_h9>Zt`leB@L&0AG|#*~1dI;U~5E--JB>Hq<6V69% z2Pl>7vBRRdGD-B%JRj1arZgZdAJs8tAkso85ZF8IoA2*P4Vj zk|3WD*oaFbWDcxIm6`!0+^KOL z#^b4EqnD-ep9(-Z%}_XCNNE(lg9KpEMDeE``!jK2>W4vRUhNlFi4Kfcw=7>UV49bIE z@&Rs>A_OZ)M7szzN{~9N0%ywh7%$aYu1F3H(D02QC!-j)>qM_Z9JEnfWKbSwRE#qe z7E;OAi#`M}3ZqN1=+PEeVjWGQy?#7%xNoU`sNDDyc`6gpZOw0l%AqyqF>#?#2p_tl zHV|QmnIw7^+9jLfLI))g2wlmFUsS499s7Umz1gqq*>&Hy&+RKB zHj3ladNjT zk2>^MP91YD^z3@Ki!@K@$@%y@S+G>?Tv@-5wsJ1Qr1=d=d52l9=W2w=e0wj!n^wRQB_K& z?;f~$v(G_#L9O{XPdV#1!%GLH&aTlYc$Ou+~3*$?%4|o(GkRE}mGer=0M!Z0^un`s5LN_m$lpfP0Jbl+%6w z$ ztOMqiyZYog*EfId?t|~!mM7-WKMiN|wrWTHGC*->-v)>2sDbqsc3N$b-}uAZo;dA_ zC|*Xi)!Spci|~Qs{s`)a{cP>XfTj;}+Q4pkpbsj7aGWo|n@1&1Fb>LZ^NLB*F52?h z10{0_!zsd~DX09Ppl& ztd<}*|K{gj6Jox~0Q5bwvCnt??bS9P=J};BFsu9g%t~@twwDrsP1yy-a*l z-wpN>gzrDEy;NI*p*R+N96Nz$Y0NDD3U9myEi8wvGH8qcR&(%^l`crHL57NU(J!Z>nhcbdI8*xazoNzm=+h zx|M=Fd7(ua@4=f@fFSb#B{;ZRSFwmvF@m^A?I6z`F{!$IMOsw`;gOT)w45r%2T-E- z@e7;_T1h99!GCXIZLxw1qsPYLH?-B#_RVK&d_$F)c?0gkd9BhzVE*g_fVQ5~iM(w8 zg)r6N9@~-mKt+m$vx3B1Xh*IvhJ$}o9n8C0$rYYJuo-&o87 zzD*YotpcL{TMk|y7X!VfbP1;OS$bSxGBxBDnDnQ0R*J)T=@CsvcQz6FB%!Ex&c$ITC7PNdc7 z@dC~2e^tlr$hgwi%#l3%))OP8K2L?rQvtHnsV9S1+Xo->&B_%KMSvrID}|uiEtK?U zawPR%WzDy}1@eQ_Egc}OhwXin7u`={oaBss#_Z#BUvNL_%IDwh?!8S{8-3B;X;A*Wnxdb_*gpL`Crd5}_!1;jlk%VF zvvB#FpZ3`o`Pi{R`E%-__QZY)Dla-N=zB{+N11QC`|M!=wSO-q_cIbPZFln{JgD*Z--k+fb22U7 zQG4sf^26mxF+J&JPrRG;PA=mo-if+^Xat z7YAAdxd?J`;065*{1Esd@I&yRgC;mgLC}anBOZ7`KLbAmehB;!EM(9G2Pp^|F=)gC zFX(6BhrkbkAA*Gpn&2P>K_do@c;E&74EzxIA@D=6kUeg=LB{P3;B58uq(*V8A* zo;qdrw0X3@XnyT4ntNj^_}TC;P#{nsP~h8>0(FD(V);SbjQYRudz~7AK7k(sKh!A@ z_@PdXpdSK11b(PfAn-$-8bLncNEp-zFo4|Qq;{Sf#e@I##f zfgkGB2>K!LL*R!x1p+_RsS)%;;D^8ubqWN2s8b{8hrkbkAL0>OgSDe$dl!Rput4J$k4P^U)F4}l*7Kh!A@_@PdXpdSK11b(PfAn-$-8bLn< zehBcNEp-zFo4|Qq;{Sf#e@I##ffgkGB2>K!LL*R!x1p+_RsS)(U zll%}mphF*Mpg^F&w=V^Pg{V{DNefZ`Yp|e!K7k+V6bSrKr$*2Zfgb`t)F}}7p-zpU z9|AuFeyCF*@I##%K|ch32>ei|K;VZuHG+N!{1Et|PJzG=b!r6t5cnbRL!APFAL`Ty z`XTT`;DJ$k4P^U)F58rzHKnL`9@$Wm` zUkm>N1p);E1-^|a@SW0q_djz!Q2PrMsneuH-#$rGPV8Ykgh=o{z& z#|1igQ4Dklbf_!kzz=~R0zU*#Ay~+R6axvk3;G%OA@D=s zhhQOtCOAkz(1<}J9(X}N13v_Q2>cK%WY7c$DF_-dXv70A=x5-Ezz=~Rf`ts4;2;Ix zni}z&nfrSBK!LL*R!x1p+_RsS)%;;D^8ubqWN2s8b{8hrkbkAL3FjC1p-zFo z4|Qq;{Sf#e@I##ffgkGB2>K!LL*R!x1p+_RsS)%;;D^8ubqWN2s8b{8hrkbkALJ)g=Le&2nENGxl;DJ$k4P^U)F4}l*7Kh!A@_@PdXpdSK11b(PfAn-$-8bLncNEp-zFo4|Qq;{Sf#e@I##ffgkGB2>K!LL*R!x1p+_RsS)(Uw;n&x z0sUR>JHx*~fk1&kfp0?!eAoR~d-Hz(UA-4;|6b~q{d@D?t8Vxs<%_j{A1d9@ZJ&5= z>t;{9H*=#W-W$2z6Yuq0_lftqPyO7}z8l`_1zNd4gEG(n-4ysB(4Y)_@M53=K1<+( zKm+-%fe!)=0w4G&F33WVg&+$-7CZ%lECg8yvJhn9K!KnSf<6fP;2;gbR}T6h=!2jS zf<8DKxCgM&1ffAH@+`|z|`il@z7JZ(1PDKi{@;mpU0`+M$hy1(xJF0cRE{Vn(3y0^Oj zfp`9v`v>m7A7O`Pbd|yXX1D_qw;c|JD6{KJ)k8cf0?Izy1L4zm3=Py#Ei~|K|P={{L<6d)z;A z@8J92&!_$Y-}-xe?g#kqx4VDJyLx>u-+kWwu=~Gw|DC{kyTSWjR{1;p?YsHy`@rM> z_s{tG z{k;2w;PgZM*V_%=``k}}*$?o}JKek8|H8Ze|G$U7z7x#f>;4sR-ouLTazDd+KgG{~ z!pi@|{h0gLeDeq02Y~f%;J(xSOZS5NN%ynt;e)LA3-05wLnX{w&}5 zX;%1gKL5|%OYXP%?z?&K9end6?la)~KHmL7pnV+Ly&EV$ zi~RNyzkkgA9yorK*Js>U`2FMVclpeR`OZtc`@=x`GCzNt)jrFA{et_n`yC*^k9B|D zJ>cD+b6;fTUv|IfevMV%=|1KDfbah{xcmfbeboJ1_c^ft6|j2X{*XO?9Qgk)YrN0B z!qm{uyWiw9Kj!|-{SrSv;eLa6UjefZ@ts%r?vJ`px*hL-0?3ctp9AUF`Tj4k=10Ki zYvA}v;Qtbsf6D#7`vTwm9sd5yto0MD*#^olyKDaT3cLFx|Nm)s&VE0{Z@=!o3jB}q z=?nh^qg_ovY6b-wilJ}Y=bu>G{VWQ|XQf8Skk2A6Ker@z2{KgC~voWK1xyZ9qM z@%!$NS@~1^_s@gRud>n&JNPnCKfzyr!M^o**D?Hli*LQgUq0@>#J^t!_8+^?^Qrf; z@~6S&cX@T)5-h)Be}9SZ{}$iS&o)&0BJY0MJ>;Bz&ox==6`+604Z!={W&G{yQ0TY$ z?T3MI4&D3iPx$_y@%ewtXFtnIU*r>A_~(-+j^AEowcm3K=<+rG|5HHyBfjwn%-e3n ze~G@Y@cs9*_9^&!o_HND`vmlTg|q#A-u)e9>NTU^A4Aj6K)*k5EqBIuUg2+_CX+f`FW9PrY`ai+nexLLFRsR3idFedA29JJ`pFanzf5BfqjWqo% z-_xmm0IGc)n*0;KL7K49|o!P}Yc&9YqVmg%Bg_7>%QyC~+n z#bBP#a$YC1d2g0aceCl#O*XvpX*?;Xt4SV}lbF{i%Ex&WjT@tKn2++|ziZiSRy*+W~QfIKneiH+Fx6=Fz{vI*hQ zGIHG5H_O@S^a9xWX2M}-QGZ-O*wJV_bb|xq{4}IkFZau{MFKfXpf`;eYt|^)L!UkD zSSO1d$DKwg>^I_o%5iRFy}MSi*h5yg*e)+w3qI#n@VWr6Vtzdv%!bo~_1cqRwU$5Z za+Gq|qa$73$0|j2NRpPvi*>b1IbY4@V3u;&Vx8t>z)B@-14hvttajrG!cmTf$JO4m zOcst)bIW`gb9Q}jOAW7Let$8aFJOS#Y&lCgw*mW&r&p6AiYJYzjFPcqzp3q2A~%6{ zw_^A1<(AzR%dc^EZt>cD$|@PFTuv9&3NC7l+u&1-`bT_zQo_ZzPWe{3czvGCO8aJs zP+S8)pQiB5m=&_g4!V!n+a>gIz}L=3;85IIt+3TZX{~rM@5~m^sARQbQcSZ+3J0F$>aaEx zKCb;?Q~1k88@7v0YnAf`YxQjRO?JKGfV4(?bZ(~-AHVyNylJ1pSQX0%|90df?N zA_Q_fTpls|82p}?((&u;SgTkxSSy{kjX(Wb16!-$FkWW0*udf@uE z;`D1Az;-!UEZJzxMq`#6a-b5+1k{EVYVBw;Mo*)&B1F=GVm6u@Q(X;8*30?_?f=FV z_mF>JE9MALG96D(P4jng6tEzyI3Dd-F@n7vM^X0EL0(%;2P=KpSzH;TOYe)(rHhuV zc814Dr}JroFf}I=lmku{3L+ZcAF<7m zr(eqIGdqhRyUp%Ek!A8wa?`sKvlKfZTd*|IC{df26{M@_y~z~Ko=>MH?o*)cpsR;A zLQHUZpu`N?mct>C?n2Yqi`nrL44U>OZ68&TVjv~eo-*u*ha#71kL52%V;rdh+ppCJ zte)T5OU7QLQd_L9efZU#sXz9F(!QLWld%)q@cH7ivh&KW>E+%n+pv1F)(>U9Oo-K1}4 zCS|h(W@?V!0dfRXcFHbyZ-Dv?@&k*?#_8}b7aPpK^iC6fk!KS5|&HRLk`xL)er#_bH}!9BAdntRe_i~tmk^VNAGIwz1hzkk2hoO z?P!F)ok6B@usp8(364ZI1JS~189)}1W{cpbSkTe*9*3}nfu+T}QIA!IqxNvlDn)IT zFMwOZOLnaUN3Detf#3sk_vD_HXu5&nD7`tFIz&S@KE-`qz^p04r-;FE#JkZNhRqON zZ<}){l0)oUyl){kz&`=n1&}hJC?Y8;NU1q;G3?qt!jaWi1mI!h=I&&+elb`a>GFA$ zp)9{xsIWK#;h48=eIFC#u{3ZEIyBjuBRI0~LH>neBa}NVKL&ePpBJt!p@ep!vlws|L~)$Q zYE)EqJB3~-4pa9tGau7_euVrQds|h|wKutp<@^*%DQJ6H6g))?qW5vF$*fnZIHEL+J z6l&-UVqRKJeurMY>1HxFp6sv+(gn>|re+4CxKg7dq%0dmoNQ^Y!})%Oou|0>_b~sv zxje|2^DT+(533J|d9Nn-qDciov3L%IYbdKwC;@_$=g_3;NeF+syfLod&HMN}sjWU> z^<;K3C5E|XamUe#ZMw#kLt9vkzr&eR4U$G%k7+aW{;A#tk1cMA6Hb-_KN7THxK*)iDdlKrGu?OBQRP4xq zW8XIOAuhKZ`aOzbi7>=Kb{x&x2-k~Zpe|6K`50y#%Mm6v9WHRlvSDISrIus|mK;3) z%~93G0aZ;^hePlLugDQClgK0l1n$ z)!+(|K*1Z^x&HPD?*cRAJ+Lprc!j}}T6ZWHxx^P{h8pIHEG9RTJ?dl-HG$<|y7&n= zE8yh)#hvwKHuL4zjb;iC=j=%^q;wU@K9=dgB+VyVQdajTs13X;sjCJq_YN4G2fXLG zAZH)55+v}C&0})a#?oS!Myre!qRdL<%o^}t++$(loBU7EU=%ou@td8Ho;U`&VW zVHe49Y^i^wUVS@S-)C!NI5H%tAc26HGHxS>14XBJr3(2STF;rg;wG1-iv$b9Wl}T& z)^IQ~2_5yyZgGS+0Dr+LaI?HAPJ!bLjyMi-!PNzDa0_Q`Ttnh4cmlHwSG3^>M>0hb zn;YB!L)=jGhj(BM4TgeU52L8ezM`XazUE+*Yb$5xrUQB$O99_0>yzWT>r{Feb@V1W zO(}~JP{hy6Ue-mQ)pq0K5yd5frkyoySGN$!FbkxcFCf}|e3@AVb_OGoYpy`c+9_x# zOr24ULpibv{AZG3B5g$uwbY5$09D%Wkq7#Fa6+Ji)~B9SM-+zxI_}LyX0A^3$&I zVfHBR1*)RN4{zbimxJ-(UVkvypt5^Ypm#plC)SObuEd^UZ zP(pA9z4oZnxhW#8-iAhF@OH-5g`LRLS5{QgB>as@@s@bAdou`+t8-uAB>&Mu42RM|`9N-Q!mGrAlFVE|^sKi!l0~T<*|OAfwsM%!t1Lgonkj@(!ro^q3gX@z zl{N%iW=_?H@`l$n9m{s_ISR5M!1PgdZq8~6`^K>DvV!?z22pS&J6Q!+_F)g z*CKe7#a7s{pY>4M84j-M30*4$ZK7*zYK(K+HHSY1$_><1lwAyZ{ZTKfApC^+RksjE zn1vK}$VdswC~_%T8T6?EH5W$CE2u%Is0=c=`BbJCCg4(o#RiNm^l=yDC!|Mfb5|T*;j^v zA7BRy>LM+mm6n*79HirO>JM`uC~YyvdX#WTzw0_hwfYA<@3R|0$SrxP)qUtD%lH_3 zTh2GLAu36gml52aDS;8~%?B^AQ$qs6{itWY!yM|3`>o!vn;rL{6nn8eSs2;82AAw=905l@ZP~t}p_{bu}UbH2iTM%4$P_dB@g#tUw2PcDm%vsH`h#R;e zJwp8e;F2TF%EebL7x+5dFN!Heyqiq`6_fBN07at165>+h3V7RQ-%}hg$yXPDxBx=b z-BtW{SYIVYosD0=fu2Gg8VsKtPmtj;{GH(Ym6o65q|g{WxI*SuzKSTAo6brrvm^~U zfhQ8|eSwC|F&@+Iy-xQC|NZ6yiYxKKOiyO>J*GtQnmmk^dHp9dlw{7UY3_f=baPat zJ(agmbf1ssgojj2@jXXI*V!QH%W*3EJ%}oHTvyxvDPtKbB(Mq2ASai=E?qz-sH}W` zWll|E&Y+_GwWSM5fTAcBoJO{7rGa&(3BHDsxrt@dQ=IFh-?ziuV{dLMm@l!_wH;@^ zP#MqXPvqyyh3`P_geY4cKx`Qe!6hjQ2dTQ00J|WGtRNvDPe~Yhm?grYvYz63e)fGR zCm-k9+^e!1_d4B8g~Km`gM5$;$1OMb%(zyWlp%Xpr97E;!9gi`pXazim9`K@+(xQT zI%cue(2hCA&*5mz1S*iY0phv_?Ij?{my(=#Xrgw<4p)AN)VI$oY=I^=X7}v5ZB?`k ziCI}pky~CtrNhhumwXW0J~2!{-JrO)uvOAYYqUllZLbN&FkhTnSk^Yk3dHJ=sp|uI zhuZPAyUloQ`}9ydCOQX*w1T3#&o!!3uEQJ%dooHX0{EEKWxUJjC83^bn=9%) zGB?7$1NRlgcpE&>UF9#XD-~U0PFI+o($rZU4n=!tb%3KDjdXqr*L96Tm!y4sVtivk zYZs-gtl$O?-{6a0Bh3?Aw^zem{8doWE?8I9w5`=^QwzB#tetWWJ(NGYF)7BNL7zF5 zzCH;NrIZ#J7_EPUOCTc_8H{l!YkSlDvN<_ZD`9E%99d~YorGkIOl1MzDrx1ZKOf8K zaFnrfoJKFB3zTrmE;68OIBV&oqC4v36@-^?Gm7QR3Q*EYa-?+pBX zCY9PPbV`VJl(Y3=mNbH($!SZ>zwY)H>?i3C??5Y;Q!7?MJ9I!3Xo_l>tkrh%_=7DGy6EnCrtp{hDdi=nSg zV>gk40^V`(=oKqvous1DA0llxXp|cnA;r5vRZdGc{ ziS5@Yvm5g@a&idjVwsw$7@CPv316mPf-?aNf)$ulcDkO7b;O*=08Ccqw+)_x#b?d9dpbDOV|uKGs;exwJh3ue?b(~G_%x$*A`>5D zs1(1buq8#T!c#`&wS`@B0MX4p>*lRMN+TL5DoV+5)4S?xZuQj#70yt$VUS zzRuZ6MkSTSWN7;o{jNxxlr$Q)QRT`D&w3kjCDK9Ch1kq?(Ml_XzgX!ZRR)~7 zBV;-%SgHzSv&VAdfHW{Z6SReCV--hB3VthEt$KFSV=4|MuMH7h0kjpQ-*qCO9n9{l z9CdD{SB_*Cv#9c~cb>)bskuT*66dtdNZx!sBA+Nm&M5<`gRvZM$x+J{qGtpB8`GAh z{6-&MTNwtfx5p`3u;+~Z7VSM)$xMiAf|2 zm~x~uT8{*C$NrU{_fEnTtzWQjxofn|0Sg&t-zu@n24equsWQG6=?Y$s%^SD(M_3Wu zbd6>^z`J$crD67DBMLEo1#fANr!0-!LuHrM=v$g&BEBuKJY#dA1+#?SQ=G#B9?lTB zaeG(6eF&|u;bL;wP_}1oyCU8;nKE^u#1rMQsX{>0IklOwrC(#Xs$*HI9R79Pw1VNC zP&vD!POrVb1LI5B4Z-MINFaB*HS5B?l9U2Es*{obM@OruQBXb=3|Y?1ER<~3+_D6c zlObp2;M`jn6lZa)Q@Si=o1`{?U>dq@nJR)>-G($M3$Ar%kz9-hj`&srI;?EYT^>!q<(RmAYOWnIp9- zh%aWy{}yu4)r3up|g?0CsX@{`h`m1PRMGiE}%UYIDRqwKjGND3^t*qf`@W>!I_bl zv$GRy^(^5q^SUs&9==-V#4l^Ay@Ef**2H8+&d{W4d-Ek~)p4|A$$tUl6zVPw@(riC ze*<(im#Z{TELQUcR<0mjd|}y__2e2T8M(jGps44pZICv$M_JRUas8${gXd$j=Oqy4 z)&5S|UrdLs!=kH$Oog!3d`y5;(&8gy)~+D=n(o-Ns&aCa`3c9=#;TnuE0@{sL{rJQ zvSvOZAlPGImz^ulbJt#0up7XZcUw>&6>NN3(=BR~R3%Be6&;IV?OB77EXsNkOSe*_ z(2iB}k=)Y?!E0gOT|sA93QnrX$#zZfcXRXgR@it24Ezpmdnh0GHr;LaKG~rTvbx0I zDUny#Dk{Fqo1P1Vsk~CR{1R!4Yx8-!Xg)PSDfg?EoNMgQBQTQo^WDd4_t_1v&3dYj zOrD0y1IpjetUR#k?##zgergVM*XgzsIDXYCD#$~FjQuf_-GB$L=`vdx?==VmiwXnD zT8{p>0t;oyT3~V*4iGkbFj)^{u$W?h+1ANgP>oh@ zP7trrY?l~{baXvT*lWxIXRuixNW(79JgQ}ZvCC0vc`HGAm(6`^UqM{3SKs+8h&@cx z-b|pNGIs)0iJ#j1Y1D_k)ZeC#;As4Cv>GaxoIqC(?+V2o<0Tg6z!5+EeF}-aDBQwg`a$zX-R{}8T*sDkPCI&spZXXOc1N6y+nvy zJMByn;j}$wr%7v5LDk@f&h<;c%z&rTMu{So`!+|2DNYe2v@!A?>ZPgdlfh6R6Kgcg z(QK+DcdHl?JB7EDRp27TC2ieQ;8p-rJuYAV8C)zc`xKUuho)A0>RxQqQFbjU>@p*A z)MN>kQR(FAP#QHSNvDpS1=hc;EacMsMaipdMv50RMO)?Vs5PlztFG+}%7U$7qBG#8 z23rklTMDEpK1LpO&HC@L85$X&jLBY=A&_NMbi5!kE@31k?lN9Etdt-!f>=P{TZkGm zQdIU8YYjU^NY0FP)HkfTiaq7c7?zd)#7LIycZe0);~gu9KeWSTs*WR;pvv13L+vd! znUQK;K}pYZgbSH=L@3^Au>b!p$x$-k-709d$CrQ2S_r3MfZ6c%*$s z8*sJZoz&{KMENMf5fGGSO4-xMR-ZIo!`qv+bquMRq%J5`Q^l-Gl?#?azXiM7p$H_7 zaU^R<28z0)elCDZSsh(S4S9G?@R<(OAV{u(GgUn+r8**?e*j&#hzy=Tcr0zFWy`fE zh)&s>Hp>bhCAN3g;F(d`a;PI!b{WVpo>nT7hDcsbi@x^Y6Qcqnba6&so6c9ZP=0w2 zJ`>f2k7~RnNoXGm=XffrvF-4NP|n~qM2vH2GjFDigC$;@TFfgf>1Vp0%oBSLh9uh7#K;Nm46UZ18*pcWd6Q=&R}|*$rg) z3V)-dP_nY!I(B=7(anyq--XU7mV$psZYUW%;H<%gvzD)`SIj(_Wcr*MzKq_;s?I7$ z^{sxNQ<>e7Y(BuA8eG+b3t$tmkf6OHia>9fXI~;!oofF-Y5G!l$lKXq|AmV@QkBd4 z;G!~$$Axj1BQA=bQbv4)%fRLwdUtRsXgw#^Hd;);$B__8Eb=GIW%x*c&d}cuT())= zKMF1$4>dR!b}s4SYgMszfYWm_A)h>AP!ZqO0=1?UrInYSn*-c7P;){w3dbC^m~0D6 zXYE0&-&`I=%UfWF$k&(Gw2`mENqNnIqfVKtsw=0o;TLDKIQzkUx@P)__o(0Q-Ixds z%(KaGD0f(W83zgUxOuP9tRTM+KSMdKTsdvuNqP#M^Tk&<=Nv~zMdb~Wm7;Ix0)WOF z%)j#7y=aGQE3cx~yD|MKvQ%mdip^>au~aw#lwu03MqjcFB3JDc%`!%ZmdMyiqggb{ z=Gv$rT$I?fVz=h0|r`mRHcEJ^ZhkgWjKASv!>qlS+)L zV^h5(E#k7SDBAB5jQFx=*@?-~5R=-v1#9Q66*}NR)x+BA6iCp=>Qa#XQyrqmXrMCg z8b4RrJZ1FUm(4v~&0kTvA1~mbHL!h~fM#uS!(j;yDUu@IJ;a~~Tuz#(qr7$9yn&Hc zjr`J^;t#UbxH{x6X6b;EPerJ~Q>cPgp&q)JdGMf**yHeArgC(2POlV%(A_ye5vna{hsIgm&v8Kx5s^EBoMU_2OYcE+$>ryRo{AumIjMmJQN*tEv zw5Y#giSwiZGflq4{i}Y0A-~rXW3FII4i6V%fa^pgY0gT{sYT6BMUr0wk!wRj?OfN3 zh%-~Pv!!TKO%EZIn39WI_~&eTP{GrtOPn=1!c$;Loi5v35(E+g53AeAjQk$finwZT za5CziN-s*CcPWoGO?{^pFjF-~B-UdF0uX$)Jhf1%5_*k*srg?mhU(-{q0UFjMdu#1 ziDjE431k-rikamUj~ni?XvBuahnFLp29?v4)17p{;2LtTaUFz(%0T{Z1|4`Ei#7tP z=+3t~ZVi)?ehWEG2W*@rjll||vNjj-9_*-;jRPwbK1O_0!|0>XKVFUvtJqvQP4_1B zq?XeSjG%d#OBB93Z9G=0q|0#}!vzKNYkoX#MV(&FW@;=daN&kvP?$4=c{6ur-s(0R zjjhq)V`f`58#P`GfT~eSbsflArMcapDovVGvha|VIe`0soRG-SIBLs+qKSoLE9&== zIa5A7Q8U^CvlAN@E8u%9TzlH;vH$Wi%;P zCe^p3OO;MhA4kc2mdY0iuaZIv4wcG==GKmS_vmnqtmk3|HVLni8dlsIa1xV7f$mxv zO*HqX3q49)yAgBUDk7Yd#8Nun5tPcIytJ5KkTo2+L<#JxzBQTM9==u4Zz_jk21)MQ z97rcEvWoubr;Vur`wi0pvJB0I?t9q6jA{XD!-$!+14uWLya8y(;--NCEotgfwI(us zm=di_gnsP6j~L;SH0$stRk& zes7bs$`8}88H}h>mgZVCqNSPp!mNSXlr`4|4JxS1 z&LvP+`1H3>KLsBghO7lot=I+0Qy{_iIk!^^W zJ_&Tj%uV}g{8{}r>TI8|=Zpl&lFVt00BoW47H_3&Et>Zcg9bEjH}){a{xUVXe+u4= z!L5YuIjxq^ms%J#vmV=ONNHbYD1xSc`u16-es@(DQEec!aB z@LiP0EFxt!Fz?4qH{&P!~6c%vI&Grl~W81qL77DuDawZ(53KA57hO*8n6m5tg zJH(GFq+}zh9oU{AeuAEp5PG;Ju~NL1r7GiK78&jip#yh z{bNQF3(*^x8a9%}6I_k*=VUxJhf(5oD4^3Usg%%$Ic2$mnqSE)9Mm+vxBXxDu22Rg zMfxdnmUlMT-UNp*#_G!FQJ~dnEH6uNxG@|)r$R3KR!T$ncre#Zfv^rg0{#}k_c$bW zn^AnkL)y^eVb%tVlXDK&)*d3KS)|oR#U+k4^sScO~5L7QFn{RM%JWM zdzS7RQGbxOz-1@dLZ=DmQ-G1Xh${m9u{G0w4OwB>6xxg{Y%ak9!wn`S*9G0h#P?z= zn4B>StSc_YXlW%ERr1?g33P+`rs!lIBB>`NHgArAFYjaq&n6Z8&(Z8a<32AcB1h}+ z*t%VtOVRkQ1L#98IBsr{EQ}5KMUCF&;G#U2@A0RGnK!!X3v)JSqFXYUs+phT?E4iSf*C?%4z0`U~K{e!ZTsVwQ(q+wuB7~Rn1k!y_{UoEu{dh%M`jMCkuMz za(XETuy%rQooEIxw2N}PlgS1bv5Nh4fpq66Bp~b~(Yo(Z3Tr5j1Jj7D2 zwQa7O8Ehq7@{96_%d1tJRn9FN@>o<46izIxcus118j=ZC=D=f-5U%vmefi}TVw7EM44bboT`Av~1Ut6CV{u`8 z@z~m0)Lx)U{{f;BHG&wSbCnX!`wbv&EL+hf4pc)+3y6CZO5<_`wXij9lHO3$&!*oDy40#wA2SGUx zkP5MpYbhjk+d>Yh{Cu?#ReXh=z%mF~-__*^^F%t2ES-=fTK2?SX)_1g2uC-)gKZBi zHH@HPcDWRax)$>*+)OzXO{*Hs=}DRsUu99luxi`Pzg#SQY%0C#fTkP7dSY6zN{>Sm z#Io7LwH$D8_b<-RFDf?aLK9{&f#}l;QYV6}?v$@vqk_Y&cTDZC=zC6}#~Gr!vD*OT zM5*gj^{KQU<0Q~>M=y+~&_-sDa?8i&tr5_#a1ype^}~yaF=zz4D9@-2pWpMql$k1} zQ|?!go7<^0YHBlux#hdbvzyo~purBysOw;Qv@uXOLz($I7Ss!_O1lzH^KMLaP|2?m z?xn1cD*OxVvt0Zf(dk`WpSv@!J|a^evXA1K4T9V^b=CkQMgGkCa}s^)^6O3ZxDC4D z(qG=w1q*@>(kop%2}ibH-hwdb+DT+MEO#N#jTSAk{Zdx)1VnvR%DO;Q#XqAtr+=`WKAiUAO4;}DbOZUn4mSlRBTUlUE64W>;X*^oT zYkYZffq~1<^NZzqc_uA7g$%pp7b;dz!Ol05C6o-ClZ;853qwQ~d+MSS-P3?k<2A!s zDv0vba;TVInMY;0dJtf2(kj0`!KuE%Ya`jhE4my3y|`G^p!?+SSHVDYOJYdHeKNBx zjzQVJ3|w0D&@}1J7Ey*cBVqxMPp@J~iGt>3dS>3$0-zYTZ>gS5V{M*mhWB`d2F(nQ z@?u`$p&laT=@n(jlhk!;y4ePM0v;onlc`NqhuA__F);fAYvy#;C=!*8RXUza&N!kR zJHoK0iDv>`W-#uqD~t0~11lV)^OweUFvU4;}iFK>u=R0wN;MUR0Esmm=d-_E=A=L0q)iz$?U z(O{{VRgR)CiU`3RqN-Y_veGgB#-;(wUZyAyS-Ayn7?B|MM`D|S8LpXOmslH#cWzZ0 zbhH`B{^?F4-NnGUS>OHI?4W$4(NXF5%^vAa0JT~Bc3PG2)cmKHZX{81&6ifZ+E?z# zH%E%g=1faY$)*gUqvI5pU@ZmXIlPB$F0q*IEICiXI5muwPZ2!}I7}rLjX&rD4q@5{ zOH!R+sarQOQK;btj(D$Xh!|7ERJ#v3Mmo~QHa{uvWWX6Jo3d=+UIRZTe;i$QFV=8S zdcHQe3PDyh7fablx|B=T9SleqoTMAdlu_@Q;yL3iH)e23RNdI}96HwmGvMgw^0$-@ zkbHkZkJMhDiOMVDG-dOzNUY{K`-=*n0Sb3j!zBlkSHYy9XsxUcZQ2+f?Rdqg5g>zzRwL|P}Np#9e-MT*8eca=qn*{$%o#mpSu6fbzY*OcIIJ0B8Dag>=lJ%aDtC0C= zaiS$A(Bq|an-sWS3N}4%%d`CS#ig*DqrwzZ=*F|hCMoLoY94XvDA=-a%Xi)HkdO)2 z&1f|J8aj2!0Tf*&{+7^3oqPpY457@*uuy_4yPOkjw$CR=sOn9nFijuh7Pw>J5_(&T zSSEQ=RmIQn8s{U0hnqc*to*VCb=Yhgzj{F^h!oks-I7 z-Qc^V)nJXrfcM_~aZ0k*8vb3-o+V#a-PyA71vcL2YIJ>}RQ%51>!|Ru2Tg{K{qU29 zc{VT#;Z}Q0kXc}9%jV8-abzZzmmB=q5?^VAP~YORww8_!%12GbD(8)7Oh4jh$Rko4 zjN0;3ySc(HJArjF+I&>a_M^9Wl%|Lx0zjt3p^DO2>ToED*Zp+*g35yG8zmy%vjB8x zp2+$#!y3~GW4U~Xk~}%T7@#AI^Q*HZ()3eY^QfK^3Lg+jN%cKlU3z>%fxG5s26Q7( zi`0Q`_t&Vr+%zH80U^o@I0P#3Pmris?ekXa6*^-af5pOs#^O>a203nJ-~fSblT|R{oL= z*%$>#icR|#08GrX?AuqS2~%_3)V1VO{K^~`*k>K${u4cOh{Ep- z{Nf6~h~s098r&|yOSfU>W66GEx7_)OnjPUt(N|`>Gu=3 z?>>*5;7F=4)VE+wp<)hB*QNo*+=^j^m&%nr^pJXm9BD7*F2>-b3x+eZ$-0!pPueHo zrdcvBoPecvbdHJ9RuoXB`5)Q4UU>C9g$Hf2@)n~ri@Ujyck%Z zlyjcN>HchOxZPBE$&10wG`va+BMb17$f*-p4IH`|NhvWU(Me+zmkFi}&9clld}(`LMbx3;E`99oiF$iav5Iee}Q=@j!vG!|X8_vCzZW(68s zI4D^=#g|IagTmwLECY`@v{6He!jFV9qx5#qc-~*&;m^*R&~!o79=#;uP*EfGv>ERa zy&cFjXvkJFTj>XiBp?%83QX;}>ZnREAth;#F$m>U@`TXjGQ&k$nln5>{Bqo*?bg1xPOAmHwd%ps$v9XU({)ql8D36vZy4Y&#MG)IjiGF z6MW|v8Hz;?YH~h1>%tHpwp3spOI_SrP}P+B)k|24HKk(2p2F03K8V^9>$y>R#tkV_ zg;LHM5*?D)PX;%A)$%k_sHk694rwSav0>^;lR-!E7`6+G4}Q64Huljau-oWhdG z@fO<;*+{4CS;NHo>xQAOEl>_Zv|LzjUj?kT-Ps}+b!@h4Xx)H&`cPJugP<>LwqPDHFN6Adx|`1^(CUY{-!okn4cJ3K?FJ40+W|C}nxG3pwC@sY5Mk(kW^T zQx}BiJ?#+dm-rfp}sPx^0FA*m!mYHpF*Z#A@3(CIWH zF;JqTH4rxJ->2ub*Bc{w-gsRfjjFB*DG51*Xx`F%VT!&`7DL8=VHI}V5eOPxJaa)@ zn{&D|ly?EzC3GE~mXGnVLHoDxP?VxfsooB;Y)Vb)b{CWfuLH_b9J&NOvpXJcxCT5Q z@%R*L&T0`4VLkDHz`qx@gY zoq%!$WEo;`JEfHDanbFu+)HA4$>tFse?yn>ktXX^_!OGVO*zn^5^)&eG1{z9+8_SQ zNu%~KzXjSu=zP}5r8YE4hkr(fe@<5$N%fBg($(uiPp7IUo!p|Ry0`8>;Dj*;9gFb9 zkVN1_o+>j&!-o06F{ez?05W>-PWOh4Y{qJW)Iiw$Ryp6`iB#^}q#em+f1vPPP;2i;(jRWl4a3)RR{+R)ZSA!n3j@{tnm zTQsI_DM+Dn3{KR+DtyMU#H_U?r5faj1H#EBX9=k9x$9iXkJzLT$&yLzZ!H%!VpPL$(bom1y?pOvj{AQp3)d0meqL z2qBuac3`+A`R}p2;^Yf5YYq&P^DFaX#|RK{qxrHqCoe2N%ZV$g?&k(ZP)rj8!dNYf z>eNt{uwgOWSS|Yu-@~r{Ib6PjkaQbI9CO)>vdqeJ>oR|z`JY>QP>OzO$GqYK8ixPL z{VN)e$UUpbh7RR5rj%%lvri77r6`>bg?jYNAI_K*hpFRP+>zLoaHNB4q*v^(t-L zN|(ora*?6dC5Ix44Xn~Lw0hhDt-d8rH=w18#mJn8(dp!|dnEJn1(cJnGV_svhO?U- zvl8gMs3Dx0AUCIIbWT=7DQaD6fe(*fBE-aZsNtcR^OW+e@F<#n&P>(71!TDfet}{f z;~5`d|0!^N!CI$ufbH35Wym-8HPp4{LDO6J8LVUjkKh;t->f5u%E{~rY-gLQ%c$}VH z`~z17yHitRzMQZ+-;#B5r#sYg{y072_<6I!qTb=kSOw%~6cwC3ctRH;tBQ)fgJL?j z5;mV1RvXd-YB%$}+l1n@z-a&sZvl6GWTql(ioH{!vN3%@Q_gUX65E~4PA{R-i^~Tl zU%IzI%0c%eaDSE$AB03{&-uVl!GkX*Gr|YFW)M+e(?h#XN7vTST!MtZ!&^uw_ zM#!t?97&o=Kq<%!8*LDgd$KuCEoaif(oSLKYeVQ&*l2Iv7Z+G3P2RO|@-%lRyQ)V9 z$}Z`q0p_jD3E=%ngs72G!I#%ls4_fdN74|5r3{KZ(;02QzJU_a!w%@C;L_rY zoNTwUsaMvYB9_zGP1#yE724)xzY_~S2nhTx&$7PaPo!OEIK)L3f<% zx_EV*Po}2r6f3QbFP6<1`X+cZiUMXP)(dExkOj?&EhRD$B9osk!8m)o z1>;vKRjNjmWBIRm{0%-A20>3gn;^(r_<{SJ>Ch3EY6wC1v+0fm?$IL7RmSha{4L#D zna~4CBbAAarneVxYQePR3XF=&`;ANT`-(8tu_~-)rfTv^jH1)FVRXhh`v+^uJJh|B z7ZyRO9-}AN_#31oPqXPW6YQ&=pPPWBf={3R^N2Qas+81X3>a;g8?ye{O8&YGC30uv zlp^aO@dzuAL4zw~+}uGrvrwu!qV%Qi zF_D2|W4tz1|Drm}>EMGgbQOgk5Z%#=Bhk~{fYMUB=IgMFh21$Tl4}=xvouRSPMqbF=D6kxS`}hVjQl0!&)G$8S+WAbTjDtsW)ZL1&AFLrU2vu2 z@K4&(#bI0S_fe+o+^)7zVwfXAwP^<>ec)}FL~aCHA6J&UUk!U%q^^lxK`-noN)h2_{n!PVmwl^~lf3`K7>n&oDbQe&3woU1{> z&R@JC?37oM-Ogw`))SI5;#s-0dWeE<+ZBeg04jLv@`;R?RtiG>MohJIHLR{gfD+lt zDh;p-(`E{nC`adoEyo*^6Is&jr2Y}5v8RUj6)G)7U*xCPj}ve&!F>(xkHB44Uu}85 z2&zXitWg{}chAVut8rUTtnjUA>H*RWq7oPi8T3+rs~^tA)T7X3y_WP>DtV!+?5@F8 zje-(K`H#xf`8k{v>#EfI%!IN4`;{er)R3%_EuB+@KjqmJwV@Dv_P7hqx^hZBrMx6p z6;0()sw4HQJSKTY^P2B}S0AYCzn&476Ml=vlEfi+jxlRns!Wb**U&<;5qUXf5GORw z#h8UFJQ691l0-m!wn5es&R-n5c-%HTbmOk%i#Z9CuN)i}^VhlTaS9in(#EKZZJ9ve zr7OQOVCz8{blYIMbk$&CcqG>Ssgict((MbvLo-7?>)J{!Gbq0(H#{WwGh|*SN~TFB zDmv0d-lM--Z-Rt82A2u+Xj$OWG_|Q29!e&|6}gkL!pHZwsW(;+e$a(Fnaz*tszr~} zxWY+2$&!g7xZD_T&5W<6NNvf>JsyM0+07*4*IK!wAJHmSBX0pP$;8TP9v@3k#D9l}$>k z6qXkXr*FD9C;OJ

!)k`<*rLT67|!`(51D}=SCls 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

{o5I;6^)cSnzyyLxf*K zO$~WVF}&(!hKjJnGEcoq&MIa#U@H43cNwd){sN@PX^&opr+q>fo_P^E8j|Dw^kYQ- zOX4Jz2w0GF3J|yew)BbqBz}FkX@8L4PRT)oe@zb1@I(0L6>i7_{=PUrzrZPu)p-?8 z9mrOmLeyM`#$cYGO$biwCl}WC)CAw)OTqq$(Zi!fHK#`a zKnnJP%1N7_;61$Gj3d@8`1&PZ|K$?uf1LT^(lcLPJYy8k>sfQo|6R=LdTC3nQnh0k znO#NSLUz3e1--$b3#3fNqIwjBfi*|n@VO0+T$fIOeE?<^D1qL?)D&Qbcb8V+mIH&tr-x4#Hc?$b@1j$ z5OwyP&BA~N4Hx+&IXvcfu$8TFQ~Bi`X1qsU;!KhsEdGrL5Ad9Qu3oS@k6$5=yv*vM zcb>;VngD*vRea#F@~IM?X@+n@+isGo5j7YMn~;DJa?X_8%k0HjdgbJYaeas2xchjB z6-;*C*%2ev3gXy5czv@#ax1F2*&p_MZ5uS>(D?w5u9*n+6_!&>flbQez~1p@8&%N* zneh+71Fl3jJlT+%4bFGmRV5YQ+og8;Vp3@cs)tF;X&PXGDbO55Y}4954sNTQTqjRF zMeg4e%pJ7$ONjut3;P|!OI=ANa^IPpP=;zk_FiGL>PD)R2z}6*4F=f}Hx0Y3 zhMJ2v{!Vu1Btx<;%gHyoV(-H@ZbKQ^80>Ps{XQOIDK=eL@dxg6T3jY0x@m8N{SCVT z$%h$FmkSrm_JKcVcq5AqU!n1E43zq>A?2O`QhYb$hd;inBW=m?3bZ z{U8H;_s+#<0)BnIK2u=3M2kdl#=ozizMJ7D`ZBK5sDaKKtv3@zU>j2wV$niS ziCO$gG_n&=KYe(N_%DPi^U(Hi;&Y_Uxcdip%DI})AL8^5(5~T9_!{e!%no;1$hQ%Z zO3w9=BB>cy;%A}xB!%=9$9$P#dhquYyn+HJzXJ_4yv9BNZ)fasCbLkPdx?|#$xo2> zH=Ic&vwIC7QQA;*WZ@gA}#~eX6})Iv?Q-^B+Hg%MRq-41ZvHNhC|7VT(FYEr88oh zYH=2LA*uBk6_<)~UTptHH2=smxY%q(!ILg+z&|~)j2vJ64X@^sJTHY=E3by%;vyQa{0CpSTH{u{XG7|>t%yL&eoVjY}WVuD_ua)x=UrWxSzJ3h(C|PWB*pi2Co|rHM zRL2bir~t4Mu$Yo5mUsvFAHQg-qBAy^3_y7Gq>fQVn^&@AYpSF_J+W<(akIYRNr@-< zS*bQ72|zvm5eyye7toseU1_Rdi)cY;F8dc>-@u^JOF^SU_d$^3+bO~axh1wkB{$d z_Ci0GA4N^CI#3xoG0CACI?|ZeQzX})F~HkLsDkcyGj(tMtN2?u->-@uNB!8$`2iX0J$X>G9jeM!cfq*Q)vpS8I*~;Mb+pba-v*;P` zNlkgNxtO)JYW)wZ_aGmGzy(O%c|{x^Dgsc>v5+&*Vd>HAuV~aw5Zrs`fQ(o*sr2sY zyXL^kKe6s-41c`9Dt+Yqrj&KfiM8M0lfA?SDzu9mzFJNUbqQ@~9D@=)^PX8NCoAOg zEhG7sN@1E;lc1LDoNzqFd#Kw6W|5mi^$n&8Ul$ zWlwyejJ}(9>1QNEi;HDM_yYV&2)08ConvLuTG`=O%|j8p2yzX)V>UcwC~}&VE+efl zrCx9zGq`4^q*Yj(qDDfCW?Z(W<5103*f?tYF17uF#7>SV+Z=eu#J8AjAeYDkov7$( z*_ib`Mr{EvBoCGGi+7_+Yv6UK9HJt2`@N;G(CZ<78@m@5c6zG74qwS9jzqumym#gb zPd!Uja!HM>SMD(P`#S`QbbRYo(>-_^@Jb9UP4mzH;mHf0%;To@Vb&{uu_CV!XJH;5 zPsCV~C)@iuG21g+-cl1g&s4UKENEGI-RkI>B<6~}a-CQOe*a*M!}ul7kG%!CTqYH- z@x#QGEn%6+AUNMAtz`dkqwZ+E}^lAn`& zI&g7?Q;(#5F1AP@64YI|jaG86;e&H$lYlVZvH!HHuK^HnZhS;8PBn!6{5q}uCP^!< z(2>7H4_UQ7{0JXj&ffTqWCt417yL#QF!0-;$MLeC=*+Mp{@d<0o>+RuodIb<&2NzG z9Z>;|xEvlR?e$_DctU%8W7b?ioNnk_xYgJN9Nn7(A@F#;=R){bFzJVFOa&XVJx3ys zuNQTI>CJhnLq!At@pynbXB!d%7P#|QN0LhKic8U_T64RkSU~a1X6F953Z9_>kI#VD zGlL)ysasrbLy|;k*<229oa|49!aLvmKssafpL|Kf8_rjb!XF0>!$3U8`Z!p}wM`q>YAE-bIOLihInJXfj}?Wi z=?sjCo}zP3QWXmB?7W{}-=i3?<1Egi<|w=Q;<>L-T`w?Pii5-eM;`>aY`m;^-uFyQk7!<}J> zoW1jt9K)rWBahSwIef+i7CKT?L1)T~`*7rj!wut%IRL4Cy_i!fxv1NyCT%o|@|q#~ zm%zt`j>tN)1WBtjlb)RV#%V!_=wm^Fwa1A!;{5@vNFJ=JY!wcOKBhh8J5orcf>M#} z%qucM+}i=jMNS-Yunh(szenPK^V{G;pBN+)wgCmRSyq5z2%=sQchV9mS-dhYY<{eM zxg)+SR_C;_Lxv7Fg*#;o>*gV4q27ACfs4oMz`TZpc3c1Mt2pw6xt{eHE?M!vhD)aL zX$!}Y{LKcd^?u23GC*GVaJ!<`f9LlILST%#7Ofky8HZ#RR3ikRr?@2NXYApiCY}H~ z4$0XMz^MoNkZJYpDDd_$yhhE|ot1#@{Jp|dpm=)RhtU<++Lehag4N7O8~Y_zQRc_p zNNU0YEfx2=8wT5=>|(I()Dkwb1r+5h_ahx9{x`o!336vM(BDBEthk)>5>%A-$${hf z`C0bK8C}OWEN$h(N@!dTat013+-vn>Oy6xCBqL8ar>|ehc%XWU2iYwyTlKbX6 zci>$BC+3{Z@D0YvxgI{nIcsLE&$)&BT07ju!^~XD#{g9EP;4bHLhr?s^KCKw{0g+l7h=? zh99GQ0a6QC3RT^LQ?10F=5y{c;^tAGbtIX6B6+)L5%T2;Hi|u z=5iOM>{Hx>9^UTxeNI?>5x>(2ugOFC`}@<`*{4tXpJJ0EWNsQ64L-1)Gh8<`jd8sW z*R6VBO2i%lss*Yvw}~5@NR8dds0#HtTor%-lpvZg#}V)O)O8eWQDs)5@AYz z(~g>h2Mtsu-RyvtOeh-c_VY8+X!sTtojuKUxOC*XtD`fRosT&Bpgy1W{M%y!Q%Qkw zT!K`ihdXmJ(~4hnO*So5$I@4Bx~$czyN_Q}?y|q+Yug&vo!QSK?)x-O;`;j|u2e1b z<8Ze_uad@{WC5xp(|#u-afE9fa}+L?tU|vex#PWV;_<5(^CMr4Htpf!onL7i)j{*= zc$VXiuBf1qT)`!30+mQ{3CO`dgPC?8e}v&I;tHyS1$tNW7$~LX{O^1zNv<;Py)y~p z?@zJw_!Z6Vb^Ig>0Lon;Uk&>!PTd;PJ8PO4Hx}6Ll1~9fFaecl3i=?!>12O-ejh(Y z9kx4tbHv_x|Bqh+9Q+r+|Hs`B-tGv2=k1BPmM|; z4|PhOmYC{gu{f)FtcNssH20m?trHJ~5494JM^J&_NOCdit7ksBuN%!Y%&ywcUY-Bs zQf$wTpOSdjfJb^1Ee6eBkvg3O^9==}7O%hDLBt7+$}-cx1rLTi*BYOsO)8A^M$xbb z2W3NIc;x`skhyOKKt(fB=X}oyg)^j55tlJoq=(Z;MVtrpemEkfXsj$=Cwvh~qAZ&8 zSV)%AQ)PQdc}WqUexZqa+qCVh7YRE)4nxM8$As{vUx14Eh29^R#C*hGtizy-#n2-B zDG}bV40YW>8u{|^D20KjnI`}2DsPQxRV{P6_7;m;ix=72v(ev|ra%cCh6Agyvt0g~a- zrtgMiH!j++PHp!JbxbdmJ(Yx36H~(qPR}L%dwa3Cu}ivS{Zy zC9n974S7h(sAf*tMyvF-9MSw;pAnhALN#qSP9a(Cf`Hl7-`C@84Ko zpZCM^0_(N>F!t2h2CiC4{^d9*Y2KZ4C>t1*u z9g#HEaoEr)1ouhrf6OVd^u)C{Q<@2;_9m3clae?8)FJ8Ng(@f~FD%&y^hIjMX_gVG zmz*S_or2j36I}{*?#q@kw*=PFlkEKeJ*&d{g7N+gIq7WpMsp+)KGdJFt5Ad&2TI?J zWZ3xx;1N=}wC7l<-wyuB^Q-Y^0x6kol9Y?b5Y%)jh4A2jino@W9BKXAmpx^o?52Vg zS!qp^&o1M&BYY@G#MF(TyTFU%tCM{3cKirmM&XA&k>>m>=W2Vl_*78sCW6HA4OCo)uAf#Q9POSCR@W#Xmf%96jWh8J>#(!62d#;avUlD(7`k zqRPT|hQ3Q|{N$dnCM0m^m(-1*7=RuQWXpa}Ue6LVqNeN`MBG}Cu(0QfU&QWkDjw54 zVP7Vm=*179&mjEeb`4 z%hKJL2ZCY(sp88n0EjWP75i76;J&I=kOK!bl#0!bGX1{wmWL_rw{D+YIlg^}(d`@} zye!d9>zjAPU*aWhd(KUtep0S~8NY>b3sF3fIi(Sg#4Pu&o8{P-@$a2mvWLHzCV3h> zEjlXM*xywq(RU>+2VzMOMX?(}E!7Ym{Qd$K!S+><2)iBh2V$tAiUC)WbAIYC_uieF*CugdE#O}Kd{ujud`cgKg3e!8mxLkG9#fk{WNKtrk6*(McYv>mv>2@6YOIWv)?GH zzF2Kax<-D2gU9r7FdLIZ(m2vgr+B9P5@7Ih90}1q{5S*_c_c*}8wNOfqVC`Ery@kx z_>-PWD}rZHNCKGx4hMV~#)zBpP6gaSl@AVJ0RoX8F^KG>E{mAkNnWI;FK8-F-!Als zHIGUTp*`tFnppnn0qaen%y#(|BoRpWRn<-FM*!Ieanu&Z=HIZK%Io~0O~@)NSEbx( zQ?HDh7OI$XNwV0|eg}aKG%-hFXU0J=Q!i;BDN!E7ml88__Gm^3J3aM2kglnJXWGT9 z@4Cd-C}(=n`CybFeg)UFGP@axw<1T-pJKw7D@kk(ToD0Yr3JgGl5XFD$I z<0r>`iV$TK2ustDO~@tDMP|K-d#+tIu7L44>fZ&QeMD6#_$A;wj;=l4#3B^XAVSY5 z_Pj4>O`^+222}%<*!)n^Gx4eg+XwOPv1TxM53+wU7&AyO135MvknN>)Mrx8t)D#fi z;8CjQD}d1fT&5Dw%n@z3R{T0!eEZC?8Sv)mlTeCMu)SE9GC~U2#l+*Np5{!@3|K~K z#h%lqJj5?i(yZ)b`x4tnaY?lsWj1~R*K^p~E0yzPPDPs~H|8;0pw08JQ+CVjZBOah}WqyIfVD;~&2Qe?{o|{Am#c@`{H{FAmH}Brkk){d2GBPOv>@gd8@ts(Zo% z*WVq!&lz#saA%A57O2L*2OHT#k5wu-gPoLYA7D3{VeKPj#+UK+x7-2S*wlB}{GG<1 zVX`>;7U9GP>iQGA(Gduf%xlJ{>_?KTB_jesknd)5CecbyHj{mGoBN#_yXE$kXc9Wo zsNJr6aYASxGZJ~LN#%SKCq5pm4xEoUp`955&P*CB70DUI1GT_vD~1&o|DerhE?1pd zE%>B1XIEHkC>QHY6y#l;XmeH7+FV$v)I7nRbYV_5m$liPQbT~A{Ec{Q`QM~FBP@4L zc@szu3QwpiYJCzGT?2X+tu9#7gIt(vpE!wRtj?y0f`}2Q+_s~da~j+B>&c(@KtNJ8 zXGQ19alYmVGVp~sTA%$t_|%Pdfir}tQXz@ZBW8BP&Wx|j$PKjh6}GulY)0$7q|Q`| z$4$zrcG$!2a2{ksmegg>#KL5SmDu8PLH=LzfBl88S)Z@Y?$7>jk}V(jZp6AC|CjAB zvi~M-n!ojouT?>yub+-#iCiBDc5RB1!BHATmj8-fh(hy=yI26WOxV_C&{4bO+-7W6 z=|O{5Ex-<(vq%+sA`?!k0!Lc7;diIb;&*=p>2CN&)+n!MPyF`z+5h;|g#s;S&QV(@ z)OWl#?~H5sJEz?+bKvb01^Shws;0eSO0s|2MDDKj8}3*_PiE-9N#+)_chRb`+9XSa zvO=yV@dT8YVmmUCBe66qR&bkaWz0JoJ*1VCc-Ao9VB&jZEuf?yqc*il`?N2ZII#`y zU6lB~7KI=(A!Oks4^ z?LEE4DPlRzd^hdhEyq=}^w zOAmY4zh*?EB93dn%ye$yKkVP}%j7{lNgUK}+rZv_UPiCiUr4!M?f0)BN9a(JxD3?6 z6K*OozI**Wc(mFtAG!m_JL6t_ID;OSaVeKkPnmI*pNg~pGt76&TeTJXL;x$!4s7Y@ zX@16?eIXd`o>rtZ_D+6iYL6oJ04mUD(Jpyl{AI_GlG%IOf{XSz8=VVi z>0KrqNW{YA8ncth!dr&*#if%nsUvDFRYlJ|JAdaGZO>*LpMpSHp8dB^X1$XTMs&jd z_tZmy^%YYOiaKCdH< zaS>0$4u&3A;5F6=^`dG@6xn_|qoMBCa|EF;G}r6a;@;W+@yUsjNr3SgsfiGFm#ln2 zZIL~{LDeX@%8S-U5=hc5Q{0oCZe2)PQwGK)&X?>|-Jl{!?pr%ky49h#!*^xZ!ZJn{ zrqMDnSf+_21w&ujxePf;&xE7;;*pRYwbJ?EOq+)!yqzEd5PqA)HG`8 zVLXk_jkv3(e3%hh245e4*))Yb=yT{Oa>>ls;s*9hBqCYtQz(FDZ~1C<&^Wnj{LaY& zwe>2juz9iJG9BCL8!gEthrAITa&XHf!%rI2L|4WP6Pf%Q@VX(@nH9rQuD;S@dy)Z(hZQ_dVm^|AK!5X2omTf(^N#U5z5iuuh3A4UDk_U%%aatBD`%m@W`T+(h}wbD2bpn}OS zm@xP>2}Zc9eQK74i*O1LJcNpJZKpY!n$wul+4C-C=fn7g05#%GD$oA&r$syQJ|l?e zMNMzU>C^qoKJeKI9yA2RSr7wQCL#Hh>zc=@^Tn-rZDsEqANF#Dsqqq;X`Pok{?~6OW`_8LRmoV8Cf>YEkHwz2vchp6q{Pt;wtif5^HYEFrjFb%3EZ+-;rJwll^nzrxYk-qtU<+Oe#^;V`(Ode#0cp*Ky`rUj9jOD z`0G13zmxHBU&zzaFQlf`kqmkqofc6Kx87L~c&An8^4!U~?eoi|n_be`)1hJHns$;0 z)KEt<=--a{94Dm1e}6=6C?>ThQvK^EtJyxMPA#h<(lrMr6V9(r0e2iE$1bvjXXl_2 zfwE7ebsym_;AFN(GQXmDqU+{_F;(+6lV0l`NuBA&6ue&|rTybxz~dP;qFPoG$ee5_ z5?P+xG>F?YzWU3lyc{f6Wfxn=dqy@gE))%#n3DIA6wHC^O4jkfZ)Z;TzkD)3o%$E=vW5-O$0N4+{dpr<(UL8Z}H25C$hw;Hy;sxxIT@` zk6*q9B_jz*o8Rql$hDXy6bzXEgy1#KY~vZU&=D6e@kVfJ7b6;nXkI$=zvD4E(vtD~ zrOWd_a{|@mOeb%_i7SG$r>3s?%W00m2J(VJ-8qJB44KeG<`Gn0%!P{u&xu=c{p07M z2n{cI?3c)sqy-eq2+aAtUhE0W-k(0fK=OrSNxd9L6e>2E^CKYrOP;Oq%>*v99sd41DSGlmCnVVzm%v zA4Yc*-&oeF6uq=_UdyHA<@~Xt1j|bS<@e<*Qq{C<1=i5TK4i>aiFREKv z1{e41=nAD&Q0)E*j~Z$Q%V2eBlSd9^R+k^H`1IEMjM4M?*B6SrCBl7&qkrJ|6u~}{ zt!FOvpFT-x+l4dk8`vh{E(``j=S02>fcy6p%YqtTf(l%!n!ocTO)hAXMc*1SP!(@ zm7HP=tJL{48MS%W@Qc%~d!5}}FdPeUj~veC137YlhK}ArN)o zbHWkiRCh5N$extWo=!!%ptP*TkQ%7oLqTH|qbI@8&Kb0m)9e{RR}R=ajUjt3Tm_KU zlA!P#t?DVAPq$D?^MB<`xId9#&%zHUbv)_PA*$$mmUvMkdUcv^X(Fyb?jpi_M+Jc_ zi@ro^k-T{dj(o`*%uscBVpQ+9z?RZ9tj?e?Z~&hBN=$iy-RK>4T(ElBep`_oNgeEx zAe}r|+#fjE>f@cP&p9Z{18u|dwC#)m{$G|`w@=y`BVisRqLwpW$iLsXr;zIcp8b!X zmelX6j4Y$eJmH~LRiVQAJW^H{@svb#7pr(*OA0p&(h)^X27v4!<}i}i>BIZC4Ood! z>o`VSjpG&r`+%rS9sK$-G@U_{Ag~MQtrKU*FF)css*|#ZFD~?*5nF6sB?^$GS;@Is z0(mz8$4g4hs`nSg3`a-Po%H7HGh~sIZLdK?YtYc@sU%2J*KqDLBRzHfEwM){ZWDlby0RK+h` zNt{rwlw&6{Nl_HwN(wuKA~qKb1;h}L083b4SquimAPEFQK@uPt4Snxz-J!=b?6c3F z=d;f_dsur-`FwuQ+NZlEs9WoH-@bj;^IgyLdw%nvU#&bPtrz>)X8I+hV%c07Wjc;x z??36IrOEv8*AihfaH(&z^IeE3oI^Y7L@C-3!ZuHF7i6Kjf(jGFoDqYn$+#+D<2C4S z!}B*s)TeQC^m4;X{{p?W^r=I_w38ZG8V`ZUPv_*gS$bgFzNii5UsIErhN{Z})x9pG z*iUb>t;7}c&K@x-;YcDGbszV>&4w%MJ2Z`Qg2B=0+{Qe|xFIScwB}p%q=1MIz{-Ker00NT z?4ynXh?k*_fi|KfWgAhlX-fmCh$GQ~c6b?M9jAzOX<-jMdu2Erv5MFN$sUM7q)Nct z;G)tO+{X({WC=%E_2##ULuR1MzO}wXXNKdDOJ?sux_^gX$02vd^l(&FxT+*u2|x?O zBq%iy-5z%BsW89~R7T{ub#&R2Nr2&0Kg%N&a)=HrIPFO;YN%{-K)qaJ071yJEi$){ z^_XTK25Q{r4IiM>Dmf9Hq=@w4-z5QL(;@9`+K}U+aZ8U)9K?^|(WXu{k%p^dN4%>)!Ua;_+27boR28R)U>UB<19F`Qc*osobR#y)q`vBsb$w7?DfvuVAw8P zgSI14)zIisZ_=i-(-1N;YJQ4f71qjV^q7Q}#&#(mXHV}v;SLJbxNt_{5=sBzN6?*l z8(br|D>R0w%=jz>xoPu8;-3(M%HEiBrPff2{H=O$6HqUK*@@I7YR@A*rcah%-5CbI zEx26f^j<}@v56Y(1H~m4rRvuk1g11nHH&^VCAbFRV%-pL95|Zdz(_7UyvT;m9h~Pt z(N(7`L*sAZRLHYl1VOj#oFyP7@@oKtGVrPPu!$U(MLQMR5Q`3qira2RNERb*#t4Hx zS1CCcaT7(|&H>gs<4j4RMuG(}yYlIaP!`zu+d||Dklrh-T#mNJo0YtA`v_AUzIC5s zmb7YeW?7HVMxgl(#w*a0=2=5HRS^)krhq10Xz{YkJt}bbDa)+ zfL-}&L~yTdPiE1P`S{k#>a@;c{DjF;HI4|qMY{cyKgA}y_*Ed&^c@GTQ~kzyC~t%* z!kmK5hJ-+&VB;0al5F~xlzW(S0M_CR_!fQIH3177Gig?p#71ZF4Wl5^QBc7;^6=0* zk!g;nZOB*MfcpfhB)(5FJ?72X7mygg_ZfyDTmd7G*=2UN>x zgnhi~4xmkloGfKzbj7abAVMWW(xS2B!NL=VdZ|Zl4LS>;Ohc=l*bugfJm)>+k#q&i zzeU;$1Jz~%hv-`_bMiUC7ot*QH-tyH3q-B@DCz>1bVR)%G@*PY>la<7N3Ow5uvc># zbFiwvERL!dp`LE+-VVi)PMDCeesYbZiZYoE^0kbr%A81{1>OV9ybbI$Ws>Vr(;ut) zYo%)%nWB)TcSGEL9aCve)KG&c&2HOM3c}jo)=%*W{D%26 zJY2?GP0GhW4%|5bhApgYMD-MHitwV0f@lqbm}pf}_TW4yx+@2<%KTI7uho+RyUj+T z+H83=C$0?C!?t{C)WUsh%WKCM;p9$fKRGy$7_F++pG6B2u%6;kDZqP+^0k9;RZ&b( zk>-Q)1#=+b9tI&^gE+eu^AOA_JsN!`{64r4+YTI~xM=n;w|JSk5U^SEQg?wnxk_iD z%+8o5n54!QBlCmNvv~`g7_c zM+*y5yDR8J^FGZO9*~IM#bB624~m8OL6PfwViT+Y>D;kiF%5%b)@i{WT9#Z+Mwk14po|EcH*g3A_a! z2rEiUxB){v!EC!93roz*L|pKkgV}_JQ5a;&>YX7P8jMDpp{WU~!l-GLurZ6{)Uxzq zGDZ6&N2|49LEC*08pMRJC?i{7`{Xrzv5!eXNm2J10!@FLw{H>Dp*ZH=;h{26Y5Z8q zsMzrox~V8xGGX4Qimxdn0i}F%`iB0tXo40AgSw~GY!C58CUcUw3?nuH%)T<|OYE^V zAxl|$cG&2v=r5q|~HdmZ-OtDs`Rke zcN!b6E9eIQV5G>T`s6b@%Ih`hg@TKn7DJI#e=H7Do!AqAl(&_UT%sXQwg$Z8sPNiG zaQnt<=;semGxS;+@S|LT9e)@4NrO@c(0W5=zRHD70~t z&D!rVPkh1mScK$6oHR5wDH+mE8fV-*K7(T$8tca`kRR%ZYcS~E;~SDALLYd=JylqX zTOMsm#R|MgLU6wW<{F!4g_9&l!O-GinpsB$qX-8{3BrL58zK`%%AP#ka4(ODY#f(G zz{GIL9E06PhJ#4utw=S}i)Qnc`r&`_FuE9OL-b)C`Ymm>Y7Q@k4_m2e?o*=+YmQk- zXT@qkC8y+ToUtE0sb4@$L%ybDu`!C_6^QjyD^u{TdgUNtVGct-yF`yDs81nu5Mhv- z95#EwEjf5D8;>f)48h^y)9;=QOrs@eW&0gy%@O@(piRLW5j#i#pAMSOkl_(!=Z539 zh39~c9D(xk`Mqc86Qke^O8};+QseL=NS_N@k66Vp<}{rc(IJS248vNSlI)bn*qi;E zkKZu1RO6CP*+Pd0Uwa8iDt;fLEu>TgYb-W6lN@5BMQ&cdVA5`eFt{ zxME1Gz$~>fxxv#~65Zcu;{5Is0bj^g^21ia+U#y>Nfgmx)6+#WPKncuM-m@s4Xo$W65- zn+LZX_nU!z3T_fqA;~MS7m#HtUKKk{v~hJ2Uyt3RG)*ZIp1{#STAP$By=}q2pCCk2v2Fj z^gyUjaQFBc%Ss2(g7BrW<|PO(aiWOs8Fn_KP2bXoDK2}*H{tNXVr^Z4wi|gnh|hx* z9fLox0qIH`tlEQg-+C=FE$p0Fzjk1Qb$yLn`}Sn>d=nWAIs#L8VStBtO|i&jWG-Gu zR7Ap)4c0VI*t3rnMAxBsCyTka@)s|06;-<0(M=p`jxyR%@*+M(_m{zlClGGZ1Dp74 z?`=Md_P=(sdAvL9{}B$#ge<19Newyj2VZHCm(&_wMuxnZPz_<5lp*g- zz#&b@#cT{rPp}PWm>eH{FvV+U1nqt6L`JAbvK}c@F*oPzlP|ajR&t*L>lGNSPcLx> zTmOt`wLw9RgcQ(wEKSMW?b;7=B-fhEE94_5q|dYtvKz&DJp}P@M>A7sGa>U znVXS%XQbrf1i2rYzT9UEucY}Xl36X)U+3I&2dzoGGx&P>aK$tri-m0vf}1$pL^Wg~ zch`TN0tgKkOS0Gm-?V;i1mFhEh;ikilj;uGK(YslnoTdWqnFX?9pJa<6bGz9leH#s zv3Arsr8z}n?xGc~&^=8AbkKoG4i!$I3L;oV*$R3mE^M<^8Mzo3GopCH_=`qxDQlWT4ZB$U@d=Bf6S>(2vshQ2(e7KURU9iN=~+3 z>?f`%azC@P>$v_hC)-sidA1ZZIdMxHPql(_h`3kAE;(SVejV*a~mDoMUiebQQu<1{U%-g`A-S1cDt;;YhUG^iB+r%Bdq( z8aAZ#qdXX$ammh^$H6>DGI$M}>{_4&mhc#=vu#fG;L|~IjvdUSxH*+WRV}+bf^E1T zvUKZ9E&F`|_zJYEXD6Udsic;vftPse3&gg{5bYwoI;O~uTV|=V)J|8cK#Q&m;w$dS zE#b79!~rC>4MJZ4E+71U3)uEI6T-p$NQ@S!{xQw6_nn=d(vZlcCEa8cWMf^X)PV!G zL7!tc`cyr}H^Q!VA{z#d!&Ar zYip);n5Rgd&Cp(p!pTYK+;+vb#>PpsSCJB5y|sxzwM_6iUeS~~#UTe+uWx`wZm-cQ zYBcQ0#Zzh#^Ybn)gf)CWE3#!dHYGQlgjXIfiQN5kfR1>Ly^^$npQcwrU7wpd4SE zbD0ez9g&(tYv@Ra0T=q&IBJx3(ZI|+vsl%x9$ z-?Dx_!yRDa*%Nk3ENd`W!;wAs_u$yDTL%oh5ksn1U>JsGV@B+RU315r@MxL!0`Xu> z)_OZ9aoS)o3qS0hba#h>AT&Z3Gah~xKJEsW*5>V#5NYZUU3wVj1hpu{pw(MVeT;De zNpADt1`Sc8xq9$xu|GY6uHDWO7FPr+b9ChDsNikFxHTGW8w5-fMo+Cm_51$ibSmHQ4`m( zh~Heg6Ib^*{%O-Y-U065Y%8u6nz9$I^~3pq?6 z%n4rAnlTnO-XBF7Wl3B>K4=>@{eY%9q)?pN!7qc vRP!ZvkUdN1-_9EPCvT%FCr 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

9Y7qJ~d|*B=vPfnkY;$r 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

4XtY}z@xsiDk@#VR$SUSIbDrK7O9=ZX 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 z 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 literal 0 HcmV?d00001 diff --git a/contrib/macdeploy/background@2x.png b/contrib/macdeploy/background@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4858183f75c382a9b8d75ae4fb8a74abd830615f GIT binary patch literal 138890 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 background_picture - background.png + background.tiff icon_size 96 applications_symlink From 66b473457bc94adcd3d277462f9d619f5a198d96 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 20 Jan 2015 18:02:45 +0100 Subject: [PATCH 0199/2337] Delete RecvLine function No longer necessary since #5161 / 845c86d128fb97d55d125e63653def38729bd2ed. --- src/net.cpp | 50 -------------------------------------------------- src/net.h | 1 - 2 files changed, 51 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 8cf2d0ffec8..bba80535e5f 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -157,56 +157,6 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer) return ret; } -bool RecvLine(SOCKET hSocket, string& strLine) -{ - strLine = ""; - while (true) - { - char c; - int nBytes = recv(hSocket, &c, 1, 0); - if (nBytes > 0) - { - if (c == '\n') - continue; - if (c == '\r') - return true; - strLine += c; - if (strLine.size() >= 9000) - return true; - } - else if (nBytes <= 0) - { - boost::this_thread::interruption_point(); - if (nBytes < 0) - { - int nErr = WSAGetLastError(); - if (nErr == WSAEMSGSIZE) - continue; - if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS) - { - MilliSleep(10); - continue; - } - } - if (!strLine.empty()) - return true; - if (nBytes == 0) - { - // socket closed - LogPrint("net", "socket closed\n"); - return false; - } - else - { - // socket error - int nErr = WSAGetLastError(); - LogPrint("net", "recv failed: %s\n", NetworkErrorString(nErr)); - return false; - } - } - } -} - int GetnScore(const CService& addr) { LOCK(cs_mapLocalHost); diff --git a/src/net.h b/src/net.h index bdb1edd50b8..b78665b5c62 100644 --- a/src/net.h +++ b/src/net.h @@ -61,7 +61,6 @@ unsigned int ReceiveFloodSize(); unsigned int SendBufferSize(); void AddOneShot(std::string strDest); -bool RecvLine(SOCKET hSocket, std::string& strLine); void AddressCurrentlyConnected(const CService& addr); CNode* FindNode(const CNetAddr& ip); CNode* FindNode(const std::string& addrName); From e7cfcc8f7e7053391bf53b1e291246857aab87a5 Mon Sep 17 00:00:00 2001 From: randy-waterhouse Date: Wed, 21 Jan 2015 12:10:35 +1300 Subject: [PATCH 0200/2337] Remove custom pkg.m4 script. --- configure.ac | 7 -- pkg.m4 | 214 --------------------------------------------------- 2 files changed, 221 deletions(-) delete mode 100644 pkg.m4 diff --git a/configure.ac b/configure.ac index 9ca2f19bf98..85e3d1d669b 100644 --- a/configure.ac +++ b/configure.ac @@ -64,13 +64,6 @@ AC_PATH_PROG(CCACHE,ccache) AC_PATH_PROG(XGETTEXT,xgettext) AC_PATH_PROG(HEXDUMP,hexdump) -# This m4 will only be used if a system copy cannot be found. This is helpful -# on systems where autotools are installed but the pkg-config macros are not in -# a default location. It is currently used for building on OSX where autotools -# are preinstalled but pkg-config comes from macports or homebrew. It should -# probably be removed when building on <= 10.6 is no longer supported. -m4_include([pkg.m4]) - dnl pkg-config check. PKG_PROG_PKG_CONFIG diff --git a/pkg.m4 b/pkg.m4 deleted file mode 100644 index c5b26b52e6c..00000000000 --- a/pkg.m4 +++ /dev/null @@ -1,214 +0,0 @@ -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 1 (pkg-config-0.24) -# -# Copyright © 2004 Scott James Remnant . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) -m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) -AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) -AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_default([$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi -fi[]dnl -])# PKG_PROG_PKG_CONFIG - -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -# only at the first occurence in configure.ac, so if the first place -# it's called might be skipped (such as if it is within an "if", you -# have to call PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_default([$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- -m4_define([_PKG_CONFIG], -[if test -n "$$1"; then - pkg_cv_[]$1="$$1" - elif test -n "$PKG_CONFIG"; then - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes ], - [pkg_failed=yes]) - else - pkg_failed=untried -fi[]dnl -])# _PKG_CONFIG - -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- -AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED - - -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $1]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -and $1[]_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details.]) - -if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) - _PKG_SHORT_ERRORS_SUPPORTED - if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - - m4_default([$4], [AC_MSG_ERROR( -[Package requirements ($2) were not met: - -$$1_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -_PKG_TEXT])[]dnl - ]) -elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) - m4_default([$4], [AC_MSG_FAILURE( -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -_PKG_TEXT - -To get pkg-config, see .])[]dnl - ]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - $3 -fi[]dnl -])# PKG_CHECK_MODULES - - -# PKG_INSTALLDIR(DIRECTORY) -# ------------------------- -# Substitutes the variable pkgconfigdir as the location where a module -# should install pkg-config .pc files. By default the directory is -# $libdir/pkgconfig, but the default can be changed by passing -# DIRECTORY. The user can override through the --with-pkgconfigdir -# parameter. -AC_DEFUN([PKG_INSTALLDIR], -[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) -m4_pushdef([pkg_description], - [pkg-config installation directory @<:@]pkg_default[@:>@]) -AC_ARG_WITH([pkgconfigdir], - [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, - [with_pkgconfigdir=]pkg_default) -AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) -m4_popdef([pkg_default]) -m4_popdef([pkg_description]) -]) dnl PKG_INSTALLDIR - - -# PKG_NOARCH_INSTALLDIR(DIRECTORY) -# ------------------------- -# Substitutes the variable noarch_pkgconfigdir as the location where a -# module should install arch-independent pkg-config .pc files. By -# default the directory is $datadir/pkgconfig, but the default can be -# changed by passing DIRECTORY. The user can override through the -# --with-noarch-pkgconfigdir parameter. -AC_DEFUN([PKG_NOARCH_INSTALLDIR], -[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) -m4_pushdef([pkg_description], - [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) -AC_ARG_WITH([noarch-pkgconfigdir], - [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, - [with_noarch_pkgconfigdir=]pkg_default) -AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) -m4_popdef([pkg_default]) -m4_popdef([pkg_description]) -]) dnl PKG_NOARCH_INSTALLDIR - - -# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, -# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# ------------------------------------------- -# Retrieves the value of the pkg-config variable for the given module. -AC_DEFUN([PKG_CHECK_VAR], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl - -_PKG_CONFIG([$1], [variable="][$3]["], [$2]) -AS_VAR_COPY([$1], [pkg_cv_][$1]) - -AS_VAR_IF([$1], [""], [$5], [$4])dnl -])# PKG_CHECK_VAR From 5fdc5b08e7e27d9d1d805cea074232b1c7f05d47 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Wed, 21 Jan 2015 15:48:27 +0800 Subject: [PATCH 0201/2337] depends: latest config.guess and config.sub --- depends/config.guess | 15 ++++++++------- depends/config.sub | 25 +++++++++++++++++++------ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/depends/config.guess b/depends/config.guess index 1f5c50c0d15..dbfb9786cb6 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2014-03-23' +timestamp='2015-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -24,12 +24,12 @@ timestamp='2014-03-23' # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # -# Originally written by Per Bothner. +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -579,8 +579,9 @@ EOF else IBM_ARCH=powerpc fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi diff --git a/depends/config.sub b/depends/config.sub index d654d03cdcd..6d2e94c8bf9 100755 --- a/depends/config.sub +++ b/depends/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2014-05-01' +timestamp='2015-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -25,7 +25,7 @@ timestamp='2014-05-01' # of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -68,7 +68,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -260,7 +260,7 @@ case $basic_machine in | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ - | fido | fr30 | frv \ + | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ @@ -302,6 +302,7 @@ case $basic_machine in | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ + | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ @@ -312,6 +313,7 @@ case $basic_machine in | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -326,6 +328,9 @@ case $basic_machine in c6x) basic_machine=tic6x-unknown ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none @@ -436,6 +441,7 @@ case $basic_machine in | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ + | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -773,6 +779,9 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; m68knommu) basic_machine=m68k-unknown os=-linux @@ -828,6 +837,10 @@ case $basic_machine in basic_machine=powerpc-unknown os=-morphos ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; msdos) basic_machine=i386-pc os=-msdos @@ -1373,7 +1386,7 @@ case $os in | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ From 6bbca99baa50eee50d1559335a66f1b2189d456d Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 21 Jan 2015 07:49:14 +0100 Subject: [PATCH 0202/2337] LSSharedFileListItemResolve() was deprecated in Mac OS X 10.10, use LSSharedFileListItemCopyResolvedURL() instead --- src/qt/guiutil.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index c675235cc26..149e0da4421 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -696,7 +696,18 @@ LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i); UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes; CFURLRef currentItemURL = NULL; - LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL); + +#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 10100 + if(&LSSharedFileListItemCopyResolvedURL) + currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, NULL); +#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 10100 + else + LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL); +#endif +#else + LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL); +#endif + if(currentItemURL && CFEqual(currentItemURL, findUrl)) { // found CFRelease(currentItemURL); From 0eade74c783f670cb69ab982f5a828f7ff5ee0db Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Fri, 23 Jan 2015 20:01:07 +0600 Subject: [PATCH 0203/2337] fix crash: CoinControl "space" bug Just like https://github.com/novacoin-project/novacoin/commit/baf80c26a2e7f1ba6061d63d174eff0a09111e6f --- src/qt/coincontroltreewidget.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp index 6cbcf7128d8..5dcbf0c3f17 100644 --- a/src/qt/coincontroltreewidget.cpp +++ b/src/qt/coincontroltreewidget.cpp @@ -17,7 +17,8 @@ void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event) { event->ignore(); int COLUMN_CHECKBOX = 0; - this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked)); + if(this->currentItem()) + this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked)); } else if (event->key() == Qt::Key_Escape) // press esc -> close dialog { @@ -29,4 +30,4 @@ void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event) { this->QTreeWidget::keyPressEvent(event); } -} \ No newline at end of file +} From e5d9d77df2de715d24638e3bab78750b7ad3e1fd Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sun, 25 Jan 2015 18:11:57 +0600 Subject: [PATCH 0204/2337] fix crash: createmultisig and addmultisigaddress --- src/rpcmisc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 184aacf5a88..c54b92cc962 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -216,6 +216,8 @@ CScript _createmultisig_redeemScript(const Array& params) throw runtime_error( strprintf("not enough keys supplied " "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired)); + if (keys.size() > 16) + throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number"); std::vector pubkeys; pubkeys.resize(keys.size()); for (unsigned int i = 0; i < keys.size(); i++) From 14d023f1aeb4f25ac0f42745b3a29c3dcd63c834 Mon Sep 17 00:00:00 2001 From: Earlz Date: Sun, 25 Jan 2015 10:27:54 -0500 Subject: [PATCH 0205/2337] change hardcoded character constants to a set of descriptive named constants for database keys --- src/txdb.cpp | 53 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 4467cdce707..f9326e5e2ea 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -14,31 +14,42 @@ using namespace std; +static const char DB_COINS = 'c'; +static const char DB_BLOCK_FILES = 'f'; +static const char DB_TXINDEX = 't'; +static const char DB_BLOCK_INDEX = 'b'; + +static const char DB_BEST_BLOCK = 'B'; +static const char DB_FLAG = 'F'; +static const char DB_REINDEX_FLAG = 'R'; +static const char DB_LAST_BLOCK = 'l'; + + void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) { if (coins.IsPruned()) - batch.Erase(make_pair('c', hash)); + batch.Erase(make_pair(DB_COINS, hash)); else - batch.Write(make_pair('c', hash), coins); + batch.Write(make_pair(DB_COINS, hash), coins); } void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) { - batch.Write('B', hash); + batch.Write(DB_BEST_BLOCK, hash); } CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) { } bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) const { - return db.Read(make_pair('c', txid), coins); + return db.Read(make_pair(DB_COINS, txid), coins); } bool CCoinsViewDB::HaveCoins(const uint256 &txid) const { - return db.Exists(make_pair('c', txid)); + return db.Exists(make_pair(DB_COINS, txid)); } uint256 CCoinsViewDB::GetBestBlock() const { uint256 hashBestChain; - if (!db.Read('B', hashBestChain)) + if (!db.Read(DB_BEST_BLOCK, hashBestChain)) return uint256(); return hashBestChain; } @@ -67,23 +78,23 @@ CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevel } bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { - return Read(make_pair('f', nFile), info); + return Read(make_pair(DB_BLOCK_FILES, nFile), info); } bool CBlockTreeDB::WriteReindexing(bool fReindexing) { if (fReindexing) - return Write('R', '1'); + return Write(DB_REINDEX_FLAG, '1'); else - return Erase('R'); + return Erase(DB_REINDEX_FLAG); } bool CBlockTreeDB::ReadReindexing(bool &fReindexing) { - fReindexing = Exists('R'); + fReindexing = Exists(DB_REINDEX_FLAG); return true; } bool CBlockTreeDB::ReadLastBlockFile(int &nFile) { - return Read('l', nFile); + return Read(DB_LAST_BLOCK, nFile); } bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { @@ -104,7 +115,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); char chType; ssKey >> chType; - if (chType == 'c') { + if (chType == DB_COINS) { leveldb::Slice slValue = pcursor->value(); CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); CCoins coins; @@ -142,33 +153,33 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { CLevelDBBatch batch; for (std::vector >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { - batch.Write(make_pair('f', it->first), *it->second); + batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second); } - batch.Write('l', nLastFile); + batch.Write(DB_LAST_BLOCK, nLastFile); for (std::vector::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { - batch.Write(make_pair('b', (*it)->GetBlockHash()), CDiskBlockIndex(*it)); + batch.Write(make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it)); } return WriteBatch(batch, true); } bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { - return Read(make_pair('t', txid), pos); + return Read(make_pair(DB_TXINDEX, txid), pos); } bool CBlockTreeDB::WriteTxIndex(const std::vector >&vect) { CLevelDBBatch batch; for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) - batch.Write(make_pair('t', it->first), it->second); + batch.Write(make_pair(DB_TXINDEX, it->first), it->second); return WriteBatch(batch); } bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) { - return Write(std::make_pair('F', name), fValue ? '1' : '0'); + return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0'); } bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { char ch; - if (!Read(std::make_pair('F', name), ch)) + if (!Read(std::make_pair(DB_FLAG, name), ch)) return false; fValue = ch == '1'; return true; @@ -179,7 +190,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() boost::scoped_ptr pcursor(NewIterator()); CDataStream ssKeySet(SER_DISK, CLIENT_VERSION); - ssKeySet << make_pair('b', uint256()); + ssKeySet << make_pair(DB_BLOCK_INDEX, uint256()); pcursor->Seek(ssKeySet.str()); // Load mapBlockIndex @@ -190,7 +201,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); char chType; ssKey >> chType; - if (chType == 'b') { + if (chType == DB_BLOCK_INDEX) { leveldb::Slice slValue = pcursor->value(); CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); CDiskBlockIndex diskindex; From 4401b2d7c52e0f3841225369fb0d10767c51aaa2 Mon Sep 17 00:00:00 2001 From: Eric Lombrozo Date: Sun, 19 Oct 2014 04:46:17 -0400 Subject: [PATCH 0206/2337] Removed main.h dependency from rpcserver.cpp Rebased by @laanwj: - update for RPC methods added since 84d13ee: setmocktime, invalidateblock, reconsiderblock. Only the first, setmocktime, required a change, the other two are thread safe. --- src/init.cpp | 22 ++++++++++++ src/rpcblockchain.cpp | 19 +++++++++++ src/rpcdump.cpp | 10 ++++++ src/rpcmining.cpp | 11 ++++-- src/rpcmisc.cpp | 16 +++++++++ src/rpcnet.cpp | 10 ++++-- src/rpcrawtransaction.cpp | 14 +++++++- src/rpcserver.cpp | 70 ++++++++++++++++++++++----------------- src/rpcserver.h | 10 ++++++ src/rpcwallet.cpp | 69 ++++++++++++++++++++++++++++++++++++-- src/sync.h | 11 ++++++ 11 files changed, 224 insertions(+), 38 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index aaa5f06c752..7054264c0bb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -234,6 +234,26 @@ bool static Bind(const CService &addr, unsigned int flags) { return true; } +void OnRPCStopped() +{ + cvBlockChange.notify_all(); + LogPrint("rpc", "RPC stopped.\n"); +} + +void OnRPCPreCommand(const CRPCCommand& cmd) +{ +#ifdef ENABLE_WALLET + if (cmd.reqWallet && !pwalletMain) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); +#endif + + // Observe safe mode + string strWarning = GetWarnings("rpc"); + if (strWarning != "" && !GetBoolArg("-disablesafemode", false) && + !cmd.okSafeMode) + throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); +} + std::string HelpMessage(HelpMessageMode mode) { // When adding new options to the categories, please keep and ensure alphabetical ordering. @@ -802,6 +822,8 @@ bool AppInit2(boost::thread_group& threadGroup) if (fServer) { uiInterface.InitMessage.connect(SetRPCWarmupStatus); + RPCServer::OnStopped(&OnRPCStopped); + RPCServer::OnPreCommand(&OnRPCPreCommand); StartRPCThreads(); } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index cfc559d1986..293d6d5619a 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -105,6 +105,7 @@ Value getblockcount(const Array& params, bool fHelp) + HelpExampleRpc("getblockcount", "") ); + LOCK(cs_main); return chainActive.Height(); } @@ -121,6 +122,7 @@ Value getbestblockhash(const Array& params, bool fHelp) + HelpExampleRpc("getbestblockhash", "") ); + LOCK(cs_main); return chainActive.Tip()->GetBlockHash().GetHex(); } @@ -137,6 +139,7 @@ Value getdifficulty(const Array& params, bool fHelp) + HelpExampleRpc("getdifficulty", "") ); + LOCK(cs_main); return GetDifficulty(); } @@ -173,6 +176,8 @@ Value getrawmempool(const Array& params, bool fHelp) + HelpExampleRpc("getrawmempool", "true") ); + LOCK(cs_main); + bool fVerbose = false; if (params.size() > 0) fVerbose = params[0].get_bool(); @@ -233,6 +238,8 @@ Value getblockhash(const Array& params, bool fHelp) + HelpExampleRpc("getblockhash", "1000") ); + LOCK(cs_main); + int nHeight = params[0].get_int(); if (nHeight < 0 || nHeight > chainActive.Height()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); @@ -277,6 +284,8 @@ Value getblock(const Array& params, bool fHelp) + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") ); + LOCK(cs_main); + std::string strHash = params[0].get_str(); uint256 hash(uint256S(strHash)); @@ -326,6 +335,8 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) + HelpExampleRpc("gettxoutsetinfo", "") ); + LOCK(cs_main); + Object ret; CCoinsStats stats; @@ -380,6 +391,8 @@ Value gettxout(const Array& params, bool fHelp) + HelpExampleRpc("gettxout", "\"txid\", 1") ); + LOCK(cs_main); + Object ret; std::string strHash = params[0].get_str(); @@ -436,6 +449,8 @@ Value verifychain(const Array& params, bool fHelp) + HelpExampleRpc("verifychain", "") ); + LOCK(cs_main); + int nCheckLevel = GetArg("-checklevel", 3); int nCheckDepth = GetArg("-checkblocks", 288); if (params.size() > 0) @@ -467,6 +482,8 @@ Value getblockchaininfo(const Array& params, bool fHelp) + HelpExampleRpc("getblockchaininfo", "") ); + LOCK(cs_main); + Object obj; obj.push_back(Pair("chain", Params().NetworkIDString())); obj.push_back(Pair("blocks", (int)chainActive.Height())); @@ -526,6 +543,8 @@ Value getchaintips(const Array& params, bool fHelp) + HelpExampleRpc("getchaintips", "") ); + LOCK(cs_main); + /* Build up a list of chain tips. We start with the list of all known blocks, and successively remove blocks that appear as pprev of another block. */ diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 8666779cc16..b9c92a06c5d 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -91,6 +91,8 @@ Value importprivkey(const Array& params, bool fHelp) + HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + EnsureWalletIsUnlocked(); string strSecret = params[0].get_str(); @@ -158,6 +160,8 @@ Value importaddress(const Array& params, bool fHelp) + HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + CScript script; CBitcoinAddress address(params[0].get_str()); @@ -223,6 +227,8 @@ Value importwallet(const Array& params, bool fHelp) + HelpExampleRpc("importwallet", "\"test\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + EnsureWalletIsUnlocked(); ifstream file; @@ -322,6 +328,8 @@ Value dumpprivkey(const Array& params, bool fHelp) + HelpExampleRpc("dumpprivkey", "\"myaddress\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + EnsureWalletIsUnlocked(); string strAddress = params[0].get_str(); @@ -351,6 +359,8 @@ Value dumpwallet(const Array& params, bool fHelp) + HelpExampleRpc("dumpwallet", "\"test\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + EnsureWalletIsUnlocked(); ofstream file; diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 5df5de66d94..369b3fb4d78 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -88,6 +88,7 @@ Value getnetworkhashps(const Array& params, bool fHelp) + HelpExampleRpc("getnetworkhashps", "") ); + LOCK(cs_main); return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); } @@ -107,6 +108,7 @@ Value getgenerate(const Array& params, bool fHelp) + HelpExampleRpc("getgenerate", "") ); + LOCK(cs_main); return GetBoolArg("-gen", false); } @@ -200,7 +202,6 @@ Value setgenerate(const Array& params, bool fHelp) return Value::null; } - #endif @@ -228,6 +229,9 @@ Value getmininginfo(const Array& params, bool fHelp) + HelpExampleRpc("getmininginfo", "") ); + + LOCK(cs_main); + Object obj; obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); @@ -268,8 +272,9 @@ Value prioritisetransaction(const Array& params, bool fHelp) + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000") ); - uint256 hash = ParseHashStr(params[0].get_str(), "txid"); + LOCK(cs_main); + uint256 hash = ParseHashStr(params[0].get_str(), "txid"); CAmount nAmount = params[2].get_int64(); mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount); @@ -358,6 +363,8 @@ Value getblocktemplate(const Array& params, bool fHelp) + HelpExampleRpc("getblocktemplate", "") ); + LOCK(cs_main); + std::string strMode = "template"; Value lpval = Value::null; if (params.size() > 0) diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 3d647a0d2d1..8d260b1cc9b 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -69,6 +69,12 @@ Value getinfo(const Array& params, bool fHelp) + HelpExampleRpc("getinfo", "") ); +#ifdef ENABLE_WALLET + LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); +#else + LOCK(cs_main); +#endif + proxyType proxy; GetProxy(NET_IPV4, proxy); @@ -172,6 +178,12 @@ Value validateaddress(const Array& params, bool fHelp) + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"") ); +#ifdef ENABLE_WALLET + LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); +#else + LOCK(cs_main); +#endif + CBitcoinAddress address(params[0].get_str()); bool isValid = address.IsValid(); @@ -329,6 +341,8 @@ Value verifymessage(const Array& params, bool fHelp) + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"") ); + LOCK(cs_main); + string strAddress = params[0].get_str(); string strSign = params[1].get_str(); string strMessage = params[2].get_str(); @@ -372,6 +386,8 @@ Value setmocktime(const Array& params, bool fHelp) if (!Params().MineBlocksOnDemand()) throw runtime_error("setmocktime for regression testing (-regtest mode) only"); + LOCK(cs_main); + RPCTypeCheck(params, boost::assign::list_of(int_type)); SetMockTime(params[0].get_int64()); diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index f0fadb59879..6306fd44060 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -34,7 +34,8 @@ Value getconnectioncount(const Array& params, bool fHelp) + HelpExampleRpc("getconnectioncount", "") ); - LOCK(cs_vNodes); + LOCK2(cs_main, cs_vNodes); + return (int)vNodes.size(); } @@ -52,7 +53,8 @@ Value ping(const Array& params, bool fHelp) ); // Request that each node send a ping during next message processing pass - LOCK(cs_vNodes); + LOCK2(cs_main, cs_vNodes); + BOOST_FOREACH(CNode* pNode, vNodes) { pNode->fPingQueued = true; } @@ -113,6 +115,8 @@ Value getpeerinfo(const Array& params, bool fHelp) + HelpExampleRpc("getpeerinfo", "") ); + LOCK(cs_main); + vector vstats; CopyNodeStats(vstats); @@ -411,6 +415,8 @@ Value getnetworkinfo(const Array& params, bool fHelp) + HelpExampleRpc("getnetworkinfo", "") ); + LOCK(cs_main); + Object obj; obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("subversion", diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 2b108bf5888..0859c0e6113 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -169,6 +169,8 @@ Value getrawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1") ); + LOCK(cs_main); + uint256 hash = ParseHashV(params[0], "parameter 1"); bool fVerbose = false; @@ -256,6 +258,7 @@ Value listunspent(const Array& params, bool fHelp) Array results; vector vecOutputs; assert(pwalletMain != NULL); + LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->AvailableCoins(vecOutputs, false); BOOST_FOREACH(const COutput& out, vecOutputs) { if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) @@ -334,6 +337,7 @@ Value createrawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"") ); + LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type)); Array inputs = params[0].get_array(); @@ -428,6 +432,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("decoderawtransaction", "\"hexstring\"") ); + LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(str_type)); CTransaction tx; @@ -466,6 +471,7 @@ Value decodescript(const Array& params, bool fHelp) + HelpExampleRpc("decodescript", "\"hexstring\"") ); + LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(str_type)); Object r; @@ -532,6 +538,11 @@ Value signrawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("signrawtransaction", "\"myhex\"") ); +#ifdef ENABLE_WALLET + LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); +#else + LOCK(cs_main); +#endif RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true); vector txData(ParseHexV(params[0], "argument 1")); @@ -591,7 +602,7 @@ Value signrawtransaction(const Array& params, bool fHelp) } } #ifdef ENABLE_WALLET - else + else if (pwalletMain) EnsureWalletIsUnlocked(); #endif @@ -722,6 +733,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("sendrawtransaction", "\"signedhex\"") ); + LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type)); // parse hex string from parameter diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index e4f23d56d24..f5f8bb22a26 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -7,9 +7,11 @@ #include "base58.h" #include "init.h" -#include "main.h" +#include "random.h" +#include "sync.h" #include "ui_interface.h" #include "util.h" +#include "utilstrencodings.h" #ifdef ENABLE_WALLET #include "wallet.h" #endif @@ -23,11 +25,13 @@ #include #include #include +#include #include #include "json/json_spirit_writer_template.h" using namespace boost::asio; using namespace json_spirit; +using namespace RPCServer; using namespace std; static std::string strRPCUserColonPass; @@ -46,6 +50,34 @@ static boost::asio::io_service::work *rpc_dummy_work = NULL; static std::vector rpc_allow_subnets; //!< List of subnets to allow RPC connections from static std::vector< boost::shared_ptr > rpc_acceptors; +static struct CRPCSignals +{ + boost::signals2::signal Started; + boost::signals2::signal Stopped; + boost::signals2::signal PreCommand; + boost::signals2::signal PostCommand; +} g_rpcSignals; + +void RPCServer::OnStarted(boost::function slot) +{ + g_rpcSignals.Started.connect(slot); +} + +void RPCServer::OnStopped(boost::function slot) +{ + g_rpcSignals.Stopped.connect(slot); +} + +void RPCServer::OnPreCommand(boost::function slot) +{ + g_rpcSignals.PreCommand.connect(boost::bind(slot, _1)); +} + +void RPCServer::OnPostCommand(boost::function slot) +{ + g_rpcSignals.PostCommand.connect(boost::bind(slot, _1)); +} + void RPCTypeCheck(const Array& params, const list& typesExpected, bool fAllowNull) @@ -693,6 +725,7 @@ void StartRPCThreads() for (int i = 0; i < GetArg("-rpcthreads", 4); i++) rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service)); fRPCRunning = true; + g_rpcSignals.Started(); } void StartDummyRPCThread() @@ -735,7 +768,7 @@ void StopRPCThreads() deadlineTimers.clear(); rpc_io_service->stop(); - cvBlockChange.notify_all(); + g_rpcSignals.Stopped(); if (rpc_worker_group != NULL) rpc_worker_group->join_all(); delete rpc_dummy_work; rpc_dummy_work = NULL; @@ -978,45 +1011,20 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s const CRPCCommand *pcmd = tableRPC[strMethod]; if (!pcmd) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); -#ifdef ENABLE_WALLET - if (pcmd->reqWallet && !pwalletMain) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); -#endif - // Observe safe mode - string strWarning = GetWarnings("rpc"); - if (strWarning != "" && !GetBoolArg("-disablesafemode", false) && - !pcmd->okSafeMode) - throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); + g_rpcSignals.PreCommand(*pcmd); try { // Execute - Value result; - { - if (pcmd->threadSafe) - result = pcmd->actor(params, false); -#ifdef ENABLE_WALLET - else if (!pwalletMain) { - LOCK(cs_main); - result = pcmd->actor(params, false); - } else { - LOCK2(cs_main, pwalletMain->cs_wallet); - result = pcmd->actor(params, false); - } -#else // ENABLE_WALLET - else { - LOCK(cs_main); - result = pcmd->actor(params, false); - } -#endif // !ENABLE_WALLET - } - return result; + return pcmd->actor(params, false); } catch (const std::exception& e) { throw JSONRPCError(RPC_MISC_ERROR, e.what()); } + + g_rpcSignals.PostCommand(*pcmd); } std::string HelpExampleCli(string methodname, string args){ diff --git a/src/rpcserver.h b/src/rpcserver.h index 1b94b758f24..41cd9da160e 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -19,6 +19,16 @@ #include "json/json_spirit_utils.h" #include "json/json_spirit_writer_template.h" +class CRPCCommand; + +namespace RPCServer +{ + void OnStarted(boost::function slot); + void OnStopped(boost::function slot); + void OnPreCommand(boost::function slot); + void OnPostCommand(boost::function slot); +} + class CBlockIndex; class CNetAddr; diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 6ad3ee54d56..338b648503f 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -90,6 +90,8 @@ Value getnewaddress(const Array& params, bool fHelp) + HelpExampleRpc("getnewaddress", "") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + // Parse the account first so we don't generate a key if there's an error string strAccount; if (params.size() > 0) @@ -164,13 +166,14 @@ Value getaccountaddress(const Array& params, bool fHelp) + HelpExampleRpc("getaccountaddress", "\"myaccount\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + // Parse the account first so we don't generate a key if there's an error string strAccount = AccountFromValue(params[0]); Value ret; ret = GetAccountAddress(strAccount).ToString(); - return ret; } @@ -189,6 +192,8 @@ Value getrawchangeaddress(const Array& params, bool fHelp) + HelpExampleRpc("getrawchangeaddress", "") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + if (!pwalletMain->IsLocked()) pwalletMain->TopUpKeyPool(); @@ -219,11 +224,12 @@ Value setaccount(const Array& params, bool fHelp) + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + CBitcoinAddress address(params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); - string strAccount; if (params.size() > 1) strAccount = AccountFromValue(params[1]); @@ -262,6 +268,8 @@ Value getaccount(const Array& params, bool fHelp) + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + CBitcoinAddress address(params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); @@ -292,6 +300,8 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + string strAccount = AccountFromValue(params[0]); // Find all addresses that have the given account @@ -363,6 +373,8 @@ Value sendtoaddress(const Array& params, bool fHelp) + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + CBitcoinAddress address(params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); @@ -409,6 +421,8 @@ Value listaddressgroupings(const Array& params, bool fHelp) + HelpExampleRpc("listaddressgroupings", "") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + Array jsonGroupings; map balances = pwalletMain->GetAddressBalances(); BOOST_FOREACH(set grouping, pwalletMain->GetAddressGroupings()) @@ -454,6 +468,8 @@ Value signmessage(const Array& params, bool fHelp) + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + EnsureWalletIsUnlocked(); string strAddress = params[0].get_str(); @@ -504,6 +520,8 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + // Bitcoin address CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); if (!address.IsValid()) @@ -557,6 +575,8 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + // Minimum confirmations int nMinDepth = 1; if (params.size() > 1) @@ -643,6 +663,8 @@ Value getbalance(const Array& params, bool fHelp) + HelpExampleRpc("getbalance", "\"*\", 6") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + if (params.size() == 0) return ValueFromAmount(pwalletMain->GetBalance()); @@ -695,6 +717,9 @@ Value getunconfirmedbalance(const Array ¶ms, bool fHelp) throw runtime_error( "getunconfirmedbalance\n" "Returns the server's total unconfirmed balance\n"); + + LOCK2(cs_main, pwalletMain->cs_wallet); + return ValueFromAmount(pwalletMain->GetUnconfirmedBalance()); } @@ -721,6 +746,8 @@ Value movecmd(const Array& params, bool fHelp) + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + string strFrom = AccountFromValue(params[0]); string strTo = AccountFromValue(params[1]); CAmount nAmount = AmountFromValue(params[2]); @@ -793,6 +820,8 @@ Value sendfrom(const Array& params, bool fHelp) + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + string strAccount = AccountFromValue(params[0]); CBitcoinAddress address(params[1].get_str()); if (!address.IsValid()) @@ -850,6 +879,8 @@ Value sendmany(const Array& params, bool fHelp) + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + string strAccount = AccountFromValue(params[0]); Object sendTo = params[1].get_obj(); int nMinDepth = 1; @@ -935,6 +966,8 @@ Value addmultisigaddress(const Array& params, bool fHelp) throw runtime_error(msg); } + LOCK2(cs_main, pwalletMain->cs_wallet); + string strAccount; if (params.size() > 2) strAccount = AccountFromValue(params[2]); @@ -1110,6 +1143,8 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) + HelpExampleRpc("listreceivedbyaddress", "6, true, true") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + return ListReceived(params, false); } @@ -1141,6 +1176,8 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) + HelpExampleRpc("listreceivedbyaccount", "6, true, true") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + return ListReceived(params, true); } @@ -1292,6 +1329,8 @@ Value listtransactions(const Array& params, bool fHelp) + HelpExampleRpc("listtransactions", "\"*\", 20, 100") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + string strAccount = "*"; if (params.size() > 0) strAccount = params[0].get_str(); @@ -1372,6 +1411,8 @@ Value listaccounts(const Array& params, bool fHelp) + HelpExampleRpc("listaccounts", "6") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + int nMinDepth = 1; if (params.size() > 0) nMinDepth = params[0].get_int(); @@ -1460,6 +1501,8 @@ Value listsinceblock(const Array& params, bool fHelp) + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + CBlockIndex *pindex = NULL; int target_confirms = 1; isminefilter filter = ISMINE_SPENDABLE; @@ -1546,6 +1589,8 @@ Value gettransaction(const Array& params, bool fHelp) + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + uint256 hash; hash.SetHex(params[0].get_str()); @@ -1594,6 +1639,8 @@ Value backupwallet(const Array& params, bool fHelp) + HelpExampleRpc("backupwallet", "\"backup.dat\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + string strDest = params[0].get_str(); if (!BackupWallet(*pwalletMain, strDest)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); @@ -1616,6 +1663,8 @@ Value keypoolrefill(const Array& params, bool fHelp) + HelpExampleRpc("keypoolrefill", "") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool unsigned int kpSize = 0; if (params.size() > 0) { @@ -1663,6 +1712,8 @@ Value walletpassphrase(const Array& params, bool fHelp) + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + if (fHelp) return true; if (!pwalletMain->IsCrypted()) @@ -1710,6 +1761,8 @@ Value walletpassphrasechange(const Array& params, bool fHelp) + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + if (fHelp) return true; if (!pwalletMain->IsCrypted()) @@ -1756,6 +1809,8 @@ Value walletlock(const Array& params, bool fHelp) + HelpExampleRpc("walletlock", "") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + if (fHelp) return true; if (!pwalletMain->IsCrypted()) @@ -1797,6 +1852,8 @@ Value encryptwallet(const Array& params, bool fHelp) + HelpExampleRpc("encryptwallet", "\"my pass phrase\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + if (fHelp) return true; if (pwalletMain->IsCrypted()) @@ -1861,6 +1918,8 @@ Value lockunspent(const Array& params, bool fHelp) + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + if (params.size() == 1) RPCTypeCheck(params, boost::assign::list_of(bool_type)); else @@ -1930,6 +1989,8 @@ Value listlockunspent(const Array& params, bool fHelp) + HelpExampleRpc("listlockunspent", "") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + vector vOutpts; pwalletMain->ListLockedCoins(vOutpts); @@ -1961,6 +2022,8 @@ Value settxfee(const Array& params, bool fHelp) + HelpExampleRpc("settxfee", "0.00001") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + // Amount CAmount nAmount = 0; if (params[0].get_real() != 0.0) @@ -1992,6 +2055,8 @@ Value getwalletinfo(const Array& params, bool fHelp) + HelpExampleRpc("getwalletinfo", "") ); + LOCK2(cs_main, pwalletMain->cs_wallet); + Object obj; obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); diff --git a/src/sync.h b/src/sync.h index 7891e415605..27e80e813b7 100644 --- a/src/sync.h +++ b/src/sync.h @@ -142,6 +142,17 @@ public: Enter(pszName, pszFile, nLine); } + CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) + { + if (!pmutexIn) return; + + lock = boost::unique_lock(*pmutexIn, boost::defer_lock); + if (fTry) + TryEnter(pszName, pszFile, nLine); + else + Enter(pszName, pszFile, nLine); + } + ~CMutexLock() { if (lock.owns_lock()) From 5ebe0956b391cfa782fd97bb417d20b479df6a36 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 26 Jan 2015 13:52:12 +0100 Subject: [PATCH 0207/2337] Trim RPC command table - invalidateblock and reconsiderblock were defined doubly - remove no-longer-used threadSafe, as locks have been pushed down --- src/rpcserver.cpp | 170 +++++++++++++++++++++++----------------------- src/rpcserver.h | 1 - 2 files changed, 84 insertions(+), 87 deletions(-) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index f5f8bb22a26..823b1fcf240 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -271,112 +271,110 @@ Value stop(const Array& params, bool fHelp) * Call Table */ static const CRPCCommand vRPCCommands[] = -{ // category name actor (function) okSafeMode threadSafe reqWallet - // --------------------- ------------------------ ----------------------- ---------- ---------- --------- +{ // category name actor (function) okSafeMode reqWallet + // --------------------- ------------------------ ----------------------- ---------- --------- /* Overall control/query calls */ - { "control", "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */ - { "control", "help", &help, true, true, false }, - { "control", "stop", &stop, true, true, false }, + { "control", "getinfo", &getinfo, true, false }, /* uses wallet if enabled */ + { "control", "help", &help, true, false }, + { "control", "stop", &stop, true, false }, /* P2P networking */ - { "network", "getnetworkinfo", &getnetworkinfo, true, false, false }, - { "network", "addnode", &addnode, true, true, false }, - { "network", "getaddednodeinfo", &getaddednodeinfo, true, true, false }, - { "network", "getconnectioncount", &getconnectioncount, true, false, false }, - { "network", "getnettotals", &getnettotals, true, true, false }, - { "network", "getpeerinfo", &getpeerinfo, true, false, false }, - { "network", "ping", &ping, true, false, false }, + { "network", "getnetworkinfo", &getnetworkinfo, true, false }, + { "network", "addnode", &addnode, true, false }, + { "network", "getaddednodeinfo", &getaddednodeinfo, true, false }, + { "network", "getconnectioncount", &getconnectioncount, true, false }, + { "network", "getnettotals", &getnettotals, true, false }, + { "network", "getpeerinfo", &getpeerinfo, true, false }, + { "network", "ping", &ping, true, false }, /* Block chain and UTXO */ - { "blockchain", "getblockchaininfo", &getblockchaininfo, true, false, false }, - { "blockchain", "getbestblockhash", &getbestblockhash, true, false, false }, - { "blockchain", "getblockcount", &getblockcount, true, false, false }, - { "blockchain", "getblock", &getblock, true, false, false }, - { "blockchain", "getblockhash", &getblockhash, true, false, false }, - { "blockchain", "getchaintips", &getchaintips, true, false, false }, - { "blockchain", "getdifficulty", &getdifficulty, true, false, false }, - { "blockchain", "getmempoolinfo", &getmempoolinfo, true, true, false }, - { "blockchain", "getrawmempool", &getrawmempool, true, false, false }, - { "blockchain", "gettxout", &gettxout, true, false, false }, - { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false, false }, - { "blockchain", "verifychain", &verifychain, true, false, false }, - { "blockchain", "invalidateblock", &invalidateblock, true, true, false }, - { "blockchain", "reconsiderblock", &reconsiderblock, true, true, false }, + { "blockchain", "getblockchaininfo", &getblockchaininfo, true, false }, + { "blockchain", "getbestblockhash", &getbestblockhash, true, false }, + { "blockchain", "getblockcount", &getblockcount, true, false }, + { "blockchain", "getblock", &getblock, true, false }, + { "blockchain", "getblockhash", &getblockhash, true, false }, + { "blockchain", "getchaintips", &getchaintips, true, false }, + { "blockchain", "getdifficulty", &getdifficulty, true, false }, + { "blockchain", "getmempoolinfo", &getmempoolinfo, true, false }, + { "blockchain", "getrawmempool", &getrawmempool, true, false }, + { "blockchain", "gettxout", &gettxout, true, false }, + { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false }, + { "blockchain", "verifychain", &verifychain, true, false }, /* Mining */ - { "mining", "getblocktemplate", &getblocktemplate, true, false, false }, - { "mining", "getmininginfo", &getmininginfo, true, false, false }, - { "mining", "getnetworkhashps", &getnetworkhashps, true, false, false }, - { "mining", "prioritisetransaction", &prioritisetransaction, true, false, false }, - { "mining", "submitblock", &submitblock, true, true, false }, + { "mining", "getblocktemplate", &getblocktemplate, true, false }, + { "mining", "getmininginfo", &getmininginfo, true, false }, + { "mining", "getnetworkhashps", &getnetworkhashps, true, false }, + { "mining", "prioritisetransaction", &prioritisetransaction, true, false }, + { "mining", "submitblock", &submitblock, true, false }, #ifdef ENABLE_WALLET /* Coin generation */ - { "generating", "getgenerate", &getgenerate, true, false, false }, - { "generating", "setgenerate", &setgenerate, true, true, false }, + { "generating", "getgenerate", &getgenerate, true, false }, + { "generating", "setgenerate", &setgenerate, true, false }, #endif /* Raw transactions */ - { "rawtransactions", "createrawtransaction", &createrawtransaction, true, false, false }, - { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false, false }, - { "rawtransactions", "decodescript", &decodescript, true, false, false }, - { "rawtransactions", "getrawtransaction", &getrawtransaction, true, false, false }, - { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false, false }, - { "rawtransactions", "signrawtransaction", &signrawtransaction, false, false, false }, /* uses wallet if enabled */ + { "rawtransactions", "createrawtransaction", &createrawtransaction, true, false }, + { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false }, + { "rawtransactions", "decodescript", &decodescript, true, false }, + { "rawtransactions", "getrawtransaction", &getrawtransaction, true, false }, + { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false }, + { "rawtransactions", "signrawtransaction", &signrawtransaction, false, false }, /* uses wallet if enabled */ /* Utility functions */ - { "util", "createmultisig", &createmultisig, true, true , false }, - { "util", "validateaddress", &validateaddress, true, false, false }, /* uses wallet if enabled */ - { "util", "verifymessage", &verifymessage, true, false, false }, - { "util", "estimatefee", &estimatefee, true, true, false }, - { "util", "estimatepriority", &estimatepriority, true, true, false }, + { "util", "createmultisig", &createmultisig, true, false }, + { "util", "validateaddress", &validateaddress, true, false }, /* uses wallet if enabled */ + { "util", "verifymessage", &verifymessage, true, false }, + { "util", "estimatefee", &estimatefee, true, false }, + { "util", "estimatepriority", &estimatepriority, true, false }, /* Not shown in help */ - { "hidden", "invalidateblock", &invalidateblock, true, true, false }, - { "hidden", "reconsiderblock", &reconsiderblock, true, true, false }, - { "hidden", "setmocktime", &setmocktime, true, false, false }, + { "hidden", "invalidateblock", &invalidateblock, true, false }, + { "hidden", "reconsiderblock", &reconsiderblock, true, false }, + { "hidden", "setmocktime", &setmocktime, true, false }, #ifdef ENABLE_WALLET /* Wallet */ - { "wallet", "addmultisigaddress", &addmultisigaddress, true, false, true }, - { "wallet", "backupwallet", &backupwallet, true, false, true }, - { "wallet", "dumpprivkey", &dumpprivkey, true, false, true }, - { "wallet", "dumpwallet", &dumpwallet, true, false, true }, - { "wallet", "encryptwallet", &encryptwallet, true, false, true }, - { "wallet", "getaccountaddress", &getaccountaddress, true, false, true }, - { "wallet", "getaccount", &getaccount, true, false, true }, - { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, false, true }, - { "wallet", "getbalance", &getbalance, false, false, true }, - { "wallet", "getnewaddress", &getnewaddress, true, false, true }, - { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, false, true }, - { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, false, true }, - { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, false, true }, - { "wallet", "gettransaction", &gettransaction, false, false, true }, - { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, false, true }, - { "wallet", "getwalletinfo", &getwalletinfo, false, false, true }, - { "wallet", "importprivkey", &importprivkey, true, false, true }, - { "wallet", "importwallet", &importwallet, true, false, true }, - { "wallet", "importaddress", &importaddress, true, false, true }, - { "wallet", "keypoolrefill", &keypoolrefill, true, false, true }, - { "wallet", "listaccounts", &listaccounts, false, false, true }, - { "wallet", "listaddressgroupings", &listaddressgroupings, false, false, true }, - { "wallet", "listlockunspent", &listlockunspent, false, false, true }, - { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, false, true }, - { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, false, true }, - { "wallet", "listsinceblock", &listsinceblock, false, false, true }, - { "wallet", "listtransactions", &listtransactions, false, false, true }, - { "wallet", "listunspent", &listunspent, false, false, true }, - { "wallet", "lockunspent", &lockunspent, true, false, true }, - { "wallet", "move", &movecmd, false, false, true }, - { "wallet", "sendfrom", &sendfrom, false, false, true }, - { "wallet", "sendmany", &sendmany, false, false, true }, - { "wallet", "sendtoaddress", &sendtoaddress, false, false, true }, - { "wallet", "setaccount", &setaccount, true, false, true }, - { "wallet", "settxfee", &settxfee, true, false, true }, - { "wallet", "signmessage", &signmessage, true, false, true }, - { "wallet", "walletlock", &walletlock, true, false, true }, - { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, false, true }, - { "wallet", "walletpassphrase", &walletpassphrase, true, false, true }, + { "wallet", "addmultisigaddress", &addmultisigaddress, true, true }, + { "wallet", "backupwallet", &backupwallet, true, true }, + { "wallet", "dumpprivkey", &dumpprivkey, true, true }, + { "wallet", "dumpwallet", &dumpwallet, true, true }, + { "wallet", "encryptwallet", &encryptwallet, true, true }, + { "wallet", "getaccountaddress", &getaccountaddress, true, true }, + { "wallet", "getaccount", &getaccount, true, true }, + { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, true }, + { "wallet", "getbalance", &getbalance, false, true }, + { "wallet", "getnewaddress", &getnewaddress, true, true }, + { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, true }, + { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, true }, + { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, true }, + { "wallet", "gettransaction", &gettransaction, false, true }, + { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, true }, + { "wallet", "getwalletinfo", &getwalletinfo, false, true }, + { "wallet", "importprivkey", &importprivkey, true, true }, + { "wallet", "importwallet", &importwallet, true, true }, + { "wallet", "importaddress", &importaddress, true, true }, + { "wallet", "keypoolrefill", &keypoolrefill, true, true }, + { "wallet", "listaccounts", &listaccounts, false, true }, + { "wallet", "listaddressgroupings", &listaddressgroupings, false, true }, + { "wallet", "listlockunspent", &listlockunspent, false, true }, + { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, true }, + { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, true }, + { "wallet", "listsinceblock", &listsinceblock, false, true }, + { "wallet", "listtransactions", &listtransactions, false, true }, + { "wallet", "listunspent", &listunspent, false, true }, + { "wallet", "lockunspent", &lockunspent, true, true }, + { "wallet", "move", &movecmd, false, true }, + { "wallet", "sendfrom", &sendfrom, false, true }, + { "wallet", "sendmany", &sendmany, false, true }, + { "wallet", "sendtoaddress", &sendtoaddress, false, true }, + { "wallet", "setaccount", &setaccount, true, true }, + { "wallet", "settxfee", &settxfee, true, true }, + { "wallet", "signmessage", &signmessage, true, true }, + { "wallet", "walletlock", &walletlock, true, true }, + { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, true }, + { "wallet", "walletpassphrase", &walletpassphrase, true, true }, #endif // ENABLE_WALLET }; diff --git a/src/rpcserver.h b/src/rpcserver.h index 41cd9da160e..f63438ecb88 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -98,7 +98,6 @@ public: std::string name; rpcfn_type actor; bool okSafeMode; - bool threadSafe; bool reqWallet; }; From 55eade9d46ebfa4b32b79893595d91d529fa30bb Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 29 Jan 2015 01:25:11 +0600 Subject: [PATCH 0208/2337] Change Coin Control first column label --- src/qt/coincontroldialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index f597eeeaf39..3f4f082b8cc 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -117,6 +117,10 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) : // (un)select all connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked())); + // change coin control first column label due Qt4 bug. + // see https://github.com/bitcoin/bitcoin/issues/5716 + ui->treeWidget->headerItem()->setText(COLUMN_CHECKBOX, QString()); + ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84); ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 100); ui->treeWidget->setColumnWidth(COLUMN_LABEL, 170); From 72ac792b4a544048261f35af859c7bb6d8bdb7a0 Mon Sep 17 00:00:00 2001 From: randy-waterhouse Date: Fri, 21 Nov 2014 12:24:50 +1300 Subject: [PATCH 0209/2337] Format build flags in src/Makefile.am. --- src/Makefile.am | 54 +++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index e2ba191e3ab..009c3c5196f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -291,6 +291,14 @@ nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h # # bitcoind binary # +bitcoind_SOURCES = bitcoind.cpp +bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +if TARGET_WINDOWS +bitcoind_SOURCES += bitcoind-res.rc +endif + bitcoind_LDADD = \ $(LIBBITCOIN_SERVER) \ $(LIBBITCOIN_COMMON) \ @@ -304,51 +312,43 @@ bitcoind_LDADD = \ if ENABLE_WALLET bitcoind_LDADD += libbitcoin_wallet.a endif -bitcoind_SOURCES = bitcoind.cpp -# - -if TARGET_WINDOWS -bitcoind_SOURCES += bitcoind-res.rc -endif bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) -bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES) -bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +# # bitcoin-cli binary # +bitcoin_cli_SOURCES = bitcoin-cli.cpp +bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +if TARGET_WINDOWS +bitcoin_cli_SOURCES += bitcoin-cli-res.rc +endif + bitcoin_cli_LDADD = \ $(LIBBITCOIN_CLI) \ $(LIBBITCOIN_UTIL) \ - $(BOOST_LIBS) \ - $(SSL_LIBS) \ - $(CRYPTO_LIBS) + $(LIBSECP256K1) -bitcoin_cli_SOURCES = \ - bitcoin-cli.cpp - -bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) # # bitcoin-tx binary # +bitcoin_tx_SOURCES = bitcoin-tx.cpp +bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + bitcoin_tx_LDADD = \ $(LIBBITCOIN_UNIVALUE) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ - $(LIBSECP256K1) \ - $(BOOST_LIBS) \ - $(CRYPTO_LIBS) + $(LIBSECP256K1) -bitcoin_tx_SOURCES = bitcoin-tx.cpp -bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) # -bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) - -if TARGET_WINDOWS -bitcoin_cli_SOURCES += bitcoin-cli-res.rc -endif -bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +# bitcoinconsensus library # if BUILD_BITCOIN_LIBS include_HEADERS = script/bitcoinconsensus.h libbitcoinconsensus_la_SOURCES = \ @@ -376,10 +376,12 @@ endif libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS) libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS) libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL + if USE_LIBSECP256K1 libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la endif endif +# CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno From fdf80ea7b19dde7ddec3baffeb1400fe1ca1c37a Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sat, 31 Jan 2015 17:39:22 +0100 Subject: [PATCH 0210/2337] [Qt] allow unit changes for read-only BitcoinAmountField - fixes #5725 --- src/qt/bitcoinamountfield.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index 4c00aca9858..d31a1e018b2 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -278,7 +278,6 @@ void BitcoinAmountField::setValue(const CAmount& value) void BitcoinAmountField::setReadOnly(bool fReadOnly) { amount->setReadOnly(fReadOnly); - unit->setEnabled(!fReadOnly); } void BitcoinAmountField::unitChanged(int idx) From 86731603d48de65960a7f2cd4da60e7ae1760813 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Sat, 13 Dec 2014 11:15:25 +0800 Subject: [PATCH 0211/2337] Remove bootstrap.md See #5455 --- doc/README.md | 2 +- doc/bootstrap.md | 56 ------------------------------------------------ 2 files changed, 1 insertion(+), 57 deletions(-) delete mode 100644 doc/bootstrap.md diff --git a/doc/README.md b/doc/README.md index b2a0c2dcb7a..0ade8f99238 100644 --- a/doc/README.md +++ b/doc/README.md @@ -3,7 +3,7 @@ Bitcoin Core 0.10.99 Setup --------------------- -[Bitcoin Core](http://bitcoin.org/en/download) is the original Bitcoin client and it builds the backbone of the network. However, it downloads and stores the entire history of Bitcoin transactions (which is currently several GBs); depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more. Thankfully you only have to do this once. If you would like the process to go faster you can [download the blockchain directly](bootstrap.md). +[Bitcoin Core](http://bitcoin.org/en/download) is the original Bitcoin client and it builds the backbone of the network. However, it downloads and stores the entire history of Bitcoin transactions (which is currently several GBs); depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more. Running --------------------- diff --git a/doc/bootstrap.md b/doc/bootstrap.md deleted file mode 100644 index b84fd24b11d..00000000000 --- a/doc/bootstrap.md +++ /dev/null @@ -1,56 +0,0 @@ -### Bootstrap the Blockchain Synchronization - -Normally the Bitcoin client will download the transaction and network information, called the blockchain, from the network by syncing with the other clients. This process can take quite some time as the [Bitcoin blockchain](https://blockchain.info/charts/blocks-size) is growing bigger and bigger for each day. Luckily there is a safe and fast way to speed up this process. We'll show you how to bootstrap your blockchain to bring your client up to speed in just a few simple steps. - -### Requirements - -- A fresh install of the Bitcoin client software. - -### Download the blockchain via BitTorrent - -Jeff Garzik, Bitcoin Core developer, offers an [torrent file](https://bitcointalk.org/index.php?topic=145386.0) for bootstrapping purposes that is updated often. BitTorrent is a protocol that speeds up the downloading of large files by using the other clients in the network. Examples of free and safe open source clients are [Deluge](http://deluge-torrent.org/) or [qBittorrent](http://www.qbittorrent.org/). A guide to installing and configuring the torrent clients can be found [here](http://dev.deluge-torrent.org/wiki/UserGuide) for Deluge and [here](http://qbforums.shiki.hu/) for qBittorrent. A further in-depth tutorial on BitTorrent can be found [here](http://www.howtogeek.com/howto/31846/bittorrent-for-beginners-how-get-started-downloading-torrents/). - -With the client installed we'll proceed to download the blockchain torrent file. Use the following magnet link: - - magnet:?xt=urn:btih:2d4e6c1f96c5d5fb260dff92aea4e600227f1aea&dn=bootstrap.dat&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.publicbt.com:80&tr=udp://tracker.ccc.de:80&tr=udp://tracker.istole.it:80 - - or go to [Jeff Garzik's topic](https://bitcointalk.org/index.php?topic=145386.0) for a signed magnet link. Alternatively you can use the [.torrent file](http://sourceforge.net/projects/bitcoin/files/Bitcoin/blockchain/bootstrap.dat.torrent/download) found on SourceForge. - -![Fig1](img/bootstrap1.png) - -The download page should look like this, with a countdown to the download. If it does not work click the direct download link. - -The torrent client installed will recognize the download of the torrent file. Save the bootstrap.dat file to the folder you use for downloads. The image below shows the torrent download in qBittorrent, with current speed and ETA highlighted. - -![Fig2](img/bootstrap2.png) - -### Importing the blockchain -Exit the Bitcoin client software if you have it running. Be sure not to have an actively used wallet in use. We are going to copy the download of the blockchain to the Bitcoin client data directory. You should run the client software at least once so it can generate the data directory. Copy the downloaded bootstrap.dat file into the Bitcoin data folder. - -**For Windows users:** -Open explorer, and type into the address bar: - - %APPDATA%\Bitcoin - -This will open up the data folder. It should look like the image below. Copy over the bootstrap.dat from your download folder to this directory. -![Fig4](img/bootstrap4.png) - -**For OSX users:** -Open Finder by pressing Press [shift] + [cmd] + [g] and enter: - - ~/Library/Application Support/Bitcoin/ - -**For Linux users:** -The directory is hidden in your User folder. Go to: - - ~/.bitcoin/ - -### Importing the blockchain -Now start the Bitcoin client software. It should show "Importing blocks from disk" like the image below. -![Fig5](img/bootstrap5.png) - -Wait until the import finishes. The client will download the last days not covered by the import. Congratulations you have successfully imported the blockchain! - -### Is this safe? - -Yes, the above method is safe. The download contains only raw blockchain data and the client verifies this on import. Do not download the blockchain from unofficial sources, especially if they provide `*.rev` and `*.sst` files. These files are not verified and can contain malicious edits. From d6bed1514c2e72ea2006942c23c31e3f518d4a77 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 16 Dec 2014 16:26:07 -0300 Subject: [PATCH 0212/2337] remove sig_canonical.json and sig_noncanonical.json --- src/Makefile.test.include | 2 -- src/test/data/sig_canonical.json | 7 ------- src/test/data/sig_noncanonical.json | 22 ---------------------- 3 files changed, 31 deletions(-) delete mode 100644 src/test/data/sig_canonical.json delete mode 100644 src/test/data/sig_noncanonical.json diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 710956a72be..90494439fa5 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -20,8 +20,6 @@ EXTRA_DIST += \ JSON_TEST_FILES = \ test/data/script_valid.json \ test/data/base58_keys_valid.json \ - test/data/sig_canonical.json \ - test/data/sig_noncanonical.json \ test/data/base58_encode_decode.json \ test/data/base58_keys_invalid.json \ test/data/script_invalid.json \ diff --git a/src/test/data/sig_canonical.json b/src/test/data/sig_canonical.json deleted file mode 100644 index e43a08629a1..00000000000 --- a/src/test/data/sig_canonical.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - "300602010002010001", - "3008020200ff020200ff01", - "304402203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df0c022030b61dd36543125d56b9f9f3a1f9353189e5af33cdda8d77a5209aec03978fa001", - "30450220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba01", - "3046022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba01" -] diff --git a/src/test/data/sig_noncanonical.json b/src/test/data/sig_noncanonical.json deleted file mode 100644 index d9a6c1cdd87..00000000000 --- a/src/test/data/sig_noncanonical.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - "non-hex strings are ignored", - - "too short:", "30050201FF020001", - "too long:", "30470221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01", - "hashtype:", "304402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed11", - "type:", "314402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01", - "total length:", "304502205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01", - "S len oob:", "301F01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb101", - "R+S:", "304502205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed0001", - - "R type:", "304401205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01", - "R len = 0:", "3024020002202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01", - "R<0:", "304402208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01", - "R padded:", "30450221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01", - - - "S type:", "304402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610501202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01", - "S len = 0:", "302402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105020001", - "S<0:", "304402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61050220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01", - "S padded:", "304502205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61050221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01" -] From bfc29dcdc5c2a75a82d6f5034c547a8f4ac94379 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Fri, 26 Dec 2014 18:03:44 +0800 Subject: [PATCH 0213/2337] Improve gitian build guide Point to the Debian 7.7 installer Fix wording now that we only use a single image Remove bitcoin checkout steps, they are covered in release-process --- doc/gitian-building.md | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 1312979cac7..efa5ef17dc1 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -24,7 +24,7 @@ Table of Contents - [Connecting to the VM](#connecting-to-the-vm) - [Setting up Debian for gitian building](#setting-up-debian-for-gitian-building) - [Installing gitian](#installing-gitian) -- [Setting up gitian images](#setting-up-gitian-images) +- [Setting up the gitian image](#setting-up-the-gitian-image) - [Getting and building the inputs](#getting-and-building-the-inputs) - [Building Bitcoin](#building-bitcoin) - [Building an alternative repository](#building-an-alternative-repository) @@ -74,11 +74,11 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the - Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side - Push the `Create` button -Get the [Debian 7.4 net installer](http://ftp.at.debian.org/debian-jigdo/current/amd64/iso-cd/debian-7.4.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). +Get the [Debian 7.7 net installer](http://cdimage.debian.org/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). This DVD image can be validated using a SHA256 hashing tool, for example on Unixy OSes by entering the following in a terminal: - echo "b712a141bc60269db217d3b3e456179bd6b181645f90e4aac9c42ed63de492e9 debian-7.4.0-amd64-netinst.iso" | sha256sum -c + echo "d440e85b4121f94608748139f25dbce1ad36771348b002fe07d4d44b9d9e623f debian-7.7.0-amd64-netinst.iso" | sha256sum -c # (must return OK) After creating the VM, we need to configure it. @@ -109,7 +109,7 @@ Then start the VM. On the first launch you will be asked for a CD or DVD image. Installing Debian ------------------ -In this section it will be explained how to install Debian on the newly created VM. +This section will explain how to install Debian on the newly created VM. - Choose the non-graphical installer. We do not need the graphical environment, it will only increase installation time and disk usage. @@ -277,24 +277,21 @@ cd .. **Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*. -Clone the git repositories for bitcoin and gitian and then checkout the bitcoin version that you want to build. +Clone the git repositories for bitcoin and gitian. ```bash git clone https://github.com/devrandom/gitian-builder.git git clone https://github.com/bitcoin/bitcoin -cd bitcoin -git checkout v${VERSION} -cd .. ``` -Setting up gitian images +Setting up the gitian image ------------------------- -Gitian needs virtual images of the operating system to build in. -Currently this is Ubuntu Precise for x86_64. -These images will be copied and used every time that a build is started to +Gitian needs a virtual image of the operating system to build in. +Currently this is Ubuntu Precise x86_64. +This image will be copied and used every time that a build is started to make sure that the build is deterministic. -Creating the images will take a while, but only has to be done once. +Creating the image will take a while, but only has to be done once. Execute the following as user `debian`: @@ -303,7 +300,7 @@ cd gitian-builder bin/make-base-vm --lxc --arch amd64 --suite precise ``` -There will be a lot of warnings printed during build of the images. These can be ignored. +There will be a lot of warnings printed during build of the image. These can be ignored. **Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*. @@ -322,7 +319,7 @@ To build Bitcoin (for Linux, OSX and Windows) just follow the steps under 'perfo gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository. This may take a long time as it also builds the dependencies needed for each descriptor. -These dependencies will be cached after a successful build to avoid rebuilding them when possible. +These dependencies will be cached after a successful build to avoid rebuilding them where possible. At any time you can check the package installation and build progress with @@ -382,9 +379,9 @@ When you execute `gsign` you will get an error from GPG, which can be ignored. C in `gitian.sigs` to your signing machine and do ```bash - gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-build.assert - gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-build.assert - gpg --detach-sign ${VERSION}-osx/${SIGNER}/bitcoin-build.assert + gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-linux-build.assert + gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-win-build.assert + gpg --detach-sign ${VERSION}-osx-unsigned/${SIGNER}/bitcoin-osx-build.assert ``` This will create the `.sig` files that can be committed together with the `.assert` files to assert your From 91a9fe094b3f0091f40ccdb19581b90e86888ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Mon, 5 Jan 2015 21:44:55 +0100 Subject: [PATCH 0214/2337] Fix typo - sentence starts with capital letter --- src/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 6ad3ee54d56..24a4d7c22cc 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -82,7 +82,7 @@ Value getnewaddress(const Array& params, bool fHelp) "If 'account' is specified (DEPRECATED), it is added to the address book \n" "so payments received with the address will be credited to 'account'.\n" "\nArguments:\n" - "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. if not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n" + "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n" "\nResult:\n" "\"bitcoinaddress\" (string) The new bitcoin address\n" "\nExamples:\n" From 3800135ad382a0a980eb20bad8bacbbf206f8cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Wed, 7 Jan 2015 18:11:59 +0100 Subject: [PATCH 0215/2337] Fix typo --- doc/build-unix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 8ddee3b7571..5f60dff06c8 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -159,7 +159,7 @@ tar -xzvf db-4.8.30.NC.tar.gz # Build the library and install to our prefix cd db-4.8.30.NC/build_unix/ -# Note: Do a static build so that it can be embedded into the exectuable, instead of having to find a .so at runtime +# Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime ../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX make install From 5262fde0ecd19f1febbfcd488f2be41c5dffd047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Thu, 8 Jan 2015 11:44:25 +0100 Subject: [PATCH 0216/2337] Remove whitespaces before double colon in errors and logs --- src/alert.cpp | 2 +- src/db.cpp | 40 +++---- src/init.cpp | 2 +- src/keystore.cpp | 2 +- src/main.cpp | 190 +++++++++++++++---------------- src/miner.cpp | 6 +- src/net.cpp | 18 +-- src/pow.cpp | 4 +- src/primitives/transaction.cpp | 2 +- src/protocol.cpp | 6 +- src/qt/addresstablemodel.cpp | 6 +- src/qt/clientmodel.cpp | 4 +- src/qt/paymentrequestplus.cpp | 22 ++-- src/qt/paymentserver.cpp | 28 ++--- src/qt/transactiontablemodel.cpp | 10 +- src/qt/walletmodel.cpp | 2 +- src/rpcwallet.cpp | 4 +- src/script/interpreter.cpp | 2 +- src/script/script.h | 2 +- src/serialize.h | 2 +- src/streams.h | 18 +-- src/test/bignum.h | 8 +- src/test/sighash_tests.cpp | 4 +- src/txdb.cpp | 6 +- src/txmempool.cpp | 8 +- src/wallet.cpp | 18 +-- src/wallet.h | 14 +-- src/walletdb.cpp | 4 +- 28 files changed, 217 insertions(+), 217 deletions(-) diff --git a/src/alert.cpp b/src/alert.cpp index 370d0cecc6f..323939913b7 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -149,7 +149,7 @@ bool CAlert::CheckSignature() const { CPubKey key(Params().AlertKey()); if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) - return error("CAlert::CheckSignature() : verify signature failed"); + return error("CAlert::CheckSignature(): verify signature failed"); // Now unserialize the data CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/db.cpp b/src/db.cpp index 7b51707f604..a7f885135ba 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -43,7 +43,7 @@ void CDBEnv::EnvShutdown() fDbEnvInit = false; int ret = dbenv.close(0); if (ret != 0) - LogPrintf("CDBEnv::EnvShutdown : Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); + LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); if (!fMockDb) DbEnv(0).remove(path.string().c_str(), 0); } @@ -75,7 +75,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) boost::filesystem::path pathLogDir = path / "database"; TryCreateDirectory(pathLogDir); boost::filesystem::path pathErrorFile = path / "db.log"; - LogPrintf("CDBEnv::Open : LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); + LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); unsigned int nEnvFlags = 0; if (GetBoolArg("-privdb", true)) @@ -102,7 +102,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) nEnvFlags, S_IRUSR | S_IWUSR); if (ret != 0) - return error("CDBEnv::Open : Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); + return error("CDBEnv::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); fDbEnvInit = true; fMockDb = false; @@ -112,7 +112,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) void CDBEnv::MakeMock() { if (fDbEnvInit) - throw runtime_error("CDBEnv::MakeMock : Already initialized"); + throw runtime_error("CDBEnv::MakeMock: Already initialized"); boost::this_thread::interruption_point(); @@ -135,7 +135,7 @@ void CDBEnv::MakeMock() DB_PRIVATE, S_IRUSR | S_IWUSR); if (ret > 0) - throw runtime_error(strprintf("CDBEnv::MakeMock : Error %d opening database environment.", ret)); + throw runtime_error(strprintf("CDBEnv::MakeMock: Error %d opening database environment.", ret)); fDbEnvInit = true; fMockDb = true; @@ -172,14 +172,14 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vectorget_mpf(); ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); if (ret != 0) - throw runtime_error(strprintf("CDB : Failed to configure for no temp file backing for database %s", strFile)); + throw runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFile)); } ret = pdb->open(NULL, // Txn pointer @@ -261,7 +261,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnClose pdb = NULL; --bitdb.mapFileUseCount[strFile]; strFile = ""; - throw runtime_error(strprintf("CDB : Error %d, can't open database %s", ret, strFile)); + throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFile)); } if (fCreate && !Exists(string("version"))) { @@ -342,7 +342,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) bitdb.mapFileUseCount.erase(strFile); bool fSuccess = true; - LogPrintf("CDB::Rewrite : Rewriting %s...\n", strFile); + LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile); string strFileRes = strFile + ".rewrite"; { // surround usage of db with extra {} CDB db(strFile.c_str(), "r"); @@ -355,7 +355,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) DB_CREATE, // Flags 0); if (ret > 0) { - LogPrintf("CDB::Rewrite : Can't create database file %s\n", strFileRes); + LogPrintf("CDB::Rewrite: Can't create database file %s\n", strFileRes); fSuccess = false; } @@ -404,7 +404,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) fSuccess = false; } if (!fSuccess) - LogPrintf("CDB::Rewrite : Failed to rewrite database file %s\n", strFileRes); + LogPrintf("CDB::Rewrite: Failed to rewrite database file %s\n", strFileRes); return fSuccess; } } @@ -418,7 +418,7 @@ void CDBEnv::Flush(bool fShutdown) { int64_t nStart = GetTimeMillis(); // Flush log data to the actual data file on all files that are not in use - LogPrint("db", "CDBEnv::Flush : Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started"); + LogPrint("db", "CDBEnv::Flush: Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started"); if (!fDbEnvInit) return; { @@ -427,21 +427,21 @@ void CDBEnv::Flush(bool fShutdown) while (mi != mapFileUseCount.end()) { string strFile = (*mi).first; int nRefCount = (*mi).second; - LogPrint("db", "CDBEnv::Flush : Flushing %s (refcount = %d)...\n", strFile, nRefCount); + LogPrint("db", "CDBEnv::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount); if (nRefCount == 0) { // Move log data to the dat file CloseDb(strFile); - LogPrint("db", "CDBEnv::Flush : %s checkpoint\n", strFile); + LogPrint("db", "CDBEnv::Flush: %s checkpoint\n", strFile); dbenv.txn_checkpoint(0, 0, 0); - LogPrint("db", "CDBEnv::Flush : %s detach\n", strFile); + LogPrint("db", "CDBEnv::Flush: %s detach\n", strFile); if (!fMockDb) dbenv.lsn_reset(strFile.c_str(), 0); - LogPrint("db", "CDBEnv::Flush : %s closed\n", strFile); + LogPrint("db", "CDBEnv::Flush: %s closed\n", strFile); mapFileUseCount.erase(mi++); } else mi++; } - LogPrint("db", "CDBEnv::Flush : Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart); + LogPrint("db", "CDBEnv::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart); if (fShutdown) { char** listp; if (mapFileUseCount.empty()) { diff --git a/src/init.cpp b/src/init.cpp index aaa5f06c752..c2af23139cd 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -977,7 +977,7 @@ bool AppInit2(boost::thread_group& threadGroup) } catch (const boost::filesystem::filesystem_error& e) { // Note: hardlink creation failing is not a disaster, it just means // blocks will get re-downloaded from peers. - LogPrintf("Error hardlinking blk%04u.dat : %s\n", i, e.what()); + LogPrintf("Error hardlinking blk%04u.dat: %s\n", i, e.what()); break; } } diff --git a/src/keystore.cpp b/src/keystore.cpp index 482125a39ae..22cd08f30c8 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -36,7 +36,7 @@ bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey) bool CBasicKeyStore::AddCScript(const CScript& redeemScript) { if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE) - return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE); + return error("CBasicKeyStore::AddCScript(): redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE); LOCK(cs_KeyStore); mapScripts[CScriptID(redeemScript)] = redeemScript; diff --git a/src/main.cpp b/src/main.cpp index 7cc69c318b1..629e0dcbc01 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -820,14 +820,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) { // Basic checks that don't depend on any context if (tx.vin.empty()) - return state.DoS(10, error("CheckTransaction() : vin empty"), + return state.DoS(10, error("CheckTransaction(): vin empty"), REJECT_INVALID, "bad-txns-vin-empty"); if (tx.vout.empty()) - return state.DoS(10, error("CheckTransaction() : vout empty"), + return state.DoS(10, error("CheckTransaction(): vout empty"), REJECT_INVALID, "bad-txns-vout-empty"); // Size limits if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) - return state.DoS(100, error("CheckTransaction() : size limits failed"), + return state.DoS(100, error("CheckTransaction(): size limits failed"), REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values @@ -835,14 +835,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) BOOST_FOREACH(const CTxOut& txout, tx.vout) { if (txout.nValue < 0) - return state.DoS(100, error("CheckTransaction() : txout.nValue negative"), + return state.DoS(100, error("CheckTransaction(): txout.nValue negative"), REJECT_INVALID, "bad-txns-vout-negative"); if (txout.nValue > MAX_MONEY) - return state.DoS(100, error("CheckTransaction() : txout.nValue too high"), + return state.DoS(100, error("CheckTransaction(): txout.nValue too high"), REJECT_INVALID, "bad-txns-vout-toolarge"); nValueOut += txout.nValue; if (!MoneyRange(nValueOut)) - return state.DoS(100, error("CheckTransaction() : txout total out of range"), + return state.DoS(100, error("CheckTransaction(): txout total out of range"), REJECT_INVALID, "bad-txns-txouttotal-toolarge"); } @@ -851,7 +851,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) BOOST_FOREACH(const CTxIn& txin, tx.vin) { if (vInOutPoints.count(txin.prevout)) - return state.DoS(100, error("CheckTransaction() : duplicate inputs"), + return state.DoS(100, error("CheckTransaction(): duplicate inputs"), REJECT_INVALID, "bad-txns-inputs-duplicate"); vInOutPoints.insert(txin.prevout); } @@ -859,14 +859,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) if (tx.IsCoinBase()) { if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) - return state.DoS(100, error("CheckTransaction() : coinbase script size"), + return state.DoS(100, error("CheckTransaction(): coinbase script size"), REJECT_INVALID, "bad-cb-length"); } else { BOOST_FOREACH(const CTxIn& txin, tx.vin) if (txin.prevout.IsNull()) - return state.DoS(10, error("CheckTransaction() : prevout is null"), + return state.DoS(10, error("CheckTransaction(): prevout is null"), REJECT_INVALID, "bad-txns-prevout-null"); } @@ -922,7 +922,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa string reason; if (Params().RequireStandard() && !IsStandardTx(tx, reason)) return state.DoS(0, - error("AcceptToMemoryPool : nonstandard transaction: %s", reason), + error("AcceptToMemoryPool: nonstandard transaction: %s", reason), REJECT_NONSTANDARD, reason); // Only accept nLockTime-using transactions that can be mined in the next @@ -942,7 +942,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // timestamp applications where it matters. if (!IsFinalTx(tx, chainActive.Height() + 1)) return state.DoS(0, - error("AcceptToMemoryPool : non-final"), + error("AcceptToMemoryPool: non-final"), REJECT_NONSTANDARD, "non-final"); // is it already in the memory pool? @@ -991,7 +991,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // are the actual inputs available? if (!view.HaveInputs(tx)) - return state.Invalid(error("AcceptToMemoryPool : inputs already spent"), + return state.Invalid(error("AcceptToMemoryPool: inputs already spent"), REJECT_DUPLICATE, "bad-txns-inputs-spent"); // Bring the best block into scope @@ -1016,7 +1016,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa nSigOps += GetP2SHSigOpCount(tx, view); if (nSigOps > MAX_STANDARD_TX_SIGOPS) return state.DoS(0, - error("AcceptToMemoryPool : too many sigops %s, %d > %d", + error("AcceptToMemoryPool: too many sigops %s, %d > %d", hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS), REJECT_NONSTANDARD, "bad-txns-too-many-sigops"); @@ -1030,7 +1030,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Don't accept it if it can't get into a block CAmount txMinFee = GetMinRelayFee(tx, nSize, true); if (fLimitFree && nFees < txMinFee) - return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d", + return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d", hash.ToString(), nFees, txMinFee), REJECT_INSUFFICIENTFEE, "insufficient fee"); @@ -1057,7 +1057,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000) - return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"), + return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); dFreeCount += nSize; @@ -1123,11 +1123,11 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock fseek(file.Get(), postx.nTxOffset, SEEK_CUR); file >> txOut; } catch (const std::exception& e) { - return error("%s : Deserialize or I/O error - %s", __func__, e.what()); + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } hashBlock = header.GetHash(); if (txOut.GetHash() != hash) - return error("%s : txid mismatch", __func__); + return error("%s: txid mismatch", __func__); return true; } } @@ -1176,7 +1176,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) // Open history file to append CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); if (fileout.IsNull()) - return error("WriteBlockToDisk : OpenBlockFile failed"); + return error("WriteBlockToDisk: OpenBlockFile failed"); // Write index header unsigned int nSize = fileout.GetSerializeSize(block); @@ -1185,7 +1185,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) // Write block long fileOutPos = ftell(fileout.Get()); if (fileOutPos < 0) - return error("WriteBlockToDisk : ftell failed"); + return error("WriteBlockToDisk: ftell failed"); pos.nPos = (unsigned int)fileOutPos; fileout << block; @@ -1199,19 +1199,19 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) // Open history file to read CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); if (filein.IsNull()) - return error("ReadBlockFromDisk : OpenBlockFile failed"); + return error("ReadBlockFromDisk: OpenBlockFile failed"); // Read block try { filein >> block; } catch (const std::exception& e) { - return error("%s : Deserialize or I/O error - %s", __func__, e.what()); + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } // Check the header if (!CheckProofOfWork(block.GetHash(), block.nBits)) - return error("ReadBlockFromDisk : Errors in block header"); + return error("ReadBlockFromDisk: Errors in block header"); return true; } @@ -1221,7 +1221,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) if (!ReadBlockFromDisk(block, pindex->GetBlockPos())) return false; if (block.GetHash() != pindex->GetBlockHash()) - return error("ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index"); + return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index"); return true; } @@ -1423,7 +1423,7 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore), &error)) { - return ::error("CScriptCheck() : %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error)); + return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error)); } return true; } @@ -1438,7 +1438,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // This doesn't trigger the DoS code on purpose; if it did, it would make it easier // for an attacker to attempt to split the network. if (!inputs.HaveInputs(tx)) - return state.Invalid(error("CheckInputs() : %s inputs unavailable", tx.GetHash().ToString())); + return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString())); // While checking, GetBestBlock() refers to the parent block. // This is also true for mempool checks. @@ -1456,31 +1456,31 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi if (coins->IsCoinBase()) { if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) return state.Invalid( - error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), + error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); } // Check for negative or overflow input values nValueIn += coins->vout[prevout.n].nValue; if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn)) - return state.DoS(100, error("CheckInputs() : txin values out of range"), + return state.DoS(100, error("CheckInputs(): txin values out of range"), REJECT_INVALID, "bad-txns-inputvalues-outofrange"); } if (nValueIn < tx.GetValueOut()) - return state.DoS(100, error("CheckInputs() : %s value in (%s) < value out (%s)", + return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s)", tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())), REJECT_INVALID, "bad-txns-in-belowout"); // Tally transaction fees CAmount nTxFee = nValueIn - tx.GetValueOut(); if (nTxFee < 0) - return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", tx.GetHash().ToString()), + return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()), REJECT_INVALID, "bad-txns-fee-negative"); nFees += nTxFee; if (!MoneyRange(nFees)) - return state.DoS(100, error("CheckInputs() : nFees out of range"), + return state.DoS(100, error("CheckInputs(): nFees out of range"), REJECT_INVALID, "bad-txns-fee-outofrange"); // The first loop above does all the inexpensive checks. @@ -1537,7 +1537,7 @@ bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint // Open history file to append CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); if (fileout.IsNull()) - return error("%s : OpenUndoFile failed", __func__); + return error("%s: OpenUndoFile failed", __func__); // Write index header unsigned int nSize = fileout.GetSerializeSize(blockundo); @@ -1546,7 +1546,7 @@ bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint // Write undo data long fileOutPos = ftell(fileout.Get()); if (fileOutPos < 0) - return error("%s : ftell failed", __func__); + return error("%s: ftell failed", __func__); pos.nPos = (unsigned int)fileOutPos; fileout << blockundo; @@ -1564,7 +1564,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin // Open history file to read CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); if (filein.IsNull()) - return error("%s : OpenBlockFile failed", __func__); + return error("%s: OpenBlockFile failed", __func__); // Read block uint256 hashChecksum; @@ -1573,7 +1573,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin filein >> hashChecksum; } catch (const std::exception& e) { - return error("%s : Deserialize or I/O error - %s", __func__, e.what()); + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } // Verify checksum @@ -1581,7 +1581,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin hasher << hashBlock; hasher << blockundo; if (hashChecksum != hasher.GetHash()) - return error("%s : Checksum mismatch", __func__); + return error("%s: Checksum mismatch", __func__); return true; } @@ -1600,12 +1600,12 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex CBlockUndo blockUndo; CDiskBlockPos pos = pindex->GetUndoPos(); if (pos.IsNull()) - return error("DisconnectBlock() : no undo data available"); + return error("DisconnectBlock(): no undo data available"); if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash())) - return error("DisconnectBlock() : failure reading undo data"); + return error("DisconnectBlock(): failure reading undo data"); if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) - return error("DisconnectBlock() : block and undo data inconsistent"); + return error("DisconnectBlock(): block and undo data inconsistent"); // undo transactions in reverse order for (int i = block.vtx.size() - 1; i >= 0; i--) { @@ -1628,7 +1628,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex if (outsBlock.nVersion < 0) outs->nVersion = outsBlock.nVersion; if (*outs != outsBlock) - fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted"); + fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted"); // remove outputs outs->Clear(); @@ -1638,7 +1638,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex if (i > 0) { // not coinbases const CTxUndo &txundo = blockUndo.vtxundo[i-1]; if (txundo.vprevout.size() != tx.vin.size()) - return error("DisconnectBlock() : transaction and undo data inconsistent"); + return error("DisconnectBlock(): transaction and undo data inconsistent"); for (unsigned int j = tx.vin.size(); j-- > 0;) { const COutPoint &out = tx.vin[j].prevout; const CTxInUndo &undo = txundo.vprevout[j]; @@ -1646,17 +1646,17 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex if (undo.nHeight != 0) { // undo data contains height: this is the last output of the prevout tx being spent if (!coins->IsPruned()) - fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction"); + fClean = fClean && error("DisconnectBlock(): undo data overwriting existing transaction"); coins->Clear(); coins->fCoinBase = undo.fCoinBase; coins->nHeight = undo.nHeight; coins->nVersion = undo.nVersion; } else { if (coins->IsPruned()) - fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction"); + fClean = fClean && error("DisconnectBlock(): undo data adding output to missing transaction"); } if (coins->IsAvailable(out.n)) - fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output"); + fClean = fClean && error("DisconnectBlock(): undo data overwriting existing output"); if (coins->vout.size() < out.n+1) coins->vout.resize(out.n+1); coins->vout[out.n] = undo.txout; @@ -1753,7 +1753,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin BOOST_FOREACH(const CTransaction& tx, block.vtx) { const CCoins* coins = view.AccessCoins(tx.GetHash()); if (coins && !coins->IsPruned()) - return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"), + return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"), REJECT_INVALID, "bad-txns-BIP30"); } } @@ -1783,13 +1783,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin nInputs += tx.vin.size(); nSigOps += GetLegacySigOpCount(tx); if (nSigOps > MAX_BLOCK_SIGOPS) - return state.DoS(100, error("ConnectBlock() : too many sigops"), + return state.DoS(100, error("ConnectBlock(): too many sigops"), REJECT_INVALID, "bad-blk-sigops"); if (!tx.IsCoinBase()) { if (!view.HaveInputs(tx)) - return state.DoS(100, error("ConnectBlock() : inputs missing/spent"), + return state.DoS(100, error("ConnectBlock(): inputs missing/spent"), REJECT_INVALID, "bad-txns-inputs-missingorspent"); if (fStrictPayToScriptHash) @@ -1799,7 +1799,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // an incredibly-expensive-to-validate block. nSigOps += GetP2SHSigOpCount(tx, view); if (nSigOps > MAX_BLOCK_SIGOPS) - return state.DoS(100, error("ConnectBlock() : too many sigops"), + return state.DoS(100, error("ConnectBlock(): too many sigops"), REJECT_INVALID, "bad-blk-sigops"); } @@ -1825,7 +1825,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (block.vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees)) return state.DoS(100, - error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)", + error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)", block.vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees)), REJECT_INVALID, "bad-cb-amount"); @@ -1843,7 +1843,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (pindex->GetUndoPos().IsNull()) { CDiskBlockPos pos; if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) - return error("ConnectBlock() : FindUndoPos failed"); + return error("ConnectBlock(): FindUndoPos failed"); if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash())) return state.Abort("Failed to write undo data"); @@ -1995,7 +1995,7 @@ bool static DisconnectTip(CValidationState &state) { { CCoinsViewCache view(pcoinsTip); if (!DisconnectBlock(block, state, pindexDelete, view)) - return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); + return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); assert(view.Flush()); } LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); @@ -2055,7 +2055,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * if (!rv) { if (state.IsInvalid()) InvalidBlockFound(pindexNew, state); - return error("ConnectTip() : ConnectBlock %s failed", pindexNew->GetBlockHash().ToString()); + return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString()); } mapBlockSource.erase(inv.hash); nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2; @@ -2492,12 +2492,12 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f { // Check proof of work matches claimed amount if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits)) - return state.DoS(50, error("CheckBlockHeader() : proof of work failed"), + return state.DoS(50, error("CheckBlockHeader(): proof of work failed"), REJECT_INVALID, "high-hash"); // Check timestamp if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) - return state.Invalid(error("CheckBlockHeader() : block timestamp too far in the future"), + return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"), REJECT_INVALID, "time-too-new"); return true; @@ -2517,14 +2517,14 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo bool mutated; uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated); if (block.hashMerkleRoot != hashMerkleRoot2) - return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"), + return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"), REJECT_INVALID, "bad-txnmrklroot", true); // Check for merkle tree malleability (CVE-2012-2459): repeating sequences // of transactions in a block without affecting the merkle root of a block, // while still invalidating it. if (mutated) - return state.DoS(100, error("CheckBlock() : duplicate transaction"), + return state.DoS(100, error("CheckBlock(): duplicate transaction"), REJECT_INVALID, "bad-txns-duplicate", true); } @@ -2534,22 +2534,22 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Size limits if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) - return state.DoS(100, error("CheckBlock() : size limits failed"), + return state.DoS(100, error("CheckBlock(): size limits failed"), REJECT_INVALID, "bad-blk-length"); // First transaction must be coinbase, the rest must not be if (block.vtx.empty() || !block.vtx[0].IsCoinBase()) - return state.DoS(100, error("CheckBlock() : first tx is not coinbase"), + return state.DoS(100, error("CheckBlock(): first tx is not coinbase"), REJECT_INVALID, "bad-cb-missing"); for (unsigned int i = 1; i < block.vtx.size(); i++) if (block.vtx[i].IsCoinBase()) - return state.DoS(100, error("CheckBlock() : more than one coinbase"), + return state.DoS(100, error("CheckBlock(): more than one coinbase"), REJECT_INVALID, "bad-cb-multiple"); // Check transactions BOOST_FOREACH(const CTransaction& tx, block.vtx) if (!CheckTransaction(tx, state)) - return error("CheckBlock() : CheckTransaction failed"); + return error("CheckBlock(): CheckTransaction failed"); unsigned int nSigOps = 0; BOOST_FOREACH(const CTransaction& tx, block.vtx) @@ -2557,7 +2557,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo nSigOps += GetLegacySigOpCount(tx); } if (nSigOps > MAX_BLOCK_SIGOPS) - return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"), + return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), REJECT_INVALID, "bad-blk-sigops", true); return true; @@ -2576,28 +2576,28 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta // Check proof of work if ((!Params().SkipProofOfWorkCheck()) && (block.nBits != GetNextWorkRequired(pindexPrev, &block))) - return state.DoS(100, error("%s : incorrect proof of work", __func__), + return state.DoS(100, error("%s: incorrect proof of work", __func__), REJECT_INVALID, "bad-diffbits"); // Check timestamp against prev if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) - return state.Invalid(error("%s : block's timestamp is too early", __func__), + return state.Invalid(error("%s: block's timestamp is too early", __func__), REJECT_INVALID, "time-too-old"); // Check that the block chain matches the known block chain up to a checkpoint if (!Checkpoints::CheckBlock(nHeight, hash)) - return state.DoS(100, error("%s : rejected by checkpoint lock-in at %d", __func__, nHeight), + return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight), REJECT_CHECKPOINT, "checkpoint mismatch"); // Don't accept any forks from the main chain prior to last checkpoint CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); if (pcheckpoint && nHeight < pcheckpoint->nHeight) - return state.DoS(100, error("%s : forked chain older than last checkpoint (height %d)", __func__, nHeight)); + return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight)); // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) { - return state.Invalid(error("%s : rejected nVersion=1 block", __func__), + return state.Invalid(error("%s: rejected nVersion=1 block", __func__), REJECT_OBSOLETE, "bad-version"); } @@ -2611,7 +2611,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, block.vtx) if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) { - return state.DoS(10, error("%s : contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); + return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); } // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height @@ -2621,7 +2621,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn CScript expect = CScript() << nHeight; if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) { - return state.DoS(100, error("%s : block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height"); + return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height"); } } @@ -2641,7 +2641,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc if (ppindex) *ppindex = pindex; if (pindex->nStatus & BLOCK_FAILED_MASK) - return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate"); + return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate"); return true; } @@ -2653,10 +2653,10 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc if (hash != Params().HashGenesisBlock()) { BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) - return state.DoS(10, error("%s : prev block not found", __func__), 0, "bad-prevblk"); + return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk"); pindexPrev = (*mi).second; if (pindexPrev->nStatus & BLOCK_FAILED_MASK) - return state.DoS(100, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); + return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); } if (!ContextualCheckBlockHeader(block, state, pindexPrev)) @@ -2682,7 +2682,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, if (pindex->nStatus & BLOCK_HAVE_DATA) { // TODO: deal better with duplicate blocks. - // return state.DoS(20, error("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate"); + // return state.DoS(20, error("AcceptBlock(): already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate"); return true; } @@ -2703,12 +2703,12 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, if (dbp != NULL) blockPos = *dbp; if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) - return error("AcceptBlock() : FindBlockPos failed"); + return error("AcceptBlock(): FindBlockPos failed"); if (dbp == NULL) if (!WriteBlockToDisk(block, blockPos)) return state.Abort("Failed to write block"); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) - return error("AcceptBlock() : ReceivedBlockTransactions failed"); + return error("AcceptBlock(): ReceivedBlockTransactions failed"); } catch (const std::runtime_error& e) { return state.Abort(std::string("System error: ") + e.what()); } @@ -2739,7 +2739,7 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis LOCK(cs_main); MarkBlockAsReceived(pblock->GetHash()); if (!checked) { - return error("%s : CheckBlock FAILED", __func__); + return error("%s: CheckBlock FAILED", __func__); } // Store to disk @@ -2749,11 +2749,11 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); } if (!ret) - return error("%s : AcceptBlock FAILED", __func__); + return error("%s: AcceptBlock FAILED", __func__); } if (!ActivateBestChain(state, pblock)) - return error("%s : ActivateBestChain failed", __func__); + return error("%s: ActivateBestChain failed", __func__); return true; } @@ -2859,7 +2859,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash) // Create new CBlockIndex* pindexNew = new CBlockIndex(); if (!pindexNew) - throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); + throw runtime_error("LoadBlockIndex(): new CBlockIndex failed"); mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); @@ -3005,24 +3005,24 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth CBlock block; // check level 0: read from disk if (!ReadBlockFromDisk(block, pindex)) - return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); + return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity if (nCheckLevel >= 1 && !CheckBlock(block, state)) - return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); + return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 2: verify undo validity if (nCheckLevel >= 2 && pindex) { CBlockUndo undo; CDiskBlockPos pos = pindex->GetUndoPos(); if (!pos.IsNull()) { if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash())) - return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); + return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); } } // check level 3: check for inconsistencies during memory-only disconnect of tip blocks if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= nCoinCacheSize) { bool fClean = true; if (!DisconnectBlock(block, state, pindex, coins, &fClean)) - return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); + return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); pindexState = pindex->pprev; if (!fClean) { nGoodTransactions = 0; @@ -3034,7 +3034,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth return true; } if (pindexFailure) - return error("VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions); + return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions); // check level 4: try reconnecting blocks if (nCheckLevel >= 4) { @@ -3045,9 +3045,9 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth pindex = chainActive.Next(pindex); CBlock block; if (!ReadBlockFromDisk(block, pindex)) - return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); + return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); if (!ConnectBlock(block, state, pindex, coins)) - return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); + return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); } } @@ -3093,18 +3093,18 @@ bool InitBlockIndex() { CDiskBlockPos blockPos; CValidationState state; if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime())) - return error("LoadBlockIndex() : FindBlockPos failed"); + return error("LoadBlockIndex(): FindBlockPos failed"); if (!WriteBlockToDisk(block, blockPos)) - return error("LoadBlockIndex() : writing genesis block to disk failed"); + return error("LoadBlockIndex(): writing genesis block to disk failed"); CBlockIndex *pindex = AddToBlockIndex(block); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) - return error("LoadBlockIndex() : genesis block not accepted"); + return error("LoadBlockIndex(): genesis block not accepted"); if (!ActivateBestChain(state, &block)) - return error("LoadBlockIndex() : genesis block cannot be activated"); + return error("LoadBlockIndex(): genesis block cannot be activated"); // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); } catch (const std::runtime_error& e) { - return error("LoadBlockIndex() : failed to initialize block database: %s", e.what()); + return error("LoadBlockIndex(): failed to initialize block database: %s", e.what()); } } @@ -3204,7 +3204,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) } } } catch (const std::exception& e) { - LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what()); + LogPrintf("%s: Deserialize or I/O error - %s", __func__, e.what()); } } } catch (const std::runtime_error& e) { @@ -3268,7 +3268,7 @@ string GetWarnings(string strFor) return strStatusBar; else if (strFor == "rpc") return strRPC; - assert(!"GetWarnings() : invalid parameter"); + assert(!"GetWarnings(): invalid parameter"); return "error"; } @@ -3835,7 +3835,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vWorkQueue.push_back(inv.hash); vEraseQueue.push_back(inv.hash); - LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s : accepted %s (poolsz %u)\n", + LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n", pfrom->id, pfrom->cleanSubVer, tx.GetHash().ToString(), mempool.mapTx.size()); @@ -4297,7 +4297,7 @@ bool ProcessMessages(CNode* pfrom) memcpy(&nChecksum, &hash, sizeof(nChecksum)); if (nChecksum != hdr.nChecksum) { - LogPrintf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", + LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", strCommand, nMessageSize, nChecksum, hdr.nChecksum); continue; } @@ -4315,12 +4315,12 @@ bool ProcessMessages(CNode* pfrom) if (strstr(e.what(), "end of data")) { // Allow exceptions from under-length message on vRecv - LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what()); + LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what()); } else if (strstr(e.what(), "size too large")) { // Allow exceptions from over-long size - LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand, nMessageSize, e.what()); + LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", strCommand, nMessageSize, e.what()); } else { diff --git a/src/miner.cpp b/src/miner.cpp index 5cc4a92791d..e359654d7ba 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -332,7 +332,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) CValidationState state; if (!TestBlockValidity(state, *pblock, pindexPrev, false, false)) - throw std::runtime_error("CreateNewBlock() : TestBlockValidity failed"); + throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed"); } return pblocktemplate.release(); @@ -415,7 +415,7 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese { LOCK(cs_main); if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash()) - return error("BitcoinMiner : generated block is stale"); + return error("BitcoinMiner: generated block is stale"); } // Remove key from key pool @@ -430,7 +430,7 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese // Process this block the same as if we had received it from another node CValidationState state; if (!ProcessNewBlock(state, NULL, pblock)) - return error("BitcoinMiner : ProcessNewBlock, block not accepted"); + return error("BitcoinMiner: ProcessNewBlock, block not accepted"); return true; } diff --git a/src/net.cpp b/src/net.cpp index bba80535e5f..e4ab9d706d8 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1020,7 +1020,7 @@ void ThreadMapPort() catch (const boost::thread_interrupted&) { r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); - LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r); + LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); freeUPNPDevlist(devlist); devlist = 0; FreeUPNPUrls(&urls); throw; @@ -1797,21 +1797,21 @@ bool CAddrDB::Write(const CAddrMan& addr) FILE *file = fopen(pathTmp.string().c_str(), "wb"); CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); if (fileout.IsNull()) - return error("%s : Failed to open file %s", __func__, pathTmp.string()); + return error("%s: Failed to open file %s", __func__, pathTmp.string()); // Write and commit header, data try { fileout << ssPeers; } catch (const std::exception& e) { - return error("%s : Serialize or I/O error - %s", __func__, e.what()); + return error("%s: Serialize or I/O error - %s", __func__, e.what()); } FileCommit(fileout.Get()); fileout.fclose(); // replace existing peers.dat, if any, with new peers.dat.XXXX if (!RenameOver(pathTmp, pathAddr)) - return error("%s : Rename-into-place failed", __func__); + return error("%s: Rename-into-place failed", __func__); return true; } @@ -1822,7 +1822,7 @@ bool CAddrDB::Read(CAddrMan& addr) FILE *file = fopen(pathAddr.string().c_str(), "rb"); CAutoFile filein(file, SER_DISK, CLIENT_VERSION); if (filein.IsNull()) - return error("%s : Failed to open file %s", __func__, pathAddr.string()); + return error("%s: Failed to open file %s", __func__, pathAddr.string()); // use file size to size memory buffer int fileSize = boost::filesystem::file_size(pathAddr); @@ -1840,7 +1840,7 @@ bool CAddrDB::Read(CAddrMan& addr) filein >> hashIn; } catch (const std::exception& e) { - return error("%s : Deserialize or I/O error - %s", __func__, e.what()); + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } filein.fclose(); @@ -1849,7 +1849,7 @@ bool CAddrDB::Read(CAddrMan& addr) // verify stored checksum matches input data uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); if (hashIn != hashTmp) - return error("%s : Checksum mismatch, data corrupted", __func__); + return error("%s: Checksum mismatch, data corrupted", __func__); unsigned char pchMsgTmp[4]; try { @@ -1858,13 +1858,13 @@ bool CAddrDB::Read(CAddrMan& addr) // ... verify the network matches ours if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) - return error("%s : Invalid network magic number", __func__); + return error("%s: Invalid network magic number", __func__); // de-serialize address data into one CAddrMan object ssPeers >> addr; } catch (const std::exception& e) { - return error("%s : Deserialize or I/O error - %s", __func__, e.what()); + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } return true; diff --git a/src/pow.cpp b/src/pow.cpp index 90bbff0a33a..e49f0d104c2 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -89,11 +89,11 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) // Check range if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit()) - return error("CheckProofOfWork() : nBits below minimum work"); + return error("CheckProofOfWork(): nBits below minimum work"); // Check proof of work matches claimed amount if (UintToArith256(hash) > bnTarget) - return error("CheckProofOfWork() : hash doesn't match nBits"); + return error("CheckProofOfWork(): hash doesn't match nBits"); return true; } diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 848d4d3e60c..606dbea7985 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -94,7 +94,7 @@ CAmount CTransaction::GetValueOut() const { nValueOut += it->nValue; if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut)) - throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); + throw std::runtime_error("CTransaction::GetValueOut(): value out of range"); } return nValueOut; } diff --git a/src/protocol.cpp b/src/protocol.cpp index 2dfded43bea..74ac706d60c 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -66,7 +66,7 @@ bool CMessageHeader::IsValid() const // Message size if (nMessageSize > MAX_SIZE) { - LogPrintf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize); + LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize); return false; } @@ -117,7 +117,7 @@ CInv::CInv(const std::string& strType, const uint256& hashIn) } } if (i == ARRAYLEN(ppszTypeName)) - throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType)); + throw std::out_of_range(strprintf("CInv::CInv(string, uint256): unknown type '%s'", strType)); hash = hashIn; } @@ -134,7 +134,7 @@ bool CInv::IsKnownType() const const char* CInv::GetCommand() const { if (!IsKnownType()) - throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type)); + throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type)); return ppszTypeName[type]; } diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index bfb5bf3fec9..162ecdba4ef 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -114,7 +114,7 @@ public: case CT_NEW: if(inModel) { - qWarning() << "AddressTablePriv::updateEntry : Warning: Got CT_NEW, but entry is already in model"; + qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_NEW, but entry is already in model"; break; } parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex); @@ -124,7 +124,7 @@ public: case CT_UPDATED: if(!inModel) { - qWarning() << "AddressTablePriv::updateEntry : Warning: Got CT_UPDATED, but entry is not in model"; + qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_UPDATED, but entry is not in model"; break; } lower->type = newEntryType; @@ -134,7 +134,7 @@ public: case CT_DELETED: if(!inModel) { - qWarning() << "AddressTablePriv::updateEntry : Warning: Got CT_DELETED, but entry is not in model"; + qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_DELETED, but entry is not in model"; break; } parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 493cdd6dd23..03d94f2e13f 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -212,14 +212,14 @@ static void ShowProgress(ClientModel *clientmodel, const std::string &title, int static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections) { - // Too noisy: qDebug() << "NotifyNumConnectionsChanged : " + QString::number(newNumConnections); + // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections); QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection, Q_ARG(int, newNumConnections)); } static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status) { - qDebug() << "NotifyAlertChanged : " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status); + qDebug() << "NotifyAlertChanged: " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status); QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(hash.GetHex())), Q_ARG(int, status)); diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 39171c89eb5..4c1e898020d 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -32,18 +32,18 @@ bool PaymentRequestPlus::parse(const QByteArray& data) { bool parseOK = paymentRequest.ParseFromArray(data.data(), data.size()); if (!parseOK) { - qWarning() << "PaymentRequestPlus::parse : Error parsing payment request"; + qWarning() << "PaymentRequestPlus::parse: Error parsing payment request"; return false; } if (paymentRequest.payment_details_version() > 1) { - qWarning() << "PaymentRequestPlus::parse : Received up-version payment details, version=" << paymentRequest.payment_details_version(); + qWarning() << "PaymentRequestPlus::parse: Received up-version payment details, version=" << paymentRequest.payment_details_version(); return false; } parseOK = details.ParseFromString(paymentRequest.serialized_payment_details()); if (!parseOK) { - qWarning() << "PaymentRequestPlus::parse : Error parsing payment details"; + qWarning() << "PaymentRequestPlus::parse: Error parsing payment details"; paymentRequest.Clear(); return false; } @@ -83,17 +83,17 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c digestAlgorithm = EVP_sha1(); } else if (paymentRequest.pki_type() == "none") { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: pki_type == none"; + qWarning() << "PaymentRequestPlus::getMerchant: Payment request: pki_type == none"; return false; } else { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type()); + qWarning() << "PaymentRequestPlus::getMerchant: Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type()); return false; } payments::X509Certificates certChain; if (!certChain.ParseFromString(paymentRequest.pki_data())) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error parsing pki_data"; + qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error parsing pki_data"; return false; } @@ -103,12 +103,12 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size()); QSslCertificate qCert(certData, QSsl::Der); if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate expired or not yet active: " << qCert; + qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate expired or not yet active: " << qCert; return false; } #if QT_VERSION >= 0x050000 if (qCert.isBlacklisted()) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate blacklisted: " << qCert; + qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate blacklisted: " << qCert; return false; } #endif @@ -118,7 +118,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c certs.push_back(cert); } if (certs.empty()) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: empty certificate chain"; + qWarning() << "PaymentRequestPlus::getMerchant: Payment request: empty certificate chain"; return false; } @@ -134,7 +134,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c // load the signing cert into it and verify. X509_STORE_CTX *store_ctx = X509_STORE_CTX_new(); if (!store_ctx) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error creating X509_STORE_CTX"; + qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error creating X509_STORE_CTX"; return false; } @@ -191,7 +191,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c } catch (const SSLVerifyError& err) { fResult = false; - qWarning() << "PaymentRequestPlus::getMerchant : SSL error: " << err.what(); + qWarning() << "PaymentRequestPlus::getMerchant: SSL error: " << err.what(); } if (website) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 46ffd055a55..a00916bf7f9 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -97,7 +97,7 @@ static QList savedPaymentRequests; static void ReportInvalidCertificate(const QSslCertificate& cert) { - qDebug() << "ReportInvalidCertificate : Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName); + qDebug() << "ReportInvalidCertificate: Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName); } // @@ -171,7 +171,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) continue; } } - qWarning() << "PaymentServer::LoadRootCAs : Loaded " << nRootCerts << " root certificates"; + qWarning() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts << " root certificates"; // Project for another day: // Fetch certificate revocation lists, and add them to certStore. @@ -244,7 +244,7 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) { // Printing to debug.log is about the best we can do here, the // GUI hasn't started yet so we can't pop up a message box. - qWarning() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg; + qWarning() << "PaymentServer::ipcSendCommandLine: Payment request file does not exist: " << arg; } } } @@ -368,10 +368,10 @@ void PaymentServer::initNetManager() if (optionsModel->getProxySettings(proxy)) { netManager->setProxy(proxy); - qDebug() << "PaymentServer::initNetManager : Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port(); + qDebug() << "PaymentServer::initNetManager: Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port(); } else - qDebug() << "PaymentServer::initNetManager : No active proxy server found."; + qDebug() << "PaymentServer::initNetManager: No active proxy server found."; connect(netManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(netRequestFinished(QNetworkReply*))); @@ -415,12 +415,12 @@ void PaymentServer::handleURIOrFile(const QString& s) if (fetchUrl.isValid()) { - qDebug() << "PaymentServer::handleURIOrFile : fetchRequest(" << fetchUrl << ")"; + qDebug() << "PaymentServer::handleURIOrFile: fetchRequest(" << fetchUrl << ")"; fetchRequest(fetchUrl); } else { - qWarning() << "PaymentServer::handleURIOrFile : Invalid URL: " << fetchUrl; + qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl; emit message(tr("URI handling"), tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()), CClientUIInterface::ICON_WARNING); @@ -585,10 +585,10 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins recipient.address = addresses.join("
"); if (!recipient.authenticatedMerchant.isEmpty()) { - qDebug() << "PaymentServer::processPaymentRequest : Secure payment request from " << recipient.authenticatedMerchant; + qDebug() << "PaymentServer::processPaymentRequest: Secure payment request from " << recipient.authenticatedMerchant; } else { - qDebug() << "PaymentServer::processPaymentRequest : Insecure payment request to " << addresses.join(", "); + qDebug() << "PaymentServer::processPaymentRequest: Insecure payment request to " << addresses.join(", "); } return true; @@ -643,7 +643,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien else { // This should never happen, because sending coins should have // just unlocked the wallet and refilled the keypool. - qWarning() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set"; + qWarning() << "PaymentServer::fetchPaymentACK: Error getting refund key, refund_to not set"; } } @@ -655,7 +655,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien } else { // This should never happen, either. - qWarning() << "PaymentServer::fetchPaymentACK : Error serializing payment message"; + qWarning() << "PaymentServer::fetchPaymentACK: Error serializing payment message"; } } @@ -694,7 +694,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) SendCoinsRecipient recipient; if (!request.parse(data)) { - qWarning() << "PaymentServer::netRequestFinished : Error parsing payment request"; + qWarning() << "PaymentServer::netRequestFinished: Error parsing payment request"; emit message(tr("Payment request error"), tr("Payment request cannot be parsed!"), CClientUIInterface::MSG_ERROR); @@ -712,7 +712,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) QString msg = tr("Bad response from server %1") .arg(reply->request().url().toString()); - qWarning() << "PaymentServer::netRequestFinished : " << msg; + qWarning() << "PaymentServer::netRequestFinished: " << msg; emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); } else @@ -728,7 +728,7 @@ void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList QString errString; foreach (const QSslError& err, errs) { - qWarning() << "PaymentServer::reportSslErrors : " << err; + qWarning() << "PaymentServer::reportSslErrors: " << err; errString += err.errorString() + "\n"; } emit message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 6771e771800..df1afbfaaae 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -94,7 +94,7 @@ public: */ void updateWallet(const uint256 &hash, int status, bool showTransaction) { - qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status); + qDebug() << "TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.ToString()) + " " + QString::number(status); // Find bounds of this transaction in model QList::iterator lower = qLowerBound( @@ -122,7 +122,7 @@ public: case CT_NEW: if(inModel) { - qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model"; + qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model"; break; } if(showTransaction) @@ -132,7 +132,7 @@ public: std::map::iterator mi = wallet->mapWallet.find(hash); if(mi == wallet->mapWallet.end()) { - qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet"; + qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet"; break; } // Added -- insert at the right position @@ -154,7 +154,7 @@ public: case CT_DELETED: if(!inModel) { - qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model"; + qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model"; break; } // Removed -- remove entire transaction from table @@ -664,7 +664,7 @@ public: void invoke(QObject *ttm) { QString strHash = QString::fromStdString(hash.GetHex()); - qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status); + qDebug() << "NotifyTransactionChanged: " + strHash + " status= " + QString::number(status); QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection, Q_ARG(QString, strHash), Q_ARG(int, status), diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 57596b77bd7..4a7abf999cb 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -452,7 +452,7 @@ static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, QString strLabel = QString::fromStdString(label); QString strPurpose = QString::fromStdString(purpose); - qDebug() << "NotifyAddressBookChanged : " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status); + qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status); QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection, Q_ARG(QString, strAddress), Q_ARG(QString, strLabel), diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 24a4d7c22cc..28371771a9e 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -319,7 +319,7 @@ void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew) if (pwalletMain->IsLocked()) { strError = "Error: Wallet locked, unable to create transaction!"; - LogPrintf("SendMoney() : %s", strError); + LogPrintf("SendMoney(): %s", strError); throw JSONRPCError(RPC_WALLET_ERROR, strError); } @@ -333,7 +333,7 @@ void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew) { if (nValue + nFeeRequired > pwalletMain->GetBalance()) strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired)); - LogPrintf("SendMoney() : %s\n", strError); + LogPrintf("SendMoney(): %s\n", strError); throw JSONRPCError(RPC_WALLET_ERROR, strError); } if (!pwalletMain->CommitTransaction(wtxNew, reservekey)) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 8a06f3d1187..0cee1a0116d 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -60,7 +60,7 @@ bool CastToBool(const valtype& vch) static inline void popstack(vector& stack) { if (stack.empty()) - throw runtime_error("popstack() : stack empty"); + throw runtime_error("popstack(): stack empty"); stack.pop_back(); } diff --git a/src/script/script.h b/src/script/script.h index 78fd12cd290..8b36aa2f506 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -391,7 +391,7 @@ public: CScript& operator<<(opcodetype opcode) { if (opcode < 0 || opcode > 0xff) - throw std::runtime_error("CScript::operator<<() : invalid opcode"); + throw std::runtime_error("CScript::operator<<(): invalid opcode"); insert(end(), (unsigned char)opcode); return *this; } diff --git a/src/serialize.h b/src/serialize.h index e4a4039c719..a62760a7938 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -249,7 +249,7 @@ uint64_t ReadCompactSize(Stream& is) throw std::ios_base::failure("non-canonical ReadCompactSize()"); } if (nSizeRet > (uint64_t)MAX_SIZE) - throw std::ios_base::failure("ReadCompactSize() : size too large"); + throw std::ios_base::failure("ReadCompactSize(): size too large"); return nSizeRet; } diff --git a/src/streams.h b/src/streams.h index 6bd6d2b920f..bd8568b1af3 100644 --- a/src/streams.h +++ b/src/streams.h @@ -224,7 +224,7 @@ public: { if (nReadPosNext > vch.size()) { - throw std::ios_base::failure("CDataStream::read() : end of data"); + throw std::ios_base::failure("CDataStream::read(): end of data"); } memcpy(pch, &vch[nReadPos], nSize); nReadPos = 0; @@ -244,7 +244,7 @@ public: if (nReadPosNext >= vch.size()) { if (nReadPosNext > vch.size()) - throw std::ios_base::failure("CDataStream::ignore() : end of data"); + throw std::ios_base::failure("CDataStream::ignore(): end of data"); nReadPos = 0; vch.clear(); return (*this); @@ -374,18 +374,18 @@ public: CAutoFile& read(char* pch, size_t nSize) { if (!file) - throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); + throw std::ios_base::failure("CAutoFile::read: file handle is NULL"); if (fread(pch, 1, nSize, file) != nSize) - throw std::ios_base::failure(feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); + throw std::ios_base::failure(feof(file) ? "CAutoFile::read: end of file" : "CAutoFile::read: fread failed"); return (*this); } CAutoFile& write(const char* pch, size_t nSize) { if (!file) - throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); + throw std::ios_base::failure("CAutoFile::write: file handle is NULL"); if (fwrite(pch, 1, nSize, file) != nSize) - throw std::ios_base::failure("CAutoFile::write : write failed"); + throw std::ios_base::failure("CAutoFile::write: write failed"); return (*this); } @@ -401,7 +401,7 @@ public: { // Serialize to this stream if (!file) - throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); + throw std::ios_base::failure("CAutoFile::operator<<: file handle is NULL"); ::Serialize(*this, obj, nType, nVersion); return (*this); } @@ -411,7 +411,7 @@ public: { // Unserialize from this stream if (!file) - throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); + throw std::ios_base::failure("CAutoFile::operator>>: file handle is NULL"); ::Unserialize(*this, obj, nType, nVersion); return (*this); } @@ -452,7 +452,7 @@ protected: return false; size_t read = fread((void*)&vchBuf[pos], 1, readNow, src); if (read == 0) { - throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed"); + throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill: end of file" : "CBufferedFile::Fill: fread failed"); } else { nSrcPos += read; return true; diff --git a/src/test/bignum.h b/src/test/bignum.h index 365b17a1c5d..e7aeee9db60 100644 --- a/src/test/bignum.h +++ b/src/test/bignum.h @@ -37,14 +37,14 @@ public: if (!BN_copy(this, &b)) { BN_clear_free(this); - throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed"); + throw bignum_error("CBigNum::CBigNum(const CBigNum&): BN_copy failed"); } } CBigNum& operator=(const CBigNum& b) { if (!BN_copy(this, &b)) - throw bignum_error("CBigNum::operator= : BN_copy failed"); + throw bignum_error("CBigNum::operator=: BN_copy failed"); return (*this); } @@ -151,7 +151,7 @@ inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) { CBigNum r; if (!BN_add(&r, &a, &b)) - throw bignum_error("CBigNum::operator+ : BN_add failed"); + throw bignum_error("CBigNum::operator+: BN_add failed"); return r; } @@ -159,7 +159,7 @@ inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) { CBigNum r; if (!BN_sub(&r, &a, &b)) - throw bignum_error("CBigNum::operator- : BN_sub failed"); + throw bignum_error("CBigNum::operator-: BN_sub failed"); return r; } diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 662f765a0bd..ea41dbcde23 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -27,7 +27,7 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); if (nIn >= txTo.vin.size()) { - printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); + printf("ERROR: SignatureHash(): nIn=%d out of range\n", nIn); return one; } CMutableTransaction txTmp(txTo); @@ -58,7 +58,7 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un unsigned int nOut = nIn; if (nOut >= txTmp.vout.size()) { - printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); + printf("ERROR: SignatureHash(): nOut=%d out of range\n", nOut); return one; } txTmp.vout.resize(nOut+1); diff --git a/src/txdb.cpp b/src/txdb.cpp index f9326e5e2ea..da271bd5d1a 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -141,7 +141,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { } pcursor->Next(); } catch (const std::exception& e) { - return error("%s : Deserialize or I/O error - %s", __func__, e.what()); + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } } stats.nHeight = mapBlockIndex.find(GetBestBlock())->second->nHeight; @@ -223,14 +223,14 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nTx = diskindex.nTx; if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits)) - return error("LoadBlockIndex() : CheckProofOfWork failed: %s", pindexNew->ToString()); + return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString()); pcursor->Next(); } else { break; // if shutdown requested or finished loading block index } } catch (const std::exception& e) { - return error("%s : Deserialize or I/O error - %s", __func__, e.what()); + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 01bf1ec080a..6e0f7e9c5a6 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -192,7 +192,7 @@ private: // Neither or both fee and priority sufficient to get confirmed: // don't know why they got confirmed. } - LogPrint("estimatefee", "Seen TX confirm: %s : %s fee/%g priority, took %d blocks\n", + LogPrint("estimatefee", "Seen TX confirm: %s: %s fee/%g priority, took %d blocks\n", assignedTo, feeRate.ToString(), dPriority, nBlocksAgo); } @@ -658,7 +658,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const minerPolicyEstimator->Write(fileout); } catch (const std::exception&) { - LogPrintf("CTxMemPool::WriteFeeEstimates() : unable to write policy estimator data (non-fatal)"); + LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)"); return false; } return true; @@ -671,13 +671,13 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein) int nVersionRequired, nVersionThatWrote; filein >> nVersionRequired >> nVersionThatWrote; if (nVersionRequired > CLIENT_VERSION) - return error("CTxMemPool::ReadFeeEstimates() : up-version (%d) fee estimate file", nVersionRequired); + return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired); LOCK(cs); minerPolicyEstimator->Read(filein, minRelayFee); } catch (const std::exception&) { - LogPrintf("CTxMemPool::ReadFeeEstimates() : unable to read policy estimator data (non-fatal)"); + LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)"); return false; } return true; diff --git a/src/wallet.cpp b/src/wallet.cpp index 1fe05521093..d66a4465c53 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -88,7 +88,7 @@ CPubKey CWallet::GenerateNewKey() nTimeFirstKey = nCreationTime; if (!AddKeyPubKey(secret, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed"); + throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); return pubkey; } @@ -619,7 +619,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow)); } else - LogPrintf("AddToWallet() : found %s in block %s not in index\n", + LogPrintf("AddToWallet(): found %s in block %s not in index\n", wtxIn.GetHash().ToString(), wtxIn.hashBlock.ToString()); } @@ -1616,7 +1616,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) if (!wtxNew.AcceptToMemoryPool(false)) { // This must not fail. The transaction has already been signed and recorded. - LogPrintf("CommitTransaction() : Error: Transaction not valid"); + LogPrintf("CommitTransaction(): Error: Transaction not valid"); return false; } wtxNew.RelayWalletTransaction(); @@ -1809,7 +1809,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (!setKeyPool.empty()) nEnd = *(--setKeyPool.end()) + 1; if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) - throw runtime_error("TopUpKeyPool() : writing generated key failed"); + throw runtime_error("TopUpKeyPool(): writing generated key failed"); setKeyPool.insert(nEnd); LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size()); } @@ -1836,9 +1836,9 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool) nIndex = *(setKeyPool.begin()); setKeyPool.erase(setKeyPool.begin()); if (!walletdb.ReadPool(nIndex, keypool)) - throw runtime_error("ReserveKeyFromKeyPool() : read failed"); + throw runtime_error("ReserveKeyFromKeyPool(): read failed"); if (!HaveKey(keypool.vchPubKey.GetID())) - throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); + throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool"); assert(keypool.vchPubKey.IsValid()); LogPrintf("keypool reserve %d\n", nIndex); } @@ -2086,11 +2086,11 @@ void CWallet::GetAllReserveKeys(set& setAddress) const { CKeyPool keypool; if (!walletdb.ReadPool(id, keypool)) - throw runtime_error("GetAllReserveKeyHashes() : read failed"); + throw runtime_error("GetAllReserveKeyHashes(): read failed"); assert(keypool.vchPubKey.IsValid()); CKeyID keyID = keypool.vchPubKey.GetID(); if (!HaveKey(keyID)) - throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool"); + throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool"); setAddress.insert(keyID); } } @@ -2303,7 +2303,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) { vMerkleBranch.clear(); nIndex = -1; - LogPrintf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); + LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n"); return 0; } diff --git a/src/wallet.h b/src/wallet.h index f9cbd3a849b..aaff00b7166 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -320,14 +320,14 @@ public: CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const { if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetCredit() : value out of range"); + throw std::runtime_error("CWallet::GetCredit(): value out of range"); return ((IsMine(txout) & filter) ? txout.nValue : 0); } bool IsChange(const CTxOut& txout) const; CAmount GetChange(const CTxOut& txout) const { if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetChange() : value out of range"); + throw std::runtime_error("CWallet::GetChange(): value out of range"); return (IsChange(txout) ? txout.nValue : 0); } bool IsMine(const CTransaction& tx) const @@ -349,7 +349,7 @@ public: { nDebit += GetDebit(txin, filter); if (!MoneyRange(nDebit)) - throw std::runtime_error("CWallet::GetDebit() : value out of range"); + throw std::runtime_error("CWallet::GetDebit(): value out of range"); } return nDebit; } @@ -360,7 +360,7 @@ public: { nCredit += GetCredit(txout, filter); if (!MoneyRange(nCredit)) - throw std::runtime_error("CWallet::GetCredit() : value out of range"); + throw std::runtime_error("CWallet::GetCredit(): value out of range"); } return nCredit; } @@ -371,7 +371,7 @@ public: { nChange += GetChange(txout); if (!MoneyRange(nChange)) - throw std::runtime_error("CWallet::GetChange() : value out of range"); + throw std::runtime_error("CWallet::GetChange(): value out of range"); } return nChange; } @@ -804,7 +804,7 @@ public: const CTxOut &txout = vout[i]; nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE); if (!MoneyRange(nCredit)) - throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + throw std::runtime_error("CWalletTx::GetAvailableCredit(): value out of range"); } } @@ -847,7 +847,7 @@ public: const CTxOut &txout = vout[i]; nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY); if (!MoneyRange(nCredit)) - throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + throw std::runtime_error("CWalletTx::GetAvailableCredit(): value out of range"); } } diff --git a/src/walletdb.cpp b/src/walletdb.cpp index d4d2e167405..b2daf036ff7 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -210,7 +210,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, listclose(); - throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB"); + throw runtime_error("CWalletDB::ListAccountCreditDebit(): error scanning DB"); } // Unserialize From bd2b73bb9b416139a0fbaf6eb2131356a59184a6 Mon Sep 17 00:00:00 2001 From: Vitalii Demianets Date: Wed, 14 Jan 2015 10:25:06 +0100 Subject: [PATCH 0217/2337] TRIVIAL: fix misleading comment --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 629e0dcbc01..f43d8c58b63 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -744,7 +744,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) // non-standard. Note that this EvalScript() call will // be quick, because if there are any operations // beside "push data" in the scriptSig - // IsStandard() will have already returned false + // IsStandardTx() will have already returned false // and this method isn't called. vector > stack; if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) From 5a809ef0f009bb6c412b5bf5f846feecfb133d70 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Sun, 18 Jan 2015 15:24:09 +0800 Subject: [PATCH 0218/2337] depends: fix typos --- depends/README | 2 +- depends/funcs.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/README b/depends/README index fed2f9b5ab9..55e7222697f 100644 --- a/depends/README +++ b/depends/README @@ -7,7 +7,7 @@ There are several features that make it different from most similar systems: In theory, binaries for any target OS/architecture can be created, from a builder running any OS/architecture. In practice, build-side tools must be -specified when the defaults don't fit, and packages must be ammended to work +specified when the defaults don't fit, and packages must be amended to work on new hosts. For now, a build architecture of x86_64 is assumed, either on Linux or OSX. diff --git a/depends/funcs.mk b/depends/funcs.mk index 337634253f5..b407737f7f4 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -205,7 +205,7 @@ endef # These functions create the build targets for each package. They must be # broken down into small steps so that each part is done for all packages # before moving on to the next step. Otherwise, a package's info -# (build-id for example) would only be avilable to another package if it +# (build-id for example) would only be available to another package if it # happened to be computed already. #set the type for host/build packages. From faf0af49f57f3b6f7161ecd5ddc80f2a629efc68 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 19 Jan 2015 19:16:49 +0000 Subject: [PATCH 0219/2337] Suggest --disable-wallet when libdb_cxx headers are missing --- build-aux/m4/bitcoin_find_bdb48.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4 index f3b14461eb9..0bf558d25b5 100644 --- a/build-aux/m4/bitcoin_find_bdb48.m4 +++ b/build-aux/m4/bitcoin_find_bdb48.m4 @@ -38,7 +38,7 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ done if test "x$bdbpath" = "xX"; then AC_MSG_RESULT([no]) - AC_MSG_ERROR(libdb_cxx headers missing) + AC_MSG_ERROR([libdb_cxx headers missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) elif test "x$bdb48path" = "xX"; then BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx) AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[ From 34c61813a401be8f65ebadcc6fe2b82c1a83b28b Mon Sep 17 00:00:00 2001 From: Matt Bogosian Date: Thu, 22 Jan 2015 19:54:20 -0800 Subject: [PATCH 0220/2337] Fix README link from util.sh -> util.py. --- qa/rpc-tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md index 3e916a7688d..02170d13ec3 100644 --- a/qa/rpc-tests/README.md +++ b/qa/rpc-tests/README.md @@ -12,7 +12,7 @@ Base class for new regression tests. ### [listtransactions.py](listtransactions.py) Tests for the listtransactions RPC call. -### [util.py](util.sh) +### [util.py](util.py) Generally useful functions. Bash-based tests, to be ported to Python: From 1fa89a54e8c207564ea7acd262e6389174feaed9 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Sat, 24 Jan 2015 06:30:06 +0300 Subject: [PATCH 0221/2337] fix _code_ snippet in gitian-building.md Trivial typo-like fix --- doc/gitian-building.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index efa5ef17dc1..25d3b8390c5 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -326,6 +326,7 @@ At any time you can check the package installation and build progress with ```bash tail -f var/install.log tail -f var/build.log +``` Output from `gbuild` will look something like From ee932025c1a318943a6b101be9fe7a4a2e10648c Mon Sep 17 00:00:00 2001 From: bikinibabe Date: Sat, 31 Jan 2015 15:07:55 -0500 Subject: [PATCH 0222/2337] Changed pronouns for correctness and inclusivity --- doc/build-unix.md | 2 +- qa/rpc-tests/wallet.py | 2 +- src/checkqueue.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 5f60dff06c8..0984f689a83 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -196,7 +196,7 @@ Hardening enables the following features: * Position Independent Executable Build position independent code to take advantage of Address Space Layout Randomization offered by some kernels. An attacker who is able to cause execution of code at an arbitrary - memory location is thwarted if he doesn't know where anything useful is located. + memory location is thwarted if he or she doesn't know where anything useful is located. The stack and heap are randomly located by default but this allows the code section to be randomly located as well. diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index f280ac380e7..3e63493dc6e 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -61,7 +61,7 @@ class WalletTest (BitcoinTestFramework): walletinfo = self.nodes[0].getwalletinfo() assert_equal(walletinfo['immature_balance'], 0) - # Have node0 mine a block, thus he will collect his own fee. + # Have node0 mine a block, thus they will collect their own fee. self.nodes[0].setgenerate(True, 1) self.sync_all() diff --git a/src/checkqueue.h b/src/checkqueue.h index b8e2a17c763..7ca825c16fc 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -81,7 +81,7 @@ private: fAllOk &= fOk; nTodo -= nNow; if (nTodo == 0 && !fMaster) - // We processed the last element; inform the master he can exit and return the result + // We processed the last element; inform the master he or she can exit and return the result condMaster.notify_one(); } else { // first iteration From 1371e6f5db88941c3b3c70d7a13b0cbf150ebf66 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Sat, 31 Jan 2015 02:54:55 +0000 Subject: [PATCH 0223/2337] Change "insane" to "absurd" (referring to high fees) in text strings and identifiers. Note that this will also require translation changes in Transifex for the key "A fee higher than %1 is considered an insanely high fee." which is now "A fee higher than %1 is considered an absurdly high fee." Signed-off-by: Daira Hopwood --- src/main.cpp | 6 +++--- src/main.h | 2 +- src/qt/sendcoinsdialog.cpp | 4 ++-- src/qt/walletmodel.cpp | 4 ++-- src/qt/walletmodel.h | 2 +- src/wallet.cpp | 4 ++-- src/wallet.h | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7cc69c318b1..35118cebe5c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -904,7 +904,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fRejectInsaneFee) + bool* pfMissingInputs, bool fRejectAbsurdFee) { AssertLockHeld(cs_main); if (pfMissingInputs) @@ -1063,8 +1063,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa dFreeCount += nSize; } - if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) - return error("AcceptToMemoryPool: insane fees %s, %d > %d", + if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) + return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d", hash.ToString(), nFees, ::minRelayTxFee.GetFee(nSize) * 10000); diff --git a/src/main.h b/src/main.h index a7360d2f700..936cd43e99e 100644 --- a/src/main.h +++ b/src/main.h @@ -205,7 +205,7 @@ void FlushStateToDisk(); /** (try to) add transaction to memory pool **/ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fRejectInsaneFee=false); + bool* pfMissingInputs, bool fRejectAbsurdFee=false); struct CNodeStateStats { diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 9e8743d8052..5aef2d7539b 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -526,8 +526,8 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn msgParams.first = tr("The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); msgParams.second = CClientUIInterface::MSG_ERROR; break; - case WalletModel::InsaneFee: - msgParams.first = tr("A fee higher than %1 is considered an insanely high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000)); + case WalletModel::AbsurdFee: + msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000)); break; case WalletModel::PaymentRequestExpired: msgParams.first = tr("Payment request expired!"); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 57596b77bd7..3893def9c24 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -279,9 +279,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact return TransactionCreationFailed; } - // reject insane fee > 0.1 bitcoin + // reject absurdly high fee > 0.1 bitcoin if (nFeeRequired > 10000000) - return InsaneFee; + return AbsurdFee; } return SendCoinsReturn(OK); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 9916d11f939..4a9a12beaa9 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -111,7 +111,7 @@ public: DuplicateAddress, TransactionCreationFailed, // Error returned when wallet is still locked TransactionCommitFailed, - InsaneFee, + AbsurdFee, PaymentRequestExpired }; diff --git a/src/wallet.cpp b/src/wallet.cpp index 1fe05521093..31ceda9c316 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -2365,9 +2365,9 @@ int CMerkleTx::GetBlocksToMaturity() const } -bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectInsaneFee) +bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) { CValidationState state; - return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectInsaneFee); + return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee); } diff --git a/src/wallet.h b/src/wallet.h index f9cbd3a849b..71d9d1fb6b2 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -548,7 +548,7 @@ public: int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; } int GetBlocksToMaturity() const; - bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectInsaneFee=true); + bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); }; /** From 80ad135a5e54e8a065fee5ef36e57034679111ab Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 13 Jan 2015 03:15:39 +0100 Subject: [PATCH 0224/2337] Change IsDERSignature to BIP66 implementation --- src/script/interpreter.cpp | 126 ++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 8a06f3d1187..0a5bef601cb 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -93,76 +93,76 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { * in which case a single 0 byte is necessary and even required). * * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 + * + * This function is consensus-critical since BIP66. */ -bool static IsDERSignature(const valtype &vchSig) { +bool static IsValidSignatureEncoding(const std::vector &sig) { + // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] + // * total-length: 1-byte length descriptor of everything that follows, + // excluding the sighash byte. + // * R-length: 1-byte length descriptor of the R value that follows. + // * R: arbitrary-length big-endian encoded R value. It must use the shortest + // possible encoding for a positive integers (which means no null bytes at + // the start, except a single one when the next byte has its highest bit set). + // * S-length: 1-byte length descriptor of the S value that follows. + // * S: arbitrary-length big-endian encoded S value. The same rules apply. + // * sighash: 1-byte value indicating what data is hashed (not part of the DER + // signature) - if (vchSig.size() < 9) { - // Non-canonical signature: too short - return false; - } - if (vchSig.size() > 73) { - // Non-canonical signature: too long - return false; - } - if (vchSig[0] != 0x30) { - // Non-canonical signature: wrong type - return false; - } - if (vchSig[1] != vchSig.size()-3) { - // Non-canonical signature: wrong length marker - return false; - } - unsigned int nLenR = vchSig[3]; - if (5 + nLenR >= vchSig.size()) { - // Non-canonical signature: S length misplaced - return false; - } - unsigned int nLenS = vchSig[5+nLenR]; - if ((unsigned long)(nLenR+nLenS+7) != vchSig.size()) { - // Non-canonical signature: R+S length mismatch - return false; - } + // Minimum and maximum size constraints. + if (sig.size() < 9) return false; + if (sig.size() > 73) return false; - const unsigned char *R = &vchSig[4]; - if (R[-2] != 0x02) { - // Non-canonical signature: R value type mismatch - return false; - } - if (nLenR == 0) { - // Non-canonical signature: R length is zero - return false; - } - if (R[0] & 0x80) { - // Non-canonical signature: R value negative - return false; - } - if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80)) { - // Non-canonical signature: R value excessively padded - return false; - } + // A signature is of type 0x30 (compound). + if (sig[0] != 0x30) return false; + + // Make sure the length covers the entire signature. + if (sig[1] != sig.size() - 3) return false; + + // Extract the length of the R element. + unsigned int lenR = sig[3]; + + // Make sure the length of the S element is still inside the signature. + if (5 + lenR >= sig.size()) return false; + + // Extract the length of the S element. + unsigned int lenS = sig[5 + lenR]; + + // Verify that the length of the signature matches the sum of the length + // of the elements. + if ((size_t)(lenR + lenS + 7) != sig.size()) return false; + + // Check whether the R element is an integer. + if (sig[2] != 0x02) return false; + + // Zero-length integers are not allowed for R. + if (lenR == 0) return false; + + // Negative numbers are not allowed for R. + if (sig[4] & 0x80) return false; + + // Null bytes at the start of R are not allowed, unless R would + // otherwise be interpreted as a negative number. + if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false; + + // Check whether the S element is an integer. + if (sig[lenR + 4] != 0x02) return false; + + // Zero-length integers are not allowed for S. + if (lenS == 0) return false; + + // Negative numbers are not allowed for S. + if (sig[lenR + 6] & 0x80) return false; + + // Null bytes at the start of S are not allowed, unless S would otherwise be + // interpreted as a negative number. + if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false; - const unsigned char *S = &vchSig[6+nLenR]; - if (S[-2] != 0x02) { - // Non-canonical signature: S value type mismatch - return false; - } - if (nLenS == 0) { - // Non-canonical signature: S length is zero - return false; - } - if (S[0] & 0x80) { - // Non-canonical signature: S value negative - return false; - } - if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80)) { - // Non-canonical signature: S value excessively padded - return false; - } return true; } bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { - if (!IsDERSignature(vchSig)) { + if (!IsValidSignatureEncoding(vchSig)) { return set_error(serror, SCRIPT_ERR_SIG_DER); } unsigned int nLenR = vchSig[3]; @@ -194,7 +194,7 @@ bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, Sc if (vchSig.size() == 0) { return true; } - if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsDERSignature(vchSig)) { + if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) { return set_error(serror, SCRIPT_ERR_SIG_DER); } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { // serror is set From 092e9fe5fb61ff7ce38dc2820938106fc0f0081d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 19 Jan 2015 18:19:37 -0500 Subject: [PATCH 0225/2337] Example unit tests from BIP66 --- src/test/data/script_invalid.json | 96 +++++++++++++++++++++++++++++++ src/test/data/script_valid.json | 48 ++++++++++++++++ src/test/script_tests.cpp | 73 +++++++++++++++++++++++ 3 files changed, 217 insertions(+) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 9a8fe1ee889..3a15acee925 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -589,6 +589,102 @@ "DERSIG", "P2PK NOT with too much R padding" ], +[ + "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "BIP66 example 1, with DERSIG" +], +[ + "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "", + "BIP66 example 2, without DERSIG" +], +[ + "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG", + "BIP66 example 2, with DERSIG" +], +[ + "0", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "", + "BIP66 example 3, without DERSIG" +], +[ + "0", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "BIP66 example 3, with DERSIG" +], +[ + "1", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "", + "BIP66 example 5, without DERSIG" +], +[ + "1", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "BIP66 example 5, with DERSIG" +], +[ + "1", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG", + "BIP66 example 6, with DERSIG" +], +[ + "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x304402200b3d0b0375bb15c14620afa4aa10ae90a0d6a046ce217bc20fe0bc1ced68c1b802204b550acab90ae6d3478057c9ad24f9df743815b799b6449dd7e7f6d3bc6e274c01", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "DERSIG", + "BIP66 example 7, with DERSIG" +], +[ + "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", + "", + "BIP66 example 8, without DERSIG" +], +[ + "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", + "DERSIG", + "BIP66 example 8, with DERSIG" +], +[ + "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "", + "BIP66 example 9, without DERSIG" +], +[ + "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "DERSIG", + "BIP66 example 9, with DERSIG" +], +[ + "0 0 0x47 0x30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", + "DERSIG", + "BIP66 example 10, with DERSIG" +], +[ + "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "", + "BIP66 example 11, without DERSIG" +], +[ + "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "DERSIG", + "BIP66 example 11, with DERSIG" +], [ "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index a187401cd4a..710d4f77076 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -755,6 +755,54 @@ "", "P2PK NOT with bad sig with too much R padding but no DERSIG" ], +[ + "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "", + "BIP66 example 1, without DERSIG" +], +[ + "0", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "", + "BIP66 example 4, without DERSIG" +], +[ + "0", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG", + "BIP66 example 4, with DERSIG" +], +[ + "1", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "", + "BIP66 example 6, without DERSIG" +], +[ + "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x304402200b3d0b0375bb15c14620afa4aa10ae90a0d6a046ce217bc20fe0bc1ced68c1b802204b550acab90ae6d3478057c9ad24f9df743815b799b6449dd7e7f6d3bc6e274c01", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "", + "BIP66 example 7, without DERSIG" +], +[ + "0 0 0x47 0x30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", + "", + "BIP66 example 10, without DERSIG" +], +[ + "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", + "", + "BIP66 example 12, without DERSIG" +], +[ + "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", + "DERSIG", + "BIP66 example 12, with DERSIG" +], [ "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 4db8942fa15..c25e8317a2b 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -406,6 +406,79 @@ BOOST_AUTO_TEST_CASE(script_build) "P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 1, without DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 2, without DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 3, without DERSIG", 0 + ).Num(0)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 4, without DERSIG", 0 + ).Num(0)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 4, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 5, without DERSIG", 0 + ).Num(1)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(1)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 6, without DERSIG", 0 + ).Num(1)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(1)); + good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 7, without DERSIG", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 8, without DERSIG", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 9, without DERSIG", 0 + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 10, without DERSIG", 0 + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 11, without DERSIG", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); + good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 12, without DERSIG", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); + good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, "P2PK with high S but no LOW_S", 0 ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); From 5a47811da5158df763aa2fca09ce646ee0c51e7b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 19 Jan 2015 18:37:21 -0500 Subject: [PATCH 0226/2337] BIP66 changeover logic --- src/main.cpp | 12 ++++++++++++ src/primitives/block.h | 2 +- src/script/bitcoinconsensus.h | 1 + src/script/standard.h | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 7cc69c318b1..f20575eaf2f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1764,6 +1764,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; + // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, when 75% of the network has upgraded: + if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, Params().EnforceBlockUpgradeMajority())) { + flags |= SCRIPT_VERIFY_DERSIG; + } + CBlockUndo blockundo; CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); @@ -2601,6 +2606,13 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta REJECT_OBSOLETE, "bad-version"); } + // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded: + if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority())) + { + return state.Invalid(error("%s : rejected nVersion=2 block", __func__), + REJECT_OBSOLETE, "bad-version"); + } + return true; } diff --git a/src/primitives/block.h b/src/primitives/block.h index d77ab162e02..c7ed6f723a4 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -24,7 +24,7 @@ class CBlockHeader { public: // header - static const int32_t CURRENT_VERSION=2; + static const int32_t CURRENT_VERSION=3; int32_t nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index 9d9c266435f..03205777978 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -46,6 +46,7 @@ enum { bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0, bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance }; /// Returns 1 if the input nIn of the serialized transaction pointed to by diff --git a/src/script/standard.h b/src/script/standard.h index ac801937739..92e2c27c13c 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -45,6 +45,7 @@ static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH; * blocks and we must accept those blocks. */ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | + SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_MINIMALDATA | SCRIPT_VERIFY_NULLDUMMY | From 819bcf9b9902319176cdb1d476cacfee9b3727ec Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 20 Jan 2015 16:39:19 -0500 Subject: [PATCH 0227/2337] Add RPC test for DERSIG BIP switchover logic --- qa/rpc-tests/bipdersig.py | 90 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100755 qa/rpc-tests/bipdersig.py diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py new file mode 100755 index 00000000000..9f2cc846015 --- /dev/null +++ b/qa/rpc-tests/bipdersig.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test the BIP66 changeover logic +# + +from test_framework import BitcoinTestFramework +from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException +from util import * +import os +import shutil + +class BIP66Test(BitcoinTestFramework): + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, [])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-blockversion=2"])) + self.nodes.append(start_node(2, self.options.tmpdir, ["-blockversion=3"])) + connect_nodes(self.nodes[1], 0) + connect_nodes(self.nodes[2], 0) + self.is_network_split = False + self.sync_all() + + def run_test(self): + cnt = self.nodes[0].getblockcount() + + # Mine some old-version blocks + self.nodes[1].setgenerate(True, 100) + self.sync_all() + if (self.nodes[0].getblockcount() != cnt + 100): + raise AssertionError("Failed to mine 100 version=2 blocks") + + # Mine 750 new-version blocks + for i in xrange(15): + self.nodes[2].setgenerate(True, 50) + self.sync_all() + if (self.nodes[0].getblockcount() != cnt + 850): + raise AssertionError("Failed to mine 750 version=3 blocks") + + # TODO: check that new DERSIG rules are not enforced + + # Mine 1 new-version block + self.nodes[2].setgenerate(True, 1) + self.sync_all() + if (self.nodes[0].getblockcount() != cnt + 851): + raise AssertionFailure("Failed to mine a version=3 blocks") + + # TODO: check that new DERSIG rules are enforced + + # Mine 198 new-version blocks + for i in xrange(2): + self.nodes[2].setgenerate(True, 99) + self.sync_all() + if (self.nodes[0].getblockcount() != cnt + 1049): + raise AssertionError("Failed to mine 198 version=3 blocks") + + # Mine 1 old-version block + self.nodes[1].setgenerate(True, 1) + self.sync_all() + if (self.nodes[0].getblockcount() != cnt + 1050): + raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks") + + # Mine 1 new-version blocks + self.nodes[2].setgenerate(True, 1) + self.sync_all() + if (self.nodes[0].getblockcount() != cnt + 1051): + raise AssertionError("Failed to mine a version=3 block") + + # Mine 1 old-version blocks + try: + self.nodes[1].setgenerate(True, 1) + raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks") + except JSONRPCException: + pass + self.sync_all() + if (self.nodes[0].getblockcount() != cnt + 1051): + raise AssertionError("Accepted a version=2 block after 950 version=3 blocks") + + # Mine 1 new-version blocks + self.nodes[2].setgenerate(True, 1) + self.sync_all() + if (self.nodes[0].getblockcount() != cnt + 1052): + raise AssertionError("Failed to mine a version=3 block") + +if __name__ == '__main__': + BIP66Test().main() From bf6cdebdc5b750cea6121095dcbbbf720b726bb9 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 25 Jan 2015 12:46:31 -0400 Subject: [PATCH 0228/2337] Increase coverage of DERSIG edge cases --- src/test/data/script_invalid.json | 10 ++++++++++ src/test/data/script_valid.json | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 3a15acee925..a67c157aff7 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -510,6 +510,16 @@ "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid." ], +["Increase DERSIG test coverage"], +["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG"], +["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG"], +["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG"], +["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG"], +["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG"], +["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG"], +["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG"], +["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG"], + ["Automatically generated test cases"], [ "0x47 0x3044022053205076a7bb12d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 710d4f77076..fb81fcb1f53 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -688,6 +688,16 @@ "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but second signature invalid. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid signature." ], +["Increase test coverage for DERSIG"], +["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Overly long signature is correctly encoded"], +["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Missing S is correctly encoded"], +["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "S with invalid S length is correctly encoded"], +["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer R is correctly encoded"], +["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer S is correctly encoded"], +["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Zero-length R is correctly encoded"], +["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is correctly encoded for DERSIG"], +["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Negative S is correctly encoded"], + ["Automatically generated test cases"], [ "0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", From f4b2078f721887b8b913464e197f6eaae9086938 Mon Sep 17 00:00:00 2001 From: Shaul Kfir Date: Mon, 2 Feb 2015 12:30:56 -0500 Subject: [PATCH 0229/2337] Replace difficulty readjustment blocks with Interval() --- src/rpcmining.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 5df5de66d94..f1c4016575e 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -44,7 +44,7 @@ Value GetNetworkHashPS(int lookup, int height) { // If lookup is -1, then use blocks since last difficulty change. if (lookup <= 0) - lookup = pb->nHeight % 2016 + 1; + lookup = pb->nHeight % Params().Interval() + 1; // If lookup is larger than chain, then set it to chain length. if (lookup > pb->nHeight) From 858809a33e4f690c4ad213f44a6c4465fc2ef025 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 27 Jan 2015 09:28:45 -0400 Subject: [PATCH 0230/2337] Use separate SignatureChecker for CMutableTransaction --- src/bitcoin-tx.cpp | 2 +- src/main.cpp | 2 +- src/rpcrawtransaction.cpp | 2 +- src/script/bitcoinconsensus.cpp | 2 +- src/script/interpreter.cpp | 4 ++-- src/script/interpreter.h | 14 ++++++++++++-- src/script/sigcache.cpp | 4 ++-- src/script/sigcache.h | 4 ++-- src/script/sign.cpp | 4 ++-- src/test/multisig_tests.cpp | 16 ++++++++-------- src/test/script_P2SH_tests.cpp | 2 +- src/test/script_tests.cpp | 28 ++++++++++++++-------------- src/test/transaction_tests.cpp | 4 ++-- 13 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 01ace1e2b2c..ff409d741b4 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -436,7 +436,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) BOOST_FOREACH(const CTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i))) + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(mergedTx, i))) fComplete = false; } diff --git a/src/main.cpp b/src/main.cpp index f43d8c58b63..702358cf940 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1422,7 +1422,7 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; - if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore), &error)) { + if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(*ptxTo, nIn, cacheStore), &error)) { return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error)); } return true; diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 2b108bf5888..07ddcc5026b 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -688,7 +688,7 @@ Value signrawtransaction(const Array& params, bool fHelp) BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i))) + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(mergedTx, i))) fComplete = false; } diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index c8dd54a7471..5e1f4735314 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -78,7 +78,7 @@ int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned i // Regardless of the verification result, the tx did not error. set_error(err, bitcoinconsensus_ERR_OK); - return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, SignatureChecker(tx, nIn), NULL); + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, TransactionSignatureChecker(tx, nIn), NULL); } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 0cee1a0116d..b1cf028c54d 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1058,12 +1058,12 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig return ss.GetHash(); } -bool SignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const +bool TransactionSignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const { return pubkey.Verify(sighash, vchSig); } -bool SignatureChecker::CheckSig(const vector& vchSigIn, const vector& vchPubKey, const CScript& scriptCode) const +bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn, const vector& vchPubKey, const CScript& scriptCode) const { CPubKey pubkey(vchPubKey); if (!pubkey.IsValid()) diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 8bf379ed895..063a0723688 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -7,6 +7,7 @@ #define BITCOIN_SCRIPT_INTERPRETER_H #include "script_error.h" +#include "primitives/transaction.h" #include #include @@ -90,7 +91,7 @@ public: virtual ~BaseSignatureChecker() {} }; -class SignatureChecker : public BaseSignatureChecker +class TransactionSignatureChecker : public BaseSignatureChecker { private: const CTransaction& txTo; @@ -100,10 +101,19 @@ protected: virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; public: - SignatureChecker(const CTransaction& txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} + TransactionSignatureChecker(const CTransaction& txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const; }; +class MutableTransactionSignatureChecker : public TransactionSignatureChecker +{ +private: + const CTransaction txTo; + +public: + MutableTransactionSignatureChecker(const CMutableTransaction& txToIn, unsigned int nInIn) : TransactionSignatureChecker(txTo, nInIn), txTo(txToIn) {} +}; + bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 75ecdb563dc..099b4ad0e31 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -74,14 +74,14 @@ public: } -bool CachingSignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const +bool CachingTransactionSignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const { static CSignatureCache signatureCache; if (signatureCache.Get(sighash, vchSig, pubkey)) return true; - if (!SignatureChecker::VerifySignature(vchSig, pubkey, sighash)) + if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash)) return false; if (store) diff --git a/src/script/sigcache.h b/src/script/sigcache.h index 3bd11caff52..6c5bba2c012 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -12,13 +12,13 @@ class CPubKey; -class CachingSignatureChecker : public SignatureChecker +class CachingTransactionSignatureChecker : public TransactionSignatureChecker { private: bool store; public: - CachingSignatureChecker(const CTransaction& txToIn, unsigned int nInIn, bool storeIn=true) : SignatureChecker(txToIn, nInIn), store(storeIn) {} + CachingTransactionSignatureChecker(const CTransaction& txToIn, unsigned int nInIn, bool storeIn=true) : TransactionSignatureChecker(txToIn, nInIn), store(storeIn) {} bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; }; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index adddd4ec789..d76466b7036 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -123,7 +123,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl } // Test solution - return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(txTo, nIn)); + return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(txTo, nIn)); } bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType) @@ -174,7 +174,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey - if (SignatureChecker(txTo, nIn).CheckSig(sig, pubkey, scriptPubKey)) + if (TransactionSignatureChecker(txTo, nIn).CheckSig(sig, pubkey, scriptPubKey)) { sigs[pubkey] = sig; break; diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 9501169943d..dcc8bf887cb 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -82,20 +82,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys.assign(1,key[0]); keys.push_back(key[1]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK(VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err)); + BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(txTo[0], 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); for (int i = 0; i < 4; i++) { keys.assign(1,key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 1: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(txTo[0], 0), &err), strprintf("a&b 1: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); keys.assign(1,key[1]); keys.push_back(key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 2: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(txTo[0], 0), &err), strprintf("a&b 2: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -106,18 +106,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(a_or_b, keys, txTo[1], 0); if (i == 0 || i == 1) { - BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } s.clear(); s << OP_0 << OP_1; - BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err)); + BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(txTo[1], 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); @@ -129,12 +129,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(escrow, keys, txTo[2], 0); if (i < j && i < 3 && j < 3) { - BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 77e70022df9..6ec301ce40c 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -43,7 +43,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri txTo.vin[0].scriptSig = scriptSig; txTo.vout[0].nValue = 1; - return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, SignatureChecker(txTo, 0), &err); + return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(txTo, 0), &err); } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 4db8942fa15..6bbc3e41c10 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -93,7 +93,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bo ScriptError err; CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); CMutableTransaction tx2 = tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(tx, 0), &err) == expect, message); + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(tx, 0), &err) == expect, message); BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message); #if defined(HAVE_CONSENSUS_LIB) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); @@ -682,18 +682,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -715,54 +715,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); } diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 96134cd72e0..04a79caf020 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - verify_flags, SignatureChecker(tx, i), &err), + verify_flags, TransactionSignatureChecker(tx, i), &err), strTest); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - verify_flags, SignatureChecker(tx, i), &err); + verify_flags, TransactionSignatureChecker(tx, i), &err); } BOOST_CHECK_MESSAGE(!fValid, strTest); BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); From 9fddceda44fb5592be179d783f0e5ac616c51c0d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 27 Jan 2015 10:01:31 -0400 Subject: [PATCH 0231/2337] Avoid storing a reference passed to SignatureChecker constructors --- src/bitcoin-tx.cpp | 2 +- src/main.cpp | 2 +- src/rpcrawtransaction.cpp | 2 +- src/script/bitcoinconsensus.cpp | 2 +- src/script/interpreter.cpp | 2 +- src/script/interpreter.h | 6 +++--- src/script/sigcache.h | 2 +- src/script/sign.cpp | 4 ++-- src/test/multisig_tests.cpp | 16 ++++++++-------- src/test/script_P2SH_tests.cpp | 2 +- src/test/script_tests.cpp | 28 ++++++++++++++-------------- src/test/transaction_tests.cpp | 4 ++-- 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index ff409d741b4..c1622cf5d3e 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -436,7 +436,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) BOOST_FOREACH(const CTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(mergedTx, i))) + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i))) fComplete = false; } diff --git a/src/main.cpp b/src/main.cpp index 702358cf940..57b44baac5d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1422,7 +1422,7 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; - if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(*ptxTo, nIn, cacheStore), &error)) { + if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) { return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error)); } return true; diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 07ddcc5026b..a3b0e47d00f 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -688,7 +688,7 @@ Value signrawtransaction(const Array& params, bool fHelp) BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(mergedTx, i))) + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i))) fComplete = false; } diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 5e1f4735314..b0d5faaf777 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -78,7 +78,7 @@ int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned i // Regardless of the verification result, the tx did not error. set_error(err, bitcoinconsensus_ERR_OK); - return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, TransactionSignatureChecker(tx, nIn), NULL); + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, TransactionSignatureChecker(&tx, nIn), NULL); } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index b1cf028c54d..af7c641c05f 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1076,7 +1076,7 @@ bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn int nHashType = vchSig.back(); vchSig.pop_back(); - uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType); + uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType); if (!VerifySignature(vchSig, pubkey, sighash)) return false; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 063a0723688..fc64438f687 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -94,14 +94,14 @@ public: class TransactionSignatureChecker : public BaseSignatureChecker { private: - const CTransaction& txTo; + const CTransaction* txTo; unsigned int nIn; protected: virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; public: - TransactionSignatureChecker(const CTransaction& txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const; }; @@ -111,7 +111,7 @@ private: const CTransaction txTo; public: - MutableTransactionSignatureChecker(const CMutableTransaction& txToIn, unsigned int nInIn) : TransactionSignatureChecker(txTo, nInIn), txTo(txToIn) {} + MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn) : TransactionSignatureChecker(&txTo, nInIn), txTo(*txToIn) {} }; bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); diff --git a/src/script/sigcache.h b/src/script/sigcache.h index 6c5bba2c012..b299038daa3 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -18,7 +18,7 @@ private: bool store; public: - CachingTransactionSignatureChecker(const CTransaction& txToIn, unsigned int nInIn, bool storeIn=true) : TransactionSignatureChecker(txToIn, nInIn), store(storeIn) {} + CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, bool storeIn=true) : TransactionSignatureChecker(txToIn, nInIn), store(storeIn) {} bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; }; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index d76466b7036..14119f7e2cc 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -123,7 +123,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl } // Test solution - return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(txTo, nIn)); + return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&txTo, nIn)); } bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType) @@ -174,7 +174,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey - if (TransactionSignatureChecker(txTo, nIn).CheckSig(sig, pubkey, scriptPubKey)) + if (TransactionSignatureChecker(&txTo, nIn).CheckSig(sig, pubkey, scriptPubKey)) { sigs[pubkey] = sig; break; diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index dcc8bf887cb..2168a5fef1f 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -82,20 +82,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys.assign(1,key[0]); keys.push_back(key[1]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(txTo[0], 0), &err)); + BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); for (int i = 0; i < 4; i++) { keys.assign(1,key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(txTo[0], 0), &err), strprintf("a&b 1: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); keys.assign(1,key[1]); keys.push_back(key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(txTo[0], 0), &err), strprintf("a&b 2: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -106,18 +106,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(a_or_b, keys, txTo[1], 0); if (i == 0 || i == 1) { - BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } s.clear(); s << OP_0 << OP_1; - BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(txTo[1], 0), &err)); + BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); @@ -129,12 +129,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(escrow, keys, txTo[2], 0); if (i < j && i < 3 && j < 3) { - BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 6ec301ce40c..94f2ce1a29a 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -43,7 +43,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri txTo.vin[0].scriptSig = scriptSig; txTo.vout[0].nValue = 1; - return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(txTo, 0), &err); + return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err); } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 6bbc3e41c10..4858cf9e531 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -93,7 +93,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bo ScriptError err; CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); CMutableTransaction tx2 = tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(tx, 0), &err) == expect, message); + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message); BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message); #if defined(HAVE_CONSENSUS_LIB) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); @@ -682,18 +682,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -715,54 +715,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); } diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 04a79caf020..5a109cabca8 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - verify_flags, TransactionSignatureChecker(tx, i), &err), + verify_flags, TransactionSignatureChecker(&tx, i), &err), strTest); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - verify_flags, TransactionSignatureChecker(tx, i), &err); + verify_flags, TransactionSignatureChecker(&tx, i), &err); } BOOST_CHECK_MESSAGE(!fValid, strTest); BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); From cf008ac8c3c5d582562d88ad89020daef3e64dcb Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 28 Jan 2015 13:48:36 -0500 Subject: [PATCH 0232/2337] Acquire CCheckQueue's lock to avoid race condition This fixes a potential race condition in the CCheckQueueControl constructor, which was looking directly at data in CCheckQueue without acquiring its lock. Remove the now-unnecessary friendship for CCheckQueueControl --- src/checkqueue.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/checkqueue.h b/src/checkqueue.h index b8e2a17c763..7f6eae6509a 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -161,7 +161,12 @@ public: { } - friend class CCheckQueueControl; + bool IsIdle() + { + boost::unique_lock lock(mutex); + return (nTotal == nIdle && nTodo == 0 && fAllOk == true); + } + }; /** @@ -180,9 +185,8 @@ public: { // passed queue is supposed to be unused, or NULL if (pqueue != NULL) { - assert(pqueue->nTotal == pqueue->nIdle); - assert(pqueue->nTodo == 0); - assert(pqueue->fAllOk == true); + bool isIdle = pqueue->IsIdle(); + assert(isIdle); } } From eb1c2cd37f75cf4d0e85970932b9774b2d073225 Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Tue, 3 Feb 2015 15:44:39 +0100 Subject: [PATCH 0233/2337] Split logic to undo txin's off DisconnectBlock. Instead, create a separate function that applies the undo operation of a CTxInUndo object onto a CCoinsViewCache. This method is used from DisconnectBlock. --- src/main.cpp | 62 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 27c427f7cdb..a0ad5e51f65 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1588,6 +1588,39 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin } // anon namespace +/** + * Apply the undo operation of a CTxInUndo to the given chain state. + * @param undo The undo object. + * @param view The coins view to which to apply the changes. + * @param out The out point that corresponds to the tx input. + * @return True on success. + */ +static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out) +{ + bool fClean = true; + + CCoinsModifier coins = view.ModifyCoins(out.hash); + if (undo.nHeight != 0) { + // undo data contains height: this is the last output of the prevout tx being spent + if (!coins->IsPruned()) + fClean = fClean && error("%s: undo data overwriting existing transaction", __func__); + coins->Clear(); + coins->fCoinBase = undo.fCoinBase; + coins->nHeight = undo.nHeight; + coins->nVersion = undo.nVersion; + } else { + if (coins->IsPruned()) + fClean = fClean && error("%s: undo data adding output to missing transaction", __func__); + } + if (coins->IsAvailable(out.n)) + fClean = fClean && error("%s: undo data overwriting existing output", __func__); + if (coins->vout.size() < out.n+1) + coins->vout.resize(out.n+1); + coins->vout[out.n] = undo.txout; + + return fClean; +} + bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean) { assert(pindex->GetBlockHash() == view.GetBestBlock()); @@ -1613,11 +1646,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex uint256 hash = tx.GetHash(); // Check that all outputs are available and match the outputs in the block itself - // exactly. Note that transactions with only provably unspendable outputs won't - // have outputs available even in the block itself, so we handle that case - // specially with outsEmpty. + // exactly. { - CCoins outsEmpty; CCoinsModifier outs = view.ModifyCoins(hash); outs->ClearUnspendable(); @@ -1642,24 +1672,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex for (unsigned int j = tx.vin.size(); j-- > 0;) { const COutPoint &out = tx.vin[j].prevout; const CTxInUndo &undo = txundo.vprevout[j]; - CCoinsModifier coins = view.ModifyCoins(out.hash); - if (undo.nHeight != 0) { - // undo data contains height: this is the last output of the prevout tx being spent - if (!coins->IsPruned()) - fClean = fClean && error("DisconnectBlock(): undo data overwriting existing transaction"); - coins->Clear(); - coins->fCoinBase = undo.fCoinBase; - coins->nHeight = undo.nHeight; - coins->nVersion = undo.nVersion; - } else { - if (coins->IsPruned()) - fClean = fClean && error("DisconnectBlock(): undo data adding output to missing transaction"); - } - if (coins->IsAvailable(out.n)) - fClean = fClean && error("DisconnectBlock(): undo data overwriting existing output"); - if (coins->vout.size() < out.n+1) - coins->vout.resize(out.n+1); - coins->vout[out.n] = undo.txout; + if (!ApplyTxInUndo(undo, view, out)) + fClean = false; } } } @@ -1670,9 +1684,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex if (pfClean) { *pfClean = fClean; return true; - } else { - return fClean; } + + return fClean; } void static FlushBlockFile(bool fFinalize = false) From a2b04ddfe6452e7d6274f4096bf3f2aee695a6d9 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 24 Nov 2014 17:25:58 -0500 Subject: [PATCH 0234/2337] build: fix newer boost build with c++11 --- src/chainparams.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index d32d96c56bd..1fd3b016812 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -156,11 +156,11 @@ public: vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); - base58Prefixes[PUBKEY_ADDRESS] = boost::assign::list_of(0); - base58Prefixes[SCRIPT_ADDRESS] = boost::assign::list_of(5); - base58Prefixes[SECRET_KEY] = boost::assign::list_of(128); - base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E); - base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4); + base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,0); + base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,5); + base58Prefixes[SECRET_KEY] = std::vector(1,128); + base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container >(); + base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container >(); convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main)); @@ -214,11 +214,11 @@ public: vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me")); vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de")); - base58Prefixes[PUBKEY_ADDRESS] = boost::assign::list_of(111); - base58Prefixes[SCRIPT_ADDRESS] = boost::assign::list_of(196); - base58Prefixes[SECRET_KEY] = boost::assign::list_of(239); - base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF); - base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94); + base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); + base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); + base58Prefixes[SECRET_KEY] = std::vector(1,239); + base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); + base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test)); From bbacd88204090e9233be375199f52d378bb75627 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 18 Dec 2014 20:00:01 -0500 Subject: [PATCH 0235/2337] c++11: MOVEONLY: move function definitions out of the header These need to be moved out of the header in order to resolve a circular dependency between CWallet and CTxWallet. See next commit. --- src/wallet.cpp | 187 +++++++++++++++++++++++++++++++++++++++++++++++ src/wallet.h | 193 ++----------------------------------------------- 2 files changed, 195 insertions(+), 185 deletions(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index d565a3dee3e..b51c4d4b14a 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1015,6 +1015,193 @@ set CWalletTx::GetConflicts() const return result; } +CAmount CWalletTx::GetDebit(const isminefilter& filter) const +{ + if (vin.empty()) + return 0; + + CAmount debit = 0; + if(filter & ISMINE_SPENDABLE) + { + if (fDebitCached) + debit += nDebitCached; + else + { + nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE); + fDebitCached = true; + debit += nDebitCached; + } + } + if(filter & ISMINE_WATCH_ONLY) + { + if(fWatchDebitCached) + debit += nWatchDebitCached; + else + { + nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY); + fWatchDebitCached = true; + debit += nWatchDebitCached; + } + } + return debit; +} + +CAmount CWalletTx::GetCredit(const isminefilter& filter) const +{ + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + + int64_t credit = 0; + if (filter & ISMINE_SPENDABLE) + { + // GetBalance can assume transactions in mapWallet won't change + if (fCreditCached) + credit += nCreditCached; + else + { + nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE); + fCreditCached = true; + credit += nCreditCached; + } + } + if (filter & ISMINE_WATCH_ONLY) + { + if (fWatchCreditCached) + credit += nWatchCreditCached; + else + { + nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY); + fWatchCreditCached = true; + credit += nWatchCreditCached; + } + } + return credit; +} + +CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const +{ + if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) + { + if (fUseCache && fImmatureCreditCached) + return nImmatureCreditCached; + nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE); + fImmatureCreditCached = true; + return nImmatureCreditCached; + } + + return 0; +} + +CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const +{ + if (pwallet == 0) + return 0; + + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + + if (fUseCache && fAvailableCreditCached) + return nAvailableCreditCached; + + CAmount nCredit = 0; + uint256 hashTx = GetHash(); + for (unsigned int i = 0; i < vout.size(); i++) + { + if (!pwallet->IsSpent(hashTx, i)) + { + const CTxOut &txout = vout[i]; + nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + } + } + + nAvailableCreditCached = nCredit; + fAvailableCreditCached = true; + return nCredit; +} + +CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const +{ + if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) + { + if (fUseCache && fImmatureWatchCreditCached) + return nImmatureWatchCreditCached; + nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY); + fImmatureWatchCreditCached = true; + return nImmatureWatchCreditCached; + } + + return 0; +} + +CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const +{ + if (pwallet == 0) + return 0; + + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + + if (fUseCache && fAvailableWatchCreditCached) + return nAvailableWatchCreditCached; + + CAmount nCredit = 0; + for (unsigned int i = 0; i < vout.size(); i++) + { + if (!pwallet->IsSpent(GetHash(), i)) + { + const CTxOut &txout = vout[i]; + nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + } + } + + nAvailableWatchCreditCached = nCredit; + fAvailableWatchCreditCached = true; + return nCredit; +} + +CAmount CWalletTx::GetChange() const +{ + if (fChangeCached) + return nChangeCached; + nChangeCached = pwallet->GetChange(*this); + fChangeCached = true; + return nChangeCached; +} + +bool CWalletTx::IsTrusted() const +{ + // Quick answer in most cases + if (!IsFinalTx(*this)) + return false; + int nDepth = GetDepthInMainChain(); + if (nDepth >= 1) + return true; + if (nDepth < 0) + return false; + if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit + return false; + + // Trusted if all inputs are from us and are in the mempool: + BOOST_FOREACH(const CTxIn& txin, vin) + { + // Transactions not sent by us: not trusted + const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash); + if (parent == NULL) + return false; + const CTxOut& parentOut = parent->vout[txin.prevout.n]; + if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE) + return false; + } + return true; +} + void CWallet::ResendWalletTransactions() { // Do this infrequently and randomly to avoid giving away diff --git a/src/wallet.h b/src/wallet.h index a7d75b70cf4..d571b92b606 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -705,165 +705,13 @@ public: } //! filter decides which addresses will count towards the debit - CAmount GetDebit(const isminefilter& filter) const - { - if (vin.empty()) - return 0; - - CAmount debit = 0; - if(filter & ISMINE_SPENDABLE) - { - if (fDebitCached) - debit += nDebitCached; - else - { - nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE); - fDebitCached = true; - debit += nDebitCached; - } - } - if(filter & ISMINE_WATCH_ONLY) - { - if(fWatchDebitCached) - debit += nWatchDebitCached; - else - { - nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY); - fWatchDebitCached = true; - debit += nWatchDebitCached; - } - } - return debit; - } - - CAmount GetCredit(const isminefilter& filter) const - { - // Must wait until coinbase is safely deep enough in the chain before valuing it - if (IsCoinBase() && GetBlocksToMaturity() > 0) - return 0; - - int64_t credit = 0; - if (filter & ISMINE_SPENDABLE) - { - // GetBalance can assume transactions in mapWallet won't change - if (fCreditCached) - credit += nCreditCached; - else - { - nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE); - fCreditCached = true; - credit += nCreditCached; - } - } - if (filter & ISMINE_WATCH_ONLY) - { - if (fWatchCreditCached) - credit += nWatchCreditCached; - else - { - nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY); - fWatchCreditCached = true; - credit += nWatchCreditCached; - } - } - return credit; - } - - CAmount GetImmatureCredit(bool fUseCache=true) const - { - if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) - { - if (fUseCache && fImmatureCreditCached) - return nImmatureCreditCached; - nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE); - fImmatureCreditCached = true; - return nImmatureCreditCached; - } - - return 0; - } - - CAmount GetAvailableCredit(bool fUseCache=true) const - { - if (pwallet == 0) - return 0; - - // Must wait until coinbase is safely deep enough in the chain before valuing it - if (IsCoinBase() && GetBlocksToMaturity() > 0) - return 0; - - if (fUseCache && fAvailableCreditCached) - return nAvailableCreditCached; - - CAmount nCredit = 0; - uint256 hashTx = GetHash(); - for (unsigned int i = 0; i < vout.size(); i++) - { - if (!pwallet->IsSpent(hashTx, i)) - { - const CTxOut &txout = vout[i]; - nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE); - if (!MoneyRange(nCredit)) - throw std::runtime_error("CWalletTx::GetAvailableCredit(): value out of range"); - } - } - - nAvailableCreditCached = nCredit; - fAvailableCreditCached = true; - return nCredit; - } - - CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const - { - if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) - { - if (fUseCache && fImmatureWatchCreditCached) - return nImmatureWatchCreditCached; - nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY); - fImmatureWatchCreditCached = true; - return nImmatureWatchCreditCached; - } - - return 0; - } - - CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const - { - if (pwallet == 0) - return 0; - - // Must wait until coinbase is safely deep enough in the chain before valuing it - if (IsCoinBase() && GetBlocksToMaturity() > 0) - return 0; - - if (fUseCache && fAvailableWatchCreditCached) - return nAvailableWatchCreditCached; - - CAmount nCredit = 0; - for (unsigned int i = 0; i < vout.size(); i++) - { - if (!pwallet->IsSpent(GetHash(), i)) - { - const CTxOut &txout = vout[i]; - nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY); - if (!MoneyRange(nCredit)) - throw std::runtime_error("CWalletTx::GetAvailableCredit(): value out of range"); - } - } - - nAvailableWatchCreditCached = nCredit; - fAvailableWatchCreditCached = true; - return nCredit; - } - - CAmount GetChange() const - { - if (fChangeCached) - return nChangeCached; - nChangeCached = pwallet->GetChange(*this); - fChangeCached = true; - return nChangeCached; - } + CAmount GetDebit(const isminefilter& filter) const; + CAmount GetCredit(const isminefilter& filter) const; + CAmount GetImmatureCredit(bool fUseCache=true) const; + CAmount GetAvailableCredit(bool fUseCache=true) const; + CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const; + CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const; + CAmount GetChange() const; void GetAmounts(std::list& listReceived, std::list& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const; @@ -876,32 +724,7 @@ public: return (GetDebit(filter) > 0); } - bool IsTrusted() const - { - // Quick answer in most cases - if (!IsFinalTx(*this)) - return false; - int nDepth = GetDepthInMainChain(); - if (nDepth >= 1) - return true; - if (nDepth < 0) - return false; - if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit - return false; - - // Trusted if all inputs are from us and are in the mempool: - BOOST_FOREACH(const CTxIn& txin, vin) - { - // Transactions not sent by us: not trusted - const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash); - if (parent == NULL) - return false; - const CTxOut& parentOut = parent->vout[txin.prevout.n]; - if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE) - return false; - } - return true; - } + bool IsTrusted() const; bool WriteToDisk(CWalletDB *pwalletdb); From 3447cf87e27262c57031361b3659fef938783295 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 18 Dec 2014 20:03:51 -0500 Subject: [PATCH 0236/2337] c++11: MOVEONLY: break circular dependency in wallet c++11 (libc++'s stdlib implementation anyway) doesn't allow for map types to be forward-declared. for example: class foo; std::map bar; // error, foo has not been defined. class foo{}; Since CWallet and CWalletTx are inter-dependent, but only std::map<*,CWalletTx> is used, forward-declare CWallet instead and define CWalletTx first. Despite the mangled git diff, this change only amounts to moving ~320 lines in a single chunk. --- src/wallet.h | 648 +++++++++++++++++++++++++-------------------------- 1 file changed, 323 insertions(+), 325 deletions(-) diff --git a/src/wallet.h b/src/wallet.h index d571b92b606..6ed87d1e687 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -103,6 +103,329 @@ public: StringMap destdata; }; + +typedef std::map mapValue_t; + + +static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue) +{ + if (!mapValue.count("n")) + { + nOrderPos = -1; // TODO: calculate elsewhere + return; + } + nOrderPos = atoi64(mapValue["n"].c_str()); +} + + +static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue) +{ + if (nOrderPos == -1) + return; + mapValue["n"] = i64tostr(nOrderPos); +} + +struct COutputEntry +{ + CTxDestination destination; + CAmount amount; + int vout; +}; + +/** A transaction with a merkle branch linking it to the block chain. */ +class CMerkleTx : public CTransaction +{ +private: + int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const; + +public: + uint256 hashBlock; + std::vector vMerkleBranch; + int nIndex; + + // memory only + mutable bool fMerkleVerified; + + + CMerkleTx() + { + Init(); + } + + CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) + { + Init(); + } + + void Init() + { + hashBlock = uint256(); + nIndex = -1; + fMerkleVerified = false; + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(*(CTransaction*)this); + nVersion = this->nVersion; + READWRITE(hashBlock); + READWRITE(vMerkleBranch); + READWRITE(nIndex); + } + + int SetMerkleBranch(const CBlock& block); + + + /** + * Return depth of transaction in blockchain: + * -1 : not in blockchain, and not in memory pool (conflicted transaction) + * 0 : in memory pool, waiting to be included in a block + * >=1 : this many blocks deep in the main chain + */ + int GetDepthInMainChain(const CBlockIndex* &pindexRet) const; + int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } + bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; } + int GetBlocksToMaturity() const; + bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); +}; + +/** + * A transaction with a bunch of additional info that only the owner cares about. + * It includes any unrecorded transactions needed to link it back to the block chain. + */ +class CWalletTx : public CMerkleTx +{ +private: + const CWallet* pwallet; + +public: + mapValue_t mapValue; + std::vector > vOrderForm; + unsigned int fTimeReceivedIsTxTime; + unsigned int nTimeReceived; //! time received by this node + unsigned int nTimeSmart; + char fFromMe; + std::string strFromAccount; + int64_t nOrderPos; //! position in ordered transaction list + + // memory only + mutable bool fDebitCached; + mutable bool fCreditCached; + mutable bool fImmatureCreditCached; + mutable bool fAvailableCreditCached; + mutable bool fWatchDebitCached; + mutable bool fWatchCreditCached; + mutable bool fImmatureWatchCreditCached; + mutable bool fAvailableWatchCreditCached; + mutable bool fChangeCached; + mutable CAmount nDebitCached; + mutable CAmount nCreditCached; + mutable CAmount nImmatureCreditCached; + mutable CAmount nAvailableCreditCached; + mutable CAmount nWatchDebitCached; + mutable CAmount nWatchCreditCached; + mutable CAmount nImmatureWatchCreditCached; + mutable CAmount nAvailableWatchCreditCached; + mutable CAmount nChangeCached; + + CWalletTx() + { + Init(NULL); + } + + CWalletTx(const CWallet* pwalletIn) + { + Init(pwalletIn); + } + + CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn) + { + Init(pwalletIn); + } + + CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn) + { + Init(pwalletIn); + } + + void Init(const CWallet* pwalletIn) + { + pwallet = pwalletIn; + mapValue.clear(); + vOrderForm.clear(); + fTimeReceivedIsTxTime = false; + nTimeReceived = 0; + nTimeSmart = 0; + fFromMe = false; + strFromAccount.clear(); + fDebitCached = false; + fCreditCached = false; + fImmatureCreditCached = false; + fAvailableCreditCached = false; + fWatchDebitCached = false; + fWatchCreditCached = false; + fImmatureWatchCreditCached = false; + fAvailableWatchCreditCached = false; + fChangeCached = false; + nDebitCached = 0; + nCreditCached = 0; + nImmatureCreditCached = 0; + nAvailableCreditCached = 0; + nWatchDebitCached = 0; + nWatchCreditCached = 0; + nAvailableWatchCreditCached = 0; + nImmatureWatchCreditCached = 0; + nChangeCached = 0; + nOrderPos = -1; + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (ser_action.ForRead()) + Init(NULL); + char fSpent = false; + + if (!ser_action.ForRead()) + { + mapValue["fromaccount"] = strFromAccount; + + WriteOrderPos(nOrderPos, mapValue); + + if (nTimeSmart) + mapValue["timesmart"] = strprintf("%u", nTimeSmart); + } + + READWRITE(*(CMerkleTx*)this); + std::vector vUnused; //! Used to be vtxPrev + READWRITE(vUnused); + READWRITE(mapValue); + READWRITE(vOrderForm); + READWRITE(fTimeReceivedIsTxTime); + READWRITE(nTimeReceived); + READWRITE(fFromMe); + READWRITE(fSpent); + + if (ser_action.ForRead()) + { + strFromAccount = mapValue["fromaccount"]; + + ReadOrderPos(nOrderPos, mapValue); + + nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0; + } + + mapValue.erase("fromaccount"); + mapValue.erase("version"); + mapValue.erase("spent"); + mapValue.erase("n"); + mapValue.erase("timesmart"); + } + + //! make sure balances are recalculated + void MarkDirty() + { + fCreditCached = false; + fAvailableCreditCached = false; + fWatchDebitCached = false; + fWatchCreditCached = false; + fAvailableWatchCreditCached = false; + fImmatureWatchCreditCached = false; + fDebitCached = false; + fChangeCached = false; + } + + void BindWallet(CWallet *pwalletIn) + { + pwallet = pwalletIn; + MarkDirty(); + } + + //! filter decides which addresses will count towards the debit + CAmount GetDebit(const isminefilter& filter) const; + CAmount GetCredit(const isminefilter& filter) const; + CAmount GetImmatureCredit(bool fUseCache=true) const; + CAmount GetAvailableCredit(bool fUseCache=true) const; + CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const; + CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const; + CAmount GetChange() const; + + void GetAmounts(std::list& listReceived, + std::list& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const; + + void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived, + CAmount& nSent, CAmount& nFee, const isminefilter& filter) const; + + bool IsFromMe(const isminefilter& filter) const + { + return (GetDebit(filter) > 0); + } + + bool IsTrusted() const; + + bool WriteToDisk(CWalletDB *pwalletdb); + + int64_t GetTxTime() const; + int GetRequestCount() const; + + void RelayWalletTransaction(); + + std::set GetConflicts() const; +}; + + + + +class COutput +{ +public: + const CWalletTx *tx; + int i; + int nDepth; + bool fSpendable; + + COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn) + { + tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; + } + + std::string ToString() const; +}; + + + + +/** Private key that includes an expiration date in case it never gets used. */ +class CWalletKey +{ +public: + CPrivKey vchPrivKey; + int64_t nTimeCreated; + int64_t nTimeExpires; + std::string strComment; + //! todo: add something to note what created it (user, getnewaddress, change) + //! maybe should have a map property map + + CWalletKey(int64_t nExpires=0); + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPrivKey); + READWRITE(nTimeCreated); + READWRITE(nTimeExpires); + READWRITE(LIMITED_STRING(strComment, 65536)); + } +}; + + + /** * A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, * and provides the ability to create new transactions. @@ -464,331 +787,6 @@ public: }; -typedef std::map mapValue_t; - - -static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue) -{ - if (!mapValue.count("n")) - { - nOrderPos = -1; // TODO: calculate elsewhere - return; - } - nOrderPos = atoi64(mapValue["n"].c_str()); -} - - -static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue) -{ - if (nOrderPos == -1) - return; - mapValue["n"] = i64tostr(nOrderPos); -} - -struct COutputEntry -{ - CTxDestination destination; - CAmount amount; - int vout; -}; - -/** A transaction with a merkle branch linking it to the block chain. */ -class CMerkleTx : public CTransaction -{ -private: - int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const; - -public: - uint256 hashBlock; - std::vector vMerkleBranch; - int nIndex; - - // memory only - mutable bool fMerkleVerified; - - - CMerkleTx() - { - Init(); - } - - CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) - { - Init(); - } - - void Init() - { - hashBlock = uint256(); - nIndex = -1; - fMerkleVerified = false; - } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(*(CTransaction*)this); - nVersion = this->nVersion; - READWRITE(hashBlock); - READWRITE(vMerkleBranch); - READWRITE(nIndex); - } - - int SetMerkleBranch(const CBlock& block); - - - /** - * Return depth of transaction in blockchain: - * -1 : not in blockchain, and not in memory pool (conflicted transaction) - * 0 : in memory pool, waiting to be included in a block - * >=1 : this many blocks deep in the main chain - */ - int GetDepthInMainChain(const CBlockIndex* &pindexRet) const; - int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } - bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; } - int GetBlocksToMaturity() const; - bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); -}; - -/** - * A transaction with a bunch of additional info that only the owner cares about. - * It includes any unrecorded transactions needed to link it back to the block chain. - */ -class CWalletTx : public CMerkleTx -{ -private: - const CWallet* pwallet; - -public: - mapValue_t mapValue; - std::vector > vOrderForm; - unsigned int fTimeReceivedIsTxTime; - unsigned int nTimeReceived; //! time received by this node - unsigned int nTimeSmart; - char fFromMe; - std::string strFromAccount; - int64_t nOrderPos; //! position in ordered transaction list - - // memory only - mutable bool fDebitCached; - mutable bool fCreditCached; - mutable bool fImmatureCreditCached; - mutable bool fAvailableCreditCached; - mutable bool fWatchDebitCached; - mutable bool fWatchCreditCached; - mutable bool fImmatureWatchCreditCached; - mutable bool fAvailableWatchCreditCached; - mutable bool fChangeCached; - mutable CAmount nDebitCached; - mutable CAmount nCreditCached; - mutable CAmount nImmatureCreditCached; - mutable CAmount nAvailableCreditCached; - mutable CAmount nWatchDebitCached; - mutable CAmount nWatchCreditCached; - mutable CAmount nImmatureWatchCreditCached; - mutable CAmount nAvailableWatchCreditCached; - mutable CAmount nChangeCached; - - CWalletTx() - { - Init(NULL); - } - - CWalletTx(const CWallet* pwalletIn) - { - Init(pwalletIn); - } - - CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn) - { - Init(pwalletIn); - } - - CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn) - { - Init(pwalletIn); - } - - void Init(const CWallet* pwalletIn) - { - pwallet = pwalletIn; - mapValue.clear(); - vOrderForm.clear(); - fTimeReceivedIsTxTime = false; - nTimeReceived = 0; - nTimeSmart = 0; - fFromMe = false; - strFromAccount.clear(); - fDebitCached = false; - fCreditCached = false; - fImmatureCreditCached = false; - fAvailableCreditCached = false; - fWatchDebitCached = false; - fWatchCreditCached = false; - fImmatureWatchCreditCached = false; - fAvailableWatchCreditCached = false; - fChangeCached = false; - nDebitCached = 0; - nCreditCached = 0; - nImmatureCreditCached = 0; - nAvailableCreditCached = 0; - nWatchDebitCached = 0; - nWatchCreditCached = 0; - nAvailableWatchCreditCached = 0; - nImmatureWatchCreditCached = 0; - nChangeCached = 0; - nOrderPos = -1; - } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (ser_action.ForRead()) - Init(NULL); - char fSpent = false; - - if (!ser_action.ForRead()) - { - mapValue["fromaccount"] = strFromAccount; - - WriteOrderPos(nOrderPos, mapValue); - - if (nTimeSmart) - mapValue["timesmart"] = strprintf("%u", nTimeSmart); - } - - READWRITE(*(CMerkleTx*)this); - std::vector vUnused; //! Used to be vtxPrev - READWRITE(vUnused); - READWRITE(mapValue); - READWRITE(vOrderForm); - READWRITE(fTimeReceivedIsTxTime); - READWRITE(nTimeReceived); - READWRITE(fFromMe); - READWRITE(fSpent); - - if (ser_action.ForRead()) - { - strFromAccount = mapValue["fromaccount"]; - - ReadOrderPos(nOrderPos, mapValue); - - nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0; - } - - mapValue.erase("fromaccount"); - mapValue.erase("version"); - mapValue.erase("spent"); - mapValue.erase("n"); - mapValue.erase("timesmart"); - } - - //! make sure balances are recalculated - void MarkDirty() - { - fCreditCached = false; - fAvailableCreditCached = false; - fWatchDebitCached = false; - fWatchCreditCached = false; - fAvailableWatchCreditCached = false; - fImmatureWatchCreditCached = false; - fDebitCached = false; - fChangeCached = false; - } - - void BindWallet(CWallet *pwalletIn) - { - pwallet = pwalletIn; - MarkDirty(); - } - - //! filter decides which addresses will count towards the debit - CAmount GetDebit(const isminefilter& filter) const; - CAmount GetCredit(const isminefilter& filter) const; - CAmount GetImmatureCredit(bool fUseCache=true) const; - CAmount GetAvailableCredit(bool fUseCache=true) const; - CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const; - CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const; - CAmount GetChange() const; - - void GetAmounts(std::list& listReceived, - std::list& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const; - - void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived, - CAmount& nSent, CAmount& nFee, const isminefilter& filter) const; - - bool IsFromMe(const isminefilter& filter) const - { - return (GetDebit(filter) > 0); - } - - bool IsTrusted() const; - - bool WriteToDisk(CWalletDB *pwalletdb); - - int64_t GetTxTime() const; - int GetRequestCount() const; - - void RelayWalletTransaction(); - - std::set GetConflicts() const; -}; - - - - -class COutput -{ -public: - const CWalletTx *tx; - int i; - int nDepth; - bool fSpendable; - - COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn) - { - tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; - } - - std::string ToString() const; -}; - - - - -/** Private key that includes an expiration date in case it never gets used. */ -class CWalletKey -{ -public: - CPrivKey vchPrivKey; - int64_t nTimeCreated; - int64_t nTimeExpires; - std::string strComment; - //! todo: add something to note what created it (user, getnewaddress, change) - //! maybe should have a map property map - - CWalletKey(int64_t nExpires=0); - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!(nType & SER_GETHASH)) - READWRITE(nVersion); - READWRITE(vchPrivKey); - READWRITE(nTimeCreated); - READWRITE(nTimeExpires); - READWRITE(LIMITED_STRING(strComment, 65536)); - } -}; - - - - - - /** * Account information. * Stored in wallet with key "acc"+string account name. From 5a6155ccfa7ee8bb2187054c67f750101986588f Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 18 Dec 2014 20:17:28 -0500 Subject: [PATCH 0237/2337] c++11: don't forward-declare types used in maps --- src/keystore.cpp | 2 -- src/keystore.h | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/keystore.cpp b/src/keystore.cpp index 22cd08f30c8..7531737e04d 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -7,8 +7,6 @@ #include "crypter.h" #include "key.h" -#include "script/script.h" -#include "script/standard.h" #include "util.h" #include diff --git a/src/keystore.h b/src/keystore.h index 6655264d720..4a4b6d20afe 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -8,14 +8,13 @@ #include "key.h" #include "pubkey.h" +#include "script/script.h" +#include "script/standard.h" #include "sync.h" #include #include -class CScript; -class CScriptID; - /** A virtual base class for key stores */ class CKeyStore { From 7f991e364eb50bd14970de9d96981a7ca268d4aa Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 18 Dec 2014 20:43:48 -0500 Subject: [PATCH 0238/2337] c++11: These look like user-defined literals. Add a space to keep the compiler happy --- src/test/util_tests.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 1c5778abed5..d829ec228db 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -282,21 +282,21 @@ BOOST_AUTO_TEST_CASE(strprintf_numbers) { int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */ uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */ - BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 "E); - BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 "E); - BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff "E); + BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E); + BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E); + BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E); size_t st = 12345678; /* unsigned size_t test value */ ssize_t sst = -12345678; /* signed size_t test value */ - BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 "E); - BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 "E); - BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e "E); + BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E); + BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E); + BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E); ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */ ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */ - BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 "E); - BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 "E); - BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 "E); + BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E); + BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E); + BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E); } #undef B #undef E From a6516686dcf0b93dd0bcae304e74f9ac69cb305c Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 9 Jan 2015 14:25:43 +0100 Subject: [PATCH 0239/2337] [Qt] prevent amount overflow problem with payment requests Bitcoin amounts are stored as uint64 in the protobuf messages (see paymentrequest.proto), but CAmount is defined as int64_t. Because of that we need to verify that single and accumulated amounts are in a valid range and no variable overflow has happened. - fixes #5624 (#5622) Thanks @SergioDemianLerner for reporting that issue and also supplying us with a possible solution. - add static verifyAmount() function to PaymentServer and move the logging on error into the function - also add a unit test to paymentservertests.cpp --- src/qt/paymentserver.cpp | 25 +++++++++++++++++++++++++ src/qt/paymentserver.h | 2 ++ src/qt/test/paymentrequestdata.h | 25 +++++++++++++++++++++++++ src/qt/test/paymentservertests.cpp | 17 +++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index a00916bf7f9..9aab944f6b5 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -569,6 +569,14 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins return false; } + // Bitcoin amounts are stored as (optional) uint64 in the protobuf messages (see paymentrequest.proto), + // but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range + // and no overflow has happened. + if (!verifyAmount(sendingTo.second)) { + emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); + return false; + } + // Extract and check amounts CTxOut txOut(sendingTo.second, sendingTo.first); if (txOut.IsDust(::minRelayTxFee)) { @@ -580,6 +588,11 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins } recipient.amount += sendingTo.second; + // Also verify that the final amount is still in a valid range after adding additional amounts. + if (!verifyAmount(recipient.amount)) { + emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); + return false; + } } // Store addresses and format them to fit nicely into the GUI recipient.address = addresses.join("
"); @@ -768,3 +781,15 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails } return fVerified; } + +bool PaymentServer::verifyAmount(const CAmount& requestAmount) +{ + bool fVerified = MoneyRange(requestAmount); + if (!fVerified) { + qWarning() << QString("PaymentServer::%1: Payment request amount out of allowed range (%2, allowed 0 - %3).") + .arg(__func__) + .arg(requestAmount) + .arg(MAX_MONEY); + } + return fVerified; +} diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index db5f44ff1df..6bf5ac2eea2 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -95,6 +95,8 @@ public: static bool verifyNetwork(const payments::PaymentDetails& requestDetails); // Verify if the payment request is expired static bool verifyExpired(const payments::PaymentDetails& requestDetails); + // Verify the payment request amount is valid + static bool verifyAmount(const CAmount& requestAmount); signals: // Fired when a valid payment request is received diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index 50636d7c67f..c548ffe429f 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -433,3 +433,28 @@ dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\ HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\ d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\ "; + +// +// Payment request with amount overflow (amount is set to 21000001 BTC) +// +const char* paymentrequest5_cert2_BASE64 = +"\ +Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\ +BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\ +ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\ +IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\ +mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\ +wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\ +RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\ +KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\ ++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\ +3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\ +tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\ +yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\ +dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iTAoEdGVzdBIkCIDC9P+F\ +vt0DEhl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGLzcrKYFKhhUZXN0aW5nIGFt\ +b3VudCBvdmVyZmxvdyEqgAG8S7WEDUC6tCL6q2CTBjop/AitgEy31RL9IqYruytR\ +iEBFUrBDJZU+UEezGwr7/zoECjo5ZY3PmtZcM2sILNjyweJF6XVzGqTxUw6pN6sW\ +XR2T3Gy2LzRvhVA25QgGqpz0/juS2BtmNbsZPkN9gMMwKimgzc+PuCzmEKwPK9cQ\ +YQ==\ +"; diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index 04935192c85..e2ec439b2e3 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -7,7 +7,10 @@ #include "optionsmodel.h" #include "paymentrequestdata.h" +#include "amount.h" #include "random.h" +#include "script/script.h" +#include "script/standard.h" #include "util.h" #include "utilstrencodings.h" @@ -184,6 +187,20 @@ void PaymentServerTests::paymentServerTests() tempFile.close(); QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); + // Payment request with amount overflow (amount is set to 21000001 BTC): + data = DecodeBase64(paymentrequest5_cert2_BASE64); + byteArray = QByteArray((const char*)&data[0], data.size()); + r.paymentRequest.parse(byteArray); + // Ensure the request is initialized + QVERIFY(r.paymentRequest.IsInitialized()); + // Extract address and amount from the request + QList > sendingTos = r.paymentRequest.getPayTo(); + foreach (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { + CTxDestination dest; + if (ExtractDestination(sendingTo.first, dest)) + QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false); + } + delete server; } From 25cf6f3d41b33c4d8523b6613f0169772fd3937f Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Tue, 9 Dec 2014 14:50:01 +0100 Subject: [PATCH 0240/2337] minor rework of SendMoney in rpcwallet - rework the function to not log errors but use throw JSONRPCError - remove a check for IsLocked() that is done in sendtoaddress and sendfrom RPC calls already - cache GetBalance() return value, because it's possibly used twice --- src/rpcwallet.cpp | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 1afc3c910e4..d097b6a0faf 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -19,6 +19,7 @@ #include #include + #include "json/json_spirit_utils.h" #include "json/json_spirit_value.h" @@ -316,35 +317,29 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) return ret; } -void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew) +static void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew) { + CAmount curBalance = pwalletMain->GetBalance(); + // Check amount if (nValue <= 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); - if (nValue > pwalletMain->GetBalance()) + if (nValue > curBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); - string strError; - if (pwalletMain->IsLocked()) - { - strError = "Error: Wallet locked, unable to create transaction!"; - LogPrintf("SendMoney(): %s", strError); - throw JSONRPCError(RPC_WALLET_ERROR, strError); - } - // Parse Bitcoin address CScript scriptPubKey = GetScriptForDestination(address); // Create and send the transaction CReserveKey reservekey(pwalletMain); CAmount nFeeRequired; - if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError)) - { - if (nValue + nFeeRequired > pwalletMain->GetBalance()) - strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired)); - LogPrintf("SendMoney(): %s\n", strError); - throw JSONRPCError(RPC_WALLET_ERROR, strError); + std::string strError; + if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError)) { + if (nValue + nFeeRequired > curBalance) + throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired))); + else + throw JSONRPCError(RPC_WALLET_ERROR, strError); } if (!pwalletMain->CommitTransaction(wtxNew, reservekey)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); From 17115d0a34ce5c370e45fb51560c02bee5339b11 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 4 Feb 2015 16:34:34 +0100 Subject: [PATCH 0241/2337] fix getblocktemplate lock issue getblocktemplate didn't have a wallet lock before #5711 and IMO there is no need for LEAVE/ENTER critical section. --- src/rpcmining.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 369b3fb4d78..8f2d34edff3 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -446,10 +446,6 @@ Value getblocktemplate(const Array& params, bool fHelp) } // Release the wallet and main lock while waiting -#ifdef ENABLE_WALLET - if(pwalletMain) - LEAVE_CRITICAL_SECTION(pwalletMain->cs_wallet); -#endif LEAVE_CRITICAL_SECTION(cs_main); { checktxtime = boost::get_system_time() + boost::posix_time::minutes(1); @@ -467,10 +463,6 @@ Value getblocktemplate(const Array& params, bool fHelp) } } ENTER_CRITICAL_SECTION(cs_main); -#ifdef ENABLE_WALLET - if(pwalletMain) - ENTER_CRITICAL_SECTION(pwalletMain->cs_wallet); -#endif if (!IsRPCRunning()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down"); From 1cb2a00cb8221841e7d748ed49fd2ea0ad50ac12 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 4 Feb 2015 11:34:28 -0500 Subject: [PATCH 0242/2337] Fix getblocktemplate_proposals test by mining one block This triggers the tested node to no longer be in initial download, allowing the call to getblocktemplate() to succeed. --- qa/rpc-tests/getblocktemplate_proposals.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index 22fe2ce044e..f65162002d2 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -95,6 +95,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework): def run_test(self): node = self.nodes[0] + node.setgenerate(True, 1) # Mine a block to leave initial block download tmpl = node.getblocktemplate() if 'coinbasetxn' not in tmpl: rawcoinbase = encodeUNum(tmpl['height']) From d67a642392e1c217acfe15098f68778062c896bb Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 4 Feb 2015 15:15:52 +0100 Subject: [PATCH 0243/2337] [Qt] add bitcoin logo to about screen --- src/qt/forms/helpmessagedialog.ui | 82 +++++++++++++++++++++++++++++++ src/qt/utilitydialog.cpp | 1 + 2 files changed, 83 insertions(+) diff --git a/src/qt/forms/helpmessagedialog.ui b/src/qt/forms/helpmessagedialog.ui index 37008f047e9..dc7df9d6c88 100644 --- a/src/qt/forms/helpmessagedialog.ui +++ b/src/qt/forms/helpmessagedialog.ui @@ -14,6 +14,69 @@ Bitcoin Core - Command-line options + + 0 + + + 12 + + + 12 + + + 12 + + + 12 + + + + + 0 + + + 4 + + + 0 + + + + + + 0 + 0 + + + + + 100 + 100 + + + + :/icons/bitcoin + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + @@ -25,6 +88,9 @@ + + QFrame::NoFrame + Qt::ScrollBarAlwaysOn @@ -56,6 +122,22 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 4 + 4 + + + + diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 4ef42b927ee..63dd6efb52e 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -137,6 +137,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : ui->helpMessage->moveCursor(QTextCursor::Start); ui->scrollArea->setVisible(false); + ui->aboutLogo->setVisible(false); } } From f5791c6ae3b59ef4c8d04e6873310a022e1211b6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 26 Jan 2015 09:47:59 +0100 Subject: [PATCH 0244/2337] Add more information to errors in ReadBlockFromDisk A lot of times, disk corruption problems appear here. To facilitate debugging and troubleshooting, add position information to the error messages. --- src/chain.h | 6 ++++++ src/main.cpp | 9 +++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/chain.h b/src/chain.h index 004e87ab527..02f53cd2f2d 100644 --- a/src/chain.h +++ b/src/chain.h @@ -48,6 +48,12 @@ struct CDiskBlockPos void SetNull() { nFile = -1; nPos = 0; } bool IsNull() const { return (nFile == -1); } + + std::string ToString() const + { + return strprintf("CBlockDiskPos(nFile=%i, nPos=%i)", nFile, nPos); + } + }; enum BlockStatus { diff --git a/src/main.cpp b/src/main.cpp index 27c427f7cdb..32baf5508ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1199,19 +1199,19 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) // Open history file to read CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); if (filein.IsNull()) - return error("ReadBlockFromDisk: OpenBlockFile failed"); + return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString()); // Read block try { filein >> block; } catch (const std::exception& e) { - return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString()); } // Check the header if (!CheckProofOfWork(block.GetHash(), block.nBits)) - return error("ReadBlockFromDisk: Errors in block header"); + return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); return true; } @@ -1221,7 +1221,8 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) if (!ReadBlockFromDisk(block, pindex->GetBlockPos())) return false; if (block.GetHash() != pindex->GetBlockHash()) - return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index"); + return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s", + pindex->ToString(), pindex->GetBlockPos().ToString()); return true; } From 65f10e0ffc0359a0af6575711d6a4cc9b96afd7a Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 6 Feb 2015 11:13:38 +0100 Subject: [PATCH 0245/2337] fix jonasschnelli's gitian key There where two keys in the keyfile and it also had a missing "-key" in the filename. See: http://bitcoinstats.com/irc/bitcoin-dev/logs/2015/02/05#l1423162105 --- contrib/gitian-downloader/jonasschnelli-key.pgp | Bin 0 -> 2230 bytes contrib/gitian-downloader/jonasschnelli.pgp | Bin 4460 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 contrib/gitian-downloader/jonasschnelli-key.pgp delete mode 100644 contrib/gitian-downloader/jonasschnelli.pgp diff --git a/contrib/gitian-downloader/jonasschnelli-key.pgp b/contrib/gitian-downloader/jonasschnelli-key.pgp new file mode 100644 index 0000000000000000000000000000000000000000..fe44c0fbd4eb3b57ff658f48a1e7af67e2d25dda GIT binary patch literal 2230 zcmV;n2ub&u0u2OIfvhqC5CE%WN{()8WljFyIIC?Fe`=~L1$@XfRpAdye(n)724ct) z68!Ix^DJB;tQbV2^sZ}EHQ24?G^EnKR5B8hs63n(WvFS6 zZiWL;DGwHZDp|40hSA-9F0OMJHJTfjk_shxaiF24;OPc6;bn)7sR?#NogZh_jeBLl z-O0HYa--V}4E%~ykZ@BW3=v@5IJY5F0BAN(*6bD)zHi5^7zdMKkm^O9l?T()Nyq-~ z?FU9ZAoy^MK%ygy%fz|$F*imZc5A~AbCNkt(L z0;lFUiNBDY7Bv2$gwrT@L;<+3_i`Z(X5T)~bJwywpdk~4yGsx-p&l|iq&YMP*Ma| zb!25XE@Nmui2^sI171cw7BiA9G&9`DFnh*^DNqcY=-%1G*KSj zl?*r+QwY3ENEVxht;x-Nrz&`1rk-+zP2gjaXdGhqquKSnUQ|HTcnC{Nbhgm%^5s{* zEpb*oY9Szg*Rdjg+)0chrP`K75n4+_yApz_)kMnzOO9HDs^Xw*ZL3)KiS!LjLuVyu zb2)qP&6rDq%$6=Un7uID&F~N|mPMlg42iR_yQ7;5N%(damikgR0(0)~s!Ou7rH-Mm zUF$ldXLj=V>N2@zvpum?LU?X;Pf@b(-L)m^-?jC6VlqE?WF}YsOWvn6jRMb_V)`X? zS@i$NT2q_|4RgQF1=5yo3Z52&e_ZahTE8|9lNr9cnUb7Fh=v|{?n91V?NS#-^QM8e z)J;Ml`W_g*0Fy_@OrYhdcaRJ6R(EbT6^mSjcj|R?_v@~6ePP~cj)p->wRVqO3xfXR zM2D9zmsZW-Ec}pjme2=S@4Y*tY+-v*O-V9&2EL#YhSci>UH-R|!{9;wjl<_+-VCaAz=1vU_QiyjrUDgMQu|ip^fJ%qZEr0n4 z_-6F7s!bl9{DK^}h~$9lItcnc}%V`@Rw|3N$bOU|K)}QLJhHNc0(+oN@ z(fYjId+<(K6FN(z>7I)|jh}ci*vZupc_PR5m(ecvk(-gK z^{`1>Hrv=Oe&vUL`IDrfn-k6OPpqBAcx| zMjbCF9XgeR4$ud!X%m$k$|i!w;u|u+5FkPB=k{{n?U|wu74lsYvL@@U8=0-`Mq!O_ zd6t1iRl%1Wj7^&rYBjxBXl>*XuTOOYC^^j`MV9^VyqX#MOIO8c;2?E)3zbtv9W@++ zhPF!O(w79^^tqb39tud*Xo~zT*iz&O-rs4>;#d!O&l!M-_Z&-Vt9!y44j{AUXHu5g zN7qjG41g63kXl);s8brp01*KI0f_=71Q-DV01pKMRDrBA0vikk2?N4s000UJ5F&8n z3{odK_KKbl|5CmMG3!7f$Rp*{Zn$`YJu_m|;`xV<$U4G!;olaPUinZ{TxZYzNYQ%b zY7yJl9n0T0hQvSBdRVfKft-Xo#YlaKGC{Tr43~7l&ZvQtt3y2%I!TSdgI81){qYO*#ws zNEtjP5ZO_0Ux)4OG@mu9pnRRt_(tvD5oleA7v5MOpR4(#w$Z`W2{J#?o%R-KX9y0E zmPTq&q#n7yoK!gMltYbQj5 zrU1wd_wNl7&v0gZ>tdNNll5@aTn%s_lwrLYJ&F-k7*E+n*qgJlbf;v@_1{aiDzn-x zqfufHxTu;NL9^sm@^@N0+y@$fr`z=a57+TDi4#Kdy49(&jAi$M+$%c^d)$w(jthJ8 zIhnAh=RIa8IE5hF{dPZyf#|4K55ou{;Y*j)#eJV2)1{SIg%fZN9Dybv804J99R#1? zcPucZnO2*-@^b~}Q}o{}Uicl$2{ut4FDj_AB|T2`3dDUn4eXsDa#&QMr)$zFy6h3M EG2;dUG5`Po literal 0 HcmV?d00001 diff --git a/contrib/gitian-downloader/jonasschnelli.pgp b/contrib/gitian-downloader/jonasschnelli.pgp deleted file mode 100644 index 96140fe171651577d56ce75c3ce50b81026dadac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4460 zcmbu>Wl$83y2o+4VacUqK|pD6K?GSsYUwWNZYc?AP*_qVmhSE@k?scRTpAQvLK=jl z|8vjWJ9B65oBQ(j_L*ls^G!t~#Lx<^5I`kHDYsOJb#|~)en1G9JCOz2mvLhH4S}^c z0g3@glIK|FLu91)$De<38G>lrdf=DzBG=T-G;d5Le5Ve&0yE@hFWzL_F`RqjeDv?rJe;xH_r7zQX**2Rx-AnQO9MkMM9FVbx3 z%lo)9?>((VMO8xoYt(0f&+Zs6z+ec2H&>8{W;A!$BOJVDLA((kiH4v$d7?PtbpD&# z-p1h`$CD#;YAsppAvE4nx+p@K08^&_`tVM|WJ^deo5Vpkt-{z)+BYQOmZlf3Yfg1N zme97<(v{0zgMwjI`JD85mZ1GNt$AdcKIBjc?LDV=TgU=H<_lNaj?cwNKjEw8#oo-I-9vOX_ z>q!K{l$tnS73G2HVU@$= zJGotT#Oy�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 Date: Sun, 7 Dec 2014 17:30:57 +0100 Subject: [PATCH 0246/2337] Ignore getaddr messages on Outbound connections. The only time when a client sends a "getaddr" message is when he esatblishes an Outbound connection (see ProcessMessage() in src/main.cpp). Another bitcoin client is expected to receive a "getaddr" message only on Inbound connection. Ignoring "gettaddr" requests on Outbound connections can resolve potential privacy issues (and as was said such request normally do not happen anyway). --- src/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 27c427f7cdb..a30084a75bd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4008,7 +4008,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "getaddr") + // This asymmetric behavior for inbound and outbound connections was introduced + // to prevent a fingerprinting attack: an attacker can send specific fake addresses + // to users' AddrMan and later request them by sending getaddr messages. + // Making users (which are behind NAT and can only make outgoing connections) ignore + // getaddr message mitigates the attack. + else if ((strCommand == "getaddr") && (pfrom->fInbound)) { pfrom->vAddrToSend.clear(); vector vAddr = addrman.GetAddr(); From 28d4cff0ed2d4438da4bbf2d4ca0465715603af5 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 8 Feb 2015 00:59:58 +0000 Subject: [PATCH 0247/2337] Sanitize command strings before logging them. Normally bitcoin core does not display any network originated strings without sanitizing or hex encoding. This wasn't done for strcommand in many places. This could be used to play havoc with a terminal displaying the logs, especially with printtoconsole in use. Thanks to Evil-Knievel for reporting this issue. --- src/main.cpp | 14 +++++++------- src/net.cpp | 2 +- src/rpcserver.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 27c427f7cdb..43e5a2d024e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3450,7 +3450,7 @@ void static ProcessGetData(CNode* pfrom) bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived) { RandAddSeedPerfmon(); - LogPrint("net", "received: %s (%u bytes) peer=%d\n", strCommand, vRecv.size(), pfrom->id); + LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n"); @@ -4285,7 +4285,7 @@ bool ProcessMessages(CNode* pfrom) // Scan for message start if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) { - LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", msg.hdr.GetCommand(), pfrom->id); + LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id); fOk = false; break; } @@ -4294,7 +4294,7 @@ bool ProcessMessages(CNode* pfrom) CMessageHeader& hdr = msg.hdr; if (!hdr.IsValid()) { - LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", hdr.GetCommand(), pfrom->id); + LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id); continue; } string strCommand = hdr.GetCommand(); @@ -4310,7 +4310,7 @@ bool ProcessMessages(CNode* pfrom) if (nChecksum != hdr.nChecksum) { LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", - strCommand, nMessageSize, nChecksum, hdr.nChecksum); + SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum); continue; } @@ -4327,12 +4327,12 @@ bool ProcessMessages(CNode* pfrom) if (strstr(e.what(), "end of data")) { // Allow exceptions from under-length message on vRecv - LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what()); + LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what()); } else if (strstr(e.what(), "size too large")) { // Allow exceptions from over-long size - LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", strCommand, nMessageSize, e.what()); + LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what()); } else { @@ -4349,7 +4349,7 @@ bool ProcessMessages(CNode* pfrom) } if (!fRet) - LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", strCommand, nMessageSize, pfrom->id); + LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id); break; } diff --git a/src/net.cpp b/src/net.cpp index e4ab9d706d8..3c3666615e1 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1971,7 +1971,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen ENTER_CRITICAL_SECTION(cs_vSend); assert(ssSend.size() == 0); ssSend << CMessageHeader(pszCommand, 0); - LogPrint("net", "sending: %s ", pszCommand); + LogPrint("net", "sending: %s ", SanitizeString(pszCommand)); } void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 823b1fcf240..20e9252d7ee 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -849,7 +849,7 @@ void JSONRequest::parse(const Value& valRequest) throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string"); strMethod = valMethod.get_str(); if (strMethod != "getblocktemplate") - LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod); + LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod)); // Parse params Value valParams = find_value(request, "params"); From 47ee8cf0911a8da90fe2f952da5f5b9dfe94e181 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Mon, 9 Feb 2015 11:21:26 +0100 Subject: [PATCH 0248/2337] [Qt] use qint64 in BitcoinGUI::setNumBlocks - as QDateTime.secsTo() returns a qint64 also store in a qint64 and not in an integer --- src/qt/bitcoingui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 09f784387ea..5c5da6dba0b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -682,7 +682,7 @@ void BitcoinGUI::setNumBlocks(int count) QDateTime lastBlockDate = clientModel->getLastBlockDate(); QDateTime currentDate = QDateTime::currentDateTime(); - int secs = lastBlockDate.secsTo(currentDate); + qint64 secs = lastBlockDate.secsTo(currentDate); tooltip = tr("Processed %n blocks of transaction history.", "", count); @@ -722,8 +722,8 @@ void BitcoinGUI::setNumBlocks(int count) } else { - int years = secs / YEAR_IN_SECONDS; - int remainder = secs % YEAR_IN_SECONDS; + qint64 years = secs / YEAR_IN_SECONDS; + qint64 remainder = secs % YEAR_IN_SECONDS; timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(tr("%n week(s)","", remainder/WEEK_IN_SECONDS)); } From deda3e156d9d424051758eeca9569a90365d2dd5 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Mon, 9 Feb 2015 11:25:23 +0100 Subject: [PATCH 0249/2337] [Qt] remove unused getNumBlocksAtStartup() from ClientModel --- src/qt/clientmodel.cpp | 11 +++-------- src/qt/clientmodel.h | 3 --- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 03d94f2e13f..729eb84a181 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -29,8 +29,9 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : optionsModel(optionsModel), peerTableModel(0), cachedNumBlocks(0), - cachedReindexing(0), cachedImporting(0), - numBlocksAtStartup(-1), pollTimer(0) + cachedReindexing(0), + cachedImporting(0), + pollTimer(0) { peerTableModel = new PeerTableModel(this); pollTimer = new QTimer(this); @@ -65,12 +66,6 @@ int ClientModel::getNumBlocks() const return chainActive.Height(); } -int ClientModel::getNumBlocksAtStartup() -{ - if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks(); - return numBlocksAtStartup; -} - quint64 ClientModel::getTotalBytesRecv() const { return CNode::GetTotalBytesRecv(); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 4856a72d7d0..7b74728b262 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -48,7 +48,6 @@ public: //! Return number of connections, default is in- and outbound (total) int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const; int getNumBlocks() const; - int getNumBlocksAtStartup(); quint64 getTotalBytesRecv() const; quint64 getTotalBytesSent() const; @@ -77,8 +76,6 @@ private: bool cachedReindexing; bool cachedImporting; - int numBlocksAtStartup; - QTimer *pollTimer; void subscribeToCoreSignals(); From 6f50dbd2fdeef7bc24317a487936502e25a05de9 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 9 Feb 2015 15:28:35 -0500 Subject: [PATCH 0250/2337] Fix NegateSignatureS to not duplicate last byte of S NegateSignatureS is called with a signature without a hashtype, so do not save the last byte and append it after S negation. Updates the two tests which were affected by this bug. --- src/test/data/script_invalid.json | 2 +- src/test/data/script_valid.json | 2 +- src/test/script_tests.cpp | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index a67c157aff7..3b2f64d766d 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -696,7 +696,7 @@ "BIP66 example 11, with DERSIG" ], [ - "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101", + "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "LOW_S", "P2PK with high S" diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index fb81fcb1f53..2b4b0989b99 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -814,7 +814,7 @@ "BIP66 example 12, with DERSIG" ], [ - "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101", + "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "", "P2PK with high S but no LOW_S" diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 6092afd7827..35a7f6639ac 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -107,7 +107,6 @@ void static NegateSignatureS(std::vector& vchSig) { std::vector r, s; r = std::vector(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]); s = std::vector(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]); - unsigned char hashtype = vchSig.back(); // Really ugly to implement mod-n negation here, but it would be feature creep to expose such functionality from libsecp256k1. static const unsigned char order[33] = { @@ -141,7 +140,6 @@ void static NegateSignatureS(std::vector& vchSig) { vchSig.push_back(0x02); vchSig.push_back(s.size()); vchSig.insert(vchSig.end(), s.begin(), s.end()); - vchSig.push_back(hashtype); } namespace From 78c6bedb9cd3ed85f829a288146533e3b41f784b Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 10 Feb 2015 12:11:59 -0500 Subject: [PATCH 0251/2337] Add test for DER-encoding edge case The fix to NegateSignatureS caused a test which had been failing in IsValidSignatureEncoding to then fail in IsLowDERSignature. Add new test so the original check remains exercised. --- src/test/data/script_invalid.json | 6 ++++++ src/test/data/script_valid.json | 6 ++++++ src/test/script_tests.cpp | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 3b2f64d766d..3c52547a64e 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -695,6 +695,12 @@ "DERSIG", "BIP66 example 11, with DERSIG" ], +[ + "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "DERSIG", + "P2PK with multi-byte hashtype, with DERSIG" +], [ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 2b4b0989b99..34e2c8d61a7 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -813,6 +813,12 @@ "DERSIG", "BIP66 example 12, with DERSIG" ], +[ + "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "", + "P2PK with multi-byte hashtype, without DERSIG" +], [ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 35a7f6639ac..e410b59710c 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -476,6 +476,12 @@ BOOST_AUTO_TEST_CASE(script_build) good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, "BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with multi-byte hashtype, without DERSIG", 0 + ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101")); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, "P2PK with high S but no LOW_S", 0 From 99437c51bafd137e94a829e0b4ade55635cc84ad Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Wed, 11 Feb 2015 21:50:24 +0800 Subject: [PATCH 0252/2337] Add fanquake PGP key --- contrib/gitian-downloader/fanquake-key.pgp | 63 ++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 contrib/gitian-downloader/fanquake-key.pgp diff --git a/contrib/gitian-downloader/fanquake-key.pgp b/contrib/gitian-downloader/fanquake-key.pgp new file mode 100644 index 00000000000..9c03ff45226 --- /dev/null +++ b/contrib/gitian-downloader/fanquake-key.pgp @@ -0,0 +1,63 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG/MacGPG2 v2.0.26 + +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 +XwbdK0Zpx/oDtRHpuDMGKJBV2LWAZYkEbFsmtg== +=3o2I +-----END PGP PUBLIC KEY BLOCK----- From 0c6ab676ee7d2071d48775d81116c86dacc6abf6 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 12 Feb 2015 17:07:13 -0500 Subject: [PATCH 0253/2337] gitian: don't add . to tar list Since permissions and timestamps are changed for the sake of determinism, . must not be added to the archive. Otherwise, tar may try to modify pwd when extracting. --- contrib/gitian-descriptors/gitian-linux.yml | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 2 +- contrib/gitian-descriptors/gitian-win.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 28bd9211acd..80de6770c5f 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -99,7 +99,7 @@ script: | find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz cd ../../ done mkdir -p $OUTDIR/src diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 3ca42248d4e..43eb79d8483 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -126,7 +126,7 @@ script: | find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz cd ../../ done mkdir -p $OUTDIR/src diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 4baa08c88da..f0459ee9461 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -106,7 +106,7 @@ script: | find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find . -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip + find ${DISTNAME} -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip cd ../.. done mkdir -p $OUTDIR/src From f9a8fc4b1a7579b843e3b1a3136ef85a0435c918 Mon Sep 17 00:00:00 2001 From: Jonathan Brown Date: Sat, 14 Feb 2015 12:07:40 +0700 Subject: [PATCH 0254/2337] Fix filename for testing QT. --- doc/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/unit-tests.md b/doc/unit-tests.md index f1d3a8bc506..72613054b91 100644 --- a/doc/unit-tests.md +++ b/doc/unit-tests.md @@ -12,7 +12,7 @@ To add more bitcoind tests, add `BOOST_AUTO_TEST_CASE` functions to the existing .cpp files in the test/ directory or add new .cpp files that implement new BOOST_AUTO_TEST_SUITE sections. -To run the bitcoin-qt tests manually, launch src/qt/test/bitcoin-qt_test +To run the bitcoin-qt tests manually, launch src/qt/test/test_bitcoin-qt To add more bitcoin-qt tests, add them to the `src/qt/test/` directory and the `src/qt/test/test_main.cpp` file. From 1630219d906f592c9258bfe2a0e0c4923df35782 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 20 Jan 2015 19:23:25 -0500 Subject: [PATCH 0255/2337] openssl: abstract out OPENSSL_cleanse This makes it easier for us to replace it if desired, since it's now only in one spot. Also, it avoids the openssl include from allocators.h, which essentially forced openssl to be included from every compilation unit. --- src/Makefile.am | 2 ++ src/allocators.h | 10 +++++----- src/base58.cpp | 2 +- src/crypter.cpp | 4 ++-- src/crypter.h | 4 ++-- src/db.cpp | 2 -- src/qt/paymentrequestplus.cpp | 1 - src/qt/paymentrequestplus.h | 2 ++ src/qt/paymentserver.cpp | 1 - src/random.cpp | 6 +++--- src/streams.h | 1 + src/support/cleanse.cpp | 13 +++++++++++++ src/support/cleanse.h | 13 +++++++++++++ 13 files changed, 44 insertions(+), 17 deletions(-) create mode 100644 src/support/cleanse.cpp create mode 100644 src/support/cleanse.h diff --git a/src/Makefile.am b/src/Makefile.am index 009c3c5196f..7644f6b325b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -123,6 +123,7 @@ BITCOIN_CORE_H = \ script/standard.h \ serialize.h \ streams.h \ + support/cleanse.h \ sync.h \ threadsafety.h \ timedata.h \ @@ -268,6 +269,7 @@ libbitcoin_util_a_SOURCES = \ compat/strnlen.cpp \ random.cpp \ rpcprotocol.cpp \ + support/cleanse.cpp \ sync.cpp \ uint256.cpp \ util.cpp \ diff --git a/src/allocators.h b/src/allocators.h index 6a131c35172..8ffe015b9e5 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_ALLOCATORS_H #define BITCOIN_ALLOCATORS_H +#include "support/cleanse.h" + #include #include #include @@ -14,8 +16,6 @@ #include #include -#include // for OPENSSL_cleanse() - /** * Thread-safe class to keep track of locked (ie, non-swappable) memory pages. * @@ -174,7 +174,7 @@ void LockObject(const T& t) template void UnlockObject(const T& t) { - OPENSSL_cleanse((void*)(&t), sizeof(T)); + memory_cleanse((void*)(&t), sizeof(T)); LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T)); } @@ -217,7 +217,7 @@ struct secure_allocator : public std::allocator { void deallocate(T* p, std::size_t n) { if (p != NULL) { - OPENSSL_cleanse(p, sizeof(T) * n); + memory_cleanse(p, sizeof(T) * n); LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n); } std::allocator::deallocate(p, n); @@ -254,7 +254,7 @@ struct zero_after_free_allocator : public std::allocator { void deallocate(T* p, std::size_t n) { if (p != NULL) - OPENSSL_cleanse(p, sizeof(T) * n); + memory_cleanse(p, sizeof(T) * n); std::allocator::deallocate(p, n); } }; diff --git a/src/base58.cpp b/src/base58.cpp index 980d3cbf429..c8091850560 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -172,7 +172,7 @@ bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) vchData.resize(vchTemp.size() - nVersionBytes); if (!vchData.empty()) memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size()); - OPENSSL_cleanse(&vchTemp[0], vchData.size()); + memory_cleanse(&vchTemp[0], vchData.size()); return true; } diff --git a/src/crypter.cpp b/src/crypter.cpp index 75d84dbf13e..c7f7e216790 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -26,8 +26,8 @@ bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::v if (i != (int)WALLET_CRYPTO_KEY_SIZE) { - OPENSSL_cleanse(chKey, sizeof(chKey)); - OPENSSL_cleanse(chIV, sizeof(chIV)); + memory_cleanse(chKey, sizeof(chKey)); + memory_cleanse(chIV, sizeof(chIV)); return false; } diff --git a/src/crypter.h b/src/crypter.h index cbaf1562f09..8a91498e2e8 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -82,8 +82,8 @@ public: void CleanKey() { - OPENSSL_cleanse(chKey, sizeof(chKey)); - OPENSSL_cleanse(chIV, sizeof(chIV)); + memory_cleanse(chKey, sizeof(chKey)); + memory_cleanse(chIV, sizeof(chIV)); fKeySet = false; } diff --git a/src/db.cpp b/src/db.cpp index a7f885135ba..3246e4b67a1 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -21,8 +21,6 @@ #include #include -#include - using namespace std; diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 4c1e898020d..b69461ad9ed 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -13,7 +13,6 @@ #include -#include #include #include diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index fbc3a09265d..61f8a3415de 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -9,6 +9,8 @@ #include "base58.h" +#include + #include #include #include diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 9aab944f6b5..96ceeb18a4b 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -16,7 +16,6 @@ #include -#include #include #include diff --git a/src/random.cpp b/src/random.cpp index 663456e962b..ae25bee1b71 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -5,6 +5,7 @@ #include "random.h" +#include "support/cleanse.h" #ifdef WIN32 #include "compat.h" // for Windows API #endif @@ -18,7 +19,6 @@ #include #endif -#include #include #include @@ -40,7 +40,7 @@ void RandAddSeed() // Seed with CPU performance counter int64_t nCounter = GetPerformanceCounter(); RAND_add(&nCounter, sizeof(nCounter), 1.5); - OPENSSL_cleanse((void*)&nCounter, sizeof(nCounter)); + memory_cleanse((void*)&nCounter, sizeof(nCounter)); } void RandAddSeedPerfmon() @@ -70,7 +70,7 @@ void RandAddSeedPerfmon() RegCloseKey(HKEY_PERFORMANCE_DATA); if (ret == ERROR_SUCCESS) { RAND_add(begin_ptr(vData), nSize, nSize / 100.0); - OPENSSL_cleanse(begin_ptr(vData), nSize); + memory_cleanse(begin_ptr(vData), nSize); LogPrint("rand", "%s: %lu bytes\n", __func__, nSize); } else { static bool warned = false; // Warn only once diff --git a/src/streams.h b/src/streams.h index bd8568b1af3..9999c2341f7 100644 --- a/src/streams.h +++ b/src/streams.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/src/support/cleanse.cpp b/src/support/cleanse.cpp new file mode 100644 index 00000000000..a2141b24498 --- /dev/null +++ b/src/support/cleanse.cpp @@ -0,0 +1,13 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "cleanse.h" + +#include + +void memory_cleanse(void *ptr, size_t len) +{ + OPENSSL_cleanse(ptr, len); +} diff --git a/src/support/cleanse.h b/src/support/cleanse.h new file mode 100644 index 00000000000..3e02aa8fd1f --- /dev/null +++ b/src/support/cleanse.h @@ -0,0 +1,13 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SUPPORT_CLEANSE_H +#define BITCOIN_SUPPORT_CLEANSE_H + +#include + +void memory_cleanse(void *ptr, size_t len); + +#endif // BITCOIN_SUPPORT_CLEANSE_H From a77021a76361108b21d1e3b59c56915ad82655a5 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 16 Feb 2015 10:37:13 +0100 Subject: [PATCH 0256/2337] doc: Add note-to-self about SHA256SUMS to release-process.md --- doc/release-process.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/release-process.md b/doc/release-process.md index 363465d827e..016090c5949 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -130,6 +130,7 @@ gpg --digest-algo sha256 --clearsign SHA256SUMS # outputs SHA256SUMS.asc rm SHA256SUMS ``` (the digest algorithm is forced to sha256 to avoid confusion of the `Hash:` header that GPG adds with the SHA256 used for the files) +Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spurious/nonsensical entry. - Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoin.org server From b63ae5626910eaa41337c8173cac0c4728a5432d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 25 Jan 2015 15:34:20 -0400 Subject: [PATCH 0257/2337] Add list of implemented BIPs --- doc/bips.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 doc/bips.md diff --git a/doc/bips.md b/doc/bips.md new file mode 100644 index 00000000000..579eadfff33 --- /dev/null +++ b/doc/bips.md @@ -0,0 +1,18 @@ +BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.10.0**): + +* [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)). +* [`BIP 13`](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki): The address format for P2SH addresses has been implemented since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)). +* [`BIP 14`](https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki): The subversion string is being used as User Agent since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)). +* [`BIP 16`](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki): The pay-to-script-hash evaluation rules have been implemented since **v0.6.0**, and took effect on *April 1st 2012* ([PR #748](https://github.com/bitcoin/bitcoin/pull/748)). +* [`BIP 21`](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki): The URI format for Bitcoin payments has been implemented since **v0.6.0** ([PR #176](https://github.com/bitcoin/bitcoin/pull/176)). +* [`BIP 22`](https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki): The 'getblocktemplate' (GBT) RPC protocol for mining has been implemented since **v0.7.0** ([PR #936](https://github.com/bitcoin/bitcoin/pull/936)). +* [`BIP 23`](https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki): Some extensions to GBT have been implemented since **v0.10.0rc1**, including longpolling and block proposals ([PR #1816](https://github.com/bitcoin/bitcoin/pull/1816)). +* [`BIP 30`](https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki): The evaluation rules to forbid creating new transactions with the same txid as previous not-fully-spent transactions were implemented since **v0.6.0**, and the rule took effect on *March 15th 2012* ([PR #915](https://github.com/bitcoin/bitcoin/pull/915)). +* [`BIP 31`](https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki): The 'pong' protocol message (and the protocol version bump to 60001) has been implemented since **v0.6.1** ([PR #1081](https://github.com/bitcoin/bitcoin/pull/1081)). +* [`BIP 34`](https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki): The rule that requires blocks to contain their height (number) in the coinbase input, and the introduction of version 2 blocks has been implemented since **v0.7.0**. The rule took effect for version 2 blocks as of *block 224413* (March 5th 2013), and version 1 blocks are no longer allowed since *block 227931* (March 25th 2013) ([PR #1526](https://github.com/bitcoin/bitcoin/pull/1526)). +* [`BIP 35`](https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki): The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since **v0.7.0** ([PR #1641](https://github.com/bitcoin/bitcoin/pull/1641)). +* [`BIP 37`](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki): The bloom filtering for transaction relaying, partial merkle trees for blocks , and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since **v0.8.0** ([PR #1795](https://github.com/bitcoin/bitcoin/pull/1795)). +* [`BIP 42`](https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki): The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in **v0.9.2** ([PR #3842](https://github.com/bitcoin/bitcoin/pull/3842)). +* [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)). +* [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). +* [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). From e5ece053da705a630bb664e16036299915ac1246 Mon Sep 17 00:00:00 2001 From: Shaul Kfir Date: Tue, 17 Feb 2015 08:46:51 -0500 Subject: [PATCH 0258/2337] Rename Interval() to DifficultyAdjustmentInterval() --- src/chainparams.h | 2 +- src/pow.cpp | 8 ++++---- src/rpcmining.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/chainparams.h b/src/chainparams.h index f52bf4e55fa..86b84df6677 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -68,7 +68,7 @@ public: bool RequireStandard() const { return fRequireStandard; } int64_t TargetTimespan() const { return nTargetTimespan; } int64_t TargetSpacing() const { return nTargetSpacing; } - int64_t Interval() const { return nTargetTimespan / nTargetSpacing; } + int64_t DifficultyAdjustmentInterval() const { return nTargetTimespan / nTargetSpacing; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ diff --git a/src/pow.cpp b/src/pow.cpp index e49f0d104c2..6dd5c4c12c7 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -20,8 +20,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead if (pindexLast == NULL) return nProofOfWorkLimit; - // Only change once per interval - if ((pindexLast->nHeight+1) % Params().Interval() != 0) + // Only change once per difficulty adjustment interval + if ((pindexLast->nHeight+1) % Params().DifficultyAdjustmentInterval() != 0) { if (Params().AllowMinDifficultyBlocks()) { @@ -34,7 +34,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead { // Return the last non-special-min-difficulty-rules-block const CBlockIndex* pindex = pindexLast; - while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit) + while (pindex->pprev && pindex->nHeight % Params().DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) pindex = pindex->pprev; return pindex->nBits; } @@ -44,7 +44,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead // Go back by what we want to be 14 days worth of blocks const CBlockIndex* pindexFirst = pindexLast; - for (int i = 0; pindexFirst && i < Params().Interval()-1; i++) + for (int i = 0; pindexFirst && i < Params().DifficultyAdjustmentInterval()-1; i++) pindexFirst = pindexFirst->pprev; assert(pindexFirst); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index e3ae5cff428..165a9df697d 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -44,7 +44,7 @@ Value GetNetworkHashPS(int lookup, int height) { // If lookup is -1, then use blocks since last difficulty change. if (lookup <= 0) - lookup = pb->nHeight % Params().Interval() + 1; + lookup = pb->nHeight % Params().DifficultyAdjustmentInterval() + 1; // If lookup is larger than chain, then set it to chain length. if (lookup > pb->nHeight) From 544e64e975e93dcf22a682a12acebd26d2306b86 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 18 Feb 2015 13:32:46 -0800 Subject: [PATCH 0259/2337] Update debian changelog and control file --- contrib/debian/changelog | 12 ++++++++++++ contrib/debian/control | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/contrib/debian/changelog b/contrib/debian/changelog index fe910b65a55..7ce3babc1b1 100644 --- a/contrib/debian/changelog +++ b/contrib/debian/changelog @@ -1,3 +1,15 @@ +bitcoin (0.10.0-precise1) precise; urgency=medium + + * New upstream releases. + + -- Matt Corallo (BlueMatt) Wed, 18 Feb 2015 13:22:00 -1000 + +bitcoin (0.9.4-precise1) precise; urgency=high + + * New upstream releases. + + -- Matt Corallo (laptop - only while traveling) Mon, 12 Jan 2015 23:30:00 -1000 + bitcoin (0.9.3-precise1) precise; urgency=medium * New upstream releases. diff --git a/contrib/debian/control b/contrib/debian/control index a653260ad30..4392bb33853 100644 --- a/contrib/debian/control +++ b/contrib/debian/control @@ -12,7 +12,7 @@ Build-Depends: debhelper, libdb4.8++-dev, libssl-dev, pkg-config, - libminiupnpc8-dev, + libminiupnpc8-dev | libminiupnpc-dev (>> 1.6), libboost-filesystem-dev (>> 1.35) | libboost-filesystem1.35-dev, libboost-program-options-dev (>> 1.35) | libboost-program-options1.35-dev, libboost-thread-dev (>> 1.35) | libboost-thread1.35-dev, From 9673c35dafee3522ec707c0ecc5e02ae9bba9409 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sat, 14 Feb 2015 21:41:12 +0100 Subject: [PATCH 0260/2337] [Qt, Win] honor current network when creating autostart link - creates a "Bitcoin (testnet).lnk" when on testnet or a "Bitcoin (regtest).lnk, when on regtest - fixes #5778 --- src/qt/guiutil.cpp | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 2a13f43ea42..d2dcdf63959 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -40,6 +40,7 @@ #if BOOST_FILESYSTEM_VERSION >= 3 #include #endif +#include #include #include @@ -567,12 +568,17 @@ TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* t #ifdef WIN32 boost::filesystem::path static StartupShortcutPath() { + if (GetBoolArg("-testnet", false)) + return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk"; + else if (GetBoolArg("-regtest", false)) + return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (regtest).lnk"; + return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk"; } bool GetStartOnSystemStartup() { - // check for Bitcoin.lnk + // check for Bitcoin*.lnk return boost::filesystem::exists(StartupShortcutPath()); } @@ -588,8 +594,8 @@ bool SetStartOnSystemStartup(bool fAutoStart) // Get a pointer to the IShellLink interface. IShellLink* psl = NULL; HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, - CLSCTX_INPROC_SERVER, IID_IShellLink, - reinterpret_cast(&psl)); + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); if (SUCCEEDED(hres)) { @@ -597,20 +603,34 @@ bool SetStartOnSystemStartup(bool fAutoStart) TCHAR pszExePath[MAX_PATH]; GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); - TCHAR pszArgs[5] = TEXT("-min"); + // Start client minimized + QString strArgs = "-min"; + // Set -testnet /-regtest options + strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false))); + +#ifdef UNICODE + boost::scoped_array args(new TCHAR[strArgs.length() + 1]); + // Convert the QString to TCHAR* + strArgs.toWCharArray(args.get()); + // Add missing '\0'-termination to string + args[strArgs.length()] = '\0'; +#endif // Set the path to the shortcut target psl->SetPath(pszExePath); PathRemoveFileSpec(pszExePath); psl->SetWorkingDirectory(pszExePath); psl->SetShowCmd(SW_SHOWMINNOACTIVE); - psl->SetArguments(pszArgs); +#ifndef UNICODE + psl->SetArguments(strArgs.toStdString().c_str()); +#else + psl->SetArguments(args.get()); +#endif // Query IShellLink for the IPersistFile interface for // saving the shortcut in persistent storage. IPersistFile* ppf = NULL; - hres = psl->QueryInterface(IID_IPersistFile, - reinterpret_cast(&ppf)); + hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast(&ppf)); if (SUCCEEDED(hres)) { WCHAR pwsz[MAX_PATH]; @@ -630,7 +650,6 @@ bool SetStartOnSystemStartup(bool fAutoStart) } return true; } - #elif defined(Q_OS_LINUX) // Follow the Desktop Application Autostart Spec: From 6cb4a5253551269db4ce6d853b39e61f9050a21e Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sun, 15 Feb 2015 16:27:08 +0100 Subject: [PATCH 0261/2337] [Qt, Linux] honor current network when creating autostart link --- src/qt/guiutil.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index d2dcdf63959..9db0a75971a 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -653,7 +653,7 @@ bool SetStartOnSystemStartup(bool fAutoStart) #elif defined(Q_OS_LINUX) // Follow the Desktop Application Autostart Spec: -// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html +// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html boost::filesystem::path static GetAutostartDir() { @@ -709,8 +709,13 @@ bool SetStartOnSystemStartup(bool fAutoStart) // Write a bitcoin.desktop file to the autostart directory: optionFile << "[Desktop Entry]\n"; optionFile << "Type=Application\n"; - optionFile << "Name=Bitcoin\n"; - optionFile << "Exec=" << pszExePath << " -min\n"; + if (GetBoolArg("-testnet", false)) + optionFile << "Name=Bitcoin (testnet)\n"; + else if (GetBoolArg("-regtest", false)) + optionFile << "Name=Bitcoin (regtest)\n"; + else + optionFile << "Name=Bitcoin\n"; + optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false)); optionFile << "Terminal=false\n"; optionFile << "Hidden=false\n"; optionFile.close(); From aaba10f275059cd762c1f07597aa5efb24176cdd Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 20 Feb 2015 09:54:38 +0100 Subject: [PATCH 0262/2337] Revert "Make nicer pull request merge messages" This reverts commit 1078fb08851442bcd7750c3d5015dc1fe7e4d927 (and thus pull #5623). It has various issues: - Pull request names get cut off at ", see e.g. a026a56 - Merge script no longer copes with pulls that have a milestone attached, due to a duplicate 'title' in JSON that is not handled by the ad-hoc parsing. --- contrib/devtools/github-merge.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh index 7e3dad49d2e..ec7a1f4c4b3 100755 --- a/contrib/devtools/github-merge.sh +++ b/contrib/devtools/github-merge.sh @@ -82,15 +82,13 @@ function cleanup() { } # Create unsigned merge commit. -PRTITLE=`curl -s https://api.github.com/repos/$REPO/pulls/$PULL | grep -e ' "title": ".*",'| awk -F'"' '{print $4}'` -MERGEMESSAGE="Merge #$PULL: $PRTITLE" ( - echo $MERGEMESSAGE + echo "Merge pull request #$PULL" echo "" git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head )>"$TMPDIR/message" if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then - if [ "d$(git log --pretty='format:%s' -n 1)" != "d$MERGEMESSAGE" ]; then + if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then echo "ERROR: Creating merge failed (already merged?)." >&2 cleanup exit 4 From de5403f87874c5c54c5a8358cbf38140bee87a9e Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Thu, 19 Feb 2015 00:33:56 +0800 Subject: [PATCH 0263/2337] [GUI] Move fee dialog minimise button away from "Transaction Fee" Its original placement was causing confusion among some users. --- src/qt/forms/sendcoinsdialog.ui | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index eebb459327e..b1ed7a27b5c 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -771,16 +771,6 @@ - - - - collapse fee-settings - - - Minimize - - - @@ -811,6 +801,16 @@ + + + + collapse fee-settings + + + Minimize + + + From 34e5015cd21e27c1bf635d92531afac93f553096 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Sat, 21 Feb 2015 12:57:44 +0000 Subject: [PATCH 0264/2337] Add unit tests for next difficulty calculations Split GetNextWorkRequired() into two functions to allow the difficulty calculations to be tested without requiring a full blockchain. Add unit tests to cover basic difficulty calculation, plus each of the min/max actual time, and maximum difficulty target conditions. --- src/Makefile.test.include | 1 + src/pow.cpp | 7 ++++- src/pow.h | 1 + src/test/pow_tests.cpp | 66 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/test/pow_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 90494439fa5..6774745de24 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -55,6 +55,7 @@ BITCOIN_TESTS =\ test/multisig_tests.cpp \ test/netbase_tests.cpp \ test/pmt_tests.cpp \ + test/pow_tests.cpp \ test/rpc_tests.cpp \ test/sanity_tests.cpp \ test/script_P2SH_tests.cpp \ diff --git a/src/pow.cpp b/src/pow.cpp index 6dd5c4c12c7..b75b293c908 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -48,8 +48,13 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead pindexFirst = pindexFirst->pprev; assert(pindexFirst); + return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime()); +} + +unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime) +{ // Limit adjustment step - int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime(); + int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan); if (nActualTimespan < Params().TargetTimespan()/4) nActualTimespan = Params().TargetTimespan()/4; diff --git a/src/pow.h b/src/pow.h index 3337a30a5e8..a5fbba62364 100644 --- a/src/pow.h +++ b/src/pow.h @@ -14,6 +14,7 @@ class uint256; class arith_uint256; unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock); +unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits); diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp new file mode 100644 index 00000000000..e42c1b0a8b6 --- /dev/null +++ b/src/test/pow_tests.cpp @@ -0,0 +1,66 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "main.h" +#include "pow.h" +#include "util.h" + +#include + +using namespace std; + +BOOST_AUTO_TEST_SUITE(pow_tests) + +/* Test calculation of next difficulty target with no constraints applying */ +BOOST_AUTO_TEST_CASE(get_next_work) +{ + SelectParams(CBaseChainParams::MAIN); + + int64_t nLastRetargetTime = 1261130161; // Block #30240 + CBlockIndex pindexLast; + pindexLast.nHeight = 32255; + pindexLast.nTime = 1262152739; // Block #32255 + pindexLast.nBits = 0x1d00ffff; + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00d86a); +} + +/* Test the constraint on the upper bound for next work */ +BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) +{ + SelectParams(CBaseChainParams::MAIN); + + int64_t nLastRetargetTime = 1231006505; // Block #0 + CBlockIndex pindexLast; + pindexLast.nHeight = 2015; + pindexLast.nTime = 1233061996; // Block #2015 + pindexLast.nBits = 0x1d00ffff; + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00ffff); +} + +/* Test the constraint on the lower bound for actual time taken */ +BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) +{ + SelectParams(CBaseChainParams::MAIN); + + int64_t nLastRetargetTime = 1279008237; // Block #66528 + CBlockIndex pindexLast; + pindexLast.nHeight = 68543; + pindexLast.nTime = 1279297671; // Block #68543 + pindexLast.nBits = 0x1c05a3f4; + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1c0168fd); +} + +/* Test the constraint on the upper bound for actual time taken */ +BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) +{ + SelectParams(CBaseChainParams::MAIN); + int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time + CBlockIndex pindexLast; + pindexLast.nHeight = 46367; + pindexLast.nTime = 1269211443; // Block #46367 + pindexLast.nBits = 0x1c387f6f; + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00e1fd); +} + +BOOST_AUTO_TEST_SUITE_END() From 3ee028f131db0ea78bfde0961a3fca7b9e95b193 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 23 Feb 2015 17:48:57 -0500 Subject: [PATCH 0265/2337] build: disable reduced exports by default This is really a packager's option. While it's helpful to encourage devs to test this option for daily builds, it's not reliable in several real-world use-cases. Some older libstdc++ runtimes (freebsd 9, debian wheezy, for example) fail to properly catch exceptions due to mismatched type_info. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19664 for more info. --- configure.ac | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/configure.ac b/configure.ac index 85e3d1d669b..9dd3f17d88d 100644 --- a/configure.ac +++ b/configure.ac @@ -115,9 +115,9 @@ AC_ARG_ENABLE([hardening], AC_ARG_ENABLE([reduce-exports], [AS_HELP_STRING([--enable-reduce-exports], - [attempt to reduce exported symbols in the resulting executables (default is yes)])], + [attempt to reduce exported symbols in the resulting executables (default is no)])], [use_reduce_exports=$enableval], - [use_reduce_exports=auto]) + [use_reduce_exports=no]) AC_ARG_ENABLE([ccache], [AS_HELP_STRING([--enable-ccache], @@ -473,20 +473,12 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([ if test x$use_reduce_exports = xyes; then AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduced-exports.]) fi - AC_MSG_WARN([Cannot find a working visibility attribute. Disabling reduced exports.]) - use_reduce_exports=no ] ) -if test x$use_reduce_exports != xno; then +if test x$use_reduce_exports = xyes; then AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"], - [ - if test x$use_reduce_exports = xyes; then - AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduced-exports.]) - fi - AC_MSG_WARN([Cannot set default symbol visibility. Disabling reduced exports.]) - use_reduce_exports=no - ]) + [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduced-exports.])]) fi LEVELDB_CPPFLAGS= @@ -533,7 +525,7 @@ AX_BOOST_THREAD AX_BOOST_CHRONO -if test x$use_reduce_exports != xno; then +if test x$use_reduce_exports = xyes; then AC_MSG_CHECKING([for working boost reduced exports]) TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS" @@ -547,25 +539,14 @@ if test x$use_reduce_exports != xno; then #endif ]])],[ AC_MSG_RESULT(yes) - ],[: - if test x$use_reduce_exports = xauto; then - use_reduce_exports=no - else - if test x$use_reduce_exports = xyes; then - AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduced-exports.]) - fi - fi - AC_MSG_RESULT(no) - AC_MSG_WARN([boost versions < 1.49 are known to have symbol visibility issues. Disabling reduced exports.]) + ],[ + AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduced-exports.]) ]) CPPFLAGS="$TEMP_CPPFLAGS" fi - -elif test x$use_reduce_exports = xauto; then - use_reduce_exports=yes fi -if test x$use_reduce_exports != xno; then +if test x$use_reduce_exports = xyes; then CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS" AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"]) fi @@ -827,7 +808,7 @@ else fi AC_MSG_CHECKING([whether to reduce exports]) -if test x$use_reduce_exports != xno; then +if test x$use_reduce_exports = xyes; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) From aa3673064c5cc2009d4a75d0ab8a553e99861ccb Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 23 Feb 2015 17:56:15 -0500 Subject: [PATCH 0266/2337] build: remove libstdc++ backwards-compat Backwards-compatibility for libstdc++ is not limited to straightforward abi changes. Symbol visibility also needs to be taken into consideration, and that really can't be addressed simply. Instead, just static-link libstdc++ for backwards-compat. --- configure.ac | 2 +- src/Makefile.am | 2 - src/compat/glibcxx_compat.cpp | 94 ----------------------------------- 3 files changed, 1 insertion(+), 97 deletions(-) delete mode 100644 src/compat/glibcxx_compat.cpp diff --git a/configure.ac b/configure.ac index 9dd3f17d88d..006c5f38aa9 100644 --- a/configure.ac +++ b/configure.ac @@ -133,7 +133,7 @@ AC_ARG_ENABLE([lcov], AC_ARG_ENABLE([glibc-back-compat], [AS_HELP_STRING([--enable-glibc-back-compat], - [enable backwards compatibility with glibc and libstdc++])], + [enable backwards compatibility with glibc])], [use_glibc_compat=$enableval], [use_glibc_compat=no]) diff --git a/src/Makefile.am b/src/Makefile.am index 7644f6b325b..37dfd5dbaa1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -280,7 +280,6 @@ libbitcoin_util_a_SOURCES = \ if GLIBC_BACK_COMPAT libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp -libbitcoin_util_a_SOURCES += compat/glibcxx_compat.cpp endif # cli: shared between bitcoin-cli and bitcoin-qt @@ -372,7 +371,6 @@ libbitcoinconsensus_la_SOURCES = \ if GLIBC_BACK_COMPAT libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp - libbitcoinconsensus_la_SOURCES += compat/glibcxx_compat.cpp endif libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS) diff --git a/src/compat/glibcxx_compat.cpp b/src/compat/glibcxx_compat.cpp deleted file mode 100644 index 4f2771e57a0..00000000000 --- a/src/compat/glibcxx_compat.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include -#include - -#ifndef _GLIBCXX_USE_NOEXCEPT -#define _GLIBCXX_USE_NOEXCEPT throw() -#endif - -namespace std -{ -const char* bad_exception::what() const throw() -{ - return "std::bad_exception"; -} - -const char* bad_cast::what() const throw() -{ - return "std::bad_cast"; -} - -const char* bad_alloc::what() const throw() -{ - return "std::bad_alloc"; -} - -namespace __detail -{ -struct _List_node_base { - void _M_hook(std::__detail::_List_node_base* const __position) throw() __attribute__((used)) - { - _M_next = __position; - _M_prev = __position->_M_prev; - __position->_M_prev->_M_next = this; - __position->_M_prev = this; - } - - void _M_unhook() __attribute__((used)) - { - _List_node_base* const __next_node = _M_next; - _List_node_base* const __prev_node = _M_prev; - __prev_node->_M_next = __next_node; - __next_node->_M_prev = __prev_node; - } - - _List_node_base* _M_next; - _List_node_base* _M_prev; -}; -} // namespace detail - -template ostream& ostream::_M_insert(bool); -template ostream& ostream::_M_insert(long); -template ostream& ostream::_M_insert(double); -template ostream& ostream::_M_insert(unsigned long); -template ostream& ostream::_M_insert(const void*); -template ostream& __ostream_insert(ostream&, const char*, streamsize); -template istream& istream::_M_extract(long&); -template istream& istream::_M_extract(unsigned short&); - -out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT {} - -length_error::~length_error() _GLIBCXX_USE_NOEXCEPT {} - -// Used with permission. -// See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d - -void ctype::_M_widen_init() const -{ - char __tmp[sizeof(_M_widen)]; - for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i) - __tmp[__i] = __i; - do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen); - - _M_widen_ok = 1; - // Set _M_widen_ok to 2 if memcpy can't be used. - for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i) - if (__tmp[__i] != _M_widen[__i]) { - _M_widen_ok = 2; - break; - } -} - -void __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__)); -void __throw_out_of_range_fmt(const char* err, ...) -{ - // Safe and over-simplified version. Ignore the format and print it as-is. - __throw_out_of_range(err); -} - -} // namespace std From 06715165f9215a954c0b5d0b15037aecff8b1d74 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 23 Feb 2015 18:18:08 -0500 Subject: [PATCH 0267/2337] build: change reduce exports/static libstdc++ options for gitian and travis For Gitian releases: - Windows builds remain unchanged. libstdc++ was already linked statically. - OSX builds remain unchanged. libstdc++ is tied to the SDK and not worth messing with. - Linux builds now statically link libstdc++. For Travis: - Match the previous behavior by adding --enable-reduce-exports as necessary. - Use static libstdc++ for the full Linux build. --- .travis.yml | 14 +++++++------- contrib/gitian-descriptors/gitian-linux.yml | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 2 +- contrib/gitian-descriptors/gitian-win.yml | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3c995be9a53..e08e78dabf5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,19 +25,19 @@ matrix: fast_finish: true include: - compiler: ": ARM" - env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" + env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": bitcoind" - env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER" + env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: ": No wallet" - env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" + env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash" + env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - compiler: ": Cross-Mac" - env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.9 GOAL="deploy" + env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2" + env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": Win32" - env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2" + env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" install: - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 80de6770c5f..10463c871ef 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -23,7 +23,7 @@ files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu" - CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat" + CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="date ar ranlib nm strip" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 43eb79d8483..b401482c70d 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -27,7 +27,7 @@ files: script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin11" - CONFIGFLAGS="--enable-upnp-default GENISOIMAGE=$WRAP_DIR/genisoimage" + CONFIGFLAGS="--enable-upnp-default --enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index f0459ee9461..2d72f7b6e5a 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -26,7 +26,7 @@ files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-w64-mingw32 i686-w64-mingw32" - CONFIGFLAGS="--enable-upnp-default" + CONFIGFLAGS="--enable-upnp-default --enable-reduce-exports" FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip" FAKETIME_PROGS="date makensis zip" From c95ac83e5115a2e9f1c29df6a3839d6788b4eafd Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 23 Feb 2015 19:43:25 -0500 Subject: [PATCH 0268/2337] gitian: fix x86_64 build with static libstdc++ --- contrib/gitian-descriptors/gitian-linux.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 10463c871ef..dde4af34915 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -15,6 +15,7 @@ packages: - "faketime" - "bsdmainutils" - "binutils-gold" +- "libstdc++6-4.6-pic" reference_datetime: "2013-06-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" @@ -69,6 +70,14 @@ script: | make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done + # Ubuntu precise hack: Not an issue in later versions. + # Precise's libstdc++.a is non-pic. There's an optional libstdc++6-4.6-pic + # package which provides libstdc++_pic.a, but the linker can't find it. + # Symlink it to a path that will be included in our link-line so that the + # linker picks it up before the default libstdc++.a. + # This is only necessary for 64bit. + ln -s /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++_pic.a ${BASEPREFIX}/x86_64-unknown-linux-gnu/lib/libstdc++.a + # Create the release tarball using (arbitrarily) the first host ./autogen.sh ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` From 3448b132c4150509eec9bf585552d1994fd32090 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 23 Feb 2015 20:18:54 -0500 Subject: [PATCH 0269/2337] build: fix typo in configure help --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 006c5f38aa9..67a0cc28e51 100644 --- a/configure.ac +++ b/configure.ac @@ -471,14 +471,14 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([ [ AC_MSG_RESULT(no) if test x$use_reduce_exports = xyes; then - AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduced-exports.]) + AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduce-exports.]) fi ] ) if test x$use_reduce_exports = xyes; then AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"], - [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduced-exports.])]) + [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) fi LEVELDB_CPPFLAGS= @@ -540,7 +540,7 @@ if test x$use_reduce_exports = xyes; then ]])],[ AC_MSG_RESULT(yes) ],[ - AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduced-exports.]) + AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.]) ]) CPPFLAGS="$TEMP_CPPFLAGS" fi From 85da07a5a001a563488382435202b74a3e3e964a Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 24 Feb 2015 04:27:25 -0800 Subject: [PATCH 0270/2337] Better fingerprinting protection for non-main-chain getdatas. With headers-first we can compare against the best header timestamp, rather than using checkpoints which require code updates to maintain. --- src/main.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 34b4c51d5f8..b6a61f7da1c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3355,19 +3355,17 @@ void static ProcessGetData(CNode* pfrom) BlockMap::iterator mi = mapBlockIndex.find(inv.hash); if (mi != mapBlockIndex.end()) { - // If the requested block is at a height below our last - // checkpoint, only serve it if it's in the checkpointed chain - int nHeight = mi->second->nHeight; - CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); - if (pcheckpoint && nHeight < pcheckpoint->nHeight) { - if (!chainActive.Contains(mi->second)) - { - LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n"); - } else { - send = true; - } - } else { + if (chainActive.Contains(mi->second)) { send = true; + } else { + // To prevent fingerprinting attacks, only send blocks outside of the active + // chain if they are valid, and no more than a month older than the best header + // chain we know about. + send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && + (mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60); + if (!send) { + LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId()); + } } } if (send) From 32eaf8a3dedb849f81a4b8d32a800ef59ca261ac Mon Sep 17 00:00:00 2001 From: 21E14 <21xe14@gmail.com> Date: Tue, 24 Feb 2015 21:03:53 -0500 Subject: [PATCH 0271/2337] WIN32 Seed Cleanup: Move nLastPerfmon behind win32 ifdef. Code to avoid calling Perfmon too often is only needed when perfmon is actually going to get called. This is not intended to make any functional difference in the addition of entropy to the random pool. --- src/random.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/random.cpp b/src/random.cpp index ae25bee1b71..0ba0de908d8 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -47,15 +47,16 @@ void RandAddSeedPerfmon() { RandAddSeed(); +#ifdef WIN32 + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom + // Seed with the entire set of perfmon data + // This can take up to 2 seconds, so only do it every 10 minutes static int64_t nLastPerfmon; if (GetTime() < nLastPerfmon + 10 * 60) return; nLastPerfmon = GetTime(); -#ifdef WIN32 - // Don't need this on Linux, OpenSSL automatically uses /dev/urandom - // Seed with the entire set of perfmon data std::vector vData(250000, 0); long ret = 0; unsigned long nSize = 0; From d23b0a271163d187eb362164d375148fdd752148 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 25 Feb 2015 14:01:02 -0500 Subject: [PATCH 0272/2337] depends: always use static qt5 for linux --- depends/Makefile | 1 - depends/README.usage | 1 - depends/packages/packages.mk | 7 +------ 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index e2ef7ee49bd..05ef33f2ee8 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -6,7 +6,6 @@ SDK_PATH ?= $(BASEDIR)/SDKs NO_QT ?= NO_WALLET ?= NO_UPNP ?= -USE_LINUX_STATIC_QT5 ?= FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources BUILD = $(shell ./config.guess) diff --git a/depends/README.usage b/depends/README.usage index f5aa5314a1f..24e1231d826 100644 --- a/depends/README.usage +++ b/depends/README.usage @@ -23,7 +23,6 @@ NO_QT: Don't download/build/cache qt and its dependencies NO_WALLET: Don't download/build/cache libs needed to enable the wallet NO_UPNP: Don't download/build/cache packages needed for enabling upnp DEBUG: disable some optimizations and enable more runtime checking -USE_LINUX_STATIC_QT5: Build a static qt5 rather than shared qt4. Linux only. If some packages are not built, for example 'make NO_WALLET=1', the appropriate options will be passed to bitcoin's configure. In this case, --disable-wallet. diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 08fd8a52478..03908aba599 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -4,15 +4,10 @@ native_packages := native_ccache native_comparisontool qt_native_packages = native_protobuf qt_packages = qrencode protobuf -qt46_linux_packages = qt46 expat dbus libxcb xcb_proto libXau xproto freetype libX11 xextproto libXext xtrans libICE libSM -qt5_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans - +qt_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans qt_darwin_packages=qt qt_mingw32_packages=qt -qt_linux_$(USE_LINUX_STATIC_QT5):=$(qt5_linux_packages) -qt_linux_:=$(qt46_linux_packages) -qt_linux_packages:=$(qt_linux_$(USE_LINUX_STATIC_QT5)) wallet_packages=bdb From eec37136fd0f6ab80772380d8f047d98743f31f5 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 27 Oct 2014 20:24:31 -0400 Subject: [PATCH 0273/2337] make CMessageHeader a dumb storage class It shouldn't know or care about bitcoind's chain param selection --- src/chainparams.h | 6 ++---- src/main.cpp | 2 +- src/net.cpp | 4 ++-- src/net.h | 2 +- src/protocol.cpp | 13 ++++++------- src/protocol.h | 8 +++++--- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/chainparams.h b/src/chainparams.h index 86b84df6677..78b575d8f37 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -14,8 +14,6 @@ #include -typedef unsigned char MessageStartChars[MESSAGE_START_SIZE]; - struct CDNSSeedData { std::string name, host; CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {} @@ -42,7 +40,7 @@ public: }; const uint256& HashGenesisBlock() const { return hashGenesisBlock; } - const MessageStartChars& MessageStart() const { return pchMessageStart; } + const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } @@ -83,7 +81,7 @@ protected: CChainParams() {} uint256 hashGenesisBlock; - MessageStartChars pchMessageStart; + CMessageHeader::MessageStartChars pchMessageStart; //! Raw pub key bytes for the broadcast alert signing key. std::vector vAlertPubKey; int nDefaultPort; diff --git a/src/main.cpp b/src/main.cpp index 34b4c51d5f8..c9a2f34a4d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4307,7 +4307,7 @@ bool ProcessMessages(CNode* pfrom) // Read header CMessageHeader& hdr = msg.hdr; - if (!hdr.IsValid()) + if (!hdr.IsValid(Params().MessageStart())) { LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id); continue; diff --git a/src/net.cpp b/src/net.cpp index 3c3666615e1..36a5b6fb6b3 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -509,7 +509,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) // get current incomplete message, or create a new one if (vRecvMsg.empty() || vRecvMsg.back().complete()) - vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion)); + vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, nRecvVersion)); CNetMessage& msg = vRecvMsg.back(); @@ -1970,7 +1970,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen { ENTER_CRITICAL_SECTION(cs_vSend); assert(ssSend.size() == 0); - ssSend << CMessageHeader(pszCommand, 0); + ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0); LogPrint("net", "sending: %s ", SanitizeString(pszCommand)); } diff --git a/src/net.h b/src/net.h index b78665b5c62..0a9fbb38c0c 100644 --- a/src/net.h +++ b/src/net.h @@ -183,7 +183,7 @@ public: int64_t nTime; // time (in microseconds) of message receipt. - CNetMessage(int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), vRecv(nTypeIn, nVersionIn) { + CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) { hdrbuf.resize(24); in_data = false; nHdrPos = 0; diff --git a/src/protocol.cpp b/src/protocol.cpp index 74ac706d60c..568580a595a 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -5,7 +5,6 @@ #include "protocol.h" -#include "chainparams.h" #include "util.h" #include "utilstrencodings.h" @@ -21,17 +20,17 @@ static const char* ppszTypeName[] = "filtered block" }; -CMessageHeader::CMessageHeader() +CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn) { - memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE); + memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE); memset(pchCommand, 0, sizeof(pchCommand)); nMessageSize = -1; nChecksum = 0; } -CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) +CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn) { - memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE); + memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE); memset(pchCommand, 0, sizeof(pchCommand)); strncpy(pchCommand, pszCommand, COMMAND_SIZE); nMessageSize = nMessageSizeIn; @@ -43,10 +42,10 @@ std::string CMessageHeader::GetCommand() const return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE)); } -bool CMessageHeader::IsValid() const +bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const { // Check start string - if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) + if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0) return false; // Check the command string for errors diff --git a/src/protocol.h b/src/protocol.h index f8394ce52fd..e838c0d3638 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -29,11 +29,13 @@ class CMessageHeader { public: - CMessageHeader(); - CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn); + typedef unsigned char MessageStartChars[MESSAGE_START_SIZE]; + + CMessageHeader(const MessageStartChars& pchMessageStartIn); + CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn); std::string GetCommand() const; - bool IsValid() const; + bool IsValid(const MessageStartChars& messageStart) const; ADD_SERIALIZE_METHODS; From 6f1274c8c9cf3e9361aa149f6d271caf3e016991 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 26 Feb 2015 10:16:48 +0100 Subject: [PATCH 0274/2337] qt: Don't save geometry for options and about/help window These dialogs will be something that people occasionally open, not keep open during their session, so just popping it up in a sensible place is good enough. Remembering only creates potential issues, like spawning it outside the current screen area. On Ubuntu this causes the dialogs to be positioned in the middle of the main dialog, so I didn't add code for that. YMMV. Inspired by github pull #5777 by @L-Cranston-Shadow --- src/qt/optionsdialog.cpp | 2 -- src/qt/utilitydialog.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index a0f3993e695..a342b4bfea4 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -38,7 +38,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : fProxyIpValid(true) { ui->setupUi(this); - GUIUtil::restoreWindowGeometry("nOptionsDialogWindow", this->size(), this); /* Main elements init */ ui->databaseCache->setMinimum(nMinDbCache); @@ -117,7 +116,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : OptionsDialog::~OptionsDialog() { - GUIUtil::saveWindowGeometry("nOptionsDialogWindow", this); delete ui; } diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 63dd6efb52e..4e7b70efe6b 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -29,7 +29,6 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : ui(new Ui::HelpMessageDialog) { ui->setupUi(this); - GUIUtil::restoreWindowGeometry("nHelpMessageDialogWindow", this->size(), this); QString version = tr("Bitcoin Core") + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion()); /* On x86 add a bit specifier to the version so that users can distinguish between @@ -143,7 +142,6 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : HelpMessageDialog::~HelpMessageDialog() { - GUIUtil::saveWindowGeometry("nHelpMessageDialogWindow", this); delete ui; } From 96c19a3a8e08047f6639de91b1ea871bc142a46a Mon Sep 17 00:00:00 2001 From: Ciemon Date: Fri, 20 Feb 2015 17:33:58 +0000 Subject: [PATCH 0275/2337] Add bitcoin-cli man page --- contrib/debian/bitcoind.manpages | 1 + contrib/debian/manpages/bitcoin-cli.1 | 48 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 contrib/debian/manpages/bitcoin-cli.1 diff --git a/contrib/debian/bitcoind.manpages b/contrib/debian/bitcoind.manpages index 3e4ca63d4ea..6d3e6838550 100644 --- a/contrib/debian/bitcoind.manpages +++ b/contrib/debian/bitcoind.manpages @@ -1,2 +1,3 @@ debian/manpages/bitcoind.1 debian/manpages/bitcoin.conf.5 +debian/manpages/bitcoin-cli.1 diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1 new file mode 100644 index 00000000000..f953ae9db7a --- /dev/null +++ b/contrib/debian/manpages/bitcoin-cli.1 @@ -0,0 +1,48 @@ +.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10" +.SH NAME +bitcoin-cli \- a remote procedure call client for Bitcoin Core. +.SH SYNOPSIS +bitcoin-cli [options] [params] \- Send command to Bitcoin Core. +.TP +bitcoin-cli [options] help \- Asks Bitcoin Core for a list of supported commands. +.SH DESCRIPTION +This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client used to send commands to Bitcoin Core. + +.SH OPTIONS +.TP +\fB\-?\fR +Show the help message. +.TP +\fB\-conf=\fR +Specify configuration file (default: bitcoin.conf). +.TP +\fB\-datadir=\fR

+Specify data directory. +.TP +\fB\-testnet\fR +Connect to a Bitcoin Core instance running in testnet mode. +.TP +\fB\-regtest\fR +Connect to a Bitcoin Core instance running in regtest mode (see documentation for -regtest on bitcoind). +.TP +\fB\-rpcuser=\fR +Username for JSON\-RPC connections. +.TP +\fB\-rpcpassword=\fR +Password for JSON\-RPC connections. +.TP +\fB\-rpcport=\fR +Listen for JSON\-RPC connections on (default: 8332 or testnet: 18332). +.TP +\fB\-rpcconnect=\fR +Send commands to node running on (default: 127.0.0.1). +.TP +\fB\-rpcssl\fR=\fI1\fR +Use OpenSSL (https) for JSON\-RPC connections (see the Bitcoin Wiki for SSL setup instructions). + +.SH "SEE ALSO" +\fBbitcoind\fP, \fBbitcoin.conf\fP +.SH AUTHOR +This manual page was written by Ciemon Dunville . Permission is granted to copy, distribute and/or modify this document under the terms of the MIT License. + +The complete text of the MIT License can be found on the web at \fIhttp://opensource.org/licenses/MIT\fP. From 9abbeeabd745b2817f69166b73fa3de16f15c0e2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 26 Feb 2015 05:30:59 -0800 Subject: [PATCH 0276/2337] Remove obsolete pubsub method definitions --- src/net.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/net.h b/src/net.h index b78665b5c62..d2b2d88ddbe 100644 --- a/src/net.h +++ b/src/net.h @@ -570,9 +570,6 @@ public: } } - bool IsSubscribed(unsigned int nChannel); - void Subscribe(unsigned int nChannel, unsigned int nHops=0); - void CancelSubscribe(unsigned int nChannel); void CloseSocketDisconnect(); // Denial-of-service detection/prevention From e96028c78e05a6f3fc3d0fda4677b5d99ca802cc Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 26 Feb 2015 20:14:34 +0000 Subject: [PATCH 0277/2337] GUI: Clarify terminology; use "Label" heading for labels row, and "Node/Service" rather than [IP] "Address" --- src/qt/peertablemodel.cpp | 2 +- src/qt/transactiontablemodel.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index dfb7a623afc..220f273d029 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -115,7 +115,7 @@ PeerTableModel::PeerTableModel(ClientModel *parent) : clientModel(parent), timer(0) { - columns << tr("Address/Hostname") << tr("User Agent") << tr("Ping Time"); + columns << tr("Node/Service") << tr("User Agent") << tr("Ping Time"); priv = new PeerTablePriv(); // default to unsorted priv->sortColumn = -1; diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index df1afbfaaae..585d8724c3f 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -227,7 +227,7 @@ TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *paren priv(new TransactionTablePriv(wallet, this)), fProcessingQueuedTransactions(false) { - columns << QString() << QString() << tr("Date") << tr("Type") << tr("Address") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); + columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); priv->refreshWallet(); connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); @@ -626,7 +626,7 @@ QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientat case Watchonly: return tr("Whether or not a watch-only address is involved in this transaction."); case ToAddress: - return tr("Destination address of transaction."); + return tr("User-defined intent/purpose of the transaction."); case Amount: return tr("Amount removed from or added to balance."); } From 16a58a86442ad587449f321c0dbab08cc028c2bd Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 27 Feb 2015 16:44:26 -0500 Subject: [PATCH 0278/2337] keys: remove libsecp256k1 verification until it's actually supported This was added a while ago for testing purposes, but was never intended to be used. Remove it until upstream libsecp256k1 decides that verification is stable/ready. --- configure.ac | 1 - src/Makefile.am | 3 --- src/key.cpp | 2 -- src/pubkey.cpp | 33 --------------------------------- 4 files changed, 39 deletions(-) diff --git a/configure.ac b/configure.ac index 85e3d1d669b..185f7e2918b 100644 --- a/configure.ac +++ b/configure.ac @@ -849,7 +849,6 @@ AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno]) AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) -AM_CONDITIONAL([USE_LIBSECP256K1],[test x$use_libsecp256k1 = xyes]) AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) diff --git a/src/Makefile.am b/src/Makefile.am index 7644f6b325b..4587727cca5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -379,9 +379,6 @@ libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS) libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS) libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL -if USE_LIBSECP256K1 -libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la -endif endif # diff --git a/src/key.cpp b/src/key.cpp index d8319db1a35..64c9bc71190 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -208,11 +208,9 @@ void CExtKey::Decode(const unsigned char code[74]) { } bool ECC_InitSanityCheck() { -#if !defined(USE_SECP256K1) if (!CECKey::SanityCheck()) { return false; } -#endif CKey key; key.MakeNewKey(true); CPubKey pubkey = key.GetPubKey(); diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 3ae67ca5feb..a4c046bff53 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -6,25 +6,16 @@ #include "eccryptoverify.h" -#ifdef USE_SECP256K1 -#include -#else #include "ecwrapper.h" -#endif bool CPubKey::Verify(const uint256 &hash, const std::vector& vchSig) const { if (!IsValid()) return false; -#ifdef USE_SECP256K1 - if (secp256k1_ecdsa_verify((const unsigned char*)&hash, &vchSig[0], vchSig.size(), begin(), size()) != 1) - return false; -#else CECKey key; if (!key.SetPubKey(begin(), size())) return false; if (!key.Verify(hash, vchSig)) return false; -#endif return true; } @@ -33,52 +24,33 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector pubkey; key.GetPubKey(pubkey, fComp); Set(pubkey.begin(), pubkey.end()); -#endif return true; } bool CPubKey::IsFullyValid() const { if (!IsValid()) return false; -#ifdef USE_SECP256K1 - if (!secp256k1_ecdsa_pubkey_verify(begin(), size())) - return false; -#else CECKey key; if (!key.SetPubKey(begin(), size())) return false; -#endif return true; } bool CPubKey::Decompress() { if (!IsValid()) return false; -#ifdef USE_SECP256K1 - int clen = size(); - int ret = secp256k1_ecdsa_pubkey_decompress((unsigned char*)begin(), &clen); - assert(ret); - assert(clen == (int)size()); -#else CECKey key; if (!key.SetPubKey(begin(), size())) return false; std::vector pubkey; key.GetPubKey(pubkey, false); Set(pubkey.begin(), pubkey.end()); -#endif return true; } @@ -89,17 +61,12 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned i unsigned char out[64]; BIP32Hash(cc, nChild, *begin(), begin()+1, out); memcpy(ccChild, out+32, 32); -#ifdef USE_SECP256K1 - pubkeyChild = *this; - bool ret = secp256k1_ecdsa_pubkey_tweak_add((unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out); -#else CECKey key; bool ret = key.SetPubKey(begin(), size()); ret &= key.TweakPublic(out); std::vector pubkey; key.GetPubKey(pubkey, true); pubkeyChild.Set(pubkey.begin(), pubkey.end()); -#endif return ret; } From 3c6d594e646f6d9427eb1c850ce26430a94051e0 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 3 Mar 2015 09:52:21 +0000 Subject: [PATCH 0279/2337] contrib/init/bitcoind.openrc: Compatibility with previous OpenRC init script variables --- contrib/init/bitcoind.openrc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contrib/init/bitcoind.openrc b/contrib/init/bitcoind.openrc index 1f7758c9202..b0ac5e31e18 100644 --- a/contrib/init/bitcoind.openrc +++ b/contrib/init/bitcoind.openrc @@ -12,9 +12,11 @@ BITCOIND_CONFIGFILE=${BITCOIND_CONFIGFILE:-/etc/bitcoin/bitcoin.conf} BITCOIND_PIDDIR=${BITCOIND_PIDDIR:-/var/run/bitcoind} BITCOIND_PIDFILE=${BITCOIND_PIDFILE:-${BITCOIND_PIDDIR}/bitcoind.pid} BITCOIND_DATADIR=${BITCOIND_DATADIR:-${BITCOIND_DEFAULT_DATADIR}} -BITCOIND_USER=${BITCOIND_USER:-bitcoin} +BITCOIND_USER=${BITCOIND_USER:-${BITCOIN_USER:-bitcoin}} BITCOIND_GROUP=${BITCOIND_GROUP:-bitcoin} BITCOIND_BIN=${BITCOIND_BIN:-/usr/bin/bitcoind} +BITCOIND_NICE=${BITCOIND_NICE:-${NICELEVEL:-0}} +BITCOIND_OPTS="${BITCOIND_OPTS:-${BITCOIN_OPTS}}" name="Bitcoin Core Daemon" description="Bitcoin crypto-currency p2p network daemon" @@ -28,7 +30,7 @@ command_args="-pid=\"${BITCOIND_PIDFILE}\" \ required_files="${BITCOIND_CONFIGFILE}" start_stop_daemon_args="-u ${BITCOIND_USER} \ - -N ${BITCOIND_NICE:-0} -w 2000" + -N ${BITCOIND_NICE} -w 2000" pidfile="${BITCOIND_PIDFILE}" retry=60 From 723664b5dbc2829ed6988dd90af2d077dd9d555a Mon Sep 17 00:00:00 2001 From: joshr Date: Tue, 3 Mar 2015 11:06:41 -0500 Subject: [PATCH 0280/2337] startup script for centos, with documentation. --- contrib/init/README.md | 1 + contrib/init/bitcoind.init | 67 ++++++++++++++++++++++++++++++++++++++ doc/init.md | 12 ++++++- 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 contrib/init/bitcoind.init diff --git a/contrib/init/README.md b/contrib/init/README.md index d3fa9665839..0d19da30399 100644 --- a/contrib/init/README.md +++ b/contrib/init/README.md @@ -4,6 +4,7 @@ SystemD: bitcoind.service Upstart: bitcoind.conf OpenRC: bitcoind.openrc bitcoind.openrcconf +CentOS: bitcoind.init have been made available to assist packagers in creating node packages here. diff --git a/contrib/init/bitcoind.init b/contrib/init/bitcoind.init new file mode 100644 index 00000000000..db5061874b3 --- /dev/null +++ b/contrib/init/bitcoind.init @@ -0,0 +1,67 @@ +#!/bin/bash +# +# bitcoind The bitcoin core server. +# +# +# chkconfig: 345 80 20 +# description: bitcoind +# processname: bitcoind +# + +# Source function library. +. /etc/init.d/functions + +# you can override defaults in /etc/sysconfig/bitcoind, see below +if [ -f /etc/sysconfig/bitcoind ]; then + . /etc/sysconfig/bitcoind +fi + +RETVAL=0 + +prog=bitcoind +# you can override the lockfile via BITCOIND_LOCKFILE in /etc/sysconfig/bitcoind +lockfile=${BITCOIND_LOCKFILE-/var/lock/subsys/bitcoind} + +# bitcoind defaults to /usr/bin/bitcoind, override with BITCOIND_BIN +bitcoind=${BITCOIND_BIN-/usr/bin/bitcoind} + +# bitcoind opts default to -disablewallet, override with BITCOIND_OPTS +bitcoind_opts=${BITCOIND_OPTS--disablewallet} + +start() { + echo -n $"Starting $prog: " + daemon $DAEMONOPTS $bitcoind $bitcoind_opts + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && touch $lockfile + return $RETVAL +} + +stop() { + echo -n $"Stopping $prog: " + killproc $prog + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && rm -f $lockfile + return $RETVAL +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status $prog + ;; + restart) + stop + start + ;; + *) + echo "Usage: service $prog {start|stop|status|restart}" + exit 1 + ;; +esac diff --git a/doc/init.md b/doc/init.md index 1f0559d8064..871bdc81234 100644 --- a/doc/init.md +++ b/doc/init.md @@ -8,6 +8,7 @@ can be found in the contrib/init folder. contrib/init/bitcoind.openrc: OpenRC compatible SysV style init script contrib/init/bitcoind.openrcconf: OpenRC conf.d file contrib/init/bitcoind.conf: Upstart service configuration file + contrib/init/bitcoind.init: CentOS compatible SysV style init script 1. Service User --------------------------------- @@ -49,6 +50,7 @@ Configuration file: /etc/bitcoin/bitcoin.conf Data directory: /var/lib/bitcoind PID file: /var/run/bitcoind/bitcoind.pid (OpenRC and Upstart) /var/lib/bitcoind/bitcoind.pid (systemd) +Lock file: /var/lock/subsys/bitcoind (CentOS) The configuration file, PID directory (if applicable) and data directory should all be owned by the bitcoin user and group. It is advised for security @@ -81,7 +83,15 @@ Drop bitcoind.conf in /etc/init. Test by running "service bitcoind start" it will automatically start on reboot. NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they -use old versions of Upstart and do not supply the start-stop-daemon uitility. +use old versions of Upstart and do not supply the start-stop-daemon utility. + +4d) CentOS + +Copy bitcoind.init to /etc/init.d/bitcoind. Test by running "service bitcoind start". + +Using this script, you can adjust the path and flags to the bitcoind program by +setting the BITCOIND and FLAGS environment variables in the file +/etc/sysconfig/bitcoind. You can also use the DAEMONOPTS environment variable here. 5. Auto-respawn ----------------------------------- From 51598b26319bf1ee98b399dee8152b902c62891a Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 3 Mar 2015 07:49:12 -0800 Subject: [PATCH 0281/2337] Reinitialize state in between individual unit tests. This changes the TestingSetup fixture to be per-unit-test rather than global. Most tests don't need it, so it's only invoked in a few. --- src/Makefile.test.include | 1 + src/db.cpp | 77 +++++++++++++++++++---------------- src/db.h | 6 ++- src/main.cpp | 24 ++++++++++- src/test/DoS_tests.cpp | 4 +- src/test/accounting_tests.cpp | 4 +- src/test/alert_tests.cpp | 4 +- src/test/miner_tests.cpp | 4 +- src/test/rpc_tests.cpp | 4 +- src/test/rpc_wallet_tests.cpp | 4 +- src/test/test_bitcoin.cpp | 28 ++++++------- src/test/test_bitcoin.h | 18 ++++++++ src/util.h | 1 + src/walletdb.cpp | 6 +-- 14 files changed, 124 insertions(+), 61 deletions(-) create mode 100644 src/test/test_bitcoin.h diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 90494439fa5..517cd7ea21d 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -65,6 +65,7 @@ BITCOIN_TESTS =\ test/sigopcount_tests.cpp \ test/skiplist_tests.cpp \ test/test_bitcoin.cpp \ + test/test_bitcoin.h \ test/timedata_tests.cpp \ test/transaction_tests.cpp \ test/uint256_tests.cpp \ diff --git a/src/db.cpp b/src/db.cpp index 3246e4b67a1..36946b7dcca 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -39,22 +39,31 @@ void CDBEnv::EnvShutdown() return; fDbEnvInit = false; - int ret = dbenv.close(0); + int ret = dbenv->close(0); if (ret != 0) LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); if (!fMockDb) DbEnv(0).remove(path.string().c_str(), 0); } -CDBEnv::CDBEnv() : dbenv(DB_CXX_NO_EXCEPTIONS) +void CDBEnv::Reset() { + delete dbenv; + dbenv = new DbEnv(DB_CXX_NO_EXCEPTIONS); fDbEnvInit = false; fMockDb = false; } +CDBEnv::CDBEnv() : dbenv(NULL) +{ + Reset(); +} + CDBEnv::~CDBEnv() { EnvShutdown(); + delete dbenv; + dbenv = NULL; } void CDBEnv::Close() @@ -79,17 +88,17 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) if (GetBoolArg("-privdb", true)) nEnvFlags |= DB_PRIVATE; - dbenv.set_lg_dir(pathLogDir.string().c_str()); - dbenv.set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet - dbenv.set_lg_bsize(0x10000); - dbenv.set_lg_max(1048576); - dbenv.set_lk_max_locks(40000); - dbenv.set_lk_max_objects(40000); - dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug - dbenv.set_flags(DB_AUTO_COMMIT, 1); - dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1); - dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); - int ret = dbenv.open(path.string().c_str(), + dbenv->set_lg_dir(pathLogDir.string().c_str()); + dbenv->set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet + dbenv->set_lg_bsize(0x10000); + dbenv->set_lg_max(1048576); + dbenv->set_lk_max_locks(40000); + dbenv->set_lk_max_objects(40000); + dbenv->set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug + dbenv->set_flags(DB_AUTO_COMMIT, 1); + dbenv->set_flags(DB_TXN_WRITE_NOSYNC, 1); + dbenv->log_set_config(DB_LOG_AUTO_REMOVE, 1); + int ret = dbenv->open(path.string().c_str(), DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | @@ -116,14 +125,14 @@ void CDBEnv::MakeMock() LogPrint("db", "CDBEnv::MakeMock\n"); - dbenv.set_cachesize(1, 0, 1); - dbenv.set_lg_bsize(10485760 * 4); - dbenv.set_lg_max(10485760); - dbenv.set_lk_max_locks(10000); - dbenv.set_lk_max_objects(10000); - dbenv.set_flags(DB_AUTO_COMMIT, 1); - dbenv.log_set_config(DB_LOG_IN_MEMORY, 1); - int ret = dbenv.open(NULL, + dbenv->set_cachesize(1, 0, 1); + dbenv->set_lg_bsize(10485760 * 4); + dbenv->set_lg_max(10485760); + dbenv->set_lk_max_locks(10000); + dbenv->set_lk_max_objects(10000); + dbenv->set_flags(DB_AUTO_COMMIT, 1); + dbenv->log_set_config(DB_LOG_IN_MEMORY, 1); + int ret = dbenv->open(NULL, DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | @@ -144,7 +153,7 @@ CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDB LOCK(cs_db); assert(mapFileUseCount.count(strFile) == 0); - Db db(&dbenv, 0); + Db db(dbenv, 0); int result = db.verify(strFile.c_str(), NULL, NULL, 0); if (result == 0) return VERIFY_OK; @@ -167,7 +176,7 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vectortxn_checkpoint(0, 0, 0); if (fMockDb) return; - dbenv.lsn_reset(strFile.c_str(), 0); + dbenv->lsn_reset(strFile.c_str(), 0); } @@ -237,7 +246,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnClose ++bitdb.mapFileUseCount[strFile]; pdb = bitdb.mapDb[strFile]; if (pdb == NULL) { - pdb = new Db(&bitdb.dbenv, 0); + pdb = new Db(bitdb.dbenv, 0); bool fMockDb = bitdb.IsMock(); if (fMockDb) { @@ -284,7 +293,7 @@ void CDB::Flush() if (fReadOnly) nMinutes = 1; - bitdb.dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0); + bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0); } void CDB::Close() @@ -324,7 +333,7 @@ bool CDBEnv::RemoveDb(const string& strFile) this->CloseDb(strFile); LOCK(cs_db); - int rc = dbenv.dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT); + int rc = dbenv->dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT); return (rc == 0); } @@ -344,7 +353,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) string strFileRes = strFile + ".rewrite"; { // surround usage of db with extra {} CDB db(strFile.c_str(), "r"); - Db* pdbCopy = new Db(&bitdb.dbenv, 0); + Db* pdbCopy = new Db(bitdb.dbenv, 0); int ret = pdbCopy->open(NULL, // Txn pointer strFileRes.c_str(), // Filename @@ -394,10 +403,10 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) } } if (fSuccess) { - Db dbA(&bitdb.dbenv, 0); + Db dbA(bitdb.dbenv, 0); if (dbA.remove(strFile.c_str(), NULL, 0)) fSuccess = false; - Db dbB(&bitdb.dbenv, 0); + Db dbB(bitdb.dbenv, 0); if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) fSuccess = false; } @@ -430,10 +439,10 @@ void CDBEnv::Flush(bool fShutdown) // Move log data to the dat file CloseDb(strFile); LogPrint("db", "CDBEnv::Flush: %s checkpoint\n", strFile); - dbenv.txn_checkpoint(0, 0, 0); + dbenv->txn_checkpoint(0, 0, 0); LogPrint("db", "CDBEnv::Flush: %s detach\n", strFile); if (!fMockDb) - dbenv.lsn_reset(strFile.c_str(), 0); + dbenv->lsn_reset(strFile.c_str(), 0); LogPrint("db", "CDBEnv::Flush: %s closed\n", strFile); mapFileUseCount.erase(mi++); } else @@ -443,7 +452,7 @@ void CDBEnv::Flush(bool fShutdown) if (fShutdown) { char** listp; if (mapFileUseCount.empty()) { - dbenv.log_archive(&listp, DB_ARCH_REMOVE); + dbenv->log_archive(&listp, DB_ARCH_REMOVE); Close(); if (!fMockDb) boost::filesystem::remove_all(path / "database"); diff --git a/src/db.h b/src/db.h index d208907c896..71133f96991 100644 --- a/src/db.h +++ b/src/db.h @@ -39,12 +39,14 @@ private: public: mutable CCriticalSection cs_db; - DbEnv dbenv; + DbEnv *dbenv; std::map mapFileUseCount; std::map mapDb; CDBEnv(); ~CDBEnv(); + void Reset(); + void MakeMock(); bool IsMock() { return fMockDb; } @@ -79,7 +81,7 @@ public: DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC) { DbTxn* ptxn = NULL; - int ret = dbenv.txn_begin(NULL, &ptxn, flags); + int ret = dbenv->txn_begin(NULL, &ptxn, flags); if (!ptxn || ret != 0) return NULL; return ptxn; diff --git a/src/main.cpp b/src/main.cpp index b6a61f7da1c..d945ece417f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,7 +54,6 @@ bool fTxIndex = false; bool fIsBareMultisigStd = true; unsigned int nCoinCacheSize = 5000; - /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */ CFeeRate minRelayTxFee = CFeeRate(1000); @@ -3085,10 +3084,31 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth void UnloadBlockIndex() { - mapBlockIndex.clear(); + LOCK(cs_main); setBlockIndexCandidates.clear(); chainActive.SetTip(NULL); pindexBestInvalid = NULL; + pindexBestHeader = NULL; + mempool.clear(); + mapOrphanTransactions.clear(); + mapOrphanTransactionsByPrev.clear(); + nSyncStarted = 0; + mapBlocksUnlinked.clear(); + vinfoBlockFile.clear(); + nLastBlockFile = 0; + nBlockSequenceId = 1; + mapBlockSource.clear(); + mapBlocksInFlight.clear(); + nQueuedValidatedHeaders = 0; + nPreferredDownload = 0; + setDirtyBlockIndex.clear(); + setDirtyFileInfo.clear(); + mapNodeState.clear(); + + BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) { + delete entry.second; + } + mapBlockIndex.clear(); } bool LoadBlockIndex() diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 9407511ecb8..bf255487550 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -16,6 +16,8 @@ #include "serialize.h" #include "util.h" +#include "test/test_bitcoin.h" + #include #include // for 'map_list_of()' @@ -41,7 +43,7 @@ CService ip(uint32_t i) return CService(CNetAddr(s), Params().GetDefaultPort()); } -BOOST_AUTO_TEST_SUITE(DoS_tests) +BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup) BOOST_AUTO_TEST_CASE(DoS_banning) { diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index da07b8c7a64..36499f01a7b 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -5,6 +5,8 @@ #include "wallet.h" #include "walletdb.h" +#include "test/test_bitcoin.h" + #include #include @@ -12,7 +14,7 @@ extern CWallet* pwalletMain; -BOOST_AUTO_TEST_SUITE(accounting_tests) +BOOST_FIXTURE_TEST_SUITE(accounting_tests, TestingSetup) static void GetResults(CWalletDB& walletdb, std::map& results) diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index efc92117179..5e1f5f0294e 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -15,6 +15,8 @@ #include "util.h" #include "utilstrencodings.h" +#include "test/test_bitcoin.h" + #include #include @@ -78,7 +80,7 @@ } #endif -struct ReadAlerts +struct ReadAlerts : public TestingSetup { ReadAlerts() { diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 44c57a8eaf2..6ab9cb8a440 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -8,9 +8,11 @@ #include "uint256.h" #include "util.h" +#include "test/test_bitcoin.h" + #include -BOOST_AUTO_TEST_SUITE(miner_tests) +BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup) static struct { diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 1c6963001ff..45cb551d04a 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -8,6 +8,8 @@ #include "base58.h" #include "netbase.h" +#include "test/test_bitcoin.h" + #include #include @@ -45,7 +47,7 @@ Value CallRPC(string args) } -BOOST_AUTO_TEST_SUITE(rpc_tests) +BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup) BOOST_AUTO_TEST_CASE(rpc_rawparams) { diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 57c49c2dfc5..44475076b3c 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -8,6 +8,8 @@ #include "base58.h" #include "wallet.h" +#include "test/test_bitcoin.h" + #include #include @@ -19,7 +21,7 @@ extern Value CallRPC(string args); extern CWallet* pwalletMain; -BOOST_AUTO_TEST_SUITE(rpc_wallet_tests) +BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup) BOOST_AUTO_TEST_CASE(rpc_addmultisig) { diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index f2dae99d693..5df417b8e5e 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -4,6 +4,8 @@ #define BOOST_TEST_MODULE Bitcoin Test Suite +#include "test_bitcoin.h" + #include "main.h" #include "random.h" #include "txdb.h" @@ -24,18 +26,15 @@ CWallet* pwalletMain; extern bool fPrintToConsole; extern void noui_connect(); -struct TestingSetup { - CCoinsViewDB *pcoinsdbview; - boost::filesystem::path pathTemp; - boost::thread_group threadGroup; - - TestingSetup() { +TestingSetup::TestingSetup() +{ fPrintToDebugLog = false; // don't want to write to debug.log file SelectParams(CBaseChainParams::UNITTEST); noui_connect(); #ifdef ENABLE_WALLET bitdb.MakeMock(); #endif + ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); boost::filesystem::create_directories(pathTemp); mapArgs["-datadir"] = pathTemp.string(); @@ -53,27 +52,28 @@ struct TestingSetup { for (int i=0; i < nScriptCheckThreads-1; i++) threadGroup.create_thread(&ThreadScriptCheck); RegisterNodeSignals(GetNodeSignals()); - } - ~TestingSetup() - { +} + +TestingSetup::~TestingSetup() +{ + UnregisterNodeSignals(GetNodeSignals()); threadGroup.interrupt_all(); threadGroup.join_all(); - UnregisterNodeSignals(GetNodeSignals()); #ifdef ENABLE_WALLET + UnregisterValidationInterface(pwalletMain); delete pwalletMain; pwalletMain = NULL; #endif + UnloadBlockIndex(); delete pcoinsTip; delete pcoinsdbview; delete pblocktree; #ifdef ENABLE_WALLET bitdb.Flush(true); + bitdb.Reset(); #endif boost::filesystem::remove_all(pathTemp); - } -}; - -BOOST_GLOBAL_FIXTURE(TestingSetup); +} void Shutdown(void* parg) { diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h new file mode 100644 index 00000000000..c1448dcdebe --- /dev/null +++ b/src/test/test_bitcoin.h @@ -0,0 +1,18 @@ +#ifndef BITCOIN_TEST_TEST_BITCOIN_H +#define BITCOIN_TEST_TEST_BITCOIN_H + +#include "txdb.h" + +#include +#include + +struct TestingSetup { + CCoinsViewDB *pcoinsdbview; + boost::filesystem::path pathTemp; + boost::thread_group threadGroup; + + TestingSetup(); + ~TestingSetup(); +}; + +#endif diff --git a/src/util.h b/src/util.h index bbb0e81039a..4d0cb7136e9 100644 --- a/src/util.h +++ b/src/util.h @@ -94,6 +94,7 @@ bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest); bool TryCreateDirectory(const boost::filesystem::path& p); boost::filesystem::path GetDefaultDataDir(); const boost::filesystem::path &GetDataDir(bool fNetSpecific = true); +void ClearDatadirCache(); boost::filesystem::path GetConfigFile(); #ifndef WIN32 boost::filesystem::path GetPidFile(); diff --git a/src/walletdb.cpp b/src/walletdb.cpp index b2daf036ff7..ddec57d9a90 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -903,8 +903,8 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) int64_t now = GetTime(); std::string newFilename = strprintf("wallet.%d.bak", now); - int result = dbenv.dbenv.dbrename(NULL, filename.c_str(), NULL, - newFilename.c_str(), DB_AUTO_COMMIT); + int result = dbenv.dbenv->dbrename(NULL, filename.c_str(), NULL, + newFilename.c_str(), DB_AUTO_COMMIT); if (result == 0) LogPrintf("Renamed %s to %s\n", filename, newFilename); else @@ -923,7 +923,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); bool fSuccess = allOK; - boost::scoped_ptr pdbCopy(new Db(&dbenv.dbenv, 0)); + boost::scoped_ptr pdbCopy(new Db(dbenv.dbenv, 0)); int ret = pdbCopy->open(NULL, // Txn pointer filename.c_str(), // Filename "main", // Logical db name From 90a43c1e93318584d5443b513c2c0e937acb966a Mon Sep 17 00:00:00 2001 From: Cozz Lovan Date: Tue, 10 Jun 2014 03:14:13 +0200 Subject: [PATCH 0282/2337] [Qt] Code-movement-only: Format confirmation message in sendcoinsdialog --- src/qt/sendcoinsdialog.cpp | 59 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 5aef2d7539b..4338e58e260 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -220,6 +220,36 @@ void SendCoinsDialog::on_sendButton_clicked() return; } + fNewRecipientAllowed = false; + + + WalletModel::UnlockContext ctx(model->requestUnlock()); + if(!ctx.isValid()) + { + // Unlock wallet was cancelled + fNewRecipientAllowed = true; + return; + } + + // prepare transaction for getting txFee earlier + WalletModelTransaction currentTransaction(recipients); + WalletModel::SendCoinsReturn prepareStatus; + if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled + prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl); + else + prepareStatus = model->prepareTransaction(currentTransaction); + + // process prepareStatus and on error generate message shown to user + processSendCoinsReturn(prepareStatus, + BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee())); + + if(prepareStatus.status != WalletModel::OK) { + fNewRecipientAllowed = true; + return; + } + + CAmount txFee = currentTransaction.getTransactionFee(); + // Format confirmation message QStringList formatted; foreach(const SendCoinsRecipient &rcp, recipients) @@ -257,35 +287,6 @@ void SendCoinsDialog::on_sendButton_clicked() formatted.append(recipientElement); } - fNewRecipientAllowed = false; - - - WalletModel::UnlockContext ctx(model->requestUnlock()); - if(!ctx.isValid()) - { - // Unlock wallet was cancelled - fNewRecipientAllowed = true; - return; - } - - // prepare transaction for getting txFee earlier - WalletModelTransaction currentTransaction(recipients); - WalletModel::SendCoinsReturn prepareStatus; - if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled - prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl); - else - prepareStatus = model->prepareTransaction(currentTransaction); - - // process prepareStatus and on error generate message shown to user - processSendCoinsReturn(prepareStatus, - BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee())); - - if(prepareStatus.status != WalletModel::OK) { - fNewRecipientAllowed = true; - return; - } - - CAmount txFee = currentTransaction.getTransactionFee(); QString questionString = tr("Are you sure you want to send?"); questionString.append("

%1"); From 84a05b843b8ab704266289de67c9779ad733a196 Mon Sep 17 00:00:00 2001 From: Rob Van Mieghem Date: Tue, 3 Mar 2015 08:42:52 +0100 Subject: [PATCH 0283/2337] QT: remove unused parameter --- src/qt/bitcoingui.cpp | 4 ++-- src/qt/bitcoingui.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 5c5da6dba0b..a0dcb46e27f 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -151,7 +151,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : // Create actions for the toolbar, menu bar and tray/dock icon // Needs walletFrame to be initialized - createActions(networkStyle); + createActions(); // Create application menu bar createMenuBar(); @@ -243,7 +243,7 @@ BitcoinGUI::~BitcoinGUI() delete rpcConsole; } -void BitcoinGUI::createActions(const NetworkStyle *networkStyle) +void BitcoinGUI::createActions() { QActionGroup *tabGroup = new QActionGroup(this); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 3216a7398ed..fd776d63f80 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -118,7 +118,7 @@ private: int spinnerFrame; /** Create the main UI actions. */ - void createActions(const NetworkStyle *networkStyle); + void createActions(); /** Create the menu bar and sub-menus. */ void createMenuBar(); /** Create the toolbars */ From 9bbb880be44dbc378bdd3210eed42eaa77efb774 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 6 Mar 2015 09:33:23 +0100 Subject: [PATCH 0284/2337] [Qt] fix a issue where "command line options"-action overwrite "Preference"-action (on OSX) - fixes #5800 --- src/qt/bitcoingui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index a0dcb46e27f..34209920815 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -340,6 +340,7 @@ void BitcoinGUI::createActions() openAction->setStatusTip(tr("Open a bitcoin: URI or payment request")); showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this); + showHelpMessageAction->setMenuRole(QAction::NoRole); showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options")); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); From 9519a9a4202cd5fcaaad6d4cf0bf6bad38a27369 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 5 Mar 2015 04:01:01 -0800 Subject: [PATCH 0285/2337] Add correct bool combiner for net signals --- src/net.h | 19 +++++++++++++++++-- src/test/main_tests.cpp | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/net.h b/src/net.h index d2b2d88ddbe..e500536cb49 100644 --- a/src/net.h +++ b/src/net.h @@ -76,12 +76,27 @@ void SocketSendData(CNode *pnode); typedef int NodeId; +struct CombinerAll +{ + typedef bool result_type; + + template + bool operator()(I first, I last) const + { + while (first != last) { + if (!(*first)) return false; + ++first; + } + return true; + } +}; + // Signals for message handling struct CNodeSignals { boost::signals2::signal GetHeight; - boost::signals2::signal ProcessMessages; - boost::signals2::signal SendMessages; + boost::signals2::signal ProcessMessages; + boost::signals2::signal SendMessages; boost::signals2::signal InitializeNode; boost::signals2::signal FinalizeNode; }; diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 2a72a220a48..5e968c26fff 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -21,4 +21,21 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test) BOOST_CHECK(nSum == 2099999997690000ULL); } +bool ReturnFalse() { return false; } +bool ReturnTrue() { return true; } + +BOOST_AUTO_TEST_CASE(test_combiner_all) +{ + boost::signals2::signal Test; + BOOST_CHECK(Test()); + Test.connect(&ReturnFalse); + BOOST_CHECK(!Test()); + Test.connect(&ReturnTrue); + BOOST_CHECK(!Test()); + Test.disconnect(&ReturnFalse); + BOOST_CHECK(Test()); + Test.disconnect(&ReturnTrue); + BOOST_CHECK(Test()); +} + BOOST_AUTO_TEST_SUITE_END() From ba04c4a7801e7d68a5e84035b919e5c3626eb7a7 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 5 Mar 2015 04:01:22 -0800 Subject: [PATCH 0286/2337] Limit message sizes before transfer This introduces a fixed limit for the size of p2p messages, and enforces it before download. --- src/net.cpp | 5 +++++ src/net.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index 3c3666615e1..d9f470b9e45 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -523,6 +523,11 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) if (handled < 0) return false; + if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) { + LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId()); + return false; + } + pch += handled; nBytes -= handled; diff --git a/src/net.h b/src/net.h index d2b2d88ddbe..24275d4a9d3 100644 --- a/src/net.h +++ b/src/net.h @@ -46,6 +46,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60; static const unsigned int MAX_INV_SZ = 50000; /** The maximum number of new addresses to accumulate before announcing. */ static const unsigned int MAX_ADDR_TO_SEND = 1000; +/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */ +static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024; /** -listen default */ static const bool DEFAULT_LISTEN = true; /** -upnp default */ From 4414f5ffe130f46becdc75c8e59ee74604e978aa Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 09:53:43 +0100 Subject: [PATCH 0287/2337] build: Endian compatibility - Detect endian instead of stopping configure on big-endian - Add `byteswap.h` and `endian.h` header for compatibility with Windows and other operating systems that don't come with them - Update `crypto/common.h` functions to use compat endian header --- configure.ac | 13 ++- src/Makefile.am | 2 + src/compat/byteswap.h | 47 ++++++++++ src/compat/endian.h | 194 ++++++++++++++++++++++++++++++++++++++++++ src/crypto/common.h | 76 +++-------------- 5 files changed, 263 insertions(+), 69 deletions(-) create mode 100644 src/compat/byteswap.h create mode 100644 src/compat/endian.h diff --git a/configure.ac b/configure.ac index f5bc1e3122b..2c918218bb8 100644 --- a/configure.ac +++ b/configure.ac @@ -350,8 +350,8 @@ if test x$use_lcov = xyes; then [AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")]) fi -dnl Require little endian -AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")]) +dnl Check for endianness +AC_C_BIGENDIAN dnl Check for pthread compile/link requirements AX_PTHREAD @@ -438,17 +438,22 @@ if test x$TARGET_OS = xdarwin; then AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) fi -AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) +AC_CHECK_HEADERS([endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])]) AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])]) AC_CHECK_DECLS([strnlen]) -AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,, +AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,, [#if HAVE_ENDIAN_H #include #endif]) +AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,, + [#if HAVE_BYTESWAP_H + #include + #endif]) + dnl Check for MSG_NOSIGNAL AC_MSG_CHECKING(for MSG_NOSIGNAL) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], diff --git a/src/Makefile.am b/src/Makefile.am index e1d467ff854..da65efa7132 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -141,6 +141,8 @@ BITCOIN_CORE_H = \ walletdb.h \ wallet.h \ wallet_ismine.h \ + compat/byteswap.h \ + compat/endian.h \ compat/sanity.h JSON_H = \ diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h new file mode 100644 index 00000000000..899220bdc54 --- /dev/null +++ b/src/compat/byteswap.h @@ -0,0 +1,47 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_COMPAT_BYTESWAP_H +#define BITCOIN_COMPAT_BYTESWAP_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include + +#if defined(HAVE_BYTESWAP_H) +#include +#endif + +#if HAVE_DECL_BSWAP_16 == 0 +inline uint16_t bswap_16(uint16_t x) +{ + return (x >> 8) | ((x & 0x00ff) << 8); +} +#endif // HAVE_DECL_BSWAP16 + +#if HAVE_DECL_BSWAP_32 == 0 +inline uint32_t bswap_32(uint32_t x) +{ + return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) | + ((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24)); +} +#endif // HAVE_DECL_BSWAP32 + +#if HAVE_DECL_BSWAP_64 == 0 +inline uint64_t bswap_64(uint64_t x) +{ + return (((x & 0xff00000000000000ull) >> 56) + | ((x & 0x00ff000000000000ull) >> 40) + | ((x & 0x0000ff0000000000ull) >> 24) + | ((x & 0x000000ff00000000ull) >> 8) + | ((x & 0x00000000ff000000ull) << 8) + | ((x & 0x0000000000ff0000ull) << 24) + | ((x & 0x000000000000ff00ull) << 40) + | ((x & 0x00000000000000ffull) << 56)); +} +#endif // HAVE_DECL_BSWAP64 + +#endif // BITCOIN_COMPAT_BYTESWAP_H diff --git a/src/compat/endian.h b/src/compat/endian.h new file mode 100644 index 00000000000..4d041d65541 --- /dev/null +++ b/src/compat/endian.h @@ -0,0 +1,194 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_COMPAT_ENDIAN_H +#define BITCOIN_COMPAT_ENDIAN_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include + +#include "compat/byteswap.h" + +#if defined(HAVE_ENDIAN_H) +#include +#endif + +#if defined(WORDS_BIGENDIAN) + +#if HAVE_DECL_HTOBE16 == 0 +inline uint16_t htobe16(uint16_t host_16bits) +{ + return host_16bits; +} +#endif // HAVE_DECL_HTOBE16 + +#if HAVE_DECL_HTOLE16 == 0 +inline uint16_t htole16(uint16_t host_16bits) +{ + return bswap_16(host_16bits); +} +#endif // HAVE_DECL_HTOLE16 + +#if HAVE_DECL_BE16TOH == 0 +inline uint16_t be16toh(uint16_t big_endian_16bits) +{ + return big_endian_16bits; +} +#endif // HAVE_DECL_BE16TOH + +#if HAVE_DECL_LE16TOH == 0 +inline uint16_t le16toh(uint16_t little_endian_16bits) +{ + return bswap_16(little_endian_16bits); +} +#endif // HAVE_DECL_LE16TOH + +#if HAVE_DECL_HTOBE32 == 0 +inline uint32_t htobe32(uint32_t host_32bits) +{ + return host_32bits; +} +#endif // HAVE_DECL_HTOBE32 + +#if HAVE_DECL_HTOLE32 == 0 +inline uint32_t htole32(uint32_t host_32bits) +{ + return bswap_32(host_32bits); +} +#endif // HAVE_DECL_HTOLE32 + +#if HAVE_DECL_BE32TOH == 0 +inline uint32_t be32toh(uint32_t big_endian_32bits) +{ + return big_endian_32bits; +} +#endif // HAVE_DECL_BE32TOH + +#if HAVE_DECL_LE32TOH == 0 +inline uint32_t le32toh(uint32_t little_endian_32bits) +{ + return bswap_32(little_endian_32bits); +} +#endif // HAVE_DECL_LE32TOH + +#if HAVE_DECL_HTOBE64 == 0 +inline uint64_t htobe64(uint64_t host_64bits) +{ + return host_64bits; +} +#endif // HAVE_DECL_HTOBE64 + +#if HAVE_DECL_HTOLE64 == 0 +inline uint64_t htole64(uint64_t host_64bits) +{ + return bswap_64(host_64bits); +} +#endif // HAVE_DECL_HTOLE64 + +#if HAVE_DECL_BE64TOH == 0 +inline uint64_t be64toh(uint64_t big_endian_64bits) +{ + return big_endian_64bits; +} +#endif // HAVE_DECL_BE64TOH + +#if HAVE_DECL_LE64TOH == 0 +inline uint64_t le64toh(uint64_t little_endian_64bits) +{ + return bswap_64(little_endian_64bits); +} +#endif // HAVE_DECL_LE64TOH + +#else // WORDS_BIGENDIAN + +#if HAVE_DECL_HTOBE16 == 0 +inline uint16_t htobe16(uint16_t host_16bits) +{ + return bswap_16(host_16bits); +} +#endif // HAVE_DECL_HTOBE16 + +#if HAVE_DECL_HTOLE16 == 0 +inline uint16_t htole16(uint16_t host_16bits) +{ + return host_16bits; +} +#endif // HAVE_DECL_HTOLE16 + +#if HAVE_DECL_BE16TOH == 0 +inline uint16_t be16toh(uint16_t big_endian_16bits) +{ + return bswap_16(big_endian_16bits); +} +#endif // HAVE_DECL_BE16TOH + +#if HAVE_DECL_LE16TOH == 0 +inline uint16_t le16toh(uint16_t little_endian_16bits) +{ + return little_endian_16bits; +} +#endif // HAVE_DECL_LE16TOH + +#if HAVE_DECL_HTOBE32 == 0 +inline uint32_t htobe32(uint32_t host_32bits) +{ + return bswap_32(host_32bits); +} +#endif // HAVE_DECL_HTOBE32 + +#if HAVE_DECL_HTOLE32 == 0 +inline uint32_t htole32(uint32_t host_32bits) +{ + return host_32bits; +} +#endif // HAVE_DECL_HTOLE32 + +#if HAVE_DECL_BE32TOH == 0 +inline uint32_t be32toh(uint32_t big_endian_32bits) +{ + return bswap_32(big_endian_32bits); +} +#endif // HAVE_DECL_BE32TOH + +#if HAVE_DECL_LE32TOH == 0 +inline uint32_t le32toh(uint32_t little_endian_32bits) +{ + return little_endian_32bits; +} +#endif // HAVE_DECL_LE32TOH + +#if HAVE_DECL_HTOBE64 == 0 +inline uint64_t htobe64(uint64_t host_64bits) +{ + return bswap_64(host_64bits); +} +#endif // HAVE_DECL_HTOBE64 + +#if HAVE_DECL_HTOLE64 == 0 +inline uint64_t htole64(uint64_t host_64bits) +{ + return host_64bits; +} +#endif // HAVE_DECL_HTOLE64 + +#if HAVE_DECL_BE64TOH == 0 +inline uint64_t be64toh(uint64_t big_endian_64bits) +{ + return bswap_64(big_endian_64bits); +} +#endif // HAVE_DECL_BE64TOH + +#if HAVE_DECL_LE64TOH == 0 +inline uint64_t le64toh(uint64_t little_endian_64bits) +{ + return little_endian_64bits; +} +#endif // HAVE_DECL_LE64TOH + +#endif // WORDS_BIGENDIAN + +#endif // BITCOIN_COMPAT_ENDIAN_H diff --git a/src/crypto/common.h b/src/crypto/common.h index 8b04b1f728f..580c72f5a64 100644 --- a/src/crypto/common.h +++ b/src/crypto/common.h @@ -11,110 +11,56 @@ #include -#if defined(HAVE_ENDIAN_H) -#include -#endif +#include "compat/endian.h" + +uint16_t static inline ReadLE16(const unsigned char* ptr) +{ + return le16toh(*((uint16_t*)ptr)); +} uint32_t static inline ReadLE32(const unsigned char* ptr) { -#if HAVE_DECL_LE32TOH == 1 return le32toh(*((uint32_t*)ptr)); -#elif !defined(WORDS_BIGENDIAN) - return *((uint32_t*)ptr); -#else - return ((uint32_t)ptr[3] << 24 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[0]); -#endif } uint64_t static inline ReadLE64(const unsigned char* ptr) { -#if HAVE_DECL_LE64TOH == 1 return le64toh(*((uint64_t*)ptr)); -#elif !defined(WORDS_BIGENDIAN) - return *((uint64_t*)ptr); -#else - return ((uint64_t)ptr[7] << 56 | (uint64_t)ptr[6] << 48 | (uint64_t)ptr[5] << 40 | (uint64_t)ptr[4] << 32 | - (uint64_t)ptr[3] << 24 | (uint64_t)ptr[2] << 16 | (uint64_t)ptr[1] << 8 | (uint64_t)ptr[0]); -#endif +} + +void static inline WriteLE16(unsigned char* ptr, uint16_t x) +{ + *((uint16_t*)ptr) = htole16(x); } void static inline WriteLE32(unsigned char* ptr, uint32_t x) { -#if HAVE_DECL_HTOLE32 == 1 *((uint32_t*)ptr) = htole32(x); -#elif !defined(WORDS_BIGENDIAN) - *((uint32_t*)ptr) = x; -#else - ptr[3] = x >> 24; - ptr[2] = x >> 16; - ptr[1] = x >> 8; - ptr[0] = x; -#endif } void static inline WriteLE64(unsigned char* ptr, uint64_t x) { -#if HAVE_DECL_HTOLE64 == 1 *((uint64_t*)ptr) = htole64(x); -#elif !defined(WORDS_BIGENDIAN) - *((uint64_t*)ptr) = x; -#else - ptr[7] = x >> 56; - ptr[6] = x >> 48; - ptr[5] = x >> 40; - ptr[4] = x >> 32; - ptr[3] = x >> 24; - ptr[2] = x >> 16; - ptr[1] = x >> 8; - ptr[0] = x; -#endif } uint32_t static inline ReadBE32(const unsigned char* ptr) { -#if HAVE_DECL_BE32TOH == 1 return be32toh(*((uint32_t*)ptr)); -#else - return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]); -#endif } uint64_t static inline ReadBE64(const unsigned char* ptr) { -#if HAVE_DECL_BE64TOH == 1 return be64toh(*((uint64_t*)ptr)); -#else - return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 | - (uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]); -#endif } void static inline WriteBE32(unsigned char* ptr, uint32_t x) { -#if HAVE_DECL_HTOBE32 == 1 *((uint32_t*)ptr) = htobe32(x); -#else - ptr[0] = x >> 24; - ptr[1] = x >> 16; - ptr[2] = x >> 8; - ptr[3] = x; -#endif } void static inline WriteBE64(unsigned char* ptr, uint64_t x) { -#if HAVE_DECL_HTOBE64 == 1 *((uint64_t*)ptr) = htobe64(x); -#else - ptr[0] = x >> 56; - ptr[1] = x >> 48; - ptr[2] = x >> 40; - ptr[3] = x >> 32; - ptr[4] = x >> 24; - ptr[5] = x >> 16; - ptr[6] = x >> 8; - ptr[7] = x; -#endif } #endif // BITCOIN_CRYPTO_COMMON_H From 3ca5852dc27cec926e4e7b09ec3ccc369a2a0781 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 11:38:03 +0100 Subject: [PATCH 0288/2337] src/hash.cpp: endian compatibility --- src/hash.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hash.cpp b/src/hash.cpp index a7eb5a2a0b1..20d5d217778 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -3,8 +3,10 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "hash.h" +#include "crypto/common.h" #include "crypto/hmac_sha512.h" + inline uint32_t ROTL32(uint32_t x, int8_t r) { return (x << r) | (x >> (32 - r)); @@ -23,10 +25,10 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector Date: Thu, 26 Feb 2015 20:57:08 +0000 Subject: [PATCH 0289/2337] GUI: Display label rather than address on popups --- src/qt/bitcoingui.cpp | 18 +++++++++--------- src/qt/bitcoingui.h | 2 +- src/qt/walletview.cpp | 8 +++++--- src/qt/walletview.h | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 09f784387ea..f64437f852b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -859,18 +859,18 @@ void BitcoinGUI::closeEvent(QCloseEvent *event) } #ifdef ENABLE_WALLET -void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address) +void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label) { // On new transaction, make an info balloon + QString msg = tr("Date: %1\n").arg(date) + + tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true)) + + tr("Type: %1\n").arg(type); + if (!label.isEmpty()) + msg += tr("Label: %1\n").arg(label); + else if (!address.isEmpty()) + msg += tr("Address: %1\n").arg(address); message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"), - tr("Date: %1\n" - "Amount: %2\n" - "Type: %3\n" - "Address: %4\n") - .arg(date) - .arg(BitcoinUnits::formatWithUnit(unit, amount, true)) - .arg(type) - .arg(address), CClientUIInterface::MSG_INFORMATION); + msg, CClientUIInterface::MSG_INFORMATION); } #endif // ENABLE_WALLET diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 3216a7398ed..c47d7a42477 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -165,7 +165,7 @@ public slots: bool handlePaymentRequest(const SendCoinsRecipient& recipient); /** Show incoming transaction notification for new transactions. */ - void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address); + void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label); #endif // ENABLE_WALLET private slots: diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 9d6a0601949..956c8b89131 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -93,7 +93,7 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui) connect(this, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int))); // Pass through transaction notifications - connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString))); + connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString))); } } @@ -149,9 +149,11 @@ void WalletView::processNewTransaction(const QModelIndex& parent, int start, int QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString(); qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong(); QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString(); - QString address = ttm->index(start, TransactionTableModel::ToAddress, parent).data().toString(); + QModelIndex index = ttm->index(start, 0, parent); + QString address = ttm->data(index, TransactionTableModel::AddressRole).toString(); + QString label = ttm->data(index, TransactionTableModel::LabelRole).toString(); - emit incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address); + emit incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label); } void WalletView::gotoOverviewPage() diff --git a/src/qt/walletview.h b/src/qt/walletview.h index f3d14c065c0..1840e21e9cf 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -113,7 +113,7 @@ signals: /** Encryption status of wallet changed */ void encryptionStatusChanged(int status); /** Notify that a new transaction appeared */ - void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address); + void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label); }; #endif // BITCOIN_QT_WALLETVIEW_H From 556814ec4ec7e2c5a1b441f8b9a49dbf715fec6b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 11:38:30 +0100 Subject: [PATCH 0290/2337] src/main.cpp: endian compatibility in packet checksum check --- src/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b6a61f7da1c..9927ac75987 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4318,8 +4318,7 @@ bool ProcessMessages(CNode* pfrom) // Checksum CDataStream& vRecv = msg.vRecv; uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize); - unsigned int nChecksum = 0; - memcpy(&nChecksum, &hash, sizeof(nChecksum)); + unsigned int nChecksum = ReadLE32((unsigned char*)&hash); if (nChecksum != hdr.nChecksum) { LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", From dec84cae2a7534af95873d5d96e38ad96b447d52 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 11:38:57 +0100 Subject: [PATCH 0291/2337] src/net.cpp: endian compatibility in EndMessage --- src/net.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index d9f470b9e45..08d1d574083 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -14,6 +14,7 @@ #include "clientversion.h" #include "primitives/transaction.h" #include "ui_interface.h" +#include "crypto/common.h" #ifdef WIN32 #include @@ -2007,7 +2008,7 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) // Set the size unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE; - memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize)); + WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize); // Set the checksum uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end()); From 81aeb28436d847ed4e6bcda8c746a3e5631c7feb Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 11:39:38 +0100 Subject: [PATCH 0292/2337] src/primitives/block.cpp: endian compatibility in GetHash --- src/primitives/block.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 3b4a360395f..8338762a38a 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -8,10 +8,22 @@ #include "hash.h" #include "tinyformat.h" #include "utilstrencodings.h" +#include "crypto/common.h" uint256 CBlockHeader::GetHash() const { +#if defined(WORDS_BIGENDIAN) + uint8_t data[80]; + WriteLE32(&data[0], nVersion); + memcpy(&data[4], hashPrevBlock.begin(), hashPrevBlock.size()); + memcpy(&data[36], hashMerkleRoot.begin(), hashMerkleRoot.size()); + WriteLE32(&data[68], nTime); + WriteLE32(&data[72], nBits); + WriteLE32(&data[76], nNonce); + return Hash(data, data + 80); +#else // Can take shortcut for little endian return Hash(BEGIN(nVersion), END(nNonce)); +#endif } uint256 CBlock::BuildMerkleTree(bool* fMutated) const From 4f92773f9285760fe3e2eb14f5ca21de850d1955 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 11:40:00 +0100 Subject: [PATCH 0293/2337] src/primitives/transaction.h: endian compatibility in serialization --- src/primitives/transaction.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 1b5a47e0da9..0ba9affeda5 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -25,7 +25,8 @@ public: template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(FLATDATA(*this)); + READWRITE(hash); + READWRITE(n); } void SetNull() { hash.SetNull(); n = (uint32_t) -1; } From 4e853aa163ddb978d25bd8b8ecfd730a1d09e051 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 11:41:12 +0100 Subject: [PATCH 0294/2337] src/script/script.h: endian compatibility for PUSHDATA sizes --- src/script/script.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/script/script.h b/src/script/script.h index 8b36aa2f506..ed456f5c5ad 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -14,6 +14,7 @@ #include #include #include +#include "crypto/common.h" static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes @@ -416,14 +417,16 @@ public: else if (b.size() <= 0xffff) { insert(end(), OP_PUSHDATA2); - unsigned short nSize = b.size(); - insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + uint8_t data[2]; + WriteLE16(data, b.size()); + insert(end(), data, data + sizeof(data)); } else { insert(end(), OP_PUSHDATA4); - unsigned int nSize = b.size(); - insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + uint8_t data[4]; + WriteLE32(data, b.size()); + insert(end(), data, data + sizeof(data)); } insert(end(), b.begin(), b.end()); return *this; @@ -496,15 +499,14 @@ public: { if (end() - pc < 2) return false; - nSize = 0; - memcpy(&nSize, &pc[0], 2); + nSize = ReadLE16(&pc[0]); pc += 2; } else if (opcode == OP_PUSHDATA4) { if (end() - pc < 4) return false; - memcpy(&nSize, &pc[0], 4); + nSize = ReadLE32(&pc[0]); pc += 4; } if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize) From 01f9c3449a88748722dd51c7b54305fd1ba87359 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 11:41:50 +0100 Subject: [PATCH 0295/2337] src/serialize.h: base serialization level endianness neutrality Serialization type-safety and endianness compatibility. --- src/serialize.h | 197 ++++++++++++++++++++++------------- src/test/serialize_tests.cpp | 24 +++++ 2 files changed, 147 insertions(+), 74 deletions(-) diff --git a/src/serialize.h b/src/serialize.h index a62760a7938..741f78f8b4f 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -18,6 +18,8 @@ #include #include +#include "compat/endian.h" + class CScript; static const unsigned int MAX_SIZE = 0x02000000; @@ -71,6 +73,79 @@ inline const T* end_ptr(const std::vector& v) return v.empty() ? NULL : (&v[0] + v.size()); } +/* + * Lowest-level serialization and conversion. + * @note Sizes of these types are verified in the tests + */ +template inline void ser_writedata8(Stream &s, uint8_t obj) +{ + s.write((char*)&obj, 1); +} +template inline void ser_writedata16(Stream &s, uint16_t obj) +{ + obj = htole16(obj); + s.write((char*)&obj, 2); +} +template inline void ser_writedata32(Stream &s, uint32_t obj) +{ + obj = htole32(obj); + s.write((char*)&obj, 4); +} +template inline void ser_writedata64(Stream &s, uint64_t obj) +{ + obj = htole64(obj); + s.write((char*)&obj, 8); +} +template inline uint8_t ser_readdata8(Stream &s) +{ + uint8_t obj; + s.read((char*)&obj, 1); + return obj; +} +template inline uint16_t ser_readdata16(Stream &s) +{ + uint16_t obj; + s.read((char*)&obj, 2); + return le16toh(obj); +} +template inline uint32_t ser_readdata32(Stream &s) +{ + uint32_t obj; + s.read((char*)&obj, 4); + return le32toh(obj); +} +template inline uint64_t ser_readdata64(Stream &s) +{ + uint64_t obj; + s.read((char*)&obj, 8); + return le64toh(obj); +} +inline uint64_t ser_double_to_uint64(double x) +{ + union { double x; uint64_t y; } tmp; + tmp.x = x; + return tmp.y; +} +inline uint32_t ser_float_to_uint32(float x) +{ + union { float x; uint32_t y; } tmp; + tmp.x = x; + return tmp.y; +} +inline double ser_uint64_to_double(uint64_t y) +{ + union { double x; uint64_t y; } tmp; + tmp.y = y; + return tmp.x; +} +inline float ser_uint32_to_float(uint32_t y) +{ + union { float x; uint32_t y; } tmp; + tmp.y = y; + return tmp.x; +} + + ///////////////////////////////////////////////////////////////// // // Templates for serializing to anything that looks like a stream, @@ -108,59 +183,48 @@ enum SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \ } - - /* * Basic Types */ -#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) -#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj)) +inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; } +inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; } +inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; } +inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; } +inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; } +inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; } +inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; } +inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; } +inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; } +inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; } +inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; } -inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(signed long long a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(unsigned long long a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); } -inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); } +template inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char +template inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); } +template inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); } +template inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); } +template inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); } +template inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); } +template inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); } +template inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); } +template inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); } +template inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); } +template inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); } -template inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, signed long long a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, unsigned long long a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); } -template inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); } - -template inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, signed long long& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, unsigned long long& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); } -template inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char +template inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); } +template inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); } +template inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); } +template inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); } +template inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); } +template inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); } +template inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); } +template inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); } +template inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); } +template inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); } inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); } -template inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); } -template inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; } +template inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); } +template inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); a=f; } @@ -187,29 +251,22 @@ void WriteCompactSize(Stream& os, uint64_t nSize) { if (nSize < 253) { - unsigned char chSize = nSize; - WRITEDATA(os, chSize); + ser_writedata8(os, nSize); } else if (nSize <= std::numeric_limits::max()) { - unsigned char chSize = 253; - unsigned short xSize = nSize; - WRITEDATA(os, chSize); - WRITEDATA(os, xSize); + ser_writedata8(os, 253); + ser_writedata16(os, nSize); } else if (nSize <= std::numeric_limits::max()) { - unsigned char chSize = 254; - unsigned int xSize = nSize; - WRITEDATA(os, chSize); - WRITEDATA(os, xSize); + ser_writedata8(os, 254); + ser_writedata32(os, nSize); } else { - unsigned char chSize = 255; - uint64_t xSize = nSize; - WRITEDATA(os, chSize); - WRITEDATA(os, xSize); + ser_writedata8(os, 255); + ser_writedata64(os, nSize); } return; } @@ -217,8 +274,7 @@ void WriteCompactSize(Stream& os, uint64_t nSize) template uint64_t ReadCompactSize(Stream& is) { - unsigned char chSize; - READDATA(is, chSize); + uint8_t chSize = ser_readdata8(is); uint64_t nSizeRet = 0; if (chSize < 253) { @@ -226,25 +282,19 @@ uint64_t ReadCompactSize(Stream& is) } else if (chSize == 253) { - unsigned short xSize; - READDATA(is, xSize); - nSizeRet = xSize; + nSizeRet = ser_readdata16(is); if (nSizeRet < 253) throw std::ios_base::failure("non-canonical ReadCompactSize()"); } else if (chSize == 254) { - unsigned int xSize; - READDATA(is, xSize); - nSizeRet = xSize; + nSizeRet = ser_readdata32(is); if (nSizeRet < 0x10000u) throw std::ios_base::failure("non-canonical ReadCompactSize()"); } else { - uint64_t xSize; - READDATA(is, xSize); - nSizeRet = xSize; + nSizeRet = ser_readdata64(is); if (nSizeRet < 0x100000000ULL) throw std::ios_base::failure("non-canonical ReadCompactSize()"); } @@ -303,7 +353,7 @@ void WriteVarInt(Stream& os, I n) len++; } do { - WRITEDATA(os, tmp[len]); + ser_writedata8(os, tmp[len]); } while(len--); } @@ -312,8 +362,7 @@ I ReadVarInt(Stream& is) { I n = 0; while(true) { - unsigned char chData; - READDATA(is, chData); + unsigned char chData = ser_readdata8(is); n = (n << 7) | (chData & 0x7F); if (chData & 0x80) n++; diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index fe49af711bd..e2d19ce5ccb 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -13,6 +13,30 @@ using namespace std; BOOST_AUTO_TEST_SUITE(serialize_tests) +BOOST_AUTO_TEST_CASE(sizes) +{ + BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0)); + BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0)); + BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0)); + BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0)); + BOOST_CHECK_EQUAL(sizeof(uint16_t), GetSerializeSize(uint16_t(0), 0)); + BOOST_CHECK_EQUAL(sizeof(int32_t), GetSerializeSize(int32_t(0), 0)); + BOOST_CHECK_EQUAL(sizeof(uint32_t), GetSerializeSize(uint32_t(0), 0)); + BOOST_CHECK_EQUAL(sizeof(int64_t), GetSerializeSize(int64_t(0), 0)); + BOOST_CHECK_EQUAL(sizeof(uint64_t), GetSerializeSize(uint64_t(0), 0)); + BOOST_CHECK_EQUAL(sizeof(float), GetSerializeSize(float(0), 0)); + BOOST_CHECK_EQUAL(sizeof(double), GetSerializeSize(double(0), 0)); + + // Bool is serialized as char + BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0)); +} + +BOOST_AUTO_TEST_CASE(floats) +{ + // TODO ser_uint32_to_float, ser_uint64_to_double + // TODO ser_float_to_uint32, ser_double_to_uint64 +} + BOOST_AUTO_TEST_CASE(varints) { // encode From aac320537523f1df1523adeba22a8498884715c9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 18 Dec 2014 22:07:31 +0100 Subject: [PATCH 0296/2337] src/netbase.h: Fix endian in CNetAddr serialization We've chosen to htons/ntohs explicitly on reading and writing (I do not know why). But as READWRITE already does an endian swap on big endian, this means the port number gets switched around, which was what we were trying to avoid in the first place. So to make this compatible, serialize it as FLATDATA. --- src/netbase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netbase.h b/src/netbase.h index 5bf13a673f3..b42c2dffa4d 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -162,7 +162,7 @@ class CService : public CNetAddr inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(FLATDATA(ip)); unsigned short portN = htons(port); - READWRITE(portN); + READWRITE(FLATDATA(portN)); if (ser_action.ForRead()) port = ntohs(portN); } From f4e6487219d4b861df71e80d89d864ff6f312d17 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 13:08:06 +0100 Subject: [PATCH 0297/2337] src/arith_256.cpp: bigendian compatibility --- src/arith_uint256.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 1243823da52..2e613635761 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -7,6 +7,7 @@ #include "uint256.h" #include "utilstrencodings.h" +#include "crypto/common.h" #include #include @@ -246,14 +247,14 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const uint256 ArithToUint256(const arith_uint256 &a) { uint256 b; - // TODO: needs bswap32 on big-endian - memcpy(b.begin(), a.pn, a.size()); + for(int x=0; x Date: Fri, 19 Dec 2014 15:21:47 +0100 Subject: [PATCH 0298/2337] src/txmempool.cpp: make numEntries a uint32_t Don't ever serialize a size_t or long, their sizes are platform dependent. --- src/txmempool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 6e0f7e9c5a6..0d506603276 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -337,7 +337,7 @@ public: void Write(CAutoFile& fileout) const { fileout << nBestSeenHeight; - fileout << history.size(); + fileout << (uint32_t)history.size(); BOOST_FOREACH(const CBlockAverage& entry, history) { entry.Write(fileout); @@ -348,7 +348,7 @@ public: { int nFileBestSeenHeight; filein >> nFileBestSeenHeight; - size_t numEntries; + uint32_t numEntries; filein >> numEntries; if (numEntries <= 0 || numEntries > 10000) throw runtime_error("Corrupt estimates file. Must have between 1 and 10k entries."); From 62b30f09acae20f83dfb7995fa8b221c35e2fbff Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 14 Jan 2015 11:07:13 +0100 Subject: [PATCH 0299/2337] Add serialize float/double tests --- src/test/serialize_tests.cpp | 96 ++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index e2d19ce5ccb..de9510d54a4 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -4,6 +4,7 @@ #include "serialize.h" #include "streams.h" +#include "hash.h" #include @@ -26,15 +27,104 @@ BOOST_AUTO_TEST_CASE(sizes) BOOST_CHECK_EQUAL(sizeof(uint64_t), GetSerializeSize(uint64_t(0), 0)); BOOST_CHECK_EQUAL(sizeof(float), GetSerializeSize(float(0), 0)); BOOST_CHECK_EQUAL(sizeof(double), GetSerializeSize(double(0), 0)); - // Bool is serialized as char BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0)); + + // Sanity-check GetSerializeSize and c++ type matching + BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1); + BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1); + BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1); + BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2); + BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2); + BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4); + BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4); + BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8); + BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8); + BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4); + BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8); + BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1); } +BOOST_AUTO_TEST_CASE(floats_conversion) +{ + // Choose values that map unambigiously to binary floating point to avoid + // rounding issues at the compiler side. + BOOST_CHECK_EQUAL(ser_uint32_to_float(0x00000000), 0.0F); + BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f000000), 0.5F); + BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f800000), 1.0F); + BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40000000), 2.0F); + BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40800000), 4.0F); + BOOST_CHECK_EQUAL(ser_uint32_to_float(0x44444444), 785.066650390625F); + + BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000); + BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000); + BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000); + BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000); + BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000); + BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444); +} + +BOOST_AUTO_TEST_CASE(doubles_conversion) +{ + // Choose values that map unambigiously to binary floating point to avoid + // rounding issues at the compiler side. + BOOST_CHECK_EQUAL(ser_uint64_to_double(0x0000000000000000ULL), 0.0); + BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3fe0000000000000ULL), 0.5); + BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3ff0000000000000ULL), 1.0); + BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4000000000000000ULL), 2.0); + BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4010000000000000ULL), 4.0); + BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4088888880000000ULL), 785.066650390625); + + BOOST_CHECK_EQUAL(ser_double_to_uint64(0.0), 0x0000000000000000ULL); + BOOST_CHECK_EQUAL(ser_double_to_uint64(0.5), 0x3fe0000000000000ULL); + BOOST_CHECK_EQUAL(ser_double_to_uint64(1.0), 0x3ff0000000000000ULL); + BOOST_CHECK_EQUAL(ser_double_to_uint64(2.0), 0x4000000000000000ULL); + BOOST_CHECK_EQUAL(ser_double_to_uint64(4.0), 0x4010000000000000ULL); + BOOST_CHECK_EQUAL(ser_double_to_uint64(785.066650390625), 0x4088888880000000ULL); +} +/* +Python code to generate the below hashes: + + def reversed_hex(x): + return binascii.hexlify(''.join(reversed(x))) + def dsha256(x): + return hashlib.sha256(hashlib.sha256(x).digest()).digest() + + reversed_hex(dsha256(''.join(struct.pack('> j; + BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i); + } +} + +BOOST_AUTO_TEST_CASE(doubles) +{ + CDataStream ss(SER_DISK, 0); + // encode + for (int i = 0; i < 1000; i++) { + ss << double(i); + } + BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96")); + + // decode + for (int i = 0; i < 1000; i++) { + double j; + ss >> j; + BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i); + } } BOOST_AUTO_TEST_CASE(varints) From a0ae79d77552d9ee67469c934458a3f3bd170858 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 18 Jan 2015 19:23:05 +0100 Subject: [PATCH 0300/2337] Replace CBlockHeader::GetHash with call to SerializeHash Removes variability between LE and BE. As suggested by @sipa. --- src/primitives/block.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 8338762a38a..5b9c13d8701 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -12,18 +12,7 @@ uint256 CBlockHeader::GetHash() const { -#if defined(WORDS_BIGENDIAN) - uint8_t data[80]; - WriteLE32(&data[0], nVersion); - memcpy(&data[4], hashPrevBlock.begin(), hashPrevBlock.size()); - memcpy(&data[36], hashMerkleRoot.begin(), hashMerkleRoot.size()); - WriteLE32(&data[68], nTime); - WriteLE32(&data[72], nBits); - WriteLE32(&data[76], nNonce); - return Hash(data, data + 80); -#else // Can take shortcut for little endian - return Hash(BEGIN(nVersion), END(nNonce)); -#endif + return SerializeHash(*this); } uint256 CBlock::BuildMerkleTree(bool* fMutated) const From 69866436be692497cf7e0aabd93a2becdcdd72f5 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Thu, 5 Mar 2015 11:49:06 -0500 Subject: [PATCH 0301/2337] Run unit tests in different orders Set the BOOST_TEST_RANDOM environment variable, to run unit tests in different orders for each test in the test matrix that runs tests. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index e08e78dabf5..9c18729b42a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ env: global: - MAKEJOBS=-j3 - RUN_TESTS=false + - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID - CCACHE_SIZE=100M - CCACHE_TEMPDIR=/tmp/.ccache-temp - CCACHE_COMPRESS=1 From 8517e9709e883ef59603d56b45dd2e06f8b7c7d7 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Mon, 9 Feb 2015 11:19:01 +0100 Subject: [PATCH 0302/2337] [Qt] rework setNumBlocks to have blockDate as parameter - reduces some functional overhead and simplifies the code --- src/qt/bitcoingui.cpp | 9 ++++----- src/qt/bitcoingui.h | 4 ++-- src/qt/clientmodel.cpp | 18 ++++++++++++------ src/qt/clientmodel.h | 5 +++-- src/qt/rpcconsole.cpp | 9 ++++----- src/qt/rpcconsole.h | 4 ++-- src/qt/sendcoinsdialog.cpp | 2 +- 7 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 34209920815..1ec968ff2be 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -436,8 +436,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) setNumConnections(clientModel->getNumConnections()); connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(clientModel->getNumBlocks()); - connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int))); + setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate()); + connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime))); // Receive and report messages from client model connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int))); @@ -653,7 +653,7 @@ void BitcoinGUI::setNumConnections(int count) labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count)); } -void BitcoinGUI::setNumBlocks(int count) +void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate) { if(!clientModel) return; @@ -681,9 +681,8 @@ void BitcoinGUI::setNumBlocks(int count) QString tooltip; - QDateTime lastBlockDate = clientModel->getLastBlockDate(); QDateTime currentDate = QDateTime::currentDateTime(); - qint64 secs = lastBlockDate.secsTo(currentDate); + qint64 secs = blockDate.secsTo(currentDate); tooltip = tr("Processed %n blocks of transaction history.", "", count); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index fd776d63f80..5a289a90460 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -143,8 +143,8 @@ signals: public slots: /** Set number of connections shown in the UI */ void setNumConnections(int count); - /** Set number of blocks shown in the UI */ - void setNumBlocks(int count); + /** Set number of blocks and last block date shown in the UI */ + void setNumBlocks(int count, const QDateTime& blockDate); /** Notify the user of an event from the core network or transaction handling code. @param[in] title the message box / notification title diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 729eb84a181..dc32f815710 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -18,7 +18,6 @@ #include -#include #include #include @@ -29,6 +28,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : optionsModel(optionsModel), peerTableModel(0), cachedNumBlocks(0), + cachedBlockDate(QDateTime()), cachedReindexing(0), cachedImporting(0), pollTimer(0) @@ -79,10 +79,11 @@ quint64 ClientModel::getTotalBytesSent() const QDateTime ClientModel::getLastBlockDate() const { LOCK(cs_main); + if (chainActive.Tip()) return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime()); - else - return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network + + return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network } double ClientModel::getVerificationProgress() const @@ -97,21 +98,26 @@ void ClientModel::updateTimer() // periodical polls if the core is holding the locks for a longer time - // for example, during a wallet rescan. TRY_LOCK(cs_main, lockMain); - if(!lockMain) + if (!lockMain) return; + // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change. // Periodically check and update with a timer. int newNumBlocks = getNumBlocks(); + QDateTime newBlockDate = getLastBlockDate(); // check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state if (cachedNumBlocks != newNumBlocks || - cachedReindexing != fReindex || cachedImporting != fImporting) + cachedBlockDate != newBlockDate || + cachedReindexing != fReindex || + cachedImporting != fImporting) { cachedNumBlocks = newNumBlocks; + cachedBlockDate = newBlockDate; cachedReindexing = fReindex; cachedImporting = fImporting; - emit numBlocksChanged(newNumBlocks); + emit numBlocksChanged(newNumBlocks, newBlockDate); } emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 7b74728b262..214701810c0 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -6,6 +6,7 @@ #define BITCOIN_QT_CLIENTMODEL_H #include +#include class AddressTableModel; class OptionsModel; @@ -15,7 +16,6 @@ class TransactionTableModel; class CWallet; QT_BEGIN_NAMESPACE -class QDateTime; class QTimer; QT_END_NAMESPACE @@ -73,6 +73,7 @@ private: PeerTableModel *peerTableModel; int cachedNumBlocks; + QDateTime cachedBlockDate; bool cachedReindexing; bool cachedImporting; @@ -83,7 +84,7 @@ private: signals: void numConnectionsChanged(int count); - void numBlocksChanged(int count); + void numBlocksChanged(int count, const QDateTime& blockDate); void alertsChanged(const QString &warnings); void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 9f3991c4c52..ccde44fb29a 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -293,8 +293,8 @@ void RPCConsole::setClientModel(ClientModel *model) setNumConnections(model->getNumConnections()); connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(model->getNumBlocks()); - connect(model, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int))); + setNumBlocks(model->getNumBlocks(), model->getLastBlockDate()); + connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime))); updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent()); connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64))); @@ -404,11 +404,10 @@ void RPCConsole::setNumConnections(int count) ui->numberOfConnections->setText(connections); } -void RPCConsole::setNumBlocks(int count) +void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate) { ui->numberOfBlocks->setText(QString::number(count)); - if(clientModel) - ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString()); + ui->lastBlockTime->setText(blockDate.toString()); } void RPCConsole::on_lineEdit_returnPressed() diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index fff5cfbf592..8737be35d1a 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -63,8 +63,8 @@ public slots: void message(int category, const QString &message, bool html = false); /** Set number of connections shown in the UI */ void setNumConnections(int count); - /** Set number of blocks shown in the UI */ - void setNumBlocks(int count); + /** Set number of blocks and last block date shown in the UI */ + void setNumBlocks(int count, const QDateTime& blockDate); /** Go forward or back in history */ void browseHistory(int offset); /** Scroll console view to end */ diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 5aef2d7539b..4f3230a8c9e 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -121,7 +121,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel) this->clientModel = clientModel; if (clientModel) { - connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(updateSmartFeeLabel())); + connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(updateSmartFeeLabel())); } } From 8cbe1f4f5870a165be729cabb9b55dcbf0f85e09 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 9 Mar 2015 15:04:12 +0100 Subject: [PATCH 0303/2337] tests: change main and wallet tests to BOOST_FIXTURE_TEST_SUITE Avoid this travis error: test_bitcoin: chainparams.cpp:330: const CChainParams& Params(): Assertion `pCurrentParams' failed. unknown location(0): fatal error in "subsidy_limit_test": signal: SIGABRT (application abort requested) test/allocator_tests.cpp(116): last checkpoint --- src/test/main_tests.cpp | 4 +++- src/test/wallet_tests.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 2a72a220a48..1927f3deab8 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -5,9 +5,11 @@ #include "primitives/transaction.h" #include "main.h" +#include "test/test_bitcoin.h" + #include -BOOST_AUTO_TEST_SUITE(main_tests) +BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup) BOOST_AUTO_TEST_CASE(subsidy_limit_test) { diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp index 289cc8c9055..25c8fab3354 100644 --- a/src/test/wallet_tests.cpp +++ b/src/test/wallet_tests.cpp @@ -9,6 +9,8 @@ #include #include +#include "test/test_bitcoin.h" + #include #include @@ -23,7 +25,7 @@ using namespace std; typedef set > CoinSet; -BOOST_AUTO_TEST_SUITE(wallet_tests) +BOOST_FIXTURE_TEST_SUITE(wallet_tests, TestingSetup) static CWallet wallet; static vector vCoins; From 59bd89f11636e90b2d684e8f411d8d7a88622458 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 9 Mar 2015 16:04:43 +0100 Subject: [PATCH 0304/2337] test: Remove UNITTEST params UNITTEST parameter are not used by any current tests, and the model (modifyable parameters) is inconvenient when unit-testing. As they are stored in a global structure eevery test would have to (re)set up its own parameters. For consistency it is also better to test with MAIN parameters. --- src/chainparams.cpp | 45 --------------------------------------- src/chainparams.h | 22 ------------------- src/chainparamsbase.cpp | 3 --- src/chainparamsbase.h | 1 - src/test/base58_tests.cpp | 4 ++-- src/test/test_bitcoin.cpp | 2 +- 6 files changed, 3 insertions(+), 74 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 1fd3b016812..c48ccbc08ab 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -281,51 +281,8 @@ public: }; static CRegTestParams regTestParams; -/** - * Unit test - */ -class CUnitTestParams : public CMainParams, public CModifiableParams { -public: - CUnitTestParams() { - strNetworkID = "unittest"; - nDefaultPort = 18445; - vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds. - vSeeds.clear(); //! Unit test mode doesn't have any DNS seeds. - - fRequireRPCPassword = false; - fMiningRequiresPeers = false; - fDefaultCheckMemPool = true; - fAllowMinDifficultyBlocks = false; - fMineBlocksOnDemand = true; - } - - const Checkpoints::CCheckpointData& Checkpoints() const - { - // UnitTest share the same checkpoints as MAIN - return data; - } - - //! Published setters to allow changing values in unit test cases - virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval=anSubsidyHalvingInterval; } - virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority=anEnforceBlockUpgradeMajority; } - virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority=anRejectBlockOutdatedMajority; } - virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority=anToCheckBlockUpgradeMajority; } - virtual void setDefaultCheckMemPool(bool afDefaultCheckMemPool) { fDefaultCheckMemPool=afDefaultCheckMemPool; } - virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; } - virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; } -}; -static CUnitTestParams unitTestParams; - - static CChainParams *pCurrentParams = 0; -CModifiableParams *ModifiableParams() -{ - assert(pCurrentParams); - assert(pCurrentParams==&unitTestParams); - return (CModifiableParams*)&unitTestParams; -} - const CChainParams &Params() { assert(pCurrentParams); return *pCurrentParams; @@ -339,8 +296,6 @@ CChainParams &Params(CBaseChainParams::Network network) { return testNetParams; case CBaseChainParams::REGTEST: return regTestParams; - case CBaseChainParams::UNITTEST: - return unitTestParams; default: assert(false && "Unimplemented network"); return mainParams; diff --git a/src/chainparams.h b/src/chainparams.h index 78b575d8f37..48b1383a675 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -108,25 +108,6 @@ protected: bool fTestnetToBeDeprecatedFieldRPC; }; -/** - * Modifiable parameters interface is used by test cases to adapt the parameters in order - * to test specific features more easily. Test cases should always restore the previous - * values after finalization. - */ - -class CModifiableParams { -public: - //! Published setters to allow changing values in unit test cases - virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) =0; - virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority)=0; - virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority)=0; - virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority)=0; - virtual void setDefaultCheckMemPool(bool aDefaultCheckMemPool)=0; - virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks)=0; - virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck)=0; -}; - - /** * Return the currently selected parameters. This won't change after app startup * outside of the unit tests. @@ -136,9 +117,6 @@ const CChainParams &Params(); /** Return parameters for the given network. */ CChainParams &Params(CBaseChainParams::Network network); -/** Get modifiable network parameters (UNITTEST only) */ -CModifiableParams *ModifiableParams(); - /** Sets the params returned by Params() to those for the given network. */ void SelectParams(CBaseChainParams::Network network); diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index c42fd106bec..7d82d689ec4 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -82,9 +82,6 @@ void SelectBaseParams(CBaseChainParams::Network network) case CBaseChainParams::REGTEST: pCurrentBaseParams = ®TestParams; break; - case CBaseChainParams::UNITTEST: - pCurrentBaseParams = &unitTestParams; - break; default: assert(false && "Unimplemented network"); return; diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index cebe7aa01a9..421a3a06ff4 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -19,7 +19,6 @@ public: MAIN, TESTNET, REGTEST, - UNITTEST, MAX_NETWORK_TYPES }; diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index e7d02818818..c242dd26e2b 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -127,6 +127,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) std::vector result; CBitcoinSecret secret; CBitcoinAddress addr; + SelectParams(CBaseChainParams::MAIN); BOOST_FOREACH(Value& tv, tests) { @@ -176,7 +177,6 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest); } } - SelectParams(CBaseChainParams::UNITTEST); } // Goal: check that generated keys match test vectors @@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) CTxDestination nodest = CNoDestination(); BOOST_CHECK(!dummyAddr.Set(nodest)); - SelectParams(CBaseChainParams::UNITTEST); + SelectParams(CBaseChainParams::MAIN); } // Goal: check that base58 parsing code is robust against a variety of corrupted data diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 5df417b8e5e..a1355ad445a 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -29,7 +29,7 @@ extern void noui_connect(); TestingSetup::TestingSetup() { fPrintToDebugLog = false; // don't want to write to debug.log file - SelectParams(CBaseChainParams::UNITTEST); + SelectParams(CBaseChainParams::MAIN); noui_connect(); #ifdef ENABLE_WALLET bitdb.MakeMock(); From 3aa0130b963087025b64108225bbadea36d8c6df Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 9 Mar 2015 16:09:54 +0100 Subject: [PATCH 0305/2337] test: remove fSkipProofOfWork Not used, and REGTEST already allows creating blocks at the lowerst possible difficulty. --- src/chainparams.cpp | 1 - src/chainparams.h | 3 --- src/main.cpp | 3 +-- src/pow.cpp | 3 --- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c48ccbc08ab..2bc8976510a 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -170,7 +170,6 @@ public: fAllowMinDifficultyBlocks = false; fRequireStandard = true; fMineBlocksOnDemand = false; - fSkipProofOfWorkCheck = false; fTestnetToBeDeprecatedFieldRPC = false; } diff --git a/src/chainparams.h b/src/chainparams.h index 48b1383a675..134dcd65582 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -60,8 +60,6 @@ public: bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; } /** Allow mining of a min-difficulty block */ bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; } - /** Skip proof-of-work check: allow mining of any difficulty block */ - bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; } /** Make standard checks */ bool RequireStandard() const { return fRequireStandard; } int64_t TargetTimespan() const { return nTargetTimespan; } @@ -104,7 +102,6 @@ protected: bool fAllowMinDifficultyBlocks; bool fRequireStandard; bool fMineBlocksOnDemand; - bool fSkipProofOfWorkCheck; bool fTestnetToBeDeprecatedFieldRPC; }; diff --git a/src/main.cpp b/src/main.cpp index 0b36b5f2194..f47155ca904 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2593,8 +2593,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta int nHeight = pindexPrev->nHeight+1; // Check proof of work - if ((!Params().SkipProofOfWorkCheck()) && - (block.nBits != GetNextWorkRequired(pindexPrev, &block))) + if ((block.nBits != GetNextWorkRequired(pindexPrev, &block))) return state.DoS(100, error("%s: incorrect proof of work", __func__), REJECT_INVALID, "bad-diffbits"); diff --git a/src/pow.cpp b/src/pow.cpp index b75b293c908..eb899ffc942 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -87,9 +87,6 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) bool fOverflow; arith_uint256 bnTarget; - if (Params().SkipProofOfWorkCheck()) - return true; - bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range From bb6acff07982dda68b5c2ac81c99dbd7255bb9cc Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 6 Mar 2015 20:26:09 -0500 Subject: [PATCH 0306/2337] fix possible block db breakage during re-index When re-indexing, there are a few cases where garbage data may be skipped in the block files. In these cases, the indices are correctly written to the index db, however the pointer to the next position for writing in the current block file is calculated by adding the sizes of the valid blocks found. As a result, when the re-index is finished, the index db is correct for all existing blocks, but the next block will be written to an incorrect offset, likely overwriting existing blocks. Rather than using the sum of all valid blocks to determine the next write position, use the end of the last block written to the file. Don't assume that the current block is the last one in the file, since they may be read out-of-order. --- src/main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 9927ac75987..183dff6d39b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2455,8 +2455,11 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd } nLastBlockFile = nFile; - vinfoBlockFile[nFile].nSize += nAddSize; vinfoBlockFile[nFile].AddBlock(nHeight, nTime); + if (fKnown) + vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize); + else + vinfoBlockFile[nFile].nSize += nAddSize; if (!fKnown) { unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; From 1fdb9fa3f905df956ed61dbf6ae086c963fd1793 Mon Sep 17 00:00:00 2001 From: Luca Venturini Date: Wed, 4 Feb 2015 00:11:49 -0800 Subject: [PATCH 0307/2337] Help messages correctly formatted (79 chars) Help messages are formatted programmatically with FormatParagraph in order not to break existing strings in Transifex. The new format works even if the translation of the strings modifies the lenght of the message. Sqashed 6 commits in a single one. Help messages correctly formatted for SVGA text mode (132 chars) Help messages are formatted programmatically with FormatParagraph in order not to break existing strings in Transifex. The new format should work even if the translation of the strings modifies the lenght of the message. Fix - syntax error Correct formatting for 79 chars Correctly based on C++ functions Removed spare spaces from option strings Fix - syntax error --- src/bitcoin-cli.cpp | 28 +++--- src/bitcoin-tx.cpp | 50 +++++----- src/init.cpp | 232 ++++++++++++++++++++++---------------------- src/util.cpp | 15 +++ src/util.h | 17 ++++ 5 files changed, 187 insertions(+), 155 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index f273a15713f..2fa8de6fd83 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -20,21 +20,21 @@ using namespace json_spirit; std::string HelpMessageCli() { string strUsage; - strUsage += _("Options:") + "\n"; - strUsage += " -? " + _("This help message") + "\n"; - strUsage += " -conf= " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n"; - strUsage += " -datadir=
" + _("Specify data directory") + "\n"; - strUsage += " -testnet " + _("Use the test network") + "\n"; - strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be " - "solved instantly. This is intended for regression testing tools and app development.") + "\n"; - strUsage += " -rpcconnect= " + strprintf(_("Send commands to node running on (default: %s)"), "127.0.0.1") + "\n"; - strUsage += " -rpcport= " + strprintf(_("Connect to JSON-RPC on (default: %u or testnet: %u)"), 8332, 18332) + "\n"; - strUsage += " -rpcwait " + _("Wait for RPC server to start") + "\n"; - strUsage += " -rpcuser= " + _("Username for JSON-RPC connections") + "\n"; - strUsage += " -rpcpassword= " + _("Password for JSON-RPC connections") + "\n"; + strUsage += HelpMessageGroup(_("Options:")); + strUsage += HelpMessageOpt("-?", _("This help message")); + strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf")); + strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); + strUsage += HelpMessageOpt("-testnet", _("Use the test network")); + strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be " + "solved instantly. This is intended for regression testing tools and app development.")); + strUsage += HelpMessageOpt("-rpcconnect=", strprintf(_("Send commands to node running on (default: %s)"), "127.0.0.1")); + strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Connect to JSON-RPC on (default: %u or testnet: %u)"), 8332, 18332)); + strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); + strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); - strUsage += "\n" + _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n"; - strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n"; + strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)")); + strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections")); return strUsage; } diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index c1622cf5d3e..78f5c2c4b6b 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -54,38 +54,34 @@ static bool AppInitRawTx(int argc, char* argv[]) fprintf(stdout, "%s", strUsage.c_str()); - strUsage = _("Options:") + "\n"; - strUsage += " -? " + _("This help message") + "\n"; - strUsage += " -create " + _("Create new, empty TX.") + "\n"; - strUsage += " -json " + _("Select JSON output") + "\n"; - strUsage += " -txid " + _("Output only the hex-encoded transaction id of the resultant transaction.") + "\n"; - strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n"; - strUsage += " -testnet " + _("Use the test network") + "\n"; - strUsage += "\n"; + strUsage = HelpMessageGroup(_("Options:")); + strUsage += HelpMessageOpt("-?", _("This help message")); + strUsage += HelpMessageOpt("-create", _("Create new, empty TX.")); + strUsage += HelpMessageOpt("-json", _("Select JSON output")); + strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction.")); + strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.")); + strUsage += HelpMessageOpt("-testnet", _("Use the test network")); fprintf(stdout, "%s", strUsage.c_str()); - - strUsage = _("Commands:") + "\n"; - strUsage += " delin=N " + _("Delete input N from TX") + "\n"; - strUsage += " delout=N " + _("Delete output N from TX") + "\n"; - strUsage += " in=TXID:VOUT " + _("Add input to TX") + "\n"; - strUsage += " locktime=N " + _("Set TX lock time to N") + "\n"; - strUsage += " nversion=N " + _("Set TX version to N") + "\n"; - strUsage += " outaddr=VALUE:ADDRESS " + _("Add address-based output to TX") + "\n"; - strUsage += " outscript=VALUE:SCRIPT " + _("Add raw script output to TX") + "\n"; - strUsage += " sign=SIGHASH-FLAGS " + _("Add zero or more signatures to transaction") + "\n"; - strUsage += " This command requires JSON registers:\n"; - strUsage += " prevtxs=JSON object\n"; - strUsage += " privatekeys=JSON object\n"; - strUsage += " See signrawtransaction docs for format of sighash flags, JSON objects.\n"; - strUsage += "\n"; + strUsage = HelpMessageGroup(_("Commands:")); + strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX")); + strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX")); + strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX")); + strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N")); + strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N")); + strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX")); + strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX")); + strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " + + _("This command requires JSON registers:") + + _("prevtxs=JSON object") + ", " + + _("privatekeys=JSON object") + ". " + + _("See signrawtransaction docs for format of sighash flags, JSON objects.")); fprintf(stdout, "%s", strUsage.c_str()); - strUsage = _("Register Commands:") + "\n"; - strUsage += " load=NAME:FILENAME " + _("Load JSON file FILENAME into register NAME") + "\n"; - strUsage += " set=NAME:JSON-STRING " + _("Set register NAME to given JSON-STRING") + "\n"; - strUsage += "\n"; + strUsage = HelpMessageGroup(_("Register Commands:")); + strUsage += HelpMessageOpt("load=NAME:FILENAME", _("Load JSON file FILENAME into register NAME")); + strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING")); fprintf(stdout, "%s", strUsage.c_str()); return false; diff --git a/src/init.cpp b/src/init.cpp index c8f32d8bfd1..eea02dc242f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -256,157 +256,161 @@ void OnRPCPreCommand(const CRPCCommand& cmd) std::string HelpMessage(HelpMessageMode mode) { + // When adding new options to the categories, please keep and ensure alphabetical ordering. - string strUsage = _("Options:") + "\n"; - strUsage += " -? " + _("This help message") + "\n"; - strUsage += " -alertnotify= " + _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)") + "\n"; - strUsage += " -blocknotify= " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n"; - strUsage += " -checkblocks= " + strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288) + "\n"; - strUsage += " -checklevel= " + strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3) + "\n"; - strUsage += " -conf= " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n"; + string strUsage = HelpMessageGroup(_("Options:")); + strUsage += HelpMessageOpt("-?", _("This help message")); + strUsage += HelpMessageOpt("-alertnotify=", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)")); + strUsage += HelpMessageOpt("-blocknotify=", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); + strUsage += HelpMessageOpt("-checkblocks=", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288)); + strUsage += HelpMessageOpt("-checklevel=", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3)); + strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf")); if (mode == HMM_BITCOIND) { #if !defined(WIN32) - strUsage += " -daemon " + _("Run in the background as a daemon and accept commands") + "\n"; + strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands")); #endif } - strUsage += " -datadir= " + _("Specify data directory") + "\n"; - strUsage += " -dbcache= " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n"; - strUsage += " -loadblock= " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n"; - strUsage += " -maxorphantx= " + strprintf(_("Keep at most unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n"; - strUsage += " -par= " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n"; + strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); + strUsage += HelpMessageOpt("-dbcache=", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); + strUsage += HelpMessageOpt("-loadblock=", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); + strUsage += HelpMessageOpt("-maxorphantx=", strprintf(_("Keep at most unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); + strUsage += HelpMessageOpt("-par=", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), + -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); #ifndef WIN32 - strUsage += " -pid= " + strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid") + "\n"; + strUsage += HelpMessageOpt("-pid=", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid")); #endif - strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n"; + strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup")); #if !defined(WIN32) - strUsage += " -sysperms " + _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)") + "\n"; + strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); #endif - strUsage += " -txindex " + strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0) + "\n"; + strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0)); - strUsage += "\n" + _("Connection options:") + "\n"; - strUsage += " -addnode= " + _("Add a node to connect to and attempt to keep the connection open") + "\n"; - strUsage += " -banscore= " + strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100) + "\n"; - strUsage += " -bantime= " + strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400) + "\n"; - strUsage += " -bind= " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n"; - strUsage += " -connect= " + _("Connect only to the specified node(s)") + "\n"; - strUsage += " -discover " + _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)") + "\n"; - strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n"; - strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n"; - strUsage += " -externalip= " + _("Specify your own public address") + "\n"; - strUsage += " -forcednsseed " + strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0) + "\n"; - strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n"; - strUsage += " -maxconnections= " + strprintf(_("Maintain at most connections to peers (default: %u)"), 125) + "\n"; - strUsage += " -maxreceivebuffer= " + strprintf(_("Maximum per-connection receive buffer, *1000 bytes (default: %u)"), 5000) + "\n"; - strUsage += " -maxsendbuffer= " + strprintf(_("Maximum per-connection send buffer, *1000 bytes (default: %u)"), 1000) + "\n"; - strUsage += " -onion= " + strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy") + "\n"; - strUsage += " -onlynet= " + _("Only connect to nodes in network (ipv4, ipv6 or onion)") + "\n"; - strUsage += " -permitbaremultisig " + strprintf(_("Relay non-P2SH multisig (default: %u)"), 1) + "\n"; - strUsage += " -port= " + strprintf(_("Listen for connections on (default: %u or testnet: %u)"), 8333, 18333) + "\n"; - strUsage += " -proxy= " + _("Connect through SOCKS5 proxy") + "\n"; - strUsage += " -seednode= " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n"; - strUsage += " -timeout= " + strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT) + "\n"; + strUsage += HelpMessageGroup(_("Connection options:")); + strUsage += HelpMessageOpt("-addnode=", _("Add a node to connect to and attempt to keep the connection open")); + strUsage += HelpMessageOpt("-banscore=", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100)); + strUsage += HelpMessageOpt("-bantime=", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400)); + strUsage += HelpMessageOpt("-bind=", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6")); + strUsage += HelpMessageOpt("-connect=", _("Connect only to the specified node(s)")); + strUsage += HelpMessageOpt("-discover", _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)")); + strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)")); + strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)")); + strUsage += HelpMessageOpt("-externalip=", _("Specify your own public address")); + strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0)); + strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)")); + strUsage += HelpMessageOpt("-maxconnections=", strprintf(_("Maintain at most connections to peers (default: %u)"), 125)); + strUsage += HelpMessageOpt("-maxreceivebuffer=", strprintf(_("Maximum per-connection receive buffer, *1000 bytes (default: %u)"), 5000)); + strUsage += HelpMessageOpt("-maxsendbuffer=", strprintf(_("Maximum per-connection send buffer, *1000 bytes (default: %u)"), 1000)); + strUsage += HelpMessageOpt("-onion=", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); + strUsage += HelpMessageOpt("-onlynet=", _("Only connect to nodes in network (ipv4, ipv6 or onion)")); + strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1)); + strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), 8333, 18333)); + strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); + strUsage += HelpMessageOpt("-seednode=", _("Connect to a node to retrieve peer addresses, and disconnect")); + strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); #ifdef USE_UPNP #if USE_UPNP - strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n"; + strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)")); #else - strUsage += " -upnp " + strprintf(_("Use UPnP to map the listening port (default: %u)"), 0) + "\n"; + strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0)); #endif #endif - strUsage += " -whitebind= " + _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6") + "\n"; - strUsage += " -whitelist= " + _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + "\n"; - strUsage += " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway") + "\n"; + strUsage += HelpMessageOpt("-whitebind=", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); + strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); + #ifdef ENABLE_WALLET - strUsage += "\n" + _("Wallet options:") + "\n"; - strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n"; - strUsage += " -keypool= " + strprintf(_("Set key pool size to (default: %u)"), 100) + "\n"; + strUsage += HelpMessageGroup(_("Wallet options:")); + strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); + strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), 100)); if (GetBoolArg("-help-debug", false)) - strUsage += " -mintxfee= " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), FormatMoney(CWallet::minTxFee.GetFeePerK())) + "\n"; - strUsage += " -paytxfee= " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n"; - strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n"; - strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n"; - strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n"; - strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n"; - strUsage += " -txconfirmtarget= " + strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1) + "\n"; - strUsage += " -maxtxfee= " + strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee)) + "\n"; - strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n"; - strUsage += " -wallet= " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n"; - strUsage += " -walletnotify= " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n"; - strUsage += " -zapwallettxes= " + _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + "\n"; - strUsage += " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n"; + strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), + FormatMoney(CWallet::minTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); + strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); + strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); + strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); + strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1)); + strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), + FormatMoney(maxTxFee))); + strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); + strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); + strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); + strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + + " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); + #endif - strUsage += "\n" + _("Debugging/Testing options:") + "\n"; + strUsage += HelpMessageGroup(_("Debugging/Testing options:")); if (GetBoolArg("-help-debug", false)) { - strUsage += " -checkpoints " + strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1) + "\n"; - strUsage += " -dblogsize= " + strprintf(_("Flush database activity from memory pool to disk log every megabytes (default: %u)"), 100) + "\n"; - strUsage += " -disablesafemode " + strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0) + "\n"; - strUsage += " -testsafemode " + strprintf(_("Force safe mode (default: %u)"), 0) + "\n"; - strUsage += " -dropmessagestest= " + _("Randomly drop 1 of every network messages") + "\n"; - strUsage += " -fuzzmessagestest= " + _("Randomly fuzz 1 of every network messages") + "\n"; - strUsage += " -flushwallet " + strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1) + "\n"; - strUsage += " -stopafterblockimport " + strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0) + "\n"; + strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1)); + strUsage += HelpMessageOpt("-dblogsize=", strprintf(_("Flush database activity from memory pool to disk log every megabytes (default: %u)"), 100)); + strUsage += HelpMessageOpt("-disablesafemode", strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0)); + strUsage += HelpMessageOpt("-testsafemode", strprintf(_("Force safe mode (default: %u)"), 0)); + strUsage += HelpMessageOpt("-dropmessagestest=", _("Randomly drop 1 of every network messages")); + strUsage += HelpMessageOpt("-fuzzmessagestest=", _("Randomly fuzz 1 of every network messages")); + strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1)); + strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0)); } - strUsage += " -debug= " + strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + "\n"; - strUsage += " " + _("If is not supplied, output all debugging information.") + "\n"; - strUsage += " " + _(" can be:"); - strUsage += " addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) - strUsage += ", qt"; - strUsage += ".\n"; + debugCategories += ", qt"; + strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + + _("If is not supplied, output all debugging information.") + _(" can be:") + " " + debugCategories + "."); #ifdef ENABLE_WALLET - strUsage += " -gen " + strprintf(_("Generate coins (default: %u)"), 0) + "\n"; - strUsage += " -genproclimit= " + strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1) + "\n"; + strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0)); + strUsage += HelpMessageOpt("-genproclimit=", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1)); #endif - strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n"; - strUsage += " -logips " + strprintf(_("Include IP addresses in debug output (default: %u)"), 0) + "\n"; - strUsage += " -logtimestamps " + strprintf(_("Prepend debug output with timestamp (default: %u)"), 1) + "\n"; + strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)")); + strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0)); + strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1)); if (GetBoolArg("-help-debug", false)) { - strUsage += " -limitfreerelay= " + strprintf(_("Continuously rate-limit free transactions to *1000 bytes per minute (default:%u)"), 15) + "\n"; - strUsage += " -relaypriority " + strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1) + "\n"; - strUsage += " -maxsigcachesize= " + strprintf(_("Limit size of signature cache to entries (default: %u)"), 50000) + "\n"; + strUsage += HelpMessageOpt("-limitfreerelay=", strprintf(_("Continuously rate-limit free transactions to *1000 bytes per minute (default:%u)"), 15)); + strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1)); + strUsage += HelpMessageOpt("-maxsigcachesize=", strprintf(_("Limit size of signature cache to entries (default: %u)"), 50000)); } - strUsage += " -minrelaytxfee= " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n"; - strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n"; + strUsage += HelpMessageOpt("-minrelaytxfee=", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file")); if (GetBoolArg("-help-debug", false)) { - strUsage += " -printpriority " + strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0) + "\n"; - strUsage += " -privdb " + strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1) + "\n"; - strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n"; - strUsage += " " + _("This is intended for regression testing tools and app development.") + "\n"; - strUsage += " " + _("In this mode -genproclimit controls how many blocks are generated immediately.") + "\n"; + strUsage += HelpMessageOpt("-printpriority", strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0)); + strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1)); + strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + " " + + _("This is intended for regression testing tools and app development.") + " " + + _("In this mode -genproclimit controls how many blocks are generated immediately.")); } - strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n"; - strUsage += " -testnet " + _("Use the test network") + "\n"; + strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)")); + strUsage += HelpMessageOpt("-testnet", _("Use the test network")); - strUsage += "\n" + _("Node relay options:") + "\n"; - strUsage += " -datacarrier " + strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1) + "\n"; - strUsage += " -datacarriersize " + strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY) + "\n"; + strUsage += HelpMessageGroup(_("Node relay options:")); + strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1)); + strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); - strUsage += "\n" + _("Block creation options:") + "\n"; - strUsage += " -blockminsize= " + strprintf(_("Set minimum block size in bytes (default: %u)"), 0) + "\n"; - strUsage += " -blockmaxsize= " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n"; - strUsage += " -blockprioritysize= " + strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE) + "\n"; + strUsage += HelpMessageGroup(_("Block creation options:")); + strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), 0)); + strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); + strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); - strUsage += "\n" + _("RPC server options:") + "\n"; - strUsage += " -server " + _("Accept command line and JSON-RPC commands") + "\n"; - strUsage += " -rest " + strprintf(_("Accept public REST requests (default: %u)"), 0) + "\n"; - strUsage += " -rpcbind= " + _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)") + "\n"; - strUsage += " -rpcuser= " + _("Username for JSON-RPC connections") + "\n"; - strUsage += " -rpcpassword= " + _("Password for JSON-RPC connections") + "\n"; - strUsage += " -rpcport= " + strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 8332, 18332) + "\n"; - strUsage += " -rpcallowip= " + _("Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times") + "\n"; - strUsage += " -rpcthreads= " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n"; - strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1) + "\n"; + strUsage += HelpMessageGroup(_("RPC server options:")); + strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands")); + strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0)); + strUsage += HelpMessageOpt("-rpcbind=", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)")); + strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 8332, 18332)); + strUsage += HelpMessageOpt("-rpcallowip=", _("Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times")); + strUsage += HelpMessageOpt("-rpcthreads=", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4)); + strUsage += HelpMessageOpt("-rpckeepalive", strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1)); - strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n"; - strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n"; - strUsage += " -rpcsslcertificatechainfile= " + strprintf(_("Server certificate file (default: %s)"), "server.cert") + "\n"; - strUsage += " -rpcsslprivatekeyfile= " + strprintf(_("Server private key (default: %s)"), "server.pem") + "\n"; - strUsage += " -rpcsslciphers= " + strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH") + "\n"; + strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)")); + strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=", strprintf(_("Server certificate file (default: %s)"), "server.cert")); + strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=", strprintf(_("Server private key (default: %s)"), "server.pem")); + strUsage += HelpMessageOpt("-rpcsslciphers=", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH")); return strUsage; } diff --git a/src/util.cpp b/src/util.cpp index 361b3631f56..792f00b61d3 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -346,6 +346,21 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue) return SoftSetArg(strArg, std::string("0")); } +static const int screenWidth = 79; +static const int optIndent = 2; +static const int msgIndent = 7; + +std::string HelpMessageGroup(const std::string &message) { + return std::string(message) + std::string("\n\n"); +} + +std::string HelpMessageOpt(const std::string &option, const std::string &message) { + return std::string(optIndent,' ') + std::string(option) + + std::string("\n") + std::string(msgIndent,' ') + + FormatParagraph(message, screenWidth - msgIndent, msgIndent) + + std::string("\n\n"); +} + static std::string FormatException(const std::exception* pex, const char* pszThread) { #ifdef WIN32 diff --git a/src/util.h b/src/util.h index 4d0cb7136e9..9b5a4153dd9 100644 --- a/src/util.h +++ b/src/util.h @@ -162,6 +162,23 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue); */ bool SoftSetBoolArg(const std::string& strArg, bool fValue); +/** + * Format a string to be used as group of options in help messages + * + * @param message Group name (e.g. "RPC server options:") + * @return the formatted string + */ +std::string HelpMessageGroup(const std::string& message); + +/** + * Format a string to be used as option description in help messages + * + * @param option Option message (e.g. "-rpcuser=") + * @param message Option description (e.g. "Username for JSON-RPC connections") + * @return the formatted string + */ +std::string HelpMessageOpt(const std::string& option, const std::string& message); + void SetThreadPriority(int nPriority); void RenameThread(const char* name); From f75470794bd344ec25e1a540637c675e7f2ad6b0 Mon Sep 17 00:00:00 2001 From: Luca Venturini Date: Mon, 9 Mar 2015 00:29:59 -0700 Subject: [PATCH 0308/2337] Fix - bitcoin-qt usage message . Closes the bug from commit e179eb3d9bfec7e67908242c71c87b716a41c97c ("bitcoin-qt -help" did not show any message) . Move all the options in init.cpp (there were already some options related to bitcoin-qt) --- src/init.cpp | 13 +++++++ src/qt/utilitydialog.cpp | 78 +++++++++++++--------------------------- 2 files changed, 37 insertions(+), 54 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index eea02dc242f..1e3cc1d899e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -412,6 +412,19 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=", strprintf(_("Server private key (default: %s)"), "server.pem")); strUsage += HelpMessageOpt("-rpcsslciphers=", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH")); + if (mode == HMM_BITCOIN_QT) + { + strUsage += HelpMessageGroup(_("UI Options:")); + if (GetBoolArg("-help-debug", false)) { + strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", _("Allow self signed root certificates (default: 0)")); + } + strUsage += HelpMessageOpt("-choosedatadir", _("Choose data directory on startup (default: 0)")); + strUsage += HelpMessageOpt("-lang=", _("Set language, for example \"de_DE\" (default: system locale)")); + strUsage += HelpMessageOpt("-min", _("Start minimized")); + strUsage += HelpMessageOpt("-rootcertificates=", _("Set SSL root certificates for payment request (default: -system-)")); + strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)")); + } + return strUsage; } diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 4e7b70efe6b..386cf31d736 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -62,13 +62,17 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : ui->helpMessage->setVisible(false); } else { setWindowTitle(tr("Command-line options")); + QString header = tr("Usage:") + "\n" + + " bitcoin-qt [" + tr("command-line options") + "] " + "\n"; QTextCursor cursor(ui->helpMessage->document()); cursor.insertText(version); cursor.insertBlock(); - cursor.insertText(tr("Usage:") + '\n' + - " bitcoin-qt [" + tr("command-line options") + "]\n"); - + cursor.insertText(header); cursor.insertBlock(); + + QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT)); + text = version + "\n" + header + "\n" + coreOptions; + QTextTableFormat tf; tf.setBorderStyle(QTextFrameFormat::BorderStyle_None); tf.setCellPadding(2); @@ -76,64 +80,30 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : widths << QTextLength(QTextLength::PercentageLength, 35); widths << QTextLength(QTextLength::PercentageLength, 65); tf.setColumnWidthConstraints(widths); - QTextTable *table = cursor.insertTable(2, 2, tf); - QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT)); - bool first = true; QTextCharFormat bold; bold.setFontWeight(QFont::Bold); - // note that coreOptions is not translated. - foreach (const QString &line, coreOptions.split('\n')) { - if (!first) { - table->appendRows(1); + + foreach (const QString &line, coreOptions.split("\n")) { + if (line.startsWith(" -")) + { + cursor.currentTable()->appendRows(1); + cursor.movePosition(QTextCursor::PreviousCell); cursor.movePosition(QTextCursor::NextRow); + cursor.insertText(line.trimmed()); + cursor.movePosition(QTextCursor::NextCell); + } else if (line.startsWith(" ")) { + cursor.insertText(line.trimmed()+' '); + } else if (line.size() > 0) { + //Title of a group + if (cursor.currentTable()) + cursor.currentTable()->appendRows(1); + cursor.movePosition(QTextCursor::Down); + cursor.insertText(line.trimmed(), bold); + cursor.insertTable(1, 2, tf); } - first = false; - - if (line.startsWith(" ")) { - int index = line.indexOf(' ', 3); - if (index > 0) { - cursor.insertText(line.left(index).trimmed()); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText(line.mid(index).trimmed()); - continue; - } - } - cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor); - table->mergeCells(cursor); - cursor.insertText(line.trimmed(), bold); } - table->appendRows(6); - cursor.movePosition(QTextCursor::NextRow); - cursor.insertText(tr("UI options") + ":", bold); - cursor.movePosition(QTextCursor::NextRow); - if (GetBoolArg("-help-debug", false)) { - cursor.insertText("-allowselfsignedrootcertificates"); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText(tr("Allow self signed root certificates (default: 0)")); - cursor.movePosition(QTextCursor::NextCell); - } - cursor.insertText("-choosedatadir"); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText(tr("Choose data directory on startup (default: 0)")); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText("-lang="); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText(tr("Set language, for example \"de_DE\" (default: system locale)")); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText("-min"); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText(tr("Start minimized")); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText("-rootcertificates="); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText(tr("Set SSL root certificates for payment request (default: -system-)")); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText("-splash"); - cursor.movePosition(QTextCursor::NextCell); - cursor.insertText(tr("Show splash screen on startup (default: 1)")); - ui->helpMessage->moveCursor(QTextCursor::Start); ui->scrollArea->setVisible(false); ui->aboutLogo->setVisible(false); From 317e66c741aef0fd272e50aa2e82ff192ca5f7e5 Mon Sep 17 00:00:00 2001 From: dexX7 Date: Wed, 11 Mar 2015 13:34:20 +0100 Subject: [PATCH 0309/2337] Initialization: set Boost path locale in main thread The path locale is lazy initialized and to avoid deinitialization errors in multithreading environments, it is set explicitly by the main thread. --- src/util.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 792f00b61d3..4192e44ae1b 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -723,18 +723,18 @@ void RenameThread(const char* name) void SetupEnvironment() { -#ifndef WIN32 - try - { -#if BOOST_FILESYSTEM_VERSION == 3 - boost::filesystem::path::codecvt(); // Raises runtime error if current locale is invalid -#else // boost filesystem v2 - std::locale(); // Raises runtime error if current locale is invalid -#endif + // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale + // may be invalid, in which case the "C" locale is used as fallback. +#if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) + try { + std::locale(""); // Raises a runtime error if current locale is invalid } catch (const std::runtime_error&) { - setenv("LC_ALL", "C", 1); // Force C locale + std::locale::global(std::locale("C")); } #endif + // The path locale is lazy initialized and to avoid deinitialization errors + // in multithreading environments, it is set explicitly by the main thread. + boost::filesystem::path::imbue(std::locale()); } void SetThreadPriority(int nPriority) From 89e70e931d3d320d2dae4c296601aab113b2e508 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 12 Mar 2015 00:08:22 +0100 Subject: [PATCH 0310/2337] [QT] fix OSX dock icon window reopening fixes #5878 --- src/qt/macdockiconhandler.mm | 57 ++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index e7b58b9cc07..564fd0353e9 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -11,52 +11,46 @@ #undef slots #include +#include +#include #if QT_VERSION < 0x050000 extern void qt_mac_set_dock_menu(QMenu *); #endif -@interface DockIconClickEventHandler : NSObject -{ - MacDockIconHandler* dockIconHandler; +static MacDockIconHandler *s_instance = NULL; + +bool dockClickHandler(id self,SEL _cmd,...) { + Q_UNUSED(self) + Q_UNUSED(_cmd) + + s_instance->handleDockIconClickEvent(); + + // Return NO (false) to suppress the default OS X actions + return false; } -@end - -@implementation DockIconClickEventHandler - -- (id)initWithDockIconHandler:(MacDockIconHandler *)aDockIconHandler -{ - self = [super init]; - if (self) { - dockIconHandler = aDockIconHandler; - - [[NSAppleEventManager sharedAppleEventManager] - setEventHandler:self - andSelector:@selector(handleDockClickEvent:withReplyEvent:) - forEventClass:kCoreEventClass - andEventID:kAEReopenApplication]; - } - return self; -} - -- (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent -{ - Q_UNUSED(event) - Q_UNUSED(replyEvent) - - if (dockIconHandler) { - dockIconHandler->handleDockIconClickEvent(); +void setupDockClickHandler() { + Class cls = objc_getClass("NSApplication"); + id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication")); + + if (appInst != NULL) { + id delegate = objc_msgSend(appInst, sel_registerName("delegate")); + Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class")); + SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); + if (class_getInstanceMethod(delClass, shouldHandle)) + class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"); + else + class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:"); } } -@end MacDockIconHandler::MacDockIconHandler() : QObject() { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this]; + setupDockClickHandler(); this->m_dummyWidget = new QWidget(); this->m_dockMenu = new QMenu(this->m_dummyWidget); this->setMainWindow(NULL); @@ -119,7 +113,6 @@ void MacDockIconHandler::setIcon(const QIcon &icon) MacDockIconHandler *MacDockIconHandler::instance() { - static MacDockIconHandler *s_instance = NULL; if (!s_instance) s_instance = new MacDockIconHandler(); return s_instance; From 92fd887fd42a61e95f716d3193104827f60f856c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 12 Mar 2015 09:34:42 +0100 Subject: [PATCH 0311/2337] tests: add a BasicTestingSetup and apply to all tests Make sure that chainparams and logging is properly initialized. Doing this for every test may be overkill, but this initialization is so simple that that does not matter. This should fix the travis issues. --- src/test/Checkpoints_tests.cpp | 3 ++- src/test/allocator_tests.cpp | 3 ++- src/test/arith_uint256_tests.cpp | 3 ++- src/test/base32_tests.cpp | 3 ++- src/test/base58_tests.cpp | 3 ++- src/test/base64_tests.cpp | 3 ++- src/test/bip32_tests.cpp | 3 ++- src/test/bloom_tests.cpp | 3 ++- src/test/checkblock_tests.cpp | 3 ++- src/test/coins_tests.cpp | 3 ++- src/test/compress_tests.cpp | 3 ++- src/test/crypto_tests.cpp | 3 ++- src/test/getarg_tests.cpp | 3 ++- src/test/hash_tests.cpp | 3 ++- src/test/key_tests.cpp | 3 ++- src/test/mruset_tests.cpp | 3 ++- src/test/multisig_tests.cpp | 3 ++- src/test/netbase_tests.cpp | 3 ++- src/test/pmt_tests.cpp | 3 ++- src/test/pow_tests.cpp | 3 ++- src/test/sanity_tests.cpp | 4 +++- src/test/script_P2SH_tests.cpp | 3 ++- src/test/script_tests.cpp | 3 ++- src/test/scriptnum_tests.cpp | 5 ++++- src/test/serialize_tests.cpp | 3 ++- src/test/sighash_tests.cpp | 3 ++- src/test/sigopcount_tests.cpp | 3 ++- src/test/skiplist_tests.cpp | 3 ++- src/test/test_bitcoin.cpp | 10 ++++++++-- src/test/test_bitcoin.h | 14 +++++++++++++- src/test/timedata_tests.cpp | 3 ++- src/test/transaction_tests.cpp | 3 ++- src/test/uint256_tests.cpp | 3 ++- src/test/univalue_tests.cpp | 3 ++- src/test/util_tests.cpp | 3 ++- 35 files changed, 90 insertions(+), 36 deletions(-) diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index a9b6cd44a87..c3125d76dc5 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -9,12 +9,13 @@ #include "checkpoints.h" #include "uint256.h" +#include "test/test_bitcoin.h" #include using namespace std; -BOOST_AUTO_TEST_SUITE(Checkpoints_tests) +BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(sanity) { diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 991b4ac0999..d4df7b54157 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -5,10 +5,11 @@ #include "util.h" #include "allocators.h" +#include "test/test_bitcoin.h" #include -BOOST_AUTO_TEST_SUITE(allocator_tests) +BOOST_FIXTURE_TEST_SUITE(allocator_tests, BasicTestingSetup) // Dummy memory page locker for platform independent tests static const void *last_lock_addr, *last_unlock_addr; diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 565b02ae642..17d6bed6d2f 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -12,8 +12,9 @@ #include "arith_uint256.h" #include #include "version.h" +#include "test/test_bitcoin.h" -BOOST_AUTO_TEST_SUITE(arith_uint256_tests) +BOOST_FIXTURE_TEST_SUITE(arith_uint256_tests, BasicTestingSetup) /// Convert vector to arith_uint256, via uint256 blob inline arith_uint256 arith_uint256V(const std::vector& vch) diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index 5d20a90ad0c..8ec88614259 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -3,10 +3,11 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "utilstrencodings.h" +#include "test/test_bitcoin.h" #include -BOOST_AUTO_TEST_SUITE(base32_tests) +BOOST_FIXTURE_TEST_SUITE(base32_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(base32_testvectors) { diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index c242dd26e2b..f07dd7a7db9 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -13,6 +13,7 @@ #include "uint256.h" #include "util.h" #include "utilstrencodings.h" +#include "test/test_bitcoin.h" #include #include @@ -23,7 +24,7 @@ using namespace json_spirit; extern Array read_json(const std::string& jsondata); -BOOST_AUTO_TEST_SUITE(base58_tests) +BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) // Goal: test low-level base58 encoding functionality BOOST_AUTO_TEST_CASE(base58_EncodeBase58) diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index 9e6cb342ccd..54c081b0ef9 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -3,10 +3,11 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "utilstrencodings.h" +#include "test/test_bitcoin.h" #include -BOOST_AUTO_TEST_SUITE(base64_tests) +BOOST_FIXTURE_TEST_SUITE(base64_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(base64_testvectors) { diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 3d28e06ffc7..d738851c1f8 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -8,6 +8,7 @@ #include "key.h" #include "uint256.h" #include "util.h" +#include "test/test_bitcoin.h" #include #include @@ -107,7 +108,7 @@ void RunTest(const TestVector &test) { } } -BOOST_AUTO_TEST_SUITE(bip32_tests) +BOOST_FIXTURE_TEST_SUITE(bip32_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(bip32_test1) { RunTest(test1); diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 64d9909b987..73a146f05c4 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -13,6 +13,7 @@ #include "uint256.h" #include "util.h" #include "utilstrencodings.h" +#include "test/test_bitcoin.h" #include @@ -21,7 +22,7 @@ using namespace std; -BOOST_AUTO_TEST_SUITE(bloom_tests) +BOOST_FIXTURE_TEST_SUITE(bloom_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize) { diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index a4121caa8b2..7abfad151ef 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -11,6 +11,7 @@ #include "clientversion.h" #include "main.h" #include "utiltime.h" +#include "test/test_bitcoin.h" #include @@ -19,7 +20,7 @@ #include -BOOST_AUTO_TEST_SUITE(CheckBlock_tests) +BOOST_FIXTURE_TEST_SUITE(CheckBlock_tests, BasicTestingSetup) bool read_block(const std::string& filename, CBlock& block) { diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 3ecd301bc74..2e2cc2214b9 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -5,6 +5,7 @@ #include "coins.h" #include "random.h" #include "uint256.h" +#include "test/test_bitcoin.h" #include #include @@ -60,7 +61,7 @@ public: }; } -BOOST_AUTO_TEST_SUITE(coins_tests) +BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup) static const unsigned int NUM_SIMULATION_ITERATIONS = 40000; diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index b4e4f2046f5..376ae936810 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -4,6 +4,7 @@ #include "compressor.h" #include "util.h" +#include "test/test_bitcoin.h" #include @@ -21,7 +22,7 @@ // amounts 50 .. 21000000 #define NUM_MULTIPLES_50BTC 420000 -BOOST_AUTO_TEST_SUITE(compress_tests) +BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup) bool static TestEncode(uint64_t in) { return in == CTxOutCompressor::DecompressAmount(CTxOutCompressor::CompressAmount(in)); diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index d5e595cd8ad..aeb2a5caa32 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -10,13 +10,14 @@ #include "crypto/hmac_sha512.h" #include "random.h" #include "utilstrencodings.h" +#include "test/test_bitcoin.h" #include #include #include -BOOST_AUTO_TEST_SUITE(crypto_tests) +BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup) template void TestVector(const Hasher &h, const In &in, const Out &out) { diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index 5fb0f4ccdd8..a0c5592a959 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "util.h" +#include "test/test_bitcoin.h" #include #include @@ -11,7 +12,7 @@ #include #include -BOOST_AUTO_TEST_SUITE(getarg_tests) +BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup) static void ResetArgs(const std::string& strArg) { diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index f1ad25e6ee9..e5d2e5a439e 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -4,6 +4,7 @@ #include "hash.h" #include "utilstrencodings.h" +#include "test/test_bitcoin.h" #include @@ -11,7 +12,7 @@ using namespace std; -BOOST_AUTO_TEST_SUITE(hash_tests) +BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(murmurhash3) { diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 1333aba4716..13ca9494690 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -9,6 +9,7 @@ #include "uint256.h" #include "util.h" #include "utilstrencodings.h" +#include "test/test_bitcoin.h" #include #include @@ -58,7 +59,7 @@ void dumpKeyInfo(uint256 privkey) #endif -BOOST_AUTO_TEST_SUITE(key_tests) +BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(key_test1) { diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp index 813ec9b8b20..bd4e9c1d381 100644 --- a/src/test/mruset_tests.cpp +++ b/src/test/mruset_tests.cpp @@ -6,6 +6,7 @@ #include "random.h" #include "util.h" +#include "test/test_bitcoin.h" #include @@ -34,7 +35,7 @@ public: } }; -BOOST_AUTO_TEST_SUITE(mruset_tests) +BOOST_FIXTURE_TEST_SUITE(mruset_tests, BasicTestingSetup) // Test that an mruset behaves like a set, as long as no more than MAX_SIZE elements are in it BOOST_AUTO_TEST_CASE(mruset_like_set) diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 2168a5fef1f..054bc3b37bf 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -10,6 +10,7 @@ #include "script/interpreter.h" #include "script/sign.h" #include "uint256.h" +#include "test/test_bitcoin.h" #ifdef ENABLE_WALLET #include "wallet_ismine.h" @@ -22,7 +23,7 @@ using namespace std; typedef vector valtype; -BOOST_AUTO_TEST_SUITE(multisig_tests) +BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup) CScript sign_multisig(CScript scriptPubKey, vector keys, CTransaction transaction, int whichIn) diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 93614599492..cb357d295c2 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "netbase.h" +#include "test/test_bitcoin.h" #include @@ -10,7 +11,7 @@ using namespace std; -BOOST_AUTO_TEST_SUITE(netbase_tests) +BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(netbase_networks) { diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 4406b08e569..f6d06d6805c 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -9,6 +9,7 @@ #include "arith_uint256.h" #include "version.h" #include "random.h" +#include "test/test_bitcoin.h" #include @@ -28,7 +29,7 @@ public: } }; -BOOST_AUTO_TEST_SUITE(pmt_tests) +BOOST_FIXTURE_TEST_SUITE(pmt_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(pmt_test1) { diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index e42c1b0a8b6..7b197c527de 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -5,12 +5,13 @@ #include "main.h" #include "pow.h" #include "util.h" +#include "test/test_bitcoin.h" #include using namespace std; -BOOST_AUTO_TEST_SUITE(pow_tests) +BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) /* Test calculation of next difficulty target with no constraints applying */ BOOST_AUTO_TEST_CASE(get_next_work) diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp index 464a8fbb8cf..f5f7f381d31 100644 --- a/src/test/sanity_tests.cpp +++ b/src/test/sanity_tests.cpp @@ -4,9 +4,11 @@ #include "compat/sanity.h" #include "key.h" +#include "test/test_bitcoin.h" #include -BOOST_AUTO_TEST_SUITE(sanity_tests) + +BOOST_FIXTURE_TEST_SUITE(sanity_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(basic_sanity) { diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 94f2ce1a29a..52171b9e3c8 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -8,6 +8,7 @@ #include "script/script.h" #include "script/script_error.h" #include "script/sign.h" +#include "test/test_bitcoin.h" #ifdef ENABLE_WALLET #include "wallet_ismine.h" @@ -47,7 +48,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri } -BOOST_AUTO_TEST_SUITE(script_P2SH_tests) +BOOST_FIXTURE_TEST_SUITE(script_P2SH_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(sign) { diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index e410b59710c..c0614cca431 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -13,6 +13,7 @@ #include "script/script_error.h" #include "script/sign.h" #include "util.h" +#include "test/test_bitcoin.h" #if defined(HAVE_CONSENSUS_LIB) #include "script/bitcoinconsensus.h" @@ -53,7 +54,7 @@ read_json(const std::string& jsondata) return v.get_array(); } -BOOST_AUTO_TEST_SUITE(script_tests) +BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup) CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey) { diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index cfbaf26e703..24c7dd3d5a4 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -4,10 +4,13 @@ #include "bignum.h" #include "script/script.h" +#include "test/test_bitcoin.h" + #include #include #include -BOOST_AUTO_TEST_SUITE(scriptnum_tests) + +BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup) static const int64_t values[] = \ { 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX }; diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index de9510d54a4..cc8f2b788d6 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -5,6 +5,7 @@ #include "serialize.h" #include "streams.h" #include "hash.h" +#include "test/test_bitcoin.h" #include @@ -12,7 +13,7 @@ using namespace std; -BOOST_AUTO_TEST_SUITE(serialize_tests) +BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(sizes) { diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index ea41dbcde23..afb7a41bbd4 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -10,6 +10,7 @@ #include "script/interpreter.h" #include "util.h" #include "version.h" +#include "test/test_bitcoin.h" #include @@ -115,7 +116,7 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) { } } -BOOST_AUTO_TEST_SUITE(sighash_tests) +BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(sighash_test) { diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 3c8264d89d1..b26fed99f2a 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -7,6 +7,7 @@ #include "script/script.h" #include "script/standard.h" #include "uint256.h" +#include "test/test_bitcoin.h" #include @@ -23,7 +24,7 @@ Serialize(const CScript& s) return sSerialized; } -BOOST_AUTO_TEST_SUITE(sigopcount_tests) +BOOST_FIXTURE_TEST_SUITE(sigopcount_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(GetSigOpCount) { diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index c75e21a2adf..86a4bc67272 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -5,6 +5,7 @@ #include "main.h" #include "random.h" #include "util.h" +#include "test/test_bitcoin.h" #include @@ -12,7 +13,7 @@ #define SKIPLIST_LENGTH 300000 -BOOST_AUTO_TEST_SUITE(skiplist_tests) +BOOST_FIXTURE_TEST_SUITE(skiplist_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(skiplist_test) { diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index a1355ad445a..48e49ed757c 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -26,11 +26,17 @@ CWallet* pwalletMain; extern bool fPrintToConsole; extern void noui_connect(); -TestingSetup::TestingSetup() +BasicTestingSetup::BasicTestingSetup() { fPrintToDebugLog = false; // don't want to write to debug.log file SelectParams(CBaseChainParams::MAIN); - noui_connect(); +} +BasicTestingSetup::~BasicTestingSetup() +{ +} + +TestingSetup::TestingSetup() +{ #ifdef ENABLE_WALLET bitdb.MakeMock(); #endif diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index c1448dcdebe..2f75332d40d 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -6,7 +6,19 @@ #include #include -struct TestingSetup { +/** Basic testing setup. + * This just configures logging and chain parameters. + */ +struct BasicTestingSetup { + BasicTestingSetup(); + ~BasicTestingSetup(); +}; + +/** Testing setup that configures a complete environment. + * Included are data directory, coins database, script check threads + * and wallet (if enabled) setup. + */ +struct TestingSetup: public BasicTestingSetup { CCoinsViewDB *pcoinsdbview; boost::filesystem::path pathTemp; boost::thread_group threadGroup; diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index 58ed963274e..887cfb47613 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -3,12 +3,13 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. // #include "timedata.h" +#include "test/test_bitcoin.h" #include using namespace std; -BOOST_AUTO_TEST_SUITE(timedata_tests) +BOOST_FIXTURE_TEST_SUITE(timedata_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(util_MedianFilter) { diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 52adfea992f..2a3083316e9 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -4,6 +4,7 @@ #include "data/tx_invalid.json.h" #include "data/tx_valid.json.h" +#include "test/test_bitcoin.h" #include "clientversion.h" #include "key.h" @@ -75,7 +76,7 @@ string FormatScriptFlags(unsigned int flags) return ret.substr(0, ret.size() - 1); } -BOOST_AUTO_TEST_SUITE(transaction_tests) +BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(tx_valid) { diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index 5b33846ba94..426d296a9ac 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -4,6 +4,7 @@ #include "arith_uint256.h" #include "uint256.h" #include "version.h" +#include "test/test_bitcoin.h" #include #include @@ -14,7 +15,7 @@ #include #include -BOOST_AUTO_TEST_SUITE(uint256_tests) +BOOST_FIXTURE_TEST_SUITE(uint256_tests, BasicTestingSetup) const unsigned char R1Array[] = "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 5f0c1deb8e2..8cecfbf6516 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -7,12 +7,13 @@ #include #include #include "univalue/univalue.h" +#include "test/test_bitcoin.h" #include using namespace std; -BOOST_AUTO_TEST_SUITE(univalue_tests) +BOOST_FIXTURE_TEST_SUITE(univalue_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(univalue_constructor) { diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index d829ec228db..3309e2e3877 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -10,6 +10,7 @@ #include "sync.h" #include "utilstrencodings.h" #include "utilmoneystr.h" +#include "test/test_bitcoin.h" #include #include @@ -18,7 +19,7 @@ using namespace std; -BOOST_AUTO_TEST_SUITE(util_tests) +BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(util_criticalsection) { From 50c72f23ad5f7fcd13bf016f79cac6323c329caf Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 3 Feb 2015 21:09:47 +0100 Subject: [PATCH 0312/2337] [Move Only] Move wallet related things to src/wallet/ could once be renamed from /src/wallet to /src/legacywallet. --- src/Makefile.am | 20 ++++++++++---------- src/Makefile.test.include | 2 +- src/init.cpp | 6 +++--- src/miner.cpp | 2 +- src/qt/addresstablemodel.cpp | 2 +- src/qt/bitcoin.cpp | 2 +- src/qt/coincontroldialog.cpp | 2 +- src/qt/optionsdialog.cpp | 2 +- src/qt/optionsmodel.cpp | 4 ++-- src/qt/paymentserver.cpp | 2 +- src/qt/sendcoinsdialog.cpp | 2 +- src/qt/signverifymessagedialog.cpp | 2 +- src/qt/splashscreen.cpp | 2 +- src/qt/transactiondesc.cpp | 4 ++-- src/qt/transactionrecord.cpp | 2 +- src/qt/transactiontablemodel.cpp | 2 +- src/qt/walletmodel.cpp | 6 +++--- src/qt/walletmodeltransaction.cpp | 2 +- src/rpcmining.cpp | 4 ++-- src/rpcmisc.cpp | 4 ++-- src/rpcrawtransaction.cpp | 2 +- src/rpcserver.cpp | 2 +- src/test/accounting_tests.cpp | 4 ++-- src/test/multisig_tests.cpp | 2 +- src/test/rpc_wallet_tests.cpp | 2 +- src/test/script_P2SH_tests.cpp | 2 +- src/test/test_bitcoin.cpp | 4 ++-- src/{ => wallet}/db.cpp | 0 src/{ => wallet}/db.h | 0 src/{ => wallet}/rpcdump.cpp | 0 src/{ => wallet}/rpcwallet.cpp | 0 src/{ => wallet}/test/wallet_tests.cpp | 2 +- src/{ => wallet}/wallet.cpp | 2 +- src/{ => wallet}/wallet.h | 4 ++-- src/{ => wallet}/wallet_ismine.cpp | 0 src/{ => wallet}/wallet_ismine.h | 0 src/{ => wallet}/walletdb.cpp | 4 ++-- src/{ => wallet}/walletdb.h | 2 +- 38 files changed, 53 insertions(+), 53 deletions(-) rename src/{ => wallet}/db.cpp (100%) rename src/{ => wallet}/db.h (100%) rename src/{ => wallet}/rpcdump.cpp (100%) rename src/{ => wallet}/rpcwallet.cpp (100%) rename src/{ => wallet}/test/wallet_tests.cpp (99%) rename src/{ => wallet}/wallet.cpp (99%) rename src/{ => wallet}/wallet.h (99%) rename src/{ => wallet}/wallet_ismine.cpp (100%) rename src/{ => wallet}/wallet_ismine.h (100%) rename src/{ => wallet}/walletdb.cpp (99%) rename src/{ => wallet}/walletdb.h (99%) diff --git a/src/Makefile.am b/src/Makefile.am index da65efa7132..c30368c5bf9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,7 +90,7 @@ BITCOIN_CORE_H = \ compressor.h \ core_io.h \ crypter.h \ - db.h \ + wallet/db.h \ eccryptoverify.h \ ecwrapper.h \ hash.h \ @@ -138,9 +138,9 @@ BITCOIN_CORE_H = \ utilstrencodings.h \ utiltime.h \ version.h \ - walletdb.h \ - wallet.h \ - wallet_ismine.h \ + wallet/walletdb.h \ + wallet/wallet.h \ + wallet/wallet_ismine.h \ compat/byteswap.h \ compat/endian.h \ compat/sanity.h @@ -196,13 +196,13 @@ libbitcoin_server_a_SOURCES = \ # when wallet enabled libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_wallet_a_SOURCES = \ - db.cpp \ + wallet/db.cpp \ crypter.cpp \ - rpcdump.cpp \ - rpcwallet.cpp \ - wallet.cpp \ - wallet_ismine.cpp \ - walletdb.cpp \ + wallet/rpcdump.cpp \ + wallet/rpcwallet.cpp \ + wallet/wallet.cpp \ + wallet/wallet_ismine.cpp \ + wallet/walletdb.cpp \ $(BITCOIN_CORE_H) # crypto primitives library diff --git a/src/Makefile.test.include b/src/Makefile.test.include index e9d99323c5f..8dd0a28454f 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -76,7 +76,7 @@ BITCOIN_TESTS =\ if ENABLE_WALLET BITCOIN_TESTS += \ test/accounting_tests.cpp \ - test/wallet_tests.cpp \ + wallet/test/wallet_tests.cpp \ test/rpc_wallet_tests.cpp endif diff --git a/src/init.cpp b/src/init.cpp index 1e3cc1d899e..a930a97a94f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -24,9 +24,9 @@ #include "util.h" #include "utilmoneystr.h" #ifdef ENABLE_WALLET -#include "db.h" -#include "wallet.h" -#include "walletdb.h" +#include "wallet/db.h" +#include "wallet/wallet.h" +#include "wallet/walletdb.h" #endif #include diff --git a/src/miner.cpp b/src/miner.cpp index e359654d7ba..01212b19c4c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -15,7 +15,7 @@ #include "util.h" #include "utilmoneystr.h" #ifdef ENABLE_WALLET -#include "wallet.h" +#include "wallet/wallet.h" #endif #include diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 162ecdba4ef..9573fe43df8 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -8,7 +8,7 @@ #include "walletmodel.h" #include "base58.h" -#include "wallet.h" +#include "wallet/wallet.h" #include #include diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 73c684e4893..3ae780abfd8 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -30,7 +30,7 @@ #include "util.h" #ifdef ENABLE_WALLET -#include "wallet.h" +#include "wallet/wallet.h" #endif #include diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 3f4f082b8cc..6d7ef70a706 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -15,7 +15,7 @@ #include "coincontrol.h" #include "main.h" -#include "wallet.h" +#include "wallet/wallet.h" #include // for 'map_list_of()' diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index a342b4bfea4..a9e4b339e48 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -18,7 +18,7 @@ #include "txdb.h" // for -dbcache defaults #ifdef ENABLE_WALLET -#include "wallet.h" // for CWallet::minTxFee +#include "wallet/wallet.h" // for CWallet::minTxFee #endif #include diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 7d2dbd96de7..a169ed6b55a 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -18,8 +18,8 @@ #include "txdb.h" // for -dbcache defaults #ifdef ENABLE_WALLET -#include "wallet.h" -#include "walletdb.h" +#include "wallet/wallet.h" +#include "wallet/walletdb.h" #endif #include diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 96ceeb18a4b..40d6e16f519 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -12,7 +12,7 @@ #include "chainparams.h" #include "ui_interface.h" #include "util.h" -#include "wallet.h" +#include "wallet/wallet.h" #include diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 4f3230a8c9e..2ec180c3ac4 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -18,7 +18,7 @@ #include "base58.h" #include "coincontrol.h" #include "ui_interface.h" -#include "wallet.h" +#include "wallet/wallet.h" #include #include diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 970f6a520d8..76da6904a98 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -12,7 +12,7 @@ #include "base58.h" #include "init.h" -#include "wallet.h" +#include "wallet/wallet.h" #include #include diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index e6a7fcaec5d..414fe02ff9b 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -12,7 +12,7 @@ #include "version.h" #ifdef ENABLE_WALLET -#include "wallet.h" +#include "wallet/wallet.h" #endif #include diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 68c275d4945..9b235f91302 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -10,13 +10,13 @@ #include "transactionrecord.h" #include "base58.h" -#include "db.h" +#include "wallet/db.h" #include "main.h" #include "script/script.h" #include "timedata.h" #include "ui_interface.h" #include "util.h" -#include "wallet.h" +#include "wallet/wallet.h" #include #include diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index fea436806a5..19e3fc0dc28 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -6,7 +6,7 @@ #include "base58.h" #include "timedata.h" -#include "wallet.h" +#include "wallet/wallet.h" #include diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index df1afbfaaae..dff2676b10b 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -17,7 +17,7 @@ #include "sync.h" #include "uint256.h" #include "util.h" -#include "wallet.h" +#include "wallet/wallet.h" #include #include diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 79f5191fc0d..d4e88c1a51c 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -11,13 +11,13 @@ #include "transactiontablemodel.h" #include "base58.h" -#include "db.h" +#include "wallet/db.h" #include "keystore.h" #include "main.h" #include "sync.h" #include "ui_interface.h" -#include "wallet.h" -#include "walletdb.h" // for BackupWallet +#include "wallet/wallet.h" +#include "wallet/walletdb.h" // for BackupWallet #include diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 8f32e46148d..d9129077f59 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -4,7 +4,7 @@ #include "walletmodeltransaction.h" -#include "wallet.h" +#include "wallet/wallet.h" WalletModelTransaction::WalletModelTransaction(const QList &recipients) : recipients(recipients), diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 165a9df697d..a07acea9aad 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -14,8 +14,8 @@ #include "rpcserver.h" #include "util.h" #ifdef ENABLE_WALLET -#include "db.h" -#include "wallet.h" +#include "wallet/db.h" +#include "wallet/wallet.h" #endif #include diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 2eda4d33552..938d79513f3 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -13,8 +13,8 @@ #include "timedata.h" #include "util.h" #ifdef ENABLE_WALLET -#include "wallet.h" -#include "walletdb.h" +#include "wallet/wallet.h" +#include "wallet/walletdb.h" #endif #include diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 4a079f5c81f..a79b4e33940 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -16,7 +16,7 @@ #include "script/standard.h" #include "uint256.h" #ifdef ENABLE_WALLET -#include "wallet.h" +#include "wallet/wallet.h" #endif #include diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 20e9252d7ee..ba71725222e 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -13,7 +13,7 @@ #include "util.h" #include "utilstrencodings.h" #ifdef ENABLE_WALLET -#include "wallet.h" +#include "wallet/wallet.h" #endif #include diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index 36499f01a7b..0c2ade48d62 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -2,8 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "wallet.h" -#include "walletdb.h" +#include "wallet/wallet.h" +#include "wallet/walletdb.h" #include "test/test_bitcoin.h" diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 2168a5fef1f..431ad995ded 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -12,7 +12,7 @@ #include "uint256.h" #ifdef ENABLE_WALLET -#include "wallet_ismine.h" +#include "wallet/wallet_ismine.h" #endif #include diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 44475076b3c..d97bea8bd2a 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -6,7 +6,7 @@ #include "rpcclient.h" #include "base58.h" -#include "wallet.h" +#include "wallet/wallet.h" #include "test/test_bitcoin.h" diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 94f2ce1a29a..357c8e93c91 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -10,7 +10,7 @@ #include "script/sign.h" #ifdef ENABLE_WALLET -#include "wallet_ismine.h" +#include "wallet/wallet_ismine.h" #endif #include diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index a1355ad445a..35f2ecd2879 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -12,8 +12,8 @@ #include "ui_interface.h" #include "util.h" #ifdef ENABLE_WALLET -#include "db.h" -#include "wallet.h" +#include "wallet/db.h" +#include "wallet/wallet.h" #endif #include diff --git a/src/db.cpp b/src/wallet/db.cpp similarity index 100% rename from src/db.cpp rename to src/wallet/db.cpp diff --git a/src/db.h b/src/wallet/db.h similarity index 100% rename from src/db.h rename to src/wallet/db.h diff --git a/src/rpcdump.cpp b/src/wallet/rpcdump.cpp similarity index 100% rename from src/rpcdump.cpp rename to src/wallet/rpcdump.cpp diff --git a/src/rpcwallet.cpp b/src/wallet/rpcwallet.cpp similarity index 100% rename from src/rpcwallet.cpp rename to src/wallet/rpcwallet.cpp diff --git a/src/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp similarity index 99% rename from src/test/wallet_tests.cpp rename to src/wallet/test/wallet_tests.cpp index 25c8fab3354..a5bc52b8dc9 100644 --- a/src/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "wallet.h" +#include "wallet/wallet.h" #include #include diff --git a/src/wallet.cpp b/src/wallet/wallet.cpp similarity index 99% rename from src/wallet.cpp rename to src/wallet/wallet.cpp index b51c4d4b14a..5b4add84318 100644 --- a/src/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3,7 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "wallet.h" +#include "wallet/wallet.h" #include "base58.h" #include "checkpoints.h" diff --git a/src/wallet.h b/src/wallet/wallet.h similarity index 99% rename from src/wallet.h rename to src/wallet/wallet.h index 6ed87d1e687..093336080e8 100644 --- a/src/wallet.h +++ b/src/wallet/wallet.h @@ -14,8 +14,8 @@ #include "keystore.h" #include "main.h" #include "ui_interface.h" -#include "wallet_ismine.h" -#include "walletdb.h" +#include "wallet/wallet_ismine.h" +#include "wallet/walletdb.h" #include #include diff --git a/src/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp similarity index 100% rename from src/wallet_ismine.cpp rename to src/wallet/wallet_ismine.cpp diff --git a/src/wallet_ismine.h b/src/wallet/wallet_ismine.h similarity index 100% rename from src/wallet_ismine.h rename to src/wallet/wallet_ismine.h diff --git a/src/walletdb.cpp b/src/wallet/walletdb.cpp similarity index 99% rename from src/walletdb.cpp rename to src/wallet/walletdb.cpp index ddec57d9a90..880026d187c 100644 --- a/src/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -3,7 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "walletdb.h" +#include "wallet/walletdb.h" #include "base58.h" #include "protocol.h" @@ -11,7 +11,7 @@ #include "sync.h" #include "util.h" #include "utiltime.h" -#include "wallet.h" +#include "wallet/wallet.h" #include #include diff --git a/src/walletdb.h b/src/wallet/walletdb.h similarity index 99% rename from src/walletdb.h rename to src/wallet/walletdb.h index 2627ef71a60..6aa0fa40df0 100644 --- a/src/walletdb.h +++ b/src/wallet/walletdb.h @@ -7,7 +7,7 @@ #define BITCOIN_WALLETDB_H #include "amount.h" -#include "db.h" +#include "wallet/db.h" #include "key.h" #include "keystore.h" From a9af415887f03cb2565895bc55be72748549e527 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Wed, 11 Mar 2015 11:56:44 -0400 Subject: [PATCH 0313/2337] fix InvalidateBlock to repopulate setBlockIndexCandidates --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 6bbb3bc1356..9b4bb431283 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2311,7 +2311,7 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { BlockMap::iterator it = mapBlockIndex.begin(); while (it != mapBlockIndex.end()) { if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) { - setBlockIndexCandidates.insert(pindex); + setBlockIndexCandidates.insert(it->second); } it++; } From 88f6c8c3657cba81c65da34a7161c860c8a23c5f Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Wed, 11 Mar 2015 11:58:40 -0400 Subject: [PATCH 0314/2337] add RPC test for InvalidateBlock --- qa/rpc-tests/invalidateblock.py | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100755 qa/rpc-tests/invalidateblock.py diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py new file mode 100755 index 00000000000..a8bfbe6e6c7 --- /dev/null +++ b/qa/rpc-tests/invalidateblock.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test InvalidateBlock code +# + +from test_framework import BitcoinTestFramework +from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException +from util import * + +class InvalidateTest(BitcoinTestFramework): + + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + self.nodes = [] + self.is_network_split = False + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"])) + + def run_test(self): + print "Mine 4 blocks on Node 0" + self.nodes[0].setgenerate(True, 4) + assert(self.nodes[0].getblockcount() == 4) + besthash = self.nodes[0].getbestblockhash() + + print "Mine competing 6 blocks on Node 1" + self.nodes[1].setgenerate(True, 6) + assert(self.nodes[1].getblockcount() == 6) + + print "Connect nodes to force a reorg" + connect_nodes_bi(self.nodes,0,1) + sync_blocks(self.nodes) + assert(self.nodes[0].getblockcount() == 6) + badhash = self.nodes[1].getblockhash(2) + + print "Invalidate block 2 on node 0 and verify we reorg to node 0's original chain" + self.nodes[0].invalidateblock(badhash) + newheight = self.nodes[0].getblockcount() + newhash = self.nodes[0].getbestblockhash() + if (newheight != 4 or newhash != besthash): + raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight)) + +if __name__ == '__main__': + InvalidateTest().main() From e96c5184e783cf940956bf803dae8690dcf2b496 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 12 Mar 2015 20:13:49 +0600 Subject: [PATCH 0315/2337] BUGFIX: Stack around the variable 'rv' was corrupted --- src/uint256.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uint256.cpp b/src/uint256.cpp index 3b1334a0324..25148808c67 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -45,7 +45,7 @@ void base_blob::SetHex(const char* psz) psz++; psz--; unsigned char* p1 = (unsigned char*)data; - unsigned char* pend = p1 + WIDTH * 4; + unsigned char* pend = p1 + WIDTH; while (psz >= pbegin && p1 < pend) { *p1 = ::HexDigit(*psz--); if (psz >= pbegin) { @@ -128,7 +128,7 @@ uint64_t uint256::GetHash(const uint256& salt) const uint32_t a, b, c; const uint32_t *pn = (const uint32_t*)data; const uint32_t *salt_pn = (const uint32_t*)salt.data; - a = b = c = 0xdeadbeef + (WIDTH << 2); + a = b = c = 0xdeadbeef + WIDTH; a += pn[0] ^ salt_pn[0]; b += pn[1] ^ salt_pn[1]; From 292623adf59edea52b2927b3d67fd2ff7f997882 Mon Sep 17 00:00:00 2001 From: Cozz Lovan Date: Wed, 23 Jul 2014 14:34:36 +0200 Subject: [PATCH 0316/2337] Subtract fee from amount Fixes #2724 and #1570. Adds the automatically-subtract-the-fee-from-the-amount-and-send-whats-left feature to the GUI and RPC (sendtoaddress,sendmany). --- qa/rpc-tests/wallet.py | 15 ++++++ src/primitives/transaction.h | 9 +++- src/qt/coincontroldialog.cpp | 23 ++++++-- src/qt/coincontroldialog.h | 1 + src/qt/forms/sendcoinsentry.ui | 16 +++++- src/qt/sendcoinsdialog.cpp | 13 +++-- src/qt/sendcoinsentry.cpp | 6 ++- src/qt/sendcoinsentry.h | 1 + src/qt/walletmodel.cpp | 22 ++++++-- src/qt/walletmodel.h | 6 ++- src/qt/walletmodeltransaction.cpp | 32 ++++++++++++ src/qt/walletmodeltransaction.h | 4 +- src/rpcclient.cpp | 2 + src/rpcwallet.cpp | 61 ++++++++++++++++------ src/wallet.cpp | 87 +++++++++++++++++++++++-------- src/wallet.h | 12 +++-- 16 files changed, 248 insertions(+), 62 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 3e63493dc6e..84d30239969 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -102,6 +102,21 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[2].getbalance(), 100) assert_equal(self.nodes[2].getbalance("from1"), 100-21) + # Send 10 XBT normal + address = self.nodes[0].getnewaddress("test") + self.nodes[2].settxfee(Decimal('0.001')) + txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) + self.nodes[2].setgenerate(True, 1) + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000')) + assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000')) + + # Send 10 XBT with subtract fee from amount + txid = self.nodes[2].sendtoaddress(address, 10, "", "", True) + self.nodes[2].setgenerate(True, 1) + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000')) + assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000')) if __name__ == '__main__': WalletTest ().main () diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 1b5a47e0da9..fdb8c50a46e 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -134,7 +134,7 @@ public: uint256 GetHash() const; - bool IsDust(CFeeRate minRelayTxFee) const + CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const { // "Dust" is defined in terms of CTransaction::minRelayTxFee, // which has units satoshis-per-kilobyte. @@ -145,7 +145,12 @@ public: // so dust is a txout less than 546 satoshis // with default minRelayTxFee. size_t nSize = GetSerializeSize(SER_DISK,0)+148u; - return (nValue < 3*minRelayTxFee.GetFee(nSize)); + return 3*minRelayTxFee.GetFee(nSize); + } + + bool IsDust(const CFeeRate &minRelayTxFee) const + { + return (nValue < GetDustThreshold(minRelayTxFee)); } friend bool operator==(const CTxOut& a, const CTxOut& b) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 3f4f082b8cc..5042ff06a26 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -33,6 +33,7 @@ using namespace std; QList CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); +bool CoinControlDialog::fSubtractFeeFromAmount = false; CoinControlDialog::CoinControlDialog(QWidget *parent) : QDialog(parent), @@ -541,6 +542,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority) sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority); + // in the subtract fee from amount case, we can tell if zero change already and subtract the bytes, so that fee calculation afterwards is accurate + if (CoinControlDialog::fSubtractFeeFromAmount) + if (nAmount - nPayAmount == 0) + nBytes -= 34; + // Fee nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool); @@ -556,7 +562,9 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) if (nPayAmount > 0) { - nChange = nAmount - nPayFee - nPayAmount; + nChange = nAmount - nPayAmount; + if (!CoinControlDialog::fSubtractFeeFromAmount) + nChange -= nPayFee; // Never create dust outputs; if we would, just add the dust to the fee. if (nChange > 0 && nChange < CENT) @@ -564,12 +572,17 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) CTxOut txout(nChange, (CScript)vector(24, 0)); if (txout.IsDust(::minRelayTxFee)) { - nPayFee += nChange; - nChange = 0; + if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust + nChange = txout.GetDustThreshold(::minRelayTxFee); + else + { + nPayFee += nChange; + nChange = 0; + } } } - if (nChange == 0) + if (nChange == 0 && !CoinControlDialog::fSubtractFeeFromAmount) nBytes -= 34; } @@ -612,7 +625,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) { l3->setText(ASYMP_UTF8 + l3->text()); l4->setText(ASYMP_UTF8 + l4->text()); - if (nChange > 0) + if (nChange > 0 && !CoinControlDialog::fSubtractFeeFromAmount) l8->setText(ASYMP_UTF8 + l8->text()); } diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 5a91876f1f9..5ec382838f9 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -43,6 +43,7 @@ public: static QList payAmounts; static CCoinControl *coinControl; + static bool fSubtractFeeFromAmount; private: Ui::CoinControlDialog *ui; diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 9f8c0a48441..b362928438c 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -157,7 +157,21 @@ - + + + + + + + + The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally. + + + S&ubtract fee from amount + + + + diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 4338e58e260..55ca65c8e6b 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -221,8 +221,6 @@ void SendCoinsDialog::on_sendButton_clicked() } fNewRecipientAllowed = false; - - WalletModel::UnlockContext ctx(model->requestUnlock()); if(!ctx.isValid()) { @@ -252,7 +250,7 @@ void SendCoinsDialog::on_sendButton_clicked() // Format confirmation message QStringList formatted; - foreach(const SendCoinsRecipient &rcp, recipients) + foreach(const SendCoinsRecipient &rcp, currentTransaction.getRecipients()) { // generate bold amount string QString amount = "" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); @@ -369,6 +367,7 @@ SendCoinsEntry *SendCoinsDialog::addEntry() ui->entries->addWidget(entry); connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*))); connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels())); + connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels())); updateTabsAndLabels(); @@ -784,11 +783,17 @@ void SendCoinsDialog::coinControlUpdateLabels() // set pay amounts CoinControlDialog::payAmounts.clear(); + CoinControlDialog::fSubtractFeeFromAmount = false; for(int i = 0; i < ui->entries->count(); ++i) { SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); if(entry) - CoinControlDialog::payAmounts.append(entry->getValue().amount); + { + SendCoinsRecipient rcp = entry->getValue(); + CoinControlDialog::payAmounts.append(rcp.amount); + if (rcp.fSubtractFeeFromAmount) + CoinControlDialog::fSubtractFeeFromAmount = true; + } } if (CoinControlDialog::coinControl->HasSelected()) diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 6db6eee75be..6ac650e74fc 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -44,6 +44,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) : // Connect signals connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged())); + connect(ui->checkboxSubtractFeeFromAmount, SIGNAL(toggled(bool)), this, SIGNAL(subtractFeeFromAmountChanged())); connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked())); connect(ui->deleteButton_is, SIGNAL(clicked()), this, SLOT(deleteClicked())); connect(ui->deleteButton_s, SIGNAL(clicked()), this, SLOT(deleteClicked())); @@ -94,6 +95,7 @@ void SendCoinsEntry::clear() ui->payTo->clear(); ui->addAsLabel->clear(); ui->payAmount->clear(); + ui->checkboxSubtractFeeFromAmount->setCheckState(Qt::Unchecked); ui->messageTextLabel->clear(); ui->messageTextLabel->hide(); ui->messageLabel->hide(); @@ -165,6 +167,7 @@ SendCoinsRecipient SendCoinsEntry::getValue() recipient.label = ui->addAsLabel->text(); recipient.amount = ui->payAmount->value(); recipient.message = ui->messageTextLabel->text(); + recipient.fSubtractFeeFromAmount = (ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked); return recipient; } @@ -174,7 +177,8 @@ QWidget *SendCoinsEntry::setupTabChain(QWidget *prev) QWidget::setTabOrder(prev, ui->payTo); QWidget::setTabOrder(ui->payTo, ui->addAsLabel); QWidget *w = ui->payAmount->setupTabChain(ui->addAsLabel); - QWidget::setTabOrder(w, ui->addressBookButton); + QWidget::setTabOrder(w, ui->checkboxSubtractFeeFromAmount); + QWidget::setTabOrder(ui->checkboxSubtractFeeFromAmount, ui->addressBookButton); QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton); QWidget::setTabOrder(ui->pasteButton, ui->deleteButton); return ui->deleteButton; diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 4cb00cd36a2..c2d1185bddb 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -51,6 +51,7 @@ public slots: signals: void removeEntry(SendCoinsEntry *entry); void payAmountChanged(); + void subtractFeeFromAmountChanged(); private slots: void deleteClicked(); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 79f5191fc0d..1baa5eb9322 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -6,6 +6,7 @@ #include "addresstablemodel.h" #include "guiconstants.h" +#include "guiutil.h" #include "paymentserver.h" #include "recentrequeststablemodel.h" #include "transactiontablemodel.h" @@ -192,8 +193,9 @@ bool WalletModel::validateAddress(const QString &address) WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { CAmount total = 0; + bool fSubtractFeeFromAmount = false; QList recipients = transaction.getRecipients(); - std::vector > vecSend; + std::vector vecSend; if(recipients.empty()) { @@ -206,6 +208,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { + if (rcp.fSubtractFeeFromAmount) + fSubtractFeeFromAmount = true; + if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... CAmount subtotal = 0; @@ -217,7 +222,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); - vecSend.push_back(std::pair(scriptPubKey, out.amount())); + CAmount nAmount = out.amount(); + CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount}; + vecSend.push_back(recipient); } if (subtotal <= 0) { @@ -239,7 +246,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact ++nAddresses; CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); - vecSend.push_back(std::pair(scriptPubKey, rcp.amount)); + CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount}; + vecSend.push_back(recipient); total += rcp.amount; } @@ -260,17 +268,21 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact LOCK2(cs_main, wallet->cs_wallet); transaction.newPossibleKeyChange(wallet); + CAmount nFeeRequired = 0; + int nChangePosRet = -1; std::string strFailReason; CWalletTx *newTx = transaction.getTransaction(); CReserveKey *keyChange = transaction.getPossibleKeyChange(); - bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason, coinControl); + bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl); transaction.setTransactionFee(nFeeRequired); + if (fSubtractFeeFromAmount && fCreated) + transaction.reassignAmounts(nChangePosRet); if(!fCreated) { - if((total + nFeeRequired) > nBalance) + if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 4a9a12beaa9..de915165f94 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -36,9 +36,9 @@ QT_END_NAMESPACE class SendCoinsRecipient { public: - explicit SendCoinsRecipient() : amount(0), nVersion(SendCoinsRecipient::CURRENT_VERSION) { } + explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { } explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message): - address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} + address(addr), label(label), amount(amount), message(message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} // If from an unauthenticated payment request, this is used for storing // the addresses, e.g. address-A
address-B
address-C. @@ -56,6 +56,8 @@ public: // Empty if no authentication or invalid signature/cert/etc. QString authenticatedMerchant; + bool fSubtractFeeFromAmount; // memory only + static const int CURRENT_VERSION = 1; int nVersion; diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 8f32e46148d..c97add6befb 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -46,6 +46,38 @@ void WalletModelTransaction::setTransactionFee(const CAmount& newFee) fee = newFee; } +void WalletModelTransaction::reassignAmounts(int nChangePosRet) +{ + int i = 0; + for (QList::iterator it = recipients.begin(); it != recipients.end(); ++it) + { + SendCoinsRecipient& rcp = (*it); + + if (rcp.paymentRequest.IsInitialized()) + { + CAmount subtotal = 0; + const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); + for (int j = 0; j < details.outputs_size(); j++) + { + const payments::Output& out = details.outputs(j); + if (out.amount() <= 0) continue; + if (i == nChangePosRet) + i++; + subtotal += walletTransaction->vout[i].nValue; + i++; + } + rcp.amount = subtotal; + } + else // normal recipient (no payment request) + { + if (i == nChangePosRet) + i++; + rcp.amount = walletTransaction->vout[i].nValue; + i++; + } + } +} + CAmount WalletModelTransaction::getTotalTransactionAmount() { CAmount totalTransactionAmount = 0; diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index b6bb6d67f6b..7765fea4afe 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -35,8 +35,10 @@ public: void newPossibleKeyChange(CWallet *wallet); CReserveKey *getPossibleKeyChange(); + void reassignAmounts(int nChangePosRet); // needed for the subtract-fee-from-amount feature + private: - const QList recipients; + QList recipients; CWalletTx *walletTransaction; CReserveKey *keyChange; CAmount fee; diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 4e45bc32ab4..a45ea9839be 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -32,6 +32,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getnetworkhashps", 0 }, { "getnetworkhashps", 1 }, { "sendtoaddress", 1 }, + { "sendtoaddress", 4 }, { "settxfee", 0 }, { "getreceivedbyaddress", 1 }, { "getreceivedbyaccount", 1 }, @@ -59,6 +60,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listsinceblock", 2 }, { "sendmany", 1 }, { "sendmany", 2 }, + { "sendmany", 4 }, { "addmultisigaddress", 0 }, { "addmultisigaddress", 1 }, { "createmultisig", 0 }, diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index d097b6a0faf..142487bc8cc 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -317,7 +317,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) return ret; } -static void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew) +static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) { CAmount curBalance = pwalletMain->GetBalance(); @@ -335,11 +335,14 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& CReserveKey reservekey(pwalletMain); CAmount nFeeRequired; std::string strError; - if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError)) { - if (nValue + nFeeRequired > curBalance) - throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired))); - else - throw JSONRPCError(RPC_WALLET_ERROR, strError); + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount}; + vecSend.push_back(recipient); + if (!pwalletMain->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > pwalletMain->GetBalance()) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); } if (!pwalletMain->CommitTransaction(wtxNew, reservekey)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); @@ -347,9 +350,9 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& Value sendtoaddress(const Array& params, bool fHelp) { - if (fHelp || params.size() < 2 || params.size() > 4) + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( - "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" )\n" + "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + HelpRequiringPassphrase() + "\nArguments:\n" @@ -360,11 +363,14 @@ Value sendtoaddress(const Array& params, bool fHelp) "4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n" " to which you're sending the transaction. This is not part of the \n" " transaction, just kept in your wallet.\n" + "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n" + " The recipient will receive less bitcoins than you enter in the amount field.\n" "\nResult:\n" "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") + + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true") + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"") ); @@ -384,9 +390,13 @@ Value sendtoaddress(const Array& params, bool fHelp) if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) wtx.mapValue["to"] = params[3].get_str(); + bool fSubtractFeeFromAmount = false; + if (params.size() > 4) + fSubtractFeeFromAmount = params[4].get_bool(); + EnsureWalletIsUnlocked(); - SendMoney(address.Get(), nAmount, wtx); + SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx); return wtx.GetHash().GetHex(); } @@ -840,7 +850,7 @@ Value sendfrom(const Array& params, bool fHelp) if (nAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); - SendMoney(address.Get(), nAmount, wtx); + SendMoney(address.Get(), nAmount, false, wtx); return wtx.GetHash().GetHex(); } @@ -848,9 +858,9 @@ Value sendfrom(const Array& params, bool fHelp) Value sendmany(const Array& params, bool fHelp) { - if (fHelp || params.size() < 2 || params.size() > 4) + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( - "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" )\n" + "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" {\"address\":true,...} )\n" "\nSend multiple times. Amounts are double-precision floating point numbers." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" @@ -862,6 +872,14 @@ Value sendmany(const Array& params, bool fHelp) " }\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" "4. \"comment\" (string, optional) A comment\n" + "5. subtractfeefromamount (string, optional) A json object with addresses and booleans.\n" + " The fee will be equally deducted from the amount of each selected address.\n" + " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" + " Default for each address is false. If no addresses are specified here, the sender pays the fee.\n" + " {\n" + " \"address\":true (boolean) Subtract fee from this address\n" + " ,...\n" + " }\n" "\nResult:\n" "\"transactionid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n" " the number of addresses.\n" @@ -870,6 +888,8 @@ Value sendmany(const Array& params, bool fHelp) + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + "\nSend two amounts to two different addresses setting the confirmation and comment:\n" + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + + "\nSend two amounts to two different addresses, subtract fee from amount:\n" + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":true,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":true}\"") + "\nAs a json rpc call\n" + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") ); @@ -887,8 +907,12 @@ Value sendmany(const Array& params, bool fHelp) if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); + Object subtractFeeFromAmount; + if (params.size() > 4) + subtractFeeFromAmount = params[4].get_obj(); + set setAddress; - vector > vecSend; + vector vecSend; CAmount totalAmount = 0; BOOST_FOREACH(const Pair& s, sendTo) @@ -905,7 +929,13 @@ Value sendmany(const Array& params, bool fHelp) CAmount nAmount = AmountFromValue(s.value_); totalAmount += nAmount; - vecSend.push_back(make_pair(scriptPubKey, nAmount)); + bool fSubtractFeeFromAmount = false; + BOOST_FOREACH(const Pair& s2, subtractFeeFromAmount) + if (s2.name_ == s.name_ && s2.value_.get_bool() == true) + fSubtractFeeFromAmount = true; + + CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount}; + vecSend.push_back(recipient); } EnsureWalletIsUnlocked(); @@ -918,8 +948,9 @@ Value sendmany(const Array& params, bool fHelp) // Send CReserveKey keyChange(pwalletMain); CAmount nFeeRequired = 0; + int nChangePosRet = -1; string strFailReason; - bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason); + bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason); if (!fCreated) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason); if (!pwalletMain->CommitTransaction(wtx, keyChange)) diff --git a/src/wallet.cpp b/src/wallet.cpp index b51c4d4b14a..9dfd34de9f4 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1549,21 +1549,22 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set >& vecSend, - CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) +bool CWallet::CreateTransaction(const vector& vecSend, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl) { CAmount nValue = 0; - BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend) + unsigned int nSubtractFeeFromAmount = 0; + BOOST_FOREACH (const CRecipient& recipient, vecSend) { - if (nValue < 0) + if (nValue < 0 || recipient.nAmount < 0) { strFailReason = _("Transaction amounts must be positive"); return false; } - nValue += s.second; + nValue += recipient.nAmount; + + if (recipient.fSubtractFeeFromAmount) + nSubtractFeeFromAmount++; } if (vecSend.empty() || nValue < 0) { @@ -1606,16 +1607,40 @@ bool CWallet::CreateTransaction(const vector >& vecSend, txNew.vin.clear(); txNew.vout.clear(); wtxNew.fFromMe = true; + nChangePosRet = -1; + bool fFirst = true; - CAmount nTotalValue = nValue + nFeeRet; + CAmount nTotalValue = nValue; + if (nSubtractFeeFromAmount == 0) + nTotalValue += nFeeRet; double dPriority = 0; // vouts to the payees - BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend) + BOOST_FOREACH (const CRecipient& recipient, vecSend) { - CTxOut txout(s.second, s.first); + CTxOut txout(recipient.nAmount, recipient.scriptPubKey); + + if (recipient.fSubtractFeeFromAmount) + { + txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient + + if (fFirst) // first receiver pays the remainder not divisible by output count + { + fFirst = false; + txout.nValue -= nFeeRet % nSubtractFeeFromAmount; + } + } + if (txout.IsDust(::minRelayTxFee)) { - strFailReason = _("Transaction amount too small"); + if (recipient.fSubtractFeeFromAmount && nFeeRet > 0) + { + if (txout.nValue < 0) + strFailReason = _("The transaction amount is too small to pay the fee"); + else + strFailReason = _("The transaction amount is too small to send after the fee has been deducted"); + } + else + strFailReason = _("Transaction amount too small"); return false; } txNew.vout.push_back(txout); @@ -1642,7 +1667,9 @@ bool CWallet::CreateTransaction(const vector >& vecSend, dPriority += (double)nCredit * age; } - CAmount nChange = nValueIn - nValue - nFeeRet; + CAmount nChange = nValueIn - nValue; + if (nSubtractFeeFromAmount == 0) + nChange -= nFeeRet; if (nChange > 0) { @@ -1676,6 +1703,28 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CTxOut newTxOut(nChange, scriptChange); + // We do not move dust-change to fees, because the sender would end up paying more than requested. + // This would be against the purpose of the all-inclusive feature. + // So instead we raise the change and deduct from the recipient. + if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee)) + { + CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue; + newTxOut.nValue += nDust; // raise change until no more dust + for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient + { + if (vecSend[i].fSubtractFeeFromAmount) + { + txNew.vout[i].nValue -= nDust; + if (txNew.vout[i].IsDust(::minRelayTxFee)) + { + strFailReason = _("The transaction amount is too small to send after the fee has been deducted"); + return false; + } + break; + } + } + } + // Never create dust outputs; if we would, just // add the dust to the fee. if (newTxOut.IsDust(::minRelayTxFee)) @@ -1686,7 +1735,8 @@ bool CWallet::CreateTransaction(const vector >& vecSend, else { // Insert change txn at random position: - vector::iterator position = txNew.vout.begin()+GetRandInt(txNew.vout.size()+1); + nChangePosRet = GetRandInt(txNew.vout.size()+1); + vector::iterator position = txNew.vout.begin()+nChangePosRet; txNew.vout.insert(position, newTxOut); } } @@ -1755,15 +1805,8 @@ bool CWallet::CreateTransaction(const vector >& vecSend, } } } - return true; -} -bool CWallet::CreateTransaction(CScript scriptPubKey, const CAmount& nValue, - CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) -{ - vector< pair > vecSend; - vecSend.push_back(make_pair(scriptPubKey, nValue)); - return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl); + return true; } /** diff --git a/src/wallet.h b/src/wallet.h index 6ed87d1e687..a5a2558f94b 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -103,6 +103,12 @@ public: StringMap destdata; }; +struct CRecipient +{ + CScript scriptPubKey; + CAmount nAmount; + bool fSubtractFeeFromAmount; +}; typedef std::map mapValue_t; @@ -611,10 +617,8 @@ public: CAmount GetWatchOnlyBalance() const; CAmount GetUnconfirmedWatchOnlyBalance() const; CAmount GetImmatureWatchOnlyBalance() const; - bool CreateTransaction(const std::vector >& vecSend, - CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); - bool CreateTransaction(CScript scriptPubKey, const CAmount& nValue, - CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); + bool CreateTransaction(const std::vector& vecSend, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); static CFeeRate minTxFee; From 40a757331af84135e9c451ebe490b5a87c780944 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 5 Mar 2015 13:30:15 +0000 Subject: [PATCH 0317/2337] rpcwallet/sendmany: Just take an array of addresses to subtract fees from, rather than an Object with all values being identical --- src/rpcwallet.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 142487bc8cc..5502b0b261d 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -860,7 +860,7 @@ Value sendmany(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( - "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" {\"address\":true,...} )\n" + "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n" "\nSend multiple times. Amounts are double-precision floating point numbers." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" @@ -872,14 +872,14 @@ Value sendmany(const Array& params, bool fHelp) " }\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" "4. \"comment\" (string, optional) A comment\n" - "5. subtractfeefromamount (string, optional) A json object with addresses and booleans.\n" + "5. subtractfeefromamount (string, optional) A json array with addresses.\n" " The fee will be equally deducted from the amount of each selected address.\n" " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" - " Default for each address is false. If no addresses are specified here, the sender pays the fee.\n" - " {\n" - " \"address\":true (boolean) Subtract fee from this address\n" + " If no addresses are specified here, the sender pays the fee.\n" + " [\n" + " \"address\" (string) Subtract fee from this address\n" " ,...\n" - " }\n" + " ]\n" "\nResult:\n" "\"transactionid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n" " the number of addresses.\n" @@ -889,7 +889,7 @@ Value sendmany(const Array& params, bool fHelp) "\nSend two amounts to two different addresses setting the confirmation and comment:\n" + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + "\nSend two amounts to two different addresses, subtract fee from amount:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":true,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":true}\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") + "\nAs a json rpc call\n" + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") ); @@ -907,9 +907,9 @@ Value sendmany(const Array& params, bool fHelp) if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); - Object subtractFeeFromAmount; + Array subtractFeeFromAmount; if (params.size() > 4) - subtractFeeFromAmount = params[4].get_obj(); + subtractFeeFromAmount = params[4].get_array(); set setAddress; vector vecSend; @@ -930,8 +930,8 @@ Value sendmany(const Array& params, bool fHelp) totalAmount += nAmount; bool fSubtractFeeFromAmount = false; - BOOST_FOREACH(const Pair& s2, subtractFeeFromAmount) - if (s2.name_ == s.name_ && s2.value_.get_bool() == true) + BOOST_FOREACH(const Value& addr, subtractFeeFromAmount) + if (addr.get_str() == s.name_) fSubtractFeeFromAmount = true; CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount}; From 1d9b378c3071293a31a3b4d1845d9626f10da432 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 5 Mar 2015 13:59:19 +0000 Subject: [PATCH 0318/2337] qa/rpc-tests/wallet: Tests for sendmany --- qa/rpc-tests/wallet.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 84d30239969..dc4e0f77bd4 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -102,7 +102,7 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[2].getbalance(), 100) assert_equal(self.nodes[2].getbalance("from1"), 100-21) - # Send 10 XBT normal + # Send 10 BTC normal address = self.nodes[0].getnewaddress("test") self.nodes[2].settxfee(Decimal('0.001')) txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) @@ -111,12 +111,26 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000')) assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000')) - # Send 10 XBT with subtract fee from amount + # Send 10 BTC with subtract fee from amount txid = self.nodes[2].sendtoaddress(address, 10, "", "", True) self.nodes[2].setgenerate(True, 1) self.sync_all() assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000')) assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000')) + # Sendmany 10 BTC + txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", []) + self.nodes[2].setgenerate(True, 1) + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('69.99800000')) + assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000')) + + # Sendmany 10 BTC with subtract fee from amount + txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address]) + self.nodes[2].setgenerate(True, 1) + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')) + assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000')) + if __name__ == '__main__': WalletTest ().main () From 5abe2cf1107689598b9f0754801e3b27108a85f2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 5 Dec 2014 10:45:29 +0100 Subject: [PATCH 0319/2337] Reorder travis builds for faster response --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9c18729b42a..44ea7b62d7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,18 +27,18 @@ matrix: include: - compiler: ": ARM" env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" + - compiler: ": Win32" + env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" + - compiler: ": 32-bit + dash" + env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" + - compiler: ": Win64" + env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": bitcoind" env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: ": No wallet" env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - compiler: ": Cross-Mac" env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" - - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - - compiler: ": Win32" - env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" install: - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi From 8b60808c1eaddb402a699ba53d865932e08109ec Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 13 Mar 2015 15:40:53 +0100 Subject: [PATCH 0320/2337] [QT] some mac specifiy cleanup (memory handling, unnecessary code) --- src/qt/bitcoingui.cpp | 2 +- src/qt/macdockiconhandler.h | 9 +-------- src/qt/macdockiconhandler.mm | 6 +++++- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 1ec968ff2be..58c005ae75b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -237,7 +237,7 @@ BitcoinGUI::~BitcoinGUI() trayIcon->hide(); #ifdef Q_OS_MAC delete appMenuBar; - MacDockIconHandler::instance()->setMainWindow(NULL); + MacDockIconHandler::cleanup(); #endif delete rpcConsole; diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 1217bd8e88a..15a6583ca44 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -14,12 +14,6 @@ class QMenu; class QWidget; QT_END_NAMESPACE -#ifdef __OBJC__ -@class DockIconClickEventHandler; -#else -class DockIconClickEventHandler; -#endif - /** Macintosh-specific dock icon handler. */ class MacDockIconHandler : public QObject @@ -33,7 +27,7 @@ public: void setIcon(const QIcon &icon); void setMainWindow(QMainWindow *window); static MacDockIconHandler *instance(); - + static void cleanup(); void handleDockIconClickEvent(); signals: @@ -42,7 +36,6 @@ signals: private: MacDockIconHandler(); - DockIconClickEventHandler *m_dockIconClickEventHandler; QWidget *m_dummyWidget; QMenu *m_dockMenu; QMainWindow *mainWindow; diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 564fd0353e9..58a0365d3dc 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -68,7 +68,6 @@ void MacDockIconHandler::setMainWindow(QMainWindow *window) { MacDockIconHandler::~MacDockIconHandler() { - [this->m_dockIconClickEventHandler release]; delete this->m_dummyWidget; this->setMainWindow(NULL); } @@ -118,6 +117,11 @@ MacDockIconHandler *MacDockIconHandler::instance() return s_instance; } +void MacDockIconHandler::cleanup() +{ + delete s_instance; +} + void MacDockIconHandler::handleDockIconClickEvent() { if (this->mainWindow) From cd3d67cf3b0d573d2c387c2ec35e8b52129863d9 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 12 Mar 2015 16:03:23 -0400 Subject: [PATCH 0321/2337] Fix InvalidateBlock to add chainActive.Tip to setBlockIndexCandidates --- qa/rpc-tests/invalidateblock.py | 29 +++++++++++++++++++++++++++-- src/main.cpp | 2 +- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py index a8bfbe6e6c7..ccfcf00e30e 100755 --- a/qa/rpc-tests/invalidateblock.py +++ b/qa/rpc-tests/invalidateblock.py @@ -16,15 +16,17 @@ class InvalidateTest(BitcoinTestFramework): def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 2) + initialize_chain_clean(self.options.tmpdir, 3) def setup_network(self): self.nodes = [] self.is_network_split = False self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"])) def run_test(self): + print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:" print "Mine 4 blocks on Node 0" self.nodes[0].setgenerate(True, 4) assert(self.nodes[0].getblockcount() == 4) @@ -36,7 +38,7 @@ class InvalidateTest(BitcoinTestFramework): print "Connect nodes to force a reorg" connect_nodes_bi(self.nodes,0,1) - sync_blocks(self.nodes) + sync_blocks(self.nodes[0:2]) assert(self.nodes[0].getblockcount() == 6) badhash = self.nodes[1].getblockhash(2) @@ -47,5 +49,28 @@ class InvalidateTest(BitcoinTestFramework): if (newheight != 4 or newhash != besthash): raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight)) + print "\nMake sure we won't reorg to a lower work chain:" + connect_nodes_bi(self.nodes,1,2) + print "Sync node 2 to node 1 so both have 6 blocks" + sync_blocks(self.nodes[1:3]) + assert(self.nodes[2].getblockcount() == 6) + print "Invalidate block 5 on node 1 so its tip is now at 4" + self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5)) + assert(self.nodes[1].getblockcount() == 4) + print "Invalidate block 3 on node 2, so its tip is now 2" + self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3)) + assert(self.nodes[2].getblockcount() == 2) + print "..and then mine a block" + self.nodes[2].setgenerate(True, 1) + print "Verify all nodes are at the right height" + time.sleep(5) + for i in xrange(3): + print i,self.nodes[i].getblockcount() + assert(self.nodes[2].getblockcount() == 3) + assert(self.nodes[0].getblockcount() == 4) + node1height = self.nodes[1].getblockcount() + if node1height < 4: + raise AssertionError("Node 1 reorged to a lower height: %d"%node1height) + if __name__ == '__main__': InvalidateTest().main() diff --git a/src/main.cpp b/src/main.cpp index 9b4bb431283..5207f608969 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2310,7 +2310,7 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { // add them again. BlockMap::iterator it = mapBlockIndex.begin(); while (it != mapBlockIndex.end()) { - if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) { + if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) { setBlockIndexCandidates.insert(it->second); } it++; From bb44d9e7546e6118cd91db5bbe471a3ce2ee7fcd Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 16 Mar 2015 21:01:20 -0400 Subject: [PATCH 0322/2337] depends: fix a static qt5 crash when using certain versions of libxcb See here for background: https://bugreports.qt.io/browse/QTBUG-34748 libxcb temporarily had an abi breakage which caused crashes when qt was compiled against a non-compatible version. Building qt with -qt-xcb should have shielded us from this issue, except that incompatible headers were used when building qt's wrapper. Make sure those headers aren't picked up by qt's build. Details: qt's build adds a wrapper around the xcb libs when -qt-xcb is used. This is done to avoid having to link to a handful of different libs, which may not be api/abi stable. This build depends on include-order, so that its files are found before the real libxcb headers. Our build (for other reasons related to qt's complicated build-system) injects our prefix into CXXFLAGS. Because libxcb is found in this path, that reverses the include-order, negating the purpose of the wrapper. To fix, libxcb's includes are simply moved to a subdir. pkg-config ensures that they're still found properly when needed. To make things even more interesting, this behavior in qt's .pro files is broken: INCLUDEPATH += $$QMAKE_CFLAGS_XCB The INCLUDEPATH variable is processed by qmake which automatically prefixes each entry with "-I". The QMAKE_CFLAGS_XCB variable comes from pkg-config and already contains -I, making the path look like "-I-I/path/to/xcb/headers". To work around that, CFLAGS/CXXFLAGS are used here rather than INCLUDEPATH. --- depends/packages/libxcb.mk | 7 ++- .../patches/qt/fix-xcb-include-order.patch | 48 +++++++++++-------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index f29b577f8ac..28f2bd6f253 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -13,8 +13,13 @@ define $(package)_preprocess_cmds sed "s/pthread-stubs//" -i configure endef +# Don't install xcb headers to the default path in order to work around a qt +# build issue: https://bugreports.qt.io/browse/QTBUG-34748 +# When using qt's internal libxcb, it may end up finding the real headers in +# depends staging. Use a non-default path to avoid that. + define $(package)_config_cmds - $($(package)_autoconf) + $($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared endef define $(package)_build_cmds diff --git a/depends/patches/qt/fix-xcb-include-order.patch b/depends/patches/qt/fix-xcb-include-order.patch index bf6c6dca36c..3bdbba32a45 100644 --- a/depends/patches/qt/fix-xcb-include-order.patch +++ b/depends/patches/qt/fix-xcb-include-order.patch @@ -1,21 +1,31 @@ ---- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:17:27.384458441 -0400 -+++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:18:28.620459303 -0400 -@@ -101,10 +101,6 @@ - } - } - --DEFINES += $$QMAKE_DEFINES_XCB --LIBS += $$QMAKE_LIBS_XCB +--- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-03-17 02:06:42.705930685 +0000 ++++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-03-17 02:08:41.281926351 +0000 +@@ -103,7 +103,6 @@ + + DEFINES += $$QMAKE_DEFINES_XCB + LIBS += $$QMAKE_LIBS_XCB -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB -- + CONFIG += qpa/genericunixfontdatabase - - contains(QT_CONFIG, dbus) { -@@ -141,3 +137,7 @@ - INCLUDEPATH += ../../../3rdparty/xkbcommon/xkbcommon/ - } - } -+ -+DEFINES += $$QMAKE_DEFINES_XCB -+LIBS += $$QMAKE_LIBS_XCB -+INCLUDEPATH += $$QMAKE_CFLAGS_XCB + +@@ -118,7 +117,8 @@ + contains(QT_CONFIG, xcb-qt) { + DEFINES += XCB_USE_RENDER + XCB_DIR = ../../../3rdparty/xcb +- INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude ++ QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB ++ QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB + LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static + } else { + LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr +--- old/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:07:04.641929383 +0000 ++++ new/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:10:15.485922059 +0000 +@@ -8,7 +8,7 @@ + + XCB_DIR = ../../../../3rdparty/xcb + +-INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude ++QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB + + # ignore compiler warnings in 3rdparty code + QMAKE_CFLAGS_STATIC_LIB+=-w From 9c2737901b5203f267d21d728019d64b46f1d9f3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 5 Mar 2015 04:01:22 -0800 Subject: [PATCH 0323/2337] Reduce fingerprinting through timestamps in 'addr' messages. Suggested by Jonas Nick. --- src/addrman.cpp | 3 ++- src/main.cpp | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 1e08ae772ea..4b7e4d51b97 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -272,8 +272,9 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime) // update info info.nLastSuccess = nTime; info.nLastTry = nTime; - info.nTime = nTime; info.nAttempts = 0; + // nTime is not updated here, to avoid leaking information about + // currently-connected peers. // if it is already in the tried set, don't do anything else if (info.fInTried) diff --git a/src/main.cpp b/src/main.cpp index e16887fa4af..4eeb913d09f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -238,6 +238,10 @@ struct CBlockReject { * and we're no longer holding the node's locks. */ struct CNodeState { + //! The peer's address + CService address; + //! Whether we have a fully established connection. + bool fCurrentlyConnected; //! Accumulated misbehaviour score for this peer. int nMisbehavior; //! Whether this peer should be disconnected and banned (unless whitelisted). @@ -262,6 +266,7 @@ struct CNodeState { bool fPreferredDownload; CNodeState() { + fCurrentlyConnected = false; nMisbehavior = 0; fShouldBan = false; pindexBestKnownBlock = NULL; @@ -305,6 +310,7 @@ void InitializeNode(NodeId nodeid, const CNode *pnode) { LOCK(cs_main); CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second; state.name = pnode->addrName; + state.address = pnode->addr; } void FinalizeNode(NodeId nodeid) { @@ -314,6 +320,10 @@ void FinalizeNode(NodeId nodeid) { if (state->fSyncStarted) nSyncStarted--; + if (state->nMisbehavior == 0 && state->fCurrentlyConnected) { + AddressCurrentlyConnected(state->address); + } + BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight) mapBlocksInFlight.erase(entry.hash); EraseOrphansFor(nodeid); @@ -3628,6 +3638,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == "verack") { pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); + + // Mark this node as currently connected, so we update its timestamp later. + if (pfrom->fNetworkNode) { + LOCK(cs_main); + State(pfrom->GetId())->fCurrentlyConnected = true; + } } @@ -4272,11 +4288,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - // Update the last seen time for this node's address - if (pfrom->fNetworkNode) - if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping") - AddressCurrentlyConnected(pfrom->addr); - return true; } From d7d187e8a451ae946fa14cead7962edbe0046f12 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 22 Jan 2015 15:02:44 -0500 Subject: [PATCH 0324/2337] allocators: split allocators and pagelocker Pagelocker is only needed for secure (usually wallet) operations, so don't make the zero-after-free allocator depend on it. --- src/Makefile.am | 6 +- src/base58.h | 1 + src/crypter.h | 2 +- src/key.h | 2 +- src/qt/askpassphrasedialog.cpp | 2 +- src/qt/walletmodel.h | 2 +- src/streams.h | 2 +- src/support/allocators/secure.h | 62 ++++++++++++ src/support/allocators/zeroafterfree.h | 48 ++++++++++ .../pagelocker.cpp} | 6 +- src/{allocators.h => support/pagelocker.h} | 96 +------------------ src/test/allocator_tests.cpp | 2 +- 12 files changed, 129 insertions(+), 102 deletions(-) create mode 100644 src/support/allocators/secure.h create mode 100644 src/support/allocators/zeroafterfree.h rename src/{allocators.cpp => support/pagelocker.cpp} (94%) rename src/{allocators.h => support/pagelocker.h} (66%) diff --git a/src/Makefile.am b/src/Makefile.am index da65efa7132..4cefc541d09 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -72,7 +72,6 @@ endif BITCOIN_CORE_H = \ addrman.h \ alert.h \ - allocators.h \ amount.h \ arith_uint256.h \ base58.h \ @@ -123,7 +122,10 @@ BITCOIN_CORE_H = \ script/standard.h \ serialize.h \ streams.h \ + support/allocators/secure.h \ + support/allocators/zeroafterfree.h \ support/cleanse.h \ + support/pagelocker.h \ sync.h \ threadsafety.h \ timedata.h \ @@ -233,7 +235,6 @@ univalue_libbitcoin_univalue_a_SOURCES = \ # common: shared between bitcoind, and bitcoin-qt and non-server tools libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_common_a_SOURCES = \ - allocators.cpp \ arith_uint256.cpp \ amount.cpp \ base58.cpp \ @@ -264,6 +265,7 @@ libbitcoin_common_a_SOURCES = \ # backward-compatibility objects and their sanity checks are linked. libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_util_a_SOURCES = \ + support/pagelocker.cpp \ chainparamsbase.cpp \ clientversion.cpp \ compat/glibc_sanity.cpp \ diff --git a/src/base58.h b/src/base58.h index ed134e6e77a..8de90046a95 100644 --- a/src/base58.h +++ b/src/base58.h @@ -19,6 +19,7 @@ #include "pubkey.h" #include "script/script.h" #include "script/standard.h" +#include "support/allocators/zeroafterfree.h" #include #include diff --git a/src/crypter.h b/src/crypter.h index 8a91498e2e8..32746b00dfb 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -5,9 +5,9 @@ #ifndef BITCOIN_CRYPTER_H #define BITCOIN_CRYPTER_H -#include "allocators.h" #include "keystore.h" #include "serialize.h" +#include "support/allocators/secure.h" class uint256; diff --git a/src/key.h b/src/key.h index 85cc1e55db0..1f1d1428874 100644 --- a/src/key.h +++ b/src/key.h @@ -6,8 +6,8 @@ #ifndef BITCOIN_KEY_H #define BITCOIN_KEY_H -#include "allocators.h" #include "serialize.h" +#include "support/allocators/secure.h" #include "uint256.h" #include diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 9b7b59c0db3..229139e65cc 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -8,7 +8,7 @@ #include "guiconstants.h" #include "walletmodel.h" -#include "allocators.h" +#include "support/allocators/secure.h" #include #include diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index de915165f94..e263438880c 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -8,7 +8,7 @@ #include "paymentrequestplus.h" #include "walletmodeltransaction.h" -#include "allocators.h" /* for SecureString */ +#include "support/allocators/secure.h" #include #include diff --git a/src/streams.h b/src/streams.h index 9999c2341f7..fa1e18defe2 100644 --- a/src/streams.h +++ b/src/streams.h @@ -6,7 +6,7 @@ #ifndef BITCOIN_STREAMS_H #define BITCOIN_STREAMS_H -#include "allocators.h" +#include "support/allocators/zeroafterfree.h" #include "serialize.h" #include diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h new file mode 100644 index 00000000000..7a74d87bb49 --- /dev/null +++ b/src/support/allocators/secure.h @@ -0,0 +1,62 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_ALLOCATORS_SECURE_H +#define BITCOIN_ALLOCATORS_SECURE_H + +#include "support/pagelocker.h" + +#include + +// +// Allocator that locks its contents from being paged +// out of memory and clears its contents before deletion. +// +template +struct secure_allocator : public std::allocator { + // MSVC8 default copy constructor is broken + typedef std::allocator base; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + typedef typename base::value_type value_type; + secure_allocator() throw() {} + secure_allocator(const secure_allocator& a) throw() : base(a) {} + template + secure_allocator(const secure_allocator& a) throw() : base(a) + { + } + ~secure_allocator() throw() {} + template + struct rebind { + typedef secure_allocator<_Other> other; + }; + + T* allocate(std::size_t n, const void* hint = 0) + { + T* p; + p = std::allocator::allocate(n, hint); + if (p != NULL) + LockedPageManager::Instance().LockRange(p, sizeof(T) * n); + return p; + } + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) { + memory_cleanse(p, sizeof(T) * n); + LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n); + } + std::allocator::deallocate(p, n); + } +}; + +// This is exactly like std::string, but with a custom allocator. +typedef std::basic_string, secure_allocator > SecureString; + +#endif // BITCOIN_ALLOCATORS_SECURE_H diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h new file mode 100644 index 00000000000..b01fcd088bc --- /dev/null +++ b/src/support/allocators/zeroafterfree.h @@ -0,0 +1,48 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_ALLOCATORS_ZEROAFTERFREE_H +#define BITCOIN_ALLOCATORS_ZEROAFTERFREE_H + +#include "support/cleanse.h" + +#include +#include + +template +struct zero_after_free_allocator : public std::allocator { + // MSVC8 default copy constructor is broken + typedef std::allocator base; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + typedef typename base::value_type value_type; + zero_after_free_allocator() throw() {} + zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} + template + zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) + { + } + ~zero_after_free_allocator() throw() {} + template + struct rebind { + typedef zero_after_free_allocator<_Other> other; + }; + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) + memory_cleanse(p, sizeof(T) * n); + std::allocator::deallocate(p, n); + } +}; + +// Byte-vector that clears its contents before deletion. +typedef std::vector > CSerializeData; + +#endif // BITCOIN_ALLOCATORS_ZEROAFTERFREE_H diff --git a/src/allocators.cpp b/src/support/pagelocker.cpp similarity index 94% rename from src/allocators.cpp rename to src/support/pagelocker.cpp index d3958aa4d70..440e0a5193a 100644 --- a/src/allocators.cpp +++ b/src/support/pagelocker.cpp @@ -2,7 +2,11 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "allocators.h" +#include "support/pagelocker.h" + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif #ifdef WIN32 #ifdef _WIN32_WINNT diff --git a/src/allocators.h b/src/support/pagelocker.h similarity index 66% rename from src/allocators.h rename to src/support/pagelocker.h index 8ffe015b9e5..964be1aec41 100644 --- a/src/allocators.h +++ b/src/support/pagelocker.h @@ -3,15 +3,12 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_ALLOCATORS_H -#define BITCOIN_ALLOCATORS_H +#ifndef BITCOIN_ALLOCATORS_PAGELOCKER_H +#define BITCOIN_ALLOCATORS_PAGELOCKER_H #include "support/cleanse.h" #include -#include -#include -#include #include #include @@ -178,91 +175,4 @@ void UnlockObject(const T& t) LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T)); } -// -// Allocator that locks its contents from being paged -// out of memory and clears its contents before deletion. -// -template -struct secure_allocator : public std::allocator { - // MSVC8 default copy constructor is broken - typedef std::allocator base; - typedef typename base::size_type size_type; - typedef typename base::difference_type difference_type; - typedef typename base::pointer pointer; - typedef typename base::const_pointer const_pointer; - typedef typename base::reference reference; - typedef typename base::const_reference const_reference; - typedef typename base::value_type value_type; - secure_allocator() throw() {} - secure_allocator(const secure_allocator& a) throw() : base(a) {} - template - secure_allocator(const secure_allocator& a) throw() : base(a) - { - } - ~secure_allocator() throw() {} - template - struct rebind { - typedef secure_allocator<_Other> other; - }; - - T* allocate(std::size_t n, const void* hint = 0) - { - T* p; - p = std::allocator::allocate(n, hint); - if (p != NULL) - LockedPageManager::Instance().LockRange(p, sizeof(T) * n); - return p; - } - - void deallocate(T* p, std::size_t n) - { - if (p != NULL) { - memory_cleanse(p, sizeof(T) * n); - LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n); - } - std::allocator::deallocate(p, n); - } -}; - - -// -// Allocator that clears its contents before deletion. -// -template -struct zero_after_free_allocator : public std::allocator { - // MSVC8 default copy constructor is broken - typedef std::allocator base; - typedef typename base::size_type size_type; - typedef typename base::difference_type difference_type; - typedef typename base::pointer pointer; - typedef typename base::const_pointer const_pointer; - typedef typename base::reference reference; - typedef typename base::const_reference const_reference; - typedef typename base::value_type value_type; - zero_after_free_allocator() throw() {} - zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} - template - zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) - { - } - ~zero_after_free_allocator() throw() {} - template - struct rebind { - typedef zero_after_free_allocator<_Other> other; - }; - - void deallocate(T* p, std::size_t n) - { - if (p != NULL) - memory_cleanse(p, sizeof(T) * n); - std::allocator::deallocate(p, n); - } -}; - -// This is exactly like std::string, but with a custom allocator. -typedef std::basic_string, secure_allocator > SecureString; - -// Byte-vector that clears its contents before deletion. -typedef std::vector > CSerializeData; - -#endif // BITCOIN_ALLOCATORS_H +#endif // BITCOIN_ALLOCATORS_PAGELOCKER_H diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index d4df7b54157..2108efece51 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -4,7 +4,7 @@ #include "util.h" -#include "allocators.h" +#include "support/allocators/secure.h" #include "test/test_bitcoin.h" #include From 2bb1c87700a80f0b20b4b2cbd68a0d82a18dbcc0 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 4 Feb 2015 21:19:27 +0100 Subject: [PATCH 0325/2337] refactor: move bdb (bitdb) interaction from init.cpp to wallet.cpp this will remove db.h from init.cpp --- src/init.cpp | 57 ++++++++++--------------------------------- src/wallet/wallet.cpp | 53 ++++++++++++++++++++++++++++++++++++++++ src/wallet/wallet.h | 6 +++++ 3 files changed, 72 insertions(+), 44 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index a930a97a94f..95ec45015f6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -24,7 +24,6 @@ #include "util.h" #include "utilmoneystr.h" #ifdef ENABLE_WALLET -#include "wallet/db.h" #include "wallet/wallet.h" #include "wallet/walletdb.h" #endif @@ -151,7 +150,7 @@ void Shutdown() StopRPCThreads(); #ifdef ENABLE_WALLET if (pwalletMain) - bitdb.Flush(false); + pwalletMain->Flush(false); GenerateBitcoins(false, NULL, 0); #endif StopNode(); @@ -184,7 +183,7 @@ void Shutdown() } #ifdef ENABLE_WALLET if (pwalletMain) - bitdb.Flush(true); + pwalletMain->Flush(true); #endif #ifndef WIN32 boost::filesystem::remove(GetPidFile()); @@ -852,47 +851,17 @@ bool AppInit2(boost::thread_group& threadGroup) LogPrintf("Using wallet %s\n", strWalletFile); uiInterface.InitMessage(_("Verifying wallet...")); - if (!bitdb.Open(GetDataDir())) - { - // try moving the database env out of the way - boost::filesystem::path pathDatabase = GetDataDir() / "database"; - boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime()); - try { - boost::filesystem::rename(pathDatabase, pathDatabaseBak); - LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); - } catch (const boost::filesystem::filesystem_error&) { - // failure is ok (well, not really, but it's not worse than what we started with) - } - - // try again - if (!bitdb.Open(GetDataDir())) { - // if it still fails, it probably means we can't even create the database env - string msg = strprintf(_("Error initializing wallet database environment %s!"), strDataDir); - return InitError(msg); - } - } - - if (GetBoolArg("-salvagewallet", false)) - { - // Recover readable keypairs: - if (!CWalletDB::Recover(bitdb, strWalletFile, true)) - return false; - } - - if (boost::filesystem::exists(GetDataDir() / strWalletFile)) - { - CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover); - if (r == CDBEnv::RECOVER_OK) - { - string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!" - " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" - " your balance or transactions are incorrect you should" - " restore from a backup."), strDataDir); - InitWarning(msg); - } - if (r == CDBEnv::RECOVER_FAIL) - return InitError(_("wallet.dat corrupt, salvage failed")); - } + std::string warningString; + std::string errorString; + + if (!CWallet::Verify(strWalletFile, warningString, errorString)) + return false; + + if (!warningString.empty()) + InitWarning(warningString); + if (!errorString.empty()) + return InitError(warningString); + } // (!fDisableWallet) #endif // ENABLE_WALLET // ********************************************************* Step 6: network initialization diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index dd331092670..44b416d4965 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -18,6 +18,7 @@ #include #include +#include #include using namespace std; @@ -339,6 +340,58 @@ set CWallet::GetConflicts(const uint256& txid) const return result; } +void CWallet::Flush(bool shutdown) +{ + bitdb.Flush(shutdown); +} + +bool CWallet::Verify(const string walletFile, string& warningString, string& errorString) +{ + if (!bitdb.Open(GetDataDir())) + { + // try moving the database env out of the way + boost::filesystem::path pathDatabase = GetDataDir() / "database"; + boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime()); + try { + boost::filesystem::rename(pathDatabase, pathDatabaseBak); + LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); + } catch (const boost::filesystem::filesystem_error&) { + // failure is ok (well, not really, but it's not worse than what we started with) + } + + // try again + if (!bitdb.Open(GetDataDir())) { + // if it still fails, it probably means we can't even create the database env + string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir()); + errorString += msg; + return true; + } + } + + if (GetBoolArg("-salvagewallet", false)) + { + // Recover readable keypairs: + if (!CWalletDB::Recover(bitdb, walletFile, true)) + return false; + } + + if (boost::filesystem::exists(GetDataDir() / walletFile)) + { + CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); + if (r == CDBEnv::RECOVER_OK) + { + warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!" + " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" + " your balance or transactions are incorrect you should" + " restore from a backup."), GetDataDir()); + } + if (r == CDBEnv::RECOVER_FAIL) + errorString += _("wallet.dat corrupt, salvage failed"); + } + + return true; +} + void CWallet::SyncMetaData(pair range) { // We want all the wallet transactions in range to have the same metadata as diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b2973250a44..1a9feff9f37 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -743,6 +743,12 @@ public: //! Get wallet transactions that conflict with given transaction (spend same outputs) std::set GetConflicts(const uint256& txid) const; + //! Flush wallet (bitdb flush) + void Flush(bool shutdown=false); + + //! Verify the wallet database and perform salvage if required + static bool Verify(const std::string walletFile, std::string& warningString, std::string& errorString); + /** * Address book entry changed. * @note called with lock cs_wallet held. From e9c3215b776b07faeb5184249fc0e43876f26723 Mon Sep 17 00:00:00 2001 From: dexX7 Date: Fri, 19 Dec 2014 06:59:16 +0100 Subject: [PATCH 0326/2337] [Wallet] sort pending wallet transactions before reaccepting During startup, when adding pending wallet transactions, which spend outputs of other pending wallet transactions, back to the memory pool, and when they are added out of order, it appears as if they are orphans with missing inputs. Those transactions are then rejected and flagged as "conflicting" (= not in the memory pool, not in the block chain). To prevent this, transactions are explicitly sorted. --- src/wallet/wallet.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 44b416d4965..207bb8c97ab 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1028,6 +1028,9 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) void CWallet::ReacceptWalletTransactions() { LOCK2(cs_main, cs_wallet); + std::map mapSorted; + + // Sort pending wallet transactions based on their initial wallet insertion order BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) { const uint256& wtxid = item.first; @@ -1036,13 +1039,19 @@ void CWallet::ReacceptWalletTransactions() int nDepth = wtx.GetDepthInMainChain(); - if (!wtx.IsCoinBase() && nDepth < 0) - { - // Try to add to memory pool - LOCK(mempool.cs); - wtx.AcceptToMemoryPool(false); + if (!wtx.IsCoinBase() && nDepth < 0) { + mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx)); } } + + // Try to add wallet transactions to memory pool + BOOST_FOREACH(PAIRTYPE(const int64_t, CWalletTx*)& item, mapSorted) + { + CWalletTx& wtx = *(item.second); + + LOCK(mempool.cs); + wtx.AcceptToMemoryPool(false); + } } void CWalletTx::RelayWalletTransaction() From 18051c7fbd224e32d9a5fea96f1083210cea3a14 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 4 Nov 2014 10:06:20 -0800 Subject: [PATCH 0327/2337] Abstract out Ctransaction-specific signing into TransactionSignatureCreator --- src/script/sign.cpp | 91 +++++++++++++++++++++++++++------------------ src/script/sign.h | 41 ++++++++++++++++++-- 2 files changed, 91 insertions(+), 41 deletions(-) diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 14119f7e2cc..eab629cd913 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -17,22 +17,31 @@ using namespace std; typedef vector valtype; -bool Sign1(const CKeyID& address, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet) +TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {} + +bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& address, const CScript& scriptCode) const { CKey key; - if (!keystore.GetKey(address, key)) + if (!keystore->GetKey(address, key)) return false; - vector vchSig; + uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType); if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)nHashType); - scriptSigRet << vchSig; - return true; } -bool SignN(const vector& multisigdata, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet) +static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet) +{ + vector vchSig; + if (!creator.CreateSig(vchSig, address, scriptCode)) + return false; + scriptSigRet << vchSig; + return true; +} + +static bool SignN(const vector& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet) { int nSigned = 0; int nRequired = multisigdata.front()[0]; @@ -40,20 +49,20 @@ bool SignN(const vector& multisigdata, const CKeyStore& keystore, uint2 { const valtype& pubkey = multisigdata[i]; CKeyID keyID = CPubKey(pubkey).GetID(); - if (Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) + if (Sign1(keyID, creator, scriptCode, scriptSigRet)) ++nSigned; } return nSigned==nRequired; } /** - * Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type. + * Sign scriptPubKey using signature made with creator. * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. * Returns false if scriptPubKey could not be completely satisfied. */ -bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType, - CScript& scriptSigRet, txnouttype& whichTypeRet) +static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey, + CScript& scriptSigRet, txnouttype& whichTypeRet) { scriptSigRet.clear(); @@ -69,39 +78,32 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash return false; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); - return Sign1(keyID, keystore, hash, nHashType, scriptSigRet); + return Sign1(keyID, creator, scriptPubKey, scriptSigRet); case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); - if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) + if (!Sign1(keyID, creator, scriptPubKey, scriptSigRet)) return false; else { CPubKey vch; - keystore.GetPubKey(keyID, vch); + creator.KeyStore().GetPubKey(keyID, vch); scriptSigRet << ToByteVector(vch); } return true; case TX_SCRIPTHASH: - return keystore.GetCScript(uint160(vSolutions[0]), scriptSigRet); + return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet); case TX_MULTISIG: scriptSigRet << OP_0; // workaround CHECKMULTISIG bug - return (SignN(vSolutions, keystore, hash, nHashType, scriptSigRet)); + return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet)); } return false; } -bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType) +bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, CScript& scriptSig) { - assert(nIn < txTo.vin.size()); - CTxIn& txin = txTo.vin[nIn]; - - // Leave out the signature from the hash, since a signature can't sign itself. - // The checksig op will also drop the signatures from its hash. - uint256 hash = SignatureHash(fromPubKey, txTo, nIn, nHashType); - txnouttype whichType; - if (!Solver(keystore, fromPubKey, hash, nHashType, txin.scriptSig, whichType)) + if (!SignStep(creator, fromPubKey, scriptSig, whichType)) return false; if (whichType == TX_SCRIPTHASH) @@ -109,21 +111,29 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl // Solver returns the subscript that need to be evaluated; // the final scriptSig is the signatures from that // and then the serialized subscript: - CScript subscript = txin.scriptSig; - - // Recompute txn hash using subscript in place of scriptPubKey: - uint256 hash2 = SignatureHash(subscript, txTo, nIn, nHashType); + CScript subscript = scriptSig; txnouttype subType; bool fSolved = - Solver(keystore, subscript, hash2, nHashType, txin.scriptSig, subType) && subType != TX_SCRIPTHASH; + SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH; // Append serialized subscript whether or not it is completely signed: - txin.scriptSig << static_cast(subscript); + scriptSig << static_cast(subscript); if (!fSolved) return false; } // Test solution - return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&txTo, nIn)); + return VerifyScript(scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()); +} + +bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType) +{ + assert(nIn < txTo.vin.size()); + CTxIn& txin = txTo.vin[nIn]; + + CTransaction txToConst(txTo); + TransactionSignatureCreator creator(&keystore, &txToConst, nIn, nHashType); + + return ProduceSignature(creator, fromPubKey, txin.scriptSig); } bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType) @@ -144,7 +154,7 @@ static CScript PushAll(const vector& values) return result; } -static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, +static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const vector& vSolutions, const vector& sigs1, const vector& sigs2) { @@ -174,7 +184,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey - if (TransactionSignatureChecker(&txTo, nIn).CheckSig(sig, pubkey, scriptPubKey)) + if (checker.CheckSig(sig, pubkey, scriptPubKey)) { sigs[pubkey] = sig; break; @@ -199,7 +209,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& return result; } -static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, +static CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const txnouttype txType, const vector& vSolutions, vector& sigs1, vector& sigs2) { @@ -233,12 +243,12 @@ static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction Solver(pubKey2, txType2, vSolutions2); sigs1.pop_back(); sigs2.pop_back(); - CScript result = CombineSignatures(pubKey2, txTo, nIn, txType2, vSolutions2, sigs1, sigs2); + CScript result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2); result << spk; return result; } case TX_MULTISIG: - return CombineMultisig(scriptPubKey, txTo, nIn, vSolutions, sigs1, sigs2); + return CombineMultisig(scriptPubKey, checker, vSolutions, sigs1, sigs2); } return CScript(); @@ -246,6 +256,13 @@ static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2) +{ + TransactionSignatureChecker checker(&txTo, nIn); + return CombineSignatures(scriptPubKey, checker, scriptSig1, scriptSig2); +} + +CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, + const CScript& scriptSig1, const CScript& scriptSig2) { txnouttype txType; vector > vSolutions; @@ -256,5 +273,5 @@ CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, vector stack2; EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); - return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2); + return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2); } diff --git a/src/script/sign.h b/src/script/sign.h index e197d5fab37..0c4cf61e5e7 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -8,19 +8,52 @@ #include "script/interpreter.h" +class CKeyID; class CKeyStore; class CScript; class CTransaction; struct CMutableTransaction; +/** Virtual base class for signature creators. */ +class BaseSignatureCreator { +protected: + const CKeyStore* keystore; + +public: + BaseSignatureCreator(const CKeyStore* keystoreIn) : keystore(keystoreIn) {} + const CKeyStore& KeyStore() const { return *keystore; }; + virtual ~BaseSignatureCreator() {} + virtual const BaseSignatureChecker& Checker() const =0; + + /** Create a singular (non-script) signature. */ + virtual bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const =0; +}; + +/** A signature creator for transactions. */ +class TransactionSignatureCreator : public BaseSignatureCreator { + const CTransaction* txTo; + unsigned int nIn; + int nHashType; + const TransactionSignatureChecker checker; + +public: + TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn=SIGHASH_ALL); + const BaseSignatureChecker& Checker() const { return checker; } + bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const; +}; + +/** Produce a script signature using a generic signature creator. */ +bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, CScript& scriptSig); + +/** Produce a script signature for a transaction. */ bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); -/** - * Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders, - * combine them intelligently and return the result. - */ +/** Combine two script signatures using a generic signature checker, intelligently, possibly with OP_0 placeholders. */ +CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const CScript& scriptSig1, const CScript& scriptSig2); + +/** Combine two script signatures on transactions. */ CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); #endif // BITCOIN_SCRIPT_SIGN_H From 341e2385d543ba96ae4d4eac649e9312537e1405 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sat, 21 Mar 2015 18:40:51 +0100 Subject: [PATCH 0328/2337] use constant references for strings in functions in wallet/*.* --- src/wallet/db.cpp | 4 ++-- src/wallet/db.h | 4 ++-- src/wallet/wallet.cpp | 2 +- src/wallet/wallet.h | 2 +- src/wallet/walletdb.cpp | 4 ++-- src/wallet/walletdb.h | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 36946b7dcca..53cfcf0961a 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -148,7 +148,7 @@ void CDBEnv::MakeMock() fMockDb = true; } -CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)) +CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFunc)(CDBEnv& dbenv, const std::string& strFile)) { LOCK(cs_db); assert(mapFileUseCount.count(strFile) == 0); @@ -165,7 +165,7 @@ CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDB return (fRecovered ? RECOVER_OK : RECOVER_FAIL); } -bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vector& vResult) +bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector& vResult) { LOCK(cs_db); assert(mapFileUseCount.count(strFile) == 0); diff --git a/src/wallet/db.h b/src/wallet/db.h index 71133f96991..0c2c139d89e 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -59,7 +59,7 @@ public: enum VerifyResult { VERIFY_OK, RECOVER_OK, RECOVER_FAIL }; - VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)); + VerifyResult Verify(const std::string& strFile, bool (*recoverFunc)(CDBEnv& dbenv, const std::string& strFile)); /** * Salvage data from a file that Verify says is bad. * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation). @@ -68,7 +68,7 @@ public: * for huge databases. */ typedef std::pair, std::vector > KeyValPair; - bool Salvage(std::string strFile, bool fAggressive, std::vector& vResult); + bool Salvage(const std::string& strFile, bool fAggressive, std::vector& vResult); bool Open(const boost::filesystem::path& path); void Close(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 44b416d4965..167639b53d7 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -345,7 +345,7 @@ void CWallet::Flush(bool shutdown) bitdb.Flush(shutdown); } -bool CWallet::Verify(const string walletFile, string& warningString, string& errorString) +bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString) { if (!bitdb.Open(GetDataDir())) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 1a9feff9f37..f00fb0caffc 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -747,7 +747,7 @@ public: void Flush(bool shutdown=false); //! Verify the wallet database and perform salvage if required - static bool Verify(const std::string walletFile, std::string& warningString, std::string& errorString); + static bool Verify(const std::string& walletFile, std::string& warningString, std::string& errorString); /** * Address book entry changed. diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 880026d187c..d7f70e435ea 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -891,7 +891,7 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) // // Try to (very carefully!) recover wallet.dat if there is a problem. // -bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) +bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys) { // Recovery procedure: // move wallet.dat to wallet.timestamp.bak @@ -968,7 +968,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) return fSuccess; } -bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename) +bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename) { return CWalletDB::Recover(dbenv, filename, false); } diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 6aa0fa40df0..a1c38b9d3d3 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -127,8 +127,8 @@ public: DBErrors LoadWallet(CWallet* pwallet); DBErrors FindWalletTx(CWallet* pwallet, std::vector& vTxHash, std::vector& vWtx); DBErrors ZapWalletTx(CWallet* pwallet, std::vector& vWtx); - static bool Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys); - static bool Recover(CDBEnv& dbenv, std::string filename); + static bool Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys); + static bool Recover(CDBEnv& dbenv, const std::string& filename); private: CWalletDB(const CWalletDB&); From 5983a4e50f2c3f53024d9a5cecab69f67c882cca Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 10 Mar 2015 11:33:46 -0700 Subject: [PATCH 0329/2337] Add a NODE_GETUTXO service bit and document NODE_NETWORK. Stop translating the NODE_* names as they are technical and cannot be translated. --- src/protocol.h | 7 +++++++ src/qt/guiutil.cpp | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/protocol.h b/src/protocol.h index e838c0d3638..fd23eae1fc6 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -67,7 +67,14 @@ public: /** nServices flags */ enum { + // NODE_NETWORK means that the node is capable of serving the block chain. It is currently + // set by all Bitcoin Core nodes, and is unset by SPV clients or other peers that just want + // network services but don't provide them. NODE_NETWORK = (1 << 0), + // NODE_GETUTXO means the node is capable of responding to the getutxo protocol request. + // Bitcoin Core does not support this but a patch set called Bitcoin XT does. + // See BIP 64 for details on how this is implemented. + NODE_GETUTXO = (1 << 1), // Bits 24-31 are reserved for temporary experiments. Just pick a bit that // isn't getting used, or one not being used much, and notify the diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 9db0a75971a..a5ee81db6c0 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -878,10 +878,13 @@ QString formatServicesStr(quint64 mask) switch (check) { case NODE_NETWORK: - strList.append(QObject::tr("NETWORK")); + strList.append("NETWORK"); + break; + case NODE_GETUTXO: + strList.append("GETUTXO"); break; default: - strList.append(QString("%1[%2]").arg(QObject::tr("UNKNOWN")).arg(check)); + strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check)); } } } From 9d086c01bc33fc264c7d32e69bc42b636439b626 Mon Sep 17 00:00:00 2001 From: CohibAA Date: Sat, 21 Mar 2015 20:05:17 -0600 Subject: [PATCH 0330/2337] Update bitcoin.conf --- contrib/debian/examples/bitcoin.conf | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/contrib/debian/examples/bitcoin.conf b/contrib/debian/examples/bitcoin.conf index 31cca981e0a..ade80d60ea0 100644 --- a/contrib/debian/examples/bitcoin.conf +++ b/contrib/debian/examples/bitcoin.conf @@ -13,6 +13,12 @@ # Connect via a SOCKS5 proxy #proxy=127.0.0.1:9050 +# Bind to given address and always listen on it. Use [host]:port notation for IPv6 +#bind= + +# Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 +#whitebind= + ############################################################## ## Quick Primer on addnode vs connect ## ## Let's say for instance you use addnode=4.2.2.4 ## @@ -57,6 +63,10 @@ # server=1 tells Bitcoin-QT and bitcoind to accept JSON-RPC commands #server=0 +# Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. +# This option can be specified multiple times (default: bind to all interfaces) +#rpcbind= + # You must set rpcuser and rpcpassword to secure the JSON-RPC api #rpcuser=Ulysseys #rpcpassword=YourSuperGreatPasswordNumber_DO_NOT_USE_THIS_OR_YOU_WILL_GET_ROBBED_385593 @@ -94,6 +104,14 @@ #rpcsslcertificatechainfile=server.cert #rpcsslprivatekeyfile=server.pem +# Transaction Fee Changes in 0.10.0 + +# Send transactions as zero-fee transactions if possible (default: 0) +#sendfreetransactions=0 + +# Create transactions that have enough fees (or priority) so they are likely to begin confirmation within n blocks (default: 1). +# This setting is over-ridden by the -paytxfee option. +#txconfirmtarget=n # Miscellaneous options From a354a59f1f3d08be148a99fa53d8cf76e6b7a784 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Sun, 22 Mar 2015 15:18:55 -0400 Subject: [PATCH 0331/2337] wallet: move crypter to wallet --- src/Makefile.am | 4 ++-- src/keystore.cpp | 1 - src/{ => wallet}/crypter.cpp | 0 src/{ => wallet}/crypter.h | 0 src/wallet/wallet.h | 2 +- 5 files changed, 3 insertions(+), 4 deletions(-) rename src/{ => wallet}/crypter.cpp (100%) rename src/{ => wallet}/crypter.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index d1a8efaa6ac..2c607c632e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -88,7 +88,6 @@ BITCOIN_CORE_H = \ compat.h \ compressor.h \ core_io.h \ - crypter.h \ wallet/db.h \ eccryptoverify.h \ ecwrapper.h \ @@ -140,6 +139,7 @@ BITCOIN_CORE_H = \ utilstrencodings.h \ utiltime.h \ version.h \ + wallet/crypter.h \ wallet/walletdb.h \ wallet/wallet.h \ wallet/wallet_ismine.h \ @@ -198,8 +198,8 @@ libbitcoin_server_a_SOURCES = \ # when wallet enabled libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_wallet_a_SOURCES = \ + wallet/crypter.cpp \ wallet/db.cpp \ - crypter.cpp \ wallet/rpcdump.cpp \ wallet/rpcwallet.cpp \ wallet/wallet.cpp \ diff --git a/src/keystore.cpp b/src/keystore.cpp index 7531737e04d..3bae24b7b94 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -5,7 +5,6 @@ #include "keystore.h" -#include "crypter.h" #include "key.h" #include "util.h" diff --git a/src/crypter.cpp b/src/wallet/crypter.cpp similarity index 100% rename from src/crypter.cpp rename to src/wallet/crypter.cpp diff --git a/src/crypter.h b/src/wallet/crypter.h similarity index 100% rename from src/crypter.h rename to src/wallet/crypter.h diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 1a9feff9f37..fbcb56685e5 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -9,11 +9,11 @@ #include "amount.h" #include "primitives/block.h" #include "primitives/transaction.h" -#include "crypter.h" #include "key.h" #include "keystore.h" #include "main.h" #include "ui_interface.h" +#include "wallet/crypter.h" #include "wallet/wallet_ismine.h" #include "wallet/walletdb.h" From b23add5521e4207085d41a0266617e94435fc22e Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 8 Mar 2015 06:30:05 -0700 Subject: [PATCH 0332/2337] Switch addrman key from vector to uint256 --- src/addrman.cpp | 14 ++++++++------ src/addrman.h | 21 +++++++++++++++------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 4b7e4d51b97..0c09a244701 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -10,30 +10,30 @@ using namespace std; -int CAddrInfo::GetTriedBucket(const std::vector& nKey) const +int CAddrInfo::GetTriedBucket(const uint256& nKey) const { CDataStream ss1(SER_GETHASH, 0); std::vector vchKey = GetKey(); - ss1 << nKey << vchKey; + ss1 << ((unsigned char)32) << nKey << vchKey; uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); CDataStream ss2(SER_GETHASH, 0); std::vector vchGroupKey = GetGroup(); - ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); + ss2 << ((unsigned char)32) << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; } -int CAddrInfo::GetNewBucket(const std::vector& nKey, const CNetAddr& src) const +int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src) const { CDataStream ss1(SER_GETHASH, 0); std::vector vchGroupKey = GetGroup(); std::vector vchSourceGroupKey = src.GetGroup(); - ss1 << nKey << vchGroupKey << vchSourceGroupKey; + ss1 << ((unsigned char)32) << nKey << vchGroupKey << vchSourceGroupKey; uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); CDataStream ss2(SER_GETHASH, 0); - ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); + ss2 << ((unsigned char)32) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); return hash2 % ADDRMAN_NEW_BUCKET_COUNT; } @@ -483,6 +483,8 @@ int CAddrMan::Check_() return -13; if (mapNew.size()) return -15; + if (nKey.IsNull()) + return -16; return 0; } diff --git a/src/addrman.h b/src/addrman.h index d47217683c7..04c7b32eafa 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -10,6 +10,7 @@ #include "random.h" #include "sync.h" #include "timedata.h" +#include "uint256.h" #include "util.h" #include @@ -79,13 +80,13 @@ public: } //! Calculate in which "tried" bucket this entry belongs - int GetTriedBucket(const std::vector &nKey) const; + int GetTriedBucket(const uint256 &nKey) const; //! Calculate in which "new" bucket this entry belongs, given a certain source - int GetNewBucket(const std::vector &nKey, const CNetAddr& src) const; + int GetNewBucket(const uint256 &nKey, const CNetAddr& src) const; //! Calculate in which "new" bucket this entry belongs, using its default source - int GetNewBucket(const std::vector &nKey) const + int GetNewBucket(const uint256 &nKey) const { return GetNewBucket(nKey, source); } @@ -176,7 +177,7 @@ private: mutable CCriticalSection cs; //! secret key to randomize bucket select with - std::vector nKey; + uint256 nKey; //! last used nId int nIdCount; @@ -284,6 +285,7 @@ public: unsigned char nVersion = 0; s << nVersion; + s << ((unsigned char)32); s << nKey; s << nNew; s << nTried; @@ -328,6 +330,9 @@ public: unsigned char nVersion; s >> nVersion; + unsigned char nKeySize; + s >> nKeySize; + if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman"); s >> nKey; s >> nNew; s >> nTried; @@ -393,14 +398,18 @@ public: CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set()) { - nKey.resize(32); - GetRandBytes(&nKey[0], 32); + nKey = GetRandHash(); nIdCount = 0; nTried = 0; nNew = 0; } + ~CAddrMan() + { + nKey.SetNull(); + } + //! Return the number of (unique) addresses in all tables. int size() { From e6b343d880f50d52390c5af8623afa15fcbc65a2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 18 Mar 2015 09:31:49 -0700 Subject: [PATCH 0333/2337] Make addrman's bucket placement deterministic. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Give each address a single fixed location in the new and tried tables, which become simple fixed-size arrays instead of sets and vectors. This prevents attackers from having an advantages by inserting an address multiple times. This change was suggested as Countermeasure 1 in Eclipse Attacks on Bitcoin’s Peer-to-Peer Network, Ethan Heilman, Alison Kendler, Aviv Zohar, Sharon Goldberg. ePrint Archive Report 2015/263. March 2015. It is also more efficient. --- src/addrman.cpp | 268 ++++++++++++++++++++++-------------------------- src/addrman.h | 169 +++++++++++++++++++----------- 2 files changed, 231 insertions(+), 206 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 0c09a244701..8310f0fe70e 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -14,12 +14,12 @@ int CAddrInfo::GetTriedBucket(const uint256& nKey) const { CDataStream ss1(SER_GETHASH, 0); std::vector vchKey = GetKey(); - ss1 << ((unsigned char)32) << nKey << vchKey; + ss1 << nKey << vchKey; uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); CDataStream ss2(SER_GETHASH, 0); std::vector vchGroupKey = GetGroup(); - ss2 << ((unsigned char)32) << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); + ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; } @@ -29,15 +29,24 @@ int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src) const CDataStream ss1(SER_GETHASH, 0); std::vector vchGroupKey = GetGroup(); std::vector vchSourceGroupKey = src.GetGroup(); - ss1 << ((unsigned char)32) << nKey << vchGroupKey << vchSourceGroupKey; + ss1 << nKey << vchGroupKey << vchSourceGroupKey; uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); CDataStream ss2(SER_GETHASH, 0); - ss2 << ((unsigned char)32) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); + ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); return hash2 % ADDRMAN_NEW_BUCKET_COUNT; } +int CAddrInfo::GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const +{ + CDataStream ss1(SER_GETHASH, 0); + std::vector vchKey = GetKey(); + ss1 << nKey << (fNew ? 'N' : 'K') << nBucket << vchKey; + uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); + return hash1 % ADDRMAN_BUCKET_SIZE; +} + bool CAddrInfo::IsTerrible(int64_t nNow) const { if (nLastTry && nLastTry >= nNow - 60) // never remove things tried in the last minute @@ -128,85 +137,44 @@ void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) vRandom[nRndPos2] = nId1; } -int CAddrMan::SelectTried(int nKBucket) +void CAddrMan::Delete(int nId) { - std::vector& vTried = vvTried[nKBucket]; + assert(mapInfo.count(nId) != 0); + CAddrInfo& info = mapInfo[nId]; + assert(!info.fInTried); + assert(info.nRefCount == 0); - // randomly shuffle the first few elements (using the entire list) - // find the least recently tried among them - int64_t nOldest = -1; - int nOldestPos = -1; - for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++) { - int nPos = GetRandInt(vTried.size() - i) + i; - int nTemp = vTried[nPos]; - vTried[nPos] = vTried[i]; - vTried[i] = nTemp; - assert(nOldest == -1 || mapInfo.count(nTemp) == 1); - if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) { - nOldest = nTemp; - nOldestPos = nPos; - } - } - - return nOldestPos; + SwapRandom(info.nRandomPos, vRandom.size() - 1); + vRandom.pop_back(); + mapAddr.erase(info); + mapInfo.erase(nId); + nNew--; } -int CAddrMan::ShrinkNew(int nUBucket) +void CAddrMan::ClearNew(int nUBucket, int nUBucketPos) { - assert(nUBucket >= 0 && (unsigned int)nUBucket < vvNew.size()); - std::set& vNew = vvNew[nUBucket]; - - // first look for deletable items - for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) { - assert(mapInfo.count(*it)); - CAddrInfo& info = mapInfo[*it]; - if (info.IsTerrible()) { - if (--info.nRefCount == 0) { - SwapRandom(info.nRandomPos, vRandom.size() - 1); - vRandom.pop_back(); - mapAddr.erase(info); - mapInfo.erase(*it); - nNew--; - } - vNew.erase(it); - return 0; + // if there is an entry in the specified bucket, delete it. + if (vvNew[nUBucket][nUBucketPos] != -1) { + int nIdDelete = vvNew[nUBucket][nUBucketPos]; + CAddrInfo& infoDelete = mapInfo[nIdDelete]; + assert(infoDelete.nRefCount > 0); + infoDelete.nRefCount--; + vvNew[nUBucket][nUBucketPos] = -1; + if (infoDelete.nRefCount == 0) { + Delete(nIdDelete); } } - - // otherwise, select four randomly, and pick the oldest of those to replace - int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())}; - int nI = 0; - int nOldest = -1; - for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) { - if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3]) { - assert(nOldest == -1 || mapInfo.count(*it) == 1); - if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime) - nOldest = *it; - } - nI++; - } - assert(mapInfo.count(nOldest) == 1); - CAddrInfo& info = mapInfo[nOldest]; - if (--info.nRefCount == 0) { - SwapRandom(info.nRandomPos, vRandom.size() - 1); - vRandom.pop_back(); - mapAddr.erase(info); - mapInfo.erase(nOldest); - nNew--; - } - vNew.erase(nOldest); - - return 1; } -void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) +void CAddrMan::MakeTried(CAddrInfo& info, int nId) { - assert(vvNew[nOrigin].count(nId) == 1); - // remove the entry from all new buckets - for (std::vector >::iterator it = vvNew.begin(); it != vvNew.end(); it++) { - if ((*it).erase(nId)) + for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) { + int pos = info.GetBucketPosition(nKey, true, bucket); + if (vvNew[bucket][pos] == nId) { + vvNew[bucket][pos] = -1; info.nRefCount--; + } } nNew--; @@ -214,44 +182,36 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) // which tried bucket to move the entry to int nKBucket = info.GetTriedBucket(nKey); - std::vector& vTried = vvTried[nKBucket]; + int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket); - // first check whether there is place to just add it - if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) { - vTried.push_back(nId); - nTried++; - info.fInTried = true; - return; + // first make space to add it (the existing tried entry there is moved to new, deleting whatever is there). + if (vvTried[nKBucket][nKBucketPos] != -1) { + // find an item to evict + int nIdEvict = vvTried[nKBucket][nKBucketPos]; + assert(mapInfo.count(nIdEvict) == 1); + CAddrInfo& infoOld = mapInfo[nIdEvict]; + + // Remove the to-be-evicted item from the tried set. + infoOld.fInTried = false; + vvTried[nKBucket][nKBucketPos] = -1; + nTried--; + + // find which new bucket it belongs to + int nUBucket = infoOld.GetNewBucket(nKey); + int nUBucketPos = infoOld.GetBucketPosition(nKey, true, nUBucket); + ClearNew(nUBucket, nUBucketPos); + assert(vvNew[nUBucket][nUBucketPos] == -1); + + // Enter it into the new set again. + infoOld.nRefCount = 1; + vvNew[nUBucket][nUBucketPos] = nIdEvict; + nNew++; } + assert(vvTried[nKBucket][nKBucketPos] == -1); - // otherwise, find an item to evict - int nPos = SelectTried(nKBucket); - - // find which new bucket it belongs to - assert(mapInfo.count(vTried[nPos]) == 1); - int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey); - std::set& vNew = vvNew[nUBucket]; - - // remove the to-be-replaced tried entry from the tried set - CAddrInfo& infoOld = mapInfo[vTried[nPos]]; - infoOld.fInTried = false; - infoOld.nRefCount = 1; - // do not update nTried, as we are going to move something else there immediately - - // check whether there is place in that one, - if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) { - // if so, move it back there - vNew.insert(vTried[nPos]); - } else { - // otherwise, move it to the new bucket nId came from (there is certainly place there) - vvNew[nOrigin].insert(vTried[nPos]); - } - nNew++; - - vTried[nPos] = nId; - // we just overwrote an entry in vTried; no need to update nTried + vvTried[nKBucket][nKBucketPos] = nId; + nTried++; info.fInTried = true; - return; } void CAddrMan::Good_(const CService& addr, int64_t nTime) @@ -281,12 +241,12 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime) return; // find a bucket it is in now - int nRnd = GetRandInt(vvNew.size()); + int nRnd = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT); int nUBucket = -1; - for (unsigned int n = 0; n < vvNew.size(); n++) { - int nB = (n + nRnd) % vvNew.size(); - std::set& vNew = vvNew[nB]; - if (vNew.count(nId)) { + for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) { + int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT; + int nBpos = info.GetBucketPosition(nKey, true, nB); + if (vvNew[nB][nBpos] == nId) { nUBucket = nB; break; } @@ -300,7 +260,7 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime) LogPrint("addrman", "Moving %s to tried\n", addr.ToString()); // move nId to the tried tables - MakeTried(info, nId, nUBucket); + MakeTried(info, nId); } bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty) @@ -348,12 +308,25 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP } int nUBucket = pinfo->GetNewBucket(nKey, source); - std::set& vNew = vvNew[nUBucket]; - if (!vNew.count(nId)) { - pinfo->nRefCount++; - if (vNew.size() == ADDRMAN_NEW_BUCKET_SIZE) - ShrinkNew(nUBucket); - vvNew[nUBucket].insert(nId); + int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket); + if (vvNew[nUBucket][nUBucketPos] != nId) { + bool fInsert = vvNew[nUBucket][nUBucketPos] == -1; + if (!fInsert) { + CAddrInfo& infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]]; + if (infoExisting.IsTerrible() || (infoExisting.nRefCount > 1 && pinfo->nRefCount == 0)) { + // Overwrite the existing new table entry. + fInsert = true; + } + } + if (fInsert) { + ClearNew(nUBucket, nUBucketPos); + pinfo->nRefCount++; + vvNew[nUBucket][nUBucketPos] = nId; + } else { + if (pinfo->nRefCount == 0) { + Delete(nId); + } + } } return fNew; } @@ -388,13 +361,13 @@ CAddress CAddrMan::Select_(int nUnkBias) // use a tried node double fChanceFactor = 1.0; while (1) { - int nKBucket = GetRandInt(vvTried.size()); - std::vector& vTried = vvTried[nKBucket]; - if (vTried.size() == 0) + int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT); + int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); + if (vvTried[nKBucket][nKBucketPos] == -1) continue; - int nPos = GetRandInt(vTried.size()); - assert(mapInfo.count(vTried[nPos]) == 1); - CAddrInfo& info = mapInfo[vTried[nPos]]; + int nId = vvTried[nKBucket][nKBucketPos]; + assert(mapInfo.count(nId) == 1); + CAddrInfo& info = mapInfo[nId]; if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) return info; fChanceFactor *= 1.2; @@ -403,16 +376,13 @@ CAddress CAddrMan::Select_(int nUnkBias) // use a new node double fChanceFactor = 1.0; while (1) { - int nUBucket = GetRandInt(vvNew.size()); - std::set& vNew = vvNew[nUBucket]; - if (vNew.size() == 0) + int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT); + int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); + if (vvNew[nUBucket][nUBucketPos] == -1) continue; - int nPos = GetRandInt(vNew.size()); - std::set::iterator it = vNew.begin(); - while (nPos--) - it++; - assert(mapInfo.count(*it) == 1); - CAddrInfo& info = mapInfo[*it]; + int nId = vvNew[nUBucket][nUBucketPos]; + assert(mapInfo.count(nId) == 1); + CAddrInfo& info = mapInfo[nId]; if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) return info; fChanceFactor *= 1.2; @@ -460,22 +430,30 @@ int CAddrMan::Check_() if (mapNew.size() != nNew) return -10; - for (int n = 0; n < vvTried.size(); n++) { - std::vector& vTried = vvTried[n]; - for (std::vector::iterator it = vTried.begin(); it != vTried.end(); it++) { - if (!setTried.count(*it)) - return -11; - setTried.erase(*it); + for (int n = 0; n < ADDRMAN_TRIED_BUCKET_COUNT; n++) { + for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) { + if (vvTried[n][i] != -1) { + if (!setTried.count(vvTried[n][i])) + return -11; + if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey) != n) + return -17; + if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i) + return -18; + setTried.erase(vvTried[n][i]); + } } } - for (int n = 0; n < vvNew.size(); n++) { - std::set& vNew = vvNew[n]; - for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) { - if (!mapNew.count(*it)) - return -12; - if (--mapNew[*it] == 0) - mapNew.erase(*it); + for (int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) { + for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) { + if (vvNew[n][i] != -1) { + if (!mapNew.count(vvNew[n][i])) + return -12; + if (mapInfo[vvNew[n][i]].GetBucketPosition(nKey, true, n) != i) + return -19; + if (--mapNew[vvNew[n][i]] == 0) + mapNew.erase(vvNew[n][i]); + } } } diff --git a/src/addrman.h b/src/addrman.h index 04c7b32eafa..f7c63184484 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -10,7 +10,6 @@ #include "random.h" #include "sync.h" #include "timedata.h" -#include "uint256.h" #include "util.h" #include @@ -91,6 +90,9 @@ public: return GetNewBucket(nKey, source); } + //! Calculate in which position of a bucket to store this entry. + int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const; + //! Determine whether the statistics about this entry are bad enough so that it can just be deleted bool IsTerrible(int64_t nNow = GetAdjustedTime()) const; @@ -128,14 +130,11 @@ public: //! total number of buckets for tried addresses #define ADDRMAN_TRIED_BUCKET_COUNT 64 -//! maximum allowed number of entries in buckets for tried addresses -#define ADDRMAN_TRIED_BUCKET_SIZE 64 - //! total number of buckets for new addresses #define ADDRMAN_NEW_BUCKET_COUNT 256 -//! maximum allowed number of entries in buckets for new addresses -#define ADDRMAN_NEW_BUCKET_SIZE 64 +//! maximum allowed number of entries in buckets for new and tried addresses +#define ADDRMAN_BUCKET_SIZE 64 //! over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 4 @@ -146,9 +145,6 @@ public: //! in how many buckets for entries with new addresses a single address may occur #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4 -//! how many entries in a bucket with tried addresses are inspected, when selecting one to replace -#define ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT 4 - //! how old addresses can maximally be #define ADDRMAN_HORIZON_DAYS 30 @@ -195,13 +191,13 @@ private: int nTried; //! list of "tried" buckets - std::vector > vvTried; + int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]; //! number of (unique) "new" entries int nNew; //! list of "new" buckets - std::vector > vvNew; + int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]; protected: @@ -215,17 +211,14 @@ protected: //! Swap two elements in vRandom. void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2); - //! Return position in given bucket to replace. - int SelectTried(int nKBucket); - - //! Remove an element from a "new" bucket. - //! This is the only place where actual deletions occur. - //! Elements are never deleted while in the "tried" table, only possibly evicted back to the "new" table. - int ShrinkNew(int nUBucket); - //! Move an entry from the "new" table(s) to the "tried" table - //! @pre vvUnkown[nOrigin].count(nId) != 0 - void MakeTried(CAddrInfo& info, int nId, int nOrigin); + void MakeTried(CAddrInfo& info, int nId); + + //! Delete an entry. It must not be in tried, and have refcount 0. + void Delete(int nId); + + //! Clear a position in a "new" table. This is the only place where entries are actually deleted. + void ClearNew(int nUBucket, int nUBucketPos); //! Mark an entry "good", possibly moving it from "new" to "tried". void Good_(const CService &addr, int64_t nTime); @@ -254,17 +247,21 @@ protected: public: /** * serialized format: - * * version byte (currently 0) - * * nKey + * * version byte (currently 1) + * * 0x20 + nKey (serialized as if it were a vector, for backward compatibility) * * nNew * * nTried - * * number of "new" buckets + * * number of "new" buckets XOR 2**30 * * all nNew addrinfos in vvNew * * all nTried addrinfos in vvTried * * for each bucket: * * number of elements * * for each element: index * + * 2**30 is xorred with the number of buckets to make addrman deserializer v0 detect it + * as incompatible. This is necessary because it did not check the version number on + * deserialization. + * * Notice that vvTried, mapAddr and vVector are never encoded explicitly; * they are instead reconstructed from the other information. * @@ -276,49 +273,53 @@ public: * * We don't use ADD_SERIALIZE_METHODS since the serialization and deserialization code has * very little in common. - * */ template void Serialize(Stream &s, int nType, int nVersionDummy) const { LOCK(cs); - unsigned char nVersion = 0; + unsigned char nVersion = 1; s << nVersion; s << ((unsigned char)32); s << nKey; s << nNew; s << nTried; - int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT; + int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30); s << nUBuckets; std::map mapUnkIds; int nIds = 0; for (std::map::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) { - if (nIds == nNew) break; // this means nNew was wrong, oh ow mapUnkIds[(*it).first] = nIds; const CAddrInfo &info = (*it).second; if (info.nRefCount) { + assert(nIds != nNew); // this means nNew was wrong, oh ow s << info; nIds++; } } nIds = 0; for (std::map::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) { - if (nIds == nTried) break; // this means nTried was wrong, oh ow const CAddrInfo &info = (*it).second; if (info.fInTried) { + assert(nIds != nTried); // this means nTried was wrong, oh ow s << info; nIds++; } } - for (std::vector >::const_iterator it = vvNew.begin(); it != vvNew.end(); it++) { - const std::set &vNew = (*it); - int nSize = vNew.size(); + for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) { + int nSize = 0; + for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) { + if (vvNew[bucket][i] != -1) + nSize++; + } s << nSize; - for (std::set::const_iterator it2 = vNew.begin(); it2 != vNew.end(); it2++) { - int nIndex = mapUnkIds[*it2]; - s << nIndex; + for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) { + if (vvNew[bucket][i] != -1) { + int nIndex = mapUnkIds[vvNew[bucket][i]]; + s << nIndex; + } } } } @@ -328,67 +329,97 @@ public: { LOCK(cs); + Clear(); + unsigned char nVersion; s >> nVersion; unsigned char nKeySize; s >> nKeySize; - if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman"); + if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman deserialization"); s >> nKey; s >> nNew; s >> nTried; - int nUBuckets = 0; s >> nUBuckets; - nIdCount = 0; - mapInfo.clear(); - mapAddr.clear(); - vRandom.clear(); - vvTried = std::vector >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)); - vvNew = std::vector >(ADDRMAN_NEW_BUCKET_COUNT, std::set()); + if (nVersion != 0) { + nUBuckets ^= (1 << 30); + } + + // Deserialize entries from the new table. for (int n = 0; n < nNew; n++) { CAddrInfo &info = mapInfo[n]; s >> info; mapAddr[info] = n; info.nRandomPos = vRandom.size(); vRandom.push_back(n); - if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) { - vvNew[info.GetNewBucket(nKey)].insert(n); - info.nRefCount++; + if (nVersion != 1 || nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) { + // In case the new table data cannot be used (nVersion unknown, or bucket count wrong), + // immediately try to give them a reference based on their primary source address. + int nUBucket = info.GetNewBucket(nKey); + int nUBucketPos = info.GetBucketPosition(nKey, true, nUBucket); + if (vvNew[nUBucket][nUBucketPos] == -1) { + vvNew[nUBucket][nUBucketPos] = n; + info.nRefCount++; + } } } nIdCount = nNew; + + // Deserialize entries from the tried table. int nLost = 0; for (int n = 0; n < nTried; n++) { CAddrInfo info; s >> info; - std::vector &vTried = vvTried[info.GetTriedBucket(nKey)]; - if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) { + int nKBucket = info.GetTriedBucket(nKey); + int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket); + if (vvTried[nKBucket][nKBucketPos] == -1) { info.nRandomPos = vRandom.size(); info.fInTried = true; vRandom.push_back(nIdCount); mapInfo[nIdCount] = info; mapAddr[info] = nIdCount; - vTried.push_back(nIdCount); + vvTried[nKBucket][nKBucketPos] = nIdCount; nIdCount++; } else { nLost++; } } nTried -= nLost; - for (int b = 0; b < nUBuckets; b++) { - std::set &vNew = vvNew[b]; + + // Deserialize positions in the new table (if possible). + for (int bucket = 0; bucket < nUBuckets; bucket++) { int nSize = 0; s >> nSize; for (int n = 0; n < nSize; n++) { int nIndex = 0; s >> nIndex; - CAddrInfo &info = mapInfo[nIndex]; - if (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) { - info.nRefCount++; - vNew.insert(nIndex); + if (nIndex >= 0 && nIndex < nNew) { + CAddrInfo &info = mapInfo[nIndex]; + int nUBucketPos = info.GetBucketPosition(nKey, true, bucket); + if (nVersion == 1 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) { + info.nRefCount++; + vvNew[bucket][nUBucketPos] = nIndex; + } } } } + + // Prune new entries with refcount 0 (as a result of collisions). + int nLostUnk = 0; + for (std::map::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) { + if (it->second.fInTried == false && it->second.nRefCount == 0) { + std::map::const_iterator itCopy = it++; + Delete(itCopy->first); + nLostUnk++; + } else { + it++; + } + } + if (nLost + nLostUnk > 0) { + LogPrint("addrman", "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost); + } + + Check(); } unsigned int GetSerializeSize(int nType, int nVersion) const @@ -396,18 +427,34 @@ public: return (CSizeComputer(nType, nVersion) << *this).size(); } - CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set()) + void Clear() { - nKey = GetRandHash(); + std::vector().swap(vRandom); + nKey = GetRandHash(); + for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) { + for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) { + vvNew[bucket][entry] = -1; + } + } + for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) { + for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) { + vvTried[bucket][entry] = -1; + } + } - nIdCount = 0; - nTried = 0; - nNew = 0; + nIdCount = 0; + nTried = 0; + nNew = 0; + } + + CAddrMan() + { + Clear(); } ~CAddrMan() { - nKey.SetNull(); + nKey.SetNull(); } //! Return the number of (unique) addresses in all tables. From a8ff7c62edc63c7c94bc91c30b80995539ed7477 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Mar 2015 08:50:04 -0700 Subject: [PATCH 0334/2337] Simplify hashing code --- src/addrman.cpp | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 8310f0fe70e..05688fbdf0b 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -12,38 +12,22 @@ using namespace std; int CAddrInfo::GetTriedBucket(const uint256& nKey) const { - CDataStream ss1(SER_GETHASH, 0); - std::vector vchKey = GetKey(); - ss1 << nKey << vchKey; - uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); - - CDataStream ss2(SER_GETHASH, 0); - std::vector vchGroupKey = GetGroup(); - ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); - uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); + uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetHash().GetCheapHash(); + uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetHash().GetCheapHash(); return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; } int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src) const { - CDataStream ss1(SER_GETHASH, 0); - std::vector vchGroupKey = GetGroup(); std::vector vchSourceGroupKey = src.GetGroup(); - ss1 << nKey << vchGroupKey << vchSourceGroupKey; - uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); - - CDataStream ss2(SER_GETHASH, 0); - ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); - uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); + uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << vchSourceGroupKey).GetHash().GetCheapHash(); + uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetHash().GetCheapHash(); return hash2 % ADDRMAN_NEW_BUCKET_COUNT; } int CAddrInfo::GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const { - CDataStream ss1(SER_GETHASH, 0); - std::vector vchKey = GetKey(); - ss1 << nKey << (fNew ? 'N' : 'K') << nBucket << vchKey; - uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); + uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << (fNew ? 'N' : 'K') << nBucket << GetKey()).GetHash().GetCheapHash(); return hash1 % ADDRMAN_BUCKET_SIZE; } From f68ba3f67bd500a64fb8932c6b41924ddc31d76f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Mar 2015 09:44:26 -0700 Subject: [PATCH 0335/2337] Do not bias outgoing connections towards fresh addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change was suggested as Countermeasure 2 in Eclipse Attacks on Bitcoin’s Peer-to-Peer Network, Ethan Heilman, Alison Kendler, Aviv Zohar, Sharon Goldberg. ePrint Archive Report 2015/263. March 2015. --- src/addrman.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 05688fbdf0b..eb431ec59c8 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -63,8 +63,6 @@ double CAddrInfo::GetChance(int64_t nNow) const if (nSinceLastTry < 0) nSinceLastTry = 0; - fChance *= 600.0 / (600.0 + nSinceLastSeen); - // deprioritize very recent attempts away if (nSinceLastTry < 60 * 10) fChance *= 0.01; From c6a63ceeb4956933588995bcf01dc3095aaeb1fc Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Mar 2015 09:51:59 -0700 Subject: [PATCH 0336/2337] Always use a 50% chance to choose between tried and new entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change was suggested as Countermeasure 2 in Eclipse Attacks on Bitcoin’s Peer-to-Peer Network, Ethan Heilman, Alison Kendler, Aviv Zohar, Sharon Goldberg. ePrint Archive Report 2015/263. March 2015. --- src/addrman.cpp | 7 +++---- src/addrman.h | 6 +++--- src/net.cpp | 3 +-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index eb431ec59c8..5d9527f0e15 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -332,14 +332,13 @@ void CAddrMan::Attempt_(const CService& addr, int64_t nTime) info.nAttempts++; } -CAddress CAddrMan::Select_(int nUnkBias) +CAddress CAddrMan::Select_() { if (size() == 0) return CAddress(); - double nCorTried = sqrt(nTried) * (100.0 - nUnkBias); - double nCorNew = sqrt(nNew) * nUnkBias; - if ((nCorTried + nCorNew) * GetRandInt(1 << 30) / (1 << 30) < nCorTried) { + // Use a 50% chance for choosing between tried and new table entries. + if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) { // use a tried node double fChanceFactor = 1.0; while (1) { diff --git a/src/addrman.h b/src/addrman.h index f7c63184484..fe06a745b5c 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -231,7 +231,7 @@ protected: //! Select an address to connect to. //! nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100) - CAddress Select_(int nUnkBias); + CAddress Select_(); #ifdef DEBUG_ADDRMAN //! Perform consistency check. Returns an error code or zero. @@ -533,13 +533,13 @@ public: * Choose an address to connect to. * nUnkBias determines how much "new" entries are favored over "tried" ones (0-100). */ - CAddress Select(int nUnkBias = 50) + CAddress Select() { CAddress addrRet; { LOCK(cs); Check(); - addrRet = Select_(nUnkBias); + addrRet = Select_(); Check(); } return addrRet; diff --git a/src/net.cpp b/src/net.cpp index 0723ee218a4..d8991ffa8df 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1221,8 +1221,7 @@ void ThreadOpenConnections() int nTries = 0; while (true) { - // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections) - CAddress addr = addrman.Select(10 + min(nOutbound,8)*10); + CAddress addr = addrman.Select(); // if we selected an invalid address, restart if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) From 1d21ba2f5ecbf03086d0b65c4c4c80a39a94c2ee Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Mar 2015 10:01:57 -0700 Subject: [PATCH 0337/2337] Scale up addrman MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change was suggested as Countermeasure 6 in Eclipse Attacks on Bitcoin’s Peer-to-Peer Network, Ethan Heilman, Alison Kendler, Aviv Zohar, Sharon Goldberg. ePrint Archive Report 2015/263. March 2015. --- src/addrman.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/addrman.h b/src/addrman.h index fe06a745b5c..8116d0b763d 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -109,15 +109,15 @@ public: * * To that end: * * Addresses are organized into buckets. - * * Address that have not yet been tried go into 256 "new" buckets. - * * Based on the address range (/16 for IPv4) of source of the information, 32 buckets are selected at random + * * Address that have not yet been tried go into 1024 "new" buckets. + * * Based on the address range (/16 for IPv4) of source of the information, 64 buckets are selected at random * * The actual bucket is chosen from one of these, based on the range the address itself is located. - * * One single address can occur in up to 4 different buckets, to increase selection chances for addresses that + * * One single address can occur in up to 8 different buckets, to increase selection chances for addresses that * are seen frequently. The chance for increasing this multiplicity decreases exponentially. * * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen * ones) is removed from it first. - * * Addresses of nodes that are known to be accessible go into 64 "tried" buckets. - * * Each address range selects at random 4 of these buckets. + * * Addresses of nodes that are known to be accessible go into 256 "tried" buckets. + * * Each address range selects at random 8 of these buckets. * * The actual bucket is chosen from one of these, based on the full address. * * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently * tried ones) is evicted from it, back to the "new" buckets. @@ -128,22 +128,22 @@ public: */ //! total number of buckets for tried addresses -#define ADDRMAN_TRIED_BUCKET_COUNT 64 +#define ADDRMAN_TRIED_BUCKET_COUNT 256 //! total number of buckets for new addresses -#define ADDRMAN_NEW_BUCKET_COUNT 256 +#define ADDRMAN_NEW_BUCKET_COUNT 1024 //! maximum allowed number of entries in buckets for new and tried addresses #define ADDRMAN_BUCKET_SIZE 64 //! over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread -#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 4 +#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8 //! over how many buckets entries with new addresses originating from a single group are spread -#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 32 +#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64 //! in how many buckets for entries with new addresses a single address may occur -#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4 +#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8 //! how old addresses can maximally be #define ADDRMAN_HORIZON_DAYS 30 From fc720207e0e513e531b1f266b966a2ffa57b936a Mon Sep 17 00:00:00 2001 From: Ruben de Vries Date: Tue, 24 Mar 2015 14:29:13 +0100 Subject: [PATCH 0338/2337] don't trickle for whitelisted nodes --- src/main.h | 7 ++++++- src/net.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main.h b/src/main.h index 936cd43e99e..65693b44b7e 100644 --- a/src/main.h +++ b/src/main.h @@ -177,7 +177,12 @@ bool LoadBlockIndex(); void UnloadBlockIndex(); /** Process protocol messages received from a given node */ bool ProcessMessages(CNode* pfrom); -/** Send queued protocol messages to be sent to a give node */ +/** + * Send queued protocol messages to be sent to a give node. + * + * @param[in] pto The node which we are sending messages to. + * @param[in] fSendTrickle When true send the trickled data, otherwise trickle the data until true. + */ bool SendMessages(CNode* pto, bool fSendTrickle); /** Run an instance of the script checking thread */ void ThreadScriptCheck(); diff --git a/src/net.cpp b/src/net.cpp index 0723ee218a4..11c2cd07d9f 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1406,7 +1406,7 @@ void ThreadMessageHandler() { TRY_LOCK(pnode->cs_vSend, lockSend); if (lockSend) - g_signals.SendMessages(pnode, pnode == pnodeTrickle); + g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted); } boost::this_thread::interruption_point(); } From 26c16d9de9874ad2f5fe28377b838a19a558639d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Thu, 5 Feb 2015 01:11:44 +0100 Subject: [PATCH 0339/2337] Includes: Refactor: Move CValidationInterface and CMainSignals out of main --- src/Makefile.am | 2 + src/main.cpp | 77 ++++--------------------------------- src/main.h | 26 +------------ src/validationinterface.cpp | 47 ++++++++++++++++++++++ src/validationinterface.h | 62 +++++++++++++++++++++++++++++ src/wallet/wallet.h | 5 ++- 6 files changed, 123 insertions(+), 96 deletions(-) create mode 100644 src/validationinterface.cpp create mode 100644 src/validationinterface.h diff --git a/src/Makefile.am b/src/Makefile.am index 2c607c632e7..1b3e0d9d5b6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -138,6 +138,7 @@ BITCOIN_CORE_H = \ utilmoneystr.h \ utilstrencodings.h \ utiltime.h \ + validationinterface.h \ version.h \ wallet/crypter.h \ wallet/walletdb.h \ @@ -191,6 +192,7 @@ libbitcoin_server_a_SOURCES = \ timedata.cpp \ txdb.cpp \ txmempool.cpp \ + validationinterface.cpp \ $(JSON_H) \ $(BITCOIN_CORE_H) diff --git a/src/main.cpp b/src/main.cpp index aa6f904574a..0ffacc338e6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,9 +5,9 @@ #include "main.h" -#include "arith_uint256.h" #include "addrman.h" #include "alert.h" +#include "arith_uint256.h" #include "chainparams.h" #include "checkpoints.h" #include "checkqueue.h" @@ -21,6 +21,7 @@ #include "undo.h" #include "util.h" #include "utilmoneystr.h" +#include "validationinterface.h" #include @@ -156,68 +157,6 @@ namespace { set setDirtyFileInfo; } // anon namespace -////////////////////////////////////////////////////////////////////////////// -// -// dispatching functions -// - -// These functions dispatch to one or all registered wallets - -namespace { - -struct CMainSignals { - /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ - boost::signals2::signal SyncTransaction; - /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */ - boost::signals2::signal EraseTransaction; - /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ - boost::signals2::signal UpdatedTransaction; - /** Notifies listeners of a new active block chain. */ - boost::signals2::signal SetBestChain; - /** Notifies listeners about an inventory item being seen on the network. */ - boost::signals2::signal Inventory; - /** Tells listeners to broadcast their data. */ - boost::signals2::signal Broadcast; - /** Notifies listeners of a block validation result */ - boost::signals2::signal BlockChecked; -} g_signals; - -} // anon namespace - -void RegisterValidationInterface(CValidationInterface* pwalletIn) { - g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); - g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); - g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); - g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); - g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); - g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); -} - -void UnregisterValidationInterface(CValidationInterface* pwalletIn) { - g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); - g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); - g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); - g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); - g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); - g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); -} - -void UnregisterAllValidationInterfaces() { - g_signals.BlockChecked.disconnect_all_slots(); - g_signals.Broadcast.disconnect_all_slots(); - g_signals.Inventory.disconnect_all_slots(); - g_signals.SetBestChain.disconnect_all_slots(); - g_signals.UpdatedTransaction.disconnect_all_slots(); - g_signals.EraseTransaction.disconnect_all_slots(); - g_signals.SyncTransaction.disconnect_all_slots(); -} - -void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) { - g_signals.SyncTransaction(tx, pblock); -} - ////////////////////////////////////////////////////////////////////////////// // // Registration of network node signals. @@ -1897,7 +1836,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Watch for changes to the previous coinbase transaction. static uint256 hashPrevBestCoinBase; - g_signals.UpdatedTransaction(hashPrevBestCoinBase); + GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); hashPrevBestCoinBase = block.vtx[0].GetHash(); int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3; @@ -1956,7 +1895,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { return state.Abort("Failed to write to coin database"); // Update best block in wallet (so we can detect restored wallets). if (mode != FLUSH_STATE_IF_NEEDED) { - g_signals.SetBestChain(chainActive.GetLocator()); + GetMainSignals().SetBestChain(chainActive.GetLocator()); } nLastWrite = GetTimeMicros(); } @@ -2080,7 +2019,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * CCoinsViewCache view(pcoinsTip); CInv inv(MSG_BLOCK, pindexNew->GetBlockHash()); bool rv = ConnectBlock(*pblock, state, pindexNew, view); - g_signals.BlockChecked(*pblock, state); + GetMainSignals().BlockChecked(*pblock, state); if (!rv) { if (state.IsInvalid()) InvalidBlockFound(pindexNew, state); @@ -3471,7 +3410,7 @@ void static ProcessGetData(CNode* pfrom) } // Track requests for our stuff. - g_signals.Inventory(inv.hash); + GetMainSignals().Inventory(inv.hash); if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) break; @@ -3765,7 +3704,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // Track requests for our stuff - g_signals.Inventory(inv.hash); + GetMainSignals().Inventory(inv.hash); if (pfrom->nSendSize > (SendBufferSize() * 2)) { Misbehaving(pfrom->GetId(), 50); @@ -4536,7 +4475,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // transactions become unconfirmed and spams other nodes. if (!fReindex && !fImporting && !IsInitialBlockDownload()) { - g_signals.Broadcast(); + GetMainSignals().Broadcast(); } // diff --git a/src/main.h b/src/main.h index 936cd43e99e..b0bab6f7bf5 100644 --- a/src/main.h +++ b/src/main.h @@ -133,15 +133,6 @@ extern CBlockIndex *pindexBestHeader; /** Minimum disk space required - used in CheckDiskSpace() */ static const uint64_t nMinDiskSpace = 52428800; -/** Register a wallet to receive updates from core */ -void RegisterValidationInterface(CValidationInterface* pwalletIn); -/** Unregister a wallet from core */ -void UnregisterValidationInterface(CValidationInterface* pwalletIn); -/** Unregister all wallets from core */ -void UnregisterAllValidationInterfaces(); -/** Push an updated transaction to all registered wallets */ -void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); - /** Register with a network node to receive its signals */ void RegisterNodeSignals(CNodeSignals& nodeSignals); /** Unregister a network node */ @@ -152,7 +143,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * block is made active. Note that it does not, however, guarantee that the * specific block passed to it has been checked for validity! * - * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface - this will have its BlockChecked method called whenever *any* block completes validation. + * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation. * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid. * @param[in] pblock The block we want to process. * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location. @@ -512,19 +503,4 @@ extern CCoinsViewCache *pcoinsTip; /** Global variable that points to the active block tree (protected by cs_main) */ extern CBlockTreeDB *pblocktree; - -class CValidationInterface { -protected: - virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}; - virtual void EraseFromWallet(const uint256 &hash) {}; - virtual void SetBestChain(const CBlockLocator &locator) {}; - virtual void UpdatedTransaction(const uint256 &hash) {}; - virtual void Inventory(const uint256 &hash) {}; - virtual void ResendWalletTransactions() {}; - virtual void BlockChecked(const CBlock&, const CValidationState&) {}; - friend void ::RegisterValidationInterface(CValidationInterface*); - friend void ::UnregisterValidationInterface(CValidationInterface*); - friend void ::UnregisterAllValidationInterfaces(); -}; - #endif // BITCOIN_MAIN_H diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp new file mode 100644 index 00000000000..ae4cd3c592a --- /dev/null +++ b/src/validationinterface.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "validationinterface.h" + +static CMainSignals g_signals; + +CMainSignals& GetMainSignals() +{ + return g_signals; +} + +void RegisterValidationInterface(CValidationInterface* pwalletIn) { + g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); + g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); + g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); + g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); + g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); + g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); + g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); +} + +void UnregisterValidationInterface(CValidationInterface* pwalletIn) { + g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); + g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); + g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); + g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); + g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); + g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); + g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); +} + +void UnregisterAllValidationInterfaces() { + g_signals.BlockChecked.disconnect_all_slots(); + g_signals.Broadcast.disconnect_all_slots(); + g_signals.Inventory.disconnect_all_slots(); + g_signals.SetBestChain.disconnect_all_slots(); + g_signals.UpdatedTransaction.disconnect_all_slots(); + g_signals.EraseTransaction.disconnect_all_slots(); + g_signals.SyncTransaction.disconnect_all_slots(); +} + +void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) { + g_signals.SyncTransaction(tx, pblock); +} diff --git a/src/validationinterface.h b/src/validationinterface.h new file mode 100644 index 00000000000..b21b6e57825 --- /dev/null +++ b/src/validationinterface.h @@ -0,0 +1,62 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_VALIDATIONINTERFACE_H +#define BITCOIN_VALIDATIONINTERFACE_H + +#include + +class CBlock; +class CBlockLocator; +class CTransaction; +class CValidationInterface; +class CValidationState; +class uint256; + +// These functions dispatch to one or all registered wallets + +/** Register a wallet to receive updates from core */ +void RegisterValidationInterface(CValidationInterface* pwalletIn); +/** Unregister a wallet from core */ +void UnregisterValidationInterface(CValidationInterface* pwalletIn); +/** Unregister all wallets from core */ +void UnregisterAllValidationInterfaces(); +/** Push an updated transaction to all registered wallets */ +void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); + +class CValidationInterface { +protected: + virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}; + virtual void EraseFromWallet(const uint256 &hash) {}; + virtual void SetBestChain(const CBlockLocator &locator) {}; + virtual void UpdatedTransaction(const uint256 &hash) {}; + virtual void Inventory(const uint256 &hash) {}; + virtual void ResendWalletTransactions() {}; + virtual void BlockChecked(const CBlock&, const CValidationState&) {}; + friend void ::RegisterValidationInterface(CValidationInterface*); + friend void ::UnregisterValidationInterface(CValidationInterface*); + friend void ::UnregisterAllValidationInterfaces(); +}; + +struct CMainSignals { + /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ + boost::signals2::signal SyncTransaction; + /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */ + boost::signals2::signal EraseTransaction; + /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ + boost::signals2::signal UpdatedTransaction; + /** Notifies listeners of a new active block chain. */ + boost::signals2::signal SetBestChain; + /** Notifies listeners about an inventory item being seen on the network. */ + boost::signals2::signal Inventory; + /** Tells listeners to broadcast their data. */ + boost::signals2::signal Broadcast; + /** Notifies listeners of a block validation result */ + boost::signals2::signal BlockChecked; +}; + +CMainSignals& GetMainSignals(); + +#endif // BITCOIN_VALIDATIONINTERFACE_H diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3f5f2859b67..30104449784 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -7,12 +7,13 @@ #define BITCOIN_WALLET_H #include "amount.h" -#include "primitives/block.h" -#include "primitives/transaction.h" #include "key.h" #include "keystore.h" #include "main.h" +#include "primitives/block.h" +#include "primitives/transaction.h" #include "ui_interface.h" +#include "validationinterface.h" #include "wallet/crypter.h" #include "wallet/wallet_ismine.h" #include "wallet/walletdb.h" From eca0b1ea62b2625d9df8daecacde96edeb486d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 4 Feb 2015 23:19:29 +0100 Subject: [PATCH 0340/2337] Includes: MOVEONLY: move more method definitions out of wallet.h --- src/wallet/wallet.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++ src/wallet/wallet.h | 68 +++++-------------------------------------- 2 files changed, 76 insertions(+), 60 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 167639b53d7..cc03d5632e0 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -817,6 +817,18 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const return 0; } +isminetype CWallet::IsMine(const CTxOut& txout) const +{ + return ::IsMine(*this, txout.scriptPubKey); +} + +CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const +{ + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetCredit(): value out of range"); + return ((IsMine(txout) & filter) ? txout.nValue : 0); +} + bool CWallet::IsChange(const CTxOut& txout) const { // TODO: fix handling of 'change' outputs. The assumption is that any @@ -839,6 +851,62 @@ bool CWallet::IsChange(const CTxOut& txout) const return false; } +CAmount CWallet::GetChange(const CTxOut& txout) const +{ + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetChange(): value out of range"); + return (IsChange(txout) ? txout.nValue : 0); +} + +bool CWallet::IsMine(const CTransaction& tx) const +{ + BOOST_FOREACH(const CTxOut& txout, tx.vout) + if (IsMine(txout)) + return true; + return false; +} + +bool CWallet::IsFromMe(const CTransaction& tx) const +{ + return (GetDebit(tx, ISMINE_ALL) > 0); +} + +CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const +{ + CAmount nDebit = 0; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + nDebit += GetDebit(txin, filter); + if (!MoneyRange(nDebit)) + throw std::runtime_error("CWallet::GetDebit(): value out of range"); + } + return nDebit; +} + +CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const +{ + CAmount nCredit = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nCredit += GetCredit(txout, filter); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWallet::GetCredit(): value out of range"); + } + return nCredit; +} + +CAmount CWallet::GetChange(const CTransaction& tx) const +{ + CAmount nChange = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nChange += GetChange(txout); + if (!MoneyRange(nChange)) + throw std::runtime_error("CWallet::GetChange(): value out of range"); + } + return nChange; +} + int64_t CWalletTx::GetTxTime() const { int64_t n = nTimeSmart; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 30104449784..9abc73f9ce1 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -641,68 +641,16 @@ public: isminetype IsMine(const CTxIn& txin) const; CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const; - isminetype IsMine(const CTxOut& txout) const - { - return ::IsMine(*this, txout.scriptPubKey); - } - CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const - { - if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); - return ((IsMine(txout) & filter) ? txout.nValue : 0); - } + isminetype IsMine(const CTxOut& txout) const; + CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const; bool IsChange(const CTxOut& txout) const; - CAmount GetChange(const CTxOut& txout) const - { - if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); - return (IsChange(txout) ? txout.nValue : 0); - } - bool IsMine(const CTransaction& tx) const - { - BOOST_FOREACH(const CTxOut& txout, tx.vout) - if (IsMine(txout)) - return true; - return false; - } + CAmount GetChange(const CTxOut& txout) const; + bool IsMine(const CTransaction& tx) const; /** should probably be renamed to IsRelevantToMe */ - bool IsFromMe(const CTransaction& tx) const - { - return (GetDebit(tx, ISMINE_ALL) > 0); - } - CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const - { - CAmount nDebit = 0; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - { - nDebit += GetDebit(txin, filter); - if (!MoneyRange(nDebit)) - throw std::runtime_error("CWallet::GetDebit(): value out of range"); - } - return nDebit; - } - CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const - { - CAmount nCredit = 0; - BOOST_FOREACH(const CTxOut& txout, tx.vout) - { - nCredit += GetCredit(txout, filter); - if (!MoneyRange(nCredit)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); - } - return nCredit; - } - CAmount GetChange(const CTransaction& tx) const - { - CAmount nChange = 0; - BOOST_FOREACH(const CTxOut& txout, tx.vout) - { - nChange += GetChange(txout); - if (!MoneyRange(nChange)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); - } - return nChange; - } + bool IsFromMe(const CTransaction& tx) const; + CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const; + CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const; + CAmount GetChange(const CTransaction& tx) const; void SetBestChain(const CBlockLocator& loc); DBErrors LoadWallet(bool& fFirstRunRet); From 8a893c949bf6b011c8ae1645888576bf236db79c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Thu, 5 Feb 2015 01:21:11 +0100 Subject: [PATCH 0341/2337] Includes: Do not include main.h from any other header --- src/qt/addresstablemodel.cpp | 2 ++ src/qt/paymentserver.cpp | 1 + src/qt/sendcoinsdialog.cpp | 1 + src/qt/signverifymessagedialog.cpp | 1 + src/qt/transactionrecord.cpp | 3 +++ src/test/rpc_wallet_tests.cpp | 1 + src/txdb.cpp | 1 + src/txdb.h | 6 ++++-- src/wallet/rpcwallet.cpp | 3 ++- src/wallet/wallet.cpp | 1 + src/wallet/wallet.h | 5 ++++- src/wallet/walletdb.cpp | 1 + 12 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 9573fe43df8..8e20836c654 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -10,6 +10,8 @@ #include "base58.h" #include "wallet/wallet.h" +#include + #include #include diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 40d6e16f519..ad489de343f 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -10,6 +10,7 @@ #include "base58.h" #include "chainparams.h" +#include "main.h" #include "ui_interface.h" #include "util.h" #include "wallet/wallet.h" diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 28c8fb95f69..774667d4ac6 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -17,6 +17,7 @@ #include "base58.h" #include "coincontrol.h" +#include "main.h" #include "ui_interface.h" #include "wallet/wallet.h" diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 76da6904a98..ce166f36721 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -12,6 +12,7 @@ #include "base58.h" #include "init.h" +#include "main.h" // For strMessageMagic #include "wallet/wallet.h" #include diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 19e3fc0dc28..9db5ad0fd46 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -5,11 +5,14 @@ #include "transactionrecord.h" #include "base58.h" +#include "main.h" #include "timedata.h" #include "wallet/wallet.h" #include +#include + /* Return positive answer if transaction should be shown in list. */ bool TransactionRecord::showTransaction(const CWalletTx &wtx) diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index d97bea8bd2a..4d5e92cbd40 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -6,6 +6,7 @@ #include "rpcclient.h" #include "base58.h" +#include "main.h" #include "wallet/wallet.h" #include "test/test_bitcoin.h" diff --git a/src/txdb.cpp b/src/txdb.cpp index da271bd5d1a..f3281502891 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -5,6 +5,7 @@ #include "txdb.h" +#include "main.h" #include "pow.h" #include "uint256.h" diff --git a/src/txdb.h b/src/txdb.h index f6b6b84fcf2..1ce93969d84 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -6,15 +6,17 @@ #ifndef BITCOIN_TXDB_H #define BITCOIN_TXDB_H +#include "coins.h" #include "leveldbwrapper.h" -#include "main.h" #include #include #include #include -class CCoins; +class CBlockFileInfo; +class CBlockIndex; +class CDiskTxPos; class uint256; //! -dbcache default (MiB) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5502b0b261d..9318c1b2b15 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6,10 +6,11 @@ #include "amount.h" #include "base58.h" #include "core_io.h" -#include "rpcserver.h" #include "init.h" +#include "main.h" #include "net.h" #include "netbase.h" +#include "rpcserver.h" #include "timedata.h" #include "util.h" #include "utilmoneystr.h" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index cc03d5632e0..09bcda577ed 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -8,6 +8,7 @@ #include "base58.h" #include "checkpoints.h" #include "coincontrol.h" +#include "main.h" #include "net.h" #include "script/script.h" #include "script/sign.h" diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 9abc73f9ce1..4a13f02195f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -9,10 +9,11 @@ #include "amount.h" #include "key.h" #include "keystore.h" -#include "main.h" #include "primitives/block.h" #include "primitives/transaction.h" +#include "tinyformat.h" #include "ui_interface.h" +#include "utilstrencodings.h" #include "validationinterface.h" #include "wallet/crypter.h" #include "wallet/wallet_ismine.h" @@ -49,10 +50,12 @@ static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWa static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; class CAccountingEntry; +class CBlockIndex; class CCoinControl; class COutput; class CReserveKey; class CScript; +class CTxMemPool; class CWalletTx; /** (client) version numbers for particular wallet features */ diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index d7f70e435ea..de56a2d1aff 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -6,6 +6,7 @@ #include "wallet/walletdb.h" #include "base58.h" +#include "main.h" #include "protocol.h" #include "serialize.h" #include "sync.h" From 0f5954c434fdd04b9abca6ddc6f1bbf895b6c6be Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Mon, 23 Mar 2015 13:47:18 -0400 Subject: [PATCH 0342/2337] Regression test for ResendWalletTransactions Adds a regression test for the wallet's ResendWalletTransactions function, which uses a new, hidden RPC command "resendwallettransactions." I refactored main's Broadcast signal so it is passed the best-block time, which let me remove a global variable shared between main.cpp and the wallet (nTimeBestReceived). I also manually tested the "rebroadcast unconfirmed every half hour or so" functionality by: 1. Running bitcoind -connect=0.0.0.0:8333 2. Creating a couple of send-to-self transactions 3. Connect to a peer using -addnode 4. Waited a while, monitoring debug.log, until I see: ```2015-03-23 18:48:10 ResendWalletTransactions: rebroadcast 2 unconfirmed transactions``` One last change: don't bother putting ResendWalletTransactions messages in debug.log unless unconfirmed transactions were actually rebroadcast. --- qa/rpc-tests/wallet.py | 21 +++++++++++++- src/main.cpp | 2 +- src/main.h | 1 - src/rpcserver.cpp | 3 ++ src/rpcserver.h | 1 + src/validationinterface.cpp | 4 +-- src/validationinterface.h | 4 +-- src/wallet/rpcwallet.cpp | 22 ++++++++++++++ src/wallet/wallet.cpp | 57 ++++++++++++++++++++++--------------- src/wallet/wallet.h | 5 ++-- 10 files changed, 88 insertions(+), 32 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index dc4e0f77bd4..01e9fa57b29 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -16,6 +16,7 @@ # h) node0 should now have 2 unspent outputs; send these to node2 via raw tx broadcast by node1 # i) have node1 mine a block # j) check balances - node0 should have 0, node2 should have 100 +# k) test ResendWalletTransactions - create transactions, startup fourth node, make sure it syncs # from test_framework import BitcoinTestFramework @@ -26,7 +27,7 @@ class WalletTest (BitcoinTestFramework): def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 3) + initialize_chain_clean(self.options.tmpdir, 4) def setup_network(self, split=False): self.nodes = start_nodes(3, self.options.tmpdir) @@ -132,5 +133,23 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')) assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000')) + # Test ResendWalletTransactions: + # Create a couple of transactions, then start up a fourth + # node (nodes[3]) and ask nodes[0] to rebroadcast. + # EXPECT: nodes[3] should have those transactions in its mempool. + txid1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1) + txid2 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) + sync_mempools(self.nodes) + + self.nodes.append(start_node(3, self.options.tmpdir)) + connect_nodes_bi(self.nodes, 0, 3) + sync_blocks(self.nodes) + + relayed = self.nodes[0].resendwallettransactions() + assert_equal(set(relayed), set([txid1, txid2])) + sync_mempools(self.nodes) + + assert(txid1 in self.nodes[3].getrawmempool()) + if __name__ == '__main__': WalletTest ().main () diff --git a/src/main.cpp b/src/main.cpp index 0ffacc338e6..8f50e7fc164 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4475,7 +4475,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // transactions become unconfirmed and spams other nodes. if (!fReindex && !fImporting && !IsInitialBlockDownload()) { - GetMainSignals().Broadcast(); + GetMainSignals().Broadcast(nTimeBestReceived); } // diff --git a/src/main.h b/src/main.h index b0bab6f7bf5..31de3f6ac5e 100644 --- a/src/main.h +++ b/src/main.h @@ -116,7 +116,6 @@ extern BlockMap mapBlockIndex; extern uint64_t nLastBlockTx; extern uint64_t nLastBlockSize; extern const std::string strMessageMagic; -extern int64_t nTimeBestReceived; extern CWaitableCriticalSection csBestBlock; extern CConditionVariable cvBlockChange; extern bool fImporting; diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index ba71725222e..d30fa32eb47 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -333,6 +333,9 @@ static const CRPCCommand vRPCCommands[] = { "hidden", "invalidateblock", &invalidateblock, true, false }, { "hidden", "reconsiderblock", &reconsiderblock, true, false }, { "hidden", "setmocktime", &setmocktime, true, false }, +#ifdef ENABLE_WALLET + { "hidden", "resendwallettransactions", &resendwallettransactions, true, true }, +#endif #ifdef ENABLE_WALLET /* Wallet */ diff --git a/src/rpcserver.h b/src/rpcserver.h index f63438ecb88..7011d41fc1b 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -207,6 +207,7 @@ extern json_spirit::Value getwalletinfo(const json_spirit::Array& params, bool f extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value setmocktime(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index ae4cd3c592a..aa9aefb0de6 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -18,13 +18,13 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); - g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); + g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); } void UnregisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); - g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); + g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); diff --git a/src/validationinterface.h b/src/validationinterface.h index b21b6e57825..cb261f6aa38 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -33,7 +33,7 @@ protected: virtual void SetBestChain(const CBlockLocator &locator) {}; virtual void UpdatedTransaction(const uint256 &hash) {}; virtual void Inventory(const uint256 &hash) {}; - virtual void ResendWalletTransactions() {}; + virtual void ResendWalletTransactions(int64_t nBestBlockTime) {}; virtual void BlockChecked(const CBlock&, const CValidationState&) {}; friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); @@ -52,7 +52,7 @@ struct CMainSignals { /** Notifies listeners about an inventory item being seen on the network. */ boost::signals2::signal Inventory; /** Tells listeners to broadcast their data. */ - boost::signals2::signal Broadcast; + boost::signals2::signal Broadcast; /** Notifies listeners of a block validation result */ boost::signals2::signal BlockChecked; }; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 9318c1b2b15..29f3eda15dd 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2096,3 +2096,25 @@ Value getwalletinfo(const Array& params, bool fHelp) obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); return obj; } + +Value resendwallettransactions(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "resendwallettransactions\n" + "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n" + "Intended only for testing; the wallet code periodically re-broadcasts\n" + "automatically.\n" + "Returns array of transaction ids that were re-broadcast.\n" + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + std::vector txids = pwalletMain->ResendWalletTransactionsBefore(GetTime()); + Array result; + BOOST_FOREACH(const uint256& txid, txids) + { + result.push_back(txid.ToString()); + } + return result; +} diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 09bcda577ed..a10123002ee 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1114,15 +1114,17 @@ void CWallet::ReacceptWalletTransactions() } } -void CWalletTx::RelayWalletTransaction() +bool CWalletTx::RelayWalletTransaction() { if (!IsCoinBase()) { if (GetDepthInMainChain() == 0) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); RelayTransaction((CTransaction)*this); + return true; } } + return false; } set CWalletTx::GetConflicts() const @@ -1324,7 +1326,31 @@ bool CWalletTx::IsTrusted() const return true; } -void CWallet::ResendWalletTransactions() +std::vector CWallet::ResendWalletTransactionsBefore(int64_t nTime) +{ + std::vector result; + + LOCK(cs_wallet); + // Sort them in chronological order + multimap mapSorted; + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + // Don't rebroadcast if newer than nTime: + if (wtx.nTimeReceived > nTime) + continue; + mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + } + BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) + { + CWalletTx& wtx = *item.second; + if (wtx.RelayWalletTransaction()) + result.push_back(wtx.GetHash()); + } + return result; +} + +void CWallet::ResendWalletTransactions(int64_t nBestBlockTime) { // Do this infrequently and randomly to avoid giving away // that these are our transactions. @@ -1336,30 +1362,15 @@ void CWallet::ResendWalletTransactions() return; // Only do it if there's been a new block since last time - if (nTimeBestReceived < nLastResend) + if (nBestBlockTime < nLastResend) return; nLastResend = GetTime(); - // Rebroadcast any of our txes that aren't in a block yet - LogPrintf("ResendWalletTransactions()\n"); - { - LOCK(cs_wallet); - // Sort them in chronological order - multimap mapSorted; - BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) - { - CWalletTx& wtx = item.second; - // Don't rebroadcast until it's had plenty of time that - // it should have gotten in already by now. - if (nTimeBestReceived - (int64_t)wtx.nTimeReceived > 5 * 60) - mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); - } - BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) - { - CWalletTx& wtx = *item.second; - wtx.RelayWalletTransaction(); - } - } + // Rebroadcast unconfirmed txes older than 5 minutes before the last + // block was found: + std::vector relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60); + if (!relayed.empty()) + LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size()); } /** @} */ // end of mapWallet diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 4a13f02195f..6ae1c87b1d3 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -381,7 +381,7 @@ public: int64_t GetTxTime() const; int GetRequestCount() const; - void RelayWalletTransaction(); + bool RelayWalletTransaction(); std::set GetConflicts() const; }; @@ -614,7 +614,8 @@ public: void EraseFromWallet(const uint256 &hash); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); void ReacceptWalletTransactions(); - void ResendWalletTransactions(); + void ResendWalletTransactions(int64_t nBestBlockTime); + std::vector ResendWalletTransactionsBefore(int64_t nTime); CAmount GetBalance() const; CAmount GetUnconfirmedBalance() const; CAmount GetImmatureBalance() const; From cbb2cf5522983e4a952cfb25e577b1998a06c769 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 24 Mar 2015 22:14:44 +0100 Subject: [PATCH 0343/2337] Fix --disable-wallet build after merge of #5681 --- src/init.cpp | 1 + src/rpcmining.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 95ec45015f6..2a13af6690a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -23,6 +23,7 @@ #include "ui_interface.h" #include "util.h" #include "utilmoneystr.h" +#include "validationinterface.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" #include "wallet/walletdb.h" diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index a07acea9aad..17db221cb4c 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -13,6 +13,7 @@ #include "pow.h" #include "rpcserver.h" #include "util.h" +#include "validationinterface.h" #ifdef ENABLE_WALLET #include "wallet/db.h" #include "wallet/wallet.h" From bd006110fb51f1fc0cbbeef3ed6eaae66b296d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 11 Feb 2015 11:58:11 +0100 Subject: [PATCH 0344/2337] Consensus: Refactor: Introduce Consensus::Params class --- src/Makefile.am | 1 + src/chainparams.cpp | 51 +++++++++++++++++++----------------------- src/chainparams.h | 35 ++++++++++++----------------- src/consensus/params.h | 32 ++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 49 deletions(-) create mode 100644 src/consensus/params.h diff --git a/src/Makefile.am b/src/Makefile.am index 1b3e0d9d5b6..37184b62863 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -87,6 +87,7 @@ BITCOIN_CORE_H = \ coins.h \ compat.h \ compressor.h \ + consensus/params.h \ core_io.h \ wallet/db.h \ eccryptoverify.h \ diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 2bc8976510a..3e20d9f8f2e 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -101,6 +101,14 @@ class CMainParams : public CChainParams { public: CMainParams() { strNetworkID = "main"; + consensus.nSubsidyHalvingInterval = 210000; + consensus.nMajorityEnforceBlockUpgrade = 750; + consensus.nMajorityRejectBlockOutdated = 950; + consensus.nMajorityWindow = 1000; + consensus.powLimit = ~arith_uint256(0) >> 32; + consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks + consensus.nPowTargetSpacing = 10 * 60; + consensus.fPowAllowMinDifficultyBlocks = false; /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -112,14 +120,7 @@ public: pchMessageStart[3] = 0xd9; vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 8333; - bnProofOfWorkLimit = ~arith_uint256(0) >> 32; - nSubsidyHalvingInterval = 210000; - nEnforceBlockUpgradeMajority = 750; - nRejectBlockOutdatedMajority = 950; - nToCheckBlockUpgradeMajority = 1000; nMinerThreads = 0; - nTargetTimespan = 14 * 24 * 60 * 60; // two weeks - nTargetSpacing = 10 * 60; /** * Build the genesis block. Note that the output of the genesis coinbase cannot @@ -146,8 +147,8 @@ public: genesis.nBits = 0x1d00ffff; genesis.nNonce = 2083236893; - hashGenesisBlock = genesis.GetHash(); - assert(hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be")); @@ -167,7 +168,6 @@ public: fRequireRPCPassword = true; fMiningRequiresPeers = true; fDefaultCheckMemPool = false; - fAllowMinDifficultyBlocks = false; fRequireStandard = true; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = false; @@ -187,24 +187,23 @@ class CTestNetParams : public CMainParams { public: CTestNetParams() { strNetworkID = "test"; + consensus.nMajorityEnforceBlockUpgrade = 51; + consensus.nMajorityRejectBlockOutdated = 75; + consensus.nMajorityWindow = 100; + consensus.fPowAllowMinDifficultyBlocks = true; pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; pchMessageStart[3] = 0x07; vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"); nDefaultPort = 18333; - nEnforceBlockUpgradeMajority = 51; - nRejectBlockOutdatedMajority = 75; - nToCheckBlockUpgradeMajority = 100; nMinerThreads = 0; - nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks - nTargetSpacing = 10 * 60; //! Modify the testnet genesis block so the timestamp is valid for a later start. genesis.nTime = 1296688602; genesis.nNonce = 414098458; - hashGenesisBlock = genesis.GetHash(); - assert(hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); vFixedSeeds.clear(); vSeeds.clear(); @@ -224,7 +223,6 @@ public: fRequireRPCPassword = true; fMiningRequiresPeers = true; fDefaultCheckMemPool = false; - fAllowMinDifficultyBlocks = true; fRequireStandard = false; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; @@ -243,24 +241,22 @@ class CRegTestParams : public CTestNetParams { public: CRegTestParams() { strNetworkID = "regtest"; + consensus.nSubsidyHalvingInterval = 150; + consensus.nMajorityEnforceBlockUpgrade = 750; + consensus.nMajorityRejectBlockOutdated = 950; + consensus.nMajorityWindow = 1000; + consensus.powLimit = ~arith_uint256(0) >> 1; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; - nSubsidyHalvingInterval = 150; - nEnforceBlockUpgradeMajority = 750; - nRejectBlockOutdatedMajority = 950; - nToCheckBlockUpgradeMajority = 1000; nMinerThreads = 1; - nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks - nTargetSpacing = 10 * 60; - bnProofOfWorkLimit = ~arith_uint256(0) >> 1; genesis.nTime = 1296688602; genesis.nBits = 0x207fffff; genesis.nNonce = 2; - hashGenesisBlock = genesis.GetHash(); + consensus.hashGenesisBlock = genesis.GetHash(); nDefaultPort = 18444; - assert(hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); + assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. @@ -268,7 +264,6 @@ public: fRequireRPCPassword = false; fMiningRequiresPeers = false; fDefaultCheckMemPool = true; - fAllowMinDifficultyBlocks = true; fRequireStandard = false; fMineBlocksOnDemand = true; fTestnetToBeDeprecatedFieldRPC = false; diff --git a/src/chainparams.h b/src/chainparams.h index 134dcd65582..aa2ec1e3012 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -6,11 +6,12 @@ #ifndef BITCOIN_CHAINPARAMS_H #define BITCOIN_CHAINPARAMS_H +#include "arith_uint256.h" #include "chainparamsbase.h" #include "checkpoints.h" +#include "consensus/params.h" #include "primitives/block.h" #include "protocol.h" -#include "arith_uint256.h" #include @@ -39,16 +40,16 @@ public: MAX_BASE58_TYPES }; - const uint256& HashGenesisBlock() const { return hashGenesisBlock; } + const Consensus::Params& GetConsensus() const { return consensus; } + const uint256& HashGenesisBlock() const { return consensus.hashGenesisBlock; } const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } - int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; } - /** Used to check majorities for block version upgrade */ - int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; } - int RejectBlockOutdatedMajority() const { return nRejectBlockOutdatedMajority; } - int ToCheckBlockUpgradeMajority() const { return nToCheckBlockUpgradeMajority; } + const arith_uint256& ProofOfWorkLimit() const { return consensus.powLimit; } + int SubsidyHalvingInterval() const { return consensus.nSubsidyHalvingInterval; } + int EnforceBlockUpgradeMajority() const { return consensus.nMajorityEnforceBlockUpgrade; } + int RejectBlockOutdatedMajority() const { return consensus.nMajorityRejectBlockOutdated; } + int ToCheckBlockUpgradeMajority() const { return consensus.nMajorityWindow; } /** Used if GenerateBitcoins is called with a negative number of threads */ int DefaultMinerThreads() const { return nMinerThreads; } @@ -59,12 +60,12 @@ public: /** Default value for -checkmempool argument */ bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; } /** Allow mining of a min-difficulty block */ - bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; } + bool AllowMinDifficultyBlocks() const { return consensus.fPowAllowMinDifficultyBlocks; } /** Make standard checks */ bool RequireStandard() const { return fRequireStandard; } - int64_t TargetTimespan() const { return nTargetTimespan; } - int64_t TargetSpacing() const { return nTargetSpacing; } - int64_t DifficultyAdjustmentInterval() const { return nTargetTimespan / nTargetSpacing; } + int64_t TargetTimespan() const { return consensus.nPowTargetTimespan; } + int64_t TargetSpacing() const { return consensus.nPowTargetSpacing; } + int64_t DifficultyAdjustmentInterval() const { return consensus.nPowTargetTimespan / consensus.nPowTargetSpacing; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ @@ -78,18 +79,11 @@ public: protected: CChainParams() {} - uint256 hashGenesisBlock; + Consensus::Params consensus; CMessageHeader::MessageStartChars pchMessageStart; //! Raw pub key bytes for the broadcast alert signing key. std::vector vAlertPubKey; int nDefaultPort; - arith_uint256 bnProofOfWorkLimit; - int nSubsidyHalvingInterval; - int nEnforceBlockUpgradeMajority; - int nRejectBlockOutdatedMajority; - int nToCheckBlockUpgradeMajority; - int64_t nTargetTimespan; - int64_t nTargetSpacing; int nMinerThreads; std::vector vSeeds; std::vector base58Prefixes[MAX_BASE58_TYPES]; @@ -99,7 +93,6 @@ protected: bool fRequireRPCPassword; bool fMiningRequiresPeers; bool fDefaultCheckMemPool; - bool fAllowMinDifficultyBlocks; bool fRequireStandard; bool fMineBlocksOnDemand; bool fTestnetToBeDeprecatedFieldRPC; diff --git a/src/consensus/params.h b/src/consensus/params.h new file mode 100644 index 00000000000..c4cfa48c7e8 --- /dev/null +++ b/src/consensus/params.h @@ -0,0 +1,32 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H +#define BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H + +#include "arith_uint256.h" +#include "uint256.h" + +namespace Consensus { +/** + * Parameters that influence chain consensus. + */ +struct Params { + uint256 hashGenesisBlock; + int nSubsidyHalvingInterval; + /** Used to check majorities for block version upgrade */ + int nMajorityEnforceBlockUpgrade; + int nMajorityRejectBlockOutdated; + int nMajorityWindow; + /** Proof of work parameters */ + arith_uint256 powLimit; + bool fPowAllowMinDifficultyBlocks; + int64_t nPowTargetSpacing; + int64_t nPowTargetTimespan; + int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } +}; +} // namespace Consensus + +#endif // BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H From d698ef690f62c08676dcf9ddc0988e23aa81cbff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Sun, 15 Feb 2015 02:21:42 +0100 Subject: [PATCH 0345/2337] Consensus: Refactor: Decouple pow.o from chainparams.o --- src/main.cpp | 6 +++--- src/main.h | 1 - src/miner.cpp | 4 ++-- src/pow.cpp | 39 +++++++++++++++++++-------------------- src/pow.h | 8 +++++--- src/rpcmining.cpp | 2 +- src/test/pow_tests.cpp | 13 +++++++++---- src/txdb.cpp | 4 +++- 8 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0ffacc338e6..1d78eedc1ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1158,7 +1158,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) } // Check the header - if (!CheckProofOfWork(block.GetHash(), block.nBits)) + if (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); return true; @@ -2462,7 +2462,7 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW) { // Check proof of work matches claimed amount - if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits)) + if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) return state.DoS(50, error("CheckBlockHeader(): proof of work failed"), REJECT_INVALID, "high-hash"); @@ -2545,7 +2545,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta int nHeight = pindexPrev->nHeight+1; // Check proof of work - if ((block.nBits != GetNextWorkRequired(pindexPrev, &block))) + if (block.nBits != GetNextWorkRequired(pindexPrev, &block, Params().GetConsensus())) return state.DoS(100, error("%s: incorrect proof of work", __func__), REJECT_INVALID, "bad-diffbits"); diff --git a/src/main.h b/src/main.h index b0bab6f7bf5..09ffc4d28ba 100644 --- a/src/main.h +++ b/src/main.h @@ -17,7 +17,6 @@ #include "primitives/block.h" #include "primitives/transaction.h" #include "net.h" -#include "pow.h" #include "script/script.h" #include "script/sigcache.h" #include "script/standard.h" diff --git a/src/miner.cpp b/src/miner.cpp index 01212b19c4c..cf08b782296 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -84,7 +84,7 @@ void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) // Updating time can change work required on testnet: if (Params().AllowMinDifficultyBlocks()) - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); } CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) @@ -326,7 +326,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); UpdateTime(pblock, pindexPrev); - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); pblock->nNonce = 0; pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); diff --git a/src/pow.cpp b/src/pow.cpp index eb899ffc942..3c5a8d9d963 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -7,34 +7,33 @@ #include "arith_uint256.h" #include "chain.h" -#include "chainparams.h" #include "primitives/block.h" #include "uint256.h" #include "util.h" -unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock) +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { - unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact(); + unsigned int nProofOfWorkLimit = params.powLimit.GetCompact(); // Genesis block if (pindexLast == NULL) return nProofOfWorkLimit; // Only change once per difficulty adjustment interval - if ((pindexLast->nHeight+1) % Params().DifficultyAdjustmentInterval() != 0) + if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0) { - if (Params().AllowMinDifficultyBlocks()) + if (params.fPowAllowMinDifficultyBlocks) { // Special difficulty rule for testnet: // If the new block's timestamp is more than 2* 10 minutes // then allow mining of a min-difficulty block. - if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2) + if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2) return nProofOfWorkLimit; else { // Return the last non-special-min-difficulty-rules-block const CBlockIndex* pindex = pindexLast; - while (pindex->pprev && pindex->nHeight % Params().DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) + while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) pindex = pindex->pprev; return pindex->nBits; } @@ -44,22 +43,22 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead // Go back by what we want to be 14 days worth of blocks const CBlockIndex* pindexFirst = pindexLast; - for (int i = 0; pindexFirst && i < Params().DifficultyAdjustmentInterval()-1; i++) + for (int i = 0; pindexFirst && i < params.DifficultyAdjustmentInterval()-1; i++) pindexFirst = pindexFirst->pprev; assert(pindexFirst); - return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime()); + return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); } -unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime) +unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) { // Limit adjustment step int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan); - if (nActualTimespan < Params().TargetTimespan()/4) - nActualTimespan = Params().TargetTimespan()/4; - if (nActualTimespan > Params().TargetTimespan()*4) - nActualTimespan = Params().TargetTimespan()*4; + if (nActualTimespan < params.nPowTargetTimespan/4) + nActualTimespan = params.nPowTargetTimespan/4; + if (nActualTimespan > params.nPowTargetTimespan*4) + nActualTimespan = params.nPowTargetTimespan*4; // Retarget arith_uint256 bnNew; @@ -67,21 +66,21 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF bnNew.SetCompact(pindexLast->nBits); bnOld = bnNew; bnNew *= nActualTimespan; - bnNew /= Params().TargetTimespan(); + bnNew /= params.nPowTargetTimespan; - if (bnNew > Params().ProofOfWorkLimit()) - bnNew = Params().ProofOfWorkLimit(); + if (bnNew > params.powLimit) + bnNew = params.powLimit; /// debug print LogPrintf("GetNextWorkRequired RETARGET\n"); - LogPrintf("Params().TargetTimespan() = %d nActualTimespan = %d\n", Params().TargetTimespan(), nActualTimespan); + LogPrintf("params.nPowTargetTimespan = %d nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan); LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString()); LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString()); return bnNew.GetCompact(); } -bool CheckProofOfWork(uint256 hash, unsigned int nBits) +bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params) { bool fNegative; bool fOverflow; @@ -90,7 +89,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range - if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit()) + if (fNegative || bnTarget == 0 || fOverflow || bnTarget > params.powLimit) return error("CheckProofOfWork(): nBits below minimum work"); // Check proof of work matches claimed amount diff --git a/src/pow.h b/src/pow.h index a5fbba62364..a5d32db178e 100644 --- a/src/pow.h +++ b/src/pow.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_POW_H #define BITCOIN_POW_H +#include "consensus/params.h" + #include class CBlockHeader; @@ -13,11 +15,11 @@ class CBlockIndex; class uint256; class arith_uint256; -unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock); -unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime); +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&); +unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ -bool CheckProofOfWork(uint256 hash, unsigned int nBits); +bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&); arith_uint256 GetBlockProof(const CBlockIndex& block); #endif // BITCOIN_POW_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 17db221cb4c..fcba7e222d5 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -181,7 +181,7 @@ Value setgenerate(const Array& params, bool fHelp) LOCK(cs_main); IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); } - while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits)) { + while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { // Yes, there is a chance every nonce could fail to satisfy the -regtest // target -- 1 in 2^(2^32). That ain't gonna happen. ++pblock->nNonce; diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 7b197c527de..4ce1591c353 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -17,51 +17,56 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(get_next_work) { SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& params = Params().GetConsensus(); int64_t nLastRetargetTime = 1261130161; // Block #30240 CBlockIndex pindexLast; pindexLast.nHeight = 32255; pindexLast.nTime = 1262152739; // Block #32255 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00d86a); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00d86a); } /* Test the constraint on the upper bound for next work */ BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) { SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& params = Params().GetConsensus(); int64_t nLastRetargetTime = 1231006505; // Block #0 CBlockIndex pindexLast; pindexLast.nHeight = 2015; pindexLast.nTime = 1233061996; // Block #2015 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00ffff); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00ffff); } /* Test the constraint on the lower bound for actual time taken */ BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) { SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& params = Params().GetConsensus(); int64_t nLastRetargetTime = 1279008237; // Block #66528 CBlockIndex pindexLast; pindexLast.nHeight = 68543; pindexLast.nTime = 1279297671; // Block #68543 pindexLast.nBits = 0x1c05a3f4; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1c0168fd); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1c0168fd); } /* Test the constraint on the upper bound for actual time taken */ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) { SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& params = Params().GetConsensus(); + int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time CBlockIndex pindexLast; pindexLast.nHeight = 46367; pindexLast.nTime = 1269211443; // Block #46367 pindexLast.nBits = 0x1c387f6f; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00e1fd); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00e1fd); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/txdb.cpp b/src/txdb.cpp index f3281502891..df9ff8d8c98 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -5,6 +5,8 @@ #include "txdb.h" +#include "chainparams.h" +#include "hash.h" #include "main.h" #include "pow.h" #include "uint256.h" @@ -223,7 +225,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nStatus = diskindex.nStatus; pindexNew->nTx = diskindex.nTx; - if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits)) + if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, Params().GetConsensus())) return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString()); pcursor->Next(); From ad9e86dca11dce023d827d342e966f3806c39d27 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 25 Mar 2015 13:13:09 -0400 Subject: [PATCH 0346/2337] Keep mempool consistent during block-reorgs This fixes a subtle bug involving block re-orgs and non-standard transactions. Start with a block containing a non-standard transaction, and one or more transactions spending it in the memory pool. Then re-org away from that block to another chain that does not contain the non-standard transaction. Result before this fix: the dependent transactions get stuck in the mempool without their parent, putting the mempool in an inconsistent state. Tested with a new unit test. --- src/Makefile.test.include | 1 + src/test/mempool_tests.cpp | 104 +++++++++++++++++++++++++++++++++++++ src/txmempool.cpp | 12 +++++ 3 files changed, 117 insertions(+) create mode 100644 src/test/mempool_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 8dd0a28454f..52ff3f224fb 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -50,6 +50,7 @@ BITCOIN_TESTS =\ test/hash_tests.cpp \ test/key_tests.cpp \ test/main_tests.cpp \ + test/mempool_tests.cpp \ test/miner_tests.cpp \ test/mruset_tests.cpp \ test/multisig_tests.cpp \ diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp new file mode 100644 index 00000000000..0996e13c485 --- /dev/null +++ b/src/test/mempool_tests.cpp @@ -0,0 +1,104 @@ +// Copyright (c) 2011-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "main.h" +#include "txmempool.h" +#include "util.h" + +#include "test/test_bitcoin.h" + +#include +#include + +BOOST_FIXTURE_TEST_SUITE(mempool_tests, TestingSetup) + +BOOST_AUTO_TEST_CASE(MempoolRemoveTest) +{ + // Test CTxMemPool::remove functionality + + // Parent transaction with three children, + // and three grand-children: + CMutableTransaction txParent; + txParent.vin.resize(1); + txParent.vin[0].scriptSig = CScript() << OP_11; + txParent.vout.resize(3); + for (int i = 0; i < 3; i++) + { + txParent.vout[i].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + txParent.vout[i].nValue = 33000LL; + } + CMutableTransaction txChild[3]; + for (int i = 0; i < 3; i++) + { + txChild[i].vin.resize(1); + txChild[i].vin[0].scriptSig = CScript() << OP_11; + txChild[i].vin[0].prevout.hash = txParent.GetHash(); + txChild[i].vin[0].prevout.n = i; + txChild[i].vout.resize(1); + txChild[i].vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + txChild[i].vout[0].nValue = 11000LL; + } + CMutableTransaction txGrandChild[3]; + for (int i = 0; i < 3; i++) + { + txGrandChild[i].vin.resize(1); + txGrandChild[i].vin[0].scriptSig = CScript() << OP_11; + txGrandChild[i].vin[0].prevout.hash = txChild[i].GetHash(); + txGrandChild[i].vin[0].prevout.n = 0; + txGrandChild[i].vout.resize(1); + txGrandChild[i].vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + txGrandChild[i].vout[0].nValue = 11000LL; + } + + + CTxMemPool testPool(CFeeRate(0)); + std::list removed; + + // Nothing in pool, remove should do nothing: + testPool.remove(txParent, removed, true); + BOOST_CHECK_EQUAL(removed.size(), 0); + + // Just the parent: + testPool.addUnchecked(txParent.GetHash(), CTxMemPoolEntry(txParent, 0, 0, 0.0, 1)); + testPool.remove(txParent, removed, true); + BOOST_CHECK_EQUAL(removed.size(), 1); + removed.clear(); + + // Parent, children, grandchildren: + testPool.addUnchecked(txParent.GetHash(), CTxMemPoolEntry(txParent, 0, 0, 0.0, 1)); + for (int i = 0; i < 3; i++) + { + testPool.addUnchecked(txChild[i].GetHash(), CTxMemPoolEntry(txChild[i], 0, 0, 0.0, 1)); + testPool.addUnchecked(txGrandChild[i].GetHash(), CTxMemPoolEntry(txGrandChild[i], 0, 0, 0.0, 1)); + } + // Remove Child[0], GrandChild[0] should be removed: + testPool.remove(txChild[0], removed, true); + BOOST_CHECK_EQUAL(removed.size(), 2); + removed.clear(); + // ... make sure grandchild and child are gone: + testPool.remove(txGrandChild[0], removed, true); + BOOST_CHECK_EQUAL(removed.size(), 0); + testPool.remove(txChild[0], removed, true); + BOOST_CHECK_EQUAL(removed.size(), 0); + // Remove parent, all children/grandchildren should go: + testPool.remove(txParent, removed, true); + BOOST_CHECK_EQUAL(removed.size(), 5); + BOOST_CHECK_EQUAL(testPool.size(), 0); + removed.clear(); + + // Add children and grandchildren, but NOT the parent (simulate the parent being in a block) + for (int i = 0; i < 3; i++) + { + testPool.addUnchecked(txChild[i].GetHash(), CTxMemPoolEntry(txChild[i], 0, 0, 0.0, 1)); + testPool.addUnchecked(txGrandChild[i].GetHash(), CTxMemPoolEntry(txGrandChild[i], 0, 0, 0.0, 1)); + } + // Now remove the parent, as might happen if a block-re-org occurs but the parent cannot be + // put into the mempool (maybe because it is non-standard): + testPool.remove(txParent, removed, true); + BOOST_CHECK_EQUAL(removed.size(), 6); + BOOST_CHECK_EQUAL(testPool.size(), 0); + removed.clear(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 0d506603276..85ea3f77b51 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -444,6 +444,18 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem LOCK(cs); std::deque txToRemove; txToRemove.push_back(origTx.GetHash()); + if (fRecursive && !mapTx.count(origTx.GetHash())) { + // If recursively removing but origTx isn't in the mempool + // be sure to remove any children that are in the pool. This can + // happen during chain re-orgs if origTx isn't re-accepted into + // the mempool for any reason. + for (unsigned int i = 0; i < origTx.vout.size(); i++) { + std::map::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i)); + if (it == mapNextTx.end()) + continue; + txToRemove.push_back(it->second.ptx->GetHash()); + } + } while (!txToRemove.empty()) { uint256 hash = txToRemove.front(); From 1cc0e96e9cc7aa094ddee9fe5b192b3ac1a59da8 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 26 Mar 2015 11:06:27 -0700 Subject: [PATCH 0347/2337] Trivial optimization: use GetAncestor to compute new target --- src/pow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pow.cpp b/src/pow.cpp index 3c5a8d9d963..cf7ac387f23 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -42,9 +42,9 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead } // Go back by what we want to be 14 days worth of blocks - const CBlockIndex* pindexFirst = pindexLast; - for (int i = 0; pindexFirst && i < params.DifficultyAdjustmentInterval()-1; i++) - pindexFirst = pindexFirst->pprev; + int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1); + assert(nHeightFirst >= 0); + const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst); assert(pindexFirst); return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); From ba0fa0d9bca19c2bab34459249e4a79426683bf0 Mon Sep 17 00:00:00 2001 From: dexX7 Date: Fri, 27 Mar 2015 01:07:49 +0100 Subject: [PATCH 0348/2337] Initialization: set fallback locale as environment variable The scope of `std::locale::global` appears to be smaller than `setenv("LC_ALL", ...)` and insufficient to fix messed up locale settings for the whole application. --- src/util.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 4192e44ae1b..5fef3a40ddf 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -723,18 +723,19 @@ void RenameThread(const char* name) void SetupEnvironment() { + std::locale loc("C"); // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale // may be invalid, in which case the "C" locale is used as fallback. #if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) try { - std::locale(""); // Raises a runtime error if current locale is invalid + loc = std::locale(""); // Raises a runtime error if current locale is invalid } catch (const std::runtime_error&) { - std::locale::global(std::locale("C")); + setenv("LC_ALL", "C", 1); } #endif // The path locale is lazy initialized and to avoid deinitialization errors // in multithreading environments, it is set explicitly by the main thread. - boost::filesystem::path::imbue(std::locale()); + boost::filesystem::path::imbue(loc); } void SetThreadPriority(int nPriority) From c8168331a259692d2a61faab647606c14f588dd9 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 14 Mar 2015 12:39:44 +0100 Subject: [PATCH 0349/2337] [Qt] fix rpc console font size to flexible metrics should fix #5897 --- src/qt/rpcconsole.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index ccde44fb29a..29c971ec79d 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -357,7 +357,6 @@ void RPCConsole::clear() ui->messagesWidget->document()->setDefaultStyleSheet( "table { }" "td.time { color: #808080; padding-top: 3px; } " - "td.message { font-family: monospace; font-size: 12px; } " // Todo: Remove fixed font-size "td.cmd-request { color: #006060; } " "td.cmd-error { color: red; } " "b { color: #006060; } " From 3fcfbc8ac5fcba474151ceedf61c4e433e433474 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 13 Mar 2015 09:25:34 -0700 Subject: [PATCH 0350/2337] Add a consistency check for the block chain data structures This adds a -checkblockindex (defaulting to true for regtest), which occasionally does a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive, and mapBlocksUnlinked. --- src/chainparams.cpp | 6 +- src/chainparams.h | 6 +- src/init.cpp | 5 +- src/main.cpp | 146 ++++++++++++++++++++++++++++++++++++-- src/main.h | 1 + src/test/test_bitcoin.cpp | 1 + 6 files changed, 153 insertions(+), 12 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 3e20d9f8f2e..8633d51b2f3 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -167,7 +167,7 @@ public: fRequireRPCPassword = true; fMiningRequiresPeers = true; - fDefaultCheckMemPool = false; + fDefaultConsistencyChecks = false; fRequireStandard = true; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = false; @@ -222,7 +222,7 @@ public: fRequireRPCPassword = true; fMiningRequiresPeers = true; - fDefaultCheckMemPool = false; + fDefaultConsistencyChecks = false; fRequireStandard = false; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; @@ -263,7 +263,7 @@ public: fRequireRPCPassword = false; fMiningRequiresPeers = false; - fDefaultCheckMemPool = true; + fDefaultConsistencyChecks = true; fRequireStandard = false; fMineBlocksOnDemand = true; fTestnetToBeDeprecatedFieldRPC = false; diff --git a/src/chainparams.h b/src/chainparams.h index aa2ec1e3012..d0613beb455 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -57,8 +57,8 @@ public: bool RequireRPCPassword() const { return fRequireRPCPassword; } /** Make miner wait to have peers to avoid wasting work */ bool MiningRequiresPeers() const { return fMiningRequiresPeers; } - /** Default value for -checkmempool argument */ - bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; } + /** Default value for -checkmempool and -checkblockindex argument */ + bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } /** Allow mining of a min-difficulty block */ bool AllowMinDifficultyBlocks() const { return consensus.fPowAllowMinDifficultyBlocks; } /** Make standard checks */ @@ -92,7 +92,7 @@ protected: std::vector vFixedSeeds; bool fRequireRPCPassword; bool fMiningRequiresPeers; - bool fDefaultCheckMemPool; + bool fDefaultConsistencyChecks; bool fRequireStandard; bool fMineBlocksOnDemand; bool fTestnetToBeDeprecatedFieldRPC; diff --git a/src/init.cpp b/src/init.cpp index 2a13af6690a..d6957ebdbca 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -697,8 +697,9 @@ bool AppInit2(boost::thread_group& threadGroup) if (GetBoolArg("-benchmark", false)) InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench.")); - // Checkmempool defaults to true in regtest mode - mempool.setSanityCheck(GetBoolArg("-checkmempool", Params().DefaultCheckMemPool())); + // Checkmempool and checkblockindex default to true in regtest mode + mempool.setSanityCheck(GetBoolArg("-checkmempool", Params().DefaultConsistencyChecks())); + fCheckBlockIndex = GetBoolArg("-checkblockindex", Params().DefaultConsistencyChecks()); Checkpoints::fEnabled = GetBoolArg("-checkpoints", true); // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency diff --git a/src/main.cpp b/src/main.cpp index 1d78eedc1ae..b8f9b949a7b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -53,6 +53,7 @@ bool fImporting = false; bool fReindex = false; bool fTxIndex = false; bool fIsBareMultisigStd = true; +bool fCheckBlockIndex = false; unsigned int nCoinCacheSize = 5000; /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */ @@ -74,6 +75,7 @@ void EraseOrphansFor(NodeId peer); * and going backwards. */ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired); +static void CheckBlockIndex(); /** Constant stuff for coinbase transactions we create: */ CScript COINBASE_FLAGS; @@ -85,7 +87,7 @@ namespace { struct CBlockIndexWorkComparator { - bool operator()(CBlockIndex *pa, CBlockIndex *pb) { + bool operator()(CBlockIndex *pa, CBlockIndex *pb) const { // First sort by most total work, ... if (pa->nChainWork > pb->nChainWork) return false; if (pa->nChainWork < pb->nChainWork) return true; @@ -107,8 +109,8 @@ namespace { CBlockIndex *pindexBestInvalid; /** - * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least - * as good as our current tip. Entries may be failed, though. + * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and + * as good as our current tip or better. Entries may be failed, though. */ set setBlockIndexCandidates; /** Number of nodes with fSyncStarted. */ @@ -2226,6 +2228,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); + CheckBlockIndex(); // Write changes periodically to disk, after relay. if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) { @@ -2362,7 +2365,9 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl CBlockIndex *pindex = queue.front(); queue.pop_front(); pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; - setBlockIndexCandidates.insert(pindex); + if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) { + setBlockIndexCandidates.insert(pindex); + } std::pair::iterator, std::multimap::iterator> range = mapBlocksUnlinked.equal_range(pindex); while (range.first != range.second) { std::multimap::iterator it = range.first; @@ -2725,6 +2730,7 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis if (pindex && pfrom) { mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); } + CheckBlockIndex(); if (!ret) return error("%s: AcceptBlock FAILED", __func__); } @@ -3213,6 +3219,136 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) return nLoaded > 0; } +void static CheckBlockIndex() +{ + if (!fCheckBlockIndex) { + return; + } + + LOCK(cs_main); + + // Build forward-pointing map of the entire block tree. + std::multimap forward; + for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) { + forward.insert(std::make_pair(it->second->pprev, it->second)); + } + + assert(forward.size() == mapBlockIndex.size()); + + std::pair::iterator,std::multimap::iterator> rangeGenesis = forward.equal_range(NULL); + CBlockIndex *pindex = rangeGenesis.first->second; + rangeGenesis.first++; + assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL. + + // Iterate over the entire block tree, using depth-first search. + // Along the way, remember whether there are blocks on the path from genesis + // block being explored which are the first to have certain properties. + size_t nNodes = 0; + int nHeight = 0; + CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid. + CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA. + CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not). + CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not). + CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not). + while (pindex != NULL) { + nNodes++; + if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex; + if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex; + if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex; + if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex; + if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex; + + // Begin: actual consistency checks. + if (pindex->pprev == NULL) { + // Genesis block checks. + assert(pindex->GetBlockHash() == Params().HashGenesisBlock()); // Genesis block's hash must match. + assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block. + } + assert((pindexFirstMissing != NULL) == (pindex->nChainTx == 0)); // nChainTx == 0 is used to signal that all parent block's transaction data is available. + assert(pindex->nHeight == nHeight); // nHeight must be consistent. + assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's. + assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks. + assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid + if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid + if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid + if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid + if (pindexFirstInvalid == NULL) { + // Checks for not-invalid blocks. + assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents. + } + if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstMissing == NULL) { + if (pindexFirstInvalid == NULL) { // If this block sorts at least as good as the current tip and is valid, it must be in setBlockIndexCandidates. + assert(setBlockIndexCandidates.count(pindex)); + } + } else { // If this block sorts worse than the current tip, it cannot be in setBlockIndexCandidates. + assert(setBlockIndexCandidates.count(pindex) == 0); + } + // Check whether this block is in mapBlocksUnlinked. + std::pair::iterator,std::multimap::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev); + bool foundInUnlinked = false; + while (rangeUnlinked.first != rangeUnlinked.second) { + assert(rangeUnlinked.first->first == pindex->pprev); + if (rangeUnlinked.first->second == pindex) { + foundInUnlinked = true; + break; + } + rangeUnlinked.first++; + } + if (pindex->pprev && pindex->nStatus & BLOCK_HAVE_DATA && pindexFirstMissing != NULL) { + if (pindexFirstInvalid == NULL) { // If this block has block data available, some parent doesn't, and has no invalid parents, it must be in mapBlocksUnlinked. + assert(foundInUnlinked); + } + } else { // If this block does not have block data available, or all parents do, it cannot be in mapBlocksUnlinked. + assert(!foundInUnlinked); + } + // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow + // End: actual consistency checks. + + // Try descending into the first subnode. + std::pair::iterator,std::multimap::iterator> range = forward.equal_range(pindex); + if (range.first != range.second) { + // A subnode was found. + pindex = range.first->second; + nHeight++; + continue; + } + // This is a leaf node. + // Move upwards until we reach a node of which we have not yet visited the last child. + while (pindex) { + // We are going to either move to a parent or a sibling of pindex. + // If pindex was the first with a certain property, unset the corresponding variable. + if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL; + if (pindex == pindexFirstMissing) pindexFirstMissing = NULL; + if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL; + if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL; + if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL; + // Find our parent. + CBlockIndex* pindexPar = pindex->pprev; + // Find which child we just visited. + std::pair::iterator,std::multimap::iterator> rangePar = forward.equal_range(pindexPar); + while (rangePar.first->second != pindex) { + assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child. + rangePar.first++; + } + // Proceed to the next one. + rangePar.first++; + if (rangePar.first != rangePar.second) { + // Move to the sibling. + pindex = rangePar.first->second; + break; + } else { + // Move up further. + pindex = pindexPar; + nHeight--; + continue; + } + } + } + + // Check that we actually traversed the entire map. + assert(nNodes == forward.size()); +} + ////////////////////////////////////////////////////////////////////////////// // // CAlert @@ -3971,6 +4107,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256()); } + + CheckBlockIndex(); } else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing diff --git a/src/main.h b/src/main.h index ac73b242f1f..73a31d6d70b 100644 --- a/src/main.h +++ b/src/main.h @@ -123,6 +123,7 @@ extern bool fReindex; extern int nScriptCheckThreads; extern bool fTxIndex; extern bool fIsBareMultisigStd; +extern bool fCheckBlockIndex; extern unsigned int nCoinCacheSize; extern CFeeRate minRelayTxFee; diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 7d5207b11e6..b5c729d6a9b 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -29,6 +29,7 @@ extern void noui_connect(); BasicTestingSetup::BasicTestingSetup() { fPrintToDebugLog = false; // don't want to write to debug.log file + fCheckBlockIndex = true; SelectParams(CBaseChainParams::MAIN); } BasicTestingSetup::~BasicTestingSetup() From 9d09322b41776a0d6ecde182f731eff77d0f052b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 27 Mar 2015 14:03:36 -0700 Subject: [PATCH 0351/2337] Squashed 'src/secp256k1/' changes from 50cc6ab..1897b8e 1897b8e Merge pull request #229 efc571c Add simple testcases for signing with rfc6979 extra entropy. 1573a10 Add ability to pass extra entropy to rfc6979 3087bc4 Merge pull request #228 d9b9f11 Merge pull request #218 0065a8f Eliminate multiple-returns from secp256k1.c. 354ffa3 Make secp256k1_ec_pubkey_create reject oversized secrets. 27bc131 Silence some warnings from pedantic static analysis tools, improve compatibility with C++. 3b7ea63 Merge pull request #221 f789c5b Merge pull request #215 4bc273b Merge pull request #222 137a8ec Merge pull request #216 7c3771d Disable overlength-strings warnings. 8956111 use 128-bit hex seed 02efd06 Use RFC6979 for test PRNGs ae55e85 Use faster byteswapping and avoid alignment-increasing casts. 443cd4b Get rid of hex format and some binary conversions 0bada0e Merge #214: Improve signing API documentation & specification 8030d7c Improve signing API documentation & specification 7b2fc1c Merge #213: Removed gotos, which are hard to trace and maintain. 11690d3 Removed gotos, which are hard to trace and maintain. 122a1ec Merge pull request #205 035406d Merge pull request #206 2d4cd53 Merge pull request #161 34b898d Additional comments for the testing PRNG and a seeding fix. 6efd6e7 Some comments explaining some of the constants in the code. ffccfd2 x86_64 assembly optimization for scalar_4x64 67cbdf0 Merge pull request #207 039723d Benchmarks for all internal operations 6cc8425 Include a comment on secp256k1_ecdsa_sign explaining low-s. f88343f Merge pull request #203 d61e899 Add group operation counts 2473f17 Merge pull request #202 b5bbce6 Some readme updates, e.g. removal of the GMP field. f0d851e Merge pull request #201 a0ea884 Merge pull request #200 f735446 Convert the rest of the codebase to C89. bf2e1ac Convert tests to C89. (also fixes a use of bare "inline" in field) fc8285f Merge pull request #199 fff412e Merge pull request #197 4be8d6f Centralize the definition of uint128_t and use it uniformly. d9543c9 Switch scalar code to C89. fcc48c4 Remove the non-storage cmov 55422b6 Switch ecmult_gen to use storage types 41f8455 Use group element storage type in EC multiplications e68d720 Add group element storage type ff889f7 Field storage type 7137be8 Merge pull request #196 0768bd5 Get rid of variable-length hex string conversions e84e761 Merge pull request #195 792bcdb Covert several more files to C89. 45cdf44 Merge pull request #193 17db09e Merge pull request #194 402878a fix ifdef/ifndef 25b35c7 Convert field code to strict C89 (+ long long, +__int128) 3627437 C89 nits and dead code removal. a9f350d Merge pull request #191 4732d26 Convert the field/group/ecdsa constant initialization to static consts 19f3e76 Remove unused secp256k1_fe_inner_{start, stop} functions f1ebfe3 Convert the scalar constant initialization to static consts git-subtree-dir: src/secp256k1 git-subtree-split: 1897b8e90bbbdcd919427c9a8ae35b420e919d8f --- Makefile.am | 10 +- README.md | 20 +- configure.ac | 12 +- include/secp256k1.h | 46 ++- src/bench.h | 29 +- src/bench_internal.c | 318 +++++++++++++++++ src/bench_inv.c | 52 --- src/bench_recover.c | 17 +- src/bench_sign.c | 15 +- src/bench_verify.c | 14 +- src/ecdsa.h | 4 - src/ecdsa_impl.h | 175 +++++----- src/eckey_impl.h | 19 +- src/ecmult_gen_impl.h | 57 +-- src/ecmult_impl.h | 144 +++++--- src/field.h | 27 +- src/field_10x26.h | 26 ++ src/field_10x26_impl.h | 185 ++++++---- src/field_5x52.h | 26 ++ src/field_5x52_impl.h | 82 +++-- src/field_5x52_int128_impl.h | 120 +++---- src/field_impl.h | 187 ++++------ src/group.h | 42 ++- src/group_impl.h | 250 +++++++------ src/hash.h | 4 +- src/hash_impl.h | 117 +++---- src/num_gmp_impl.h | 29 +- src/scalar.h | 7 +- src/scalar_4x64.h | 2 + src/scalar_4x64_impl.h | 551 +++++++++++++++++++++++++++-- src/scalar_8x32.h | 2 + src/scalar_8x32_impl.h | 87 +++-- src/scalar_impl.h | 279 +++++++-------- src/secp256k1.c | 311 +++++++++-------- src/testrand.h | 6 +- src/testrand_impl.h | 48 +-- src/tests.c | 657 ++++++++++++++++++++++------------- src/util.h | 21 +- 38 files changed, 2529 insertions(+), 1469 deletions(-) create mode 100644 src/bench_internal.c delete mode 100644 src/bench_inv.c diff --git a/Makefile.am b/Makefile.am index 985c172eba2..cc15338b7ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -49,7 +49,7 @@ libsecp256k1_la_LIBADD = $(SECP_LIBS) noinst_PROGRAMS = if USE_BENCHMARK -noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_inv +noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal bench_verify_SOURCES = src/bench_verify.c bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) bench_verify_LDFLAGS = -static @@ -59,10 +59,10 @@ bench_recover_LDFLAGS = -static bench_sign_SOURCES = src/bench_sign.c bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) bench_sign_LDFLAGS = -static -bench_inv_SOURCES = src/bench_inv.c -bench_inv_LDADD = $(SECP_LIBS) -bench_inv_LDFLAGS = -static -bench_inv_CPPFLAGS = $(SECP_INCLUDES) +bench_internal_SOURCES = src/bench_internal.c +bench_internal_LDADD = $(SECP_LIBS) +bench_internal_LDFLAGS = -static +bench_internal_CPPFLAGS = $(SECP_INCLUDES) endif if USE_TESTS diff --git a/README.md b/README.md index 1e49f494166..6095db42205 100644 --- a/README.md +++ b/README.md @@ -5,25 +5,29 @@ libsecp256k1 Optimized C library for EC operations on curve secp256k1. -This library is experimental, so use at your own risk. +This library is a work in progress and is being used to research best practices. Use at your own risk. Features: -* Low-level field and group operations on secp256k1. -* ECDSA signing/verification and key generation. +* secp256k1 ECDSA signing/verification and key generation. * Adding/multiplying private/public keys. * Serialization/parsing of private keys, public keys, signatures. +* Constant time, constant memory access signing and pubkey generation. +* Derandomized DSA (via RFC6979 or with a caller provided function.) * Very efficient implementation. Implementation details ---------------------- * General - * Avoid dynamic memory usage almost everywhere. + * No runtime heap allocation. + * Extensive testing infrastructure. + * Structured to facilitate review and analysis. + * Intended to be portable to any system with a C89 compiler and uint64_t support. + * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.") * Field operations * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys). * Using 10 26-bit limbs. - * Using GMP. * Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman). * Scalar operations * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. @@ -33,14 +37,15 @@ Implementation details * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). * Use addition between points in Jacobian and affine coordinates where possible. * Use a unified addition/doubling formula where necessary to avoid data-dependent branches. + * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space. * Point multiplication for verification (a*P + b*G). * Use wNAF notation for point multiplicands. * Use a much larger window for multiples of G, using precomputed multiples. * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. - * Optionally use secp256k1's efficiently-computable endomorphism to split the multiplicands into 4 half-sized ones first. + * Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. * Point multiplication for signing * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. - * Slice the precomputed table in memory per byte, so memory access to the table becomes uniform. + * Access the table with branch-free conditional moves so memory access is uniform. * No data-dependent branches * The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally. @@ -52,4 +57,5 @@ libsecp256k1 is built using autotools: $ ./autogen.sh $ ./configure $ make + $ ./tests $ sudo make install # optional diff --git a/configure.ac b/configure.ac index f691156ff74..3dc1829516e 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ AC_CONFIG_MACRO_DIR([build-aux/m4]) AC_CANONICAL_HOST AH_TOP([#ifndef LIBSECP256K1_CONFIG_H]) AH_TOP([#define LIBSECP256K1_CONFIG_H]) -AH_BOTTOM([#endif //LIBSECP256K1_CONFIG_H]) +AH_BOTTOM([#endif /*LIBSECP256K1_CONFIG_H*/]) AM_INIT_AUTOMAKE([foreign subdir-objects]) LT_INIT @@ -22,9 +22,9 @@ if test "x$CFLAGS" = "x"; then CFLAGS="-O3 -g" fi -AC_PROG_CC_C99 -if test x"$ac_cv_prog_cc_c99" = x"no"; then - AC_MSG_ERROR([c99 compiler support required]) +AC_PROG_CC_C89 +if test x"$ac_cv_prog_cc_c89" = x"no"; then + AC_MSG_ERROR([c89 compiler support required]) fi case $host in @@ -70,7 +70,7 @@ esac CFLAGS="$CFLAGS -W" -warn_CFLAGS="-Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function" +warn_CFLAGS="-std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings" saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $warn_CFLAGS" AC_MSG_CHECKING([if ${CC} supports ${warn_CFLAGS}]) @@ -305,6 +305,8 @@ if test x"$use_endomorphism" = x"yes"; then AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization]) fi +AC_C_BIGENDIAN() + AC_MSG_NOTICE([Using assembly optimizations: $set_asm]) AC_MSG_NOTICE([Using field implementation: $set_field]) AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) diff --git a/include/secp256k1.h b/include/secp256k1.h index cfdae31eaf8..a6e39d13dbe 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -78,7 +78,7 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); /** A pointer to a function to deterministically generate a nonce. - * Returns: 1 if a nonce was succesfully generated. 0 will cause signing to fail. + * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail. * In: msg32: the 32-byte message hash being verified (will not be NULL) * key32: pointer to a 32-byte secret key (will not be NULL) * attempt: how many iterations we have tried to find a nonce. @@ -97,7 +97,10 @@ typedef int (*secp256k1_nonce_function_t)( const void *data ); -/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. */ +/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. + * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of + * extra entropy. + */ extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979; /** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ @@ -106,15 +109,43 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default; /** Create an ECDSA signature. * Returns: 1: signature created - * 0: the nonce generation function failed + * 0: the nonce generation function failed, the private key was invalid, or there is not + * enough space in the signature (as indicated by siglen). * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid) + * seckey: pointer to a 32-byte secret key (cannot be NULL) * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) * In/Out: siglen: pointer to an int with the length of sig, which will be updated - * to contain the actual signature length (<=72). + * to contain the actual signature length (<=72). If 0 is returned, this will be + * set to zero. * Requires starting using SECP256K1_START_SIGN. + * + * The sig always has an s value in the lower half of the range (From 0x1 + * to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, + * inclusive), unlike many other implementations. + * With ECDSA a third-party can can forge a second distinct signature + * of the same message given a single initial signature without knowing + * the key by setting s to its additive inverse mod-order, 'flipping' the + * sign of the random point R which is not included in the signature. + * Since the forgery is of the same message this isn't universally + * problematic, but in systems where message malleability or uniqueness + * of signatures is important this can cause issues. This forgery can be + * blocked by all verifiers forcing signers to use a canonical form. The + * lower-S form reduces the size of signatures slightly on average when + * variable length encodings (such as DER) are used and is cheap to + * verify, making it a good choice. Security of always using lower-S is + * assured because anyone can trivially modify a signature after the + * fact to enforce this property. Adjusting it inside the signing + * function avoids the need to re-serialize or have curve specific + * constants outside of the library. By always using a canonical form + * even in applications where it isn't needed it becomes possible to + * impose a requirement later if a need is discovered. + * No other forms of ECDSA malleability are known and none seem likely, + * but there is no formal proof that ECDSA, even with this additional + * restriction, is free of other malleability. Commonly used serialization + * schemes will also accept various non-unique encodings, so care should + * be taken when this property is required for an application. */ int secp256k1_ecdsa_sign( const unsigned char *msg32, @@ -127,12 +158,13 @@ int secp256k1_ecdsa_sign( /** Create a compact ECDSA signature (64 byte + recovery id). * Returns: 1: signature created - * 0: the nonce generation function failed + * 0: the nonce generation function failed, or the secret key was invalid. * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid) + * seckey: pointer to a 32-byte secret key (cannot be NULL) * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) * Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL) + * In case 0 is returned, the returned signature length will be zero. * recid: pointer to an int, which will be updated to contain the recovery id (can be NULL) * Requires starting using SECP256K1_START_SIGN. */ diff --git a/src/bench.h b/src/bench.h index 668ec39f715..0559b3e8535 100644 --- a/src/bench.h +++ b/src/bench.h @@ -17,21 +17,40 @@ static double gettimedouble(void) { return tv.tv_usec * 0.000001 + tv.tv_sec; } -void run_benchmark(void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { +void print_number(double x) { + double y = x; + int c = 0; + if (y < 0.0) y = -y; + while (y < 100.0) { + y *= 10.0; + c++; + } + printf("%.*f", c, x); +} + +void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { + int i; double min = HUGE_VAL; double sum = 0.0; double max = 0.0; - for (int i = 0; i < count; i++) { + for (i = 0; i < count; i++) { + double begin, total; if (setup) setup(data); - double begin = gettimedouble(); + begin = gettimedouble(); benchmark(data); - double total = gettimedouble() - begin; + total = gettimedouble() - begin; if (teardown) teardown(data); if (total < min) min = total; if (total > max) max = total; sum += total; } - printf("min %.3fus / avg %.3fus / max %.3fus\n", min * 1000000.0 / iter, (sum / count) * 1000000.0 / iter, max * 1000000.0 / iter); + printf("%s: min ", name); + print_number(min * 1000000.0 / iter); + printf("us / avg "); + print_number((sum / count) * 1000000.0 / iter); + printf("us / avg "); + print_number(max * 1000000.0 / iter); + printf("us\n"); } #endif diff --git a/src/bench_internal.c b/src/bench_internal.c new file mode 100644 index 00000000000..a960549b94f --- /dev/null +++ b/src/bench_internal.c @@ -0,0 +1,318 @@ +/********************************************************************** + * Copyright (c) 2014-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ +#include + +#include "include/secp256k1.h" + +#include "util.h" +#include "hash_impl.h" +#include "num_impl.h" +#include "field_impl.h" +#include "group_impl.h" +#include "scalar_impl.h" +#include "ecmult_impl.h" +#include "bench.h" + +typedef struct { + secp256k1_scalar_t scalar_x, scalar_y; + secp256k1_fe_t fe_x, fe_y; + secp256k1_ge_t ge_x, ge_y; + secp256k1_gej_t gej_x, gej_y; + unsigned char data[32]; + int wnaf[256]; +} bench_inv_t; + +void bench_setup(void* arg) { + bench_inv_t *data = (bench_inv_t*)arg; + + static const unsigned char init_x[32] = { + 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13, + 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35, + 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59, + 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83 + }; + + static const unsigned char init_y[32] = { + 0x82, 0x83, 0x85, 0x87, 0x8b, 0x8d, 0x81, 0x83, + 0x97, 0xad, 0xaf, 0xb5, 0xb9, 0xbb, 0xbf, 0xc5, + 0xdb, 0xdd, 0xe3, 0xe7, 0xe9, 0xef, 0xf3, 0xf9, + 0x11, 0x15, 0x17, 0x1b, 0x1d, 0xb1, 0xbf, 0xd3 + }; + + secp256k1_scalar_set_b32(&data->scalar_x, init_x, NULL); + secp256k1_scalar_set_b32(&data->scalar_y, init_y, NULL); + secp256k1_fe_set_b32(&data->fe_x, init_x); + secp256k1_fe_set_b32(&data->fe_y, init_y); + CHECK(secp256k1_ge_set_xo_var(&data->ge_x, &data->fe_x, 0)); + CHECK(secp256k1_ge_set_xo_var(&data->ge_y, &data->fe_y, 1)); + secp256k1_gej_set_ge(&data->gej_x, &data->ge_x); + secp256k1_gej_set_ge(&data->gej_y, &data->ge_y); + memcpy(data->data, init_x, 32); +} + +void bench_scalar_add(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 2000000; i++) { + secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + } +} + +void bench_scalar_negate(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 2000000; i++) { + secp256k1_scalar_negate(&data->scalar_x, &data->scalar_x); + } +} + +void bench_scalar_sqr(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 200000; i++) { + secp256k1_scalar_sqr(&data->scalar_x, &data->scalar_x); + } +} + +void bench_scalar_mul(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 200000; i++) { + secp256k1_scalar_mul(&data->scalar_x, &data->scalar_x, &data->scalar_y); + } +} + +#ifdef USE_ENDOMORPHISM +void bench_scalar_split(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_scalar_t l, r; + secp256k1_scalar_split_lambda_var(&l, &r, &data->scalar_x); + secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + } +} +#endif + +void bench_scalar_inverse(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 2000; i++) { + secp256k1_scalar_inverse(&data->scalar_x, &data->scalar_x); + secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + } +} + +void bench_scalar_inverse_var(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 2000; i++) { + secp256k1_scalar_inverse_var(&data->scalar_x, &data->scalar_x); + secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + } +} + +void bench_field_normalize(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 2000000; i++) { + secp256k1_fe_normalize(&data->fe_x); + } +} + +void bench_field_normalize_weak(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 2000000; i++) { + secp256k1_fe_normalize_weak(&data->fe_x); + } +} + +void bench_field_mul(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 200000; i++) { + secp256k1_fe_mul(&data->fe_x, &data->fe_x, &data->fe_y); + } +} + +void bench_field_sqr(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 200000; i++) { + secp256k1_fe_sqr(&data->fe_x, &data->fe_x); + } +} + +void bench_field_inverse(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_fe_inv(&data->fe_x, &data->fe_x); + secp256k1_fe_add(&data->fe_x, &data->fe_y); + } +} + +void bench_field_inverse_var(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_fe_inv_var(&data->fe_x, &data->fe_x); + secp256k1_fe_add(&data->fe_x, &data->fe_y); + } +} + +void bench_field_sqrt_var(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_fe_sqrt_var(&data->fe_x, &data->fe_x); + secp256k1_fe_add(&data->fe_x, &data->fe_y); + } +} + +void bench_group_double_var(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 200000; i++) { + secp256k1_gej_double_var(&data->gej_x, &data->gej_x); + } +} + +void bench_group_add_var(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 200000; i++) { + secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y); + } +} + +void bench_group_add_affine(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 200000; i++) { + secp256k1_gej_add_ge(&data->gej_x, &data->gej_x, &data->ge_y); + } +} + +void bench_group_add_affine_var(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 200000; i++) { + secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y); + } +} + +void bench_ecmult_wnaf(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_ecmult_wnaf(data->wnaf, &data->scalar_x, WINDOW_A); + secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + } +} + + +void bench_sha256(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + secp256k1_sha256_t sha; + + for (i = 0; i < 20000; i++) { + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, data->data, 32); + secp256k1_sha256_finalize(&sha, data->data); + } +} + +void bench_hmac_sha256(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + secp256k1_hmac_sha256_t hmac; + + for (i = 0; i < 20000; i++) { + secp256k1_hmac_sha256_initialize(&hmac, data->data, 32); + secp256k1_hmac_sha256_write(&hmac, data->data, 32); + secp256k1_hmac_sha256_finalize(&hmac, data->data); + } +} + +void bench_rfc6979_hmac_sha256(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + secp256k1_rfc6979_hmac_sha256_t rng; + + for (i = 0; i < 20000; i++) { + secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 32, data->data, 32, NULL, 0); + secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32); + } +} + + +int have_flag(int argc, char** argv, char *flag) { + char** argm = argv + argc; + argv++; + if (argv == argm) { + return 1; + } + while (argv != NULL && argv != argm) { + if (strcmp(*argv, flag) == 0) return 1; + argv++; + } + return 0; +} + +int main(int argc, char **argv) { + bench_inv_t data; + if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, 2000000); + if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, 2000000); + if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, 200000); +#ifdef USE_ENDOMORPHISM + if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, 20000); +#endif + if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, 2000); + if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, 2000); + + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, 2000000); + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, 2000000); + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, 20000); + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, 20000); + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt_var", bench_field_sqrt_var, bench_setup, NULL, &data, 10, 20000); + + if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000); + + if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000); + + if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000); + if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, 20000); + if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, 20000); + return 0; +} diff --git a/src/bench_inv.c b/src/bench_inv.c deleted file mode 100644 index 3bdedea30e4..00000000000 --- a/src/bench_inv.c +++ /dev/null @@ -1,52 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ -#include - -#include "include/secp256k1.h" - -#include "util.h" -#include "num_impl.h" -#include "field_impl.h" -#include "group_impl.h" -#include "scalar_impl.h" -#include "bench.h" - -typedef struct { - secp256k1_scalar_t base, x; -} bench_inv_t; - -void bench_inv_setup(void* arg) { - bench_inv_t *data = (bench_inv_t*)arg; - - static const unsigned char init[32] = { - 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13, - 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35, - 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59, - 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83 - }; - - secp256k1_scalar_set_b32(&data->base, init, NULL); - secp256k1_scalar_set_b32(&data->x, init, NULL); -} - -void bench_inv(void* arg) { - bench_inv_t *data = (bench_inv_t*)arg; - - for (int i=0; i<20000; i++) { - secp256k1_scalar_inverse(&data->x, &data->x); - secp256k1_scalar_add(&data->x, &data->x, &data->base); - } -} - -int main(void) { - secp256k1_ge_start(); - - bench_inv_t data; - run_benchmark(bench_inv, bench_inv_setup, NULL, &data, 10, 20000); - - secp256k1_ge_stop(); - return 0; -} diff --git a/src/bench_recover.c b/src/bench_recover.c index b1e0f33efa6..6991cc9d6c5 100644 --- a/src/bench_recover.c +++ b/src/bench_recover.c @@ -14,13 +14,15 @@ typedef struct { } bench_recover_t; void bench_recover(void* arg) { + int i; bench_recover_t *data = (bench_recover_t*)arg; - unsigned char pubkey[33]; - for (int i=0; i<20000; i++) { + + for (i = 0; i < 20000; i++) { + int j; int pubkeylen = 33; CHECK(secp256k1_ecdsa_recover_compact(data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2)); - for (int j = 0; j < 32; j++) { + for (j = 0; j < 32; j++) { data->sig[j + 32] = data->msg[j]; /* Move former message to S. */ data->msg[j] = data->sig[j]; /* Move former R to message. */ data->sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ @@ -29,17 +31,18 @@ void bench_recover(void* arg) { } void bench_recover_setup(void* arg) { + int i; bench_recover_t *data = (bench_recover_t*)arg; - for (int i = 0; i < 32; i++) data->msg[i] = 1 + i; - for (int i = 0; i < 64; i++) data->sig[i] = 65 + i; + for (i = 0; i < 32; i++) data->msg[i] = 1 + i; + for (i = 0; i < 64; i++) data->sig[i] = 65 + i; } int main(void) { + bench_recover_t data; secp256k1_start(SECP256K1_START_VERIFY); - bench_recover_t data; - run_benchmark(bench_recover, bench_recover_setup, NULL, &data, 10, 20000); + run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, 20000); secp256k1_stop(); return 0; diff --git a/src/bench_sign.c b/src/bench_sign.c index 2276f00b9a6..c5b6829a846 100644 --- a/src/bench_sign.c +++ b/src/bench_sign.c @@ -14,20 +14,23 @@ typedef struct { } bench_sign_t; static void bench_sign_setup(void* arg) { + int i; bench_sign_t *data = (bench_sign_t*)arg; - for (int i = 0; i < 32; i++) data->msg[i] = i + 1; - for (int i = 0; i < 32; i++) data->key[i] = i + 65; + for (i = 0; i < 32; i++) data->msg[i] = i + 1; + for (i = 0; i < 32; i++) data->key[i] = i + 65; } static void bench_sign(void* arg) { + int i; bench_sign_t *data = (bench_sign_t*)arg; unsigned char sig[64]; - for (int i=0; i<20000; i++) { + for (i = 0; i < 20000; i++) { + int j; int recid = 0; CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, NULL, NULL, &recid)); - for (int j = 0; j < 32; j++) { + for (j = 0; j < 32; j++) { data->msg[j] = sig[j]; /* Move former R to message. */ data->key[j] = sig[j + 32]; /* Move former S to key. */ } @@ -35,10 +38,10 @@ static void bench_sign(void* arg) { } int main(void) { + bench_sign_t data; secp256k1_start(SECP256K1_START_SIGN); - bench_sign_t data; - run_benchmark(bench_sign, bench_sign_setup, NULL, &data, 10, 20000); + run_benchmark("ecdsa_sign", bench_sign, bench_sign_setup, NULL, &data, 10, 20000); secp256k1_stop(); return 0; diff --git a/src/bench_verify.c b/src/bench_verify.c index a58ca84347b..c279305a0db 100644 --- a/src/bench_verify.c +++ b/src/bench_verify.c @@ -21,9 +21,10 @@ typedef struct { } benchmark_verify_t; static void benchmark_verify(void* arg) { + int i; benchmark_verify_t* data = (benchmark_verify_t*)arg; - for (int i=0; i<20000; i++) { + for (i = 0; i < 20000; i++) { data->sig[data->siglen - 1] ^= (i & 0xFF); data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); @@ -35,18 +36,19 @@ static void benchmark_verify(void* arg) { } int main(void) { - secp256k1_start(SECP256K1_START_VERIFY | SECP256K1_START_SIGN); - + int i; benchmark_verify_t data; - for (int i = 0; i < 32; i++) data.msg[i] = 1 + i; - for (int i = 0; i < 32; i++) data.key[i] = 33 + i; + secp256k1_start(SECP256K1_START_VERIFY | SECP256K1_START_SIGN); + + for (i = 0; i < 32; i++) data.msg[i] = 1 + i; + for (i = 0; i < 32; i++) data.key[i] = 33 + i; data.siglen = 72; secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, NULL, NULL); data.pubkeylen = 33; CHECK(secp256k1_ec_pubkey_create(data.pubkey, &data.pubkeylen, data.key, 1)); - run_benchmark(benchmark_verify, NULL, NULL, &data, 10, 20000); + run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000); secp256k1_stop(); return 0; diff --git a/src/ecdsa.h b/src/ecdsa.h index 5fc5230c36c..c195e7afcbf 100644 --- a/src/ecdsa.h +++ b/src/ecdsa.h @@ -10,9 +10,6 @@ #include "scalar.h" #include "group.h" -static void secp256k1_ecsda_start(void); -static void secp256k1_ecdsa_stop(void); - typedef struct { secp256k1_scalar_t r, s; } secp256k1_ecdsa_sig_t; @@ -22,6 +19,5 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message); static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid); static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid); -static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s); #endif diff --git a/src/ecdsa_impl.h b/src/ecdsa_impl.h index 674650c1e9f..1a77649390e 100644 --- a/src/ecdsa_impl.h +++ b/src/ecdsa_impl.h @@ -15,71 +15,69 @@ #include "ecmult_gen.h" #include "ecdsa.h" -typedef struct { - secp256k1_fe_t order_as_fe; - secp256k1_fe_t p_minus_order; -} secp256k1_ecdsa_consts_t; +/** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1 + * sage: for t in xrange(1023, -1, -1): + * .. p = 2**256 - 2**32 - t + * .. if p.is_prime(): + * .. print '%x'%p + * .. break + * 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f' + * sage: a = 0 + * sage: b = 7 + * sage: F = FiniteField (p) + * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) + * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' + */ +static const secp256k1_fe_t secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, + 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL +); -static const secp256k1_ecdsa_consts_t *secp256k1_ecdsa_consts = NULL; - -static void secp256k1_ecdsa_start(void) { - if (secp256k1_ecdsa_consts != NULL) - return; - - /* Allocate. */ - secp256k1_ecdsa_consts_t *ret = (secp256k1_ecdsa_consts_t*)checked_malloc(sizeof(secp256k1_ecdsa_consts_t)); - - static const unsigned char order[] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 - }; - - secp256k1_fe_set_b32(&ret->order_as_fe, order); - secp256k1_fe_negate(&ret->p_minus_order, &ret->order_as_fe, 1); - secp256k1_fe_normalize_var(&ret->p_minus_order); - - /* Set the global pointer. */ - secp256k1_ecdsa_consts = ret; -} - -static void secp256k1_ecdsa_stop(void) { - if (secp256k1_ecdsa_consts == NULL) - return; - - secp256k1_ecdsa_consts_t *c = (secp256k1_ecdsa_consts_t*)secp256k1_ecdsa_consts; - secp256k1_ecdsa_consts = NULL; - free(c); -} +/** Difference between field and order, values 'p' and 'n' values defined in + * "Standards for Efficient Cryptography" (SEC2) 2.7.1. + * sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F + * sage: a = 0 + * sage: b = 7 + * sage: F = FiniteField (p) + * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) + * '14551231950b75fc4402da1722fc9baee' + */ +static const secp256k1_fe_t secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( + 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL +); static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) { + unsigned char ra[32] = {0}, sa[32] = {0}; + const unsigned char *rp; + const unsigned char *sp; + int lenr; + int lens; + int overflow; if (sig[0] != 0x30) return 0; - int lenr = sig[3]; + lenr = sig[3]; if (5+lenr >= size) return 0; - int lens = sig[lenr+5]; + lens = sig[lenr+5]; if (sig[1] != lenr+lens+4) return 0; if (lenr+lens+6 > size) return 0; if (sig[2] != 0x02) return 0; if (lenr == 0) return 0; if (sig[lenr+4] != 0x02) return 0; if (lens == 0) return 0; - const unsigned char *sp = sig + 6 + lenr; + sp = sig + 6 + lenr; while (lens > 0 && sp[0] == 0) { lens--; sp++; } if (lens > 32) return 0; - const unsigned char *rp = sig + 4; + rp = sig + 4; while (lenr > 0 && rp[0] == 0) { lenr--; rp++; } if (lenr > 32) return 0; - unsigned char ra[32] = {0}, sa[32] = {0}; memcpy(ra + 32 - lenr, rp, lenr); memcpy(sa + 32 - lens, sp, lens); - int overflow = 0; + overflow = 0; secp256k1_scalar_set_b32(&r->r, ra, &overflow); if (overflow) return 0; secp256k1_scalar_set_b32(&r->s, sa, &overflow); @@ -89,10 +87,10 @@ static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned ch static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) { unsigned char r[33] = {0}, s[33] = {0}; - secp256k1_scalar_get_b32(&r[1], &a->r); - secp256k1_scalar_get_b32(&s[1], &a->s); unsigned char *rp = r, *sp = s; int lenR = 33, lenS = 33; + secp256k1_scalar_get_b32(&r[1], &a->r); + secp256k1_scalar_get_b32(&s[1], &a->s); while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; } while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; } if (*size < 6+lenS+lenR) @@ -110,93 +108,100 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se } static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { + unsigned char c[32]; + secp256k1_scalar_t sn, u1, u2; + secp256k1_fe_t xr; + secp256k1_gej_t pubkeyj; + secp256k1_gej_t pr; + if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) return 0; - secp256k1_scalar_t sn, u1, u2; secp256k1_scalar_inverse_var(&sn, &sig->s); secp256k1_scalar_mul(&u1, &sn, message); secp256k1_scalar_mul(&u2, &sn, &sig->r); - secp256k1_gej_t pubkeyj; secp256k1_gej_set_ge(&pubkeyj, pubkey); - secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1); + secp256k1_gej_set_ge(&pubkeyj, pubkey); + secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1); if (secp256k1_gej_is_infinity(&pr)) { return 0; } - unsigned char c[32]; secp256k1_scalar_get_b32(c, &sig->r); - secp256k1_fe_t xr; secp256k1_fe_set_b32(&xr, c); - // We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) - // in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p), - // compute the remainder modulo n, and compare it to xr. However: - // - // xr == X(pr) mod n - // <=> exists h. (xr + h * n < p && xr + h * n == X(pr)) - // [Since 2 * n > p, h can only be 0 or 1] - // <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr)) - // [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p] - // <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p) - // [Multiplying both sides of the equations by pr.z^2 mod p] - // <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x) - // - // Thus, we can avoid the inversion, but we have to check both cases separately. - // secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. + /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) + * in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p), + * compute the remainder modulo n, and compare it to xr. However: + * + * xr == X(pr) mod n + * <=> exists h. (xr + h * n < p && xr + h * n == X(pr)) + * [Since 2 * n > p, h can only be 0 or 1] + * <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr)) + * [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p] + * <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p) + * [Multiplying both sides of the equations by pr.z^2 mod p] + * <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x) + * + * Thus, we can avoid the inversion, but we have to check both cases separately. + * secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. + */ if (secp256k1_gej_eq_x_var(&xr, &pr)) { - // xr.x == xr * xr.z^2 mod p, so the signature is valid. + /* xr.x == xr * xr.z^2 mod p, so the signature is valid. */ return 1; } - if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_consts->p_minus_order) >= 0) { - // xr + p >= n, so we can skip testing the second case. + if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) { + /* xr + p >= n, so we can skip testing the second case. */ return 0; } - secp256k1_fe_add(&xr, &secp256k1_ecdsa_consts->order_as_fe); + secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe); if (secp256k1_gej_eq_x_var(&xr, &pr)) { - // (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. + /* (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. */ return 1; } return 0; } static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) { + unsigned char brx[32]; + secp256k1_fe_t fx; + secp256k1_ge_t x; + secp256k1_gej_t xj; + secp256k1_scalar_t rn, u1, u2; + secp256k1_gej_t qj; + if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) return 0; - unsigned char brx[32]; secp256k1_scalar_get_b32(brx, &sig->r); - secp256k1_fe_t fx; VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* brx comes from a scalar, so is less than the order; certainly less than p */ if (recid & 2) { - if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_consts->p_minus_order) >= 0) + if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) return 0; - secp256k1_fe_add(&fx, &secp256k1_ecdsa_consts->order_as_fe); + secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); } - secp256k1_ge_t x; if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) return 0; - secp256k1_gej_t xj; secp256k1_gej_set_ge(&xj, &x); - secp256k1_scalar_t rn, u1, u2; secp256k1_scalar_inverse_var(&rn, &sig->r); secp256k1_scalar_mul(&u1, &rn, message); secp256k1_scalar_negate(&u1, &u1); secp256k1_scalar_mul(&u2, &rn, &sig->s); - secp256k1_gej_t qj; secp256k1_ecmult(&qj, &xj, &u2, &u1); secp256k1_ge_set_gej_var(pubkey, &qj); return !secp256k1_gej_is_infinity(&qj); } static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) { - secp256k1_gej_t rp; - secp256k1_ecmult_gen(&rp, nonce); - secp256k1_ge_t r; - secp256k1_ge_set_gej(&r, &rp); unsigned char b[32]; + secp256k1_gej_t rp; + secp256k1_ge_t r; + secp256k1_scalar_t n; + int overflow = 0; + + secp256k1_ecmult_gen(&rp, nonce); + secp256k1_ge_set_gej(&r, &rp); secp256k1_fe_normalize(&r.x); secp256k1_fe_normalize(&r.y); secp256k1_fe_get_b32(b, &r.x); - int overflow = 0; secp256k1_scalar_set_b32(&sig->r, b, &overflow); if (secp256k1_scalar_is_zero(&sig->r)) { /* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */ @@ -206,7 +211,6 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_ } if (recid) *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); - secp256k1_scalar_t n; secp256k1_scalar_mul(&n, &sig->r, seckey); secp256k1_scalar_add(&n, &n, message); secp256k1_scalar_inverse(&sig->s, nonce); @@ -224,9 +228,4 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_ return 1; } -static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s) { - sig->r = *r; - sig->s = *s; -} - #endif diff --git a/src/eckey_impl.h b/src/eckey_impl.h index b3fa7d9bd21..3e06d05b47c 100644 --- a/src/eckey_impl.h +++ b/src/eckey_impl.h @@ -51,13 +51,16 @@ static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char } static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen) { + unsigned char c[32] = {0}; const unsigned char *end = privkey + privkeylen; + int lenb = 0; + int len = 0; + int overflow = 0; /* sequence header */ if (end < privkey+1 || *privkey != 0x30) return 0; privkey++; /* sequence length constructor */ - int lenb = 0; if (end < privkey+1 || !(*privkey & 0x80)) return 0; lenb = *privkey & ~0x80; privkey++; @@ -66,7 +69,6 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned if (end < privkey+lenb) return 0; /* sequence length */ - int len = 0; len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0); privkey += lenb; if (end < privkey+len) @@ -78,8 +80,6 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned /* sequence element 1: octet string, up to 32 bytes */ if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) return 0; - int overflow = 0; - unsigned char c[32] = {0}; memcpy(c + 32 - privkey[1], privkey + 2, privkey[1]); secp256k1_scalar_set_b32(key, c, &overflow); memset(c, 0, 32); @@ -88,8 +88,9 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) { secp256k1_gej_t rp; - secp256k1_ecmult_gen(&rp, key); secp256k1_ge_t r; + int pubkeylen = 0; + secp256k1_ecmult_gen(&rp, key); secp256k1_ge_set_gej(&r, &rp); if (compressed) { static const unsigned char begin[] = { @@ -110,7 +111,6 @@ static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privke memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); secp256k1_scalar_get_b32(ptr, key); ptr += 32; memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); - int pubkeylen = 0; if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 1)) { return 0; } @@ -137,7 +137,6 @@ static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privke memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); secp256k1_scalar_get_b32(ptr, key); ptr += 32; memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); - int pubkeylen = 0; if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 0)) { return 0; } @@ -156,8 +155,8 @@ static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { secp256k1_gej_t pt; - secp256k1_gej_set_ge(&pt, key); secp256k1_scalar_t one; + secp256k1_gej_set_ge(&pt, key); secp256k1_scalar_set_int(&one, 1); secp256k1_ecmult(&pt, &pt, &one, tweak); @@ -176,12 +175,12 @@ static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp } static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { + secp256k1_scalar_t zero; + secp256k1_gej_t pt; if (secp256k1_scalar_is_zero(tweak)) return 0; - secp256k1_scalar_t zero; secp256k1_scalar_set_int(&zero, 0); - secp256k1_gej_t pt; secp256k1_gej_set_ge(&pt, key); secp256k1_ecmult(&pt, &pt, tweak, &zero); secp256k1_ge_set_gej(key, &pt); diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index 48436316e12..849452c7a1b 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -24,49 +24,53 @@ typedef struct { * None of the resulting prec group elements have a known scalar, and neither do any of * the intermediate sums while computing a*G. */ - secp256k1_fe_t prec[64][16][2]; /* prec[j][i] = (16^j * i * G + U_i).{x,y} */ + secp256k1_ge_storage_t prec[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ } secp256k1_ecmult_gen_consts_t; static const secp256k1_ecmult_gen_consts_t *secp256k1_ecmult_gen_consts = NULL; static void secp256k1_ecmult_gen_start(void) { + secp256k1_ge_t prec[1024]; + secp256k1_gej_t gj; + secp256k1_gej_t nums_gej; + secp256k1_ecmult_gen_consts_t *ret; + int i, j; if (secp256k1_ecmult_gen_consts != NULL) return; /* Allocate the precomputation table. */ - secp256k1_ecmult_gen_consts_t *ret = (secp256k1_ecmult_gen_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_gen_consts_t)); + ret = (secp256k1_ecmult_gen_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_gen_consts_t)); /* get the generator */ - const secp256k1_ge_t *g = &secp256k1_ge_consts->g; - secp256k1_gej_t gj; secp256k1_gej_set_ge(&gj, g); + secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ - secp256k1_gej_t nums_gej; { - static const unsigned char nums_b32[32] = "The scalar for this x is unknown"; + static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; secp256k1_fe_t nums_x; - VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32)); secp256k1_ge_t nums_ge; + VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32)); VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0)); secp256k1_gej_set_ge(&nums_gej, &nums_ge); /* Add G to make the bits in x uniformly distributed. */ - secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, g); + secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g); } /* compute prec. */ - secp256k1_ge_t prec[1024]; { secp256k1_gej_t precj[1024]; /* Jacobian versions of prec. */ - secp256k1_gej_t gbase; gbase = gj; /* 16^j * G */ - secp256k1_gej_t numsbase; numsbase = nums_gej; /* 2^j * nums. */ - for (int j=0; j<64; j++) { + secp256k1_gej_t gbase; + secp256k1_gej_t numsbase; + gbase = gj; /* 16^j * G */ + numsbase = nums_gej; /* 2^j * nums. */ + for (j = 0; j < 64; j++) { /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */ precj[j*16] = numsbase; - for (int i=1; i<16; i++) { + for (i = 1; i < 16; i++) { secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase); } /* Multiply gbase by 16. */ - for (int i=0; i<4; i++) { + for (i = 0; i < 4; i++) { secp256k1_gej_double_var(&gbase, &gbase); } /* Multiply numbase by 2. */ @@ -79,11 +83,9 @@ static void secp256k1_ecmult_gen_start(void) { } secp256k1_ge_set_all_gej_var(1024, prec, precj); } - for (int j=0; j<64; j++) { - for (int i=0; i<16; i++) { - VERIFY_CHECK(!secp256k1_ge_is_infinity(&prec[j*16 + i])); - ret->prec[j][i][0] = prec[j*16 + i].x; - ret->prec[j][i][1] = prec[j*16 + i].y; + for (j = 0; j < 64; j++) { + for (i = 0; i < 16; i++) { + secp256k1_ge_to_storage(&ret->prec[j][i], &prec[j*16 + i]); } } @@ -92,26 +94,29 @@ static void secp256k1_ecmult_gen_start(void) { } static void secp256k1_ecmult_gen_stop(void) { + secp256k1_ecmult_gen_consts_t *c; if (secp256k1_ecmult_gen_consts == NULL) return; - secp256k1_ecmult_gen_consts_t *c = (secp256k1_ecmult_gen_consts_t*)secp256k1_ecmult_gen_consts; + c = (secp256k1_ecmult_gen_consts_t*)secp256k1_ecmult_gen_consts; secp256k1_ecmult_gen_consts = NULL; free(c); } static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *gn) { const secp256k1_ecmult_gen_consts_t *c = secp256k1_ecmult_gen_consts; - secp256k1_gej_set_infinity(r); secp256k1_ge_t add; - add.infinity = 0; + secp256k1_ge_storage_t adds; int bits; - for (int j=0; j<64; j++) { + int i, j; + secp256k1_gej_set_infinity(r); + add.infinity = 0; + for (j = 0; j < 64; j++) { bits = secp256k1_scalar_get_bits(gn, j * 4, 4); - for (int i=0; i<16; i++) { - secp256k1_fe_cmov(&add.x, &c->prec[j][i][0], i == bits); - secp256k1_fe_cmov(&add.y, &c->prec[j][i][1], i == bits); + for (i = 0; i < 16; i++) { + secp256k1_ge_storage_cmov(&adds, &c->prec[j][i], i == bits); } + secp256k1_ge_from_storage(&add, &adds); secp256k1_gej_add_ge(r, r, &add); } bits = 0; diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h index 345cfae7332..ece0b0a4598 100644 --- a/src/ecmult_impl.h +++ b/src/ecmult_impl.h @@ -37,22 +37,31 @@ * G is constant, so it only needs to be done once in advance. */ static void secp256k1_ecmult_table_precomp_gej_var(secp256k1_gej_t *pre, const secp256k1_gej_t *a, int w) { + secp256k1_gej_t d; + int i; pre[0] = *a; - secp256k1_gej_t d; secp256k1_gej_double_var(&d, &pre[0]); - for (int i=1; i<(1 << (w-2)); i++) + secp256k1_gej_double_var(&d, &pre[0]); + for (i = 1; i < (1 << (w-2)); i++) secp256k1_gej_add_var(&pre[i], &d, &pre[i-1]); } -static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const secp256k1_gej_t *a, int w) { +static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a, int w) { + secp256k1_gej_t d; + int i; const int table_size = 1 << (w-2); secp256k1_gej_t *prej = checked_malloc(sizeof(secp256k1_gej_t) * table_size); + secp256k1_ge_t *prea = checked_malloc(sizeof(secp256k1_ge_t) * table_size); prej[0] = *a; - secp256k1_gej_t d; secp256k1_gej_double_var(&d, a); - for (int i=1; i= -((1 << ((w)-1)) - 1)); \ VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ if ((n) > 0) \ *(r) = (pre)[((n)-1)/2]; \ else \ - (neg)((r), &(pre)[(-(n)-1)/2]); \ + secp256k1_gej_neg((r), &(pre)[(-(n)-1)/2]); \ +} while(0) +#define ECMULT_TABLE_GET_GE_STORAGE(r,pre,n,w) do { \ + VERIFY_CHECK(((n) & 1) == 1); \ + VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ + VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ + if ((n) > 0) \ + secp256k1_ge_from_storage((r), &(pre)[((n)-1)/2]); \ + else {\ + secp256k1_ge_from_storage((r), &(pre)[(-(n)-1)/2]); \ + secp256k1_ge_neg((r), (r)); \ + } \ } while(0) - -#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg) -#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg) typedef struct { /* For accelerating the computation of a*P + b*G: */ - secp256k1_ge_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of the generator */ + secp256k1_ge_storage_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of the generator */ #ifdef USE_ENDOMORPHISM - secp256k1_ge_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of 2^128*generator */ + secp256k1_ge_storage_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of 2^128*generator */ #endif } secp256k1_ecmult_consts_t; static const secp256k1_ecmult_consts_t *secp256k1_ecmult_consts = NULL; static void secp256k1_ecmult_start(void) { + secp256k1_gej_t gj; + secp256k1_ecmult_consts_t *ret; if (secp256k1_ecmult_consts != NULL) return; /* Allocate the precomputation table. */ - secp256k1_ecmult_consts_t *ret = (secp256k1_ecmult_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_consts_t)); + ret = (secp256k1_ecmult_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_consts_t)); /* get the generator */ - const secp256k1_ge_t *g = &secp256k1_ge_consts->g; - secp256k1_gej_t gj; secp256k1_gej_set_ge(&gj, g); + secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); -#ifdef USE_ENDOMORPHISM - /* calculate 2^128*generator */ - secp256k1_gej_t g_128j = gj; - for (int i=0; i<128; i++) - secp256k1_gej_double_var(&g_128j, &g_128j); -#endif /* precompute the tables with odd multiples */ - secp256k1_ecmult_table_precomp_ge_var(ret->pre_g, &gj, WINDOW_G); + secp256k1_ecmult_table_precomp_ge_storage_var(ret->pre_g, &gj, WINDOW_G); + #ifdef USE_ENDOMORPHISM - secp256k1_ecmult_table_precomp_ge_var(ret->pre_g_128, &g_128j, WINDOW_G); + { + secp256k1_gej_t g_128j; + int i; + /* calculate 2^128*generator */ + g_128j = gj; + for (i = 0; i < 128; i++) + secp256k1_gej_double_var(&g_128j, &g_128j); + secp256k1_ecmult_table_precomp_ge_storage_var(ret->pre_g_128, &g_128j, WINDOW_G); + } #endif /* Set the global pointer to the precomputation table. */ @@ -112,10 +133,11 @@ static void secp256k1_ecmult_start(void) { } static void secp256k1_ecmult_stop(void) { + secp256k1_ecmult_consts_t *c; if (secp256k1_ecmult_consts == NULL) return; - secp256k1_ecmult_consts_t *c = (secp256k1_ecmult_consts_t*)secp256k1_ecmult_consts; + c = (secp256k1_ecmult_consts_t*)secp256k1_ecmult_consts; secp256k1_ecmult_consts = NULL; free(c); } @@ -129,16 +151,18 @@ static void secp256k1_ecmult_stop(void) { */ static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) { secp256k1_scalar_t s = *a; - + int set_bits = 0; + int bit = 0; int sign = 1; + if (secp256k1_scalar_get_bits(&s, 255, 1)) { secp256k1_scalar_negate(&s, &s); sign = -1; } - int set_bits = 0; - int bit = 0; while (bit < 256) { + int now; + int word; if (secp256k1_scalar_get_bits(&s, bit, 1) == 0) { bit++; continue; @@ -146,11 +170,11 @@ static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) while (set_bits < bit) { wnaf[set_bits++] = 0; } - int now = w; + now = w; if (bit + now > 256) { now = 256 - bit; } - int word = secp256k1_scalar_get_bits_var(&s, bit, now); + word = secp256k1_scalar_get_bits_var(&s, bit, now); if (word & (1 << (w-1))) { secp256k1_scalar_add_bit(&s, bit + w); wnaf[set_bits++] = sign * (word - (1 << w)); @@ -163,58 +187,74 @@ static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) } static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) { + secp256k1_gej_t tmpj; + secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ge_t tmpa; const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts; +#ifdef USE_ENDOMORPHISM + secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_scalar_t na_1, na_lam; + /* Splitted G factors. */ + secp256k1_scalar_t ng_1, ng_128; + int wnaf_na_1[130]; + int wnaf_na_lam[130]; + int bits_na_1; + int bits_na_lam; + int wnaf_ng_1[129]; + int bits_ng_1; + int wnaf_ng_128[129]; + int bits_ng_128; +#else + int wnaf_na[256]; + int bits_na; + int wnaf_ng[257]; + int bits_ng; +#endif + int i; + int bits; #ifdef USE_ENDOMORPHISM - secp256k1_scalar_t na_1, na_lam; /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */ secp256k1_scalar_split_lambda_var(&na_1, &na_lam, na); /* build wnaf representation for na_1 and na_lam. */ - int wnaf_na_1[130]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A); - int wnaf_na_lam[130]; int bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A); + bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A); + bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A); VERIFY_CHECK(bits_na_1 <= 130); VERIFY_CHECK(bits_na_lam <= 130); - int bits = bits_na_1; + bits = bits_na_1; if (bits_na_lam > bits) bits = bits_na_lam; #else /* build wnaf representation for na. */ - int wnaf_na[256]; int bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A); - int bits = bits_na; + bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A); + bits = bits_na; #endif /* calculate odd multiples of a */ - secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; secp256k1_ecmult_table_precomp_gej_var(pre_a, a, WINDOW_A); #ifdef USE_ENDOMORPHISM - secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - for (int i=0; i bits) bits = bits_ng_1; if (bits_ng_128 > bits) bits = bits_ng_128; #else - int wnaf_ng[257]; int bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, ng, WINDOW_G); + bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, ng, WINDOW_G); if (bits_ng > bits) bits = bits_ng; #endif secp256k1_gej_set_infinity(r); - secp256k1_gej_t tmpj; - secp256k1_ge_t tmpa; - for (int i=bits-1; i>=0; i--) { - secp256k1_gej_double_var(r, r); + for (i = bits-1; i >= 0; i--) { int n; + secp256k1_gej_double_var(r, r); #ifdef USE_ENDOMORPHISM if (i < bits_na_1 && (n = wnaf_na_1[i])) { ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A); @@ -225,11 +265,11 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_add_var(r, r, &tmpj); } if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { - ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G); + ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g, n, WINDOW_G); secp256k1_gej_add_ge_var(r, r, &tmpa); } if (i < bits_ng_128 && (n = wnaf_ng_128[i])) { - ECMULT_TABLE_GET_GE(&tmpa, c->pre_g_128, n, WINDOW_G); + ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g_128, n, WINDOW_G); secp256k1_gej_add_ge_var(r, r, &tmpa); } #else @@ -238,7 +278,7 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_add_var(r, r, &tmpj); } if (i < bits_ng && (n = wnaf_ng[i])) { - ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G); + ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g, n, WINDOW_G); secp256k1_gej_add_ge_var(r, r, &tmpa); } #endif diff --git a/src/field.h b/src/field.h index 14e2b813c17..9e6d7d3c042 100644 --- a/src/field.h +++ b/src/field.h @@ -30,21 +30,6 @@ #error "Please select field implementation" #endif -typedef struct { -#ifndef USE_NUM_NONE - secp256k1_num_t p; -#endif - secp256k1_fe_t order; -} secp256k1_fe_consts_t; - -static const secp256k1_fe_consts_t *secp256k1_fe_consts = NULL; - -/** Initialize field element precomputation data. */ -static void secp256k1_fe_start(void); - -/** Unload field element precomputation data. */ -static void secp256k1_fe_stop(void); - /** Normalize a field element. */ static void secp256k1_fe_normalize(secp256k1_fe_t *r); @@ -117,15 +102,15 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a); /** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and * outputs must not overlap in memory. */ -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]); +static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a); -/** Convert a field element to a hexadecimal string. */ -static void secp256k1_fe_get_hex(char *r, int *rlen, const secp256k1_fe_t *a); +/** Convert a field element to the storage type. */ +static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t*); -/** Convert a hexadecimal string to a field element. */ -static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen); +/** Convert a field element back from the storage type. */ +static void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t*); /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag); +static void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag); #endif diff --git a/src/field_10x26.h b/src/field_10x26.h index 66fb3f2563a..44bce6525df 100644 --- a/src/field_10x26.h +++ b/src/field_10x26.h @@ -18,4 +18,30 @@ typedef struct { #endif } secp256k1_fe_t; +/* Unpacks a constant into a overlapping multi-limbed FE element. */ +#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ + (d0) & 0x3FFFFFFUL, \ + ((d0) >> 26) | ((d1) & 0xFFFFFUL) << 6, \ + ((d1) >> 20) | ((d2) & 0x3FFFUL) << 12, \ + ((d2) >> 14) | ((d3) & 0xFFUL) << 18, \ + ((d3) >> 8) | ((d4) & 0x3) << 24, \ + ((d4) >> 2) & 0x3FFFFFFUL, \ + ((d4) >> 28) | ((d5) & 0x3FFFFFUL) << 4, \ + ((d5) >> 22) | ((d6) & 0xFFFF) << 10, \ + ((d6) >> 16) | ((d7) & 0x3FF) << 16, \ + ((d7) >> 10) \ +} + +#ifdef VERIFY +#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} +#else +#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} +#endif + +typedef struct { + uint32_t n[8]; +} secp256k1_fe_storage_t; + +#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} + #endif diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index 9ef60a807ac..0afbb18a4af 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -13,9 +13,6 @@ #include "num.h" #include "field.h" -static void secp256k1_fe_inner_start(void) {} -static void secp256k1_fe_inner_stop(void) {} - #ifdef VERIFY static void secp256k1_fe_verify(const secp256k1_fe_t *a) { const uint32_t *d = a->n; @@ -54,8 +51,8 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; uint32_t m; + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; /* The first pass ensures the magnitude is 1, ... */ t0 += x * 0x3D1UL; t1 += (x << 6); @@ -140,8 +137,8 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; uint32_t m; + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; /* The first pass ensures the magnitude is 1, ... */ t0 += x * 0x3D1UL; t1 += (x << 6); @@ -195,12 +192,12 @@ static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; - /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ uint32_t z0, z1; + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + /* The first pass ensures the magnitude is 1, ... */ t0 += x * 0x3D1UL; t1 += (x << 6); t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL; @@ -221,23 +218,36 @@ static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { } static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { - uint32_t t0 = r->n[0], t9 = r->n[9]; + uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; + uint32_t z0, z1; + uint32_t x; + + t0 = r->n[0]; + t9 = r->n[9]; /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t x = t9 >> 22; + x = t9 >> 22; /* The first pass ensures the magnitude is 1, ... */ t0 += x * 0x3D1UL; /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ - uint32_t z0 = t0 & 0x3FFFFFFUL, z1 = z0 ^ 0x3D0UL; + z0 = t0 & 0x3FFFFFFUL; + z1 = z0 ^ 0x3D0UL; /* Fast return path should catch the majority of cases */ if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) return 0; - uint32_t t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], - t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8]; + t1 = r->n[1]; + t2 = r->n[2]; + t3 = r->n[3]; + t4 = r->n[4]; + t5 = r->n[5]; + t6 = r->n[6]; + t7 = r->n[7]; + t8 = r->n[8]; + t9 &= 0x03FFFFFUL; t1 += (x << 6); @@ -269,11 +279,11 @@ SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { } SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { + const uint32_t *t = a->n; #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif - const uint32_t *t = a->n; return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0; } @@ -286,23 +296,25 @@ SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { } SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { + int i; #ifdef VERIFY a->magnitude = 0; a->normalized = 1; #endif - for (int i=0; i<10; i++) { + for (i=0; i<10; i++) { a->n[i] = 0; } } static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { + int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); VERIFY_CHECK(b->normalized); secp256k1_fe_verify(a); secp256k1_fe_verify(b); #endif - for (int i = 9; i >= 0; i--) { + for (i = 9; i >= 0; i--) { if (a->n[i] > b->n[i]) return 1; if (a->n[i] < b->n[i]) return -1; } @@ -310,10 +322,12 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b } static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { + int i; r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; - for (int i=0; i<32; i++) { - for (int j=0; j<4; j++) { + for (i=0; i<32; i++) { + int j; + for (j=0; j<4; j++) { int limb = (8*i+2*j)/26; int shift = (8*i+2*j)%26; r->n[limb] |= (uint32_t)((a[31-i] >> (2*j)) & 0x3) << shift; @@ -332,13 +346,15 @@ static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { + int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif - for (int i=0; i<32; i++) { + for (i=0; i<32; i++) { + int j; int c = 0; - for (int j=0; j<4; j++) { + for (j=0; j<4; j++) { int limb = (8*i+2*j)/26; int shift = (8*i+2*j)%26; c |= ((a->n[limb] >> shift) & 0x3) << (2 * j); @@ -415,6 +431,11 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1 #endif SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) { + uint64_t c, d; + uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; + uint32_t t9, t1, t0, t2, t3, t4, t5, t6, t7; + const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; + VERIFY_BITS(a[0], 30); VERIFY_BITS(a[1], 30); VERIFY_BITS(a[2], 30); @@ -436,14 +457,11 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t VERIFY_BITS(b[8], 30); VERIFY_BITS(b[9], 26); - const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. * px is a shorthand for sum(a[i]*b[x-i], i=0..x). * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. */ - uint64_t c, d; - d = (uint64_t)a[0] * b[9] + (uint64_t)a[1] * b[8] + (uint64_t)a[2] * b[7] @@ -456,7 +474,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t + (uint64_t)a[9] * b[0]; /* VERIFY_BITS(d, 64); */ /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - uint32_t t9 = d & M; d >>= 26; + t9 = d & M; d >>= 26; VERIFY_BITS(t9, 26); VERIFY_BITS(d, 38); /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ @@ -475,12 +493,12 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t + (uint64_t)a[9] * b[1]; VERIFY_BITS(d, 63); /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - uint64_t u0 = d & M; d >>= 26; c += u0 * R0; + u0 = d & M; d >>= 26; c += u0 * R0; VERIFY_BITS(u0, 26); VERIFY_BITS(d, 37); VERIFY_BITS(c, 61); /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - uint32_t t0 = c & M; c >>= 26; c += u0 * R1; + t0 = c & M; c >>= 26; c += u0 * R1; VERIFY_BITS(t0, 26); VERIFY_BITS(c, 37); /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ @@ -500,12 +518,12 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t + (uint64_t)a[9] * b[2]; VERIFY_BITS(d, 63); /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - uint64_t u1 = d & M; d >>= 26; c += u1 * R0; + u1 = d & M; d >>= 26; c += u1 * R0; VERIFY_BITS(u1, 26); VERIFY_BITS(d, 37); VERIFY_BITS(c, 63); /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - uint32_t t1 = c & M; c >>= 26; c += u1 * R1; + t1 = c & M; c >>= 26; c += u1 * R1; VERIFY_BITS(t1, 26); VERIFY_BITS(c, 38); /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ @@ -525,12 +543,12 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t + (uint64_t)a[9] * b[3]; VERIFY_BITS(d, 63); /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - uint64_t u2 = d & M; d >>= 26; c += u2 * R0; + u2 = d & M; d >>= 26; c += u2 * R0; VERIFY_BITS(u2, 26); VERIFY_BITS(d, 37); VERIFY_BITS(c, 63); /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - uint32_t t2 = c & M; c >>= 26; c += u2 * R1; + t2 = c & M; c >>= 26; c += u2 * R1; VERIFY_BITS(t2, 26); VERIFY_BITS(c, 38); /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ @@ -550,12 +568,12 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t + (uint64_t)a[9] * b[4]; VERIFY_BITS(d, 63); /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - uint64_t u3 = d & M; d >>= 26; c += u3 * R0; + u3 = d & M; d >>= 26; c += u3 * R0; VERIFY_BITS(u3, 26); VERIFY_BITS(d, 37); /* VERIFY_BITS(c, 64); */ /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - uint32_t t3 = c & M; c >>= 26; c += u3 * R1; + t3 = c & M; c >>= 26; c += u3 * R1; VERIFY_BITS(t3, 26); VERIFY_BITS(c, 39); /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ @@ -575,12 +593,12 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t + (uint64_t)a[9] * b[5]; VERIFY_BITS(d, 62); /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - uint64_t u4 = d & M; d >>= 26; c += u4 * R0; + u4 = d & M; d >>= 26; c += u4 * R0; VERIFY_BITS(u4, 26); VERIFY_BITS(d, 36); /* VERIFY_BITS(c, 64); */ /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - uint32_t t4 = c & M; c >>= 26; c += u4 * R1; + t4 = c & M; c >>= 26; c += u4 * R1; VERIFY_BITS(t4, 26); VERIFY_BITS(c, 39); /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ @@ -600,12 +618,12 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t + (uint64_t)a[9] * b[6]; VERIFY_BITS(d, 62); /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - uint64_t u5 = d & M; d >>= 26; c += u5 * R0; + u5 = d & M; d >>= 26; c += u5 * R0; VERIFY_BITS(u5, 26); VERIFY_BITS(d, 36); /* VERIFY_BITS(c, 64); */ /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - uint32_t t5 = c & M; c >>= 26; c += u5 * R1; + t5 = c & M; c >>= 26; c += u5 * R1; VERIFY_BITS(t5, 26); VERIFY_BITS(c, 39); /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ @@ -625,12 +643,12 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t + (uint64_t)a[9] * b[7]; VERIFY_BITS(d, 61); /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - uint64_t u6 = d & M; d >>= 26; c += u6 * R0; + u6 = d & M; d >>= 26; c += u6 * R0; VERIFY_BITS(u6, 26); VERIFY_BITS(d, 35); /* VERIFY_BITS(c, 64); */ /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - uint32_t t6 = c & M; c >>= 26; c += u6 * R1; + t6 = c & M; c >>= 26; c += u6 * R1; VERIFY_BITS(t6, 26); VERIFY_BITS(c, 39); /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ @@ -651,13 +669,13 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t + (uint64_t)a[9] * b[8]; VERIFY_BITS(d, 58); /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - uint64_t u7 = d & M; d >>= 26; c += u7 * R0; + u7 = d & M; d >>= 26; c += u7 * R0; VERIFY_BITS(u7, 26); VERIFY_BITS(d, 32); /* VERIFY_BITS(c, 64); */ VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - uint32_t t7 = c & M; c >>= 26; c += u7 * R1; + t7 = c & M; c >>= 26; c += u7 * R1; VERIFY_BITS(t7, 26); VERIFY_BITS(c, 38); /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ @@ -678,7 +696,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t d += (uint64_t)a[9] * b[9]; VERIFY_BITS(d, 57); /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - uint64_t u8 = d & M; d >>= 26; c += u8 * R0; + u8 = d & M; d >>= 26; c += u8 * R0; VERIFY_BITS(u8, 26); VERIFY_BITS(d, 31); /* VERIFY_BITS(c, 64); */ @@ -742,6 +760,11 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t } SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) { + uint64_t c, d; + uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; + uint32_t t9, t0, t1, t2, t3, t4, t5, t6, t7; + const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; + VERIFY_BITS(a[0], 30); VERIFY_BITS(a[1], 30); VERIFY_BITS(a[2], 30); @@ -753,14 +776,11 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t VERIFY_BITS(a[8], 30); VERIFY_BITS(a[9], 26); - const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. * px is a shorthand for sum(a[i]*a[x-i], i=0..x). * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. */ - uint64_t c, d; - d = (uint64_t)(a[0]*2) * a[9] + (uint64_t)(a[1]*2) * a[8] + (uint64_t)(a[2]*2) * a[7] @@ -768,7 +788,7 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t + (uint64_t)(a[4]*2) * a[5]; /* VERIFY_BITS(d, 64); */ /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - uint32_t t9 = d & M; d >>= 26; + t9 = d & M; d >>= 26; VERIFY_BITS(t9, 26); VERIFY_BITS(d, 38); /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ @@ -783,12 +803,12 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t + (uint64_t)a[5] * a[5]; VERIFY_BITS(d, 63); /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - uint64_t u0 = d & M; d >>= 26; c += u0 * R0; + u0 = d & M; d >>= 26; c += u0 * R0; VERIFY_BITS(u0, 26); VERIFY_BITS(d, 37); VERIFY_BITS(c, 61); /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - uint32_t t0 = c & M; c >>= 26; c += u0 * R1; + t0 = c & M; c >>= 26; c += u0 * R1; VERIFY_BITS(t0, 26); VERIFY_BITS(c, 37); /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ @@ -803,12 +823,12 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t + (uint64_t)(a[5]*2) * a[6]; VERIFY_BITS(d, 63); /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - uint64_t u1 = d & M; d >>= 26; c += u1 * R0; + u1 = d & M; d >>= 26; c += u1 * R0; VERIFY_BITS(u1, 26); VERIFY_BITS(d, 37); VERIFY_BITS(c, 63); /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - uint32_t t1 = c & M; c >>= 26; c += u1 * R1; + t1 = c & M; c >>= 26; c += u1 * R1; VERIFY_BITS(t1, 26); VERIFY_BITS(c, 38); /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ @@ -824,12 +844,12 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t + (uint64_t)a[6] * a[6]; VERIFY_BITS(d, 63); /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - uint64_t u2 = d & M; d >>= 26; c += u2 * R0; + u2 = d & M; d >>= 26; c += u2 * R0; VERIFY_BITS(u2, 26); VERIFY_BITS(d, 37); VERIFY_BITS(c, 63); /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - uint32_t t2 = c & M; c >>= 26; c += u2 * R1; + t2 = c & M; c >>= 26; c += u2 * R1; VERIFY_BITS(t2, 26); VERIFY_BITS(c, 38); /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ @@ -844,12 +864,12 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t + (uint64_t)(a[6]*2) * a[7]; VERIFY_BITS(d, 63); /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - uint64_t u3 = d & M; d >>= 26; c += u3 * R0; + u3 = d & M; d >>= 26; c += u3 * R0; VERIFY_BITS(u3, 26); VERIFY_BITS(d, 37); /* VERIFY_BITS(c, 64); */ /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - uint32_t t3 = c & M; c >>= 26; c += u3 * R1; + t3 = c & M; c >>= 26; c += u3 * R1; VERIFY_BITS(t3, 26); VERIFY_BITS(c, 39); /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ @@ -865,12 +885,12 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t + (uint64_t)a[7] * a[7]; VERIFY_BITS(d, 62); /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - uint64_t u4 = d & M; d >>= 26; c += u4 * R0; + u4 = d & M; d >>= 26; c += u4 * R0; VERIFY_BITS(u4, 26); VERIFY_BITS(d, 36); /* VERIFY_BITS(c, 64); */ /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - uint32_t t4 = c & M; c >>= 26; c += u4 * R1; + t4 = c & M; c >>= 26; c += u4 * R1; VERIFY_BITS(t4, 26); VERIFY_BITS(c, 39); /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ @@ -885,12 +905,12 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t + (uint64_t)(a[7]*2) * a[8]; VERIFY_BITS(d, 62); /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - uint64_t u5 = d & M; d >>= 26; c += u5 * R0; + u5 = d & M; d >>= 26; c += u5 * R0; VERIFY_BITS(u5, 26); VERIFY_BITS(d, 36); /* VERIFY_BITS(c, 64); */ /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - uint32_t t5 = c & M; c >>= 26; c += u5 * R1; + t5 = c & M; c >>= 26; c += u5 * R1; VERIFY_BITS(t5, 26); VERIFY_BITS(c, 39); /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ @@ -906,12 +926,12 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t + (uint64_t)a[8] * a[8]; VERIFY_BITS(d, 61); /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - uint64_t u6 = d & M; d >>= 26; c += u6 * R0; + u6 = d & M; d >>= 26; c += u6 * R0; VERIFY_BITS(u6, 26); VERIFY_BITS(d, 35); /* VERIFY_BITS(c, 64); */ /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - uint32_t t6 = c & M; c >>= 26; c += u6 * R1; + t6 = c & M; c >>= 26; c += u6 * R1; VERIFY_BITS(t6, 26); VERIFY_BITS(c, 39); /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ @@ -927,13 +947,13 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t d += (uint64_t)(a[8]*2) * a[9]; VERIFY_BITS(d, 58); /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - uint64_t u7 = d & M; d >>= 26; c += u7 * R0; + u7 = d & M; d >>= 26; c += u7 * R0; VERIFY_BITS(u7, 26); VERIFY_BITS(d, 32); /* VERIFY_BITS(c, 64); */ VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - uint32_t t7 = c & M; c >>= 26; c += u7 * R1; + t7 = c & M; c >>= 26; c += u7 * R1; VERIFY_BITS(t7, 26); VERIFY_BITS(c, 38); /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ @@ -950,7 +970,7 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t d += (uint64_t)a[9] * a[9]; VERIFY_BITS(d, 57); /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - uint64_t u8 = d & M; d >>= 26; c += u8 * R0; + u8 = d & M; d >>= 26; c += u8 * R0; VERIFY_BITS(u8, 26); VERIFY_BITS(d, 31); /* VERIFY_BITS(c, 64); */ @@ -1043,8 +1063,10 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #endif } -static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { - uint32_t mask0 = flag + ~((uint32_t)0), mask1 = ~mask0; +static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) { + uint32_t mask0, mask1; + mask0 = flag + ~((uint32_t)0); + mask1 = ~mask0; r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); @@ -1053,13 +1075,36 @@ static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int fl r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); - r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); - r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); +} + +static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) { #ifdef VERIFY - if (flag) { - r->magnitude = a->magnitude; - r->normalized = a->normalized; - } + VERIFY_CHECK(a->normalized); +#endif + r->n[0] = a->n[0] | a->n[1] << 26; + r->n[1] = a->n[1] >> 6 | a->n[2] << 20; + r->n[2] = a->n[2] >> 12 | a->n[3] << 14; + r->n[3] = a->n[3] >> 18 | a->n[4] << 8; + r->n[4] = a->n[4] >> 24 | a->n[5] << 2 | a->n[6] << 28; + r->n[5] = a->n[6] >> 4 | a->n[7] << 22; + r->n[6] = a->n[7] >> 10 | a->n[8] << 16; + r->n[7] = a->n[8] >> 16 | a->n[9] << 10; +} + +static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) { + r->n[0] = a->n[0] & 0x3FFFFFFUL; + r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL); + r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL); + r->n[3] = a->n[2] >> 14 | ((a->n[3] << 18) & 0x3FFFFFFUL); + r->n[4] = a->n[3] >> 8 | ((a->n[4] << 24) & 0x3FFFFFFUL); + r->n[5] = (a->n[4] >> 2) & 0x3FFFFFFUL; + r->n[6] = a->n[4] >> 28 | ((a->n[5] << 4) & 0x3FFFFFFUL); + r->n[7] = a->n[5] >> 22 | ((a->n[6] << 10) & 0x3FFFFFFUL); + r->n[8] = a->n[6] >> 16 | ((a->n[7] << 16) & 0x3FFFFFFUL); + r->n[9] = a->n[7] >> 10; +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; #endif } diff --git a/src/field_5x52.h b/src/field_5x52.h index aeb0a6a1e86..4513d36f49f 100644 --- a/src/field_5x52.h +++ b/src/field_5x52.h @@ -18,4 +18,30 @@ typedef struct { #endif } secp256k1_fe_t; +/* Unpacks a constant into a overlapping multi-limbed FE element. */ +#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ + (d0) | ((uint64_t)(d1) & 0xFFFFFUL) << 32, \ + ((d1) >> 20) | ((uint64_t)(d2)) << 12 | ((uint64_t)(d3) & 0xFFUL) << 44, \ + ((d3) >> 8) | ((uint64_t)(d4) & 0xFFFFFFFUL) << 24, \ + ((d4) >> 28) | ((uint64_t)(d5)) << 4 | ((uint64_t)(d6) & 0xFFFFUL) << 36, \ + ((d6) >> 16) | ((uint64_t)(d7)) << 16 \ +} + +#ifdef VERIFY +#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} +#else +#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} +#endif + +typedef struct { + uint64_t n[4]; +} secp256k1_fe_storage_t; + +#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ + (d0) | ((uint64_t)(d1)) << 32, \ + (d2) | ((uint64_t)(d3)) << 32, \ + (d4) | ((uint64_t)(d5)) << 32, \ + (d6) | ((uint64_t)(d7)) << 32 \ +}} + #endif diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index 4db9e6f5ff5..2f9c8704a84 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -30,13 +30,11 @@ * output. */ -static void secp256k1_fe_inner_start(void) {} -static void secp256k1_fe_inner_stop(void) {} - #ifdef VERIFY static void secp256k1_fe_verify(const secp256k1_fe_t *a) { const uint64_t *d = a->n; int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; + /* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ r &= (d[0] <= 0xFFFFFFFFFFFFFULL * m); r &= (d[1] <= 0xFFFFFFFFFFFFFULL * m); r &= (d[2] <= 0xFFFFFFFFFFFFFULL * m); @@ -62,8 +60,8 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* Reduce t4 at the start so there will be at most a single carry from the first pass */ - uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; uint64_t m; + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; /* The first pass ensures the magnitude is 1, ... */ t0 += x * 0x1000003D1ULL; @@ -129,8 +127,8 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* Reduce t4 at the start so there will be at most a single carry from the first pass */ - uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; uint64_t m; + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; /* The first pass ensures the magnitude is 1, ... */ t0 += x * 0x1000003D1ULL; @@ -172,12 +170,12 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; - /* Reduce t4 at the start so there will be at most a single carry from the first pass */ - uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; - /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ uint64_t z0, z1; + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + /* The first pass ensures the magnitude is 1, ... */ t0 += x * 0x1000003D1ULL; t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; z0 = t0; z1 = t0 ^ 0x1000003D0ULL; @@ -193,22 +191,31 @@ static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { } static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { - uint64_t t0 = r->n[0], t4 = r->n[4]; + uint64_t t0, t1, t2, t3, t4; + uint64_t z0, z1; + uint64_t x; + + t0 = r->n[0]; + t4 = r->n[4]; /* Reduce t4 at the start so there will be at most a single carry from the first pass */ - uint64_t x = t4 >> 48; + x = t4 >> 48; /* The first pass ensures the magnitude is 1, ... */ t0 += x * 0x1000003D1ULL; /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ - uint64_t z0 = t0 & 0xFFFFFFFFFFFFFULL, z1 = z0 ^ 0x1000003D0ULL; + z0 = t0 & 0xFFFFFFFFFFFFFULL; + z1 = z0 ^ 0x1000003D0ULL; /* Fast return path should catch the majority of cases */ if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL)) return 0; - uint64_t t1 = r->n[1], t2 = r->n[2], t3 = r->n[3]; + t1 = r->n[1]; + t2 = r->n[2]; + t3 = r->n[3]; + t4 &= 0x0FFFFFFFFFFFFULL; t1 += (t0 >> 52); t0 = z0; @@ -234,11 +241,11 @@ SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { } SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { + const uint64_t *t = a->n; #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif - const uint64_t *t = a->n; return (t[0] | t[1] | t[2] | t[3] | t[4]) == 0; } @@ -251,23 +258,25 @@ SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { } SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { + int i; #ifdef VERIFY a->magnitude = 0; a->normalized = 1; #endif - for (int i=0; i<5; i++) { + for (i=0; i<5; i++) { a->n[i] = 0; } } static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { + int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); VERIFY_CHECK(b->normalized); secp256k1_fe_verify(a); secp256k1_fe_verify(b); #endif - for (int i = 4; i >= 0; i--) { + for (i = 4; i >= 0; i--) { if (a->n[i] > b->n[i]) return 1; if (a->n[i] < b->n[i]) return -1; } @@ -275,9 +284,11 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b } static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { + int i; r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; - for (int i=0; i<32; i++) { - for (int j=0; j<2; j++) { + for (i=0; i<32; i++) { + int j; + for (j=0; j<2; j++) { int limb = (8*i+4*j)/52; int shift = (8*i+4*j)%52; r->n[limb] |= (uint64_t)((a[31-i] >> (4*j)) & 0xF) << shift; @@ -296,13 +307,15 @@ static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { + int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif - for (int i=0; i<32; i++) { + for (i=0; i<32; i++) { + int j; int c = 0; - for (int j=0; j<2; j++) { + for (j=0; j<2; j++) { int limb = (8*i+4*j)/52; int shift = (8*i+4*j)%52; c |= ((a->n[limb] >> shift) & 0xF) << (4 * j); @@ -386,18 +399,35 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #endif } -static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { - uint64_t mask0 = flag + ~((uint64_t)0), mask1 = ~mask0; +static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) { + uint64_t mask0, mask1; + mask0 = flag + ~((uint64_t)0); + mask1 = ~mask0; r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); - r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); +} + +static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) { #ifdef VERIFY - if (flag) { - r->magnitude = a->magnitude; - r->normalized = a->normalized; - } + VERIFY_CHECK(a->normalized); +#endif + r->n[0] = a->n[0] | a->n[1] << 52; + r->n[1] = a->n[1] >> 12 | a->n[2] << 40; + r->n[2] = a->n[2] >> 24 | a->n[3] << 28; + r->n[3] = a->n[3] >> 36 | a->n[4] << 16; +} + +static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) { + r->n[0] = a->n[0] & 0xFFFFFFFFFFFFFULL; + r->n[1] = a->n[0] >> 52 | ((a->n[1] << 12) & 0xFFFFFFFFFFFFFULL); + r->n[2] = a->n[1] >> 40 | ((a->n[2] << 24) & 0xFFFFFFFFFFFFFULL); + r->n[3] = a->n[2] >> 28 | ((a->n[3] << 36) & 0xFFFFFFFFFFFFFULL); + r->n[4] = a->n[3] >> 16; +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; #endif } diff --git a/src/field_5x52_int128_impl.h b/src/field_5x52_int128_impl.h index ec631833cfa..9280bb5ea22 100644 --- a/src/field_5x52_int128_impl.h +++ b/src/field_5x52_int128_impl.h @@ -16,6 +16,11 @@ #endif SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { + uint128_t c, d; + uint64_t t3, t4, tx, u0; + uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; + const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; + VERIFY_BITS(a[0], 56); VERIFY_BITS(a[1], 56); VERIFY_BITS(a[2], 56); @@ -28,63 +33,58 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t VERIFY_BITS(b[4], 52); VERIFY_CHECK(r != b); - const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; /* [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. * px is a shorthand for sum(a[i]*b[x-i], i=0..x). * Note that [x 0 0 0 0 0] = [x*R]. */ - uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; - - __int128 c, d; - - d = (__int128)a0 * b[3] - + (__int128)a1 * b[2] - + (__int128)a2 * b[1] - + (__int128)a3 * b[0]; + d = (uint128_t)a0 * b[3] + + (uint128_t)a1 * b[2] + + (uint128_t)a2 * b[1] + + (uint128_t)a3 * b[0]; VERIFY_BITS(d, 114); /* [d 0 0 0] = [p3 0 0 0] */ - c = (__int128)a4 * b[4]; + c = (uint128_t)a4 * b[4]; VERIFY_BITS(c, 112); /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ d += (c & M) * R; c >>= 52; VERIFY_BITS(d, 115); VERIFY_BITS(c, 60); /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - uint64_t t3 = d & M; d >>= 52; + t3 = d & M; d >>= 52; VERIFY_BITS(t3, 52); VERIFY_BITS(d, 63); /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - d += (__int128)a0 * b[4] - + (__int128)a1 * b[3] - + (__int128)a2 * b[2] - + (__int128)a3 * b[1] - + (__int128)a4 * b[0]; + d += (uint128_t)a0 * b[4] + + (uint128_t)a1 * b[3] + + (uint128_t)a2 * b[2] + + (uint128_t)a3 * b[1] + + (uint128_t)a4 * b[0]; VERIFY_BITS(d, 115); /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ d += c * R; VERIFY_BITS(d, 116); /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - uint64_t t4 = d & M; d >>= 52; + t4 = d & M; d >>= 52; VERIFY_BITS(t4, 52); VERIFY_BITS(d, 64); /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - uint64_t tx = (t4 >> 48); t4 &= (M >> 4); + tx = (t4 >> 48); t4 &= (M >> 4); VERIFY_BITS(tx, 4); VERIFY_BITS(t4, 48); /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - c = (__int128)a0 * b[0]; + c = (uint128_t)a0 * b[0]; VERIFY_BITS(c, 112); /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ - d += (__int128)a1 * b[4] - + (__int128)a2 * b[3] - + (__int128)a3 * b[2] - + (__int128)a4 * b[1]; + d += (uint128_t)a1 * b[4] + + (uint128_t)a2 * b[3] + + (uint128_t)a3 * b[2] + + (uint128_t)a4 * b[1]; VERIFY_BITS(d, 115); /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - uint64_t u0 = d & M; d >>= 52; + u0 = d & M; d >>= 52; VERIFY_BITS(u0, 52); VERIFY_BITS(d, 63); /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ @@ -92,7 +92,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t u0 = (u0 << 4) | tx; VERIFY_BITS(u0, 56); /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - c += (__int128)u0 * (R >> 4); + c += (uint128_t)u0 * (R >> 4); VERIFY_BITS(c, 115); /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ r[0] = c & M; c >>= 52; @@ -100,13 +100,13 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t VERIFY_BITS(c, 61); /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ - c += (__int128)a0 * b[1] - + (__int128)a1 * b[0]; + c += (uint128_t)a0 * b[1] + + (uint128_t)a1 * b[0]; VERIFY_BITS(c, 114); /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ - d += (__int128)a2 * b[4] - + (__int128)a3 * b[3] - + (__int128)a4 * b[2]; + d += (uint128_t)a2 * b[4] + + (uint128_t)a3 * b[3] + + (uint128_t)a4 * b[2]; VERIFY_BITS(d, 114); /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ c += (d & M) * R; d >>= 52; @@ -118,13 +118,13 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t VERIFY_BITS(c, 63); /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - c += (__int128)a0 * b[2] - + (__int128)a1 * b[1] - + (__int128)a2 * b[0]; + c += (uint128_t)a0 * b[2] + + (uint128_t)a1 * b[1] + + (uint128_t)a2 * b[0]; VERIFY_BITS(c, 114); /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (__int128)a3 * b[4] - + (__int128)a4 * b[3]; + d += (uint128_t)a3 * b[4] + + (uint128_t)a4 * b[3]; VERIFY_BITS(d, 114); /* [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ c += (d & M) * R; d >>= 52; @@ -153,64 +153,64 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t } SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { + uint128_t c, d; + uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; + int64_t t3, t4, tx, u0; + const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; + VERIFY_BITS(a[0], 56); VERIFY_BITS(a[1], 56); VERIFY_BITS(a[2], 56); VERIFY_BITS(a[3], 56); VERIFY_BITS(a[4], 52); - const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; /** [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. * px is a shorthand for sum(a[i]*a[x-i], i=0..x). * Note that [x 0 0 0 0 0] = [x*R]. */ - __int128 c, d; - - uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; - - d = (__int128)(a0*2) * a3 - + (__int128)(a1*2) * a2; + d = (uint128_t)(a0*2) * a3 + + (uint128_t)(a1*2) * a2; VERIFY_BITS(d, 114); /* [d 0 0 0] = [p3 0 0 0] */ - c = (__int128)a4 * a4; + c = (uint128_t)a4 * a4; VERIFY_BITS(c, 112); /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ d += (c & M) * R; c >>= 52; VERIFY_BITS(d, 115); VERIFY_BITS(c, 60); /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - uint64_t t3 = d & M; d >>= 52; + t3 = d & M; d >>= 52; VERIFY_BITS(t3, 52); VERIFY_BITS(d, 63); /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ a4 *= 2; - d += (__int128)a0 * a4 - + (__int128)(a1*2) * a3 - + (__int128)a2 * a2; + d += (uint128_t)a0 * a4 + + (uint128_t)(a1*2) * a3 + + (uint128_t)a2 * a2; VERIFY_BITS(d, 115); /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ d += c * R; VERIFY_BITS(d, 116); /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - uint64_t t4 = d & M; d >>= 52; + t4 = d & M; d >>= 52; VERIFY_BITS(t4, 52); VERIFY_BITS(d, 64); /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - uint64_t tx = (t4 >> 48); t4 &= (M >> 4); + tx = (t4 >> 48); t4 &= (M >> 4); VERIFY_BITS(tx, 4); VERIFY_BITS(t4, 48); /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - c = (__int128)a0 * a0; + c = (uint128_t)a0 * a0; VERIFY_BITS(c, 112); /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ - d += (__int128)a1 * a4 - + (__int128)(a2*2) * a3; + d += (uint128_t)a1 * a4 + + (uint128_t)(a2*2) * a3; VERIFY_BITS(d, 114); /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - uint64_t u0 = d & M; d >>= 52; + u0 = d & M; d >>= 52; VERIFY_BITS(u0, 52); VERIFY_BITS(d, 62); /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ @@ -218,7 +218,7 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t u0 = (u0 << 4) | tx; VERIFY_BITS(u0, 56); /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - c += (__int128)u0 * (R >> 4); + c += (uint128_t)u0 * (R >> 4); VERIFY_BITS(c, 113); /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ r[0] = c & M; c >>= 52; @@ -227,11 +227,11 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ a0 *= 2; - c += (__int128)a0 * a1; + c += (uint128_t)a0 * a1; VERIFY_BITS(c, 114); /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ - d += (__int128)a2 * a4 - + (__int128)a3 * a3; + d += (uint128_t)a2 * a4 + + (uint128_t)a3 * a3; VERIFY_BITS(d, 114); /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ c += (d & M) * R; d >>= 52; @@ -243,11 +243,11 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t VERIFY_BITS(c, 63); /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - c += (__int128)a0 * a2 - + (__int128)a1 * a1; + c += (uint128_t)a0 * a2 + + (uint128_t)a1 * a1; VERIFY_BITS(c, 114); /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (__int128)a3 * a4; + d += (uint128_t)a3 * a4; VERIFY_BITS(d, 114); /* [d 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ c += (d & M) * R; d >>= 52; diff --git a/src/field_impl.h b/src/field_impl.h index 4e2c24aa153..047914cf28e 100644 --- a/src/field_impl.h +++ b/src/field_impl.h @@ -21,49 +21,6 @@ #error "Please select field implementation" #endif -static void secp256k1_fe_get_hex(char *r, int *rlen, const secp256k1_fe_t *a) { - if (*rlen < 65) { - *rlen = 65; - return; - } - *rlen = 65; - unsigned char tmp[32]; - secp256k1_fe_t b = *a; - secp256k1_fe_normalize(&b); - secp256k1_fe_get_b32(tmp, &b); - for (int i=0; i<32; i++) { - static const char *c = "0123456789ABCDEF"; - r[2*i] = c[(tmp[i] >> 4) & 0xF]; - r[2*i+1] = c[(tmp[i]) & 0xF]; - } - r[64] = 0x00; -} - -static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) { - unsigned char tmp[32] = {}; - static const int cvt[256] = {0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 1, 2, 3, 4, 5, 6,7,8,9,0,0,0,0,0,0, - 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, - 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}; - for (int i=0; i<32; i++) { - if (alen > i*2) - tmp[32 - alen/2 + i] = (cvt[(unsigned char)a[2*i]] << 4) + cvt[(unsigned char)a[2*i+1]]; - } - return secp256k1_fe_set_b32(r, tmp); -} - SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { secp256k1_fe_t na; secp256k1_fe_negate(&na, a, 1); @@ -72,62 +29,62 @@ SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, cons } static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { + secp256k1_fe_t x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; + int j; /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in * { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: * 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] */ - secp256k1_fe_t x2; secp256k1_fe_sqr(&x2, a); secp256k1_fe_mul(&x2, &x2, a); - secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &x2); secp256k1_fe_mul(&x3, &x3, a); - secp256k1_fe_t x6 = x3; - for (int j=0; j<3; j++) secp256k1_fe_sqr(&x6, &x6); + x6 = x3; + for (j=0; j<3; j++) secp256k1_fe_sqr(&x6, &x6); secp256k1_fe_mul(&x6, &x6, &x3); - secp256k1_fe_t x9 = x6; - for (int j=0; j<3; j++) secp256k1_fe_sqr(&x9, &x9); + x9 = x6; + for (j=0; j<3; j++) secp256k1_fe_sqr(&x9, &x9); secp256k1_fe_mul(&x9, &x9, &x3); - secp256k1_fe_t x11 = x9; - for (int j=0; j<2; j++) secp256k1_fe_sqr(&x11, &x11); + x11 = x9; + for (j=0; j<2; j++) secp256k1_fe_sqr(&x11, &x11); secp256k1_fe_mul(&x11, &x11, &x2); - secp256k1_fe_t x22 = x11; - for (int j=0; j<11; j++) secp256k1_fe_sqr(&x22, &x22); + x22 = x11; + for (j=0; j<11; j++) secp256k1_fe_sqr(&x22, &x22); secp256k1_fe_mul(&x22, &x22, &x11); - secp256k1_fe_t x44 = x22; - for (int j=0; j<22; j++) secp256k1_fe_sqr(&x44, &x44); + x44 = x22; + for (j=0; j<22; j++) secp256k1_fe_sqr(&x44, &x44); secp256k1_fe_mul(&x44, &x44, &x22); - secp256k1_fe_t x88 = x44; - for (int j=0; j<44; j++) secp256k1_fe_sqr(&x88, &x88); + x88 = x44; + for (j=0; j<44; j++) secp256k1_fe_sqr(&x88, &x88); secp256k1_fe_mul(&x88, &x88, &x44); - secp256k1_fe_t x176 = x88; - for (int j=0; j<88; j++) secp256k1_fe_sqr(&x176, &x176); + x176 = x88; + for (j=0; j<88; j++) secp256k1_fe_sqr(&x176, &x176); secp256k1_fe_mul(&x176, &x176, &x88); - secp256k1_fe_t x220 = x176; - for (int j=0; j<44; j++) secp256k1_fe_sqr(&x220, &x220); + x220 = x176; + for (j=0; j<44; j++) secp256k1_fe_sqr(&x220, &x220); secp256k1_fe_mul(&x220, &x220, &x44); - secp256k1_fe_t x223 = x220; - for (int j=0; j<3; j++) secp256k1_fe_sqr(&x223, &x223); + x223 = x220; + for (j=0; j<3; j++) secp256k1_fe_sqr(&x223, &x223); secp256k1_fe_mul(&x223, &x223, &x3); /* The final result is then assembled using a sliding window over the blocks. */ - secp256k1_fe_t t1 = x223; - for (int j=0; j<23; j++) secp256k1_fe_sqr(&t1, &t1); + t1 = x223; + for (j=0; j<23; j++) secp256k1_fe_sqr(&t1, &t1); secp256k1_fe_mul(&t1, &t1, &x22); - for (int j=0; j<6; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<6; j++) secp256k1_fe_sqr(&t1, &t1); secp256k1_fe_mul(&t1, &t1, &x2); secp256k1_fe_sqr(&t1, &t1); secp256k1_fe_sqr(r, &t1); @@ -139,66 +96,66 @@ static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { } static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) { + secp256k1_fe_t x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; + int j; /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in * { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: * [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] */ - secp256k1_fe_t x2; secp256k1_fe_sqr(&x2, a); secp256k1_fe_mul(&x2, &x2, a); - secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &x2); secp256k1_fe_mul(&x3, &x3, a); - secp256k1_fe_t x6 = x3; - for (int j=0; j<3; j++) secp256k1_fe_sqr(&x6, &x6); + x6 = x3; + for (j=0; j<3; j++) secp256k1_fe_sqr(&x6, &x6); secp256k1_fe_mul(&x6, &x6, &x3); - secp256k1_fe_t x9 = x6; - for (int j=0; j<3; j++) secp256k1_fe_sqr(&x9, &x9); + x9 = x6; + for (j=0; j<3; j++) secp256k1_fe_sqr(&x9, &x9); secp256k1_fe_mul(&x9, &x9, &x3); - secp256k1_fe_t x11 = x9; - for (int j=0; j<2; j++) secp256k1_fe_sqr(&x11, &x11); + x11 = x9; + for (j=0; j<2; j++) secp256k1_fe_sqr(&x11, &x11); secp256k1_fe_mul(&x11, &x11, &x2); - secp256k1_fe_t x22 = x11; - for (int j=0; j<11; j++) secp256k1_fe_sqr(&x22, &x22); + x22 = x11; + for (j=0; j<11; j++) secp256k1_fe_sqr(&x22, &x22); secp256k1_fe_mul(&x22, &x22, &x11); - secp256k1_fe_t x44 = x22; - for (int j=0; j<22; j++) secp256k1_fe_sqr(&x44, &x44); + x44 = x22; + for (j=0; j<22; j++) secp256k1_fe_sqr(&x44, &x44); secp256k1_fe_mul(&x44, &x44, &x22); - secp256k1_fe_t x88 = x44; - for (int j=0; j<44; j++) secp256k1_fe_sqr(&x88, &x88); + x88 = x44; + for (j=0; j<44; j++) secp256k1_fe_sqr(&x88, &x88); secp256k1_fe_mul(&x88, &x88, &x44); - secp256k1_fe_t x176 = x88; - for (int j=0; j<88; j++) secp256k1_fe_sqr(&x176, &x176); + x176 = x88; + for (j=0; j<88; j++) secp256k1_fe_sqr(&x176, &x176); secp256k1_fe_mul(&x176, &x176, &x88); - secp256k1_fe_t x220 = x176; - for (int j=0; j<44; j++) secp256k1_fe_sqr(&x220, &x220); + x220 = x176; + for (j=0; j<44; j++) secp256k1_fe_sqr(&x220, &x220); secp256k1_fe_mul(&x220, &x220, &x44); - secp256k1_fe_t x223 = x220; - for (int j=0; j<3; j++) secp256k1_fe_sqr(&x223, &x223); + x223 = x220; + for (j=0; j<3; j++) secp256k1_fe_sqr(&x223, &x223); secp256k1_fe_mul(&x223, &x223, &x3); /* The final result is then assembled using a sliding window over the blocks. */ - secp256k1_fe_t t1 = x223; - for (int j=0; j<23; j++) secp256k1_fe_sqr(&t1, &t1); + t1 = x223; + for (j=0; j<23; j++) secp256k1_fe_sqr(&t1, &t1); secp256k1_fe_mul(&t1, &t1, &x22); - for (int j=0; j<5; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<5; j++) secp256k1_fe_sqr(&t1, &t1); secp256k1_fe_mul(&t1, &t1, a); - for (int j=0; j<3; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<3; j++) secp256k1_fe_sqr(&t1, &t1); secp256k1_fe_mul(&t1, &t1, &x2); - for (int j=0; j<2; j++) secp256k1_fe_sqr(&t1, &t1); + for (j=0; j<2; j++) secp256k1_fe_sqr(&t1, &t1); secp256k1_fe_mul(r, a, &t1); } @@ -206,13 +163,21 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #if defined(USE_FIELD_INV_BUILTIN) secp256k1_fe_inv(r, a); #elif defined(USE_FIELD_INV_NUM) + secp256k1_num_t n, m; + /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ + static const unsigned char prime[32] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F + }; unsigned char b[32]; secp256k1_fe_t c = *a; secp256k1_fe_normalize_var(&c); secp256k1_fe_get_b32(b, &c); - secp256k1_num_t n; secp256k1_num_set_bin(&n, b, 32); - secp256k1_num_mod_inverse(&n, &n, &secp256k1_fe_consts->p); + secp256k1_num_set_bin(&m, prime, 32); + secp256k1_num_mod_inverse(&n, &n, &m); secp256k1_num_get_bin(b, 32, &n); VERIFY_CHECK(secp256k1_fe_set_b32(r, b)); #else @@ -220,7 +185,9 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #endif } -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]) { +static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a) { + secp256k1_fe_t u; + size_t i; if (len < 1) return; @@ -228,12 +195,12 @@ static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const se r[0] = a[0]; - size_t i = 0; + i = 0; while (++i < len) { secp256k1_fe_mul(&r[i], &r[i - 1], &a[i]); } - secp256k1_fe_t u; secp256k1_fe_inv_var(&u, &r[--i]); + secp256k1_fe_inv_var(&u, &r[--i]); while (i > 0) { int j = i--; @@ -244,32 +211,4 @@ static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const se r[0] = u; } -static void secp256k1_fe_start(void) { -#ifndef USE_NUM_NONE - static const unsigned char secp256k1_fe_consts_p[] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F - }; -#endif - if (secp256k1_fe_consts == NULL) { - secp256k1_fe_inner_start(); - secp256k1_fe_consts_t *ret = (secp256k1_fe_consts_t*)checked_malloc(sizeof(secp256k1_fe_consts_t)); -#ifndef USE_NUM_NONE - secp256k1_num_set_bin(&ret->p, secp256k1_fe_consts_p, sizeof(secp256k1_fe_consts_p)); -#endif - secp256k1_fe_consts = ret; - } -} - -static void secp256k1_fe_stop(void) { - if (secp256k1_fe_consts != NULL) { - secp256k1_fe_consts_t *c = (secp256k1_fe_consts_t*)secp256k1_fe_consts; - free((void*)c); - secp256k1_fe_consts = NULL; - secp256k1_fe_inner_stop(); - } -} - #endif diff --git a/src/group.h b/src/group.h index 6dea6bb5acb..d1e58349096 100644 --- a/src/group.h +++ b/src/group.h @@ -17,6 +17,9 @@ typedef struct { int infinity; /* whether this represents the point at infinity */ } secp256k1_ge_t; +#define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0} +#define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} + /** A group element of the secp256k1 curve, in jacobian coordinates. */ typedef struct { secp256k1_fe_t x; /* actual X: x/z^2 */ @@ -25,23 +28,15 @@ typedef struct { int infinity; /* whether this represents the point at infinity */ } secp256k1_gej_t; -/** Global constants related to the group */ +#define SECP256K1_GEJ_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), 0} +#define SECP256K1_GEJ_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} + typedef struct { - secp256k1_ge_t g; /* the generator point */ + secp256k1_fe_storage_t x; + secp256k1_fe_storage_t y; +} secp256k1_ge_storage_t; -#ifdef USE_ENDOMORPHISM - /* constants related to secp256k1's efficiently computable endomorphism */ - secp256k1_fe_t beta; -#endif -} secp256k1_ge_consts_t; - -static const secp256k1_ge_consts_t *secp256k1_ge_consts = NULL; - -/** Initialize the group module. */ -static void secp256k1_ge_start(void); - -/** De-initialize the group module. */ -static void secp256k1_ge_stop(void); +#define SECP256K1_GE_STORAGE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_STORAGE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_STORAGE_CONST((i),(j),(k),(l),(m),(n),(o),(p))} /** Set a group element equal to the point at infinity */ static void secp256k1_ge_set_infinity(secp256k1_ge_t *r); @@ -61,14 +56,11 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a); static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a); -/** Get a hex representation of a point. *rlen will be overwritten with the real length. */ -static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a); - /** Set a group element equal to another which is given in jacobian coordinates */ static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a); /** Set a batch of group elements equal to the inputs given in jacobian coordinates */ -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t r[len], const secp256k1_gej_t a[len]); +static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a); /** Set a group element (jacobian) equal to the point at infinity. */ @@ -103,9 +95,6 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c guarantee, and b is allowed to be infinity. */ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b); -/** Get a hex representation of a point. *rlen will be overwritten with the real length. */ -static void secp256k1_gej_get_hex(char *r, int *rlen, const secp256k1_gej_t *a); - #ifdef USE_ENDOMORPHISM /** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */ static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a); @@ -117,4 +106,13 @@ static void secp256k1_gej_clear(secp256k1_gej_t *r); /** Clear a secp256k1_ge_t to prevent leaking sensitive information. */ static void secp256k1_ge_clear(secp256k1_ge_t *r); +/** Convert a group element to the storage type. */ +static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t*); + +/** Convert a group element back from the storage type. */ +static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t*); + +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ +static void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag); + #endif diff --git a/src/group_impl.h b/src/group_impl.h index fef06df2892..8d8c359c5a4 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -13,6 +13,16 @@ #include "field.h" #include "group.h" +/** Generator for secp256k1, value 'g' defined in + * "Standards for Efficient Cryptography" (SEC2) 2.7.1. + */ +static const secp256k1_ge_t secp256k1_ge_const_g = SECP256K1_GE_CONST( + 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL, + 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL, + 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL, + 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL +); + static void secp256k1_ge_set_infinity(secp256k1_ge_t *r) { r->infinity = 1; } @@ -33,32 +43,12 @@ static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) { secp256k1_fe_negate(&r->y, &r->y, 1); } -static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a) { - char cx[65]; int lx=65; - char cy[65]; int ly=65; - secp256k1_fe_get_hex(cx, &lx, &a->x); - secp256k1_fe_get_hex(cy, &ly, &a->y); - lx = strlen(cx); - ly = strlen(cy); - int len = lx + ly + 3 + 1; - if (*rlen < len) { - *rlen = len; - return; - } - *rlen = len; - r[0] = '('; - memcpy(r+1, cx, lx); - r[1+lx] = ','; - memcpy(r+2+lx, cy, ly); - r[2+lx+ly] = ')'; - r[3+lx+ly] = 0; -} - static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a) { + secp256k1_fe_t z2, z3; r->infinity = a->infinity; secp256k1_fe_inv(&a->z, &a->z); - secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_t z3; secp256k1_fe_mul(&z3, &a->z, &z2); + secp256k1_fe_sqr(&z2, &a->z); + secp256k1_fe_mul(&z3, &a->z, &z2); secp256k1_fe_mul(&a->x, &a->x, &z2); secp256k1_fe_mul(&a->y, &a->y, &z3); secp256k1_fe_set_int(&a->z, 1); @@ -67,13 +57,14 @@ static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a) { } static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) { + secp256k1_fe_t z2, z3; r->infinity = a->infinity; if (a->infinity) { return; } secp256k1_fe_inv_var(&a->z, &a->z); - secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_t z3; secp256k1_fe_mul(&z3, &a->z, &z2); + secp256k1_fe_sqr(&z2, &a->z); + secp256k1_fe_mul(&z3, &a->z, &z2); secp256k1_fe_mul(&a->x, &a->x, &z2); secp256k1_fe_mul(&a->y, &a->y, &z3); secp256k1_fe_set_int(&a->z, 1); @@ -81,26 +72,30 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) { r->y = a->y; } -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t r[len], const secp256k1_gej_t a[len]) { +static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a) { + secp256k1_fe_t *az; + secp256k1_fe_t *azi; + size_t i; size_t count = 0; - secp256k1_fe_t *az = checked_malloc(sizeof(secp256k1_fe_t) * len); - for (size_t i=0; ix = *x; - secp256k1_fe_t x2; secp256k1_fe_sqr(&x2, x); - secp256k1_fe_t x3; secp256k1_fe_mul(&x3, x, &x2); + secp256k1_fe_sqr(&x2, x); + secp256k1_fe_mul(&x3, x, &x2); r->infinity = 0; - secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7); + secp256k1_fe_set_int(&c, 7); secp256k1_fe_add(&c, &x3); if (!secp256k1_fe_sqrt_var(&r->y, &c)) return 0; @@ -158,9 +154,10 @@ static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a) { } static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a) { + secp256k1_fe_t r, r2; VERIFY_CHECK(!a->infinity); - secp256k1_fe_t r; secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); - secp256k1_fe_t r2 = a->x; secp256k1_fe_normalize_weak(&r2); + secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); + r2 = a->x; secp256k1_fe_normalize_weak(&r2); return secp256k1_fe_equal_var(&r, &r2); } @@ -178,6 +175,7 @@ static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a) { } static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { + secp256k1_fe_t y2, x3, z2, z6; if (a->infinity) return 0; /** y^2 = x^3 + 7 @@ -185,10 +183,10 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { * Y^2 / Z^6 = X^3 / Z^6 + 7 * Y^2 = X^3 + 7*Z^6 */ - secp256k1_fe_t y2; secp256k1_fe_sqr(&y2, &a->y); - secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_t z6; secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); + secp256k1_fe_sqr(&y2, &a->y); + secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); + secp256k1_fe_sqr(&z2, &a->z); + secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); secp256k1_fe_mul_int(&z6, 7); secp256k1_fe_add(&x3, &z6); secp256k1_fe_normalize_weak(&x3); @@ -196,27 +194,30 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { } static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) { + secp256k1_fe_t y2, x3, c; if (a->infinity) return 0; /* y^2 = x^3 + 7 */ - secp256k1_fe_t y2; secp256k1_fe_sqr(&y2, &a->y); - secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7); + secp256k1_fe_sqr(&y2, &a->y); + secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); + secp256k1_fe_set_int(&c, 7); secp256k1_fe_add(&x3, &c); secp256k1_fe_normalize_weak(&x3); return secp256k1_fe_equal_var(&y2, &x3); } static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) { - // For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, - // Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have - // y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. + /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate */ + secp256k1_fe_t t1,t2,t3,t4; + /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, + * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have + * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. + */ r->infinity = a->infinity; if (r->infinity) { return; } - secp256k1_fe_t t1,t2,t3,t4; secp256k1_fe_mul(&r->z, &a->z, &a->y); secp256k1_fe_mul_int(&r->z, 2); /* Z' = 2*Y*Z (2) */ secp256k1_fe_sqr(&t1, &a->x); @@ -240,6 +241,8 @@ static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t * } static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b) { + /* Operations: 12 mul, 4 sqr, 2 normalize, 12 mul_int/add/negate */ + secp256k1_fe_t z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; if (a->infinity) { *r = *b; return; @@ -249,14 +252,14 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, return; } r->infinity = 0; - secp256k1_fe_t z22; secp256k1_fe_sqr(&z22, &b->z); - secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z); - secp256k1_fe_t u1; secp256k1_fe_mul(&u1, &a->x, &z22); - secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); - secp256k1_fe_t s1; secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); - secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + secp256k1_fe_sqr(&z22, &b->z); + secp256k1_fe_sqr(&z12, &a->z); + secp256k1_fe_mul(&u1, &a->x, &z22); + secp256k1_fe_mul(&u2, &b->x, &z12); + secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); + secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); + secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { secp256k1_gej_double_var(r, a); @@ -265,11 +268,11 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, } return; } - secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2); + secp256k1_fe_sqr(&i2, &i); + secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_mul(&h3, &h, &h2); secp256k1_fe_mul(&r->z, &a->z, &b->z); secp256k1_fe_mul(&r->z, &r->z, &h); - secp256k1_fe_t t; secp256k1_fe_mul(&t, &u1, &h2); + secp256k1_fe_mul(&t, &u1, &h2); r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); @@ -277,6 +280,8 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, } static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { + /* 8 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ + secp256k1_fe_t z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; if (a->infinity) { r->infinity = b->infinity; r->x = b->x; @@ -289,13 +294,13 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * return; } r->infinity = 0; - secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z); - secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1); - secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); - secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1); - secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + secp256k1_fe_sqr(&z12, &a->z); + u1 = a->x; secp256k1_fe_normalize_weak(&u1); + secp256k1_fe_mul(&u2, &b->x, &z12); + s1 = a->y; secp256k1_fe_normalize_weak(&s1); + secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); + secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { secp256k1_gej_double_var(r, a); @@ -304,11 +309,11 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * } return; } - secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2); + secp256k1_fe_sqr(&i2, &i); + secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_mul(&h3, &h, &h2); r->z = a->z; secp256k1_fe_mul(&r->z, &r->z, &h); - secp256k1_fe_t t; secp256k1_fe_mul(&t, &u1, &h2); + secp256k1_fe_mul(&t, &u1, &h2); r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); @@ -316,6 +321,9 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * } static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { + /* Operations: 7 mul, 5 sqr, 5 normalize, 19 mul_int/add/negate */ + secp256k1_fe_t zz, u1, u2, s1, s2, z, t, m, n, q, rr; + int infinity; VERIFY_CHECK(!b->infinity); VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); @@ -341,24 +349,24 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c * (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.) */ - secp256k1_fe_t zz; secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ - secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */ - secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ - secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ - secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */ - secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ - secp256k1_fe_t z = a->z; /* z = Z = Z1*Z2 (8) */ - secp256k1_fe_t t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ - secp256k1_fe_t m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ - secp256k1_fe_t n; secp256k1_fe_sqr(&n, &m); /* n = M^2 (1) */ - secp256k1_fe_t q; secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*M^2 (1) */ - secp256k1_fe_sqr(&n, &n); /* n = M^4 (1) */ - secp256k1_fe_t rr; secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ + secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ + u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */ + secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ + s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ + secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */ + secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ + z = a->z; /* z = Z = Z1*Z2 (8) */ + t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ + m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ + secp256k1_fe_sqr(&n, &m); /* n = M^2 (1) */ + secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*M^2 (1) */ + secp256k1_fe_sqr(&n, &n); /* n = M^4 (1) */ + secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ secp256k1_fe_mul(&t, &u1, &u2); secp256k1_fe_negate(&t, &t, 1); /* t = -U1*U2 (2) */ secp256k1_fe_add(&rr, &t); /* rr = R = T^2-U1*U2 (3) */ secp256k1_fe_sqr(&t, &rr); /* t = R^2 (1) */ secp256k1_fe_mul(&r->z, &m, &z); /* r->z = M*Z (1) */ - int infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); + infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); secp256k1_fe_mul_int(&r->z, 2 * (1 - a->infinity)); /* r->z = Z3 = 2*M*Z (2) */ r->x = t; /* r->x = R^2 (1) */ secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ @@ -386,63 +394,37 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c r->infinity = infinity; } +static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t *a) { + secp256k1_fe_t x, y; + VERIFY_CHECK(!a->infinity); + x = a->x; + secp256k1_fe_normalize(&x); + y = a->y; + secp256k1_fe_normalize(&y); + secp256k1_fe_to_storage(&r->x, &x); + secp256k1_fe_to_storage(&r->y, &y); +} +static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t *a) { + secp256k1_fe_from_storage(&r->x, &a->x); + secp256k1_fe_from_storage(&r->y, &a->y); + r->infinity = 0; +} -static void secp256k1_gej_get_hex(char *r, int *rlen, const secp256k1_gej_t *a) { - secp256k1_gej_t c = *a; - secp256k1_ge_t t; secp256k1_ge_set_gej(&t, &c); - secp256k1_ge_get_hex(r, rlen, &t); +static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag) { + secp256k1_fe_storage_cmov(&r->x, &a->x, flag); + secp256k1_fe_storage_cmov(&r->y, &a->y, flag); } #ifdef USE_ENDOMORPHISM static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a) { - const secp256k1_fe_t *beta = &secp256k1_ge_consts->beta; + static const secp256k1_fe_t beta = SECP256K1_FE_CONST( + 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul, + 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul + ); *r = *a; - secp256k1_fe_mul(&r->x, &r->x, beta); + secp256k1_fe_mul(&r->x, &r->x, &beta); } #endif -static void secp256k1_ge_start(void) { - static const unsigned char secp256k1_ge_consts_g_x[] = { - 0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC, - 0x55,0xA0,0x62,0x95,0xCE,0x87,0x0B,0x07, - 0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9, - 0x59,0xF2,0x81,0x5B,0x16,0xF8,0x17,0x98 - }; - static const unsigned char secp256k1_ge_consts_g_y[] = { - 0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65, - 0x5D,0xA4,0xFB,0xFC,0x0E,0x11,0x08,0xA8, - 0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19, - 0x9C,0x47,0xD0,0x8F,0xFB,0x10,0xD4,0xB8 - }; -#ifdef USE_ENDOMORPHISM - /* properties of secp256k1's efficiently computable endomorphism */ - static const unsigned char secp256k1_ge_consts_beta[] = { - 0x7a,0xe9,0x6a,0x2b,0x65,0x7c,0x07,0x10, - 0x6e,0x64,0x47,0x9e,0xac,0x34,0x34,0xe9, - 0x9c,0xf0,0x49,0x75,0x12,0xf5,0x89,0x95, - 0xc1,0x39,0x6c,0x28,0x71,0x95,0x01,0xee - }; -#endif - if (secp256k1_ge_consts == NULL) { - secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)checked_malloc(sizeof(secp256k1_ge_consts_t)); -#ifdef USE_ENDOMORPHISM - VERIFY_CHECK(secp256k1_fe_set_b32(&ret->beta, secp256k1_ge_consts_beta)); -#endif - secp256k1_fe_t g_x, g_y; - VERIFY_CHECK(secp256k1_fe_set_b32(&g_x, secp256k1_ge_consts_g_x)); - VERIFY_CHECK(secp256k1_fe_set_b32(&g_y, secp256k1_ge_consts_g_y)); - secp256k1_ge_set_xy(&ret->g, &g_x, &g_y); - secp256k1_ge_consts = ret; - } -} - -static void secp256k1_ge_stop(void) { - if (secp256k1_ge_consts != NULL) { - secp256k1_ge_consts_t *c = (secp256k1_ge_consts_t*)secp256k1_ge_consts; - free((void*)c); - secp256k1_ge_consts = NULL; - } -} - #endif diff --git a/src/hash.h b/src/hash.h index d1e65b968a9..843423d7f70 100644 --- a/src/hash.h +++ b/src/hash.h @@ -12,7 +12,7 @@ typedef struct { uint32_t s[32]; - unsigned char buf[64]; + uint32_t buf[16]; /* In big endian */ size_t bytes; } secp256k1_sha256_t; @@ -34,7 +34,7 @@ typedef struct { int retry; } secp256k1_rfc6979_hmac_sha256_t; -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen); +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen, const unsigned char *rnd, size_t rndlen); static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen); static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng); diff --git a/src/hash_impl.h b/src/hash_impl.h index f35c5f7a821..60fdbf77184 100644 --- a/src/hash_impl.h +++ b/src/hash_impl.h @@ -11,6 +11,7 @@ #include #include +#include #define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) #define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) @@ -26,8 +27,11 @@ (h) = t1 + t2; \ } while(0) -#define ReadBE32(p) (((uint32_t)((p)[0])) << 24 | ((uint32_t)((p)[1])) << 16 | ((uint32_t)((p)[2])) << 8 | ((uint32_t)((p)[3]))) -#define WriteBE32(p, v) do { (p)[0] = (v) >> 24; (p)[1] = (v) >> 16; (p)[2] = (v) >> 8; (p)[3] = (v); } while(0) +#ifdef WORDS_BIGENDIAN +#define BE32(x) (x) +#else +#define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) +#endif static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) { hash->s[0] = 0x6a09e667ul; @@ -41,27 +45,27 @@ static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) { hash->bytes = 0; } -/** Perform one SHA-256 transformation, processing a 64-byte chunk. */ -static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* chunk) { +/** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */ +static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) { uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0)); - Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4)); - Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8)); - Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12)); - Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16)); - Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20)); - Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24)); - Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28)); - Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32)); - Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36)); - Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40)); - Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44)); - Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48)); - Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52)); - Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56)); - Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60)); + Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = BE32(chunk[0])); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = BE32(chunk[1])); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = BE32(chunk[2])); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = BE32(chunk[3])); + Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = BE32(chunk[4])); + Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = BE32(chunk[5])); + Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = BE32(chunk[6])); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = BE32(chunk[7])); + Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = BE32(chunk[8])); + Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = BE32(chunk[9])); + Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = BE32(chunk[10])); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = BE32(chunk[11])); + Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = BE32(chunk[12])); + Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = BE32(chunk[13])); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = BE32(chunk[14])); + Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = BE32(chunk[15])); Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); @@ -125,55 +129,40 @@ static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* chunk) } static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t len) { - const unsigned char* end = data + len; - size_t bufsize = hash->bytes % 64; - if (bufsize && bufsize + len >= 64) { - // Fill the buffer, and process it. - memcpy(hash->buf + bufsize, data, 64 - bufsize); - hash->bytes += 64 - bufsize; + size_t bufsize = hash->bytes & 0x3F; + hash->bytes += len; + while (bufsize + len >= 64) { + /* Fill the buffer, and process it. */ + memcpy(((unsigned char*)hash->buf) + bufsize, data, 64 - bufsize); data += 64 - bufsize; + len -= 64 - bufsize; secp256k1_sha256_transform(hash->s, hash->buf); bufsize = 0; } - while (end >= data + 64) { - // Process full chunks directly from the source. - secp256k1_sha256_transform(hash->s, data); - hash->bytes += 64; - data += 64; - } - if (end > data) { - // Fill the buffer with what remains. - memcpy(hash->buf + bufsize, data, end - data); - hash->bytes += end - data; + if (len) { + /* Fill the buffer with what remains. */ + memcpy(((unsigned char*)hash->buf) + bufsize, data, len); } } static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32) { static const unsigned char pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - unsigned char sizedesc[8]; - WriteBE32(sizedesc, hash->bytes >> 29); - WriteBE32(sizedesc + 4, hash->bytes << 3); + uint32_t sizedesc[2]; + uint32_t out[8]; + int i = 0; + sizedesc[0] = BE32(hash->bytes >> 29); + sizedesc[1] = BE32(hash->bytes << 3); secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64)); - secp256k1_sha256_write(hash, sizedesc, 8); - WriteBE32(out32, hash->s[0]); - hash->s[0] = 0; - WriteBE32(out32 + 4, hash->s[1]); - hash->s[1] = 0; - WriteBE32(out32 + 8, hash->s[2]); - hash->s[2] = 0; - WriteBE32(out32 + 12, hash->s[3]); - hash->s[3] = 0; - WriteBE32(out32 + 16, hash->s[4]); - hash->s[4] = 0; - WriteBE32(out32 + 20, hash->s[5]); - hash->s[5] = 0; - WriteBE32(out32 + 24, hash->s[6]); - hash->s[6] = 0; - WriteBE32(out32 + 28, hash->s[7]); - hash->s[7] = 0; + secp256k1_sha256_write(hash, (const unsigned char*)sizedesc, 8); + for (i = 0; i < 8; i++) { + out[i] = BE32(hash->s[i]); + hash->s[i] = 0; + } + memcpy(out32, (const unsigned char*)out, 32); } static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t keylen) { + int n; unsigned char rkey[64]; if (keylen <= 64) { memcpy(rkey, key, keylen); @@ -187,12 +176,12 @@ static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, cons } secp256k1_sha256_initialize(&hash->outer); - for (int n = 0; n < 64; n++) + for (n = 0; n < 64; n++) rkey[n] ^= 0x5c; secp256k1_sha256_write(&hash->outer, rkey, 64); secp256k1_sha256_initialize(&hash->inner); - for (int n = 0; n < 64; n++) + for (n = 0; n < 64; n++) rkey[n] ^= 0x5c ^ 0x36; secp256k1_sha256_write(&hash->inner, rkey, 64); memset(rkey, 0, 64); @@ -211,19 +200,22 @@ static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsign } -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen) { +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen, const unsigned char *rnd, size_t rndlen) { + secp256k1_hmac_sha256_t hmac; static const unsigned char zero[1] = {0x00}; static const unsigned char one[1] = {0x01}; memset(rng->v, 0x01, 32); memset(rng->k, 0x00, 32); - secp256k1_hmac_sha256_t hmac; secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_write(&hmac, zero, 1); secp256k1_hmac_sha256_write(&hmac, key, keylen); secp256k1_hmac_sha256_write(&hmac, msg, msglen); + if (rnd && rndlen) { + secp256k1_hmac_sha256_write(&hmac, rnd, rndlen); + } secp256k1_hmac_sha256_finalize(&hmac, rng->k); secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); @@ -234,6 +226,9 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 secp256k1_hmac_sha256_write(&hmac, one, 1); secp256k1_hmac_sha256_write(&hmac, key, keylen); secp256k1_hmac_sha256_write(&hmac, msg, msglen); + if (rnd && rndlen) { + secp256k1_hmac_sha256_write(&hmac, rnd, rndlen); + } secp256k1_hmac_sha256_finalize(&hmac, rng->k); secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); @@ -256,10 +251,10 @@ static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 while (outlen > 0) { secp256k1_hmac_sha256_t hmac; + int now = outlen; secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_finalize(&hmac, rng->v); - int now = outlen; if (now > 32) { now = 32; } diff --git a/src/num_gmp_impl.h b/src/num_gmp_impl.h index 19d474e59ff..3e4b92d3291 100644 --- a/src/num_gmp_impl.h +++ b/src/num_gmp_impl.h @@ -29,10 +29,10 @@ static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a) { static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) { unsigned char tmp[65]; int len = 0; + int shift = 0; if (a->limbs>1 || a->data[0] != 0) { len = mpn_get_str(tmp, 256, (mp_limb_t*)a->data, a->limbs); } - int shift = 0; while (shift < len && tmp[shift] == 0) shift++; VERIFY_CHECK(len-shift <= (int)rlen); memset(r, 0, rlen - len + shift); @@ -43,9 +43,10 @@ static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const sec } static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) { + int len; VERIFY_CHECK(alen > 0); VERIFY_CHECK(alen <= 64); - int len = mpn_set_str(r->data, a, alen, 256); + len = mpn_set_str(r->data, a, alen, 256); if (len == 0) { r->data[0] = 0; len = 1; @@ -91,6 +92,12 @@ static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { } static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m) { + int i; + mp_limb_t g[NUM_LIMBS+1]; + mp_limb_t u[NUM_LIMBS+1]; + mp_limb_t v[NUM_LIMBS+1]; + mp_size_t sn; + mp_size_t gn; secp256k1_num_sanity(a); secp256k1_num_sanity(m); @@ -106,15 +113,12 @@ static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t */ VERIFY_CHECK(m->limbs <= NUM_LIMBS); VERIFY_CHECK(m->data[m->limbs-1] != 0); - mp_limb_t g[NUM_LIMBS+1]; - mp_limb_t u[NUM_LIMBS+1]; - mp_limb_t v[NUM_LIMBS+1]; - for (int i=0; i < m->limbs; i++) { + for (i = 0; i < m->limbs; i++) { u[i] = (i < a->limbs) ? a->data[i] : 0; v[i] = m->data[i]; } - mp_size_t sn = NUM_LIMBS+1; - mp_size_t gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); + sn = NUM_LIMBS+1; + gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); VERIFY_CHECK(gn == 1); VERIFY_CHECK(g[0] == 1); r->neg = a->neg ^ m->neg; @@ -183,10 +187,10 @@ static void secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, cons } static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + mp_limb_t tmp[2*NUM_LIMBS+1]; secp256k1_num_sanity(a); secp256k1_num_sanity(b); - mp_limb_t tmp[2*NUM_LIMBS+1]; VERIFY_CHECK(a->limbs + b->limbs <= 2*NUM_LIMBS+1); if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) { r->limbs = 1; @@ -207,13 +211,14 @@ static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, cons } static void secp256k1_num_shift(secp256k1_num_t *r, int bits) { + int i; if (bits % GMP_NUMB_BITS) { - // Shift within limbs. + /* Shift within limbs. */ mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS); } if (bits >= GMP_NUMB_BITS) { - // Shift full limbs. - for (int i = 0; i < r->limbs; i++) { + /* Shift full limbs. */ + for (i = 0; i < r->limbs; i++) { int index = i + (bits / GMP_NUMB_BITS); if (index < r->limbs && index < 2*NUM_LIMBS) { r->data[i] = r->data[index]; diff --git a/src/scalar.h b/src/scalar.h index 2f5ba0d447a..f5d09f8d474 100644 --- a/src/scalar.h +++ b/src/scalar.h @@ -21,9 +21,6 @@ #error "Please select scalar implementation" #endif -static void secp256k1_scalar_start(void); -static void secp256k1_scalar_stop(void); - /** Clear a scalar to prevent the leak of sensitive data. */ static void secp256k1_scalar_clear(secp256k1_scalar_t *r); @@ -83,9 +80,9 @@ static void secp256k1_scalar_order_get_num(secp256k1_num_t *r); /** Compare two scalars. */ static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b); -static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a); - #ifdef USE_ENDOMORPHISM +/** Find r1 and r2 such that r1+r2*2^128 = a. */ +static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a); /** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */ static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a); #endif diff --git a/src/scalar_4x64.h b/src/scalar_4x64.h index 5a751c68622..82899aa7b04 100644 --- a/src/scalar_4x64.h +++ b/src/scalar_4x64.h @@ -14,4 +14,6 @@ typedef struct { uint64_t d[4]; } secp256k1_scalar_t; +#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} + #endif diff --git a/src/scalar_4x64_impl.h b/src/scalar_4x64_impl.h index d1447752202..ff365292f86 100644 --- a/src/scalar_4x64_impl.h +++ b/src/scalar_4x64_impl.h @@ -7,8 +7,6 @@ #ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ #define _SECP256K1_SCALAR_REPR_IMPL_H_ -typedef unsigned __int128 uint128_t; - /* Limbs of the secp256k1 order. */ #define SECP256K1_N_0 ((uint64_t)0xBFD25E8CD0364141ULL) #define SECP256K1_N_1 ((uint64_t)0xBAAEDCE6AF48A03BULL) @@ -69,8 +67,9 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal } SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, unsigned int overflow) { + uint128_t t; VERIFY_CHECK(overflow <= 1); - uint128_t t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0; + t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0; r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; t += (uint128_t)r->d[1] + overflow * SECP256K1_N_C_1; r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; @@ -82,6 +81,7 @@ SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, unsig } static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + int overflow; uint128_t t = (uint128_t)a->d[0] + b->d[0]; r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; t += (uint128_t)a->d[1] + b->d[1]; @@ -90,15 +90,16 @@ static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; t += (uint128_t)a->d[3] + b->d[3]; r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - int overflow = t + secp256k1_scalar_check_overflow(r); + overflow = t + secp256k1_scalar_check_overflow(r); VERIFY_CHECK(overflow == 0 || overflow == 1); secp256k1_scalar_reduce(r, overflow); return overflow; } static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { + uint128_t t; VERIFY_CHECK(bit < 256); - uint128_t t = (uint128_t)r->d[0] + (((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F)); + t = (uint128_t)r->d[0] + (((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F)); r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; t += (uint128_t)r->d[1] + (((uint64_t)((bit >> 6) == 1)) << (bit & 0x3F)); r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; @@ -113,11 +114,12 @@ static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { } static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) { + int over; r->d[0] = (uint64_t)b32[31] | (uint64_t)b32[30] << 8 | (uint64_t)b32[29] << 16 | (uint64_t)b32[28] << 24 | (uint64_t)b32[27] << 32 | (uint64_t)b32[26] << 40 | (uint64_t)b32[25] << 48 | (uint64_t)b32[24] << 56; r->d[1] = (uint64_t)b32[23] | (uint64_t)b32[22] << 8 | (uint64_t)b32[21] << 16 | (uint64_t)b32[20] << 24 | (uint64_t)b32[19] << 32 | (uint64_t)b32[18] << 40 | (uint64_t)b32[17] << 48 | (uint64_t)b32[16] << 56; r->d[2] = (uint64_t)b32[15] | (uint64_t)b32[14] << 8 | (uint64_t)b32[13] << 16 | (uint64_t)b32[12] << 24 | (uint64_t)b32[11] << 32 | (uint64_t)b32[10] << 40 | (uint64_t)b32[9] << 48 | (uint64_t)b32[8] << 56; r->d[3] = (uint64_t)b32[7] | (uint64_t)b32[6] << 8 | (uint64_t)b32[5] << 16 | (uint64_t)b32[4] << 24 | (uint64_t)b32[3] << 32 | (uint64_t)b32[2] << 40 | (uint64_t)b32[1] << 48 | (uint64_t)b32[0] << 56; - int over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); + over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); if (overflow) { *overflow = over; } @@ -195,16 +197,16 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { /** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ #define muladd2(a,b) { \ - uint64_t tl, th; \ + uint64_t tl, th, th2, tl2; \ { \ uint128_t t = (uint128_t)a * b; \ th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ tl = t; \ } \ - uint64_t th2 = th + th; /* at most 0xFFFFFFFFFFFFFFFE (in case th was 0x7FFFFFFFFFFFFFFF) */ \ + th2 = th + th; /* at most 0xFFFFFFFFFFFFFFFE (in case th was 0x7FFFFFFFFFFFFFFF) */ \ c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ VERIFY_CHECK((th2 >= th) || (c2 != 0)); \ - uint64_t tl2 = tl + tl; /* at most 0xFFFFFFFFFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFFFFFFFFFF) */ \ + tl2 = tl + tl; /* at most 0xFFFFFFFFFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFFFFFFFFFF) */ \ th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ c0 += tl2; /* overflow is handled on the next line */ \ th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \ @@ -217,8 +219,9 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { /** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ #define sumadd(a) { \ + unsigned int over; \ c0 += (a); /* overflow is handled on the next line */ \ - unsigned int over = (c0 < (a)) ? 1 : 0; \ + over = (c0 < (a)) ? 1 : 0; \ c1 += over; /* overflow is handled on the next line */ \ c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \ } @@ -248,63 +251,301 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { } static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l) { - uint64_t n0 = l[4], n1 = l[5], n2 = l[6], n3 = l[7]; +#ifdef USE_ASM_X86_64 + /* Reduce 512 bits into 385. */ + uint64_t m0, m1, m2, m3, m4, m5, m6; + uint64_t p0, p1, p2, p3, p4; + uint64_t c; - /* 160 bit accumulator. */ - uint64_t c0, c1; - uint32_t c2; + __asm__ __volatile__( + /* Preload. */ + "movq 32(%%rsi), %%r11\n" + "movq 40(%%rsi), %%r12\n" + "movq 48(%%rsi), %%r13\n" + "movq 56(%%rsi), %%r14\n" + /* Initialize r8,r9,r10 */ + "movq 0(%%rsi), %%r8\n" + "movq $0, %%r9\n" + "movq $0, %%r10\n" + /* (r8,r9) += n0 * c0 */ + "movq %8, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + /* extract m0 */ + "movq %%r8, %q0\n" + "movq $0, %%r8\n" + /* (r9,r10) += l1 */ + "addq 8(%%rsi), %%r9\n" + "adcq $0, %%r10\n" + /* (r9,r10,r8) += n1 * c0 */ + "movq %8, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += n0 * c1 */ + "movq %9, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* extract m1 */ + "movq %%r9, %q1\n" + "movq $0, %%r9\n" + /* (r10,r8,r9) += l2 */ + "addq 16(%%rsi), %%r10\n" + "adcq $0, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += n2 * c0 */ + "movq %8, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += n1 * c1 */ + "movq %9, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += n0 */ + "addq %%r11, %%r10\n" + "adcq $0, %%r8\n" + "adcq $0, %%r9\n" + /* extract m2 */ + "movq %%r10, %q2\n" + "movq $0, %%r10\n" + /* (r8,r9,r10) += l3 */ + "addq 24(%%rsi), %%r8\n" + "adcq $0, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += n3 * c0 */ + "movq %8, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += n2 * c1 */ + "movq %9, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += n1 */ + "addq %%r12, %%r8\n" + "adcq $0, %%r9\n" + "adcq $0, %%r10\n" + /* extract m3 */ + "movq %%r8, %q3\n" + "movq $0, %%r8\n" + /* (r9,r10,r8) += n3 * c1 */ + "movq %9, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += n2 */ + "addq %%r13, %%r9\n" + "adcq $0, %%r10\n" + "adcq $0, %%r8\n" + /* extract m4 */ + "movq %%r9, %q4\n" + /* (r10,r8) += n3 */ + "addq %%r14, %%r10\n" + "adcq $0, %%r8\n" + /* extract m5 */ + "movq %%r10, %q5\n" + /* extract m6 */ + "movq %%r8, %q6\n" + : "=g"(m0), "=g"(m1), "=g"(m2), "=g"(m3), "=g"(m4), "=g"(m5), "=g"(m6) + : "S"(l), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1) + : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "cc"); + + /* Reduce 385 bits into 258. */ + __asm__ __volatile__( + /* Preload */ + "movq %q9, %%r11\n" + "movq %q10, %%r12\n" + "movq %q11, %%r13\n" + /* Initialize (r8,r9,r10) */ + "movq %q5, %%r8\n" + "movq $0, %%r9\n" + "movq $0, %%r10\n" + /* (r8,r9) += m4 * c0 */ + "movq %12, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + /* extract p0 */ + "movq %%r8, %q0\n" + "movq $0, %%r8\n" + /* (r9,r10) += m1 */ + "addq %q6, %%r9\n" + "adcq $0, %%r10\n" + /* (r9,r10,r8) += m5 * c0 */ + "movq %12, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += m4 * c1 */ + "movq %13, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* extract p1 */ + "movq %%r9, %q1\n" + "movq $0, %%r9\n" + /* (r10,r8,r9) += m2 */ + "addq %q7, %%r10\n" + "adcq $0, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += m6 * c0 */ + "movq %12, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += m5 * c1 */ + "movq %13, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += m4 */ + "addq %%r11, %%r10\n" + "adcq $0, %%r8\n" + "adcq $0, %%r9\n" + /* extract p2 */ + "movq %%r10, %q2\n" + /* (r8,r9) += m3 */ + "addq %q8, %%r8\n" + "adcq $0, %%r9\n" + /* (r8,r9) += m6 * c1 */ + "movq %13, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + /* (r8,r9) += m5 */ + "addq %%r12, %%r8\n" + "adcq $0, %%r9\n" + /* extract p3 */ + "movq %%r8, %q3\n" + /* (r9) += m6 */ + "addq %%r13, %%r9\n" + /* extract p4 */ + "movq %%r9, %q4\n" + : "=&g"(p0), "=&g"(p1), "=&g"(p2), "=g"(p3), "=g"(p4) + : "g"(m0), "g"(m1), "g"(m2), "g"(m3), "g"(m4), "g"(m5), "g"(m6), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1) + : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "cc"); + + /* Reduce 258 bits into 256. */ + __asm__ __volatile__( + /* Preload */ + "movq %q5, %%r10\n" + /* (rax,rdx) = p4 * c0 */ + "movq %7, %%rax\n" + "mulq %%r10\n" + /* (rax,rdx) += p0 */ + "addq %q1, %%rax\n" + "adcq $0, %%rdx\n" + /* extract r0 */ + "movq %%rax, 0(%q6)\n" + /* Move to (r8,r9) */ + "movq %%rdx, %%r8\n" + "movq $0, %%r9\n" + /* (r8,r9) += p1 */ + "addq %q2, %%r8\n" + "adcq $0, %%r9\n" + /* (r8,r9) += p4 * c1 */ + "movq %8, %%rax\n" + "mulq %%r10\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + /* Extract r1 */ + "movq %%r8, 8(%q6)\n" + "movq $0, %%r8\n" + /* (r9,r8) += p4 */ + "addq %%r10, %%r9\n" + "adcq $0, %%r8\n" + /* (r9,r8) += p2 */ + "addq %q3, %%r9\n" + "adcq $0, %%r8\n" + /* Extract r2 */ + "movq %%r9, 16(%q6)\n" + "movq $0, %%r9\n" + /* (r8,r9) += p3 */ + "addq %q4, %%r8\n" + "adcq $0, %%r9\n" + /* Extract r3 */ + "movq %%r8, 24(%q6)\n" + /* Extract c */ + "movq %%r9, %q0\n" + : "=g"(c) + : "g"(p0), "g"(p1), "g"(p2), "g"(p3), "g"(p4), "D"(r), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1) + : "rax", "rdx", "r8", "r9", "r10", "cc", "memory"); +#else + uint128_t c; + uint64_t c0, c1, c2; + uint64_t n0 = l[4], n1 = l[5], n2 = l[6], n3 = l[7]; + uint64_t m0, m1, m2, m3, m4, m5; + uint32_t m6; + uint64_t p0, p1, p2, p3; + uint32_t p4; /* Reduce 512 bits into 385. */ /* m[0..6] = l[0..3] + n[0..3] * SECP256K1_N_C. */ c0 = l[0]; c1 = 0; c2 = 0; muladd_fast(n0, SECP256K1_N_C_0); - uint64_t m0; extract_fast(m0); + extract_fast(m0); sumadd_fast(l[1]); muladd(n1, SECP256K1_N_C_0); muladd(n0, SECP256K1_N_C_1); - uint64_t m1; extract(m1); + extract(m1); sumadd(l[2]); muladd(n2, SECP256K1_N_C_0); muladd(n1, SECP256K1_N_C_1); sumadd(n0); - uint64_t m2; extract(m2); + extract(m2); sumadd(l[3]); muladd(n3, SECP256K1_N_C_0); muladd(n2, SECP256K1_N_C_1); sumadd(n1); - uint64_t m3; extract(m3); + extract(m3); muladd(n3, SECP256K1_N_C_1); sumadd(n2); - uint64_t m4; extract(m4); + extract(m4); sumadd_fast(n3); - uint64_t m5; extract_fast(m5); + extract_fast(m5); VERIFY_CHECK(c0 <= 1); - uint32_t m6 = c0; + m6 = c0; /* Reduce 385 bits into 258. */ /* p[0..4] = m[0..3] + m[4..6] * SECP256K1_N_C. */ c0 = m0; c1 = 0; c2 = 0; muladd_fast(m4, SECP256K1_N_C_0); - uint64_t p0; extract_fast(p0); + extract_fast(p0); sumadd_fast(m1); muladd(m5, SECP256K1_N_C_0); muladd(m4, SECP256K1_N_C_1); - uint64_t p1; extract(p1); + extract(p1); sumadd(m2); muladd(m6, SECP256K1_N_C_0); muladd(m5, SECP256K1_N_C_1); sumadd(m4); - uint64_t p2; extract(p2); + extract(p2); sumadd_fast(m3); muladd_fast(m6, SECP256K1_N_C_1); sumadd_fast(m5); - uint64_t p3; extract_fast(p3); - uint32_t p4 = c0 + m6; + extract_fast(p3); + p4 = c0 + m6; VERIFY_CHECK(p4 <= 2); /* Reduce 258 bits into 256. */ /* r[0..3] = p[0..3] + p[4] * SECP256K1_N_C. */ - uint128_t c = p0 + (uint128_t)SECP256K1_N_C_0 * p4; + c = p0 + (uint128_t)SECP256K1_N_C_0 * p4; r->d[0] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; c += p1 + (uint128_t)SECP256K1_N_C_1 * p4; r->d[1] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; @@ -312,12 +553,146 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l r->d[2] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; c += p3; r->d[3] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; +#endif /* Final reduction of r. */ secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); } static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +#ifdef USE_ASM_X86_64 + const uint64_t *pb = b->d; + __asm__ __volatile__( + /* Preload */ + "movq 0(%%rdi), %%r15\n" + "movq 8(%%rdi), %%rbx\n" + "movq 16(%%rdi), %%rcx\n" + "movq 0(%%rdx), %%r11\n" + "movq 8(%%rdx), %%r12\n" + "movq 16(%%rdx), %%r13\n" + "movq 24(%%rdx), %%r14\n" + /* (rax,rdx) = a0 * b0 */ + "movq %%r15, %%rax\n" + "mulq %%r11\n" + /* Extract l0 */ + "movq %%rax, 0(%%rsi)\n" + /* (r8,r9,r10) = (rdx) */ + "movq %%rdx, %%r8\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" + /* (r8,r9,r10) += a0 * b1 */ + "movq %%r15, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += a1 * b0 */ + "movq %%rbx, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* Extract l1 */ + "movq %%r8, 8(%%rsi)\n" + "xorq %%r8, %%r8\n" + /* (r9,r10,r8) += a0 * b2 */ + "movq %%r15, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += a1 * b1 */ + "movq %%rbx, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += a2 * b0 */ + "movq %%rcx, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* Extract l2 */ + "movq %%r9, 16(%%rsi)\n" + "xorq %%r9, %%r9\n" + /* (r10,r8,r9) += a0 * b3 */ + "movq %%r15, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* Preload a3 */ + "movq 24(%%rdi), %%r15\n" + /* (r10,r8,r9) += a1 * b2 */ + "movq %%rbx, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += a2 * b1 */ + "movq %%rcx, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += a3 * b0 */ + "movq %%r15, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* Extract l3 */ + "movq %%r10, 24(%%rsi)\n" + "xorq %%r10, %%r10\n" + /* (r8,r9,r10) += a1 * b3 */ + "movq %%rbx, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += a2 * b2 */ + "movq %%rcx, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += a3 * b1 */ + "movq %%r15, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* Extract l4 */ + "movq %%r8, 32(%%rsi)\n" + "xorq %%r8, %%r8\n" + /* (r9,r10,r8) += a2 * b3 */ + "movq %%rcx, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += a3 * b2 */ + "movq %%r15, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* Extract l5 */ + "movq %%r9, 40(%%rsi)\n" + /* (r10,r8) += a3 * b3 */ + "movq %%r15, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + /* Extract l6 */ + "movq %%r10, 48(%%rsi)\n" + /* Extract l7 */ + "movq %%r8, 56(%%rsi)\n" + : "+d"(pb) + : "S"(l), "D"(a->d) + : "rax", "rbx", "rcx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "cc", "memory"); +#else /* 160 bit accumulator. */ uint64_t c0 = 0, c1 = 0; uint32_t c2 = 0; @@ -348,9 +723,119 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar_t *a, extract_fast(l[6]); VERIFY_CHECK(c1 <= 0); l[7] = c0; +#endif } static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar_t *a) { +#ifdef USE_ASM_X86_64 + __asm__ __volatile__( + /* Preload */ + "movq 0(%%rdi), %%r11\n" + "movq 8(%%rdi), %%r12\n" + "movq 16(%%rdi), %%r13\n" + "movq 24(%%rdi), %%r14\n" + /* (rax,rdx) = a0 * a0 */ + "movq %%r11, %%rax\n" + "mulq %%r11\n" + /* Extract l0 */ + "movq %%rax, 0(%%rsi)\n" + /* (r8,r9,r10) = (rdx,0) */ + "movq %%rdx, %%r8\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" + /* (r8,r9,r10) += 2 * a0 * a1 */ + "movq %%r11, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* Extract l1 */ + "movq %%r8, 8(%%rsi)\n" + "xorq %%r8, %%r8\n" + /* (r9,r10,r8) += 2 * a0 * a2 */ + "movq %%r11, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += a1 * a1 */ + "movq %%r12, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* Extract l2 */ + "movq %%r9, 16(%%rsi)\n" + "xorq %%r9, %%r9\n" + /* (r10,r8,r9) += 2 * a0 * a3 */ + "movq %%r11, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += 2 * a1 * a2 */ + "movq %%r12, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* Extract l3 */ + "movq %%r10, 24(%%rsi)\n" + "xorq %%r10, %%r10\n" + /* (r8,r9,r10) += 2 * a1 * a3 */ + "movq %%r12, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += a2 * a2 */ + "movq %%r13, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* Extract l4 */ + "movq %%r8, 32(%%rsi)\n" + "xorq %%r8, %%r8\n" + /* (r9,r10,r8) += 2 * a2 * a3 */ + "movq %%r13, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* Extract l5 */ + "movq %%r9, 40(%%rsi)\n" + /* (r10,r8) += a3 * a3 */ + "movq %%r14, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + /* Extract l6 */ + "movq %%r10, 48(%%rsi)\n" + /* Extract l7 */ + "movq %%r8, 56(%%rsi)\n" + : + : "S"(l), "D"(a->d) + : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "cc", "memory"); +#else /* 160 bit accumulator. */ uint64_t c0 = 0, c1 = 0; uint32_t c2 = 0; @@ -375,6 +860,7 @@ static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar_t *a) extract_fast(l[6]); VERIFY_CHECK(c1 == 0); l[7] = c0; +#endif } #undef sumadd @@ -413,12 +899,15 @@ SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, con } SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) { - VERIFY_CHECK(shift >= 256); uint64_t l[8]; + unsigned int shiftlimbs; + unsigned int shiftlow; + unsigned int shifthigh; + VERIFY_CHECK(shift >= 256); secp256k1_scalar_mul_512(l, a, b); - unsigned int shiftlimbs = shift >> 6; - unsigned int shiftlow = shift & 0x3F; - unsigned int shifthigh = 64 - shiftlow; + shiftlimbs = shift >> 6; + shiftlow = shift & 0x3F; + shifthigh = 64 - shiftlow; r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[1] = shift < 448 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[2] = shift < 384 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; diff --git a/src/scalar_8x32.h b/src/scalar_8x32.h index f70328cfc93..f17017e24e2 100644 --- a/src/scalar_8x32.h +++ b/src/scalar_8x32.h @@ -14,4 +14,6 @@ typedef struct { uint32_t d[8]; } secp256k1_scalar_t; +#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} + #endif diff --git a/src/scalar_8x32_impl.h b/src/scalar_8x32_impl.h index 915cbcddbe8..22b31d41125 100644 --- a/src/scalar_8x32_impl.h +++ b/src/scalar_8x32_impl.h @@ -91,8 +91,9 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal } SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, uint32_t overflow) { + uint64_t t; VERIFY_CHECK(overflow <= 1); - uint64_t t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0; + t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0; r->d[0] = t & 0xFFFFFFFFUL; t >>= 32; t += (uint64_t)r->d[1] + overflow * SECP256K1_N_C_1; r->d[1] = t & 0xFFFFFFFFUL; t >>= 32; @@ -112,6 +113,7 @@ SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, uint3 } static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + int overflow; uint64_t t = (uint64_t)a->d[0] + b->d[0]; r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; t += (uint64_t)a->d[1] + b->d[1]; @@ -128,15 +130,16 @@ static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; t += (uint64_t)a->d[7] + b->d[7]; r->d[7] = t & 0xFFFFFFFFULL; t >>= 32; - int overflow = t + secp256k1_scalar_check_overflow(r); + overflow = t + secp256k1_scalar_check_overflow(r); VERIFY_CHECK(overflow == 0 || overflow == 1); secp256k1_scalar_reduce(r, overflow); return overflow; } static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { + uint64_t t; VERIFY_CHECK(bit < 256); - uint64_t t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F)); + t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F)); r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F)); r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; @@ -159,6 +162,7 @@ static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { } static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) { + int over; r->d[0] = (uint32_t)b32[31] | (uint32_t)b32[30] << 8 | (uint32_t)b32[29] << 16 | (uint32_t)b32[28] << 24; r->d[1] = (uint32_t)b32[27] | (uint32_t)b32[26] << 8 | (uint32_t)b32[25] << 16 | (uint32_t)b32[24] << 24; r->d[2] = (uint32_t)b32[23] | (uint32_t)b32[22] << 8 | (uint32_t)b32[21] << 16 | (uint32_t)b32[20] << 24; @@ -167,7 +171,7 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char r->d[5] = (uint32_t)b32[11] | (uint32_t)b32[10] << 8 | (uint32_t)b32[9] << 16 | (uint32_t)b32[8] << 24; r->d[6] = (uint32_t)b32[7] | (uint32_t)b32[6] << 8 | (uint32_t)b32[5] << 16 | (uint32_t)b32[4] << 24; r->d[7] = (uint32_t)b32[3] | (uint32_t)b32[2] << 8 | (uint32_t)b32[1] << 16 | (uint32_t)b32[0] << 24; - int over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); + over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); if (overflow) { *overflow = over; } @@ -263,16 +267,16 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { /** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ #define muladd2(a,b) { \ - uint32_t tl, th; \ + uint32_t tl, th, th2, tl2; \ { \ uint64_t t = (uint64_t)a * b; \ th = t >> 32; /* at most 0xFFFFFFFE */ \ tl = t; \ } \ - uint32_t th2 = th + th; /* at most 0xFFFFFFFE (in case th was 0x7FFFFFFF) */ \ + th2 = th + th; /* at most 0xFFFFFFFE (in case th was 0x7FFFFFFF) */ \ c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ VERIFY_CHECK((th2 >= th) || (c2 != 0)); \ - uint32_t tl2 = tl + tl; /* at most 0xFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFF) */ \ + tl2 = tl + tl; /* at most 0xFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFF) */ \ th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ c0 += tl2; /* overflow is handled on the next line */ \ th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \ @@ -285,8 +289,9 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { /** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ #define sumadd(a) { \ + unsigned int over; \ c0 += (a); /* overflow is handled on the next line */ \ - unsigned int over = (c0 < (a)) ? 1 : 0; \ + over = (c0 < (a)) ? 1 : 0; \ c1 += over; /* overflow is handled on the next line */ \ c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \ } @@ -316,7 +321,10 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { } static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint32_t *l) { + uint64_t c; uint32_t n0 = l[8], n1 = l[9], n2 = l[10], n3 = l[11], n4 = l[12], n5 = l[13], n6 = l[14], n7 = l[15]; + uint32_t m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12; + uint32_t p0, p1, p2, p3, p4, p5, p6, p7, p8; /* 96 bit accumulator. */ uint32_t c0, c1, c2; @@ -325,115 +333,115 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint32_t *l /* m[0..12] = l[0..7] + n[0..7] * SECP256K1_N_C. */ c0 = l[0]; c1 = 0; c2 = 0; muladd_fast(n0, SECP256K1_N_C_0); - uint32_t m0; extract_fast(m0); + extract_fast(m0); sumadd_fast(l[1]); muladd(n1, SECP256K1_N_C_0); muladd(n0, SECP256K1_N_C_1); - uint32_t m1; extract(m1); + extract(m1); sumadd(l[2]); muladd(n2, SECP256K1_N_C_0); muladd(n1, SECP256K1_N_C_1); muladd(n0, SECP256K1_N_C_2); - uint32_t m2; extract(m2); + extract(m2); sumadd(l[3]); muladd(n3, SECP256K1_N_C_0); muladd(n2, SECP256K1_N_C_1); muladd(n1, SECP256K1_N_C_2); muladd(n0, SECP256K1_N_C_3); - uint32_t m3; extract(m3); + extract(m3); sumadd(l[4]); muladd(n4, SECP256K1_N_C_0); muladd(n3, SECP256K1_N_C_1); muladd(n2, SECP256K1_N_C_2); muladd(n1, SECP256K1_N_C_3); sumadd(n0); - uint32_t m4; extract(m4); + extract(m4); sumadd(l[5]); muladd(n5, SECP256K1_N_C_0); muladd(n4, SECP256K1_N_C_1); muladd(n3, SECP256K1_N_C_2); muladd(n2, SECP256K1_N_C_3); sumadd(n1); - uint32_t m5; extract(m5); + extract(m5); sumadd(l[6]); muladd(n6, SECP256K1_N_C_0); muladd(n5, SECP256K1_N_C_1); muladd(n4, SECP256K1_N_C_2); muladd(n3, SECP256K1_N_C_3); sumadd(n2); - uint32_t m6; extract(m6); + extract(m6); sumadd(l[7]); muladd(n7, SECP256K1_N_C_0); muladd(n6, SECP256K1_N_C_1); muladd(n5, SECP256K1_N_C_2); muladd(n4, SECP256K1_N_C_3); sumadd(n3); - uint32_t m7; extract(m7); + extract(m7); muladd(n7, SECP256K1_N_C_1); muladd(n6, SECP256K1_N_C_2); muladd(n5, SECP256K1_N_C_3); sumadd(n4); - uint32_t m8; extract(m8); + extract(m8); muladd(n7, SECP256K1_N_C_2); muladd(n6, SECP256K1_N_C_3); sumadd(n5); - uint32_t m9; extract(m9); + extract(m9); muladd(n7, SECP256K1_N_C_3); sumadd(n6); - uint32_t m10; extract(m10); + extract(m10); sumadd_fast(n7); - uint32_t m11; extract_fast(m11); + extract_fast(m11); VERIFY_CHECK(c0 <= 1); - uint32_t m12 = c0; + m12 = c0; /* Reduce 385 bits into 258. */ /* p[0..8] = m[0..7] + m[8..12] * SECP256K1_N_C. */ c0 = m0; c1 = 0; c2 = 0; muladd_fast(m8, SECP256K1_N_C_0); - uint32_t p0; extract_fast(p0); + extract_fast(p0); sumadd_fast(m1); muladd(m9, SECP256K1_N_C_0); muladd(m8, SECP256K1_N_C_1); - uint32_t p1; extract(p1); + extract(p1); sumadd(m2); muladd(m10, SECP256K1_N_C_0); muladd(m9, SECP256K1_N_C_1); muladd(m8, SECP256K1_N_C_2); - uint32_t p2; extract(p2); + extract(p2); sumadd(m3); muladd(m11, SECP256K1_N_C_0); muladd(m10, SECP256K1_N_C_1); muladd(m9, SECP256K1_N_C_2); muladd(m8, SECP256K1_N_C_3); - uint32_t p3; extract(p3); + extract(p3); sumadd(m4); muladd(m12, SECP256K1_N_C_0); muladd(m11, SECP256K1_N_C_1); muladd(m10, SECP256K1_N_C_2); muladd(m9, SECP256K1_N_C_3); sumadd(m8); - uint32_t p4; extract(p4); + extract(p4); sumadd(m5); muladd(m12, SECP256K1_N_C_1); muladd(m11, SECP256K1_N_C_2); muladd(m10, SECP256K1_N_C_3); sumadd(m9); - uint32_t p5; extract(p5); + extract(p5); sumadd(m6); muladd(m12, SECP256K1_N_C_2); muladd(m11, SECP256K1_N_C_3); sumadd(m10); - uint32_t p6; extract(p6); + extract(p6); sumadd_fast(m7); muladd_fast(m12, SECP256K1_N_C_3); sumadd_fast(m11); - uint32_t p7; extract_fast(p7); - uint32_t p8 = c0 + m12; + extract_fast(p7); + p8 = c0 + m12; VERIFY_CHECK(p8 <= 2); /* Reduce 258 bits into 256. */ /* r[0..7] = p[0..7] + p[8] * SECP256K1_N_C. */ - uint64_t c = p0 + (uint64_t)SECP256K1_N_C_0 * p8; + c = p0 + (uint64_t)SECP256K1_N_C_0 * p8; r->d[0] = c & 0xFFFFFFFFUL; c >>= 32; c += p1 + (uint64_t)SECP256K1_N_C_1 * p8; r->d[1] = c & 0xFFFFFFFFUL; c >>= 32; @@ -454,7 +462,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint32_t *l secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); } -static void secp256k1_scalar_mul_512(uint32_t l[16], const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { /* 96 bit accumulator. */ uint32_t c0 = 0, c1 = 0, c2 = 0; @@ -542,7 +550,7 @@ static void secp256k1_scalar_mul_512(uint32_t l[16], const secp256k1_scalar_t *a l[15] = c0; } -static void secp256k1_scalar_sqr_512(uint32_t l[16], const secp256k1_scalar_t *a) { +static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar_t *a) { /* 96 bit accumulator. */ uint32_t c0 = 0, c1 = 0, c2 = 0; @@ -622,6 +630,7 @@ static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t secp256k1_scalar_reduce_512(r, l); } +#ifdef USE_ENDOMORPHISM static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { r1->d[0] = a->d[0]; r1->d[1] = a->d[1]; @@ -640,18 +649,22 @@ static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_ r2->d[6] = 0; r2->d[7] = 0; } +#endif SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0; } SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) { - VERIFY_CHECK(shift >= 256); uint32_t l[16]; + unsigned int shiftlimbs; + unsigned int shiftlow; + unsigned int shifthigh; + VERIFY_CHECK(shift >= 256); secp256k1_scalar_mul_512(l, a, b); - unsigned int shiftlimbs = shift >> 5; - unsigned int shiftlow = shift & 0x1F; - unsigned int shifthigh = 32 - shiftlow; + shiftlimbs = shift >> 5; + shiftlow = shift & 0x1F; + shifthigh = 32 - shiftlow; r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 480 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[1] = shift < 480 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[2] = shift < 448 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 416 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; diff --git a/src/scalar_impl.h b/src/scalar_impl.h index 4408cce2d88..3acbe264ae9 100644 --- a/src/scalar_impl.h +++ b/src/scalar_impl.h @@ -24,121 +24,6 @@ #error "Please select scalar implementation" #endif -typedef struct { -#ifndef USE_NUM_NONE - secp256k1_num_t order; -#endif -#ifdef USE_ENDOMORPHISM - secp256k1_scalar_t minus_lambda, minus_b1, minus_b2, g1, g2; -#endif -} secp256k1_scalar_consts_t; - -static const secp256k1_scalar_consts_t *secp256k1_scalar_consts = NULL; - -static void secp256k1_scalar_start(void) { - if (secp256k1_scalar_consts != NULL) - return; - - /* Allocate. */ - secp256k1_scalar_consts_t *ret = (secp256k1_scalar_consts_t*)checked_malloc(sizeof(secp256k1_scalar_consts_t)); - -#ifndef USE_NUM_NONE - static const unsigned char secp256k1_scalar_consts_order[] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 - }; - secp256k1_num_set_bin(&ret->order, secp256k1_scalar_consts_order, sizeof(secp256k1_scalar_consts_order)); -#endif -#ifdef USE_ENDOMORPHISM - /** - * Lambda is a scalar which has the property for secp256k1 that point multiplication by - * it is efficiently computable (see secp256k1_gej_mul_lambda). */ - static const unsigned char secp256k1_scalar_consts_lambda[32] = { - 0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0, - 0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, - 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78, - 0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72 - }; - /** - * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm - * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1 - * and k2 have a small size. - * It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are: - * - * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} - * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3} - * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8} - * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} - * - * The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives - * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and - * compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2. - * - * g1, g2 are precomputed constants used to replace division with a rounded multiplication - * when decomposing the scalar for an endomorphism-based point multiplication. - * - * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve - * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5. - * - * The derivation is described in the paper "Efficient Software Implementation of Public-Key - * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez), - * Section 4.3 (here we use a somewhat higher-precision estimate): - * d = a1*b2 - b1*a2 - * g1 = round((2^272)*b2/d) - * g2 = round((2^272)*b1/d) - * - * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found - * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda'). - */ - static const unsigned char secp256k1_scalar_consts_minus_b1[32] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28, - 0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3 - }; - static const unsigned char secp256k1_scalar_consts_b2[32] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd, - 0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15 - }; - static const unsigned char secp256k1_scalar_consts_g1[32] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x86, - 0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c, - 0x90,0xe4,0x92,0x84,0xeb,0x15,0x3d,0xab - }; - static const unsigned char secp256k1_scalar_consts_g2[32] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x43, - 0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54, - 0x7f,0xa9,0x0a,0xbf,0xe4,0xc4,0x22,0x12 - }; - - secp256k1_scalar_set_b32(&ret->minus_lambda, secp256k1_scalar_consts_lambda, NULL); - secp256k1_scalar_negate(&ret->minus_lambda, &ret->minus_lambda); - secp256k1_scalar_set_b32(&ret->minus_b1, secp256k1_scalar_consts_minus_b1, NULL); - secp256k1_scalar_set_b32(&ret->minus_b2, secp256k1_scalar_consts_b2, NULL); - secp256k1_scalar_negate(&ret->minus_b2, &ret->minus_b2); - secp256k1_scalar_set_b32(&ret->g1, secp256k1_scalar_consts_g1, NULL); - secp256k1_scalar_set_b32(&ret->g2, secp256k1_scalar_consts_g2, NULL); -#endif - - /* Set the global pointer. */ - secp256k1_scalar_consts = ret; -} - -static void secp256k1_scalar_stop(void) { - if (secp256k1_scalar_consts == NULL) - return; - - secp256k1_scalar_consts_t *c = (secp256k1_scalar_consts_t*)secp256k1_scalar_consts; - secp256k1_scalar_consts = NULL; - free(c); -} - #ifndef USE_NUM_NONE static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a) { unsigned char c[32]; @@ -146,12 +31,21 @@ static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_ secp256k1_num_set_bin(r, c, 32); } +/** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */ static void secp256k1_scalar_order_get_num(secp256k1_num_t *r) { - *r = secp256k1_scalar_consts->order; + static const unsigned char order[32] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, + 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 + }; + secp256k1_num_set_bin(r, order, 32); } #endif static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) { + secp256k1_scalar_t *t; + int i; /* First compute x ^ (2^N - 1) for some values of N. */ secp256k1_scalar_t x2, x3, x4, x6, x7, x8, x15, x30, x60, x120, x127; @@ -175,129 +69,129 @@ static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scal secp256k1_scalar_mul(&x8, &x8, x); secp256k1_scalar_sqr(&x15, &x8); - for (int i=0; i<6; i++) + for (i = 0; i < 6; i++) secp256k1_scalar_sqr(&x15, &x15); secp256k1_scalar_mul(&x15, &x15, &x7); secp256k1_scalar_sqr(&x30, &x15); - for (int i=0; i<14; i++) + for (i = 0; i < 14; i++) secp256k1_scalar_sqr(&x30, &x30); secp256k1_scalar_mul(&x30, &x30, &x15); secp256k1_scalar_sqr(&x60, &x30); - for (int i=0; i<29; i++) + for (i = 0; i < 29; i++) secp256k1_scalar_sqr(&x60, &x60); secp256k1_scalar_mul(&x60, &x60, &x30); secp256k1_scalar_sqr(&x120, &x60); - for (int i=0; i<59; i++) + for (i = 0; i < 59; i++) secp256k1_scalar_sqr(&x120, &x120); secp256k1_scalar_mul(&x120, &x120, &x60); secp256k1_scalar_sqr(&x127, &x120); - for (int i=0; i<6; i++) + for (i = 0; i < 6; i++) secp256k1_scalar_sqr(&x127, &x127); secp256k1_scalar_mul(&x127, &x127, &x7); /* Then accumulate the final result (t starts at x127). */ - secp256k1_scalar_t *t = &x127; - for (int i=0; i<2; i++) /* 0 */ + t = &x127; + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<4; i++) /* 0 */ + for (i = 0; i < 4; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<4; i++) /* 0 */ + for (i = 0; i < 4; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (int i=0; i<3; i++) /* 0 */ + for (i = 0; i < 3; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (int i=0; i<4; i++) /* 0 */ + for (i = 0; i < 4; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (int i=0; i<5; i++) /* 00 */ + for (i = 0; i < 5; i++) /* 00 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (int i=0; i<4; i++) /* 00 */ + for (i = 0; i < 4; i++) /* 00 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<5; i++) /* 0 */ + for (i = 0; i < 5; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x4); /* 1111 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<3; i++) /* 00 */ + for (i = 0; i < 3; i++) /* 00 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<4; i++) /* 000 */ + for (i = 0; i < 4; i++) /* 000 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<10; i++) /* 0000000 */ + for (i = 0; i < 10; i++) /* 0000000 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (int i=0; i<4; i++) /* 0 */ + for (i = 0; i < 4; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (int i=0; i<9; i++) /* 0 */ + for (i = 0; i < 9; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x8); /* 11111111 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<3; i++) /* 00 */ + for (i = 0; i < 3; i++) /* 00 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<3; i++) /* 00 */ + for (i = 0; i < 3; i++) /* 00 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<5; i++) /* 0 */ + for (i = 0; i < 5; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x4); /* 1111 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<5; i++) /* 000 */ + for (i = 0; i < 5; i++) /* 000 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (int i=0; i<4; i++) /* 00 */ + for (i = 0; i < 4; i++) /* 00 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (int i=0; i<2; i++) /* 0 */ + for (i = 0; i < 2; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<8; i++) /* 000000 */ + for (i = 0; i < 8; i++) /* 000000 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (int i=0; i<3; i++) /* 0 */ + for (i = 0; i < 3; i++) /* 0 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (int i=0; i<3; i++) /* 00 */ + for (i = 0; i < 3; i++) /* 00 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<6; i++) /* 00000 */ + for (i = 0; i < 6; i++) /* 00000 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(t, t, x); /* 1 */ - for (int i=0; i<8; i++) /* 00 */ + for (i = 0; i < 8; i++) /* 00 */ secp256k1_scalar_sqr(t, t); secp256k1_scalar_mul(r, t, &x6); /* 111111 */ } @@ -307,10 +201,11 @@ static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_ secp256k1_scalar_inverse(r, x); #elif defined(USE_SCALAR_INV_NUM) unsigned char b[32]; + secp256k1_num_t n, m; secp256k1_scalar_get_b32(b, x); - secp256k1_num_t n; secp256k1_num_set_bin(&n, b, 32); - secp256k1_num_mod_inverse(&n, &n, &secp256k1_scalar_consts->order); + secp256k1_scalar_order_get_num(&m); + secp256k1_num_mod_inverse(&n, &n, &m); secp256k1_num_get_bin(b, 32, &n); secp256k1_scalar_set_b32(r, b, NULL); #else @@ -319,16 +214,74 @@ static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_ } #ifdef USE_ENDOMORPHISM +/** + * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where + * lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, + * 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72} + * + * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm + * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1 + * and k2 have a small size. + * It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are: + * + * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} + * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3} + * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8} + * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} + * + * The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives + * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and + * compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2. + * + * g1, g2 are precomputed constants used to replace division with a rounded multiplication + * when decomposing the scalar for an endomorphism-based point multiplication. + * + * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve + * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5. + * + * The derivation is described in the paper "Efficient Software Implementation of Public-Key + * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez), + * Section 4.3 (here we use a somewhat higher-precision estimate): + * d = a1*b2 - b1*a2 + * g1 = round((2^272)*b2/d) + * g2 = round((2^272)*b1/d) + * + * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found + * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda'). + * + * The function below splits a in r1 and r2, such that r1 + lambda * r2 == a (mod order). + */ + static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { + secp256k1_scalar_t c1, c2; + static const secp256k1_scalar_t minus_lambda = SECP256K1_SCALAR_CONST( + 0xAC9C52B3UL, 0x3FA3CF1FUL, 0x5AD9E3FDUL, 0x77ED9BA4UL, + 0xA880B9FCUL, 0x8EC739C2UL, 0xE0CFC810UL, 0xB51283CFUL + ); + static const secp256k1_scalar_t minus_b1 = SECP256K1_SCALAR_CONST( + 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, + 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL + ); + static const secp256k1_scalar_t minus_b2 = SECP256K1_SCALAR_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, + 0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL + ); + static const secp256k1_scalar_t g1 = SECP256K1_SCALAR_CONST( + 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00003086UL, + 0xD221A7D4UL, 0x6BCDE86CUL, 0x90E49284UL, 0xEB153DABUL + ); + static const secp256k1_scalar_t g2 = SECP256K1_SCALAR_CONST( + 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0000E443UL, + 0x7ED6010EUL, 0x88286F54UL, 0x7FA90ABFUL, 0xE4C42212UL + ); VERIFY_CHECK(r1 != a); VERIFY_CHECK(r2 != a); - secp256k1_scalar_t c1, c2; - secp256k1_scalar_mul_shift_var(&c1, a, &secp256k1_scalar_consts->g1, 272); - secp256k1_scalar_mul_shift_var(&c2, a, &secp256k1_scalar_consts->g2, 272); - secp256k1_scalar_mul(&c1, &c1, &secp256k1_scalar_consts->minus_b1); - secp256k1_scalar_mul(&c2, &c2, &secp256k1_scalar_consts->minus_b2); + secp256k1_scalar_mul_shift_var(&c1, a, &g1, 272); + secp256k1_scalar_mul_shift_var(&c2, a, &g2, 272); + secp256k1_scalar_mul(&c1, &c1, &minus_b1); + secp256k1_scalar_mul(&c2, &c2, &minus_b2); secp256k1_scalar_add(r2, &c1, &c2); - secp256k1_scalar_mul(r1, r2, &secp256k1_scalar_consts->minus_lambda); + secp256k1_scalar_mul(r1, r2, &minus_lambda); secp256k1_scalar_add(r1, r1, a); } #endif diff --git a/src/secp256k1.c b/src/secp256k1.c index 58bcd8d009e..8c4eca4b629 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -20,10 +20,6 @@ #include "hash_impl.h" void secp256k1_start(unsigned int flags) { - secp256k1_fe_start(); - secp256k1_ge_start(); - secp256k1_scalar_start(); - secp256k1_ecdsa_start(); if (flags & SECP256K1_START_SIGN) { secp256k1_ecmult_gen_start(); } @@ -35,46 +31,43 @@ void secp256k1_start(unsigned int flags) { void secp256k1_stop(void) { secp256k1_ecmult_stop(); secp256k1_ecmult_gen_stop(); - secp256k1_ecdsa_stop(); - secp256k1_scalar_stop(); - secp256k1_ge_stop(); - secp256k1_fe_stop(); } int secp256k1_ecdsa_verify(const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { + secp256k1_ge_t q; + secp256k1_ecdsa_sig_t s; + secp256k1_scalar_t m; + int ret = -3; DEBUG_CHECK(secp256k1_ecmult_consts != NULL); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig != NULL); DEBUG_CHECK(pubkey != NULL); - int ret = -3; - secp256k1_scalar_t m; - secp256k1_ecdsa_sig_t s; - secp256k1_ge_t q; secp256k1_scalar_set_b32(&m, msg32, NULL); - if (!secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) { + if (secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) { + if (secp256k1_ecdsa_sig_parse(&s, sig, siglen)) { + if (secp256k1_ecdsa_sig_verify(&s, &q, &m)) { + /* success is 1, all other values are fail */ + ret = 1; + } else { + ret = 0; + } + } else { + ret = -2; + } + } else { ret = -1; - goto end; } - if (!secp256k1_ecdsa_sig_parse(&s, sig, siglen)) { - ret = -2; - goto end; - } - if (!secp256k1_ecdsa_sig_verify(&s, &q, &m)) { - ret = 0; - goto end; - } - ret = 1; -end: + return ret; } static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { - (void)data; secp256k1_rfc6979_hmac_sha256_t rng; - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32); - for (unsigned int i = 0; i <= counter; i++) { + unsigned int i; + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32, data, data != NULL ? 32 : 0); + for (i = 0; i <= counter; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); @@ -85,6 +78,11 @@ const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979 = nonce_functi const secp256k1_nonce_function_t secp256k1_nonce_function_default = nonce_function_rfc6979; int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) { + secp256k1_ecdsa_sig_t sig; + secp256k1_scalar_t sec, non, msg; + int ret = 0; + int overflow = 0; + unsigned int count = 0; DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(signature != NULL); @@ -94,38 +92,44 @@ int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, i noncefp = secp256k1_nonce_function_default; } - secp256k1_scalar_t sec, non, msg; - secp256k1_scalar_set_b32(&sec, seckey, NULL); - secp256k1_scalar_set_b32(&msg, msg32, NULL); - int overflow = 0; - int ret = 0; - unsigned int count = 0; - secp256k1_ecdsa_sig_t sig; - while (1) { - unsigned char nonce32[32]; - ret = noncefp(nonce32, msg32, seckey, count, noncedata); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL)) { + secp256k1_scalar_set_b32(&sec, seckey, &overflow); + /* Fail if the secret key is invalid. */ + if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + secp256k1_scalar_set_b32(&msg, msg32, NULL); + while (1) { + unsigned char nonce32[32]; + ret = noncefp(nonce32, msg32, seckey, count, noncedata); + if (!ret) { break; } + secp256k1_scalar_set_b32(&non, nonce32, &overflow); + memset(nonce32, 0, 32); + if (!secp256k1_scalar_is_zero(&non) && !overflow) { + if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL)) { + break; + } + } + count++; } - count++; + if (ret) { + ret = secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig); + } + secp256k1_scalar_clear(&msg); + secp256k1_scalar_clear(&non); + secp256k1_scalar_clear(&sec); } - if (ret) { - ret = secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig); + if (!ret) { + *signaturelen = 0; } - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); return ret; } int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) { + secp256k1_ecdsa_sig_t sig; + secp256k1_scalar_t sec, non, msg; + int ret = 0; + int overflow = 0; + unsigned int count = 0; DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig64 != NULL); @@ -134,39 +138,45 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig6 noncefp = secp256k1_nonce_function_default; } - secp256k1_scalar_t sec, non, msg; - secp256k1_scalar_set_b32(&sec, seckey, NULL); - secp256k1_scalar_set_b32(&msg, msg32, NULL); - int overflow = 0; - int ret = 0; - unsigned int count = 0; - secp256k1_ecdsa_sig_t sig; - while (1) { - unsigned char nonce32[32]; - ret = noncefp(nonce32, msg32, seckey, count, noncedata); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid)) { + secp256k1_scalar_set_b32(&sec, seckey, &overflow); + /* Fail if the secret key is invalid. */ + if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + secp256k1_scalar_set_b32(&msg, msg32, NULL); + while (1) { + unsigned char nonce32[32]; + ret = noncefp(nonce32, msg32, seckey, count, noncedata); + if (!ret) { break; } + secp256k1_scalar_set_b32(&non, nonce32, &overflow); + memset(nonce32, 0, 32); + if (!secp256k1_scalar_is_zero(&non) && !overflow) { + if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid)) { + break; + } + } + count++; } - count++; + if (ret) { + secp256k1_scalar_get_b32(sig64, &sig.r); + secp256k1_scalar_get_b32(sig64 + 32, &sig.s); + } + secp256k1_scalar_clear(&msg); + secp256k1_scalar_clear(&non); + secp256k1_scalar_clear(&sec); } - if (ret) { - secp256k1_scalar_get_b32(sig64, &sig.r); - secp256k1_scalar_get_b32(sig64 + 32, &sig.s); + if (!ret) { + memset(sig64, 0, 64); } - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); return ret; } int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { + secp256k1_ge_t q; + secp256k1_ecdsa_sig_t sig; + secp256k1_scalar_t m; + int ret = 0; + int overflow = 0; DEBUG_CHECK(secp256k1_ecmult_consts != NULL); DEBUG_CHECK(msg32 != NULL); DEBUG_CHECK(sig64 != NULL); @@ -174,82 +184,87 @@ int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned c DEBUG_CHECK(pubkeylen != NULL); DEBUG_CHECK(recid >= 0 && recid <= 3); - int ret = 0; - secp256k1_scalar_t m; - secp256k1_ecdsa_sig_t sig; - int overflow = 0; secp256k1_scalar_set_b32(&sig.r, sig64, &overflow); - if (overflow) { - return 0; - } - secp256k1_scalar_set_b32(&sig.s, sig64 + 32, &overflow); - if (overflow) { - return 0; - } - secp256k1_scalar_set_b32(&m, msg32, NULL); + if (!overflow) { + secp256k1_scalar_set_b32(&sig.s, sig64 + 32, &overflow); + if (!overflow) { + secp256k1_scalar_set_b32(&m, msg32, NULL); - secp256k1_ge_t q; - if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) { - ret = secp256k1_eckey_pubkey_serialize(&q, pubkey, pubkeylen, compressed); + if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) { + ret = secp256k1_eckey_pubkey_serialize(&q, pubkey, pubkeylen, compressed); + } + } } return ret; } int secp256k1_ec_seckey_verify(const unsigned char *seckey) { + secp256k1_scalar_t sec; + int ret; + int overflow; DEBUG_CHECK(seckey != NULL); - secp256k1_scalar_t sec; - int overflow; secp256k1_scalar_set_b32(&sec, seckey, &overflow); - int ret = !secp256k1_scalar_is_zero(&sec) && !overflow; + ret = !secp256k1_scalar_is_zero(&sec) && !overflow; secp256k1_scalar_clear(&sec); return ret; } int secp256k1_ec_pubkey_verify(const unsigned char *pubkey, int pubkeylen) { + secp256k1_ge_t q; DEBUG_CHECK(pubkey != NULL); - secp256k1_ge_t q; return secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen); } int secp256k1_ec_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) { + secp256k1_gej_t pj; + secp256k1_ge_t p; + secp256k1_scalar_t sec; + int overflow; + int ret = 0; DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(pubkeylen != NULL); DEBUG_CHECK(seckey != NULL); - secp256k1_scalar_t sec; - secp256k1_scalar_set_b32(&sec, seckey, NULL); - secp256k1_gej_t pj; - secp256k1_ecmult_gen(&pj, &sec); - secp256k1_scalar_clear(&sec); - secp256k1_ge_t p; - secp256k1_ge_set_gej(&p, &pj); - return secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, compressed); + secp256k1_scalar_set_b32(&sec, seckey, &overflow); + if (!overflow) { + secp256k1_ecmult_gen(&pj, &sec); + secp256k1_scalar_clear(&sec); + secp256k1_ge_set_gej(&p, &pj); + ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, compressed); + } + if (!ret) { + *pubkeylen = 0; + } + return ret; } int secp256k1_ec_pubkey_decompress(unsigned char *pubkey, int *pubkeylen) { + secp256k1_ge_t p; + int ret = 0; DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(pubkeylen != NULL); - secp256k1_ge_t p; - if (!secp256k1_eckey_pubkey_parse(&p, pubkey, *pubkeylen)) - return 0; - return secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, 0); + if (secp256k1_eckey_pubkey_parse(&p, pubkey, *pubkeylen)) { + ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, 0); + } + return ret; } int secp256k1_ec_privkey_tweak_add(unsigned char *seckey, const unsigned char *tweak) { + secp256k1_scalar_t term; + secp256k1_scalar_t sec; + int ret = 0; + int overflow = 0; DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(tweak != NULL); - secp256k1_scalar_t term; - int overflow = 0; secp256k1_scalar_set_b32(&term, tweak, &overflow); - secp256k1_scalar_t sec; secp256k1_scalar_set_b32(&sec, seckey, NULL); - int ret = secp256k1_eckey_privkey_tweak_add(&sec, &term) && !overflow; + ret = secp256k1_eckey_privkey_tweak_add(&sec, &term) && !overflow; if (ret) { secp256k1_scalar_get_b32(seckey, &sec); } @@ -260,40 +275,41 @@ int secp256k1_ec_privkey_tweak_add(unsigned char *seckey, const unsigned char *t } int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { + secp256k1_ge_t p; + secp256k1_scalar_t term; + int ret = 0; + int overflow = 0; DEBUG_CHECK(secp256k1_ecmult_consts != NULL); DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(tweak != NULL); - secp256k1_scalar_t term; - int overflow = 0; secp256k1_scalar_set_b32(&term, tweak, &overflow); - if (overflow) { - return 0; - } - secp256k1_ge_t p; - int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); - if (ret) { - ret = secp256k1_eckey_pubkey_tweak_add(&p, &term); - } - if (ret) { - int oldlen = pubkeylen; - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); - VERIFY_CHECK(pubkeylen == oldlen); + if (!overflow) { + ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); + if (ret) { + ret = secp256k1_eckey_pubkey_tweak_add(&p, &term); + } + if (ret) { + int oldlen = pubkeylen; + ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); + VERIFY_CHECK(pubkeylen == oldlen); + } } return ret; } int secp256k1_ec_privkey_tweak_mul(unsigned char *seckey, const unsigned char *tweak) { + secp256k1_scalar_t factor; + secp256k1_scalar_t sec; + int ret = 0; + int overflow = 0; DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(tweak != NULL); - secp256k1_scalar_t factor; - int overflow = 0; secp256k1_scalar_set_b32(&factor, tweak, &overflow); - secp256k1_scalar_t sec; secp256k1_scalar_set_b32(&sec, seckey, NULL); - int ret = secp256k1_eckey_privkey_tweak_mul(&sec, &factor) && !overflow; + ret = secp256k1_eckey_privkey_tweak_mul(&sec, &factor) && !overflow; if (ret) { secp256k1_scalar_get_b32(seckey, &sec); } @@ -304,50 +320,53 @@ int secp256k1_ec_privkey_tweak_mul(unsigned char *seckey, const unsigned char *t } int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { + secp256k1_ge_t p; + secp256k1_scalar_t factor; + int ret = 0; + int overflow = 0; DEBUG_CHECK(secp256k1_ecmult_consts != NULL); DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(tweak != NULL); - secp256k1_scalar_t factor; - int overflow = 0; secp256k1_scalar_set_b32(&factor, tweak, &overflow); - if (overflow) { - return 0; - } - secp256k1_ge_t p; - int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); - if (ret) { - ret = secp256k1_eckey_pubkey_tweak_mul(&p, &factor); - } - if (ret) { - int oldlen = pubkeylen; - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); - VERIFY_CHECK(pubkeylen == oldlen); + if (!overflow) { + ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); + if (ret) { + ret = secp256k1_eckey_pubkey_tweak_mul(&p, &factor); + } + if (ret) { + int oldlen = pubkeylen; + ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); + VERIFY_CHECK(pubkeylen == oldlen); + } } return ret; } int secp256k1_ec_privkey_export(const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) { + secp256k1_scalar_t key; + int ret = 0; DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(privkey != NULL); DEBUG_CHECK(privkeylen != NULL); - secp256k1_scalar_t key; secp256k1_scalar_set_b32(&key, seckey, NULL); - int ret = secp256k1_eckey_privkey_serialize(privkey, privkeylen, &key, compressed); + ret = secp256k1_eckey_privkey_serialize(privkey, privkeylen, &key, compressed); secp256k1_scalar_clear(&key); return ret; } int secp256k1_ec_privkey_import(unsigned char *seckey, const unsigned char *privkey, int privkeylen) { + secp256k1_scalar_t key; + int ret = 0; DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(privkey != NULL); - secp256k1_scalar_t key; - int ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen); - if (ret) + ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen); + if (ret) { secp256k1_scalar_get_b32(seckey, &key); + } secp256k1_scalar_clear(&key); return ret; } diff --git a/src/testrand.h b/src/testrand.h index 018b65cd53f..041bb92c47a 100644 --- a/src/testrand.h +++ b/src/testrand.h @@ -11,8 +11,10 @@ #include "libsecp256k1-config.h" #endif -/** Seed the pseudorandom number generator. */ -SECP256K1_INLINE static void secp256k1_rand_seed(uint64_t v); +/* A non-cryptographic RNG used only for test infrastructure. */ + +/** Seed the pseudorandom number generator for testing. */ +SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16); /** Generate a pseudorandom 32-bit number. */ static uint32_t secp256k1_rand32(void); diff --git a/src/testrand_impl.h b/src/testrand_impl.h index 677c4b9a0e4..21c69f1c51e 100644 --- a/src/testrand_impl.h +++ b/src/testrand_impl.h @@ -11,44 +11,44 @@ #include #include "testrand.h" +#include "hash.h" -static uint32_t secp256k1_Rz = 11, secp256k1_Rw = 11; +static secp256k1_rfc6979_hmac_sha256_t secp256k1_test_rng; +static uint32_t secp256k1_test_rng_precomputed[8]; +static int secp256k1_test_rng_precomputed_used = 8; -SECP256K1_INLINE static void secp256k1_rand_seed(uint64_t v) { - secp256k1_Rz = v >> 32; - secp256k1_Rw = v; - - if (secp256k1_Rz == 0 || secp256k1_Rz == 0x9068ffffU) { - secp256k1_Rz = 111; - } - if (secp256k1_Rw == 0 || secp256k1_Rw == 0x464fffffU) { - secp256k1_Rw = 111; - } +SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) { + secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, (const unsigned char*)"TestRNG", 7, seed16, 16, NULL, 0); } SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { - secp256k1_Rz = 36969 * (secp256k1_Rz & 0xFFFF) + (secp256k1_Rz >> 16); - secp256k1_Rw = 18000 * (secp256k1_Rw & 0xFFFF) + (secp256k1_Rw >> 16); - return (secp256k1_Rw << 16) + (secp256k1_Rw >> 16) + secp256k1_Rz; + if (secp256k1_test_rng_precomputed_used == 8) { + secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, (unsigned char*)(&secp256k1_test_rng_precomputed[0]), sizeof(secp256k1_test_rng_precomputed)); + secp256k1_test_rng_precomputed_used = 0; + } + return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; } static void secp256k1_rand256(unsigned char *b32) { - for (int i=0; i<8; i++) { - uint32_t r = secp256k1_rand32(); - b32[i*4 + 0] = (r >> 0) & 0xFF; - b32[i*4 + 1] = (r >> 8) & 0xFF; - b32[i*4 + 2] = (r >> 16) & 0xFF; - b32[i*4 + 3] = (r >> 24) & 0xFF; - } + secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); } static void secp256k1_rand256_test(unsigned char *b32) { int bits=0; + uint64_t ent = 0; + int entleft = 0; memset(b32, 0, 32); while (bits < 256) { - uint32_t ent = secp256k1_rand32(); - int now = 1 + ((ent % 64)*((ent >> 6) % 32)+16)/31; - uint32_t val = 1 & (ent >> 11); + int now; + uint32_t val; + if (entleft < 12) { + ent |= ((uint64_t)secp256k1_rand32()) << entleft; + entleft += 32; + } + now = 1 + ((ent % 64)*((ent >> 6) % 32)+16)/31; + val = 1 & (ent >> 11); + ent >>= 12; + entleft -= 12; while (now > 0 && bits < 256) { b32[bits / 8] |= val << (bits % 8); now--; diff --git a/src/tests.c b/src/tests.c index cff32f1d068..f7f1acac646 100644 --- a/src/tests.c +++ b/src/tests.c @@ -36,12 +36,12 @@ void random_field_element_test(secp256k1_fe_t *fe) { } void random_field_element_magnitude(secp256k1_fe_t *fe) { + secp256k1_fe_t zero; int n = secp256k1_rand32() % 9; secp256k1_fe_normalize(fe); if (n == 0) { return; } - secp256k1_fe_t zero; secp256k1_fe_clear(&zero); secp256k1_fe_negate(&zero, &zero, 0); secp256k1_fe_mul_int(&zero, n - 1); @@ -61,14 +61,15 @@ void random_group_element_test(secp256k1_ge_t *ge) { } void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge_t *ge) { + secp256k1_fe_t z2, z3; do { random_field_element_test(&gej->z); if (!secp256k1_fe_is_zero(&gej->z)) { break; } } while(1); - secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &gej->z); - secp256k1_fe_t z3; secp256k1_fe_mul(&z3, &z2, &gej->z); + secp256k1_fe_sqr(&z2, &gej->z); + secp256k1_fe_mul(&z3, &z2, &gej->z); secp256k1_fe_mul(&gej->x, &ge->x, &z2); secp256k1_fe_mul(&gej->y, &ge->y, &z3); gej->infinity = ge->infinity; @@ -77,8 +78,8 @@ void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge void random_scalar_order_test(secp256k1_scalar_t *num) { do { unsigned char b32[32]; - secp256k1_rand256_test(b32); int overflow = 0; + secp256k1_rand256_test(b32); secp256k1_scalar_set_b32(num, b32, &overflow); if (overflow || secp256k1_scalar_is_zero(num)) continue; @@ -89,8 +90,8 @@ void random_scalar_order_test(secp256k1_scalar_t *num) { void random_scalar_order(secp256k1_scalar_t *num) { do { unsigned char b32[32]; - secp256k1_rand256(b32); int overflow = 0; + secp256k1_rand256(b32); secp256k1_scalar_set_b32(num, b32, &overflow); if (overflow || secp256k1_scalar_is_zero(num)) continue; @@ -117,16 +118,17 @@ void run_sha256_tests(void) { {0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42}, {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8} }; - for (int i = 0; i < 8; i++) { + int i; + for (i = 0; i < 8; i++) { + unsigned char out[32]; secp256k1_sha256_t hasher; secp256k1_sha256_initialize(&hasher); secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); - unsigned char out[32]; secp256k1_sha256_finalize(&hasher, out); CHECK(memcmp(out, outputs[i], 32) == 0); if (strlen(inputs[i]) > 0) { - secp256k1_sha256_initialize(&hasher); int split = secp256k1_rand32() % strlen(inputs[i]); + secp256k1_sha256_initialize(&hasher); secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); secp256k1_sha256_finalize(&hasher, out); @@ -160,16 +162,17 @@ void run_hmac_sha256_tests(void) { {0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54}, {0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2} }; - for (int i = 0; i < 6; i++) { + int i; + for (i = 0; i < 6; i++) { secp256k1_hmac_sha256_t hasher; + unsigned char out[32]; secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); - unsigned char out[32]; secp256k1_hmac_sha256_finalize(&hasher, out); CHECK(memcmp(out, outputs[i], 32) == 0); if (strlen(inputs[i]) > 0) { - secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); int split = secp256k1_rand32() % strlen(inputs[i]); + secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); secp256k1_hmac_sha256_finalize(&hasher, out); @@ -197,16 +200,25 @@ void run_rfc6979_hmac_sha256_tests(void) { secp256k1_rfc6979_hmac_sha256_t rng; unsigned char out[32]; + unsigned char zero[1] = {0}; + int i; - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32); - for (int i = 0; i < 3; i++) { + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32, NULL, 1); + for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); CHECK(memcmp(out, out1[i], 32) == 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 32, msg2, 32); - for (int i = 0; i < 3; i++) { + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32, zero, 1); + for (i = 0; i < 3; i++) { + secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); + CHECK(memcmp(out, out1[i], 32) != 0); + } + secp256k1_rfc6979_hmac_sha256_finalize(&rng); + + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 32, msg2, 32, zero, 0); + for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); CHECK(memcmp(out, out2[i], 32) == 0); } @@ -254,9 +266,10 @@ void test_num_negate(void) { } void test_num_add_sub(void) { - int r = secp256k1_rand32(); secp256k1_num_t n1; secp256k1_num_t n2; + secp256k1_num_t n1p2, n2p1, n1m2, n2m1; + int r = secp256k1_rand32(); random_num_order_test(&n1); /* n1 = R1 */ if (r & 1) { random_num_negate(&n1); @@ -265,7 +278,6 @@ void test_num_add_sub(void) { if (r & 2) { random_num_negate(&n2); } - secp256k1_num_t n1p2, n2p1, n1m2, n2m1; secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */ secp256k1_num_add(&n2p1, &n2, &n1); /* n2p1 = R2 + R1 */ secp256k1_num_sub(&n1m2, &n1, &n2); /* n1m2 = R1 - R2 */ @@ -283,7 +295,8 @@ void test_num_add_sub(void) { } void run_num_smalltests(void) { - for (int i=0; i<100*count; i++) { + int i; + for (i = 0; i < 100*count; i++) { test_num_negate(); test_num_add_sub(); } @@ -293,41 +306,45 @@ void run_num_smalltests(void) { /***** SCALAR TESTS *****/ void scalar_test(void) { + secp256k1_scalar_t s; + secp256k1_scalar_t s1; + secp256k1_scalar_t s2; +#ifndef USE_NUM_NONE + secp256k1_num_t snum, s1num, s2num; + secp256k1_num_t order, half_order; +#endif unsigned char c[32]; /* Set 's' to a random scalar, with value 'snum'. */ - secp256k1_scalar_t s; random_scalar_order_test(&s); /* Set 's1' to a random scalar, with value 's1num'. */ - secp256k1_scalar_t s1; random_scalar_order_test(&s1); /* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */ - secp256k1_scalar_t s2; random_scalar_order_test(&s2); secp256k1_scalar_get_b32(c, &s2); #ifndef USE_NUM_NONE - secp256k1_num_t snum, s1num, s2num; secp256k1_scalar_get_num(&snum, &s); secp256k1_scalar_get_num(&s1num, &s1); secp256k1_scalar_get_num(&s2num, &s2); - secp256k1_num_t order; secp256k1_scalar_order_get_num(&order); - secp256k1_num_t half_order = order; + half_order = order; secp256k1_num_shift(&half_order, 1); #endif { + int i; /* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */ secp256k1_scalar_t n; secp256k1_scalar_set_int(&n, 0); - for (int i = 0; i < 256; i += 4) { + for (i = 0; i < 256; i += 4) { secp256k1_scalar_t t; + int j; secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4)); - for (int j = 0; j < 4; j++) { + for (j = 0; j < 4; j++) { secp256k1_scalar_add(&n, &n, &n); } secp256k1_scalar_add(&n, &n, &t); @@ -338,16 +355,17 @@ void scalar_test(void) { { /* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */ secp256k1_scalar_t n; - secp256k1_scalar_set_int(&n, 0); int i = 0; + secp256k1_scalar_set_int(&n, 0); while (i < 256) { + secp256k1_scalar_t t; + int j; int now = (secp256k1_rand32() % 15) + 1; if (now + i > 256) { now = 256 - i; } - secp256k1_scalar_t t; secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_var(&s, 256 - now - i, now)); - for (int j = 0; j < now; j++) { + for (j = 0; j < now; j++) { secp256k1_scalar_add(&n, &n, &n); } secp256k1_scalar_add(&n, &n, &t); @@ -360,23 +378,23 @@ void scalar_test(void) { { /* Test that adding the scalars together is equal to adding their numbers together modulo the order. */ secp256k1_num_t rnum; + secp256k1_num_t r2num; + secp256k1_scalar_t r; secp256k1_num_add(&rnum, &snum, &s2num); secp256k1_num_mod(&rnum, &order); - secp256k1_scalar_t r; secp256k1_scalar_add(&r, &s, &s2); - secp256k1_num_t r2num; secp256k1_scalar_get_num(&r2num, &r); CHECK(secp256k1_num_eq(&rnum, &r2num)); } { /* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */ + secp256k1_scalar_t r; + secp256k1_num_t r2num; secp256k1_num_t rnum; secp256k1_num_mul(&rnum, &snum, &s2num); secp256k1_num_mod(&rnum, &order); - secp256k1_scalar_t r; secp256k1_scalar_mul(&r, &s, &s2); - secp256k1_num_t r2num; secp256k1_scalar_get_num(&r2num, &r); CHECK(secp256k1_num_eq(&rnum, &r2num)); /* The result can only be zero if at least one of the factors was zero. */ @@ -387,20 +405,20 @@ void scalar_test(void) { } { + secp256k1_scalar_t neg; + secp256k1_num_t negnum; + secp256k1_num_t negnum2; /* Check that comparison with zero matches comparison with zero on the number. */ CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s)); /* Check that comparison with the half order is equal to testing for high scalar. */ CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &half_order) > 0)); - secp256k1_scalar_t neg; secp256k1_scalar_negate(&neg, &s); - secp256k1_num_t negnum; secp256k1_num_sub(&negnum, &order, &snum); secp256k1_num_mod(&negnum, &order); /* Check that comparison with the half order is equal to testing for high scalar after negation. */ CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &half_order) > 0)); /* Negating should change the high property, unless the value was already zero. */ CHECK((secp256k1_scalar_is_high(&s) == secp256k1_scalar_is_high(&neg)) == secp256k1_scalar_is_zero(&s)); - secp256k1_num_t negnum2; secp256k1_scalar_get_num(&negnum2, &neg); /* Negating a scalar should be equal to (order - n) mod order on the number. */ CHECK(secp256k1_num_eq(&negnum, &negnum2)); @@ -415,17 +433,17 @@ void scalar_test(void) { { /* Test secp256k1_scalar_mul_shift_var. */ secp256k1_scalar_t r; + secp256k1_num_t one; + secp256k1_num_t rnum; + secp256k1_num_t rnum2; + unsigned char cone[1] = {0x01}; unsigned int shift = 256 + (secp256k1_rand32() % 257); secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift); - secp256k1_num_t rnum; secp256k1_num_mul(&rnum, &s1num, &s2num); secp256k1_num_shift(&rnum, shift - 1); - secp256k1_num_t one; - unsigned char cone[1] = {0x01}; secp256k1_num_set_bin(&one, cone, 1); secp256k1_num_add(&rnum, &rnum, &one); secp256k1_num_shift(&rnum, 1); - secp256k1_num_t rnum2; secp256k1_scalar_get_num(&rnum2, &r); CHECK(secp256k1_num_eq(&rnum, &rnum2)); } @@ -435,11 +453,13 @@ void scalar_test(void) { /* Test that scalar inverses are equal to the inverse of their number modulo the order. */ if (!secp256k1_scalar_is_zero(&s)) { secp256k1_scalar_t inv; - secp256k1_scalar_inverse(&inv, &s); #ifndef USE_NUM_NONE secp256k1_num_t invnum; - secp256k1_num_mod_inverse(&invnum, &snum, &order); secp256k1_num_t invnum2; +#endif + secp256k1_scalar_inverse(&inv, &s); +#ifndef USE_NUM_NONE + secp256k1_num_mod_inverse(&invnum, &snum, &order); secp256k1_scalar_get_num(&invnum2, &inv); CHECK(secp256k1_num_eq(&invnum, &invnum2)); #endif @@ -461,15 +481,18 @@ void scalar_test(void) { } { + secp256k1_scalar_t r1, r2; + secp256k1_scalar_t b; + int i; /* Test add_bit. */ int bit = secp256k1_rand32() % 256; - secp256k1_scalar_t b; secp256k1_scalar_set_int(&b, 1); CHECK(secp256k1_scalar_is_one(&b)); - for (int i = 0; i < bit; i++) { + for (i = 0; i < bit; i++) { secp256k1_scalar_add(&b, &b, &b); } - secp256k1_scalar_t r1 = s1, r2 = s1; + r1 = s1; + r2 = s1; if (!secp256k1_scalar_add(&r1, &r1, &b)) { /* No overflow happened. */ secp256k1_scalar_add_bit(&r2, bit); @@ -551,7 +574,8 @@ void scalar_test(void) { } void run_scalar_tests(void) { - for (int i = 0; i < 128 * count; i++) { + int i; + for (i = 0; i < 128 * count; i++) { scalar_test(); } @@ -571,11 +595,11 @@ void run_scalar_tests(void) { { /* A scalar with value of the curve order should be 0. */ secp256k1_num_t order; - secp256k1_scalar_order_get_num(&order); - unsigned char bin[32]; - secp256k1_num_get_bin(bin, 32, &order); secp256k1_scalar_t zero; + unsigned char bin[32]; int overflow = 0; + secp256k1_scalar_order_get_num(&order); + secp256k1_num_get_bin(bin, 32, &order); secp256k1_scalar_set_b32(&zero, bin, &overflow); CHECK(overflow == 1); CHECK(secp256k1_scalar_is_zero(&zero)); @@ -608,39 +632,67 @@ void random_fe_non_zero(secp256k1_fe_t *nz) { } void random_fe_non_square(secp256k1_fe_t *ns) { - random_fe_non_zero(ns); secp256k1_fe_t r; + random_fe_non_zero(ns); if (secp256k1_fe_sqrt_var(&r, ns)) { secp256k1_fe_negate(ns, ns, 1); } } int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { - secp256k1_fe_t an = *a; secp256k1_fe_normalize_weak(&an); - secp256k1_fe_t bn = *b; secp256k1_fe_normalize_var(&bn); + secp256k1_fe_t an = *a; + secp256k1_fe_t bn = *b; + secp256k1_fe_normalize_weak(&an); + secp256k1_fe_normalize_var(&bn); return secp256k1_fe_equal_var(&an, &bn); } int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) { - secp256k1_fe_t x; secp256k1_fe_mul(&x, a, ai); - secp256k1_fe_t one; secp256k1_fe_set_int(&one, 1); + secp256k1_fe_t x; + secp256k1_fe_t one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_fe_mul(&x, a, ai); return check_fe_equal(&x, &one); } -void run_field_misc(void) { - const unsigned char f32_5[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, +void run_field_convert(void) { + static const unsigned char b32[32] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40 }; + static const secp256k1_fe_storage_t fes = SECP256K1_FE_STORAGE_CONST( + 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL, + 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL + ); + static const secp256k1_fe_t fe = SECP256K1_FE_CONST( + 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL, + 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL + ); + secp256k1_fe_t fe2; + unsigned char b322[32]; + secp256k1_fe_storage_t fes2; + /* Check conversions to fe. */ + CHECK(secp256k1_fe_set_b32(&fe2, b32)); + CHECK(secp256k1_fe_equal_var(&fe, &fe2)); + secp256k1_fe_from_storage(&fe2, &fes); + CHECK(secp256k1_fe_equal_var(&fe, &fe2)); + /* Check conversion from fe. */ + secp256k1_fe_get_b32(b322, &fe); + CHECK(memcmp(b322, b32, 32) == 0); + secp256k1_fe_to_storage(&fes2, &fe); + CHECK(memcmp(&fes2, &fes, sizeof(fes)) == 0); +} + +void run_field_misc(void) { secp256k1_fe_t x; secp256k1_fe_t y; secp256k1_fe_t z; secp256k1_fe_t q; - secp256k1_fe_t fe5; - CHECK(secp256k1_fe_set_b32(&fe5, f32_5)); - for (int i=0; i<5*count; i++) { + secp256k1_fe_t fe5 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 5); + int i; + for (i = 0; i < 5*count; i++) { + secp256k1_fe_storage_t xs, ys, zs; random_fe(&x); random_fe_non_zero(&y); /* Test the fe equality and comparison operations. */ @@ -649,12 +701,17 @@ void run_field_misc(void) { z = x; secp256k1_fe_add(&z,&y); secp256k1_fe_normalize(&z); - /* Test the conditional move. */ - secp256k1_fe_cmov(&z, &x, 0); - CHECK(secp256k1_fe_equal_var(&x, &z) == 0); - CHECK(secp256k1_fe_cmp_var(&x, &z) != 0); - secp256k1_fe_cmov(&y, &x, 1); - CHECK(secp256k1_fe_equal_var(&x, &y)); + /* Test storage conversion and conditional moves. */ + secp256k1_fe_to_storage(&xs, &x); + secp256k1_fe_to_storage(&ys, &y); + secp256k1_fe_to_storage(&zs, &z); + secp256k1_fe_storage_cmov(&zs, &xs, 0); + CHECK(memcmp(&xs, &zs, sizeof(xs)) != 0); + secp256k1_fe_storage_cmov(&ys, &xs, 1); + CHECK(memcmp(&xs, &ys, sizeof(xs)) == 0); + secp256k1_fe_from_storage(&x, &xs); + secp256k1_fe_from_storage(&y, &ys); + secp256k1_fe_from_storage(&z, &zs); /* Test that mul_int, mul, and add agree. */ secp256k1_fe_add(&y, &x); secp256k1_fe_add(&y, &x); @@ -678,7 +735,8 @@ void run_field_misc(void) { void run_field_inv(void) { secp256k1_fe_t x, xi, xii; - for (int i=0; i<10*count; i++) { + int i; + for (i = 0; i < 10*count; i++) { random_fe_non_zero(&x); secp256k1_fe_inv(&xi, &x); CHECK(check_fe_inverse(&x, &xi)); @@ -689,7 +747,8 @@ void run_field_inv(void) { void run_field_inv_var(void) { secp256k1_fe_t x, xi, xii; - for (int i=0; i<10*count; i++) { + int i; + for (i = 0; i < 10*count; i++) { random_fe_non_zero(&x); secp256k1_fe_inv_var(&xi, &x); CHECK(check_fe_inverse(&x, &xi)); @@ -700,17 +759,19 @@ void run_field_inv_var(void) { void run_field_inv_all_var(void) { secp256k1_fe_t x[16], xi[16], xii[16]; + int i; /* Check it's safe to call for 0 elements */ secp256k1_fe_inv_all_var(0, xi, x); - for (int i=0; iinfinity == b->infinity); if (a->infinity) return; /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */ - secp256k1_fe_t z2s; secp256k1_fe_sqr(&z2s, &b->z); - secp256k1_fe_t u1, u2, s1, s2; secp256k1_fe_mul(&u1, &a->x, &z2s); u2 = b->x; secp256k1_fe_normalize_weak(&u2); secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z); @@ -803,6 +867,7 @@ void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) { } void test_ge(void) { + int i, i1; int runs = 4; /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4). * The second in each pair of identical points uses a random Z coordinate in the Jacobian form. @@ -814,7 +879,8 @@ void test_ge(void) { secp256k1_gej_set_infinity(&gej[0]); secp256k1_ge_clear(&ge[0]); secp256k1_ge_set_gej_var(&ge[0], &gej[0]); - for (int i = 0; i < runs; i++) { + for (i = 0; i < runs; i++) { + int j; secp256k1_ge_t g; random_group_element_test(&g); ge[1 + 4 * i] = g; @@ -825,7 +891,7 @@ void test_ge(void) { random_group_element_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]); secp256k1_gej_set_ge(&gej[3 + 4 * i], &ge[3 + 4 * i]); random_group_element_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]); - for (int j = 0; j < 4; j++) { + for (j = 0; j < 4; j++) { random_field_element_magnitude(&ge[1 + j + 4 * i].x); random_field_element_magnitude(&ge[1 + j + 4 * i].y); random_field_element_magnitude(&gej[1 + j + 4 * i].x); @@ -834,8 +900,9 @@ void test_ge(void) { } } - for (int i1 = 0; i1 < 1 + 4 * runs; i1++) { - for (int i2 = 0; i2 < 1 + 4 * runs; i2++) { + for (i1 = 0; i1 < 1 + 4 * runs; i1++) { + int i2; + for (i2 = 0; i2 < 1 + 4 * runs; i2++) { /* Compute reference result using gej + gej (var). */ secp256k1_gej_t refj, resj; secp256k1_ge_t ref; @@ -883,11 +950,12 @@ void test_ge(void) { /* Test adding all points together in random order equals infinity. */ { + secp256k1_gej_t sum = SECP256K1_GEJ_CONST_INFINITY; secp256k1_gej_t *gej_shuffled = malloc((4 * runs + 1) * sizeof(secp256k1_gej_t)); - for (int i = 0; i < 4 * runs + 1; i++) { + for (i = 0; i < 4 * runs + 1; i++) { gej_shuffled[i] = gej[i]; } - for (int i = 0; i < 4 * runs + 1; i++) { + for (i = 0; i < 4 * runs + 1; i++) { int swap = i + secp256k1_rand32() % (4 * runs + 1 - i); if (swap != i) { secp256k1_gej_t t = gej_shuffled[i]; @@ -895,9 +963,7 @@ void test_ge(void) { gej_shuffled[swap] = t; } } - secp256k1_gej_t sum; - secp256k1_gej_set_infinity(&sum); - for (int i = 0; i < 4 * runs + 1; i++) { + for (i = 0; i < 4 * runs + 1; i++) { secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i]); } CHECK(secp256k1_gej_is_infinity(&sum)); @@ -908,7 +974,7 @@ void test_ge(void) { { secp256k1_ge_t *ge_set_all = malloc((4 * runs + 1) * sizeof(secp256k1_ge_t)); secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej); - for (int i = 0; i < 4 * runs + 1; i++) { + for (i = 0; i < 4 * runs + 1; i++) { ge_equals_gej(&ge_set_all[i], &gej[i]); } free(ge_set_all); @@ -919,7 +985,8 @@ void test_ge(void) { } void run_ge(void) { - for (int i = 0; i < count * 32; i++) { + int i; + for (i = 0; i < count * 32; i++) { test_ge(); } } @@ -928,41 +995,35 @@ void run_ge(void) { void run_ecmult_chain(void) { /* random starting point A (on the curve) */ - secp256k1_fe_t ax; VERIFY_CHECK(secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64)); - secp256k1_fe_t ay; VERIFY_CHECK(secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64)); - secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay); + secp256k1_gej_t a = SECP256K1_GEJ_CONST( + 0x8b30bbe9, 0xae2a9906, 0x96b22f67, 0x0709dff3, + 0x727fd8bc, 0x04d3362c, 0x6c7bf458, 0xe2846004, + 0xa357ae91, 0x5c4a6528, 0x1309edf2, 0x0504740f, + 0x0eb33439, 0x90216b4f, 0x81063cb6, 0x5f2f7e0f + ); /* two random initial factors xn and gn */ - static const unsigned char xni[32] = { - 0x84, 0xcc, 0x54, 0x52, 0xf7, 0xfd, 0xe1, 0xed, - 0xb4, 0xd3, 0x8a, 0x8c, 0xe9, 0xb1, 0xb8, 0x4c, - 0xce, 0xf3, 0x1f, 0x14, 0x6e, 0x56, 0x9b, 0xe9, - 0x70, 0x5d, 0x35, 0x7a, 0x42, 0x98, 0x54, 0x07 - }; - secp256k1_scalar_t xn; - secp256k1_scalar_set_b32(&xn, xni, NULL); - static const unsigned char gni[32] = { - 0xa1, 0xe5, 0x8d, 0x22, 0x55, 0x3d, 0xcd, 0x42, - 0xb2, 0x39, 0x80, 0x62, 0x5d, 0x4c, 0x57, 0xa9, - 0x6e, 0x93, 0x23, 0xd4, 0x2b, 0x31, 0x52, 0xe5, - 0xca, 0x2c, 0x39, 0x90, 0xed, 0xc7, 0xc9, 0xde - }; - secp256k1_scalar_t gn; - secp256k1_scalar_set_b32(&gn, gni, NULL); + secp256k1_scalar_t xn = SECP256K1_SCALAR_CONST( + 0x84cc5452, 0xf7fde1ed, 0xb4d38a8c, 0xe9b1b84c, + 0xcef31f14, 0x6e569be9, 0x705d357a, 0x42985407 + ); + secp256k1_scalar_t gn = SECP256K1_SCALAR_CONST( + 0xa1e58d22, 0x553dcd42, 0xb2398062, 0x5d4c57a9, + 0x6e9323d4, 0x2b3152e5, 0xca2c3990, 0xedc7c9de + ); /* two small multipliers to be applied to xn and gn in every iteration: */ - static const unsigned char xfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x13,0x37}; - secp256k1_scalar_t xf; - secp256k1_scalar_set_b32(&xf, xfi, NULL); - static const unsigned char gfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x71,0x13}; - secp256k1_scalar_t gf; - secp256k1_scalar_set_b32(&gf, gfi, NULL); + static const secp256k1_scalar_t xf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x1337); + static const secp256k1_scalar_t gf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x7113); /* accumulators with the resulting coefficients to A and G */ - secp256k1_scalar_t ae; - secp256k1_scalar_set_int(&ae, 1); - secp256k1_scalar_t ge; - secp256k1_scalar_set_int(&ge, 0); - /* the point being computed */ + secp256k1_scalar_t ae = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_scalar_t ge = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + /* actual points */ secp256k1_gej_t x = a; - for (int i=0; i<200*count; i++) { + secp256k1_gej_t x2; + int i; + + /* the point being computed */ + x = a; + for (i = 0; i < 200*count; i++) { /* in each iteration, compute X = xn*X + gn*G; */ secp256k1_ecmult(&x, &x, &xn, &gn); /* also compute ae and ge: the actual accumulated factors for A and G */ @@ -976,78 +1037,84 @@ void run_ecmult_chain(void) { /* verify */ if (i == 19999) { - char res[132]; int resl = 132; - secp256k1_gej_get_hex(res, &resl, &x); - CHECK(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0); + /* expected result after 19999 iterations */ + secp256k1_gej_t rp = SECP256K1_GEJ_CONST( + 0xD6E96687, 0xF9B10D09, 0x2A6F3543, 0x9D86CEBE, + 0xA4535D0D, 0x409F5358, 0x6440BD74, 0xB933E830, + 0xB95CBCA2, 0xC77DA786, 0x539BE8FD, 0x53354D2D, + 0x3B4F566A, 0xE6580454, 0x07ED6015, 0xEE1B2A88 + ); + + secp256k1_gej_neg(&rp, &rp); + secp256k1_gej_add_var(&rp, &rp, &x); + CHECK(secp256k1_gej_is_infinity(&rp)); } } /* redo the computation, but directly with the resulting ae and ge coefficients: */ - secp256k1_gej_t x2; secp256k1_ecmult(&x2, &a, &ae, &ge); - char res[132]; int resl = 132; - char res2[132]; int resl2 = 132; - secp256k1_gej_get_hex(res, &resl, &x); - secp256k1_gej_get_hex(res2, &resl2, &x2); - CHECK(strcmp(res, res2) == 0); - CHECK(strlen(res) == 131); + secp256k1_ecmult(&x2, &a, &ae, &ge); + secp256k1_gej_neg(&x2, &x2); + secp256k1_gej_add_var(&x2, &x2, &x); + CHECK(secp256k1_gej_is_infinity(&x2)); } void test_point_times_order(const secp256k1_gej_t *point) { - unsigned char pub[65]; /* X * (point + G) + (order-X) * (pointer + G) = 0 */ secp256k1_scalar_t x; - random_scalar_order_test(&x); secp256k1_scalar_t nx; - secp256k1_scalar_negate(&nx, &x); secp256k1_gej_t res1, res2; + secp256k1_ge_t res3; + unsigned char pub[65]; + int psize = 65; + random_scalar_order_test(&x); + secp256k1_scalar_negate(&nx, &x); secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */ secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ secp256k1_gej_add_var(&res1, &res1, &res2); CHECK(secp256k1_gej_is_infinity(&res1)); CHECK(secp256k1_gej_is_valid_var(&res1) == 0); - secp256k1_ge_t res3; secp256k1_ge_set_gej(&res3, &res1); CHECK(secp256k1_ge_is_infinity(&res3)); CHECK(secp256k1_ge_is_valid_var(&res3) == 0); - int psize = 65; CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0); psize = 65; CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0); } void run_point_times_order(void) { - secp256k1_fe_t x; VERIFY_CHECK(secp256k1_fe_set_hex(&x, "02", 2)); - for (int i=0; i<500; i++) { + int i; + secp256k1_fe_t x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2); + static const secp256k1_fe_t xr = SECP256K1_FE_CONST( + 0x7603CB59, 0xB0EF6C63, 0xFE608479, 0x2A0C378C, + 0xDB3233A8, 0x0F8A9A09, 0xA877DEAD, 0x31B38C45 + ); + for (i = 0; i < 500; i++) { secp256k1_ge_t p; if (secp256k1_ge_set_xo_var(&p, &x, 1)) { - CHECK(secp256k1_ge_is_valid_var(&p)); secp256k1_gej_t j; + CHECK(secp256k1_ge_is_valid_var(&p)); secp256k1_gej_set_ge(&j, &p); CHECK(secp256k1_gej_is_valid_var(&j)); test_point_times_order(&j); } secp256k1_fe_sqr(&x, &x); } - char c[65]; - int cl = 1; - c[1] = 123; - secp256k1_fe_get_hex(c, &cl, &x); /* Check that fe_get_hex handles a too short input. */ - CHECK(c[1] == 123); - cl = 65; - secp256k1_fe_get_hex(c, &cl, &x); - CHECK(strcmp(c, "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45") == 0); + secp256k1_fe_normalize_var(&x); + CHECK(secp256k1_fe_equal_var(&x, &xr)); } void test_wnaf(const secp256k1_scalar_t *number, int w) { secp256k1_scalar_t x, two, t; + int wnaf[256]; + int zeroes = -1; + int i; + int bits; secp256k1_scalar_set_int(&x, 0); secp256k1_scalar_set_int(&two, 2); - int wnaf[256]; - int bits = secp256k1_ecmult_wnaf(wnaf, number, w); + bits = secp256k1_ecmult_wnaf(wnaf, number, w); CHECK(bits <= 256); - int zeroes = -1; - for (int i=bits-1; i>=0; i--) { - secp256k1_scalar_mul(&x, &x, &two); + for (i = bits-1; i >= 0; i--) { int v = wnaf[i]; + secp256k1_scalar_mul(&x, &x, &two); if (v) { CHECK(zeroes == -1 || zeroes >= w-1); /* check that distance between non-zero elements is at least w-1 */ zeroes=0; @@ -1070,8 +1137,9 @@ void test_wnaf(const secp256k1_scalar_t *number, int w) { } void run_wnaf(void) { + int i; secp256k1_scalar_t n; - for (int i=0; i= 0 && recid < 4); CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); - secp256k1_scalar_t one; secp256k1_scalar_set_int(&one, 1); secp256k1_scalar_add(&msg, &msg, &one); CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); } void run_ecdsa_sign_verify(void) { - for (int i=0; i<10*count; i++) { + int i; + for (i = 0; i < 10*count; i++) { test_ecdsa_sign_verify(); } } @@ -1149,9 +1220,32 @@ static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char return nonce_function_rfc6979(nonce32, msg32, key32, counter - 5, data); } +int is_empty_compact_signature(const unsigned char *sig64) { + static const unsigned char res[64] = {0}; + return memcmp(sig64, res, 64) == 0; +} + void test_ecdsa_end_to_end(void) { + unsigned char extra[32] = {0x00}; unsigned char privkey[32]; unsigned char message[32]; + unsigned char privkey2[32]; + unsigned char csignature[64]; + unsigned char signature[72]; + unsigned char signature2[72]; + unsigned char signature3[72]; + unsigned char signature4[72]; + unsigned char pubkey[65]; + unsigned char recpubkey[65]; + unsigned char seckey[300]; + int signaturelen = 72; + int signaturelen2 = 72; + int signaturelen3 = 72; + int signaturelen4 = 72; + int recid = 0; + int recpubkeylen = 0; + int pubkeylen = 65; + int seckeylen = 300; /* Generate a random key and message. */ { @@ -1164,7 +1258,6 @@ void test_ecdsa_end_to_end(void) { /* Construct and verify corresponding public key. */ CHECK(secp256k1_ec_seckey_verify(privkey) == 1); - unsigned char pubkey[65]; int pubkeylen = 65; CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1); if (secp256k1_rand32() & 1) { CHECK(secp256k1_ec_pubkey_decompress(pubkey, &pubkeylen)); @@ -1172,52 +1265,73 @@ void test_ecdsa_end_to_end(void) { CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen)); /* Verify private key import and export. */ - unsigned char seckey[300]; int seckeylen = 300; CHECK(secp256k1_ec_privkey_export(privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1); - unsigned char privkey2[32]; CHECK(secp256k1_ec_privkey_import(privkey2, seckey, seckeylen) == 1); CHECK(memcmp(privkey, privkey2, 32) == 0); /* Optionally tweak the keys using addition. */ if (secp256k1_rand32() % 3 == 0) { + int ret1; + int ret2; unsigned char rnd[32]; + unsigned char pubkey2[65]; + int pubkeylen2 = 65; secp256k1_rand256_test(rnd); - int ret1 = secp256k1_ec_privkey_tweak_add(privkey, rnd); - int ret2 = secp256k1_ec_pubkey_tweak_add(pubkey, pubkeylen, rnd); + ret1 = secp256k1_ec_privkey_tweak_add(privkey, rnd); + ret2 = secp256k1_ec_pubkey_tweak_add(pubkey, pubkeylen, rnd); CHECK(ret1 == ret2); if (ret1 == 0) return; - unsigned char pubkey2[65]; int pubkeylen2 = 65; CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); } /* Optionally tweak the keys using multiplication. */ if (secp256k1_rand32() % 3 == 0) { + int ret1; + int ret2; unsigned char rnd[32]; + unsigned char pubkey2[65]; + int pubkeylen2 = 65; secp256k1_rand256_test(rnd); - int ret1 = secp256k1_ec_privkey_tweak_mul(privkey, rnd); - int ret2 = secp256k1_ec_pubkey_tweak_mul(pubkey, pubkeylen, rnd); + ret1 = secp256k1_ec_privkey_tweak_mul(privkey, rnd); + ret2 = secp256k1_ec_pubkey_tweak_mul(pubkey, pubkeylen, rnd); CHECK(ret1 == ret2); if (ret1 == 0) return; - unsigned char pubkey2[65]; int pubkeylen2 = 65; CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); } /* Sign. */ - unsigned char signature[72]; int signaturelen = 72; CHECK(secp256k1_ecdsa_sign(message, signature, &signaturelen, privkey, NULL, NULL) == 1); + CHECK(signaturelen > 0); + CHECK(secp256k1_ecdsa_sign(message, signature2, &signaturelen2, privkey, NULL, extra) == 1); + CHECK(signaturelen2 > 0); + extra[31] = 1; + CHECK(secp256k1_ecdsa_sign(message, signature3, &signaturelen3, privkey, NULL, extra) == 1); + CHECK(signaturelen3 > 0); + extra[31] = 0; + extra[0] = 1; + CHECK(secp256k1_ecdsa_sign(message, signature4, &signaturelen4, privkey, NULL, extra) == 1); + CHECK(signaturelen3 > 0); + CHECK((signaturelen != signaturelen2) || (memcmp(signature, signature2, signaturelen) != 0)); + CHECK((signaturelen != signaturelen3) || (memcmp(signature, signature3, signaturelen) != 0)); + CHECK((signaturelen3 != signaturelen2) || (memcmp(signature3, signature2, signaturelen3) != 0)); + CHECK((signaturelen4 != signaturelen3) || (memcmp(signature4, signature3, signaturelen4) != 0)); + CHECK((signaturelen4 != signaturelen2) || (memcmp(signature4, signature2, signaturelen4) != 0)); + CHECK((signaturelen4 != signaturelen) || (memcmp(signature4, signature, signaturelen4) != 0)); /* Verify. */ CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) == 1); + CHECK(secp256k1_ecdsa_verify(message, signature2, signaturelen2, pubkey, pubkeylen) == 1); + CHECK(secp256k1_ecdsa_verify(message, signature3, signaturelen3, pubkey, pubkeylen) == 1); + CHECK(secp256k1_ecdsa_verify(message, signature4, signaturelen4, pubkey, pubkeylen) == 1); /* Destroy signature and verify again. */ signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255); CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) != 1); /* Compact sign. */ - unsigned char csignature[64]; int recid = 0; CHECK(secp256k1_ecdsa_sign_compact(message, csignature, privkey, NULL, NULL, &recid) == 1); + CHECK(!is_empty_compact_signature(csignature)); /* Recover. */ - unsigned char recpubkey[65]; int recpubkeylen = 0; CHECK(secp256k1_ecdsa_recover_compact(message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1); CHECK(recpubkeylen == pubkeylen); CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0); @@ -1230,6 +1344,8 @@ void test_ecdsa_end_to_end(void) { } void test_random_pubkeys(void) { + secp256k1_ge_t elem; + secp256k1_ge_t elem2; unsigned char in[65]; /* Generate some randomly sized pubkeys. */ uint32_t r = secp256k1_rand32(); @@ -1247,8 +1363,6 @@ void test_random_pubkeys(void) { r>>=11; if (len > 1) secp256k1_rand256(&in[1]); if (len > 33) secp256k1_rand256(&in[33]); - secp256k1_ge_t elem; - secp256k1_ge_t elem2; if (secp256k1_eckey_pubkey_parse(&elem, in, len)) { unsigned char out[65]; unsigned char firstb; @@ -1282,13 +1396,15 @@ void test_random_pubkeys(void) { } void run_random_pubkeys(void) { - for (int i=0; i<10*count; i++) { + int i; + for (i = 0; i < 10*count; i++) { test_random_pubkeys(); } } void run_ecdsa_end_to_end(void) { - for (int i=0; i<64*count; i++) { + int i; + for (i = 0; i < 64*count; i++) { test_ecdsa_end_to_end(); } } @@ -1314,12 +1430,8 @@ void test_ecdsa_edge_cases(void) { 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57 }; unsigned char pubkey[65]; + int t; int pubkeylen = 65; - CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 0)); - CHECK(secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 1)); - CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 2)); - CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 3)); - /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */ const unsigned char sigb64[64] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1333,7 +1445,16 @@ void test_ecdsa_edge_cases(void) { }; unsigned char pubkeyb[33]; int pubkeyblen = 33; - for (int recid = 0; recid < 4; recid++) { + int recid; + + CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 0)); + CHECK(secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 1)); + CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 2)); + CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 3)); + + for (recid = 0; recid < 4; recid++) { + int i; + int recid2; /* (4,4) encoded in DER. */ unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04}; unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01}; @@ -1376,7 +1497,7 @@ void test_ecdsa_edge_cases(void) { }; CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid)); CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1); - for (int recid2 = 0; recid2 < 4; recid2++) { + for (recid2 = 0; recid2 < 4; recid2++) { unsigned char pubkey2b[33]; int pubkey2blen = 33; CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2)); @@ -1402,10 +1523,11 @@ void test_ecdsa_edge_cases(void) { sigbder[7]--; CHECK(secp256k1_ecdsa_verify(msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2); CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2); - for(int i = 0; i<8; i++) { + for(i = 0; i < 8; i++) { + int c; unsigned char orig = sigbder[i]; /*Try every single-byte change.*/ - for (int c=0; c<256; c++) { + for (c = 0; c < 256; c++) { if (c == orig ) continue; sigbder[i] = c; CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == @@ -1417,16 +1539,17 @@ void test_ecdsa_edge_cases(void) { /* Test the case where ECDSA recomputes a point that is infinity. */ { + secp256k1_gej_t keyj; + secp256k1_ge_t key; + secp256k1_scalar_t msg; secp256k1_ecdsa_sig_t sig; secp256k1_scalar_set_int(&sig.s, 1); secp256k1_scalar_negate(&sig.s, &sig.s); secp256k1_scalar_inverse(&sig.s, &sig.s); secp256k1_scalar_set_int(&sig.r, 1); - secp256k1_gej_t keyj; secp256k1_ecmult_gen(&keyj, &sig.r); - secp256k1_ge_t key; secp256k1_ge_set_gej(&key, &keyj); - secp256k1_scalar_t msg = sig.s; + msg = sig.s; CHECK(secp256k1_ecdsa_sig_verify(&sig, &key, &msg) == 0); } @@ -1489,69 +1612,97 @@ void test_ecdsa_edge_cases(void) { unsigned char sig[72]; int siglen = 72; CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0); + CHECK(siglen == 0); CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0); + CHECK(siglen == 0); msg[31] = 0xaa; siglen = 72; CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1); + CHECK(siglen > 0); CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1); + CHECK(siglen > 0); siglen = 10; CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1); + CHECK(siglen == 0); } /* Nonce function corner cases. */ - { + for (t = 0; t < 2; t++) { + static const unsigned char zero[32] = {0x00}; + int i; unsigned char key[32]; unsigned char msg[32]; unsigned char sig[72]; - memset(key, 0, 32); - memset(msg, 0, 32); - key[31] = 1; - msg[31] = 1; - int siglen = 72; - int recid; - /* Nonce function failure results in signature failure. */ - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_fail, NULL) == 0); - CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_fail, NULL, &recid) == 0); - /* The retry loop successfully makes its way to the first good value. */ unsigned char sig2[72]; + secp256k1_ecdsa_sig_t s[512]; + int siglen = 72; int siglen2 = 72; - siglen = 72; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_retry, NULL) == 1); - CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, nonce_function_rfc6979, NULL) == 1); - CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); int recid2; - CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_retry, NULL, &recid) == 1); - CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, nonce_function_rfc6979, NULL, &recid2) == 1); + const unsigned char *extra; + extra = t == 0 ? NULL : zero; + memset(msg, 0, 32); + msg[31] = 1; + /* High key results in signature failure. */ + memset(key, 0xFF, 32); + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, extra) == 0); + CHECK(siglen == 0); + /* Zero key results in signature failure. */ + memset(key, 0, 32); + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, extra) == 0); + CHECK(siglen == 0); + /* Nonce function failure results in signature failure. */ + key[31] = 1; + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_fail, extra) == 0); + CHECK(siglen == 0); + CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_fail, extra, &recid) == 0); + CHECK(is_empty_compact_signature(sig)); + /* The retry loop successfully makes its way to the first good value. */ + siglen = 72; + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_retry, extra) == 1); + CHECK(siglen > 0); + CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, nonce_function_rfc6979, extra) == 1); + CHECK(siglen > 0); + CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); + CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_retry, extra, &recid) == 1); + CHECK(!is_empty_compact_signature(sig)); + CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, nonce_function_rfc6979, extra, &recid2) == 1); + CHECK(!is_empty_compact_signature(sig2)); CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); /* The default nonce function is determinstic. */ siglen = 72; siglen2 = 72; - CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, extra) == 1); + CHECK(siglen > 0); + CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, extra) == 1); + CHECK(siglen2 > 0); CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); - CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, NULL, NULL, &recid) == 1); - CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, NULL, NULL, &recid2) == 1); + CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, NULL, extra, &recid) == 1); + CHECK(!is_empty_compact_signature(sig)); + CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, NULL, extra, &recid2) == 1); + CHECK(!is_empty_compact_signature(sig)); CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); /* The default nonce function changes output with different messages. */ - secp256k1_ecdsa_sig_t s[512]; - for(int i=0; i<256; i++) { + for(i = 0; i < 256; i++) { + int j; siglen2 = 72; msg[0] = i; - CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, extra) == 1); + CHECK(!is_empty_compact_signature(sig)); CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2)); - for (int j=0; j 1) { count = strtol(argv[1], NULL, 0); } /* find random seed */ - uint64_t seed; if (argc > 2) { - seed = strtoull(argv[2], NULL, 0); + int pos = 0; + const char* ch = argv[2]; + while (pos < 16 && ch[0] != 0 && ch[1] != 0) { + unsigned short sh; + if (sscanf(ch, "%2hx", &sh)) { + seed16[pos] = sh; + } else { + break; + } + ch += 2; + pos++; + } } else { FILE *frand = fopen("/dev/urandom", "r"); - if (!frand || !fread(&seed, sizeof(seed), 1, frand)) { - seed = time(NULL) * 1337; + if (!frand || !fread(&seed16, sizeof(seed16), 1, frand)) { + uint64_t t = time(NULL) * (uint64_t)1337; + seed16[0] ^= t; + seed16[1] ^= t >> 8; + seed16[2] ^= t >> 16; + seed16[3] ^= t >> 24; + seed16[4] ^= t >> 32; + seed16[5] ^= t >> 40; + seed16[6] ^= t >> 48; + seed16[7] ^= t >> 56; } fclose(frand); } - secp256k1_rand_seed(seed); + secp256k1_rand_seed(seed16); printf("test count = %i\n", count); - printf("random seed = %llu\n", (unsigned long long)seed); + printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); /* initialize */ secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY); @@ -1657,12 +1830,6 @@ int main(int argc, char **argv) { /* initializing a second time shouldn't cause any harm or memory leaks. */ secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY); - /* Likewise, re-running the internal init functions should be harmless. */ - secp256k1_fe_start(); - secp256k1_ge_start(); - secp256k1_scalar_start(); - secp256k1_ecdsa_start(); - run_sha256_tests(); run_hmac_sha256_tests(); run_rfc6979_hmac_sha256_tests(); @@ -1680,6 +1847,7 @@ int main(int argc, char **argv) { run_field_inv_var(); run_field_inv_all_var(); run_field_misc(); + run_field_convert(); run_sqr(); run_sqrt(); @@ -1700,18 +1868,13 @@ int main(int argc, char **argv) { run_ecdsa_openssl(); #endif - printf("random run = %llu\n", (unsigned long long)secp256k1_rand32() + ((unsigned long long)secp256k1_rand32() << 32)); + secp256k1_rand256(run32); + printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); /* shutdown */ secp256k1_stop(); /* shutting down twice shouldn't cause any double frees. */ secp256k1_stop(); - - /* Same for the internal shutdown functions. */ - secp256k1_fe_stop(); - secp256k1_ge_stop(); - secp256k1_scalar_stop(); - secp256k1_ecdsa_stop(); return 0; } diff --git a/src/util.h b/src/util.h index c3a8f3a42bf..ae98639f7ca 100644 --- a/src/util.h +++ b/src/util.h @@ -27,7 +27,7 @@ } while(0) #endif -#ifndef HAVE_BUILTIN_EXPECT +#ifdef HAVE_BUILTIN_EXPECT #define EXPECT(x,c) __builtin_expect((x),(c)) #else #define EXPECT(x,c) (x) @@ -61,7 +61,7 @@ #define VERIFY_CHECK(cond) do { (void)(cond); } while(0) #endif -static inline void *checked_malloc(size_t size) { +static SECP256K1_INLINE void *checked_malloc(size_t size) { void *ret = malloc(size); CHECK(ret != NULL); return ret; @@ -84,4 +84,21 @@ static inline void *checked_malloc(size_t size) { # endif #endif +#if defined(_WIN32) +# define I64FORMAT "I64d" +# define I64uFORMAT "I64u" +#else +# define I64FORMAT "lld" +# define I64uFORMAT "llu" +#endif + +#if defined(HAVE___INT128) +# if defined(__GNUC__) +# define SECP256K1_GNUC_EXT __extension__ +# else +# define SECP256K1_GNUC_EXT +# endif +SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; +#endif + #endif From 437ada3e55df8ae6f801cb2aa2e79ec5bb5f1971 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 27 Mar 2015 15:31:44 -0700 Subject: [PATCH 0352/2337] Switch test case signing to RFC6979 extra entropy Instead of manually tweaking the deterministic nonce post-generation, pass the test case number in as extra entropy to RFC6979. --- src/key.cpp | 18 +++--------- src/key.h | 3 +- src/test/data/script_invalid.json | 46 +++++++++++++++---------------- src/test/data/script_valid.json | 42 ++++++++++++++-------------- 4 files changed, 49 insertions(+), 60 deletions(-) diff --git a/src/key.cpp b/src/key.cpp index 64c9bc71190..e146e47d0df 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -5,6 +5,7 @@ #include "key.h" #include "arith_uint256.h" +#include "crypto/common.h" #include "crypto/hmac_sha512.h" #include "eccryptoverify.h" #include "pubkey.h" @@ -73,25 +74,14 @@ CPubKey CKey::GetPubKey() const { return result; } -extern "C" -{ -static int secp256k1_nonce_function_test_case(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int attempt, const void *data) -{ - const uint32_t *test_case = static_cast(data); - uint256 nonce; - secp256k1_nonce_function_rfc6979(nonce.begin(), msg32, key32, attempt, NULL); - nonce = ArithToUint256(UintToArith256(nonce) + *test_case); - memcpy(nonce32, nonce.begin(), 32); - return 1; -} -} - bool CKey::Sign(const uint256 &hash, std::vector& vchSig, uint32_t test_case) const { if (!fValid) return false; vchSig.resize(72); int nSigLen = 72; - int ret = secp256k1_ecdsa_sign(hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), test_case == 0 ? secp256k1_nonce_function_rfc6979 : secp256k1_nonce_function_test_case, test_case == 0 ? NULL : &test_case); + unsigned char extra_entropy[32] = {0}; + WriteLE32(extra_entropy, test_case); + int ret = secp256k1_ecdsa_sign(hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL); assert(ret); vchSig.resize(nSigLen); return true; diff --git a/src/key.h b/src/key.h index 1f1d1428874..104a8f5c720 100644 --- a/src/key.h +++ b/src/key.h @@ -124,8 +124,7 @@ public: /** * Create a DER-serialized signature. - * The test_case parameter tweaks the deterministic nonce, and is only for - * testing. It should be zero for normal use. + * The test_case parameter tweaks the deterministic nonce. */ bool Sign(const uint256& hash, std::vector& vchSig, uint32_t test_case = 0) const; diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 3c52547a64e..271bc70f735 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -522,13 +522,13 @@ ["Automatically generated test cases"], [ - "0x47 0x3044022053205076a7bb12d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", + "0x47 0x304402200a5c6163f07b8c3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", "P2PK, bad sig" ], [ - "0x47 0x30440220151ea78fa148b59f399b23731b634645ebc142f299ee9838d46fb78cf7e0bc0102200d62327dcd54ac6bcfb1516b035b1bf8eaea438c52c62d3450d1f3a8f030e0de01 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640", + "0x47 0x3044022034bb0494b50b8ef130e2185bb220265b9284ef5b4b8a8da4d8415df489c83b5102206259a26d9cc0a125ac26af6153b17c02956855ebe1467412f066e402f5f05d1201 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640", "DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG", "", "P2PKH, bad pubkey" @@ -540,19 +540,19 @@ "P2PK anyonecanpay marked with normal hashtype" ], [ - "0x47 0x304402202166fcd5e607de452d3c6f15e059505cf21654346592f9650ba906b9e8be88fa022005d976d28eb8de477102feba28807b3ad361e7fa24796d259c9d61452f7c318c01 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", "P2SH", "P2SH(P2PK), bad redeemscript" ], [ - "0x47 0x3044022064cc90ca89ad721384b231653b945579359a24b928ef8539b331172628c9cc6102203e238869ab5dac3fc293db53c12e7dd3079e86cfde9024b689efc7227e4d671001 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", + "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", "P2SH", "P2SH(P2PKH), bad sig" ], [ - "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0", + "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "3-of-3, 2 sigs" @@ -564,13 +564,13 @@ "P2SH(2-of-3), 1 sig" ], [ - "0x47 0x30440220001d6702bfa4f49c3a2542af9b1c2844a2eaac55f86f310f42d26a5dd17d6a8002202cdadbe608c00b50dd951c6ba0877d5b07a970f3e265c18697bc413a0a86f69901", + "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", "P2PK with too much R padding" ], [ - "0x48 0x304502207d2b258e959605e2ea50b46fea1325b7391ffb0c14a5b58ef8ad3851da3644380221007e75136df5f2e38216c4338b31c97e8307102edb97d611e06914e1f8fba68ead01", + "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", "P2PK with too much S padding" @@ -582,19 +582,19 @@ "P2PK with too little R padding" ], [ - "0x47 0x30440220003040725f724b0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01", + "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "DERSIG", "P2PK NOT with bad sig with too much R padding" ], [ - "0x47 0x30440220003040725f724a0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01", + "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "", "P2PK NOT with too much R padding but no DERSIG" ], [ - "0x47 0x30440220003040725f724a0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01", + "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "DERSIG", "P2PK NOT with too much R padding" @@ -648,19 +648,19 @@ "BIP66 example 6, with DERSIG" ], [ - "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x304402200b3d0b0375bb15c14620afa4aa10ae90a0d6a046ce217bc20fe0bc1ced68c1b802204b550acab90ae6d3478057c9ad24f9df743815b799b6449dd7e7f6d3bc6e274c01", + "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "DERSIG", "BIP66 example 7, with DERSIG" ], [ - "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", + "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "", "BIP66 example 8, without DERSIG" ], [ - "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", + "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "DERSIG", "BIP66 example 8, with DERSIG" @@ -678,7 +678,7 @@ "BIP66 example 9, with DERSIG" ], [ - "0 0 0x47 0x30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501", + "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "DERSIG", "BIP66 example 10, with DERSIG" @@ -708,37 +708,37 @@ "P2PK with high S" ], [ - "0x47 0x30440220745d63eb70d45652128b450aa5ca7d9b513439963f261cb1c40a60f0785e7ee402204877785b38945ca9dbec78e1c1d4dd12148cc25c868bd27480023b49ae0f310501", + "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "STRICTENC", "P2PK with hybrid pubkey" ], [ - "0x47 0x30440220606f6f9f6cebc94ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201", + "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "", "P2PK NOT with hybrid pubkey but no STRICTENC" ], [ - "0x47 0x30440220606f6f9f6cebc94ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201", + "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "STRICTENC", "P2PK NOT with hybrid pubkey" ], [ - "0x47 0x30440220606f6f9f6cebc84ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201", + "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "STRICTENC", "P2PK NOT with invalid hybrid pubkey" ], [ - "0 0x47 0x304402203cdcf66792fe97e3955655ede5dad004950e58b369831ffa7743132c507b272c022031fbcfb4a72b3e00217abf2f5557585f1f9891f12827d2f0a2ae2978e7f9f11001", + "0 0x47 0x3044022079c7824d6c868e0e1a273484e28c2654a27d043c8a27f49f52cb72efed0759090220452bbbf7089574fa082095a4fc1b3a16bafcf97a3a34d745fafc922cce66b27201", "1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG", "STRICTENC", "1-of-2 with the first 1 hybrid pubkey" ], [ - "0x47 0x304402201c215cb13e4954e60ce4f6de74941904c771f998de7b1d9627e82a1949fde517022031c2197455f3dbecbb78321201308d7b039424e38d480772d7cd4eb465a083f405", + "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "STRICTENC", "P2PK with undefined hashtype" @@ -750,7 +750,7 @@ "P2PK NOT with invalid sig and undefined hashtype" ], [ - "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", + "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "NULLDUMMY", "3-of-3 with nonzero dummy" @@ -762,7 +762,7 @@ "3-of-3 NOT with invalid sig with nonzero dummy" ], [ - "0 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01 DUP", + "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "SIGPUSHONLY", "2-of-2 with two identical keys and sigs pushed using OP_DUP" @@ -780,7 +780,7 @@ "P2SH(P2PK) with non-push scriptSig" ], [ - "11 0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", + "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "CLEANSTACK,P2SH", "P2PK with unnecessary input" diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 34e2c8d61a7..064dde8464d 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -700,7 +700,7 @@ ["Automatically generated test cases"], [ - "0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", + "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", "P2PK" @@ -718,37 +718,37 @@ "P2PK anyonecanpay" ], [ - "0x47 0x304402202166fcd5e607de452d3c6f15e059505cf21654346592f9650ba906b9e8be88fa022005d976d28eb8de477102feba28807b3ad361e7fa24796d259c9d61452f7c318c01 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", "P2SH", "P2SH(P2PK)" ], [ - "0x47 0x3044022064cc90ca89ad721384b231653b945579359a24b928ef8539b331172628c9cc6102203e238869ab5dac3fc293db53c12e7dd3079e86cfde9024b689efc7227e4d671001 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", + "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", "", "P2SH(P2PKH), bad sig but no VERIFY_P2SH" ], [ - "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", + "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "3-of-3" ], [ - "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0x47 0x304402204511cf05e85c2be07c6c176c5338a08ed3cb34212667f39613340881169986c002207cc48b27aa3691a20706a5773ec9923cadd20fedffd00c24457d85f83f0b51fe01 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", + "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0x47 0x30440220563e5b3b1fc11662a84bc5ea2a32cc3819703254060ba30d639a1aaf2d5068ad0220601c1f47ddc76d93284dd9ed68f7c9974c4a0ea7cbe8a247d6bc3878567a5fca01 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", "P2SH", "P2SH(2-of-3)" ], [ - "0x47 0x30440220001d6702bfa4f49c3a2542af9b1c2844a2eaac55f86f310f42d26a5dd17d6a8002202cdadbe608c00b50dd951c6ba0877d5b07a970f3e265c18697bc413a0a86f69901", + "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", "P2PK with too much R padding but no DERSIG" ], [ - "0x48 0x304502207d2b258e959605e2ea50b46fea1325b7391ffb0c14a5b58ef8ad3851da3644380221007e75136df5f2e38216c4338b31c97e8307102edb97d611e06914e1f8fba68ead01", + "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", "P2PK with too much S padding but no DERSIG" @@ -760,7 +760,7 @@ "P2PK with too little R padding but no DERSIG" ], [ - "0x47 0x30440220003040725f724b0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01", + "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "", "P2PK NOT with bad sig with too much R padding but no DERSIG" @@ -790,25 +790,25 @@ "BIP66 example 6, without DERSIG" ], [ - "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x304402200b3d0b0375bb15c14620afa4aa10ae90a0d6a046ce217bc20fe0bc1ced68c1b802204b550acab90ae6d3478057c9ad24f9df743815b799b6449dd7e7f6d3bc6e274c01", + "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "", "BIP66 example 7, without DERSIG" ], [ - "0 0 0x47 0x30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501", + "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "", "BIP66 example 10, without DERSIG" ], [ - "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0", + "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "", "BIP66 example 12, without DERSIG" ], [ - "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0", + "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "DERSIG", "BIP66 example 12, with DERSIG" @@ -826,31 +826,31 @@ "P2PK with high S but no LOW_S" ], [ - "0x47 0x30440220745d63eb70d45652128b450aa5ca7d9b513439963f261cb1c40a60f0785e7ee402204877785b38945ca9dbec78e1c1d4dd12148cc25c868bd27480023b49ae0f310501", + "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", "P2PK with hybrid pubkey but no STRICTENC" ], [ - "0x47 0x30440220606f6f9f6cebc84ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201", + "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "", "P2PK NOT with invalid hybrid pubkey but no STRICTENC" ], [ - "0 0x47 0x304402203a5ee39032637c431af0a3ac42e32e0627390bd44f6f98c9c04e6d714635ad0202207b42fcd889c3ae8a1b515608f38535f1f9be815176ee8d1b65a27c767cf37aed01", + "0 0x47 0x304402202e79441ad1baf5a07fb86bae3753184f6717d9692680947ea8b6e8b777c69af1022079a262e13d868bb5a0964fefe3ba26942e1b0669af1afb55ef3344bc9d4fc4c401", "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "", "1-of-2 with the second 1 hybrid pubkey and no STRICTENC" ], [ - "0 0x47 0x304402203a5ee39032637c431af0a3ac42e32e0627390bd44f6f98c9c04e6d714635ad0202207b42fcd889c3ae8a1b515608f38535f1f9be815176ee8d1b65a27c767cf37aed01", + "0 0x47 0x304402202e79441ad1baf5a07fb86bae3753184f6717d9692680947ea8b6e8b777c69af1022079a262e13d868bb5a0964fefe3ba26942e1b0669af1afb55ef3344bc9d4fc4c401", "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "STRICTENC", "1-of-2 with the second 1 hybrid pubkey" ], [ - "0x47 0x304402201c215cb13e4954e60ce4f6de74941904c771f998de7b1d9627e82a1949fde517022031c2197455f3dbecbb78321201308d7b039424e38d480772d7cd4eb465a083f405", + "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "", "P2PK with undefined hashtype but no STRICTENC" @@ -862,7 +862,7 @@ "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC" ], [ - "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", + "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "3-of-3 with nonzero dummy but no NULLDUMMY" @@ -874,19 +874,19 @@ "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY" ], [ - "0 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01 DUP", + "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "", "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY" ], [ - "0 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01", + "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "SIGPUSHONLY", "2-of-2 with two identical keys and sigs pushed" ], [ - "11 0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", + "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "P2SH", "P2PK with unnecessary input but no CLEANSTACK" From fc3979ac695f75f5a5cf2c97322eaebb9decddf8 Mon Sep 17 00:00:00 2001 From: dexX7 Date: Wed, 25 Mar 2015 12:09:17 +0100 Subject: [PATCH 0353/2337] Initialization: setup environment before starting tests The environment is prepared by the main thread to guard against invalid locale settings and to prevent deinitialization issues of Boost path, which can result in app crashes. --- src/test/test_bitcoin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 7d5207b11e6..5358e186680 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -28,6 +28,7 @@ extern void noui_connect(); BasicTestingSetup::BasicTestingSetup() { + SetupEnvironment(); fPrintToDebugLog = false; // don't want to write to debug.log file SelectParams(CBaseChainParams::MAIN); } From 3a3ecc02e55ba955ee535d645412ebb66295939a Mon Sep 17 00:00:00 2001 From: dexX7 Date: Fri, 27 Mar 2015 01:33:34 +0100 Subject: [PATCH 0354/2337] Initialization: setup environment before starting QT tests The environment is prepared by the main thread to guard against invalid locale settings. --- src/qt/test/test_main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index da5f0743907..bb768f13253 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -6,6 +6,7 @@ #include "config/bitcoin-config.h" #endif +#include "util.h" #include "uritests.h" #ifdef ENABLE_WALLET @@ -27,6 +28,7 @@ Q_IMPORT_PLUGIN(qkrcodecs) // This is all you need to run all the tests int main(int argc, char *argv[]) { + SetupEnvironment(); bool fInvalid = false; // Don't remove this, it's needed to access From 63e4c9cd355042d050e568c6164473c1bd6cc63d Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Sun, 29 Mar 2015 19:45:05 +0800 Subject: [PATCH 0355/2337] Fix clang compile warnings intriduced in #5681 --- src/txdb.h | 2 +- src/validationinterface.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/txdb.h b/src/txdb.h index 1ce93969d84..86e1c5d8316 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -16,7 +16,7 @@ class CBlockFileInfo; class CBlockIndex; -class CDiskTxPos; +struct CDiskTxPos; class uint256; //! -dbcache default (MiB) diff --git a/src/validationinterface.h b/src/validationinterface.h index b21b6e57825..bee67d892fa 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -9,7 +9,7 @@ #include class CBlock; -class CBlockLocator; +struct CBlockLocator; class CTransaction; class CValidationInterface; class CValidationState; From 6f252627b2843ff5072cb702b47e241f4ffbed92 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 27 Mar 2015 10:34:48 +0100 Subject: [PATCH 0356/2337] wallet: make it possible to disable transaction broadcast This is an advanced feature which will disable any kind of automatic transaction broadcasting in the wallet. This gives the user full control of how the transaction is sent. For example they can broadcast new transactions through some other mechanism themselves, after getting the transaction hex through `gettransaction`. This just adds the option `-walletbroadcast=<0,1>`. Right now these transactions will get the status Status: conflicted, has not been successfully broadcast yet They shouldn't be shown as conflicted at all (`walletconflicts` is empty). This status will go away when the transaction is received through the network. --- src/init.cpp | 2 ++ src/wallet/wallet.cpp | 21 ++++++++++++++------- src/wallet/wallet.h | 7 +++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 2a13af6690a..9445e2fa10f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -337,6 +337,7 @@ std::string HelpMessage(HelpMessageMode mode) FormatMoney(maxTxFee))); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); + strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true)); strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); @@ -1242,6 +1243,7 @@ bool AppInit2(boost::thread_group& threadGroup) } } } + pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", true)); } // (!fDisableWallet) #else // ENABLE_WALLET LogPrintf("No wallet compiled in!\n"); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a10123002ee..2566b2712bd 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1096,6 +1096,9 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) void CWallet::ReacceptWalletTransactions() { + // If transcations aren't broadcasted, don't let them into local mempool either + if (!fBroadcastTransactions) + return; LOCK2(cs_main, cs_wallet); BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) { @@ -1116,6 +1119,7 @@ void CWallet::ReacceptWalletTransactions() bool CWalletTx::RelayWalletTransaction() { + assert(pwallet->GetBroadcastTransactions()); if (!IsCoinBase()) { if (GetDepthInMainChain() == 0) { @@ -1354,7 +1358,7 @@ void CWallet::ResendWalletTransactions(int64_t nBestBlockTime) { // Do this infrequently and randomly to avoid giving away // that these are our transactions. - if (GetTime() < nNextResend) + if (GetTime() < nNextResend || !fBroadcastTransactions) return; bool fFirst = (nNextResend == 0); nNextResend = GetTime() + GetRand(30 * 60); @@ -1979,14 +1983,17 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) // Track how many getdata requests our transaction gets mapRequestCount[wtxNew.GetHash()] = 0; - // Broadcast - if (!wtxNew.AcceptToMemoryPool(false)) + if (fBroadcastTransactions) { - // This must not fail. The transaction has already been signed and recorded. - LogPrintf("CommitTransaction(): Error: Transaction not valid"); - return false; + // Broadcast + if (!wtxNew.AcceptToMemoryPool(false)) + { + // This must not fail. The transaction has already been signed and recorded. + LogPrintf("CommitTransaction(): Error: Transaction not valid"); + return false; + } + wtxNew.RelayWalletTransaction(); } - wtxNew.RelayWalletTransaction(); } return true; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6ae1c87b1d3..4dbb0e2e578 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -455,6 +455,7 @@ private: int64_t nNextResend; int64_t nLastResend; + bool fBroadcastTransactions; /** * Used to keep track of spent outpoints, and @@ -518,6 +519,7 @@ public: nNextResend = 0; nLastResend = 0; nTimeFirstKey = 0; + fBroadcastTransactions = false; } std::map mapWallet; @@ -723,6 +725,11 @@ public: /** Watch-only address added */ boost::signals2::signal NotifyWatchonlyChanged; + + /** Inquire whether this wallet broadcasts transactions. */ + bool GetBroadcastTransactions() const { return fBroadcastTransactions; } + /** Set whether this wallet broadcasts transactions. */ + void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; } }; /** A key allocated from the key pool. */ From 77650cc9f4646787e843b2922730d8cba5af36a1 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 1 Apr 2015 11:56:52 +0200 Subject: [PATCH 0357/2337] add -walletbroadcast=0 rpc test --- qa/rpc-tests/wallet.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 01e9fa57b29..284fc1cb6f7 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -150,6 +150,47 @@ class WalletTest (BitcoinTestFramework): sync_mempools(self.nodes) assert(txid1 in self.nodes[3].getrawmempool()) + + + #do some -walletbroadcast tests + stop_nodes(self.nodes) + wait_bitcoinds() + self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"],["-walletbroadcast=0"],["-walletbroadcast=0"]]) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.sync_all() + txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2); + txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) + self.nodes[1].setgenerate(True, 1) #mine a block, tx should not be in there + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')); #should not be changed because tx was not broadcasted + + #now broadcast from another node, mine a block, sync, and check the balance + self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex']) + self.nodes[1].setgenerate(True, 1) + self.sync_all() + txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) + assert_equal(self.nodes[2].getbalance(), Decimal('61.99800000')); #should not be + + #create another tx + txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2); + + #restart the nodes with -walletbroadcast=1 + stop_nodes(self.nodes) + wait_bitcoinds() + self.nodes = start_nodes(3, self.options.tmpdir) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + sync_blocks(self.nodes) + + self.nodes[0].setgenerate(True, 1) + sync_blocks(self.nodes) + + #tx should be added to balance because after restarting the nodes tx should be broadcastet + assert_equal(self.nodes[2].getbalance(), Decimal('63.99800000')); #should not be + if __name__ == '__main__': WalletTest ().main () From 15facb4aca75122b6ae0dcc6f6e112127e6a0e59 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 1 Apr 2015 18:43:49 +0200 Subject: [PATCH 0358/2337] doc: add historical release notes for 0.10.0 --- doc/release-notes/release-notes-0.10.0.md | 762 ++++++++++++++++++++++ 1 file changed, 762 insertions(+) create mode 100644 doc/release-notes/release-notes-0.10.0.md diff --git a/doc/release-notes/release-notes-0.10.0.md b/doc/release-notes/release-notes-0.10.0.md new file mode 100644 index 00000000000..986b8832ec1 --- /dev/null +++ b/doc/release-notes/release-notes-0.10.0.md @@ -0,0 +1,762 @@ +Bitcoin Core version 0.10.0 is now available from: + + https://bitcoin.org/bin/0.10.0/ + +This is a new major version release, bringing both new features and +bug fixes. + +Please report bugs using the issue tracker at github: + + https://github.com/bitcoin/bitcoin/issues + +Upgrading and downgrading +========================= + +How to Upgrade +-------------- + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or +bitcoind/bitcoin-qt (on Linux). + +Downgrading warning +--------------------- + +Because release 0.10.0 makes use of headers-first synchronization and parallel +block download (see further), the block files and databases are not +backwards-compatible with older versions of Bitcoin Core or other software: + +* Blocks will be stored on disk out of order (in the order they are +received, really), which makes it incompatible with some tools or +other programs. Reindexing using earlier versions will also not work +anymore as a result of this. + +* The block index database will now hold headers for which no block is +stored on disk, which earlier versions won't support. + +If you want to be able to downgrade smoothly, make a backup of your entire data +directory. Without this your node will need start syncing (or importing from +bootstrap.dat) anew afterwards. It is possible that the data from a completely +synchronised 0.10 node may be usable in older versions as-is, but this is not +supported and may break as soon as the older version attempts to reindex. + +This does not affect wallet forward or backward compatibility. + + +Notable changes +=============== + +Faster synchronization +---------------------- + +Bitcoin Core now uses 'headers-first synchronization'. This means that we first +ask peers for block headers (a total of 27 megabytes, as of December 2014) and +validate those. In a second stage, when the headers have been discovered, we +download the blocks. However, as we already know about the whole chain in +advance, the blocks can be downloaded in parallel from all available peers. + +In practice, this means a much faster and more robust synchronization. On +recent hardware with a decent network link, it can be as little as 3 hours +for an initial full synchronization. You may notice a slower progress in the +very first few minutes, when headers are still being fetched and verified, but +it should gain speed afterwards. + +A few RPCs were added/updated as a result of this: +- `getblockchaininfo` now returns the number of validated headers in addition to +the number of validated blocks. +- `getpeerinfo` lists both the number of blocks and headers we know we have in +common with each peer. While synchronizing, the heights of the blocks that we +have requested from peers (but haven't received yet) are also listed as +'inflight'. +- A new RPC `getchaintips` lists all known branches of the block chain, +including those we only have headers for. + +Transaction fee changes +----------------------- + +This release automatically estimates how high a transaction fee (or how +high a priority) transactions require to be confirmed quickly. The default +settings will create transactions that confirm quickly; see the new +'txconfirmtarget' setting to control the tradeoff between fees and +confirmation times. Fees are added by default unless the 'sendfreetransactions' +setting is enabled. + +Prior releases used hard-coded fees (and priorities), and would +sometimes create transactions that took a very long time to confirm. + +Statistics used to estimate fees and priorities are saved in the +data directory in the `fee_estimates.dat` file just before +program shutdown, and are read in at startup. + +New command line options for transaction fee changes: +- `-txconfirmtarget=n` : create transactions that have enough fees (or priority) +so they are likely to begin confirmation within n blocks (default: 1). This setting +is over-ridden by the -paytxfee option. +- `-sendfreetransactions` : Send transactions as zero-fee transactions if possible +(default: 0) + +New RPC commands for fee estimation: +- `estimatefee nblocks` : Returns approximate fee-per-1,000-bytes needed for +a transaction to begin confirmation within nblocks. Returns -1 if not enough +transactions have been observed to compute a good estimate. +- `estimatepriority nblocks` : Returns approximate priority needed for +a zero-fee transaction to begin confirmation within nblocks. Returns -1 if not +enough free transactions have been observed to compute a good +estimate. + +RPC access control changes +-------------------------- + +Subnet matching for the purpose of access control is now done +by matching the binary network address, instead of with string wildcard matching. +For the user this means that `-rpcallowip` takes a subnet specification, which can be + +- a single IP address (e.g. `1.2.3.4` or `fe80::0012:3456:789a:bcde`) +- a network/CIDR (e.g. `1.2.3.0/24` or `fe80::0000/64`) +- a network/netmask (e.g. `1.2.3.4/255.255.255.0` or `fe80::0012:3456:789a:bcde/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff`) + +An arbitrary number of `-rpcallow` arguments can be given. An incoming connection will be accepted if its origin address +matches one of them. + +For example: + +| 0.9.x and before | 0.10.x | +|--------------------------------------------|---------------------------------------| +| `-rpcallowip=192.168.1.1` | `-rpcallowip=192.168.1.1` (unchanged) | +| `-rpcallowip=192.168.1.*` | `-rpcallowip=192.168.1.0/24` | +| `-rpcallowip=192.168.*` | `-rpcallowip=192.168.0.0/16` | +| `-rpcallowip=*` (dangerous!) | `-rpcallowip=::/0` (still dangerous!) | + +Using wildcards will result in the rule being rejected with the following error in debug.log: + + Error: Invalid -rpcallowip subnet specification: *. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). + + +REST interface +-------------- + +A new HTTP API is exposed when running with the `-rest` flag, which allows +unauthenticated access to public node data. + +It is served on the same port as RPC, but does not need a password, and uses +plain HTTP instead of JSON-RPC. + +Assuming a local RPC server running on port 8332, it is possible to request: +- Blocks: http://localhost:8332/rest/block/*HASH*.*EXT* +- Blocks without transactions: http://localhost:8332/rest/block/notxdetails/*HASH*.*EXT* +- Transactions (requires `-txindex`): http://localhost:8332/rest/tx/*HASH*.*EXT* + +In every case, *EXT* can be `bin` (for raw binary data), `hex` (for hex-encoded +binary) or `json`. + +For more details, see the `doc/REST-interface.md` document in the repository. + +RPC Server "Warm-Up" Mode +------------------------- + +The RPC server is started earlier now, before most of the expensive +intialisations like loading the block index. It is available now almost +immediately after starting the process. However, until all initialisations +are done, it always returns an immediate error with code -28 to all calls. + +This new behaviour can be useful for clients to know that a server is already +started and will be available soon (for instance, so that they do not +have to start it themselves). + +Improved signing security +------------------------- + +For 0.10 the security of signing against unusual attacks has been +improved by making the signatures constant time and deterministic. + +This change is a result of switching signing to use libsecp256k1 +instead of OpenSSL. Libsecp256k1 is a cryptographic library +optimized for the curve Bitcoin uses which was created by Bitcoin +Core developer Pieter Wuille. + +There exist attacks[1] against most ECC implementations where an +attacker on shared virtual machine hardware could extract a private +key if they could cause a target to sign using the same key hundreds +of times. While using shared hosts and reusing keys are inadvisable +for other reasons, it's a better practice to avoid the exposure. + +OpenSSL has code in their source repository for derandomization +and reduction in timing leaks that we've eagerly wanted to use for a +long time, but this functionality has still not made its +way into a released version of OpenSSL. Libsecp256k1 achieves +significantly stronger protection: As far as we're aware this is +the only deployed implementation of constant time signing for +the curve Bitcoin uses and we have reason to believe that +libsecp256k1 is better tested and more thoroughly reviewed +than the implementation in OpenSSL. + +[1] https://eprint.iacr.org/2014/161.pdf + +Watch-only wallet support +------------------------- + +The wallet can now track transactions to and from wallets for which you know +all addresses (or scripts), even without the private keys. + +This can be used to track payments without needing the private keys online on a +possibly vulnerable system. In addition, it can help for (manual) construction +of multisig transactions where you are only one of the signers. + +One new RPC, `importaddress`, is added which functions similarly to +`importprivkey`, but instead takes an address or script (in hexadecimal) as +argument. After using it, outputs credited to this address or script are +considered to be received, and transactions consuming these outputs will be +considered to be sent. + +The following RPCs have optional support for watch-only: +`getbalance`, `listreceivedbyaddress`, `listreceivedbyaccount`, +`listtransactions`, `listaccounts`, `listsinceblock`, `gettransaction`. See the +RPC documentation for those methods for more information. + +Compared to using `getrawtransaction`, this mechanism does not require +`-txindex`, scales better, integrates better with the wallet, and is compatible +with future block chain pruning functionality. It does mean that all relevant +addresses need to added to the wallet before the payment, though. + +Consensus library +----------------- + +Starting from 0.10.0, the Bitcoin Core distribution includes a consensus library. + +The purpose of this library is to make the verification functionality that is +critical to Bitcoin's consensus available to other applications, e.g. to language +bindings such as [python-bitcoinlib](https://pypi.python.org/pypi/python-bitcoinlib) or +alternative node implementations. + +This library is called `libbitcoinconsensus.so` (or, `.dll` for Windows). +Its interface is defined in the C header [bitcoinconsensus.h](https://github.com/bitcoin/bitcoin/blob/0.10/src/script/bitcoinconsensus.h). + +In its initial version the API includes two functions: + +- `bitcoinconsensus_verify_script` verifies a script. It returns whether the indicated input of the provided serialized transaction +correctly spends the passed scriptPubKey under additional constraints indicated by flags +- `bitcoinconsensus_version` returns the API version, currently at an experimental `0` + +The functionality is planned to be extended to e.g. UTXO management in upcoming releases, but the interface +for existing methods should remain stable. + +Standard script rules relaxed for P2SH addresses +------------------------------------------------ + +The IsStandard() rules have been almost completely removed for P2SH +redemption scripts, allowing applications to make use of any valid +script type, such as "n-of-m OR y", hash-locked oracle addresses, etc. +While the Bitcoin protocol has always supported these types of script, +actually using them on mainnet has been previously inconvenient as +standard Bitcoin Core nodes wouldn't relay them to miners, nor would +most miners include them in blocks they mined. + +bitcoin-tx +---------- + +It has been observed that many of the RPC functions offered by bitcoind are +"pure functions", and operate independently of the bitcoind wallet. This +included many of the RPC "raw transaction" API functions, such as +createrawtransaction. + +bitcoin-tx is a newly introduced command line utility designed to enable easy +manipulation of bitcoin transactions. A summary of its operation may be +obtained via "bitcoin-tx --help" Transactions may be created or signed in a +manner similar to the RPC raw tx API. Transactions may be updated, deleting +inputs or outputs, or appending new inputs and outputs. Custom scripts may be +easily composed using a simple text notation, borrowed from the bitcoin test +suite. + +This tool may be used for experimenting with new transaction types, signing +multi-party transactions, and many other uses. Long term, the goal is to +deprecate and remove "pure function" RPC API calls, as those do not require a +server round-trip to execute. + +Other utilities "bitcoin-key" and "bitcoin-script" have been proposed, making +key and script operations easily accessible via command line. + +Mining and relay policy enhancements +------------------------------------ + +Bitcoin Core's block templates are now for version 3 blocks only, and any mining +software relying on its `getblocktemplate` must be updated in parallel to use +libblkmaker either version 0.4.2 or any version from 0.5.1 onward. +If you are solo mining, this will affect you the moment you upgrade Bitcoin +Core, which must be done prior to BIP66 achieving its 951/1001 status. +If you are mining with the stratum mining protocol: this does not affect you. +If you are mining with the getblocktemplate protocol to a pool: this will affect +you at the pool operator's discretion, which must be no later than BIP66 +achieving its 951/1001 status. + +The `prioritisetransaction` RPC method has been added to enable miners to +manipulate the priority of transactions on an individual basis. + +Bitcoin Core now supports BIP 22 long polling, so mining software can be +notified immediately of new templates rather than having to poll periodically. + +Support for BIP 23 block proposals is now available in Bitcoin Core's +`getblocktemplate` method. This enables miners to check the basic validity of +their next block before expending work on it, reducing risks of accidental +hardforks or mining invalid blocks. + +Two new options to control mining policy: +- `-datacarrier=0/1` : Relay and mine "data carrier" (OP_RETURN) transactions +if this is 1. +- `-datacarriersize=n` : Maximum size, in bytes, we consider acceptable for +"data carrier" outputs. + +The relay policy has changed to more properly implement the desired behavior of not +relaying free (or very low fee) transactions unless they have a priority above the +AllowFreeThreshold(), in which case they are relayed subject to the rate limiter. + +BIP 66: strict DER encoding for signatures +------------------------------------------ + +Bitcoin Core 0.10 implements BIP 66, which introduces block version 3, and a new +consensus rule, which prohibits non-DER signatures. Such transactions have been +non-standard since Bitcoin v0.8.0 (released in February 2013), but were +technically still permitted inside blocks. + +This change breaks the dependency on OpenSSL's signature parsing, and is +required if implementations would want to remove all of OpenSSL from the +consensus code. + +The same miner-voting mechanism as in BIP 34 is used: when 751 out of a +sequence of 1001 blocks have version number 3 or higher, the new consensus +rule becomes active for those blocks. When 951 out of a sequence of 1001 +blocks have version number 3 or higher, it becomes mandatory for all blocks. + +Backward compatibility with current mining software is NOT provided, thus miners +should read the first paragraph of "Mining and relay policy enhancements" above. + +0.10.0 Change log +================= + +Detailed release notes follow. This overview includes changes that affect external +behavior, not code moves, refactors or string updates. + +RPC: +- `f923c07` Support IPv6 lookup in bitcoin-cli even when IPv6 only bound on localhost +- `b641c9c` Fix addnode "onetry": Connect with OpenNetworkConnection +- `171ca77` estimatefee / estimatepriority RPC methods +- `b750cf1` Remove cli functionality from bitcoind +- `f6984e8` Add "chain" to getmininginfo, improve help in getblockchaininfo +- `99ddc6c` Add nLocalServices info to RPC getinfo +- `cf0c47b` Remove getwork() RPC call +- `2a72d45` prioritisetransaction +- `e44fea5` Add an option `-datacarrier` to allow users to disable relaying/mining data carrier transactions +- `2ec5a3d` Prevent easy RPC memory exhaustion attack +- `d4640d7` Added argument to getbalance to include watchonly addresses and fixed errors in balance calculation +- `83f3543` Added argument to listaccounts to include watchonly addresses +- `952877e` Showing 'involvesWatchonly' property for transactions returned by 'listtransactions' and 'listsinceblock'. It is only appended when the transaction involves a watchonly address +- `d7d5d23` Added argument to listtransactions and listsinceblock to include watchonly addresses +- `f87ba3d` added includeWatchonly argument to 'gettransaction' because it affects balance calculation +- `0fa2f88` added includedWatchonly argument to listreceivedbyaddress/...account +- `6c37f7f` `getrawchangeaddress`: fail when keypool exhausted and wallet locked +- `ff6a7af` getblocktemplate: longpolling support +- `c4a321f` Add peerid to getpeerinfo to allow correlation with the logs +- `1b4568c` Add vout to ListTransactions output +- `b33bd7a` Implement "getchaintips" RPC command to monitor blockchain forks +- `733177e` Remove size limit in RPC client, keep it in server +- `6b5b7cb` Categorize rpc help overview +- `6f2c26a` Closely track mempool byte total. Add "getmempoolinfo" RPC +- `aa82795` Add detailed network info to getnetworkinfo RPC +- `01094bd` Don't reveal whether password is <20 or >20 characters in RPC +- `57153d4` rpc: Compute number of confirmations of a block from block height +- `ff36cbe` getnetworkinfo: export local node's client sub-version string +- `d14d7de` SanitizeString: allow '(' and ')' +- `31d6390` Fixed setaccount accepting foreign address +- `b5ec5fe` update getnetworkinfo help with subversion +- `ad6e601` RPC additions after headers-first +- `33dfbf5` rpc: Fix leveldb iterator leak, and flush before `gettxoutsetinfo` +- `2aa6329` Enable customising node policy for datacarrier data size with a -datacarriersize option +- `f877aaa` submitblock: Use a temporary CValidationState to determine accurately the outcome of ProcessBlock +- `e69a587` submitblock: Support for returning specific rejection reasons +- `af82884` Add "warmup mode" for RPC server +- `e2655e0` Add unauthenticated HTTP REST interface to public blockchain data +- `683dc40` Disable SSLv3 (in favor of TLS) for the RPC client and server +- `44b4c0d` signrawtransaction: validate private key +- `9765a50` Implement BIP 23 Block Proposal +- `f9de17e` Add warning comment to getinfo + +Command-line options: +- `ee21912` Use netmasks instead of wildcards for IP address matching +- `deb3572` Add `-rpcbind` option to allow binding RPC port on a specific interface +- `96b733e` Add `-version` option to get just the version +- `1569353` Add `-stopafterblockimport` option +- `77cbd46` Let -zapwallettxes recover transaction meta data +- `1c750db` remove -tor compatibility code (only allow -onion) +- `4aaa017` rework help messages for fee-related options +- `4278b1d` Clarify error message when invalid -rpcallowip +- `6b407e4` -datadir is now allowed in config files +- `bdd5b58` Add option `-sysperms` to disable 077 umask (create new files with system default umask) +- `cbe39a3` Add "bitcoin-tx" command line utility and supporting modules +- `dbca89b` Trigger -alertnotify if network is upgrading without you +- `ad96e7c` Make -reindex cope with out-of-order blocks +- `16d5194` Skip reindexed blocks individually +- `ec01243` --tracerpc option for regression tests +- `f654f00` Change -genproclimit default to 1 +- `3c77714` Make -proxy set all network types, avoiding a connect leak +- `57be955` Remove -printblock, -printblocktree, and -printblockindex +- `ad3d208` remove -maxorphanblocks config parameter since it is no longer functional + +Block and transaction handling: +- `7a0e84d` ProcessGetData(): abort if a block file is missing from disk +- `8c93bf4` LoadBlockIndexDB(): Require block db reindex if any `blk*.dat` files are missing +- `77339e5` Get rid of the static chainMostWork (optimization) +- `4e0eed8` Allow ActivateBestChain to release its lock on cs_main +- `18e7216` Push cs_mains down in ProcessBlock +- `fa126ef` Avoid undefined behavior using CFlatData in CScript serialization +- `7f3b4e9` Relax IsStandard rules for pay-to-script-hash transactions +- `c9a0918` Add a skiplist to the CBlockIndex structure +- `bc42503` Use unordered_map for CCoinsViewCache with salted hash (optimization) +- `d4d3fbd` Do not flush the cache after every block outside of IBD (optimization) +- `ad08d0b` Bugfix: make CCoinsViewMemPool support pruned entries in underlying cache +- `5734d4d` Only remove actualy failed blocks from setBlockIndexValid +- `d70bc52` Rework block processing benchmark code +- `714a3e6` Only keep setBlockIndexValid entries that are possible improvements +- `ea100c7` Reduce maximum coinscache size during verification (reduce memory usage) +- `4fad8e6` Reject transactions with excessive numbers of sigops +- `b0875eb` Allow BatchWrite to destroy its input, reducing copying (optimization) +- `92bb6f2` Bypass reloading blocks from disk (optimization) +- `2e28031` Perform CVerifyDB on pcoinsdbview instead of pcoinsTip (reduce memory usage) +- `ab15b2e` Avoid copying undo data (optimization) +- `341735e` Headers-first synchronization +- `afc32c5` Fix rebuild-chainstate feature and improve its performance +- `e11b2ce` Fix large reorgs +- `ed6d1a2` Keep information about all block files in memory +- `a48f2d6` Abstract context-dependent block checking from acceptance +- `7e615f5` Fixed mempool sync after sending a transaction +- `51ce901` Improve chainstate/blockindex disk writing policy +- `a206950` Introduce separate flushing modes +- `9ec75c5` Add a locking mechanism to IsInitialBlockDownload to ensure it never goes from false to true +- `868d041` Remove coinbase-dependant transactions during reorg +- `723d12c` Remove txn which are invalidated by coinbase maturity during reorg +- `0cb8763` Check against MANDATORY flags prior to accepting to mempool +- `8446262` Reject headers that build on an invalid parent +- `008138c` Bugfix: only track UTXO modification after lookup + +P2P protocol and network code: +- `f80cffa` Do not trigger a DoS ban if SCRIPT_VERIFY_NULLDUMMY fails +- `c30329a` Add testnet DNS seed of Alex Kotenko +- `45a4baf` Add testnet DNS seed of Andreas Schildbach +- `f1920e8` Ping automatically every 2 minutes (unconditionally) +- `806fd19` Allocate receive buffers in on the fly +- `6ecf3ed` Display unknown commands received +- `aa81564` Track peers' available blocks +- `caf6150` Use async name resolving to improve net thread responsiveness +- `9f4da19` Use pong receive time rather than processing time +- `0127a9b` remove SOCKS4 support from core and GUI, use SOCKS5 +- `40f5cb8` Send rejects and apply DoS scoring for errors in direct block validation +- `dc942e6` Introduce whitelisted peers +- `c994d2e` prevent SOCKET leak in BindListenPort() +- `a60120e` Add built-in seeds for .onion +- `60dc8e4` Allow -onlynet=onion to be used +- `3a56de7` addrman: Do not propagate obviously poor addresses onto the network +- `6050ab6` netbase: Make SOCKS5 negotiation interruptible +- `604ee2a` Remove tx from AlreadyAskedFor list once we receive it, not when we process it +- `efad808` Avoid reject message feedback loops +- `71697f9` Separate protocol versioning from clientversion +- `20a5f61` Don't relay alerts to peers before version negotiation +- `b4ee0bd` Introduce preferred download peers +- `845c86d` Do not use third party services for IP detection +- `12a49ca` Limit the number of new addressses to accumulate +- `35e408f` Regard connection failures as attempt for addrman +- `a3a7317` Introduce 10 minute block download timeout +- `3022e7d` Require sufficent priority for relay of free transactions +- `58fda4d` Update seed IPs, based on bitcoin.sipa.be crawler data +- `18021d0` Remove bitnodes.io from dnsseeds. + +Validation: +- `6fd7ef2` Also switch the (unused) verification code to low-s instead of even-s +- `584a358` Do merkle root and txid duplicates check simultaneously +- `217a5c9` When transaction outputs exceed inputs, show the offending amounts so as to aid debugging +- `f74fc9b` Print input index when signature validation fails, to aid debugging +- `6fd59ee` script.h: set_vch() should shift a >32 bit value +- `d752ba8` Add SCRIPT_VERIFY_SIGPUSHONLY (BIP62 rule 2) (test only) +- `698c6ab` Add SCRIPT_VERIFY_MINIMALDATA (BIP62 rules 3 and 4) (test only) +- `ab9edbd` script: create sane error return codes for script validation and remove logging +- `219a147` script: check ScriptError values in script tests +- `0391423` Discourage NOPs reserved for soft-fork upgrades +- `98b135f` Make STRICTENC invalid pubkeys fail the script rather than the opcode +- `307f7d4` Report script evaluation failures in log and reject messages +- `ace39db` consensus: guard against openssl's new strict DER checks +- `12b7c44` Improve robustness of DER recoding code +- `76ce5c8` fail immediately on an empty signature + +Build system: +- `f25e3ad` Fix build in OS X 10.9 +- `65e8ba4` build: Switch to non-recursive make +- `460b32d` build: fix broken boost chrono check on some platforms +- `9ce0774` build: Fix windows configure when using --with-qt-libdir +- `ea96475` build: Add mention of --disable-wallet to bdb48 error messages +- `1dec09b` depends: add shared dependency builder +- `c101c76` build: Add --with-utils (bitcoin-cli and bitcoin-tx, default=yes). Help string consistency tweaks. Target sanity check fix +- `e432a5f` build: add option for reducing exports (v2) +- `6134b43` Fixing condition 'sabotaging' MSVC build +- `af0bd5e` osx: fix signing to make Gatekeeper happy (again) +- `a7d1f03` build: fix dynamic boost check when --with-boost= is used +- `d5fd094` build: fix qt test build when libprotobuf is in a non-standard path +- `2cf5f16` Add libbitcoinconsensus library +- `914868a` build: add a deterministic dmg signer +- `2d375fe` depends: bump openssl to 1.0.1k +- `b7a4ecc` Build: Only check for boost when building code that requires it + +Wallet: +- `b33d1f5` Use fee/priority estimates in wallet CreateTransaction +- `4b7b1bb` Sanity checks for estimates +- `c898846` Add support for watch-only addresses +- `d5087d1` Use script matching rather than destination matching for watch-only +- `d88af56` Fee fixes +- `a35b55b` Dont run full check every time we decrypt wallet +- `3a7c348` Fix make_change to not create half-satoshis +- `f606bb9` fix a possible memory leak in CWalletDB::Recover +- `870da77` fix possible memory leaks in CWallet::EncryptWallet +- `ccca27a` Watch-only fixes +- `9b1627d` [Wallet] Reduce minTxFee for transaction creation to 1000 satoshis +- `a53fd41` Deterministic signing +- `15ad0b5` Apply AreSane() checks to the fees from the network +- `11855c1` Enforce minRelayTxFee on wallet created tx and add a maxtxfee option + +GUI: +- `c21c74b` osx: Fix missing dock menu with qt5 +- `b90711c` Fix Transaction details shows wrong To: +- `516053c` Make links in 'About Bitcoin Core' clickable +- `bdc83e8` Ensure payment request network matches client network +- `65f78a1` Add GUI view of peer information +- `06a91d9` VerifyDB progress reporting +- `fe6bff2` Add BerkeleyDB version info to RPCConsole +- `b917555` PeerTableModel: Fix potential deadlock. #4296 +- `dff0e3b` Improve rpc console history behavior +- `95a9383` Remove CENT-fee-rule from coin control completely +- `56b07d2` Allow setting listen via GUI +- `d95ba75` Log messages with type>QtDebugMsg as non-debug +- `8969828` New status bar Unit Display Control and related changes +- `674c070` seed OpenSSL PNRG with Windows event data +- `509f926` Payment request parsing on startup now only changes network if a valid network name is specified +- `acd432b` Prevent balloon-spam after rescan +- `7007402` Implement SI-style (thin space) thoudands separator +- `91cce17` Use fixed-point arithmetic in amount spinbox +- `bdba2dd` Remove an obscure option no-one cares about +- `bd0aa10` Replace the temporary file hack currently used to change Bitcoin-Qt's dock icon (OS X) with a buffer-based solution +- `94e1b9e` Re-work overviewpage UI +- `8bfdc9a` Better looking trayicon +- `b197bf3` disable tray interactions when client model set to 0 +- `1c5f0af` Add column Watch-only to transactions list +- `21f139b` Fix tablet crash. closes #4854 +- `e84843c` Broken addresses on command line no longer trigger testnet +- `a49f11d` Change splash screen to normal window +- `1f9be98` Disable App Nap on OSX 10.9+ +- `27c3e91` Add proxy to options overridden if necessary +- `4bd1185` Allow "emergency" shutdown during startup +- `d52f072` Don't show wallet options in the preferences menu when running with -disablewallet +- `6093aa1` Qt: QProgressBar CPU-Issue workaround +- `0ed9675` [Wallet] Add global boolean whether to send free transactions (default=true) +- `ed3e5e4` [Wallet] Add global boolean whether to pay at least the custom fee (default=true) +- `e7876b2` [Wallet] Prevent user from paying a non-sense fee +- `c1c9d5b` Add Smartfee to GUI +- `e0a25c5` Make askpassphrase dialog behave more sanely +- `94b362d` On close of splashscreen interrupt verifyDB +- `b790d13` English translation update +- `8543b0d` Correct tooltip on address book page + +Tests: +- `b41e594` Fix script test handling of empty scripts +- `d3a33fc` Test CHECKMULTISIG with m == 0 and n == 0 +- `29c1749` Let tx (in)valid tests use any SCRIPT_VERIFY flag +- `6380180` Add rejection of non-null CHECKMULTISIG dummy values +- `21bf3d2` Add tests for BoostAsioToCNetAddr +- `b5ad5e7` Add Python test for -rpcbind and -rpcallowip +- `9ec0306` Add CODESEPARATOR/FindAndDelete() tests +- `75ebced` Added many rpc wallet tests +- `0193fb8` Allow multiple regression tests to run at once +- `92a6220` Hook up sanity checks +- `3820e01` Extend and move all crypto tests to crypto_tests.cpp +- `3f9a019` added list/get received by address/ account tests +- `a90689f` Remove timing-based signature cache unit test +- `236982c` Add skiplist unit tests +- `f4b00be` Add CChain::GetLocator() unit test +- `b45a6e8` Add test for getblocktemplate longpolling +- `cdf305e` Set -discover=0 in regtest framework +- `ed02282` additional test for OP_SIZE in script_valid.json +- `0072d98` script tests: BOOLAND, BOOLOR decode to integer +- `833ff16` script tests: values that overflow to 0 are true +- `4cac5db` script tests: value with trailing 0x00 is true +- `89101c6` script test: test case for 5-byte bools +- `d2d9dc0` script tests: add tests for CHECKMULTISIG limits +- `d789386` Add "it works" test for bitcoin-tx +- `df4d61e` Add bitcoin-tx tests +- `aa41ac2` Test IsPushOnly() with invalid push +- `6022b5d` Make `script_{valid,invalid}.json` validation flags configurable +- `8138cbe` Add automatic script test generation, and actual checksig tests +- `ed27e53` Add coins_tests with a large randomized CCoinViewCache test +- `9df9cf5` Make SCRIPT_VERIFY_STRICTENC compatible with BIP62 +- `dcb9846` Extend getchaintips RPC test +- `554147a` Ensure MINIMALDATA invalid tests can only fail one way +- `dfeec18` Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule +- `2b62e17` Clearly separate PUSHDATA and numeric argument MINIMALDATA tests +- `16d78bd` Add valid invert of invalid every numeric opcode tests +- `f635269` tests: enable alertnotify test for Windows +- `7a41614` tests: allow rpc-tests to get filenames for bitcoind and bitcoin-cli from the environment +- `5122ea7` tests: fix forknotify.py on windows +- `fa7f8cd` tests: remove old pull-tester scripts +- `7667850` tests: replace the old (unused since Travis) tests with new rpc test scripts +- `f4e0aef` Do signature-s negation inside the tests +- `1837987` Optimize -regtest setgenerate block generation +- `2db4c8a` Fix node ranges in the test framework +- `a8b2ce5` regression test only setmocktime RPC call +- `daf03e7` RPC tests: create initial chain with specific timestamps +- `8656dbb` Port/fix txnmall.sh regression test +- `ca81587` Test the exact order of CHECKMULTISIG sig/pubkey evaluation +- `7357893` Prioritize and display -testsafemode status in UI +- `f321d6b` Add key generation/verification to ECC sanity check +- `132ea9b` miner_tests: Disable checkpoints so they don't fail the subsidy-change test +- `bc6cb41` QA RPC tests: Add tests block block proposals +- `f67a9ce` Use deterministically generated script tests +- `11d7a7d` [RPC] add rpc-test for http keep-alive (persistent connections) +- `34318d7` RPC-test based on invalidateblock for mempool coinbase spends +- `76ec867` Use actually valid transactions for script tests +- `c8589bf` Add actual signature tests +- `e2677d7` Fix smartfees test for change to relay policy +- `263b65e` tests: run sanity checks in tests too + +Miscellaneous: +- `122549f` Fix incorrect checkpoint data for testnet3 +- `5bd02cf` Log used config file to debug.log on startup +- `68ba85f` Updated Debian example bitcoin.conf with config from wiki + removed some cruft and updated comments +- `e5ee8f0` Remove -beta suffix +- `38405ac` Add comment regarding experimental-use service bits +- `be873f6` Issue warning if collecting RandSeed data failed +- `8ae973c` Allocate more space if necessary in RandSeedAddPerfMon +- `675bcd5` Correct comment for 15-of-15 p2sh script size +- `fda3fed` libsecp256k1 integration +- `2e36866` Show nodeid instead of addresses in log (for anonymity) unless otherwise requested +- `cd01a5e` Enable paranoid corruption checks in LevelDB >= 1.16 +- `9365937` Add comment about never updating nTimeOffset past 199 samples +- `403c1bf` contrib: remove getwork-based pyminer (as getwork API call has been removed) +- `0c3e101` contrib: Added systemd .service file in order to help distributions integrate bitcoind +- `0a0878d` doc: Add new DNSseed policy +- `2887bff` Update coding style and add .clang-format +- `5cbda4f` Changed LevelDB cursors to use scoped pointers to ensure destruction when going out of scope +- `b4a72a7` contrib/linearize: split output files based on new-timestamp-year or max-file-size +- `e982b57` Use explicit fflush() instead of setvbuf() +- `234bfbf` contrib: Add init scripts and docs for Upstart and OpenRC +- `01c2807` Add warning about the merkle-tree algorithm duplicate txid flaw +- `d6712db` Also create pid file in non-daemon mode +- `772ab0e` contrib: use batched JSON-RPC in linarize-hashes (optimization) +- `7ab4358` Update bash-completion for v0.10 +- `6e6a36c` contrib: show pull # in prompt for github-merge script +- `5b9f842` Upgrade leveldb to 1.18, make chainstate databases compatible between ARM and x86 (issue #2293) +- `4e7c219` Catch UTXO set read errors and shutdown +- `867c600` Catch LevelDB errors during flush +- `06ca065` Fix CScriptID(const CScript& in) in empty script case + +Credits +======= + +Thanks to everyone who contributed to this release: + +- 21E14 +- Adam Weiss +- Aitor Pazos +- Alexander Jeng +- Alex Morcos +- Alon Muroch +- Andreas Schildbach +- Andrew Poelstra +- Andy Alness +- Ashley Holman +- Benedict Chan +- Ben Holden-Crowther +- Bryan Bishop +- BtcDrak +- Christian von Roques +- Clinton Christian +- Cory Fields +- Cozz Lovan +- daniel +- Daniel Kraft +- David Hill +- Derek701 +- dexX7 +- dllud +- Dominyk Tiller +- Doug +- elichai +- elkingtowa +- ENikS +- Eric Shaw +- Federico Bond +- Francis GASCHET +- Gavin Andresen +- Giuseppe Mazzotta +- Glenn Willen +- Gregory Maxwell +- gubatron +- HarryWu +- himynameismartin +- Huang Le +- Ian Carroll +- imharrywu +- Jameson Lopp +- Janusz Lenar +- JaSK +- Jeff Garzik +- JL2035 +- Johnathan Corgan +- Jonas Schnelli +- jtimon +- Julian Haight +- Kamil Domanski +- kazcw +- kevin +- kiwigb +- Kosta Zertsekel +- LongShao007 +- Luke Dashjr +- Mark Friedenbach +- Mathy Vanvoorden +- Matt Corallo +- Matthew Bogosian +- Micha +- Michael Ford +- Mike Hearn +- mrbandrews +- mruddy +- ntrgn +- Otto Allmendinger +- paveljanik +- Pavel Vasin +- Peter Todd +- phantomcircuit +- Philip Kaufmann +- Pieter Wuille +- pryds +- randy-waterhouse +- R E Broadley +- Rose Toomey +- Ross Nicoll +- Roy Badami +- Ruben Dario Ponticelli +- Rune K. Svendsen +- Ryan X. Charles +- Saivann +- sandakersmann +- SergioDemianLerner +- shshshsh +- sinetek +- Stuart Cardall +- Suhas Daftuar +- Tawanda Kembo +- Teran McKinney +- tm314159 +- Tom Harding +- Trevin Hofmann +- Whit J +- Wladimir J. van der Laan +- Yoichi Hirai +- Zak Wilcox + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). + From 0df67f1f7ab4adfe9f0b3ba6276e737b37826464 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 31 Mar 2015 19:15:42 -0700 Subject: [PATCH 0359/2337] Simplify hash loop code --- src/miner.cpp | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index cf08b782296..44661fd13ef 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -365,33 +365,23 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& // // ScanHash scans nonces looking for a hash with at least some zero bits. -// The nonce is usually preserved between calls, but periodically or if the -// nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at -// zero. +// The nonce is usually preserved between calls, but periodically the block is +// rebuilt and nNonce starts over at zero. // -bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash) +bool static ScanHash(CBlockHeader *pblock, uint256 *phash) { - // Write the first 76 bytes of the block header to a double-SHA256 state. - CHash256 hasher; - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << *pblock; - assert(ss.size() == 80); - hasher.Write((unsigned char*)&ss[0], 76); - while (true) { - nNonce++; + pblock->nNonce++; - // Write the last 4 bytes of the block header (the nonce) to a copy of - // the double-SHA256 state, and compute the result. - CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash); + *phash = (CHashWriter(SER_GETHASH, 0) << *pblock).GetHash(); // Return the nonce if the hash has at least some zero bits, // caller will check if it has enough to reach the target if (((uint16_t*)phash)[15] == 0) return true; - // If nothing found after trying for a while, return -1 - if ((nNonce & 0xfff) == 0) + // If nothing found after trying for a while, return false. + if ((pblock->nNonce & 0xfff) == 0) return false; } } @@ -478,15 +468,13 @@ void static BitcoinMiner(CWallet *pwallet) int64_t nStart = GetTime(); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); uint256 hash; - uint32_t nNonce = 0; while (true) { // Check if something found - if (ScanHash(pblock, nNonce, &hash)) + if (ScanHash(pblock, &hash)) { if (UintToArith256(hash) <= hashTarget) { // Found a solution - pblock->nNonce = nNonce; assert(hash == pblock->GetHash()); SetThreadPriority(THREAD_PRIORITY_NORMAL); @@ -508,7 +496,7 @@ void static BitcoinMiner(CWallet *pwallet) // Regtest mode doesn't require peers if (vNodes.empty() && Params().MiningRequiresPeers()) break; - if (nNonce >= 0xffff0000) + if (pblock->nNonce >= 0xffff0000) break; if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60) break; From 6b04508e37c5dd18cec1cd61cc4356bd208aa991 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 31 Mar 2015 20:28:28 -0700 Subject: [PATCH 0360/2337] Introduce separate 'generate' RPC call --- qa/rpc-tests/bipdersig.py | 16 ++-- qa/rpc-tests/conflictedbalance.sh | 6 +- qa/rpc-tests/forknotify.py | 8 +- qa/rpc-tests/getblocktemplate_longpoll.py | 6 +- qa/rpc-tests/getblocktemplate_proposals.py | 2 +- qa/rpc-tests/getchaintips.py | 4 +- qa/rpc-tests/invalidateblock.py | 6 +- qa/rpc-tests/listtransactions.py | 2 +- qa/rpc-tests/mempool_coinbase_spends.py | 6 +- qa/rpc-tests/mempool_resurrect_test.py | 6 +- qa/rpc-tests/mempool_spendcoinbase.py | 2 +- qa/rpc-tests/receivedby.py | 6 +- qa/rpc-tests/rest.py | 2 +- qa/rpc-tests/smartfees.py | 6 +- qa/rpc-tests/txn_doublespend.py | 6 +- qa/rpc-tests/util.py | 2 +- qa/rpc-tests/wallet.py | 18 ++--- qa/rpc-tests/walletbackup.py | 12 +-- qa/rpc-tests/zapwallettxes.py | 6 +- src/miner.cpp | 86 ++++++++++++-------- src/miner.h | 2 + src/rpcclient.cpp | 1 + src/rpcmining.cpp | 91 ++++++++++------------ src/rpcserver.cpp | 1 + src/rpcserver.h | 1 + 25 files changed, 162 insertions(+), 142 deletions(-) diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py index 9f2cc846015..2c43bba8652 100755 --- a/qa/rpc-tests/bipdersig.py +++ b/qa/rpc-tests/bipdersig.py @@ -29,14 +29,14 @@ class BIP66Test(BitcoinTestFramework): cnt = self.nodes[0].getblockcount() # Mine some old-version blocks - self.nodes[1].setgenerate(True, 100) + self.nodes[1].generate(100) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 100): raise AssertionError("Failed to mine 100 version=2 blocks") # Mine 750 new-version blocks for i in xrange(15): - self.nodes[2].setgenerate(True, 50) + self.nodes[2].generate(50) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 850): raise AssertionError("Failed to mine 750 version=3 blocks") @@ -44,7 +44,7 @@ class BIP66Test(BitcoinTestFramework): # TODO: check that new DERSIG rules are not enforced # Mine 1 new-version block - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 851): raise AssertionFailure("Failed to mine a version=3 blocks") @@ -53,26 +53,26 @@ class BIP66Test(BitcoinTestFramework): # Mine 198 new-version blocks for i in xrange(2): - self.nodes[2].setgenerate(True, 99) + self.nodes[2].generate(99) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1049): raise AssertionError("Failed to mine 198 version=3 blocks") # Mine 1 old-version block - self.nodes[1].setgenerate(True, 1) + self.nodes[1].generate(1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1050): raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks") # Mine 1 new-version blocks - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1051): raise AssertionError("Failed to mine a version=3 block") # Mine 1 old-version blocks try: - self.nodes[1].setgenerate(True, 1) + self.nodes[1].generate(1) raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks") except JSONRPCException: pass @@ -81,7 +81,7 @@ class BIP66Test(BitcoinTestFramework): raise AssertionError("Accepted a version=2 block after 950 version=3 blocks") # Mine 1 new-version blocks - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1052): raise AssertionError("Failed to mine a version=3 block") diff --git a/qa/rpc-tests/conflictedbalance.sh b/qa/rpc-tests/conflictedbalance.sh index a112244c744..3b6c8dc318c 100755 --- a/qa/rpc-tests/conflictedbalance.sh +++ b/qa/rpc-tests/conflictedbalance.sh @@ -84,11 +84,11 @@ WaitPeers "$B1ARGS" 1 # 2 block, 50 XBT each == 100 XBT # These will be transactions "A" and "B" -$CLI $B1ARGS setgenerate true 2 +$CLI $B1ARGS generate 2 WaitBlocks # 100 blocks, 0 mature == 0 XBT -$CLI $B2ARGS setgenerate true 100 +$CLI $B2ARGS generate 100 WaitBlocks CheckBalance "$B1ARGS" 100 @@ -130,7 +130,7 @@ WaitPeers "$B1ARGS" 1 # Having B2 mine the next block puts the mutated # transaction C in the chain: -$CLI $B2ARGS setgenerate true 1 +$CLI $B2ARGS generate 1 WaitBlocks # B1 should still be able to spend 100, because D is conflicted diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index ad2a748ca11..af22ffb1a51 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -34,12 +34,12 @@ class ForkNotifyTest(BitcoinTestFramework): def run_test(self): # Mine 51 up-version blocks - self.nodes[1].setgenerate(True, 51) + self.nodes[1].generate(51) self.sync_all() # -alertnotify should trigger on the 51'st, # but mine and sync another to give # -alertnotify time to write - self.nodes[1].setgenerate(True, 1) + self.nodes[1].generate(1) self.sync_all() with open(self.alert_filename, 'r') as f: @@ -49,9 +49,9 @@ class ForkNotifyTest(BitcoinTestFramework): raise AssertionError("-alertnotify did not warn of up-version blocks") # Mine more up-version blocks, should not get more alerts: - self.nodes[1].setgenerate(True, 1) + self.nodes[1].generate(1) self.sync_all() - self.nodes[1].setgenerate(True, 1) + self.nodes[1].generate(1) self.sync_all() with open(self.alert_filename, 'r') as f: diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py index b749b260b76..64fe49b8359 100755 --- a/qa/rpc-tests/getblocktemplate_longpoll.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -51,7 +51,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework): def run_test(self): print "Warning: this test will take about 70 seconds in the best case. Be patient." - self.nodes[0].setgenerate(True, 10) + self.nodes[0].generate(10) templat = self.nodes[0].getblocktemplate() longpollid = templat['longpollid'] # longpollid should not change between successive invocations if nothing else happens @@ -66,7 +66,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework): assert(thr.is_alive()) # Test 2: test that longpoll will terminate if another node generates a block - self.nodes[1].setgenerate(True, 1) # generate a block on another node + self.nodes[1].generate(1) # generate a block on another node # check that thread will exit now that new transaction entered mempool thr.join(5) # wait 5 seconds or until thread exits assert(not thr.is_alive()) @@ -74,7 +74,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework): # Test 3: test that longpoll will terminate if we generate a block ourselves thr = LongpollThread(self.nodes[0]) thr.start() - self.nodes[0].setgenerate(True, 1) # generate a block on another node + self.nodes[0].generate(1) # generate a block on another node thr.join(5) # wait 5 seconds or until thread exits assert(not thr.is_alive()) diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index f65162002d2..a63f456d6bf 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -95,7 +95,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework): def run_test(self): node = self.nodes[0] - node.setgenerate(True, 1) # Mine a block to leave initial block download + node.generate(1) # Mine a block to leave initial block download tmpl = node.getblocktemplate() if 'coinbasetxn' not in tmpl: rawcoinbase = encodeUNum(tmpl['height']) diff --git a/qa/rpc-tests/getchaintips.py b/qa/rpc-tests/getchaintips.py index 84fe102d812..83a95372852 100755 --- a/qa/rpc-tests/getchaintips.py +++ b/qa/rpc-tests/getchaintips.py @@ -23,8 +23,8 @@ class GetChainTipsTest (BitcoinTestFramework): # Split the network and build two chains of different lengths. self.split_network () - self.nodes[0].setgenerate (True, 10); - self.nodes[2].setgenerate (True, 20); + self.nodes[0].generate(10); + self.nodes[2].generate(20); self.sync_all () tips = self.nodes[1].getchaintips () diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py index ccfcf00e30e..fd8a8e57856 100755 --- a/qa/rpc-tests/invalidateblock.py +++ b/qa/rpc-tests/invalidateblock.py @@ -28,12 +28,12 @@ class InvalidateTest(BitcoinTestFramework): def run_test(self): print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:" print "Mine 4 blocks on Node 0" - self.nodes[0].setgenerate(True, 4) + self.nodes[0].generate(4) assert(self.nodes[0].getblockcount() == 4) besthash = self.nodes[0].getbestblockhash() print "Mine competing 6 blocks on Node 1" - self.nodes[1].setgenerate(True, 6) + self.nodes[1].generate(6) assert(self.nodes[1].getblockcount() == 6) print "Connect nodes to force a reorg" @@ -61,7 +61,7 @@ class InvalidateTest(BitcoinTestFramework): self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3)) assert(self.nodes[2].getblockcount() == 2) print "..and then mine a block" - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) print "Verify all nodes are at the right height" time.sleep(5) for i in xrange(3): diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 8ee9d66a29e..11e3635c043 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -44,7 +44,7 @@ class ListTransactionsTest(BitcoinTestFramework): {"txid":txid}, {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0}) # mine a block, confirmations should change: - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) self.sync_all() check_array_result(self.nodes[0].listtransactions(), {"txid":txid}, diff --git a/qa/rpc-tests/mempool_coinbase_spends.py b/qa/rpc-tests/mempool_coinbase_spends.py index 7b43712768b..853d031de4a 100755 --- a/qa/rpc-tests/mempool_coinbase_spends.py +++ b/qa/rpc-tests/mempool_coinbase_spends.py @@ -41,7 +41,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # Mine three blocks. After this, nodes[0] blocks # 101, 102, and 103 are spend-able. - new_blocks = self.nodes[1].setgenerate(True, 4) + new_blocks = self.nodes[1].generate(4) self.sync_all() node0_address = self.nodes[0].getnewaddress() @@ -62,7 +62,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # Broadcast and mine spend_102 and 103: spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw) spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw) - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) # Create 102_1 and 103_1: spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50) @@ -70,7 +70,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # Broadcast and mine 103_1: spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) # ... now put spend_101 and spend_102_1 in memory pools: spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw) diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 81db812bfc3..6f7f577e36c 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -51,12 +51,12 @@ class MempoolCoinbaseTest(BitcoinTestFramework): spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ] blocks = [] - blocks.extend(self.nodes[0].setgenerate(True, 1)) + blocks.extend(self.nodes[0].generate(1)) spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ] spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ] - blocks.extend(self.nodes[0].setgenerate(True, 1)) + blocks.extend(self.nodes[0].generate(1)) # mempool should be empty, all txns confirmed assert_equal(set(self.nodes[0].getrawmempool()), set()) @@ -76,7 +76,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework): assert(tx["confirmations"] == 0) # Generate another block, they should all get mined - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) # mempool should be empty, all txns confirmed assert_equal(set(self.nodes[0].getrawmempool()), set()) for txid in spends1_id+spends2_id: diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index f0b34f2904f..ab5817c869a 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -58,7 +58,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework): assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ]) # mine a block, spend_101 should get confirmed - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) assert_equal(set(self.nodes[0].getrawmempool()), set()) # ... and now height 102 can be spent: diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index d3504e0920e..1a681e1aaee 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -69,7 +69,7 @@ class ReceivedByTest(BitcoinTestFramework): { }, True) #Bury Tx under 10 block so it will be returned by listreceivedbyaddress - self.nodes[1].setgenerate(True, 10) + self.nodes[1].generate(10) self.sync_all() check_array_result(self.nodes[1].listreceivedbyaddress(), {"address":addr}, @@ -106,7 +106,7 @@ class ReceivedByTest(BitcoinTestFramework): raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance)) #Bury Tx under 10 block so it will be returned by the default getreceivedbyaddress - self.nodes[1].setgenerate(True, 10) + self.nodes[1].generate(10) self.sync_all() balance = self.nodes[1].getreceivedbyaddress(addr) if balance != Decimal("0.1"): @@ -136,7 +136,7 @@ class ReceivedByTest(BitcoinTestFramework): if balance != balance_by_account: raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance)) - self.nodes[1].setgenerate(True, 10) + self.nodes[1].generate(10) self.sync_all() # listreceivedbyaccount should return updated account balance check_array_result(self.nodes[1].listreceivedbyaccount(), diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index a9d41cf3672..9b7008531cb 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -90,7 +90,7 @@ class RESTTest (BitcoinTestFramework): self.sync_all() # now mine the transactions - newblockhash = self.nodes[1].setgenerate(True, 1) + newblockhash = self.nodes[1].generate(1) self.sync_all() #check if the 3 tx show up in the new block diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 0c07ef8a53d..4eb8bb4842d 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -51,7 +51,7 @@ class EstimateFeeTest(BitcoinTestFramework): # Mine blocks with node2 until the memory pool clears: count_start = self.nodes[2].getblockcount() while len(self.nodes[2].getrawmempool()) > 0: - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) self.sync_all() all_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ] @@ -70,7 +70,7 @@ class EstimateFeeTest(BitcoinTestFramework): Decimal("0.0"), min_fee, 20) tx_kbytes = (len(txhex)/2)/1000.0 fees_per_kb.append(float(fee)/tx_kbytes) - self.nodes[1].setgenerate(True, 1) + self.nodes[1].generate(1) self.sync_all() all_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ] @@ -81,7 +81,7 @@ class EstimateFeeTest(BitcoinTestFramework): # Finish by mining a normal-sized block: while len(self.nodes[0].getrawmempool()) > 0: - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) self.sync_all() final_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ] diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index 942d9fc66c1..fe9168944bc 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -58,7 +58,7 @@ class TxnMallTest(BitcoinTestFramework): # Have node0 mine a block: if (self.options.mine_block): - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) sync_blocks(self.nodes[0:2]) tx1 = self.nodes[0].gettransaction(txid1) @@ -88,11 +88,11 @@ class TxnMallTest(BitcoinTestFramework): # Now give doublespend to miner: mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"]) # ... mine a block... - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) # Reconnect the split network, and sync chain: connect_nodes(self.nodes[1], 2) - self.nodes[2].setgenerate(True, 1) # Mine another block to make sure we sync + self.nodes[2].generate(1) # Mine another block to make sure we sync sync_blocks(self.nodes) # Re-fetch transaction info: diff --git a/qa/rpc-tests/util.py b/qa/rpc-tests/util.py index ec65f783e8f..9ecee31959a 100644 --- a/qa/rpc-tests/util.py +++ b/qa/rpc-tests/util.py @@ -109,7 +109,7 @@ def initialize_chain(test_dir): for peer in range(4): for j in range(25): set_node_times(rpcs, block_time) - rpcs[peer].setgenerate(True, 1) + rpcs[peer].generate(1) block_time += 10*60 # Must sync before next peer starts generating blocks sync_blocks(rpcs) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 01e9fa57b29..7616625b8a8 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -40,14 +40,14 @@ class WalletTest (BitcoinTestFramework): def run_test (self): print "Mining blocks..." - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) walletinfo = self.nodes[0].getwalletinfo() assert_equal(walletinfo['immature_balance'], 50) assert_equal(walletinfo['balance'], 0) self.sync_all() - self.nodes[1].setgenerate(True, 101) + self.nodes[1].generate(101) self.sync_all() assert_equal(self.nodes[0].getbalance(), 50) @@ -63,11 +63,11 @@ class WalletTest (BitcoinTestFramework): assert_equal(walletinfo['immature_balance'], 0) # Have node0 mine a block, thus they will collect their own fee. - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) self.sync_all() # Have node1 generate 100 blocks (so node0 can recover the fee) - self.nodes[1].setgenerate(True, 100) + self.nodes[1].generate(100) self.sync_all() # node0 should end up with 100 btc in block rewards plus fees, but @@ -96,7 +96,7 @@ class WalletTest (BitcoinTestFramework): self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], True) # Have node1 mine a block to confirm transactions: - self.nodes[1].setgenerate(True, 1) + self.nodes[1].generate(1) self.sync_all() assert_equal(self.nodes[0].getbalance(), 0) @@ -107,28 +107,28 @@ class WalletTest (BitcoinTestFramework): address = self.nodes[0].getnewaddress("test") self.nodes[2].settxfee(Decimal('0.001')) txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) self.sync_all() assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000')) assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000')) # Send 10 BTC with subtract fee from amount txid = self.nodes[2].sendtoaddress(address, 10, "", "", True) - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) self.sync_all() assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000')) assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000')) # Sendmany 10 BTC txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", []) - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) self.sync_all() assert_equal(self.nodes[2].getbalance(), Decimal('69.99800000')) assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000')) # Sendmany 10 BTC with subtract fee from amount txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address]) - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) self.sync_all() assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')) assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000')) diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index 049697c2db5..b9fc8622341 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -77,7 +77,7 @@ class WalletBackupTest(BitcoinTestFramework): # Have the miner (node3) mine a block. # Must sync mempools before mining. sync_mempools(self.nodes) - self.nodes[3].setgenerate(True, 1) + self.nodes[3].generate(1) # As above, this mirrors the original bash test. def start_three(self): @@ -101,13 +101,13 @@ class WalletBackupTest(BitcoinTestFramework): def run_test(self): logging.info("Generating initial blockchain") - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) sync_blocks(self.nodes) - self.nodes[1].setgenerate(True, 1) + self.nodes[1].generate(1) sync_blocks(self.nodes) - self.nodes[2].setgenerate(True, 1) + self.nodes[2].generate(1) sync_blocks(self.nodes) - self.nodes[3].setgenerate(True, 100) + self.nodes[3].generate(100) sync_blocks(self.nodes) assert_equal(self.nodes[0].getbalance(), 50) @@ -134,7 +134,7 @@ class WalletBackupTest(BitcoinTestFramework): self.do_one_round() # Generate 101 more blocks, so any fees paid mature - self.nodes[3].setgenerate(True, 101) + self.nodes[3].generate(101) self.sync_all() balance0 = self.nodes[0].getbalance() diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py index a773575906f..045614e94c3 100755 --- a/qa/rpc-tests/zapwallettxes.py +++ b/qa/rpc-tests/zapwallettxes.py @@ -23,9 +23,9 @@ class ZapWalletTXesTest (BitcoinTestFramework): def run_test (self): print "Mining blocks..." - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) self.sync_all() - self.nodes[1].setgenerate(True, 101) + self.nodes[1].generate(101) self.sync_all() assert_equal(self.nodes[0].getbalance(), 50) @@ -33,7 +33,7 @@ class ZapWalletTXesTest (BitcoinTestFramework): txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) self.sync_all() - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) self.sync_all() txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) diff --git a/src/miner.cpp b/src/miner.cpp index 44661fd13ef..fdbc47a1c32 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -372,8 +372,7 @@ bool static ScanHash(CBlockHeader *pblock, uint256 *phash) { while (true) { pblock->nNonce++; - - *phash = (CHashWriter(SER_GETHASH, 0) << *pblock).GetHash(); + *phash = pblock->GetHash(); // Return the nonce if the hash has at least some zero bits, // caller will check if it has enough to reach the target @@ -425,6 +424,56 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese return true; } +bool static ScanLoop(CBlock *pblock, CBlockIndex *pindexPrev, CWallet *pwallet, CReserveKey& reservekey) +{ + UpdateTime(pblock, pindexPrev); + arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); + + uint256 hash; + if (ScanHash(pblock, &hash)) { + if (UintToArith256(hash) <= hashTarget) { + // Found a solution + SetThreadPriority(THREAD_PRIORITY_NORMAL); + LogPrintf("BitcoinMiner:\n"); + LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex()); + ProcessBlockFound(pblock, *pwallet, reservekey); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + + return true; + } + } + + return false; +} + +bool MineBlock(CWallet *pwallet, uint256& hash) +{ + CReserveKey reservekey(pwallet); + unsigned int nExtraNonce = 0; + + while (true) { + CBlockIndex *pindexPrev = chainActive.Tip(); // Actually needs cs_main... + + auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); + if (!pblocktemplate.get()) { + return false; + } + + CBlock *pblock = &pblocktemplate->block; + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); + + while (true) { + if (ScanLoop(pblock, pindexPrev, pwallet, reservekey)) { + hash = pblock->GetHash(); + return true; + } + boost::this_thread::interruption_point(); + if (pblock->nNonce >= 0xffff0000) + break; + } + } +} + void static BitcoinMiner(CWallet *pwallet) { LogPrintf("BitcoinMiner started\n"); @@ -448,7 +497,7 @@ void static BitcoinMiner(CWallet *pwallet) // Create new block // unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrev = chainActive.Tip(); + CBlockIndex* pindexPrev = chainActive.Tip(); // Actually needs cs_main... auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); if (!pblocktemplate.get()) @@ -466,30 +515,10 @@ void static BitcoinMiner(CWallet *pwallet) // Search // int64_t nStart = GetTime(); - arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); - uint256 hash; while (true) { // Check if something found - if (ScanHash(pblock, &hash)) - { - if (UintToArith256(hash) <= hashTarget) - { - // Found a solution - assert(hash == pblock->GetHash()); - - SetThreadPriority(THREAD_PRIORITY_NORMAL); - LogPrintf("BitcoinMiner:\n"); - LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex()); - ProcessBlockFound(pblock, *pwallet, reservekey); - SetThreadPriority(THREAD_PRIORITY_LOWEST); - - // In regression test mode, stop mining after a block is found. - if (Params().MineBlocksOnDemand()) - throw boost::thread_interrupted(); - - break; - } - } + if (ScanLoop(pblock, pindexPrev, pwallet, reservekey)) + break; // Check for stop or if block needs to be rebuilt boost::this_thread::interruption_point(); @@ -503,13 +532,6 @@ void static BitcoinMiner(CWallet *pwallet) if (pindexPrev != chainActive.Tip()) break; - // Update nTime every few seconds - UpdateTime(pblock, pindexPrev); - if (Params().AllowMinDifficultyBlocks()) - { - // Changing pblock->nTime can change work required on testnet: - hashTarget.SetCompact(pblock->nBits); - } } } } diff --git a/src/miner.h b/src/miner.h index 5d5c9c86c7c..549658ec171 100644 --- a/src/miner.h +++ b/src/miner.h @@ -24,6 +24,8 @@ struct CBlockTemplate /** Run the miner threads */ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); +/** Create a single block */ +bool MineBlock(CWallet *pwallet, uint256& hash); /** Generate a new block, without valid proof-of-work */ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index a45ea9839be..428e1049dc1 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -29,6 +29,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getaddednodeinfo", 0 }, { "setgenerate", 0 }, { "setgenerate", 1 }, + { "generate", 0 }, { "getnetworkhashps", 0 }, { "getnetworkhashps", 1 }, { "sendtoaddress", 1 }, diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index fcba7e222d5..49c5c3ca583 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -113,6 +113,45 @@ Value getgenerate(const Array& params, bool fHelp) return GetBoolArg("-gen", false); } +Value generate(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1) + throw runtime_error( + "generate numblocks\n" + "\nMine blocks immediately (before the RPC call returns)\n" + "1. numblocks (numeric) How many blocks are generated immediately.\n" + "\nResult\n" + "[ blockhashes ] (array) hashes of blocks generated\n" + "\nExamples:\n" + "\nGenerate 11 blocks\n" + + HelpExampleCli("generate", "11") + ); + + if (pwalletMain == NULL) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); + + int nHeightStart = 0; + int nHeightEnd = 0; + int nHeight = 0; + int nGenerate = params[0].get_int(); + + { // Don't keep cs_main locked + LOCK(cs_main); + nHeightStart = chainActive.Height(); + nHeight = nHeightStart; + nHeightEnd = nHeightStart+nGenerate; + } + Array blockHashes; + while (nHeight < nHeightEnd) { + uint256 hash; + if (!MineBlock(pwalletMain, hash)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); + + ++nHeight; + blockHashes.push_back(hash.GetHex()); + } + return blockHashes; +} Value setgenerate(const Array& params, bool fHelp) { @@ -125,9 +164,6 @@ Value setgenerate(const Array& params, bool fHelp) "\nArguments:\n" "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n" "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n" - " Note: in -regtest mode, genproclimit controls how many blocks are generated immediately.\n" - "\nResult\n" - "[ blockhashes ] (array, -regtest only) hashes of blocks generated\n" "\nExamples:\n" "\nSet the generation on with a limit of one processor\n" + HelpExampleCli("setgenerate", "true 1") + @@ -154,52 +190,9 @@ Value setgenerate(const Array& params, bool fHelp) fGenerate = false; } - // -regtest mode: don't return until nGenProcLimit blocks are generated - if (fGenerate && Params().MineBlocksOnDemand()) - { - int nHeightStart = 0; - int nHeightEnd = 0; - int nHeight = 0; - int nGenerate = (nGenProcLimit > 0 ? nGenProcLimit : 1); - CReserveKey reservekey(pwalletMain); - - { // Don't keep cs_main locked - LOCK(cs_main); - nHeightStart = chainActive.Height(); - nHeight = nHeightStart; - nHeightEnd = nHeightStart+nGenerate; - } - unsigned int nExtraNonce = 0; - Array blockHashes; - while (nHeight < nHeightEnd) - { - auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); - if (!pblocktemplate.get()) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); - CBlock *pblock = &pblocktemplate->block; - { - LOCK(cs_main); - IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); - } - while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { - // Yes, there is a chance every nonce could fail to satisfy the -regtest - // target -- 1 in 2^(2^32). That ain't gonna happen. - ++pblock->nNonce; - } - CValidationState state; - if (!ProcessNewBlock(state, NULL, pblock)) - throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); - ++nHeight; - blockHashes.push_back(pblock->GetHash().GetHex()); - } - return blockHashes; - } - else // Not -regtest: start generate thread, return immediately - { - mapArgs["-gen"] = (fGenerate ? "1" : "0"); - mapArgs ["-genproclimit"] = itostr(nGenProcLimit); - GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit); - } + mapArgs["-gen"] = (fGenerate ? "1" : "0"); + mapArgs ["-genproclimit"] = itostr(nGenProcLimit); + GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit); return Value::null; } diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index d30fa32eb47..0fd7769a199 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -312,6 +312,7 @@ static const CRPCCommand vRPCCommands[] = /* Coin generation */ { "generating", "getgenerate", &getgenerate, true, false }, { "generating", "setgenerate", &setgenerate, true, false }, + { "generating", "generate", &generate, true, false }, #endif /* Raw transactions */ diff --git a/src/rpcserver.h b/src/rpcserver.h index 7011d41fc1b..e7aaed8bdff 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -162,6 +162,7 @@ extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fH extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value generate(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp); From e2edf95cd3f43331843676e49a82830128a95050 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 31 Mar 2015 20:35:04 -0700 Subject: [PATCH 0361/2337] Bugfix: make CreateNewBlock return pindexPrev --- src/miner.cpp | 16 ++++++++-------- src/miner.h | 4 ++-- src/rpcmining.cpp | 4 ++-- src/test/miner_tests.cpp | 27 ++++++++++++++------------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index fdbc47a1c32..7f01918eeff 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -87,7 +87,7 @@ void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); } -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) +CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev) { // Create new block auto_ptr pblocktemplate(new CBlockTemplate()); @@ -132,7 +132,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { LOCK2(cs_main, mempool.cs); - CBlockIndex* pindexPrev = chainActive.Tip(); + pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; CCoinsViewCache view(pcoinsTip); @@ -385,14 +385,14 @@ bool static ScanHash(CBlockHeader *pblock, uint256 *phash) } } -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CBlockIndex*& pindexPrev) { CPubKey pubkey; if (!reservekey.GetReservedKey(pubkey)) return NULL; CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; - return CreateNewBlock(scriptPubKey); + return CreateNewBlock(scriptPubKey, pindexPrev); } static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) @@ -452,9 +452,9 @@ bool MineBlock(CWallet *pwallet, uint256& hash) unsigned int nExtraNonce = 0; while (true) { - CBlockIndex *pindexPrev = chainActive.Tip(); // Actually needs cs_main... + CBlockIndex *pindexPrev; - auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); + auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev)); if (!pblocktemplate.get()) { return false; } @@ -497,9 +497,9 @@ void static BitcoinMiner(CWallet *pwallet) // Create new block // unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrev = chainActive.Tip(); // Actually needs cs_main... + CBlockIndex* pindexPrev; - auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); + auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev)); if (!pblocktemplate.get()) { LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); diff --git a/src/miner.h b/src/miner.h index 549658ec171..00ad299512f 100644 --- a/src/miner.h +++ b/src/miner.h @@ -27,8 +27,8 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); /** Create a single block */ bool MineBlock(CWallet *pwallet, uint256& hash); /** Generate a new block, without valid proof-of-work */ -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); +CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev); +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CBlockIndex*& pindexPrev); /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 49c5c3ca583..6f165028d5e 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -475,7 +475,7 @@ Value getblocktemplate(const Array& params, bool fHelp) // Store the pindexBest used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrevNew = chainActive.Tip(); + CBlockIndex* pindexPrevNew; nStart = GetTime(); // Create new block @@ -485,7 +485,7 @@ Value getblocktemplate(const Array& params, bool fHelp) pblocktemplate = NULL; } CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = CreateNewBlock(scriptDummy); + pblocktemplate = CreateNewBlock(scriptDummy, pindexPrevNew); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 6ab9cb8a440..27c0a08de9d 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -62,7 +62,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) Checkpoints::fEnabled = false; // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + CBlockIndex* pindexPrev; + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) @@ -90,7 +91,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) delete pblocktemplate; // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; // block sigops > limit: 1000 CHECKMULTISIG + 1 @@ -108,7 +109,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -128,14 +129,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); // orphan in mempool hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -153,7 +154,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 5900000000LL; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -164,7 +165,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 0; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -182,7 +183,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue -= 1000000; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -196,17 +197,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); // subsidy changing int nHeight = chainActive.Height(); chainActive.Tip()->nHeight = 209999; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; chainActive.Tip()->nHeight = 210000; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; chainActive.Tip()->nHeight = nHeight; @@ -238,7 +239,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); BOOST_CHECK(!IsFinalTx(tx2)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); // Neither tx should have make it into the template. BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); @@ -251,7 +252,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 1)); BOOST_CHECK(IsFinalTx(tx2)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); delete pblocktemplate; From ede379f780b8b976be5e44ce0d8019d59e8829d6 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 1 Apr 2015 13:12:50 -0400 Subject: [PATCH 0362/2337] Add additional block index consistency checks This adds more tests to CheckBlockIndex: - HAVE_DATA is true iff nTx > 0 - BLOCK_VALID_TRANSACTIONS is true iff nTx > 0 - BLOCK_VALID_TRANSACTIONS is true for a block and all parents iff nChainTx > 0 --- src/main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 011016204e4..7da190bdf03 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3248,6 +3248,7 @@ void static CheckBlockIndex() CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid. CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA. CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not). + CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not). CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not). CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not). while (pindex != NULL) { @@ -3255,6 +3256,7 @@ void static CheckBlockIndex() if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex; if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex; if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex; + if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex; if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex; if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex; @@ -3264,7 +3266,12 @@ void static CheckBlockIndex() assert(pindex->GetBlockHash() == Params().HashGenesisBlock()); // Genesis block's hash must match. assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block. } + // HAVE_DATA is equivalent to VALID_TRANSACTIONS and equivalent to nTx > 0 (we stored the number of transactions in the block) + assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0)); + assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); + // All parents having data is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set. assert((pindexFirstMissing != NULL) == (pindex->nChainTx == 0)); // nChainTx == 0 is used to signal that all parent block's transaction data is available. + assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0)); assert(pindex->nHeight == nHeight); // nHeight must be consistent. assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's. assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks. @@ -3320,6 +3327,7 @@ void static CheckBlockIndex() if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL; if (pindex == pindexFirstMissing) pindexFirstMissing = NULL; if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL; + if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL; if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL; if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL; // Find our parent. From 00dcaf4bebb6e238b5711530a8a5e4f8fdb6b455 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 12 Jan 2015 09:55:48 -0500 Subject: [PATCH 0363/2337] Change download logic to allow calling getheaders/getdata on inbound peers SendMessages will now call getheaders on both inbound and outbound peers, once the headers chain is close to synced. It will also try downloading blocks from inbound peers once we're out of initial block download (so inbound peers will participate in parallel block fetching for the last day or two of blocks being downloaded). --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 3ceacf32e7f..a741115932e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4459,9 +4459,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (pindexBestHeader == NULL) pindexBestHeader = chainActive.Tip(); bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do. - if (!state.fSyncStarted && !pto->fClient && fFetch && !fImporting && !fReindex) { + if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) { // Only actively request headers from a single peer, unless we're close to today. - if (nSyncStarted == 0 || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) { + if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) { state.fSyncStarted = true; nSyncStarted++; CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader; @@ -4549,7 +4549,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // Message: getdata (blocks) // vector vGetData; - if (!pto->fDisconnect && !pto->fClient && fFetch && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vector vToDownload; NodeId staller = -1; FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller); From 5ff94c630e33e0a2b95aa374eb5f5375ba6b19ba Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 2 Apr 2015 17:15:29 -0700 Subject: [PATCH 0364/2337] Add git-subtree-check.sh script --- contrib/devtools/README.md | 13 +++++ contrib/devtools/git-subtree-check.sh | 74 +++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100755 contrib/devtools/git-subtree-check.sh diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 40495cce8b1..f90afa7f20d 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -81,3 +81,16 @@ It will do the following automatically: See doc/translation-process.md for more information. +git-subtree-check.sh +==================== + +Run this script from the root of the repository to verify that a subtree matches the contents of +the commit it claims to have been updated to. + +To use, make sure that you have fetched the upstream repository branch in which the subtree is +maintained: +* for src/secp256k1: https://github.com/bitcoin/secp256k1.git (branch master) +* for sec/leveldb: https://github.com/bitcoin/leveldb.git (branch bitcoin-fork) + +Usage: git-subtree-check.sh DIR COMMIT +COMMIT may be omitted, in which case HEAD is used. diff --git a/contrib/devtools/git-subtree-check.sh b/contrib/devtools/git-subtree-check.sh new file mode 100755 index 00000000000..1cb82fe6826 --- /dev/null +++ b/contrib/devtools/git-subtree-check.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +DIR="$1" +COMMIT="$2" +if [ -z "$COMMIT" ]; then + COMMIT=HEAD +fi + +# Taken from git-subtree (Copyright (C) 2009 Avery Pennarun ) +find_latest_squash() +{ + dir="$1" + sq= + main= + sub= + git log --grep="^git-subtree-dir: $dir/*\$" \ + --pretty=format:'START %H%n%s%n%n%b%nEND%n' "$COMMIT" | + while read a b junk; do + case "$a" in + START) sq="$b" ;; + git-subtree-mainline:) main="$b" ;; + git-subtree-split:) sub="$b" ;; + END) + if [ -n "$sub" ]; then + if [ -n "$main" ]; then + # a rejoin commit? + # Pretend its sub was a squash. + sq="$sub" + fi + echo "$sq" "$sub" + break + fi + sq= + main= + sub= + ;; + esac + done +} + +latest_squash="$(find_latest_squash "$DIR")" +if [ -z "$latest_squash" ]; then + echo "ERROR: $DIR is not a subtree" >&2 + exit 2 +fi + +set $latest_squash +old=$1 +rev=$2 +if [ "d$(git cat-file -t $rev 2>/dev/null)" != dcommit ]; then + echo "ERROR: subtree commit $rev unavailable. Fetch/update the subtree repository" >&2 + exit 2 +fi +tree_subtree=$(git show -s --format="%T" $rev) +echo "$DIR in $COMMIT was last updated to upstream commit $rev (tree $tree_subtree)" +tree_actual=$(git ls-tree -d "$COMMIT" "$DIR" | head -n 1) +if [ -z "$tree_actual" ]; then + echo "FAIL: subtree directory $DIR not found in $COMMIT" >&2 + exit 1 +fi +set $tree_actual +tree_actual_type=$2 +tree_actual_tree=$3 +echo "$DIR in $COMMIT currently refers to $tree_actual_type $tree_actual_tree" +if [ "d$tree_actual_type" != "dtree" ]; then + echo "FAIL: subtree directory $DIR is not a tree in $COMMIT" >&2 + exit 1 +fi +if [ "$tree_actual_tree" != "$tree_subtree" ]; then + git diff-tree $tree_actual_tree $tree_subtree >&2 + echo "FAIL: subtree directory tree doesn't match subtree commit tree" >&2 + exit 1 +fi +echo "GOOD" From 2dc679d22f821d26a9f8a7eef6d095ef21d1b27c Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Fri, 3 Apr 2015 07:51:31 +0200 Subject: [PATCH 0365/2337] Docs: Use new Bitcoin.org download URLs --- doc/release-process.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/doc/release-process.md b/doc/release-process.md index 016090c5949..5dad9bf5dee 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -133,15 +133,22 @@ rm SHA256SUMS Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spurious/nonsensical entry. - Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoin.org server + into `/var/www/bin/bitcoin-core-${VERSION}` - Update bitcoin.org version - - Make a pull request to add a file named `YYYY-MM-DD-vX.Y.Z.md` with the release notes - to https://github.com/bitcoin/bitcoin.org/tree/master/_releases - ([Example for 0.9.2.1](https://raw.githubusercontent.com/bitcoin/bitcoin.org/master/_releases/2014-06-19-v0.9.2.1.md)). + - First, check to see if the Bitcoin.org maintainers have prepared a + release: https://github.com/bitcoin/bitcoin.org/labels/Releases - - After the pull request is merged, the website will automatically show the newest version, as well - as update the OS download links. Ping Saivann in case anything goes wrong + - If they have, it will have previously failed their Travis CI + checks because the final release files weren't uploaded. + Trigger a Travis CI rebuild---if it passes, merge. + + - If they have not prepared a release, follow the Bitcoin.org release + instructions: https://github.com/bitcoin/bitcoin.org#release-notes + + - After the pull request is merged, the website will automatically show the newest version within 15 minutes, as well + as update the OS download links. Ping @saivann/@harding (saivann/harding on Freenode) in case anything goes wrong - Announce the release: From f14e687feb554e64bf38715c001da0c0954be694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Fri, 3 Apr 2015 17:42:06 +0200 Subject: [PATCH 0366/2337] Chainparams: Decouple CAlert from CChainParams --- src/alert.cpp | 9 ++++----- src/alert.h | 4 ++-- src/main.cpp | 2 +- src/test/alert_tests.cpp | 7 +++++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/alert.cpp b/src/alert.cpp index 323939913b7..aa7ac748dad 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -5,7 +5,6 @@ #include "alert.h" -#include "chainparams.h" #include "clientversion.h" #include "net.h" #include "pubkey.h" @@ -145,9 +144,9 @@ bool CAlert::RelayTo(CNode* pnode) const return false; } -bool CAlert::CheckSignature() const +bool CAlert::CheckSignature(const std::vector& alertKey) const { - CPubKey key(Params().AlertKey()); + CPubKey key(alertKey); if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) return error("CAlert::CheckSignature(): verify signature failed"); @@ -169,9 +168,9 @@ CAlert CAlert::getAlertByHash(const uint256 &hash) return retval; } -bool CAlert::ProcessAlert(bool fThread) +bool CAlert::ProcessAlert(const std::vector& alertKey, bool fThread) { - if (!CheckSignature()) + if (!CheckSignature(alertKey)) return false; if (!IsInEffect()) return false; diff --git a/src/alert.h b/src/alert.h index af42171af5b..746967c4aff 100644 --- a/src/alert.h +++ b/src/alert.h @@ -100,8 +100,8 @@ public: bool AppliesTo(int nVersion, std::string strSubVerIn) const; bool AppliesToMe() const; bool RelayTo(CNode* pnode) const; - bool CheckSignature() const; - bool ProcessAlert(bool fThread = true); // fThread means run -alertnotify in a free-running thread + bool CheckSignature(const std::vector& alertKey) const; + bool ProcessAlert(const std::vector& alertKey, bool fThread = true); // fThread means run -alertnotify in a free-running thread static void Notify(const std::string& strMessage, bool fThread); /* diff --git a/src/main.cpp b/src/main.cpp index 011016204e4..bd424b18264 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4262,7 +4262,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, uint256 alertHash = alert.GetHash(); if (pfrom->setKnown.count(alertHash) == 0) { - if (alert.ProcessAlert()) + if (alert.ProcessAlert(Params().AlertKey())) { // Relay pfrom->setKnown.insert(alertHash); diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 5e1f5f0294e..6b6df5199a0 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -10,6 +10,7 @@ #include "clientversion.h" #include "data/alertTests.raw.h" +#include "chainparams.h" #include "serialize.h" #include "streams.h" #include "util.h" @@ -119,10 +120,11 @@ BOOST_FIXTURE_TEST_SUITE(Alert_tests, ReadAlerts) BOOST_AUTO_TEST_CASE(AlertApplies) { SetMockTime(11); + const std::vector& alertKey = Params(CBaseChainParams::MAIN).AlertKey(); BOOST_FOREACH(const CAlert& alert, alerts) { - BOOST_CHECK(alert.CheckSignature()); + BOOST_CHECK(alert.CheckSignature(alertKey)); } BOOST_CHECK(alerts.size() >= 3); @@ -159,6 +161,7 @@ BOOST_AUTO_TEST_CASE(AlertApplies) BOOST_AUTO_TEST_CASE(AlertNotify) { SetMockTime(11); + const std::vector& alertKey = Params(CBaseChainParams::MAIN).AlertKey(); boost::filesystem::path temp = GetTempPath() / "alertnotify.txt"; boost::filesystem::remove(temp); @@ -166,7 +169,7 @@ BOOST_AUTO_TEST_CASE(AlertNotify) mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string(); BOOST_FOREACH(CAlert alert, alerts) - alert.ProcessAlert(false); + alert.ProcessAlert(alertKey, false); std::vector r = read_lines(temp); BOOST_CHECK_EQUAL(r.size(), 4u); From 6c3566443ffa2fd9df1da6d3b8fcb823f1a87677 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 5 Apr 2015 14:22:52 +0200 Subject: [PATCH 0367/2337] [Qt] Clarify: smartfee button name "Minimize" Make clear this button hides the options instead of minimizing the transaction fee. --- src/qt/forms/sendcoinsdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index b1ed7a27b5c..8911b41cbf3 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -807,7 +807,7 @@ collapse fee-settings - Minimize + Hide
From f702d1c66df1534d3fad881f4f72160818a8305c Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Wed, 8 Apr 2015 14:31:53 +0200 Subject: [PATCH 0368/2337] move ThreadFlushWalletDB declaration to walletdb.h --- src/wallet/db.h | 3 --- src/wallet/walletdb.h | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wallet/db.h b/src/wallet/db.h index 0c2c139d89e..790ae504131 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -25,9 +25,6 @@ class COutPoint; extern unsigned int nWalletDBUpdated; -void ThreadFlushWalletDB(const std::string& strWalletFile); - - class CDBEnv { private: diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index a1c38b9d3d3..e5f64ffaae1 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -138,5 +138,6 @@ private: }; bool BackupWallet(const CWallet& wallet, const std::string& strDest); +void ThreadFlushWalletDB(const std::string& strFile); #endif // BITCOIN_WALLETDB_H From 4ac79f99b02e1d288dda353c15f4183180e538df Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 9 Apr 2015 17:36:10 +0200 Subject: [PATCH 0369/2337] Fix travis after merging #5957 New wallet tests have been added in the meantime and need to be updated to use `generate` instead of `setgenerate`. --- qa/rpc-tests/wallet.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 0301f160c1a..5f3178c606b 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -163,13 +163,13 @@ class WalletTest (BitcoinTestFramework): txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2); txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) - self.nodes[1].setgenerate(True, 1) #mine a block, tx should not be in there + self.nodes[1].generate(1) #mine a block, tx should not be in there self.sync_all() assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')); #should not be changed because tx was not broadcasted #now broadcast from another node, mine a block, sync, and check the balance self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex']) - self.nodes[1].setgenerate(True, 1) + self.nodes[1].generate(1) self.sync_all() txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) assert_equal(self.nodes[2].getbalance(), Decimal('61.99800000')); #should not be @@ -186,7 +186,7 @@ class WalletTest (BitcoinTestFramework): connect_nodes_bi(self.nodes,0,2) sync_blocks(self.nodes) - self.nodes[0].setgenerate(True, 1) + self.nodes[0].generate(1) sync_blocks(self.nodes) #tx should be added to balance because after restarting the nodes tx should be broadcastet From 48265f3cf4e62b6c6267b3e67c71a8780f2e2cc1 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 10 Apr 2015 07:33:06 +0200 Subject: [PATCH 0370/2337] Revert mining changes in #5957 This reverts commit e2edf95cd3f43331843676e49a82830128a95050 6b04508e37c5dd18cec1cd61cc4356bd208aa991 0df67f1f7ab4adfe9f0b3ba6276e737b37826464, except the changes to the RPC tests. A `generate` RPC call is introduced based on the old code. --- src/miner.cpp | 122 ++++++++++++++++++--------------------- src/miner.h | 6 +- src/rpcmining.cpp | 33 ++++++++--- src/test/miner_tests.cpp | 27 +++++---- 4 files changed, 97 insertions(+), 91 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 7f01918eeff..cf08b782296 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -87,7 +87,7 @@ void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); } -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev) +CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { // Create new block auto_ptr pblocktemplate(new CBlockTemplate()); @@ -132,7 +132,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pind { LOCK2(cs_main, mempool.cs); - pindexPrev = chainActive.Tip(); + CBlockIndex* pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; CCoinsViewCache view(pcoinsTip); @@ -365,34 +365,45 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& // // ScanHash scans nonces looking for a hash with at least some zero bits. -// The nonce is usually preserved between calls, but periodically the block is -// rebuilt and nNonce starts over at zero. +// The nonce is usually preserved between calls, but periodically or if the +// nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at +// zero. // -bool static ScanHash(CBlockHeader *pblock, uint256 *phash) +bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash) { + // Write the first 76 bytes of the block header to a double-SHA256 state. + CHash256 hasher; + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << *pblock; + assert(ss.size() == 80); + hasher.Write((unsigned char*)&ss[0], 76); + while (true) { - pblock->nNonce++; - *phash = pblock->GetHash(); + nNonce++; + + // Write the last 4 bytes of the block header (the nonce) to a copy of + // the double-SHA256 state, and compute the result. + CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash); // Return the nonce if the hash has at least some zero bits, // caller will check if it has enough to reach the target if (((uint16_t*)phash)[15] == 0) return true; - // If nothing found after trying for a while, return false. - if ((pblock->nNonce & 0xfff) == 0) + // If nothing found after trying for a while, return -1 + if ((nNonce & 0xfff) == 0) return false; } } -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CBlockIndex*& pindexPrev) +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) { CPubKey pubkey; if (!reservekey.GetReservedKey(pubkey)) return NULL; CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; - return CreateNewBlock(scriptPubKey, pindexPrev); + return CreateNewBlock(scriptPubKey); } static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) @@ -424,56 +435,6 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese return true; } -bool static ScanLoop(CBlock *pblock, CBlockIndex *pindexPrev, CWallet *pwallet, CReserveKey& reservekey) -{ - UpdateTime(pblock, pindexPrev); - arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); - - uint256 hash; - if (ScanHash(pblock, &hash)) { - if (UintToArith256(hash) <= hashTarget) { - // Found a solution - SetThreadPriority(THREAD_PRIORITY_NORMAL); - LogPrintf("BitcoinMiner:\n"); - LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex()); - ProcessBlockFound(pblock, *pwallet, reservekey); - SetThreadPriority(THREAD_PRIORITY_LOWEST); - - return true; - } - } - - return false; -} - -bool MineBlock(CWallet *pwallet, uint256& hash) -{ - CReserveKey reservekey(pwallet); - unsigned int nExtraNonce = 0; - - while (true) { - CBlockIndex *pindexPrev; - - auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev)); - if (!pblocktemplate.get()) { - return false; - } - - CBlock *pblock = &pblocktemplate->block; - IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); - - while (true) { - if (ScanLoop(pblock, pindexPrev, pwallet, reservekey)) { - hash = pblock->GetHash(); - return true; - } - boost::this_thread::interruption_point(); - if (pblock->nNonce >= 0xffff0000) - break; - } - } -} - void static BitcoinMiner(CWallet *pwallet) { LogPrintf("BitcoinMiner started\n"); @@ -497,9 +458,9 @@ void static BitcoinMiner(CWallet *pwallet) // Create new block // unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrev; + CBlockIndex* pindexPrev = chainActive.Tip(); - auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev)); + auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); if (!pblocktemplate.get()) { LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); @@ -515,23 +476,52 @@ void static BitcoinMiner(CWallet *pwallet) // Search // int64_t nStart = GetTime(); + arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); + uint256 hash; + uint32_t nNonce = 0; while (true) { // Check if something found - if (ScanLoop(pblock, pindexPrev, pwallet, reservekey)) - break; + if (ScanHash(pblock, nNonce, &hash)) + { + if (UintToArith256(hash) <= hashTarget) + { + // Found a solution + pblock->nNonce = nNonce; + assert(hash == pblock->GetHash()); + + SetThreadPriority(THREAD_PRIORITY_NORMAL); + LogPrintf("BitcoinMiner:\n"); + LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex()); + ProcessBlockFound(pblock, *pwallet, reservekey); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + + // In regression test mode, stop mining after a block is found. + if (Params().MineBlocksOnDemand()) + throw boost::thread_interrupted(); + + break; + } + } // Check for stop or if block needs to be rebuilt boost::this_thread::interruption_point(); // Regtest mode doesn't require peers if (vNodes.empty() && Params().MiningRequiresPeers()) break; - if (pblock->nNonce >= 0xffff0000) + if (nNonce >= 0xffff0000) break; if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60) break; if (pindexPrev != chainActive.Tip()) break; + // Update nTime every few seconds + UpdateTime(pblock, pindexPrev); + if (Params().AllowMinDifficultyBlocks()) + { + // Changing pblock->nTime can change work required on testnet: + hashTarget.SetCompact(pblock->nBits); + } } } } diff --git a/src/miner.h b/src/miner.h index 00ad299512f..5d5c9c86c7c 100644 --- a/src/miner.h +++ b/src/miner.h @@ -24,11 +24,9 @@ struct CBlockTemplate /** Run the miner threads */ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); -/** Create a single block */ -bool MineBlock(CWallet *pwallet, uint256& hash); /** Generate a new block, without valid proof-of-work */ -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev); -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CBlockIndex*& pindexPrev); +CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 6f165028d5e..1e6531f68a8 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -119,6 +119,7 @@ Value generate(const Array& params, bool fHelp) throw runtime_error( "generate numblocks\n" "\nMine blocks immediately (before the RPC call returns)\n" + "\nNote: this function can only be used on the regtest network\n" "1. numblocks (numeric) How many blocks are generated immediately.\n" "\nResult\n" "[ blockhashes ] (array) hashes of blocks generated\n" @@ -129,11 +130,14 @@ Value generate(const Array& params, bool fHelp) if (pwalletMain == NULL) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); + if (!Params().MineBlocksOnDemand()) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest"); int nHeightStart = 0; int nHeightEnd = 0; int nHeight = 0; int nGenerate = params[0].get_int(); + CReserveKey reservekey(pwalletMain); { // Don't keep cs_main locked LOCK(cs_main); @@ -141,18 +145,33 @@ Value generate(const Array& params, bool fHelp) nHeight = nHeightStart; nHeightEnd = nHeightStart+nGenerate; } + unsigned int nExtraNonce = 0; Array blockHashes; - while (nHeight < nHeightEnd) { - uint256 hash; - if (!MineBlock(pwalletMain, hash)) + while (nHeight < nHeightEnd) + { + auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); + if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); - + CBlock *pblock = &pblocktemplate->block; + { + LOCK(cs_main); + IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); + } + while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { + // Yes, there is a chance every nonce could fail to satisfy the -regtest + // target -- 1 in 2^(2^32). That ain't gonna happen. + ++pblock->nNonce; + } + CValidationState state; + if (!ProcessNewBlock(state, NULL, pblock)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; - blockHashes.push_back(hash.GetHex()); + blockHashes.push_back(pblock->GetHash().GetHex()); } return blockHashes; } + Value setgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) @@ -475,7 +494,7 @@ Value getblocktemplate(const Array& params, bool fHelp) // Store the pindexBest used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrevNew; + CBlockIndex* pindexPrevNew = chainActive.Tip(); nStart = GetTime(); // Create new block @@ -485,7 +504,7 @@ Value getblocktemplate(const Array& params, bool fHelp) pblocktemplate = NULL; } CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = CreateNewBlock(scriptDummy, pindexPrevNew); + pblocktemplate = CreateNewBlock(scriptDummy); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 27c0a08de9d..6ab9cb8a440 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -62,8 +62,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) Checkpoints::fEnabled = false; // Simple block creation, nothing special yet: - CBlockIndex* pindexPrev; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) @@ -91,7 +90,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) delete pblocktemplate; // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; // block sigops > limit: 1000 CHECKMULTISIG + 1 @@ -109,7 +108,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -129,14 +128,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); // orphan in mempool hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -154,7 +153,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 5900000000LL; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -165,7 +164,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 0; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -183,7 +182,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue -= 1000000; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -197,17 +196,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); // subsidy changing int nHeight = chainActive.Height(); chainActive.Tip()->nHeight = 209999; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; chainActive.Tip()->nHeight = 210000; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; chainActive.Tip()->nHeight = nHeight; @@ -239,7 +238,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); BOOST_CHECK(!IsFinalTx(tx2)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); // Neither tx should have make it into the template. BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); @@ -252,7 +251,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 1)); BOOST_CHECK(IsFinalTx(tx2)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); delete pblocktemplate; From fd311996e877d567a4e34a19b47e94d66e07100a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 25 Mar 2015 15:00:32 -0400 Subject: [PATCH 0371/2337] consensus: don't use arith_uint256 in consensus.h Requiring arith_uint256 at such a base level is not good for modularity. --- src/chainparams.cpp | 4 ++-- src/chainparams.h | 3 +-- src/consensus/params.h | 3 +-- src/pow.cpp | 9 +++++---- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 8633d51b2f3..97312b366de 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -105,7 +105,7 @@ public: consensus.nMajorityEnforceBlockUpgrade = 750; consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 1000; - consensus.powLimit = ~arith_uint256(0) >> 32; + consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = false; @@ -245,7 +245,7 @@ public: consensus.nMajorityEnforceBlockUpgrade = 750; consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 1000; - consensus.powLimit = ~arith_uint256(0) >> 1; + consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; diff --git a/src/chainparams.h b/src/chainparams.h index d0613beb455..e5e691cc533 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -6,7 +6,6 @@ #ifndef BITCOIN_CHAINPARAMS_H #define BITCOIN_CHAINPARAMS_H -#include "arith_uint256.h" #include "chainparamsbase.h" #include "checkpoints.h" #include "consensus/params.h" @@ -45,7 +44,7 @@ public: const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - const arith_uint256& ProofOfWorkLimit() const { return consensus.powLimit; } + const uint256& ProofOfWorkLimit() const { return consensus.powLimit; } int SubsidyHalvingInterval() const { return consensus.nSubsidyHalvingInterval; } int EnforceBlockUpgradeMajority() const { return consensus.nMajorityEnforceBlockUpgrade; } int RejectBlockOutdatedMajority() const { return consensus.nMajorityRejectBlockOutdated; } diff --git a/src/consensus/params.h b/src/consensus/params.h index c4cfa48c7e8..35d447b7127 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -6,7 +6,6 @@ #ifndef BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H #define BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H -#include "arith_uint256.h" #include "uint256.h" namespace Consensus { @@ -21,7 +20,7 @@ struct Params { int nMajorityRejectBlockOutdated; int nMajorityWindow; /** Proof of work parameters */ - arith_uint256 powLimit; + uint256 powLimit; bool fPowAllowMinDifficultyBlocks; int64_t nPowTargetSpacing; int64_t nPowTargetTimespan; diff --git a/src/pow.cpp b/src/pow.cpp index cf7ac387f23..fc6ed4f3d19 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -13,7 +13,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { - unsigned int nProofOfWorkLimit = params.powLimit.GetCompact(); + unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); // Genesis block if (pindexLast == NULL) @@ -61,6 +61,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF nActualTimespan = params.nPowTargetTimespan*4; // Retarget + const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); arith_uint256 bnNew; arith_uint256 bnOld; bnNew.SetCompact(pindexLast->nBits); @@ -68,8 +69,8 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF bnNew *= nActualTimespan; bnNew /= params.nPowTargetTimespan; - if (bnNew > params.powLimit) - bnNew = params.powLimit; + if (bnNew > bnPowLimit) + bnNew = bnPowLimit; /// debug print LogPrintf("GetNextWorkRequired RETARGET\n"); @@ -89,7 +90,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range - if (fNegative || bnTarget == 0 || fOverflow || bnTarget > params.powLimit) + if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) return error("CheckProofOfWork(): nBits below minimum work"); // Check proof of work matches claimed amount From b2b361926215eadd6bf43ed1d7110b925fc7cae5 Mon Sep 17 00:00:00 2001 From: Tom Harding Date: Wed, 11 Mar 2015 16:48:53 -0700 Subject: [PATCH 0372/2337] Implement CTransaction::IsEquivalentTo(...) Define CTransaction::IsEquivalentTo(const CTransaction& tx) True if only scriptSigs are different. In other words, true if the two transactions are malleability clones. In other words, true if the two transactions have the same effect on the outside universe. In the wallet, only SyncMetaData for equivalent transactions. --- src/primitives/transaction.cpp | 9 +++++++++ src/primitives/transaction.h | 3 +++ src/wallet/wallet.cpp | 1 + 3 files changed, 13 insertions(+) diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 606dbea7985..d864a9b6d3b 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -87,6 +87,15 @@ CTransaction& CTransaction::operator=(const CTransaction &tx) { return *this; } +bool CTransaction::IsEquivalentTo(const CTransaction& tx) const +{ + CMutableTransaction tx1 = *this; + CMutableTransaction tx2 = tx; + for (unsigned int i = 0; i < tx1.vin.size(); i++) tx1.vin[i].scriptSig = CScript(); + for (unsigned int i = 0; i < tx2.vin.size(); i++) tx2.vin[i].scriptSig = CScript(); + return CTransaction(tx1) == CTransaction(tx2); +} + CAmount CTransaction::GetValueOut() const { CAmount nValueOut = 0; diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 6cfd93a9a18..0c9ebb7b881 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -222,6 +222,9 @@ public: return hash; } + // True if only scriptSigs are different + bool IsEquivalentTo(const CTransaction& tx) const; + // Return sum of txouts. CAmount GetValueOut() const; // GetValueIn() is a method on CCoinsViewCache, because diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2566b2712bd..92bb972cf35 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -417,6 +417,7 @@ void CWallet::SyncMetaData(pair range) const uint256& hash = it->second; CWalletTx* copyTo = &mapWallet[hash]; if (copyFrom == copyTo) continue; + if (!copyFrom->IsEquivalentTo(*copyTo)) continue; copyTo->mapValue = copyFrom->mapValue; copyTo->vOrderForm = copyFrom->vOrderForm; // fTimeReceivedIsTxTime not copied on purpose From defd2d55b789163be4a863d0887d5d309ff9cde3 Mon Sep 17 00:00:00 2001 From: Tom Harding Date: Wed, 11 Mar 2015 14:29:06 -0700 Subject: [PATCH 0373/2337] Better txn_doublespend.py test Remove reliance on accounting "move" ledger entries. Instead, create funding transactions (and deal with fee complexities). Do not rely on broken SyncMetaData. Instead expect double-spend amount to be debited from the default "" account. --- qa/rpc-tests/txn_doublespend.py | 77 ++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index fe9168944bc..9551080039d 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -4,7 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -# Test proper accounting with malleable transactions +# Test proper accounting with a double-spend conflict # from test_framework import BitcoinTestFramework @@ -32,28 +32,40 @@ class TxnMallTest(BitcoinTestFramework): self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress! # Assign coins to foo and bar accounts: - self.nodes[0].move("", "foo", 1220) - self.nodes[0].move("", "bar", 30) - assert_equal(self.nodes[0].getbalance(""), 0) + node0_address_foo = self.nodes[0].getnewaddress("foo") + fund_foo_txid = self.nodes[0].sendfrom("", node0_address_foo, 1219) + fund_foo_tx = self.nodes[0].gettransaction(fund_foo_txid) + + node0_address_bar = self.nodes[0].getnewaddress("bar") + fund_bar_txid = self.nodes[0].sendfrom("", node0_address_bar, 29) + fund_bar_tx = self.nodes[0].gettransaction(fund_bar_txid) + + assert_equal(self.nodes[0].getbalance(""), + starting_balance - 1219 - 29 + fund_foo_tx["fee"] + fund_bar_tx["fee"]) # Coins are sent to node1_address node1_address = self.nodes[1].getnewaddress("from0") - # First: use raw transaction API to send 1210 BTC to node1_address, + # First: use raw transaction API to send 1240 BTC to node1_address, # but don't broadcast: - (total_in, inputs) = gather_inputs(self.nodes[0], 1210) - change_address = self.nodes[0].getnewaddress("foo") + doublespend_fee = Decimal('-.02') + rawtx_input_0 = {} + rawtx_input_0["txid"] = fund_foo_txid + rawtx_input_0["vout"] = find_output(self.nodes[0], fund_foo_txid, 1219) + rawtx_input_1 = {} + rawtx_input_1["txid"] = fund_bar_txid + rawtx_input_1["vout"] = find_output(self.nodes[0], fund_bar_txid, 29) + inputs = [rawtx_input_0, rawtx_input_1] + change_address = self.nodes[0].getnewaddress() outputs = {} - outputs[change_address] = 40 - outputs[node1_address] = 1210 + outputs[node1_address] = 1240 + outputs[change_address] = 1248 - 1240 + doublespend_fee rawtx = self.nodes[0].createrawtransaction(inputs, outputs) doublespend = self.nodes[0].signrawtransaction(rawtx) assert_equal(doublespend["complete"], True) - # Create two transaction from node[0] to node[1]; the - # second must spend change from the first because the first - # spends all mature inputs: - txid1 = self.nodes[0].sendfrom("foo", node1_address, 1210, 0) + # Create two spends using 1 50 BTC coin each + txid1 = self.nodes[0].sendfrom("foo", node1_address, 40, 0) txid2 = self.nodes[0].sendfrom("bar", node1_address, 20, 0) # Have node0 mine a block: @@ -65,16 +77,16 @@ class TxnMallTest(BitcoinTestFramework): tx2 = self.nodes[0].gettransaction(txid2) # Node0's balance should be starting balance, plus 50BTC for another - # matured block, minus 1210, minus 20, and minus transaction fees: - expected = starting_balance + # matured block, minus 40, minus 20, and minus transaction fees: + expected = starting_balance + fund_foo_tx["fee"] + fund_bar_tx["fee"] if self.options.mine_block: expected += 50 expected += tx1["amount"] + tx1["fee"] expected += tx2["amount"] + tx2["fee"] assert_equal(self.nodes[0].getbalance(), expected) # foo and bar accounts should be debited: - assert_equal(self.nodes[0].getbalance("foo"), 1220+tx1["amount"]+tx1["fee"]) - assert_equal(self.nodes[0].getbalance("bar"), 30+tx2["amount"]+tx2["fee"]) + assert_equal(self.nodes[0].getbalance("foo", 0), 1219+tx1["amount"]+tx1["fee"]) + assert_equal(self.nodes[0].getbalance("bar", 0), 29+tx2["amount"]+tx2["fee"]) if self.options.mine_block: assert_equal(tx1["confirmations"], 1) @@ -85,8 +97,10 @@ class TxnMallTest(BitcoinTestFramework): assert_equal(tx1["confirmations"], 0) assert_equal(tx2["confirmations"], 0) - # Now give doublespend to miner: - mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"]) + # Now give doublespend and its parents to miner: + self.nodes[2].sendrawtransaction(fund_foo_tx["hex"]) + self.nodes[2].sendrawtransaction(fund_bar_tx["hex"]) + self.nodes[2].sendrawtransaction(doublespend["hex"]) # ... mine a block... self.nodes[2].generate(1) @@ -104,17 +118,28 @@ class TxnMallTest(BitcoinTestFramework): assert_equal(tx2["confirmations"], -1) # Node0's total balance should be starting balance, plus 100BTC for - # two more matured blocks, minus 1210 for the double-spend: - expected = starting_balance + 100 - 1210 + # two more matured blocks, minus 1240 for the double-spend, plus fees (which are + # negative): + expected = starting_balance + 100 - 1240 + fund_foo_tx["fee"] + fund_bar_tx["fee"] + doublespend_fee assert_equal(self.nodes[0].getbalance(), expected) assert_equal(self.nodes[0].getbalance("*"), expected) - # foo account should be debited, but bar account should not: - assert_equal(self.nodes[0].getbalance("foo"), 1220-1210) - assert_equal(self.nodes[0].getbalance("bar"), 30) + # Final "" balance is starting_balance - amount moved to accounts - doublespend + subsidies + + # fees (which are negative) + assert_equal(self.nodes[0].getbalance("foo"), 1219) + assert_equal(self.nodes[0].getbalance("bar"), 29) + assert_equal(self.nodes[0].getbalance(""), starting_balance + -1219 + - 29 + -1240 + + 100 + + fund_foo_tx["fee"] + + fund_bar_tx["fee"] + + doublespend_fee) - # Node1's "from" account balance should be just the mutated send: - assert_equal(self.nodes[1].getbalance("from0"), 1210) + # Node1's "from0" account balance should be just the doublespend: + assert_equal(self.nodes[1].getbalance("from0"), 1240) if __name__ == '__main__': TxnMallTest().main() + From 0b9dc9c8f5943a8389faa1fd0e52fa5ac6a4a759 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 12 Apr 2015 17:56:32 +0200 Subject: [PATCH 0374/2337] [move] move listunspent to wallet/rpcwallet.cpp --- src/rpcrawtransaction.cpp | 111 ------------------------------------- src/wallet/rpcwallet.cpp | 112 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 111 deletions(-) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index a79b4e33940..c979217a130 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -193,117 +193,6 @@ Value getrawtransaction(const Array& params, bool fHelp) return result; } -#ifdef ENABLE_WALLET -Value listunspent(const Array& params, bool fHelp) -{ - if (fHelp || params.size() > 3) - throw runtime_error( - "listunspent ( minconf maxconf [\"address\",...] )\n" - "\nReturns array of unspent transaction outputs\n" - "with between minconf and maxconf (inclusive) confirmations.\n" - "Optionally filter to only include txouts paid to specified addresses.\n" - "Results are an array of Objects, each of which has:\n" - "{txid, vout, scriptPubKey, amount, confirmations}\n" - "\nArguments:\n" - "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" - "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" - "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n" - " [\n" - " \"address\" (string) bitcoin address\n" - " ,...\n" - " ]\n" - "\nResult\n" - "[ (array of json object)\n" - " {\n" - " \"txid\" : \"txid\", (string) the transaction id \n" - " \"vout\" : n, (numeric) the vout value\n" - " \"address\" : \"address\", (string) the bitcoin address\n" - " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" - " \"scriptPubKey\" : \"key\", (string) the script key\n" - " \"amount\" : x.xxx, (numeric) the transaction amount in btc\n" - " \"confirmations\" : n (numeric) The number of confirmations\n" - " }\n" - " ,...\n" - "]\n" - - "\nExamples\n" - + HelpExampleCli("listunspent", "") - + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") - + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") - ); - - RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type)); - - int nMinDepth = 1; - if (params.size() > 0) - nMinDepth = params[0].get_int(); - - int nMaxDepth = 9999999; - if (params.size() > 1) - nMaxDepth = params[1].get_int(); - - set setAddress; - if (params.size() > 2) { - Array inputs = params[2].get_array(); - BOOST_FOREACH(Value& input, inputs) { - CBitcoinAddress address(input.get_str()); - if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); - if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); - setAddress.insert(address); - } - } - - Array results; - vector vecOutputs; - assert(pwalletMain != NULL); - LOCK2(cs_main, pwalletMain->cs_wallet); - pwalletMain->AvailableCoins(vecOutputs, false); - BOOST_FOREACH(const COutput& out, vecOutputs) { - if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) - continue; - - if (setAddress.size()) { - CTxDestination address; - if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) - continue; - - if (!setAddress.count(address)) - continue; - } - - CAmount nValue = out.tx->vout[out.i].nValue; - const CScript& pk = out.tx->vout[out.i].scriptPubKey; - Object entry; - entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); - entry.push_back(Pair("vout", out.i)); - CTxDestination address; - if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { - entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); - if (pwalletMain->mapAddressBook.count(address)) - entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); - } - entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); - if (pk.IsPayToScriptHash()) { - CTxDestination address; - if (ExtractDestination(pk, address)) { - const CScriptID& hash = boost::get(address); - CScript redeemScript; - if (pwalletMain->GetCScript(hash, redeemScript)) - entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); - } - } - entry.push_back(Pair("amount",ValueFromAmount(nValue))); - entry.push_back(Pair("confirmations",out.nDepth)); - entry.push_back(Pair("spendable", out.fSpendable)); - results.push_back(entry); - } - - return results; -} -#endif - Value createrawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() != 2) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 29f3eda15dd..f94a2ce8ea6 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2118,3 +2118,115 @@ Value resendwallettransactions(const Array& params, bool fHelp) } return result; } + +Value listunspent(const Array& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + + if (fHelp || params.size() > 3) + throw runtime_error( + "listunspent ( minconf maxconf [\"address\",...] )\n" + "\nReturns array of unspent transaction outputs\n" + "with between minconf and maxconf (inclusive) confirmations.\n" + "Optionally filter to only include txouts paid to specified addresses.\n" + "Results are an array of Objects, each of which has:\n" + "{txid, vout, scriptPubKey, amount, confirmations}\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" + "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" + "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n" + " [\n" + " \"address\" (string) bitcoin address\n" + " ,...\n" + " ]\n" + "\nResult\n" + "[ (array of json object)\n" + " {\n" + " \"txid\" : \"txid\", (string) the transaction id \n" + " \"vout\" : n, (numeric) the vout value\n" + " \"address\" : \"address\", (string) the bitcoin address\n" + " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" + " \"scriptPubKey\" : \"key\", (string) the script key\n" + " \"amount\" : x.xxx, (numeric) the transaction amount in btc\n" + " \"confirmations\" : n (numeric) The number of confirmations\n" + " }\n" + " ,...\n" + "]\n" + + "\nExamples\n" + + HelpExampleCli("listunspent", "") + + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + ); + + RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type)); + + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + int nMaxDepth = 9999999; + if (params.size() > 1) + nMaxDepth = params[1].get_int(); + + set setAddress; + if (params.size() > 2) { + Array inputs = params[2].get_array(); + BOOST_FOREACH(Value& input, inputs) { + CBitcoinAddress address(input.get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); + setAddress.insert(address); + } + } + + Array results; + vector vecOutputs; + assert(pwalletMain != NULL); + LOCK2(cs_main, pwalletMain->cs_wallet); + pwalletMain->AvailableCoins(vecOutputs, false); + BOOST_FOREACH(const COutput& out, vecOutputs) { + if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) + continue; + + if (setAddress.size()) { + CTxDestination address; + if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) + continue; + + if (!setAddress.count(address)) + continue; + } + + CAmount nValue = out.tx->vout[out.i].nValue; + const CScript& pk = out.tx->vout[out.i].scriptPubKey; + Object entry; + entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); + entry.push_back(Pair("vout", out.i)); + CTxDestination address; + if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { + entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); + if (pwalletMain->mapAddressBook.count(address)) + entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + } + entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); + if (pk.IsPayToScriptHash()) { + CTxDestination address; + if (ExtractDestination(pk, address)) { + const CScriptID& hash = boost::get(address); + CScript redeemScript; + if (pwalletMain->GetCScript(hash, redeemScript)) + entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); + } + } + entry.push_back(Pair("amount",ValueFromAmount(nValue))); + entry.push_back(Pair("confirmations",out.nDepth)); + entry.push_back(Pair("spendable", out.fSpendable)); + results.push_back(entry); + } + + return results; +} \ No newline at end of file From b9fb692d04e90967b14c6988553c9121c5eea64e Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 12 Apr 2015 17:56:44 +0200 Subject: [PATCH 0375/2337] Push down RPC reqWallet flag --- src/init.cpp | 5 -- src/rpcserver.cpp | 177 +++++++++++++++++++-------------------- src/rpcserver.h | 1 - src/wallet/rpcdump.cpp | 16 ++++ src/wallet/rpcwallet.cpp | 114 +++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 97 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 53e521983f5..eb3a3fe58b1 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -242,11 +242,6 @@ void OnRPCStopped() void OnRPCPreCommand(const CRPCCommand& cmd) { -#ifdef ENABLE_WALLET - if (cmd.reqWallet && !pwalletMain) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); -#endif - // Observe safe mode string strWarning = GetWarnings("rpc"); if (strWarning != "" && !GetBoolArg("-disablesafemode", false) && diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 0fd7769a199..e2df41fe211 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -193,11 +193,6 @@ string CRPCTable::help(string strCommand) const continue; if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand) continue; -#ifdef ENABLE_WALLET - if (pcmd->reqWallet && !pwalletMain) - continue; -#endif - try { Array params; @@ -271,114 +266,114 @@ Value stop(const Array& params, bool fHelp) * Call Table */ static const CRPCCommand vRPCCommands[] = -{ // category name actor (function) okSafeMode reqWallet - // --------------------- ------------------------ ----------------------- ---------- --------- +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- /* Overall control/query calls */ - { "control", "getinfo", &getinfo, true, false }, /* uses wallet if enabled */ - { "control", "help", &help, true, false }, - { "control", "stop", &stop, true, false }, + { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */ + { "control", "help", &help, true }, + { "control", "stop", &stop, true }, /* P2P networking */ - { "network", "getnetworkinfo", &getnetworkinfo, true, false }, - { "network", "addnode", &addnode, true, false }, - { "network", "getaddednodeinfo", &getaddednodeinfo, true, false }, - { "network", "getconnectioncount", &getconnectioncount, true, false }, - { "network", "getnettotals", &getnettotals, true, false }, - { "network", "getpeerinfo", &getpeerinfo, true, false }, - { "network", "ping", &ping, true, false }, + { "network", "getnetworkinfo", &getnetworkinfo, true }, + { "network", "addnode", &addnode, true }, + { "network", "getaddednodeinfo", &getaddednodeinfo, true }, + { "network", "getconnectioncount", &getconnectioncount, true }, + { "network", "getnettotals", &getnettotals, true }, + { "network", "getpeerinfo", &getpeerinfo, true }, + { "network", "ping", &ping, true }, /* Block chain and UTXO */ - { "blockchain", "getblockchaininfo", &getblockchaininfo, true, false }, - { "blockchain", "getbestblockhash", &getbestblockhash, true, false }, - { "blockchain", "getblockcount", &getblockcount, true, false }, - { "blockchain", "getblock", &getblock, true, false }, - { "blockchain", "getblockhash", &getblockhash, true, false }, - { "blockchain", "getchaintips", &getchaintips, true, false }, - { "blockchain", "getdifficulty", &getdifficulty, true, false }, - { "blockchain", "getmempoolinfo", &getmempoolinfo, true, false }, - { "blockchain", "getrawmempool", &getrawmempool, true, false }, - { "blockchain", "gettxout", &gettxout, true, false }, - { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false }, - { "blockchain", "verifychain", &verifychain, true, false }, + { "blockchain", "getblockchaininfo", &getblockchaininfo, true }, + { "blockchain", "getbestblockhash", &getbestblockhash, true }, + { "blockchain", "getblockcount", &getblockcount, true }, + { "blockchain", "getblock", &getblock, true }, + { "blockchain", "getblockhash", &getblockhash, true }, + { "blockchain", "getchaintips", &getchaintips, true }, + { "blockchain", "getdifficulty", &getdifficulty, true }, + { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, + { "blockchain", "getrawmempool", &getrawmempool, true }, + { "blockchain", "gettxout", &gettxout, true }, + { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, + { "blockchain", "verifychain", &verifychain, true }, /* Mining */ - { "mining", "getblocktemplate", &getblocktemplate, true, false }, - { "mining", "getmininginfo", &getmininginfo, true, false }, - { "mining", "getnetworkhashps", &getnetworkhashps, true, false }, - { "mining", "prioritisetransaction", &prioritisetransaction, true, false }, - { "mining", "submitblock", &submitblock, true, false }, + { "mining", "getblocktemplate", &getblocktemplate, true }, + { "mining", "getmininginfo", &getmininginfo, true }, + { "mining", "getnetworkhashps", &getnetworkhashps, true }, + { "mining", "prioritisetransaction", &prioritisetransaction, true }, + { "mining", "submitblock", &submitblock, true }, #ifdef ENABLE_WALLET /* Coin generation */ - { "generating", "getgenerate", &getgenerate, true, false }, - { "generating", "setgenerate", &setgenerate, true, false }, - { "generating", "generate", &generate, true, false }, + { "generating", "getgenerate", &getgenerate, true }, + { "generating", "setgenerate", &setgenerate, true }, + { "generating", "generate", &generate, true }, #endif /* Raw transactions */ - { "rawtransactions", "createrawtransaction", &createrawtransaction, true, false }, - { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false }, - { "rawtransactions", "decodescript", &decodescript, true, false }, - { "rawtransactions", "getrawtransaction", &getrawtransaction, true, false }, - { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false }, - { "rawtransactions", "signrawtransaction", &signrawtransaction, false, false }, /* uses wallet if enabled */ + { "rawtransactions", "createrawtransaction", &createrawtransaction, true }, + { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true }, + { "rawtransactions", "decodescript", &decodescript, true }, + { "rawtransactions", "getrawtransaction", &getrawtransaction, true }, + { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false }, + { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */ /* Utility functions */ - { "util", "createmultisig", &createmultisig, true, false }, - { "util", "validateaddress", &validateaddress, true, false }, /* uses wallet if enabled */ - { "util", "verifymessage", &verifymessage, true, false }, - { "util", "estimatefee", &estimatefee, true, false }, - { "util", "estimatepriority", &estimatepriority, true, false }, + { "util", "createmultisig", &createmultisig, true }, + { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ + { "util", "verifymessage", &verifymessage, true }, + { "util", "estimatefee", &estimatefee, true }, + { "util", "estimatepriority", &estimatepriority, true }, /* Not shown in help */ - { "hidden", "invalidateblock", &invalidateblock, true, false }, - { "hidden", "reconsiderblock", &reconsiderblock, true, false }, - { "hidden", "setmocktime", &setmocktime, true, false }, + { "hidden", "invalidateblock", &invalidateblock, true }, + { "hidden", "reconsiderblock", &reconsiderblock, true }, + { "hidden", "setmocktime", &setmocktime, true }, #ifdef ENABLE_WALLET - { "hidden", "resendwallettransactions", &resendwallettransactions, true, true }, + { "hidden", "resendwallettransactions", &resendwallettransactions, true}, #endif #ifdef ENABLE_WALLET /* Wallet */ - { "wallet", "addmultisigaddress", &addmultisigaddress, true, true }, - { "wallet", "backupwallet", &backupwallet, true, true }, - { "wallet", "dumpprivkey", &dumpprivkey, true, true }, - { "wallet", "dumpwallet", &dumpwallet, true, true }, - { "wallet", "encryptwallet", &encryptwallet, true, true }, - { "wallet", "getaccountaddress", &getaccountaddress, true, true }, - { "wallet", "getaccount", &getaccount, true, true }, - { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, true }, - { "wallet", "getbalance", &getbalance, false, true }, - { "wallet", "getnewaddress", &getnewaddress, true, true }, - { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, true }, - { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, true }, - { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, true }, - { "wallet", "gettransaction", &gettransaction, false, true }, - { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, true }, - { "wallet", "getwalletinfo", &getwalletinfo, false, true }, - { "wallet", "importprivkey", &importprivkey, true, true }, - { "wallet", "importwallet", &importwallet, true, true }, - { "wallet", "importaddress", &importaddress, true, true }, - { "wallet", "keypoolrefill", &keypoolrefill, true, true }, - { "wallet", "listaccounts", &listaccounts, false, true }, - { "wallet", "listaddressgroupings", &listaddressgroupings, false, true }, - { "wallet", "listlockunspent", &listlockunspent, false, true }, - { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, true }, - { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, true }, - { "wallet", "listsinceblock", &listsinceblock, false, true }, - { "wallet", "listtransactions", &listtransactions, false, true }, - { "wallet", "listunspent", &listunspent, false, true }, - { "wallet", "lockunspent", &lockunspent, true, true }, - { "wallet", "move", &movecmd, false, true }, - { "wallet", "sendfrom", &sendfrom, false, true }, - { "wallet", "sendmany", &sendmany, false, true }, - { "wallet", "sendtoaddress", &sendtoaddress, false, true }, - { "wallet", "setaccount", &setaccount, true, true }, - { "wallet", "settxfee", &settxfee, true, true }, - { "wallet", "signmessage", &signmessage, true, true }, - { "wallet", "walletlock", &walletlock, true, true }, - { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, true }, - { "wallet", "walletpassphrase", &walletpassphrase, true, true }, + { "wallet", "addmultisigaddress", &addmultisigaddress, true }, + { "wallet", "backupwallet", &backupwallet, true }, + { "wallet", "dumpprivkey", &dumpprivkey, true }, + { "wallet", "dumpwallet", &dumpwallet, true }, + { "wallet", "encryptwallet", &encryptwallet, true }, + { "wallet", "getaccountaddress", &getaccountaddress, true }, + { "wallet", "getaccount", &getaccount, true }, + { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true }, + { "wallet", "getbalance", &getbalance, false }, + { "wallet", "getnewaddress", &getnewaddress, true }, + { "wallet", "getrawchangeaddress", &getrawchangeaddress, true }, + { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false }, + { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false }, + { "wallet", "gettransaction", &gettransaction, false }, + { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false }, + { "wallet", "getwalletinfo", &getwalletinfo, false }, + { "wallet", "importprivkey", &importprivkey, true }, + { "wallet", "importwallet", &importwallet, true }, + { "wallet", "importaddress", &importaddress, true }, + { "wallet", "keypoolrefill", &keypoolrefill, true }, + { "wallet", "listaccounts", &listaccounts, false }, + { "wallet", "listaddressgroupings", &listaddressgroupings, false }, + { "wallet", "listlockunspent", &listlockunspent, false }, + { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false }, + { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false }, + { "wallet", "listsinceblock", &listsinceblock, false }, + { "wallet", "listtransactions", &listtransactions, false }, + { "wallet", "listunspent", &listunspent, false }, + { "wallet", "lockunspent", &lockunspent, true }, + { "wallet", "move", &movecmd, false }, + { "wallet", "sendfrom", &sendfrom, false }, + { "wallet", "sendmany", &sendmany, false }, + { "wallet", "sendtoaddress", &sendtoaddress, false }, + { "wallet", "setaccount", &setaccount, true }, + { "wallet", "settxfee", &settxfee, true }, + { "wallet", "signmessage", &signmessage, true }, + { "wallet", "walletlock", &walletlock, true }, + { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, + { "wallet", "walletpassphrase", &walletpassphrase, true }, #endif // ENABLE_WALLET }; diff --git a/src/rpcserver.h b/src/rpcserver.h index e7aaed8bdff..c3200d8c35d 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -98,7 +98,6 @@ public: std::string name; rpcfn_type actor; bool okSafeMode; - bool reqWallet; }; /** diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index b9c92a06c5d..ab951d1d7d1 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -25,6 +25,7 @@ using namespace json_spirit; using namespace std; void EnsureWalletIsUnlocked(); +bool EnsureWalletIsAvailable(bool avoidException); std::string static EncodeDumpTime(int64_t nTime) { return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); @@ -71,6 +72,9 @@ std::string DecodeDumpString(const std::string &str) { Value importprivkey(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 1 || params.size() > 3) throw runtime_error( "importprivkey \"bitcoinprivkey\" ( \"label\" rescan )\n" @@ -142,6 +146,9 @@ Value importprivkey(const Array& params, bool fHelp) Value importaddress(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 1 || params.size() > 3) throw runtime_error( "importaddress \"address\" ( \"label\" rescan )\n" @@ -212,6 +219,9 @@ Value importaddress(const Array& params, bool fHelp) Value importwallet(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 1) throw runtime_error( "importwallet \"filename\"\n" @@ -313,6 +323,9 @@ Value importwallet(const Array& params, bool fHelp) Value dumpprivkey(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 1) throw runtime_error( "dumpprivkey \"bitcoinaddress\"\n" @@ -348,6 +361,9 @@ Value dumpprivkey(const Array& params, bool fHelp) Value dumpwallet(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 1) throw runtime_error( "dumpwallet \"filename\"\n" diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f94a2ce8ea6..2c3507fb3b7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -37,6 +37,18 @@ std::string HelpRequiringPassphrase() : ""; } +bool EnsureWalletIsAvailable(bool avoidException) +{ + if (!pwalletMain) + { + if (!avoidException) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); + else + return false; + } + return true; +} + void EnsureWalletIsUnlocked() { if (pwalletMain->IsLocked()) @@ -77,6 +89,9 @@ string AccountFromValue(const Value& value) Value getnewaddress(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 1) throw runtime_error( "getnewaddress ( \"account\" )\n" @@ -153,6 +168,9 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) Value getaccountaddress(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 1) throw runtime_error( "getaccountaddress \"account\"\n" @@ -182,6 +200,9 @@ Value getaccountaddress(const Array& params, bool fHelp) Value getrawchangeaddress(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 1) throw runtime_error( "getrawchangeaddress\n" @@ -214,6 +235,9 @@ Value getrawchangeaddress(const Array& params, bool fHelp) Value setaccount(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "setaccount \"bitcoinaddress\" \"account\"\n" @@ -257,6 +281,9 @@ Value setaccount(const Array& params, bool fHelp) Value getaccount(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 1) throw runtime_error( "getaccount \"bitcoinaddress\"\n" @@ -286,6 +313,9 @@ Value getaccount(const Array& params, bool fHelp) Value getaddressesbyaccount(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 1) throw runtime_error( "getaddressesbyaccount \"account\"\n" @@ -351,6 +381,9 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr Value sendtoaddress(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" @@ -404,6 +437,9 @@ Value sendtoaddress(const Array& params, bool fHelp) Value listaddressgroupings(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp) throw runtime_error( "listaddressgroupings\n" @@ -453,6 +489,9 @@ Value listaddressgroupings(const Array& params, bool fHelp) Value signmessage(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 2) throw runtime_error( "signmessage \"bitcoinaddress\" \"message\"\n" @@ -506,6 +545,9 @@ Value signmessage(const Array& params, bool fHelp) Value getreceivedbyaddress(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getreceivedbyaddress \"bitcoinaddress\" ( minconf )\n" @@ -561,6 +603,9 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) Value getreceivedbyaccount(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getreceivedbyaccount \"account\" ( minconf )\n" @@ -647,6 +692,9 @@ CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminef Value getbalance(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 3) throw runtime_error( "getbalance ( \"account\" minconf includeWatchonly )\n" @@ -719,6 +767,9 @@ Value getbalance(const Array& params, bool fHelp) Value getunconfirmedbalance(const Array ¶ms, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 0) throw runtime_error( "getunconfirmedbalance\n" @@ -732,6 +783,9 @@ Value getunconfirmedbalance(const Array ¶ms, bool fHelp) Value movecmd(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 3 || params.size() > 5) throw runtime_error( "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n" @@ -799,6 +853,9 @@ Value movecmd(const Array& params, bool fHelp) Value sendfrom(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n" @@ -859,6 +916,9 @@ Value sendfrom(const Array& params, bool fHelp) Value sendmany(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n" @@ -965,6 +1025,9 @@ extern CScript _createmultisig_redeemScript(const Array& params); Value addmultisigaddress(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 2 || params.size() > 3) { string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n" @@ -1143,6 +1206,9 @@ Value ListReceived(const Array& params, bool fByAccounts) Value listreceivedbyaddress(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 3) throw runtime_error( "listreceivedbyaddress ( minconf includeempty includeWatchonly)\n" @@ -1177,6 +1243,9 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) Value listreceivedbyaccount(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 3) throw runtime_error( "listreceivedbyaccount ( minconf includeempty includeWatchonly)\n" @@ -1304,6 +1373,9 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar Value listtransactions(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 4) throw runtime_error( "listtransactions ( \"account\" count from includeWatchonly)\n" @@ -1415,6 +1487,9 @@ Value listtransactions(const Array& params, bool fHelp) Value listaccounts(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 2) throw runtime_error( "listaccounts ( minconf includeWatchonly)\n" @@ -1492,6 +1567,9 @@ Value listaccounts(const Array& params, bool fHelp) Value listsinceblock(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp) throw runtime_error( "listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n" @@ -1580,6 +1658,9 @@ Value listsinceblock(const Array& params, bool fHelp) Value gettransaction(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "gettransaction \"txid\" ( includeWatchonly )\n" @@ -1655,6 +1736,9 @@ Value gettransaction(const Array& params, bool fHelp) Value backupwallet(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 1) throw runtime_error( "backupwallet \"destination\"\n" @@ -1678,6 +1762,9 @@ Value backupwallet(const Array& params, bool fHelp) Value keypoolrefill(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 1) throw runtime_error( "keypoolrefill ( newsize )\n" @@ -1719,6 +1806,9 @@ static void LockWallet(CWallet* pWallet) Value walletpassphrase(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" @@ -1776,6 +1866,9 @@ Value walletpassphrase(const Array& params, bool fHelp) Value walletpassphrasechange(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" @@ -1819,6 +1912,9 @@ Value walletpassphrasechange(const Array& params, bool fHelp) Value walletlock(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) throw runtime_error( "walletlock\n" @@ -1855,6 +1951,9 @@ Value walletlock(const Array& params, bool fHelp) Value encryptwallet(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) throw runtime_error( "encryptwallet \"passphrase\"\n" @@ -1909,6 +2008,9 @@ Value encryptwallet(const Array& params, bool fHelp) Value lockunspent(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n" @@ -1990,6 +2092,9 @@ Value lockunspent(const Array& params, bool fHelp) Value listlockunspent(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() > 0) throw runtime_error( "listlockunspent\n" @@ -2036,6 +2141,9 @@ Value listlockunspent(const Array& params, bool fHelp) Value settxfee(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( "settxfee amount\n" @@ -2062,6 +2170,9 @@ Value settxfee(const Array& params, bool fHelp) Value getwalletinfo(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 0) throw runtime_error( "getwalletinfo\n" @@ -2099,6 +2210,9 @@ Value getwalletinfo(const Array& params, bool fHelp) Value resendwallettransactions(const Array& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + if (fHelp || params.size() != 0) throw runtime_error( "resendwallettransactions\n" From 4e382177eda203e799310350ffb2efc28d010799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Thu, 9 Apr 2015 15:58:34 +0200 Subject: [PATCH 0376/2337] Chainparams: Refactor: Remove redundant HashGenesisBlock() getter --- src/chainparams.h | 1 - src/init.cpp | 7 ++++--- src/main.cpp | 17 +++++++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/chainparams.h b/src/chainparams.h index d0613beb455..03b4be8e17f 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -41,7 +41,6 @@ public: }; const Consensus::Params& GetConsensus() const { return consensus; } - const uint256& HashGenesisBlock() const { return consensus.hashGenesisBlock; } const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } diff --git a/src/init.cpp b/src/init.cpp index 53e521983f5..0d98b2b92bb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -607,6 +607,7 @@ bool AppInit2(boost::thread_group& threadGroup) #endif // ********************************************************* Step 2: parameter interactions + const CChainParams& chainparams = Params(); // Set this early so that parameter interactions go to console fPrintToConsole = GetBoolArg("-printtoconsole", false); @@ -699,8 +700,8 @@ bool AppInit2(boost::thread_group& threadGroup) InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench.")); // Checkmempool and checkblockindex default to true in regtest mode - mempool.setSanityCheck(GetBoolArg("-checkmempool", Params().DefaultConsistencyChecks())); - fCheckBlockIndex = GetBoolArg("-checkblockindex", Params().DefaultConsistencyChecks()); + mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks())); + fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); Checkpoints::fEnabled = GetBoolArg("-checkpoints", true); // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency @@ -1043,7 +1044,7 @@ bool AppInit2(boost::thread_group& threadGroup) // If the loaded chain has a wrong genesis, bail out immediately // (we're likely using a testnet datadir, or the other way around). - if (!mapBlockIndex.empty() && mapBlockIndex.count(Params().HashGenesisBlock()) == 0) + if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0) return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); // Initialize the block index (no-op if non-empty database was already loaded) diff --git a/src/main.cpp b/src/main.cpp index 8fb6766301e..247c2c786d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1680,6 +1680,7 @@ static int64_t nTimeTotal = 0; bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) { + const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); // Check it again in case a previous version let a bad block in if (!CheckBlock(block, state, !fJustCheck, !fJustCheck)) @@ -1691,7 +1692,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Special case for the genesis block, skipping connection of its transactions // (its coinbase is unspendable) - if (block.GetHash() == Params().HashGenesisBlock()) { + if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) { if (!fJustCheck) view.SetBestBlock(pindex->GetBlockHash()); return true; @@ -2541,8 +2542,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) { + const Consensus::Params& consensusParams = Params().GetConsensus(); uint256 hash = block.GetHash(); - if (hash == Params().HashGenesisBlock()) + if (hash == consensusParams.hashGenesisBlock) return true; assert(pindexPrev); @@ -2612,6 +2614,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex) { + const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); // Check for duplicate uint256 hash = block.GetHash(); @@ -2632,7 +2635,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc // Get prev block index CBlockIndex* pindexPrev = NULL; - if (hash != Params().HashGenesisBlock()) { + if (hash != chainparams.GetConsensus().hashGenesisBlock) { BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk"); @@ -3119,6 +3122,7 @@ bool InitBlockIndex() { bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) { + const CChainParams& chainparams = Params(); // Map of disk positions for blocks with unknown parent (only used for reindex) static std::multimap mapBlocksUnknownParent; int64_t nStart = GetTimeMillis(); @@ -3164,7 +3168,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) // detect out of order blocks, and store them for later uint256 hash = block.GetHash(); - if (hash != Params().HashGenesisBlock() && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) { + if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) { LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(), block.hashPrevBlock.ToString()); if (dbp) @@ -3179,7 +3183,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) nLoaded++; if (state.IsError()) break; - } else if (hash != Params().HashGenesisBlock() && mapBlockIndex[hash]->nHeight % 1000 == 0) { + } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) { LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight); } @@ -3221,6 +3225,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) void static CheckBlockIndex() { + const Consensus::Params& consensusParams = Params().GetConsensus(); if (!fCheckBlockIndex) { return; } @@ -3263,7 +3268,7 @@ void static CheckBlockIndex() // Begin: actual consistency checks. if (pindex->pprev == NULL) { // Genesis block checks. - assert(pindex->GetBlockHash() == Params().HashGenesisBlock()); // Genesis block's hash must match. + assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match. assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block. } // HAVE_DATA is equivalent to VALID_TRANSACTIONS and equivalent to nTx > 0 (we stored the number of transactions in the block) From ea9e82df739dfc1e84b42cc42c6a65c243cca03d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 13 Apr 2015 15:04:08 +0200 Subject: [PATCH 0377/2337] [squashme] fix listunspent code indentation --- src/wallet/rpcwallet.cpp | 106 +++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 2c3507fb3b7..e03cd5b84ea 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2239,64 +2239,64 @@ Value listunspent(const Array& params, bool fHelp) return Value::null; if (fHelp || params.size() > 3) - throw runtime_error( - "listunspent ( minconf maxconf [\"address\",...] )\n" - "\nReturns array of unspent transaction outputs\n" - "with between minconf and maxconf (inclusive) confirmations.\n" - "Optionally filter to only include txouts paid to specified addresses.\n" - "Results are an array of Objects, each of which has:\n" - "{txid, vout, scriptPubKey, amount, confirmations}\n" - "\nArguments:\n" - "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" - "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" - "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n" - " [\n" - " \"address\" (string) bitcoin address\n" - " ,...\n" - " ]\n" - "\nResult\n" - "[ (array of json object)\n" - " {\n" - " \"txid\" : \"txid\", (string) the transaction id \n" - " \"vout\" : n, (numeric) the vout value\n" - " \"address\" : \"address\", (string) the bitcoin address\n" - " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" - " \"scriptPubKey\" : \"key\", (string) the script key\n" - " \"amount\" : x.xxx, (numeric) the transaction amount in btc\n" - " \"confirmations\" : n (numeric) The number of confirmations\n" - " }\n" - " ,...\n" - "]\n" - - "\nExamples\n" - + HelpExampleCli("listunspent", "") - + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") - + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") - ); - + throw runtime_error( + "listunspent ( minconf maxconf [\"address\",...] )\n" + "\nReturns array of unspent transaction outputs\n" + "with between minconf and maxconf (inclusive) confirmations.\n" + "Optionally filter to only include txouts paid to specified addresses.\n" + "Results are an array of Objects, each of which has:\n" + "{txid, vout, scriptPubKey, amount, confirmations}\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" + "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" + "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n" + " [\n" + " \"address\" (string) bitcoin address\n" + " ,...\n" + " ]\n" + "\nResult\n" + "[ (array of json object)\n" + " {\n" + " \"txid\" : \"txid\", (string) the transaction id \n" + " \"vout\" : n, (numeric) the vout value\n" + " \"address\" : \"address\", (string) the bitcoin address\n" + " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" + " \"scriptPubKey\" : \"key\", (string) the script key\n" + " \"amount\" : x.xxx, (numeric) the transaction amount in btc\n" + " \"confirmations\" : n (numeric) The number of confirmations\n" + " }\n" + " ,...\n" + "]\n" + + "\nExamples\n" + + HelpExampleCli("listunspent", "") + + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + ); + RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type)); - + int nMinDepth = 1; if (params.size() > 0) - nMinDepth = params[0].get_int(); - + nMinDepth = params[0].get_int(); + int nMaxDepth = 9999999; if (params.size() > 1) - nMaxDepth = params[1].get_int(); - + nMaxDepth = params[1].get_int(); + set setAddress; if (params.size() > 2) { Array inputs = params[2].get_array(); BOOST_FOREACH(Value& input, inputs) { CBitcoinAddress address(input.get_str()); if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); - setAddress.insert(address); + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); + setAddress.insert(address); } } - + Array results; vector vecOutputs; assert(pwalletMain != NULL); @@ -2304,17 +2304,17 @@ Value listunspent(const Array& params, bool fHelp) pwalletMain->AvailableCoins(vecOutputs, false); BOOST_FOREACH(const COutput& out, vecOutputs) { if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) - continue; - + continue; + if (setAddress.size()) { CTxDestination address; if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) - continue; - + continue; + if (!setAddress.count(address)) - continue; + continue; } - + CAmount nValue = out.tx->vout[out.i].nValue; const CScript& pk = out.tx->vout[out.i].scriptPubKey; Object entry; @@ -2324,7 +2324,7 @@ Value listunspent(const Array& params, bool fHelp) if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); if (pwalletMain->mapAddressBook.count(address)) - entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); } entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); if (pk.IsPayToScriptHash()) { @@ -2333,7 +2333,7 @@ Value listunspent(const Array& params, bool fHelp) const CScriptID& hash = boost::get(address); CScript redeemScript; if (pwalletMain->GetCScript(hash, redeemScript)) - entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); + entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); } } entry.push_back(Pair("amount",ValueFromAmount(nValue))); @@ -2341,6 +2341,6 @@ Value listunspent(const Array& params, bool fHelp) entry.push_back(Pair("spendable", out.fSpendable)); results.push_back(entry); } - + return results; } \ No newline at end of file From e8e8904ddae09ef9dc444bcdd2955109c9e9ce64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Fri, 10 Apr 2015 18:35:09 +0200 Subject: [PATCH 0378/2337] Chainparams: Cleanup: Delete CChainParams getters to attributes from Consensus::Params --- src/chainparams.h | 4 ---- src/main.cpp | 6 ++++-- src/rpcmining.cpp | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/chainparams.h b/src/chainparams.h index e5e691cc533..d604c1d76e6 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -44,7 +44,6 @@ public: const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - const uint256& ProofOfWorkLimit() const { return consensus.powLimit; } int SubsidyHalvingInterval() const { return consensus.nSubsidyHalvingInterval; } int EnforceBlockUpgradeMajority() const { return consensus.nMajorityEnforceBlockUpgrade; } int RejectBlockOutdatedMajority() const { return consensus.nMajorityRejectBlockOutdated; } @@ -62,9 +61,6 @@ public: bool AllowMinDifficultyBlocks() const { return consensus.fPowAllowMinDifficultyBlocks; } /** Make standard checks */ bool RequireStandard() const { return fRequireStandard; } - int64_t TargetTimespan() const { return consensus.nPowTargetTimespan; } - int64_t TargetSpacing() const { return consensus.nPowTargetSpacing; } - int64_t DifficultyAdjustmentInterval() const { return consensus.nPowTargetTimespan / consensus.nPowTargetSpacing; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ diff --git a/src/main.cpp b/src/main.cpp index 8fb6766301e..5878d3dc079 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3577,6 +3577,7 @@ void static ProcessGetData(CNode* pfrom) bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived) { + const CChainParams& chainparams = Params(); RandAddSeedPerfmon(); LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) @@ -3836,7 +3837,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // not a direct successor. pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); CNodeState *nodestate = State(pfrom->GetId()); - if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20 && + if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vToFetch.push_back(inv); // Mark block as in flight already, even though the actual "getdata" message only goes out @@ -4499,6 +4500,7 @@ bool ProcessMessages(CNode* pfrom) bool SendMessages(CNode* pto, bool fSendTrickle) { + const Consensus::Params& consensusParams = Params().GetConsensus(); { // Don't send anything until we get their version message if (pto->nVersion == 0) @@ -4686,7 +4688,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes // to unreasonably increase our timeout. - if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { + if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * consensusParams.nPowTargetSpacing * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id); pto->fDisconnect = true; } diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 1e6531f68a8..f8cd8791c57 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -45,7 +45,7 @@ Value GetNetworkHashPS(int lookup, int height) { // If lookup is -1, then use blocks since last difficulty change. if (lookup <= 0) - lookup = pb->nHeight % Params().DifficultyAdjustmentInterval() + 1; + lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1; // If lookup is larger than chain, then set it to chain length. if (lookup > pb->nHeight) From eb63bf86cf6dc99f150574463df6ffb013a34493 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 13 Apr 2015 17:55:41 +0100 Subject: [PATCH 0379/2337] Fix missing lock in submitblock --- src/rpcmining.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 1e6531f68a8..949fe3ed524 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -629,14 +629,19 @@ Value submitblock(const Array& params, bool fHelp) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); uint256 hash = block.GetHash(); - BlockMap::iterator mi = mapBlockIndex.find(hash); - if (mi != mapBlockIndex.end()) { - CBlockIndex *pindex = mi->second; - if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) - return "duplicate"; - if (pindex->nStatus & BLOCK_FAILED_MASK) - return "duplicate-invalid"; - // Otherwise, we might only have the header - process the block before returning + bool fBlockPresent = false; + { + LOCK(cs_main); + BlockMap::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) { + CBlockIndex *pindex = mi->second; + if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) + return "duplicate"; + if (pindex->nStatus & BLOCK_FAILED_MASK) + return "duplicate-invalid"; + // Otherwise, we might only have the header - process the block before returning + fBlockPresent = true; + } } CValidationState state; @@ -644,7 +649,7 @@ Value submitblock(const Array& params, bool fHelp) RegisterValidationInterface(&sc); bool fAccepted = ProcessNewBlock(state, NULL, &block); UnregisterValidationInterface(&sc); - if (mi != mapBlockIndex.end()) + if (fBlockPresent) { if (fAccepted && !sc.found) return "duplicate-inconclusive"; From c1ecee8f723c2635fbd51100fa09acdb0cbec8a0 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 13 Apr 2015 12:26:28 -0400 Subject: [PATCH 0380/2337] Set nSequenceId when a block is fully linked Also adds a test to CheckBlockIndex --- src/main.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8fb6766301e..6feebd24b49 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2349,10 +2349,6 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl pindexNew->nUndoPos = 0; pindexNew->nStatus |= BLOCK_HAVE_DATA; pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); - { - LOCK(cs_nBlockSequenceId); - pindexNew->nSequenceId = nBlockSequenceId++; - } setDirtyBlockIndex.insert(pindexNew); if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) { @@ -2365,6 +2361,10 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl CBlockIndex *pindex = queue.front(); queue.pop_front(); pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; + { + LOCK(cs_nBlockSequenceId); + pindex->nSequenceId = nBlockSequenceId++; + } if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) { setBlockIndexCandidates.insert(pindex); } @@ -3269,6 +3269,7 @@ void static CheckBlockIndex() // HAVE_DATA is equivalent to VALID_TRANSACTIONS and equivalent to nTx > 0 (we stored the number of transactions in the block) assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0)); assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); + if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked // All parents having data is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set. assert((pindexFirstMissing != NULL) == (pindex->nChainTx == 0)); // nChainTx == 0 is used to signal that all parent block's transaction data is available. assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0)); From 0421c18f3a261f04e83a03f59884e5798af74fd9 Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Thu, 9 Apr 2015 11:08:39 -0400 Subject: [PATCH 0381/2337] Fix CheckBlockIndex for reindex. Some tests in CheckBlockIndex require chainActive.Tip(), but when reindexing, chainActive has not been set on the first call to CheckBlockIndex. reindex.py starts a node, mines 3 blocks, stops, and reindexes with CheckBlockIndex enabled. --- qa/rpc-tests/reindex.py | 34 ++++++++++++++++++++++++++++++++++ src/main.cpp | 8 ++++++++ 2 files changed, 42 insertions(+) create mode 100755 qa/rpc-tests/reindex.py diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py new file mode 100755 index 00000000000..fe767586bb7 --- /dev/null +++ b/qa/rpc-tests/reindex.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test -reindex with CheckBlockIndex +# +from test_framework import BitcoinTestFramework +from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException +from util import * +import os.path + +class ReindexTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 1) + + def setup_network(self): + self.nodes = [] + self.is_network_split = False + self.nodes.append(start_node(0, self.options.tmpdir)) + + def run_test(self): + self.nodes[0].generate(3) + stop_node(self.nodes[0], 0) + wait_bitcoinds() + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex", "-checkblockindex=1"]) + assert_equal(self.nodes[0].getblockcount(), 3) + print "Success" + +if __name__ == '__main__': + ReindexTest().main() diff --git a/src/main.cpp b/src/main.cpp index 8fb6766301e..a9051118a89 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3227,6 +3227,14 @@ void static CheckBlockIndex() LOCK(cs_main); + // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain, + // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when + // iterating the block tree require that chainActive has been initialized.) + if (chainActive.Height() < 0) { + assert(mapBlockIndex.size() <= 1); + return; + } + // Build forward-pointing map of the entire block tree. std::multimap forward; for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) { From bebe7282ffbfbc260bfc020f1b62710fdfd07cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Fri, 10 Apr 2015 18:42:50 +0200 Subject: [PATCH 0382/2337] Chainparams: Refactor: Remove redundant AllowMinDifficultyBlocks() getter --- src/chainparams.h | 2 -- src/miner.cpp | 22 ++++++++++++---------- src/miner.h | 3 ++- src/rpcmining.cpp | 2 +- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/chainparams.h b/src/chainparams.h index 119a7a81d3c..06920944783 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -56,8 +56,6 @@ public: bool MiningRequiresPeers() const { return fMiningRequiresPeers; } /** Default value for -checkmempool and -checkblockindex argument */ bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } - /** Allow mining of a min-difficulty block */ - bool AllowMinDifficultyBlocks() const { return consensus.fPowAllowMinDifficultyBlocks; } /** Make standard checks */ bool RequireStandard() const { return fRequireStandard; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ diff --git a/src/miner.cpp b/src/miner.cpp index cf08b782296..3abd2d68e40 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -6,11 +6,12 @@ #include "miner.h" #include "amount.h" -#include "primitives/transaction.h" +#include "chainparams.h" #include "hash.h" #include "main.h" #include "net.h" #include "pow.h" +#include "primitives/transaction.h" #include "timedata.h" #include "util.h" #include "utilmoneystr.h" @@ -78,13 +79,13 @@ public: } }; -void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) +void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) { pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); // Updating time can change work required on testnet: - if (Params().AllowMinDifficultyBlocks()) - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); + if (consensusParams.fPowAllowMinDifficultyBlocks) + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams); } CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) @@ -325,7 +326,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - UpdateTime(pblock, pindexPrev); + UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); pblock->nNonce = 0; pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); @@ -440,6 +441,7 @@ void static BitcoinMiner(CWallet *pwallet) LogPrintf("BitcoinMiner started\n"); SetThreadPriority(THREAD_PRIORITY_LOWEST); RenameThread("bitcoin-miner"); + const CChainParams& chainparams = Params(); // Each thread has its own key and counter CReserveKey reservekey(pwallet); @@ -447,7 +449,7 @@ void static BitcoinMiner(CWallet *pwallet) try { while (true) { - if (Params().MiningRequiresPeers()) { + if (chainparams.MiningRequiresPeers()) { // Busy-wait for the network to come online so we don't waste time mining // on an obsolete chain. In regtest mode we expect to fly solo. while (vNodes.empty()) @@ -496,7 +498,7 @@ void static BitcoinMiner(CWallet *pwallet) SetThreadPriority(THREAD_PRIORITY_LOWEST); // In regression test mode, stop mining after a block is found. - if (Params().MineBlocksOnDemand()) + if (chainparams.MineBlocksOnDemand()) throw boost::thread_interrupted(); break; @@ -506,7 +508,7 @@ void static BitcoinMiner(CWallet *pwallet) // Check for stop or if block needs to be rebuilt boost::this_thread::interruption_point(); // Regtest mode doesn't require peers - if (vNodes.empty() && Params().MiningRequiresPeers()) + if (vNodes.empty() && chainparams.MiningRequiresPeers()) break; if (nNonce >= 0xffff0000) break; @@ -516,8 +518,8 @@ void static BitcoinMiner(CWallet *pwallet) break; // Update nTime every few seconds - UpdateTime(pblock, pindexPrev); - if (Params().AllowMinDifficultyBlocks()) + UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); + if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks) { // Changing pblock->nTime can change work required on testnet: hashTarget.SetCompact(pblock->nBits); diff --git a/src/miner.h b/src/miner.h index 5d5c9c86c7c..0be3152d97d 100644 --- a/src/miner.h +++ b/src/miner.h @@ -14,6 +14,7 @@ class CBlockIndex; class CReserveKey; class CScript; class CWallet; +namespace Consensus { class Params; }; struct CBlockTemplate { @@ -29,6 +30,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); -void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); +void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); #endif // BITCOIN_MINER_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 18f0ec0f818..851d113f3be 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -514,7 +514,7 @@ Value getblocktemplate(const Array& params, bool fHelp) CBlock* pblock = &pblocktemplate->block; // pointer for convenience // Update nTime - UpdateTime(pblock, pindexPrev); + UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nNonce = 0; static const Array aCaps = boost::assign::list_of("proposal"); From 5a53d7cda37677f393cddcc483523eb2cbfaf88d Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 12 Dec 2014 10:15:34 +0100 Subject: [PATCH 0383/2337] [Qt] paymentserver: do not log NULL certificates - also add a few more comments in PaymentServer::LoadRootCAs --- src/qt/paymentserver.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index ad489de343f..f05bfc059f6 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -143,13 +143,20 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) int nRootCerts = 0; const QDateTime currentTime = QDateTime::currentDateTime(); - foreach (const QSslCertificate& cert, certList) - { + + foreach (const QSslCertificate& cert, certList) { + // Don't log NULL certificates + if (cert.isNull()) + continue; + + // Not yet active/valid, or expired certificate if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) { ReportInvalidCertificate(cert); continue; } + #if QT_VERSION >= 0x050000 + // Blacklisted certificate if (cert.isBlacklisted()) { ReportInvalidCertificate(cert); continue; From 6e17a747661bc1c737b10f77d1df87d37e49fbb8 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 12 Dec 2014 10:17:56 +0100 Subject: [PATCH 0384/2337] [Qt] paymentserver: better logging of invalid certs Before and after was tested in Windows: before: GUI: ReportInvalidCertificate : Payment server found an invalid certificate: ("Microsoft Authenticode(tm) Root Authority") GUI: ReportInvalidCertificate : Payment server found an invalid certificate: () GUI: ReportInvalidCertificate : Payment server found an invalid certificate: () GUI: ReportInvalidCertificate : Payment server found an invalid certificate: () after: GUI: ReportInvalidCertificate: Payment server found an invalid certificate: "01" ("Microsoft Authenticode(tm) Root Authority") () () GUI: ReportInvalidCertificate: Payment server found an invalid certificate: "01" () () ("Copyright (c) 1997 Microsoft Corp.", "Microsoft Time Stamping Service Root", "Microsoft Corporation") GUI: ReportInvalidCertificate: Payment server found an invalid certificate: "4a:19:d2:38:8c:82:59:1c:a5:5d:73:5f:15:5d:dc:a3" () () ("NO LIABILITY ACCEPTED, (c)97 VeriSign, Inc.", "VeriSign Time Stamping Service Root", "VeriSign, Inc.") GUI: ReportInvalidCertificate: Payment server found an invalid certificate: "e4:9e:fd:f3:3a:e8:0e:cf:a5:11:3e:19:a4:24:02:32" () () ("Class 3 Public Primary Certification Authority") --- src/qt/paymentserver.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index f05bfc059f6..1d35de6f03a 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -97,7 +97,11 @@ static QList savedPaymentRequests; static void ReportInvalidCertificate(const QSslCertificate& cert) { - qDebug() << "ReportInvalidCertificate: Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName); +#if QT_VERSION < 0x050000 + qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName); +#else + qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::DistinguishedNameQualifier) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName); +#endif } // From d19ae3cf665de269c5dc4e2d9ed5ebe954b88be8 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 12 Dec 2014 10:21:07 +0100 Subject: [PATCH 0385/2337] [Qt] remove unused PaymentRequestPlus::getPKIType function --- src/qt/paymentrequestplus.cpp | 6 ------ src/qt/paymentrequestplus.h | 1 - 2 files changed, 7 deletions(-) diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index b69461ad9ed..de222fe1470 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -59,12 +59,6 @@ bool PaymentRequestPlus::IsInitialized() const return paymentRequest.IsInitialized(); } -QString PaymentRequestPlus::getPKIType() const -{ - if (!IsInitialized()) return QString("none"); - return QString::fromStdString(paymentRequest.pki_type()); -} - bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) const { merchant.clear(); diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index 61f8a3415de..99a7186b859 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -29,7 +29,6 @@ public: bool SerializeToString(std::string* output) const; bool IsInitialized() const; - QString getPKIType() const; // Returns true if merchant's identity is authenticated, and // returns human-readable merchant identity in merchant bool getMerchant(X509_STORE* certStore, QString& merchant) const; From 9b14aefee379345a051f2d4cdd92fe8cd52a658d Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 12 Dec 2014 16:14:44 +0100 Subject: [PATCH 0386/2337] [Qt] take care of a missing typecast in PaymentRequestPlus::getMerchant() --- src/qt/paymentrequestplus.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index de222fe1470..7e9729eeb9c 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -118,7 +118,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c // The first cert is the signing cert, the rest are untrusted certs that chain // to a valid root authority. OpenSSL needs them separately. STACK_OF(X509) *chain = sk_X509_new_null(); - for (int i = certs.size()-1; i > 0; i--) { + for (int i = certs.size() - 1; i > 0; i--) { sk_X509_push(chain, certs[i]); } X509 *signing_cert = certs[0]; @@ -166,9 +166,8 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c EVP_MD_CTX_init(&ctx); if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) || !EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) || - !EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), paymentRequest.signature().size(), pubkey)) { - - throw SSLVerifyError("Bad signature, invalid PaymentRequest."); + !EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) { + throw SSLVerifyError("Bad signature, invalid payment request."); } // OpenSSL API for getting human printable strings from certs is baroque. From 35d15959b0b6eb58e87b351d8f58952fa8e90103 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Mon, 12 Jan 2015 14:24:01 +0100 Subject: [PATCH 0387/2337] [Qt] constify first parameter of processPaymentRequest() --- src/qt/paymentserver.cpp | 2 +- src/qt/paymentserver.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 1d35de6f03a..e7c2f6a08ca 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -526,7 +526,7 @@ bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentR return request.parse(data); } -bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient) +bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient) { if (!optionsModel) return false; diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 6bf5ac2eea2..32ed27983eb 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -131,7 +131,7 @@ protected: bool eventFilter(QObject *object, QEvent *event); private: - bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient); + bool processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient); void fetchRequest(const QUrl& url); // Setup networking From 06087bda87214e3f4995a0de65633511d4158d78 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Mon, 12 Jan 2015 14:26:52 +0100 Subject: [PATCH 0388/2337] [Qt] minor comment updates in PaymentServer --- src/qt/paymentserver.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index e7c2f6a08ca..09e9949b103 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -312,7 +312,7 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : // Install global event filter to catch QFileOpenEvents // on Mac: sent when you click bitcoin: links - // other OSes: helpful when dealing with payment request files (in the future) + // other OSes: helpful when dealing with payment request files if (parent) parent->installEventFilter(this); @@ -343,14 +343,13 @@ PaymentServer::~PaymentServer() } // -// OSX-specific way of handling bitcoin: URIs and -// PaymentRequest mime types +// OSX-specific way of handling bitcoin: URIs and PaymentRequest mime types. +// Also used by paymentservertests.cpp and when opening a payment request file +// via "Open URI..." menu entry. // bool PaymentServer::eventFilter(QObject *object, QEvent *event) { - // clicking on bitcoin: URIs creates FileOpen events on the Mac - if (event->type() == QEvent::FileOpen) - { + if (event->type() == QEvent::FileOpen) { QFileOpenEvent *fileEvent = static_cast(event); if (!fileEvent->file().isEmpty()) handleURIOrFile(fileEvent->file()); @@ -571,9 +570,9 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString())); } else if (!recipient.authenticatedMerchant.isEmpty()) { - // Insecure payments to custom bitcoin addresses are not supported - // (there is no good way to tell the user where they are paying in a way - // they'd have a chance of understanding). + // Unauthenticated payment requests to custom bitcoin addresses are not supported + // (there is no good way to tell the user where they are paying in a way they'd + // have a chance of understanding). emit message(tr("Payment request rejected"), tr("Unverified payment requests to custom payment scripts are unsupported."), CClientUIInterface::MSG_ERROR); From 6171e494fcd38a4e9a2921e066c10720a74e0ddb Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Tue, 3 Feb 2015 22:44:33 +0100 Subject: [PATCH 0389/2337] [Qt] Use identical strings for expired payment request message - used in sendcoinsdialog.cpp and paymentserver.cpp - removes an unneded translation string --- src/qt/sendcoinsdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 774667d4ac6..59939fa871a 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -531,7 +531,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000)); break; case WalletModel::PaymentRequestExpired: - msgParams.first = tr("Payment request expired!"); + msgParams.first = tr("Payment request expired."); msgParams.second = CClientUIInterface::MSG_ERROR; break; // included to prevent a compiler warning. From 8ba7f842e5a00e43167e53b456c6d8732b8861c5 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 6 Apr 2015 13:10:33 -0400 Subject: [PATCH 0390/2337] Reduce download timeouts as blocks arrive Compare the block download timeout to what the timeout would be if calculated based on current time and current value of nQueuedValidatedHeaders, but ignoring other in-flight blocks from the same peer. If the calculation based on present conditions is shorter, then set that to be the time after which we disconnect the peer for not delivering this block. --- src/main.cpp | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f0aa3022cdd..bc2e2118435 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -141,8 +141,8 @@ namespace { uint256 hash; CBlockIndex *pindex; //! Optional. int64_t nTime; //! Time of "getdata" request in microseconds. - int nValidatedQueuedBefore; //! Number of blocks queued with validated headers (globally) at the time this one is requested. bool fValidatedHeaders; //! Whether this block has validated headers at the time of request. + int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer) }; map::iterator> > mapBlocksInFlight; @@ -203,6 +203,7 @@ struct CNodeState { int64_t nStallingSince; list vBlocksInFlight; int nBlocksInFlight; + int nBlocksInFlightValidHeaders; //! Whether we consider this a preferred download peer. bool fPreferredDownload; @@ -216,6 +217,7 @@ struct CNodeState { fSyncStarted = false; nStallingSince = 0; nBlocksInFlight = 0; + nBlocksInFlightValidHeaders = 0; fPreferredDownload = false; } }; @@ -247,6 +249,12 @@ void UpdatePreferredDownload(CNode* node, CNodeState* state) nPreferredDownload += state->fPreferredDownload; } +// Returns time at which to timeout block request (nTime in microseconds) +int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore) +{ + return nTime + 500000 * Params().GetConsensus().nPowTargetSpacing * (4 + nValidatedQueuedBefore); +} + void InitializeNode(NodeId nodeid, const CNode *pnode) { LOCK(cs_main); CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second; @@ -279,6 +287,7 @@ void MarkBlockAsReceived(const uint256& hash) { if (itInFlight != mapBlocksInFlight.end()) { CNodeState *state = State(itInFlight->second.first); nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders; + state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders; state->vBlocksInFlight.erase(itInFlight->second.second); state->nBlocksInFlight--; state->nStallingSince = 0; @@ -294,10 +303,12 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex // Make sure it's not listed somewhere already. MarkBlockAsReceived(hash); - QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL}; + int64_t nNow = GetTimeMicros(); + QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders)}; nQueuedValidatedHeaders += newentry.fValidatedHeaders; list::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); state->nBlocksInFlight++; + state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders; mapBlocksInFlight[hash] = std::make_pair(nodeid, it); } @@ -4693,9 +4704,22 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes // to unreasonably increase our timeout. - if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * consensusParams.nPowTargetSpacing * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { - LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id); - pto->fDisconnect = true; + // We also compare the block download timeout originally calculated against the time at which we'd disconnect + // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're + // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a + // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing + // more quickly than once every 5 minutes, then we'll shorten the download window for this block). + if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) { + QueuedBlock &queuedBlock = state.vBlocksInFlight.front(); + int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders); + if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) { + LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow); + queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow; + } + if (queuedBlock.nTimeDisconnect < nNow) { + LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id); + pto->fDisconnect = true; + } } // From 30c43d9821ca54a9fa69b8becce6e1bd8d4f0e25 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 16 Apr 2015 10:32:47 +0200 Subject: [PATCH 0391/2337] miner.h: fix clang warning because of class/struct mix - class 'Params' was previously declared as a struct --- src/miner.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miner.h b/src/miner.h index 0be3152d97d..96a6b70ecd7 100644 --- a/src/miner.h +++ b/src/miner.h @@ -14,7 +14,7 @@ class CBlockIndex; class CReserveKey; class CScript; class CWallet; -namespace Consensus { class Params; }; +namespace Consensus { struct Params; }; struct CBlockTemplate { From b74dcb3b4aa29958d22135f2d6c015578069e83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Thu, 16 Apr 2015 16:20:01 +0200 Subject: [PATCH 0392/2337] Separate CTranslationInterface from CClientUIInterface --- src/bitcoin-cli.cpp | 2 -- src/bitcoin-tx.cpp | 2 -- src/bitcoind.cpp | 1 - src/init.cpp | 2 +- src/qt/bitcoin.cpp | 2 +- src/qt/transactiondesc.cpp | 1 - src/rpcclient.cpp | 1 - src/test/test_bitcoin.cpp | 2 +- src/ui_interface.h | 13 ------------- src/util.cpp | 1 + src/util.h | 20 ++++++++++++++++++++ 11 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 2fa8de6fd83..1269d7a119f 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -12,8 +12,6 @@ #include -#define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */ - using namespace std; using namespace json_spirit; diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 78f5c2c4b6b..075d529408e 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -11,7 +11,6 @@ #include "keystore.h" #include "script/script.h" #include "script/sign.h" -#include "ui_interface.h" // for _(...) #include "univalue/univalue.h" #include "util.h" #include "utilstrencodings.h" @@ -26,7 +25,6 @@ using namespace std; static bool fCreateBlank; static map registers; -CClientUIInterface uiInterface; static bool AppInitRawTx(int argc, char* argv[]) { diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index a0a96c2dfa6..84df00527cb 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -8,7 +8,6 @@ #include "init.h" #include "main.h" #include "noui.h" -#include "ui_interface.h" #include "util.h" #include diff --git a/src/init.cpp b/src/init.cpp index 4d9c233c8c1..7f95b5f9277 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -68,7 +68,7 @@ enum BindFlags { }; static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; -CClientUIInterface uiInterface; +CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h ////////////////////////////////////////////////////////////////////////////// // diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 3ae780abfd8..1abce1eb218 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -533,7 +533,7 @@ int main(int argc, char *argv[]) // Now that QSettings are accessible, initialize translations QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator); - uiInterface.Translate.connect(Translate); + translationInterface.Translate.connect(Translate); // Show help message immediately after parsing command-line options (for "-lang") and setting locale, // but before showing splash screen. diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 9b235f91302..a7f705d2b24 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -14,7 +14,6 @@ #include "main.h" #include "script/script.h" #include "timedata.h" -#include "ui_interface.h" #include "util.h" #include "wallet/wallet.h" diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 428e1049dc1..ccb7cf15e9a 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -7,7 +7,6 @@ #include "rpcprotocol.h" #include "util.h" -#include "ui_interface.h" #include #include diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index a2cb78c9893..4057eccbedf 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -20,7 +20,7 @@ #include #include -CClientUIInterface uiInterface; +CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h CWallet* pwalletMain; extern bool fPrintToConsole; diff --git a/src/ui_interface.h b/src/ui_interface.h index 3f11a1ddabe..32a92a4b81d 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -78,9 +78,6 @@ public: /** Progress message during initialization. */ boost::signals2::signal InitMessage; - /** Translate a message to the native language of the user. */ - boost::signals2::signal Translate; - /** Number of network connections changed. */ boost::signals2::signal NotifyNumConnectionsChanged; @@ -102,14 +99,4 @@ public: extern CClientUIInterface uiInterface; -/** - * Translation function: Call Translate signal on UI interface, which returns a boost::optional result. - * If no translation slot is registered, nothing is returned, and simply return the input. - */ -inline std::string _(const char* psz) -{ - boost::optional rv = uiInterface.Translate(psz); - return rv ? (*rv) : psz; -} - #endif // BITCOIN_UI_INTERFACE_H diff --git a/src/util.cpp b/src/util.cpp index 5fef3a40ddf..78c7731500d 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -104,6 +104,7 @@ string strMiscWarning; bool fLogTimestamps = false; bool fLogIPs = false; volatile bool fReopenDebugLog = false; +CTranslationInterface translationInterface; /** Init OpenSSL library multithreading support */ static CCriticalSection** ppmutexOpenSSL; diff --git a/src/util.h b/src/util.h index 9b5a4153dd9..483d9d78583 100644 --- a/src/util.h +++ b/src/util.h @@ -25,8 +25,17 @@ #include #include +#include #include +/** Signals for translation. */ +class CTranslationInterface +{ +public: + /** Translate a message to the native language of the user. */ + boost::signals2::signal Translate; +}; + extern std::map mapArgs; extern std::map > mapMultiArgs; extern bool fDebug; @@ -37,6 +46,17 @@ extern std::string strMiscWarning; extern bool fLogTimestamps; extern bool fLogIPs; extern volatile bool fReopenDebugLog; +extern CTranslationInterface translationInterface; + +/** + * Translation function: Call Translate signal on UI interface, which returns a boost::optional result. + * If no translation slot is registered, nothing is returned, and simply return the input. + */ +inline std::string _(const char* psz) +{ + boost::optional rv = translationInterface.Translate(psz); + return rv ? (*rv) : psz; +} void SetupEnvironment(); From 67a79493976a3d5f5dac6ec64993fc3f415cac43 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 16 Mar 2015 16:30:49 +0100 Subject: [PATCH 0393/2337] privacy: Stream isolation for Tor According to Tor's extensions to the SOCKS protocol (https://gitweb.torproject.org/torspec.git/tree/socks-extensions.txt) it is possible to perform stream isolation by providing authentication to the proxy. Each set of credentials will create a new circuit, which makes it harder to correlate connections. This patch adds an option, `-proxyrandomize` (on by default) that randomizes credentials for every outgoing connection, thus creating a new circuit. 2015-03-16 15:29:59 SOCKS5 Sending proxy authentication 3842137544:3256031132 --- src/init.cpp | 13 +-- src/netbase.cpp | 180 ++++++++++++++++++++++++---------------- src/netbase.h | 16 +++- src/qt/optionsmodel.cpp | 4 +- src/rpcmisc.cpp | 2 +- src/rpcnet.cpp | 3 +- 6 files changed, 134 insertions(+), 84 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 4d9c233c8c1..8f52d254f4d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -301,6 +301,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1)); strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), 8333, 18333)); strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); + strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), 1)); strUsage += HelpMessageOpt("-seednode=", _("Connect to a node to retrieve peer addresses, and disconnect")); strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); #ifdef USE_UPNP @@ -351,7 +352,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1)); strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0)); } - string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + @@ -891,10 +892,10 @@ bool AppInit2(boost::thread_group& threadGroup) } } - CService addrProxy; + proxyType addrProxy; bool fProxy = false; if (mapArgs.count("-proxy")) { - addrProxy = CService(mapArgs["-proxy"], 9050); + addrProxy = proxyType(CService(mapArgs["-proxy"], 9050), GetArg("-proxyrandomize", true)); if (!addrProxy.IsValid()) return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"])); @@ -904,14 +905,14 @@ bool AppInit2(boost::thread_group& threadGroup) fProxy = true; } - // -onion can override normal proxy, -noonion disables tor entirely + // -onion can override normal proxy, -noonion disables connecting to .onion entirely if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") && (fProxy || mapArgs.count("-onion"))) { - CService addrOnion; + proxyType addrOnion; if (!mapArgs.count("-onion")) addrOnion = addrProxy; else - addrOnion = CService(mapArgs["-onion"], 9050); + addrOnion = proxyType(CService(mapArgs["-onion"], 9050), GetArg("-proxyrandomize", true)); if (!addrOnion.IsValid()) return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs["-onion"])); SetProxy(NET_TOR, addrOnion); diff --git a/src/netbase.cpp b/src/netbase.cpp index a2ac6575bcd..1837cfa9c3f 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -12,6 +12,7 @@ #include "hash.h" #include "sync.h" #include "uint256.h" +#include "random.h" #include "util.h" #include "utilstrencodings.h" @@ -38,7 +39,7 @@ using namespace std; // Settings static proxyType proxyInfo[NET_MAX]; -static CService nameProxy; +static proxyType nameProxy; static CCriticalSection cs_proxyInfos; int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; bool fNameLookup = false; @@ -285,59 +286,100 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock return len == 0; } -bool static Socks5(string strDest, int port, SOCKET& hSocket) +struct ProxyCredentials +{ + std::string username; + std::string password; +}; + +/** Connect using SOCKS5 (as described in RFC1928) */ +bool static Socks5(string strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket) { LogPrintf("SOCKS5 connecting %s\n", strDest); - if (strDest.size() > 255) - { + if (strDest.size() > 255) { CloseSocket(hSocket); return error("Hostname too long"); } - char pszSocks5Init[] = "\5\1\0"; - ssize_t nSize = sizeof(pszSocks5Init) - 1; - - ssize_t ret = send(hSocket, pszSocks5Init, nSize, MSG_NOSIGNAL); - if (ret != nSize) - { + // Accepted authentication methods + std::vector vSocks5Init; + vSocks5Init.push_back(0x05); + if (auth) { + vSocks5Init.push_back(0x02); // # METHODS + vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED + vSocks5Init.push_back(0x02); // X'02' USERNAME/PASSWORD (RFC1929) + } else { + vSocks5Init.push_back(0x01); // # METHODS + vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED + } + ssize_t ret = send(hSocket, (const char*)begin_ptr(vSocks5Init), vSocks5Init.size(), MSG_NOSIGNAL); + if (ret != (ssize_t)vSocks5Init.size()) { CloseSocket(hSocket); return error("Error sending to proxy"); } char pchRet1[2]; - if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) - { + if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { CloseSocket(hSocket); return error("Error reading proxy response"); } - if (pchRet1[0] != 0x05 || pchRet1[1] != 0x00) - { + if (pchRet1[0] != 0x05) { CloseSocket(hSocket); return error("Proxy failed to initialize"); } - string strSocks5("\5\1"); - strSocks5 += '\000'; strSocks5 += '\003'; - strSocks5 += static_cast(std::min((int)strDest.size(), 255)); - strSocks5 += strDest; - strSocks5 += static_cast((port >> 8) & 0xFF); - strSocks5 += static_cast((port >> 0) & 0xFF); - ret = send(hSocket, strSocks5.data(), strSocks5.size(), MSG_NOSIGNAL); - if (ret != (ssize_t)strSocks5.size()) - { + if (pchRet1[1] == 0x02 && auth) { + // Perform username/password authentication (as described in RFC1929) + std::vector vAuth; + vAuth.push_back(0x01); + if (auth->username.size() > 255 || auth->password.size() > 255) + return error("Proxy username or password too long"); + vAuth.push_back(auth->username.size()); + vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end()); + vAuth.push_back(auth->password.size()); + vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end()); + ret = send(hSocket, (const char*)begin_ptr(vAuth), vAuth.size(), MSG_NOSIGNAL); + if (ret != (ssize_t)vAuth.size()) { + CloseSocket(hSocket); + return error("Error sending authentication to proxy"); + } + LogPrint("proxy", "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password); + char pchRetA[2]; + if (!InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + CloseSocket(hSocket); + return error("Error reading proxy authentication response"); + } + if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) { + CloseSocket(hSocket); + return error("Proxy authentication unsuccesful"); + } + } else if (pchRet1[1] == 0x00) { + // Perform no authentication + } else { + CloseSocket(hSocket); + return error("Proxy requested wrong authentication method %02x", pchRet1[1]); + } + std::vector vSocks5; + vSocks5.push_back(0x05); // VER protocol version + vSocks5.push_back(0x01); // CMD CONNECT + vSocks5.push_back(0x00); // RSV Reserved + vSocks5.push_back(0x03); // ATYP DOMAINNAME + vSocks5.push_back(strDest.size()); // Length<=255 is checked at beginning of function + vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end()); + vSocks5.push_back((port >> 8) & 0xFF); + vSocks5.push_back((port >> 0) & 0xFF); + ret = send(hSocket, (const char*)begin_ptr(vSocks5), vSocks5.size(), MSG_NOSIGNAL); + if (ret != (ssize_t)vSocks5.size()) { CloseSocket(hSocket); return error("Error sending to proxy"); } char pchRet2[4]; - if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) - { + if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) { CloseSocket(hSocket); return error("Error reading proxy response"); } - if (pchRet2[0] != 0x05) - { + if (pchRet2[0] != 0x05) { CloseSocket(hSocket); return error("Proxy failed to accept request"); } - if (pchRet2[1] != 0x00) - { + if (pchRet2[1] != 0x00) { CloseSocket(hSocket); switch (pchRet2[1]) { @@ -352,8 +394,7 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket) default: return error("Proxy error: unknown"); } } - if (pchRet2[2] != 0x00) - { + if (pchRet2[2] != 0x00) { CloseSocket(hSocket); return error("Error: malformed proxy response"); } @@ -375,13 +416,11 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket) } default: CloseSocket(hSocket); return error("Error: malformed proxy response"); } - if (!ret) - { + if (!ret) { CloseSocket(hSocket); return error("Error reading from proxy"); } - if (!InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) - { + if (!InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { CloseSocket(hSocket); return error("Error reading from proxy"); } @@ -471,7 +510,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe return true; } -bool SetProxy(enum Network net, CService addrProxy) { +bool SetProxy(enum Network net, const proxyType &addrProxy) { assert(net >= 0 && net < NET_MAX); if (!addrProxy.IsValid()) return false; @@ -489,7 +528,7 @@ bool GetProxy(enum Network net, proxyType &proxyInfoOut) { return true; } -bool SetNameProxy(CService addrProxy) { +bool SetNameProxy(const proxyType &addrProxy) { if (!addrProxy.IsValid()) return false; LOCK(cs_proxyInfos); @@ -497,7 +536,7 @@ bool SetNameProxy(CService addrProxy) { return true; } -bool GetNameProxy(CService &nameProxyOut) { +bool GetNameProxy(proxyType &nameProxyOut) { LOCK(cs_proxyInfos); if(!nameProxy.IsValid()) return false; @@ -513,35 +552,47 @@ bool HaveNameProxy() { bool IsProxy(const CNetAddr &addr) { LOCK(cs_proxyInfos); for (int i = 0; i < NET_MAX; i++) { - if (addr == (CNetAddr)proxyInfo[i]) + if (addr == (CNetAddr)proxyInfo[i].proxy) return true; } return false; } +static bool ConnectThroughProxy(const proxyType &proxy, const std::string strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed) +{ + SOCKET hSocket = INVALID_SOCKET; + // first connect to proxy server + if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout)) { + if (outProxyConnectionFailed) + *outProxyConnectionFailed = true; + return false; + } + // do socks negotiation + if (proxy.randomize_credentials) { + ProxyCredentials random_auth; + random_auth.username = strprintf("%i", insecure_rand()); + random_auth.password = strprintf("%i", insecure_rand()); + if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket)) + return false; + } else { + if (!Socks5(strDest, (unsigned short)port, 0, hSocket)) + return false; + } + + hSocketRet = hSocket; + return true; +} + bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed) { proxyType proxy; if (outProxyConnectionFailed) *outProxyConnectionFailed = false; - // no proxy needed (none set for target network) - if (!GetProxy(addrDest.GetNetwork(), proxy)) + + if (GetProxy(addrDest.GetNetwork(), proxy)) + return ConnectThroughProxy(proxy, addrDest.ToStringIP(), addrDest.GetPort(), hSocketRet, nTimeout, outProxyConnectionFailed); + else // no proxy needed (none set for target network) return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout); - - SOCKET hSocket = INVALID_SOCKET; - - // first connect to proxy server - if (!ConnectSocketDirectly(proxy, hSocket, nTimeout)) { - if (outProxyConnectionFailed) - *outProxyConnectionFailed = true; - return false; - } - // do socks negotiation - if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket)) - return false; - - hSocketRet = hSocket; - return true; } bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed) @@ -554,9 +605,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest SplitHostPort(string(pszDest), port, strDest); - SOCKET hSocket = INVALID_SOCKET; - - CService nameProxy; + proxyType nameProxy; GetNameProxy(nameProxy); CService addrResolved(CNetAddr(strDest, fNameLookup && !HaveNameProxy()), port); @@ -569,18 +618,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest if (!HaveNameProxy()) return false; - // first connect to name proxy server - if (!ConnectSocketDirectly(nameProxy, hSocket, nTimeout)) { - if (outProxyConnectionFailed) - *outProxyConnectionFailed = true; - return false; - } - // do socks negotiation - if (!Socks5(strDest, (unsigned short)port, hSocket)) - return false; - - hSocketRet = hSocket; - return true; + return ConnectThroughProxy(nameProxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed); } void CNetAddr::Init() diff --git a/src/netbase.h b/src/netbase.h index b42c2dffa4d..6d2ca4afb22 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -168,15 +168,25 @@ class CService : public CNetAddr } }; -typedef CService proxyType; +class proxyType +{ +public: + proxyType(): randomize_credentials(false) {} + proxyType(const CService &proxy, bool randomize_credentials=false): proxy(proxy), randomize_credentials(randomize_credentials) {} + + bool IsValid() const { return proxy.IsValid(); } + + CService proxy; + bool randomize_credentials; +}; enum Network ParseNetwork(std::string net); std::string GetNetworkName(enum Network net); void SplitHostPort(std::string in, int &portOut, std::string &hostOut); -bool SetProxy(enum Network net, CService addrProxy); +bool SetProxy(enum Network net, const proxyType &addrProxy); bool GetProxy(enum Network net, proxyType &proxyInfoOut); bool IsProxy(const CNetAddr &addr); -bool SetNameProxy(CService addrProxy); +bool SetNameProxy(const proxyType &addrProxy); bool HaveNameProxy(); bool LookupHost(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true); bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index a169ed6b55a..41d6acf3584 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -335,8 +335,8 @@ bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const proxyType curProxy; if (GetProxy(NET_IPV4, curProxy)) { proxy.setType(QNetworkProxy::Socks5Proxy); - proxy.setHostName(QString::fromStdString(curProxy.ToStringIP())); - proxy.setPort(curProxy.GetPort()); + proxy.setHostName(QString::fromStdString(curProxy.proxy.ToStringIP())); + proxy.setPort(curProxy.proxy.GetPort()); return true; } diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 938d79513f3..f5bef2a0779 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -90,7 +90,7 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("timeoffset", GetTimeOffset())); obj.push_back(Pair("connections", (int)vNodes.size())); - obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.ToStringIPPort() : string()))); + obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string()))); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); #ifdef ENABLE_WALLET diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 6306fd44060..bdee5b9f2e3 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -371,7 +371,8 @@ static Array GetNetworksInfo() obj.push_back(Pair("name", GetNetworkName(network))); obj.push_back(Pair("limited", IsLimited(network))); obj.push_back(Pair("reachable", IsReachable(network))); - obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.ToStringIPPort() : string())); + obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())); + obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials)); networks.push_back(obj); } return networks; From 1d5b47a9033738743e5323409777b1415a0d0af7 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 19 Apr 2015 11:10:13 -0700 Subject: [PATCH 0394/2337] nLastTry is only used for addrman entries No need to define it for every CAddress, as it's memory only anyway. --- src/addrman.cpp | 4 ++-- src/addrman.h | 13 +++++++------ src/net.cpp | 2 +- src/protocol.cpp | 1 - src/protocol.h | 3 --- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 5d9527f0e15..cefd70a1b1a 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -332,10 +332,10 @@ void CAddrMan::Attempt_(const CService& addr, int64_t nTime) info.nAttempts++; } -CAddress CAddrMan::Select_() +CAddrInfo CAddrMan::Select_() { if (size() == 0) - return CAddress(); + return CAddrInfo(); // Use a 50% chance for choosing between tried and new table entries. if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) { diff --git a/src/addrman.h b/src/addrman.h index 8116d0b763d..5badd4ef958 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -22,6 +22,10 @@ */ class CAddrInfo : public CAddress { +public: + //! last try whatsoever by us (memory only) + int64_t nLastTry; + private: //! where knowledge about this address first came from CNetAddr source; @@ -29,9 +33,6 @@ private: //! last successful connection by us int64_t nLastSuccess; - //! last try whatsoever by us: - // int64_t CAddress::nLastTry - //! connection attempts since last successful attempt int nAttempts; @@ -231,7 +232,7 @@ protected: //! Select an address to connect to. //! nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100) - CAddress Select_(); + CAddrInfo Select_(); #ifdef DEBUG_ADDRMAN //! Perform consistency check. Returns an error code or zero. @@ -533,9 +534,9 @@ public: * Choose an address to connect to. * nUnkBias determines how much "new" entries are favored over "tried" ones (0-100). */ - CAddress Select() + CAddrInfo Select() { - CAddress addrRet; + CAddrInfo addrRet; { LOCK(cs); Check(); diff --git a/src/net.cpp b/src/net.cpp index 48e6367f20d..e5f67262ce6 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1221,7 +1221,7 @@ void ThreadOpenConnections() int nTries = 0; while (true) { - CAddress addr = addrman.Select(); + CAddrInfo addr = addrman.Select(); // if we selected an invalid address, restart if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) diff --git a/src/protocol.cpp b/src/protocol.cpp index 568580a595a..dd855aa33aa 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -89,7 +89,6 @@ void CAddress::Init() { nServices = NODE_NETWORK; nTime = 100000000; - nLastTry = 0; } CInv::CInv() diff --git a/src/protocol.h b/src/protocol.h index fd23eae1fc6..b5e65032a21 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -116,9 +116,6 @@ public: // disk and network only unsigned int nTime; - - // memory only - int64_t nLastTry; }; /** inv message data */ From a784f90c9892f06b9fea4e7579f5eca3585482c3 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 19 Apr 2015 11:47:56 -0700 Subject: [PATCH 0395/2337] Cap nAttempts penalty at 8 and switch to pow instead of a division loop. On hosts that had spent some time with a failed internet connection their nAttempts penalty was going through the roof (e.g. thousands for all peers) and as a result the connect search was pegging the CPU and failing to get more than a 4 connections after days of running (because it was taking so long per try). --- src/addrman.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 5d9527f0e15..094c913e9c0 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -67,9 +67,8 @@ double CAddrInfo::GetChance(int64_t nNow) const if (nSinceLastTry < 60 * 10) fChance *= 0.01; - // deprioritize 50% after each failed attempt - for (int n = 0; n < nAttempts; n++) - fChance /= 1.5; + // deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages. + fChance *= pow(0.66, min(nAttempts, 8)); return fChance; } From 2eadeb27ed40d4dcb252a9d993d3946435f6e22e Mon Sep 17 00:00:00 2001 From: dexX7 Date: Mon, 20 Apr 2015 11:50:33 +0200 Subject: [PATCH 0396/2337] QA: stop nodes after RPC tests, even with --nocleanup `--nocleanup` should provide a way to preserve test data, but should not have an impact on whether nodes are to be stopped after the test execution. In particular, when currently running RPC tests with `--nocleanup`, then it may result in several active `bitcoind` processes, which are not terminated properly. --- qa/rpc-tests/test_framework.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework.py b/qa/rpc-tests/test_framework.py index 4c8a11b821d..8de7a4b5e4d 100755 --- a/qa/rpc-tests/test_framework.py +++ b/qa/rpc-tests/test_framework.py @@ -128,10 +128,12 @@ class BitcoinTestFramework(object): print("Unexpected exception caught during testing: "+str(e)) traceback.print_tb(sys.exc_info()[2]) + print("Stopping nodes") + stop_nodes(self.nodes) + wait_bitcoinds() + if not self.options.nocleanup: print("Cleaning up") - stop_nodes(self.nodes) - wait_bitcoinds() shutil.rmtree(self.options.tmpdir) if success: From 60c146938e9b30bb25c639bb3d795942525e3ba1 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 30 Jan 2015 10:08:46 +0100 Subject: [PATCH 0397/2337] [Qt] header group cleanup - seperate core from GUI headers where this was missing - remove an unneeded new-line --- src/qt/bitcoin.cpp | 1 - src/qt/coincontroldialog.cpp | 2 +- src/qt/recentrequeststablemodel.cpp | 3 ++- src/qt/splashscreen.cpp | 5 +++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 3ae780abfd8..069601ab677 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -107,7 +107,6 @@ static QString GetLangTerritory() /** Set up translations */ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator) { - // Remove old translators QApplication::removeTranslator(&qtTranslatorBase); QApplication::removeTranslator(&qtTranslator); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index e4e9015c85d..0a60632bfa2 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -8,12 +8,12 @@ #include "addresstablemodel.h" #include "bitcoinunits.h" #include "guiutil.h" -#include "init.h" #include "optionsmodel.h" #include "scicon.h" #include "walletmodel.h" #include "coincontrol.h" +#include "init.h" #include "main.h" #include "wallet/wallet.h" diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 5221ec3e24a..543b977d8fb 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -5,9 +5,10 @@ #include "recentrequeststablemodel.h" #include "bitcoinunits.h" -#include "clientversion.h" #include "guiutil.h" #include "optionsmodel.h" + +#include "clientversion.h" #include "streams.h" #include diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 414fe02ff9b..8430e017c16 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -4,11 +4,12 @@ #include "splashscreen.h" +#include "networkstyle.h" + #include "clientversion.h" #include "init.h" -#include "networkstyle.h" -#include "ui_interface.h" #include "util.h" +#include "ui_interface.h" #include "version.h" #ifdef ENABLE_WALLET From fa535f9a5bb96895dc62cc975348e0944037596a Mon Sep 17 00:00:00 2001 From: sandakersmann Date: Mon, 2 Feb 2015 15:36:41 +0100 Subject: [PATCH 0398/2337] Remove folder and images for bootstrap.md --- doc/img/bootstrap1.png | Bin 55028 -> 0 bytes doc/img/bootstrap2.png | Bin 35195 -> 0 bytes doc/img/bootstrap4.png | Bin 110060 -> 0 bytes doc/img/bootstrap5.png | Bin 20825 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/img/bootstrap1.png delete mode 100644 doc/img/bootstrap2.png delete mode 100644 doc/img/bootstrap4.png delete mode 100644 doc/img/bootstrap5.png diff --git a/doc/img/bootstrap1.png b/doc/img/bootstrap1.png deleted file mode 100644 index 075930791b6e7adfa28671acf2768adaff400bb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55028 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

_AJVB12%3VER}WuS9PcIh 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%0D*Z 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%0AW|G2d_<1J6MQm(?QJx81uI?iUc37x6 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 DwJ)mq diff --git a/doc/img/bootstrap5.png b/doc/img/bootstrap5.png deleted file mode 100644 index d8d9baaf37acf58203b5c51857fb049ac894a310..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20825 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 Date: Mon, 2 Feb 2015 21:19:50 +0800 Subject: [PATCH 0399/2337] Add x86_64* i686* mips* and arm* to depends .gitignore --- depends/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/depends/.gitignore b/depends/.gitignore index 82c48638b00..1f163897b9e 100644 --- a/depends/.gitignore +++ b/depends/.gitignore @@ -3,3 +3,7 @@ work/ built/ sources/ config.site +x86_64* +i686* +mips* +arm* From 0b2f93091f2a30f994bee2a006d66771b92eacca Mon Sep 17 00:00:00 2001 From: charlescharles Date: Sun, 8 Feb 2015 17:45:13 -0500 Subject: [PATCH 0400/2337] Fix docs for 'complete' field in 'signrawtransaction' response --- src/rpcrawtransaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index c979217a130..8393a8502e1 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -419,7 +419,7 @@ Value signrawtransaction(const Array& params, bool fHelp) "\nResult:\n" "{\n" " \"hex\": \"value\", (string) The raw transaction with signature(s) (hex-encoded string)\n" - " \"complete\": n (numeric) if transaction has a complete set of signature (0 if not)\n" + " \"complete\": true|false (boolean) if transaction has a complete set of signature\n" "}\n" "\nExamples:\n" From 9bdd03fb406da991bc7619b28a609c635cca488b Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Thu, 5 Feb 2015 21:33:27 +0800 Subject: [PATCH 0401/2337] Point to the Debian 7.8 installer Link to 7.7 is broken. --- doc/gitian-building.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 25d3b8390c5..d285fffdbb7 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -74,11 +74,11 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the - Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side - Push the `Create` button -Get the [Debian 7.7 net installer](http://cdimage.debian.org/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). +Get the [Debian 7.8 net installer](http://cdimage.debian.org/debian-cd/7.8.0/amd64/iso-cd/debian-7.8.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). This DVD image can be validated using a SHA256 hashing tool, for example on Unixy OSes by entering the following in a terminal: - echo "d440e85b4121f94608748139f25dbce1ad36771348b002fe07d4d44b9d9e623f debian-7.7.0-amd64-netinst.iso" | sha256sum -c + echo "e39c36d6adc0fd86c6edb0e03e22919086c883b37ca194d063b8e3e8f6ff6a3a debian-7.8.0-amd64-netinst.iso" | sha256sum -c # (must return OK) After creating the VM, we need to configure it. From 30c1db1c612ef2622d4eb72f0b7f12f311cac7cd Mon Sep 17 00:00:00 2001 From: Nicolas Benoit Date: Tue, 24 Feb 2015 18:32:34 +0100 Subject: [PATCH 0402/2337] Replaced current function names with __func__ in LogPrintf() calls. --- src/main.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8dd61a37205..75738dace75 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1233,14 +1233,14 @@ void CheckForkWarningConditions() } if (pindexBestForkTip && pindexBestForkBase) { - LogPrintf("CheckForkWarningConditions: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", + LogPrintf("%s: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", __func__, pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(), pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString()); fLargeWorkForkFound = true; } else { - LogPrintf("CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n"); + LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__); fLargeWorkInvalidChainFound = true; } } @@ -1298,10 +1298,10 @@ void Misbehaving(NodeId pnode, int howmuch) int banscore = GetArg("-banscore", 100); if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore) { - LogPrintf("Misbehaving: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", state->name, state->nMisbehavior-howmuch, state->nMisbehavior); + LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior); state->fShouldBan = true; } else - LogPrintf("Misbehaving: %s (%d -> %d)\n", state->name, state->nMisbehavior-howmuch, state->nMisbehavior); + LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior); } void static InvalidChainFound(CBlockIndex* pindexNew) @@ -1309,11 +1309,11 @@ void static InvalidChainFound(CBlockIndex* pindexNew) if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork) pindexBestInvalid = pindexNew; - LogPrintf("InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n", + LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime())); - LogPrintf("InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s\n", + LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__, chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime())); CheckForkWarningConditions(); @@ -1921,7 +1921,7 @@ void static UpdateTip(CBlockIndex *pindexNew) { nTimeBestReceived = GetTime(); mempool.AddTransactionsUpdated(1); - LogPrintf("UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", + LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", __func__, chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize()); @@ -1941,7 +1941,7 @@ void static UpdateTip(CBlockIndex *pindexNew) { pindex = pindex->pprev; } if (nUpgraded > 0) - LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION); + LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION); if (nUpgraded > 100/2) { // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: @@ -2936,7 +2936,7 @@ bool static LoadBlockIndexDB() // Check whether we have a transaction index pblocktree->ReadFlag("txindex", fTxIndex); - LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled"); + LogPrintf("%s(): transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled"); // Load pointer to end of best chain BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); @@ -2946,7 +2946,7 @@ bool static LoadBlockIndexDB() PruneBlockIndexCandidates(); - LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n", + LogPrintf("%s(): hashBestChain=%s height=%d date=%s progress=%f\n", __func__, chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), Checkpoints::GuessVerificationProgress(chainActive.Tip())); @@ -3492,7 +3492,7 @@ void static ProcessGetData(CNode* pfrom) send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && (mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60); if (!send) { - LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId()); + LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId()); } } } @@ -4394,7 +4394,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, bool ProcessMessages(CNode* pfrom) { //if (fDebug) - // LogPrintf("ProcessMessages(%u messages)\n", pfrom->vRecvMsg.size()); + // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size()); // // Message format @@ -4422,7 +4422,7 @@ bool ProcessMessages(CNode* pfrom) CNetMessage& msg = *it; //if (fDebug) - // LogPrintf("ProcessMessages(message %u msgsz, %u bytes, complete:%s)\n", + // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__, // msg.hdr.nMessageSize, msg.vRecv.size(), // msg.complete() ? "Y" : "N"); @@ -4458,7 +4458,7 @@ bool ProcessMessages(CNode* pfrom) unsigned int nChecksum = ReadLE32((unsigned char*)&hash); if (nChecksum != hdr.nChecksum) { - LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", + LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__, SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum); continue; } @@ -4476,12 +4476,12 @@ bool ProcessMessages(CNode* pfrom) if (strstr(e.what(), "end of data")) { // Allow exceptions from under-length message on vRecv - LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what()); + LogPrintf("%s(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); } else if (strstr(e.what(), "size too large")) { // Allow exceptions from over-long size - LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what()); + LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); } else { @@ -4498,7 +4498,7 @@ bool ProcessMessages(CNode* pfrom) } if (!fRet) - LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id); + LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id); break; } From 52070c87fda663e1f074998fd95fa1dafff667f9 Mon Sep 17 00:00:00 2001 From: Nicolas Benoit Date: Wed, 25 Feb 2015 18:40:32 +0100 Subject: [PATCH 0403/2337] Removed '()' where used without contents inside This additional patch removes '()' from current function name in LogPrintf output. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 75738dace75..c6a936c5cc3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2936,7 +2936,7 @@ bool static LoadBlockIndexDB() // Check whether we have a transaction index pblocktree->ReadFlag("txindex", fTxIndex); - LogPrintf("%s(): transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled"); + LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled"); // Load pointer to end of best chain BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); @@ -2946,7 +2946,7 @@ bool static LoadBlockIndexDB() PruneBlockIndexCandidates(); - LogPrintf("%s(): hashBestChain=%s height=%d date=%s progress=%f\n", __func__, + LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__, chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), Checkpoints::GuessVerificationProgress(chainActive.Tip())); From c0692346654e391fa9bafc0a9a32ea7370751e11 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Wed, 11 Feb 2015 12:24:38 +0800 Subject: [PATCH 0404/2337] Fix typo in init.cpp interpration/interpretation --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 4d9c233c8c1..a3c9a80431d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -123,7 +123,7 @@ public: LogPrintf("Error reading from database: %s\n", e.what()); // Starting the shutdown sequence and returning false to the caller would be // interpreted as 'entry not found' (as opposed to unable to read data), and - // could lead to invalid interpration. Just exit immediately, as we can't + // could lead to invalid interpretation. Just exit immediately, as we can't // continue anyway, and all writes should be atomic. abort(); } From 447d37e7d3e4c1a53eaacaae5f5c34bf98739f22 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Wed, 11 Feb 2015 12:27:21 +0800 Subject: [PATCH 0405/2337] Use https link to bitcoin.org in Doxygen intro --- src/bitcoind.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index a0a96c2dfa6..2172f4a21b5 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -21,7 +21,7 @@ * * \section intro_sec Introduction * - * This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin (http://www.bitcoin.org/), + * This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin (https://www.bitcoin.org/), * which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate * with no central authority: managing transactions and issuing money are carried out collectively by the network. * From abcec3082e4eb3d91ada6144090d7f1ea46b7d3c Mon Sep 17 00:00:00 2001 From: paveljanik Date: Thu, 5 Mar 2015 09:51:52 +0100 Subject: [PATCH 0406/2337] Update REST URL to match reality --- doc/REST-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/REST-interface.md b/doc/REST-interface.md index 23154ee903e..f14aed72877 100644 --- a/doc/REST-interface.md +++ b/doc/REST-interface.md @@ -36,4 +36,4 @@ Only supports JSON as output format. Risks ------------- -Running a webbrowser on the same node with a REST enabled bitcoind can be a risk. Accessing prepared XSS websites could read out tx/block data of your node by placing links like `

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 E18DGLm;e9( literal 163518 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

2-?ujQQE8`RvqF(568WR2s4oD3oO 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%0A6<2e`@J8zd@tF)BB&^`Vfshr`C?W?*4GjmTV0M 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�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

2-?ujQQE8`RvqF(568WR2s4oD3oO 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%0A6<2e`@J8zd@tF)BB&^`Vfshr`C?W?*4GjmTV0M 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�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