diff options
-rw-r--r-- | src/init.cpp | 25 | ||||
-rw-r--r-- | src/main.cpp | 5 | ||||
-rw-r--r-- | src/main.h | 5 | ||||
-rw-r--r-- | src/rpcblockchain.cpp | 5 | ||||
-rw-r--r-- | src/script.cpp | 167 | ||||
-rw-r--r-- | src/test/util_tests.cpp | 58 | ||||
-rw-r--r-- | src/txdb.cpp | 22 | ||||
-rw-r--r-- | src/wallet.cpp | 44 | ||||
-rw-r--r-- | src/wallet.h | 4 |
9 files changed, 75 insertions, 260 deletions
diff --git a/src/init.cpp b/src/init.cpp index 3845cfad81..3775790b68 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -290,8 +290,7 @@ std::string HelpMessage() " -? " + _("This help message") + "\n" + " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n" + " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n" + - " -gen " + _("Generate coins") + "\n" + - " -gen=0 " + _("Don't generate coins") + "\n" + + " -gen " + _("Generate coins (default: 0)") + "\n" + " -datadir=<dir> " + _("Specify data directory") + "\n" + " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" + " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n" + @@ -358,7 +357,7 @@ std::string HelpMessage() " -txindex " + _("Maintain a full transaction index (default: 0)") + "\n" + " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + "\n" + " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + "\n" + - " -par=N " + _("Set the number of script verification threads (up to 16, 0=auto, negative=leave N CPUs free, default: 0)") + "\n" + + " -par=<n> " + _("Set the number of script verification threads (up to 16, 0 = auto, <0 = leave that many cores free, default: 0)") + "\n" + "\n" + _("Block creation options:") + "\n" + " -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n" + @@ -466,9 +465,9 @@ bool AppInit2(boost::thread_group& threadGroup) // Initialize Windows Sockets WSADATA wsadata; int ret = WSAStartup(MAKEWORD(2,2), &wsadata); - if (ret != NO_ERROR) + if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2) { - return InitError(strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret)); + return InitError(strprintf("Error: Winsock library failed to start (WSAStartup returned error %d)", ret)); } #endif #ifndef WIN32 @@ -612,7 +611,7 @@ bool AppInit2(boost::thread_group& threadGroup) if (!fLogTimestamps) printf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str()); printf("Default data directory %s\n", GetDefaultDataDir().string().c_str()); - printf("Used data directory %s\n", strDataDir.c_str()); + printf("Using data directory %s\n", strDataDir.c_str()); printf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD); std::ostringstream strErrors; @@ -967,11 +966,11 @@ bool AppInit2(boost::thread_group& threadGroup) RandAddSeedPerfmon(); CPubKey newDefaultKey; - if (!pwalletMain->GetKeyFromPool(newDefaultKey, false)) - strErrors << _("Cannot initialize keypool") << "\n"; - pwalletMain->SetDefaultKey(newDefaultKey); - if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), "")) - strErrors << _("Cannot write default address") << "\n"; + if (pwalletMain->GetKeyFromPool(newDefaultKey, false)) { + pwalletMain->SetDefaultKey(newDefaultKey); + if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), "")) + strErrors << _("Cannot write default address") << "\n"; + } } printf("%s", strErrors.str().c_str()); @@ -988,6 +987,8 @@ bool AppInit2(boost::thread_group& threadGroup) CBlockLocator locator; if (walletdb.ReadBestBlock(locator)) pindexRescan = locator.GetBlockIndex(); + else + pindexRescan = pindexGenesisBlock; } if (pindexBest && pindexBest != pindexRescan) { @@ -996,6 +997,8 @@ bool AppInit2(boost::thread_group& threadGroup) nStart = GetTimeMillis(); pwalletMain->ScanForWalletTransactions(pindexRescan, true); printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart); + pwalletMain->SetBestChain(CBlockLocator(pindexBest)); + nWalletDBUpdated++; } // ********************************************************* Step 9: import blocks diff --git a/src/main.cpp b/src/main.cpp index aace382d8b..45fb7af005 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4158,7 +4158,10 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); txNew.vout.resize(1); - txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; + CPubKey pubkey; + if (!reservekey.GetReservedKey(pubkey)) + return NULL; + txNew.vout[0].scriptPubKey << pubkey << OP_CHECKSIG; // Add our coinbase tx as first transaction pblock->vtx.push_back(txNew); diff --git a/src/main.h b/src/main.h index 24b2cb2aa6..e02edbc529 100644 --- a/src/main.h +++ b/src/main.h @@ -2096,11 +2096,14 @@ extern CTxMemPool mempool; struct CCoinsStats { int nHeight; + uint256 hashBlock; uint64 nTransactions; uint64 nTransactionOutputs; uint64 nSerializedSize; + uint256 hashSerialized; + int64 nTotalAmount; - CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0) {} + CCoinsStats() : nHeight(0), hashBlock(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), hashSerialized(0), nTotalAmount(0) {} }; /** Abstract view on the open txout dataset. */ diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 2200679050..11af1abf5d 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -172,10 +172,13 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) CCoinsStats stats; if (pcoinsTip->GetStats(stats)) { - ret.push_back(Pair("bestblock", pcoinsTip->GetBestBlock()->GetBlockHash().GetHex())); + ret.push_back(Pair("height", (boost::int64_t)stats.nHeight)); + ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); ret.push_back(Pair("transactions", (boost::int64_t)stats.nTransactions)); ret.push_back(Pair("txouts", (boost::int64_t)stats.nTransactionOutputs)); ret.push_back(Pair("bytes_serialized", (boost::int64_t)stats.nSerializedSize)); + ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); + ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); } return ret; } diff --git a/src/script.cpp b/src/script.cpp index 5e5cd096cd..90066efd33 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -54,32 +54,6 @@ bool CastToBool(const valtype& vch) return false; } -// -// WARNING: This does not work as expected for signed integers; the sign-bit -// is left in place as the integer is zero-extended. The correct behavior -// would be to move the most significant bit of the last byte during the -// resize process. MakeSameSize() is currently only used by the disabled -// opcodes OP_AND, OP_OR, and OP_XOR. -// -void MakeSameSize(valtype& vch1, valtype& vch2) -{ - // Lengthen the shorter one - if (vch1.size() < vch2.size()) - // PATCH: - // +unsigned char msb = vch1[vch1.size()-1]; - // +vch1[vch1.size()-1] &= 0x7f; - // vch1.resize(vch2.size(), 0); - // +vch1[vch1.size()-1] = msb; - vch1.resize(vch2.size(), 0); - if (vch2.size() < vch1.size()) - // PATCH: - // +unsigned char msb = vch2[vch2.size()-1]; - // +vch2[vch2.size()-1] &= 0x7f; - // vch2.resize(vch1.size(), 0); - // +vch2[vch2.size()-1] = msb; - vch2.resize(vch1.size(), 0); -} - // @@ -361,7 +335,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT) - return false; + return false; // Disabled opcodes. if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) stack.push_back(vchPushValue); @@ -659,64 +633,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co break; - // - // Splice ops - // - case OP_CAT: - { - // (x1 x2 -- out) - if (stack.size() < 2) - return false; - valtype& vch1 = stacktop(-2); - valtype& vch2 = stacktop(-1); - vch1.insert(vch1.end(), vch2.begin(), vch2.end()); - popstack(stack); - if (stacktop(-1).size() > MAX_SCRIPT_ELEMENT_SIZE) - return false; - } - break; - - case OP_SUBSTR: - { - // (in begin size -- out) - if (stack.size() < 3) - return false; - valtype& vch = stacktop(-3); - int nBegin = CastToBigNum(stacktop(-2)).getint(); - int nEnd = nBegin + CastToBigNum(stacktop(-1)).getint(); - if (nBegin < 0 || nEnd < nBegin) - return false; - if (nBegin > (int)vch.size()) - nBegin = vch.size(); - if (nEnd > (int)vch.size()) - nEnd = vch.size(); - vch.erase(vch.begin() + nEnd, vch.end()); - vch.erase(vch.begin(), vch.begin() + nBegin); - popstack(stack); - popstack(stack); - } - break; - - case OP_LEFT: - case OP_RIGHT: - { - // (in size -- out) - if (stack.size() < 2) - return false; - valtype& vch = stacktop(-2); - int nSize = CastToBigNum(stacktop(-1)).getint(); - if (nSize < 0) - return false; - if (nSize > (int)vch.size()) - nSize = vch.size(); - if (opcode == OP_LEFT) - vch.erase(vch.begin() + nSize, vch.end()); - else - vch.erase(vch.begin(), vch.end() - nSize); - popstack(stack); - } - break; - case OP_SIZE: { // (in -- in size) @@ -731,51 +647,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // // Bitwise logic // - case OP_INVERT: - { - // (in - out) - if (stack.size() < 1) - return false; - valtype& vch = stacktop(-1); - for (unsigned int i = 0; i < vch.size(); i++) - vch[i] = ~vch[i]; - } - break; - - // - // WARNING: These disabled opcodes exhibit unexpected behavior - // when used on signed integers due to a bug in MakeSameSize() - // [see definition of MakeSameSize() above]. - // - case OP_AND: - case OP_OR: - case OP_XOR: - { - // (x1 x2 - out) - if (stack.size() < 2) - return false; - valtype& vch1 = stacktop(-2); - valtype& vch2 = stacktop(-1); - MakeSameSize(vch1, vch2); // <-- NOT SAFE FOR SIGNED VALUES - if (opcode == OP_AND) - { - for (unsigned int i = 0; i < vch1.size(); i++) - vch1[i] &= vch2[i]; - } - else if (opcode == OP_OR) - { - for (unsigned int i = 0; i < vch1.size(); i++) - vch1[i] |= vch2[i]; - } - else if (opcode == OP_XOR) - { - for (unsigned int i = 0; i < vch1.size(); i++) - vch1[i] ^= vch2[i]; - } - popstack(stack); - } - break; - case OP_EQUAL: case OP_EQUALVERIFY: //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL @@ -810,8 +681,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // case OP_1ADD: case OP_1SUB: - case OP_2MUL: - case OP_2DIV: case OP_NEGATE: case OP_ABS: case OP_NOT: @@ -825,8 +694,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { case OP_1ADD: bn += bnOne; break; case OP_1SUB: bn -= bnOne; break; - case OP_2MUL: bn <<= 1; break; - case OP_2DIV: bn >>= 1; break; case OP_NEGATE: bn = -bn; break; case OP_ABS: if (bn < bnZero) bn = -bn; break; case OP_NOT: bn = (bn == bnZero); break; @@ -840,11 +707,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co case OP_ADD: case OP_SUB: - case OP_MUL: - case OP_DIV: - case OP_MOD: - case OP_LSHIFT: - case OP_RSHIFT: case OP_BOOLAND: case OP_BOOLOR: case OP_NUMEQUAL: @@ -873,33 +735,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co bn = bn1 - bn2; break; - case OP_MUL: - if (!BN_mul(&bn, &bn1, &bn2, pctx)) - return false; - break; - - case OP_DIV: - if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) - return false; - break; - - case OP_MOD: - if (!BN_mod(&bn, &bn1, &bn2, pctx)) - return false; - break; - - case OP_LSHIFT: - if (bn2 < bnZero || bn2 > CBigNum(2048)) - return false; - bn = bn1 << bn2.getulong(); - break; - - case OP_RSHIFT: - if (bn2 < bnZero || bn2 > CBigNum(2048)) - return false; - bn = bn1 >> bn2.getulong(); - break; - case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; case OP_NUMEQUAL: bn = (bn1 == bn2); break; diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 2d05794cc7..1b0ccad511 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -323,62 +323,4 @@ BOOST_AUTO_TEST_CASE(util_seed_insecure_rand) } } -static int nCounter = 0; - -static void Count() -{ - ++nCounter; - MilliSleep(10); -} - -static void CountWithArg(int arg) -{ - nCounter += arg; - MilliSleep(10); -} - -BOOST_AUTO_TEST_CASE(util_loop_forever1) -{ - boost::thread_group threadGroup; - - threadGroup.create_thread(boost::bind(&LoopForever<void (*)()>, "count", &Count, 1)); - MilliSleep(1); - threadGroup.interrupt_all(); - BOOST_CHECK_EQUAL(nCounter, 1); - nCounter = 0; -} - -BOOST_AUTO_TEST_CASE(util_loop_forever2) -{ - boost::thread_group threadGroup; - - boost::function<void()> f = boost::bind(&CountWithArg, 11); - threadGroup.create_thread(boost::bind(&LoopForever<boost::function<void()> >, "count11", f, 11)); - MilliSleep(1); - threadGroup.interrupt_all(); - BOOST_CHECK_EQUAL(nCounter, 11); - nCounter = 0; -} - -BOOST_AUTO_TEST_CASE(util_threadtrace1) -{ - boost::thread_group threadGroup; - - threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "count11", &Count)); - threadGroup.join_all(); - BOOST_CHECK_EQUAL(nCounter, 1); - nCounter = 0; -} - -BOOST_AUTO_TEST_CASE(util_threadtrace2) -{ - boost::thread_group threadGroup; - - boost::function<void()> f = boost::bind(&CountWithArg, 11); - threadGroup.create_thread(boost::bind(&TraceThread<boost::function<void()> >, "count11", f)); - threadGroup.join_all(); - BOOST_CHECK_EQUAL(nCounter, 11); - nCounter = 0; -} - BOOST_AUTO_TEST_SUITE_END() diff --git a/src/txdb.cpp b/src/txdb.cpp index 5b0527c76c..3d34710d22 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -5,6 +5,7 @@ #include "txdb.h" #include "main.h" +#include "hash.h" using namespace std; @@ -114,6 +115,10 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) { leveldb::Iterator *pcursor = db.NewIterator(); pcursor->SeekToFirst(); + CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); + stats.hashBlock = GetBestBlock()->GetBlockHash(); + ss << stats.hashBlock; + int64 nTotalAmount = 0; while (pcursor->Valid()) { boost::this_thread::interruption_point(); try { @@ -128,13 +133,22 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) { ssValue >> coins; uint256 txhash; ssKey >> txhash; - + ss << txhash; + ss << VARINT(coins.nVersion); + ss << (coins.fCoinBase ? 'c' : 'n'); + ss << VARINT(coins.nHeight); stats.nTransactions++; - BOOST_FOREACH(const CTxOut &out, coins.vout) { - if (!out.IsNull()) + for (unsigned int i=0; i<coins.vout.size(); i++) { + const CTxOut &out = coins.vout[i]; + if (!out.IsNull()) { stats.nTransactionOutputs++; + ss << VARINT(i+1); + ss << out; + nTotalAmount += out.nValue; + } } stats.nSerializedSize += 32 + slValue.size(); + ss << VARINT(0); } pcursor->Next(); } catch (std::exception &e) { @@ -143,6 +157,8 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) { } delete pcursor; stats.nHeight = GetBestBlock()->nHeight; + stats.hashSerialized = ss.GetHash(); + stats.nTotalAmount = nTotalAmount; return true; } diff --git a/src/wallet.cpp b/src/wallet.cpp index c7eb4f74e8..a56d53e7e3 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -71,6 +71,11 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char return false; } +bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) +{ + return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); +} + bool CWallet::AddCScript(const CScript& redeemScript) { if (!CCryptoKeyStore::AddCScript(redeemScript)) @@ -457,17 +462,19 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) return false; #ifndef QT_GUI // If default receiving address gets used, replace it with a new one - CScript scriptDefaultKey; - scriptDefaultKey.SetDestination(vchDefaultKey.GetID()); - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - { - if (txout.scriptPubKey == scriptDefaultKey) + if (vchDefaultKey.IsValid()) { + CScript scriptDefaultKey; + scriptDefaultKey.SetDestination(vchDefaultKey.GetID()); + BOOST_FOREACH(const CTxOut& txout, wtx.vout) { - CPubKey newDefaultKey; - if (GetKeyFromPool(newDefaultKey, false)) + if (txout.scriptPubKey == scriptDefaultKey) { - SetDefaultKey(newDefaultKey); - SetAddressBookName(vchDefaultKey.GetID(), ""); + CPubKey newDefaultKey; + if (GetKeyFromPool(newDefaultKey, false)) + { + SetDefaultKey(newDefaultKey); + SetAddressBookName(vchDefaultKey.GetID(), ""); + } } } } @@ -1199,8 +1206,8 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW // post-backup change. // Reserve a new key pair from key pool - CPubKey vchPubKey = reservekey.GetReservedKey(); - // assert(mapKeys.count(vchPubKey)); + CPubKey vchPubKey; + assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked // Fill a vout to ourself // TODO: pass in scriptChange instead of reservekey so @@ -1737,7 +1744,7 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings() return ret; } -CPubKey CReserveKey::GetReservedKey() +bool CReserveKey::GetReservedKey(CPubKey& pubkey) { if (nIndex == -1) { @@ -1745,14 +1752,17 @@ CPubKey CReserveKey::GetReservedKey() pwallet->ReserveKeyFromKeyPool(nIndex, keypool); if (nIndex != -1) vchPubKey = keypool.vchPubKey; - else - { - printf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!"); - vchPubKey = pwallet->vchDefaultKey; + else { + if (pwallet->vchDefaultKey.IsValid()) { + printf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!"); + vchPubKey = pwallet->vchDefaultKey; + } else + return false; } } assert(vchPubKey.IsValid()); - return vchPubKey; + pubkey = vchPubKey; + return true; } void CReserveKey::KeepKey() diff --git a/src/wallet.h b/src/wallet.h index 2e007557b0..19f50e7e6d 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -145,7 +145,7 @@ public: // Adds an encrypted key to the store, and saves it to disk. bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) - bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } + bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); bool AddCScript(const CScript& redeemScript); bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); } @@ -331,7 +331,7 @@ public: } void ReturnKey(); - CPubKey GetReservedKey(); + bool GetReservedKey(CPubKey &pubkey); void KeepKey(); }; |