aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp25
-rw-r--r--src/main.cpp5
-rw-r--r--src/main.h5
-rw-r--r--src/rpcblockchain.cpp5
-rw-r--r--src/script.cpp167
-rw-r--r--src/test/util_tests.cpp58
-rw-r--r--src/txdb.cpp22
-rw-r--r--src/wallet.cpp44
-rw-r--r--src/wallet.h4
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();
};