aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bitcoin-qt.pro2
-rw-r--r--doc/release-process.txt2
-rw-r--r--src/base58.h53
-rw-r--r--src/bignum.h10
-rw-r--r--src/bitcoinrpc.cpp34
-rw-r--r--src/db.cpp12
-rw-r--r--src/headers.h4
-rw-r--r--src/init.cpp3
-rw-r--r--src/key.cpp117
-rw-r--r--src/key.h132
-rw-r--r--src/keystore.cpp12
-rw-r--r--src/keystore.h59
-rw-r--r--src/main.cpp19
-rw-r--r--src/main.h29
-rw-r--r--src/makefile.linux-mingw2
-rw-r--r--src/makefile.mingw2
-rw-r--r--src/makefile.osx2
-rw-r--r--src/makefile.unix2
-rw-r--r--src/net.cpp23
-rw-r--r--src/net.h12
-rw-r--r--src/protocol.cpp2
-rw-r--r--src/qt/bitcoin.cpp2
-rw-r--r--src/qt/bitcoingui.cpp8
-rw-r--r--src/qt/bitcoingui.h1
-rw-r--r--src/qt/optionsmodel.cpp2
-rw-r--r--src/qt/transactionrecord.cpp2
-rw-r--r--src/rpcdump.cpp101
-rw-r--r--src/serialize.h94
-rw-r--r--src/uint256.h14
-rw-r--r--src/util.cpp40
-rw-r--r--src/util.h42
-rw-r--r--src/wallet.cpp64
-rw-r--r--src/wallet.h15
33 files changed, 600 insertions, 318 deletions
diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro
index cbb92353b7..0bd2113c67 100644
--- a/bitcoin-qt.pro
+++ b/bitcoin-qt.pro
@@ -148,6 +148,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/editaddressdialog.cpp \
src/qt/bitcoinaddressvalidator.cpp \
src/util.cpp \
+ src/key.cpp \
src/script.cpp \
src/main.cpp \
src/init.cpp \
@@ -173,6 +174,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/transactionview.cpp \
src/qt/walletmodel.cpp \
src/bitcoinrpc.cpp \
+ src/rpcdump.cpp \
src/qt/overviewpage.cpp \
src/qt/csvmodelwriter.cpp \
src/crypter.cpp \
diff --git a/doc/release-process.txt b/doc/release-process.txt
index 14d8efeb32..ee1a5d4a34 100644
--- a/doc/release-process.txt
+++ b/doc/release-process.txt
@@ -1,6 +1,6 @@
* update (commit) version in sources
bitcoin-qt.pro
- src/serialize.h
+ src/main.h (CLIENT_VERSION : PROTOCOL_VERSION in serialize.h is updated only on protocol changes)
share/setup.nsi
doc/README*
diff --git a/src/base58.h b/src/base58.h
index cace423d6e..113fa14a5e 100644
--- a/src/base58.h
+++ b/src/base58.h
@@ -18,6 +18,7 @@
#include <string>
#include <vector>
#include "bignum.h"
+#include "key.h"
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
@@ -257,15 +258,14 @@ public:
class CBitcoinAddress : public CBase58Data
{
public:
- bool SetHash160(const uint160& hash160)
+ void SetHash160(const uint160& hash160)
{
SetData(fTestNet ? 111 : 0, &hash160, 20);
- return true;
}
- bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
+ void SetPubKey(const std::vector<unsigned char>& vchPubKey)
{
- return SetHash160(Hash160(vchPubKey));
+ SetHash160(Hash160(vchPubKey));
}
bool IsValid() const
@@ -320,4 +320,49 @@ public:
}
};
+class CBitcoinSecret : public CBase58Data
+{
+public:
+ void SetSecret(const CSecret& vchSecret)
+ {
+ SetData(fTestNet ? 239 : 128, &vchSecret[0], vchSecret.size());
+ }
+
+ CSecret GetSecret()
+ {
+ CSecret vchSecret;
+ vchSecret.resize(vchData.size());
+ memcpy(&vchSecret[0], &vchData[0], vchData.size());
+ return vchSecret;
+ }
+
+ bool IsValid() const
+ {
+ int nExpectedSize = 32;
+ bool fExpectTestNet = false;
+ switch(nVersion)
+ {
+ case 128:
+ break;
+
+ case 239:
+ fExpectTestNet = true;
+ break;
+
+ default:
+ return false;
+ }
+ return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
+ }
+
+ CBitcoinSecret(const CSecret& vchSecret)
+ {
+ SetSecret(vchSecret);
+ }
+
+ CBitcoinSecret()
+ {
+ }
+};
+
#endif
diff --git a/src/bignum.h b/src/bignum.h
index 1a2406b935..135eade679 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -115,9 +115,9 @@ public:
{
unsigned long n = BN_get_word(this);
if (!BN_is_negative(this))
- return (n > INT_MAX ? INT_MAX : n);
+ return (n > std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
else
- return (n > INT_MAX ? INT_MIN : -(int)n);
+ return (n > std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
}
void setint64(int64 n)
@@ -338,19 +338,19 @@ public:
return ToString(16);
}
- unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
+ unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
{
return ::GetSerializeSize(getvch(), nType, nVersion);
}
template<typename Stream>
- void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
+ void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
{
::Serialize(s, getvch(), nType, nVersion);
}
template<typename Stream>
- void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
+ void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
{
std::vector<unsigned char> vch;
::Unserialize(s, vch, nType, nVersion);
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index bb8d8e2d77..fdb1b34a0a 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -9,9 +9,11 @@
#include "init.h"
#undef printf
#include <boost/asio.hpp>
+#include <boost/filesystem.hpp>
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
#ifdef USE_SSL
#include <boost/asio/ssl.hpp>
#include <boost/filesystem.hpp>
@@ -41,6 +43,8 @@ static std::string strRPCUserColonPass;
static int64 nWalletUnlockTime;
static CCriticalSection cs_nWalletUnlockTime;
+extern Value dumpprivkey(const Array& params, bool fHelp);
+extern Value importprivkey(const Array& params, bool fHelp);
Object JSONRPCError(int code, const string& message)
{
@@ -87,7 +91,13 @@ Value ValueFromAmount(int64 amount)
void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
{
- entry.push_back(Pair("confirmations", wtx.GetDepthInMainChain()));
+ int confirms = wtx.GetDepthInMainChain();
+ entry.push_back(Pair("confirmations", confirms));
+ if (confirms)
+ {
+ entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
+ entry.push_back(Pair("blockindex", wtx.nIndex));
+ }
entry.push_back(Pair("txid", wtx.GetHash().GetHex()));
entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime()));
BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
@@ -304,7 +314,8 @@ Value getinfo(const Array& params, bool fHelp)
"Returns an object containing various state info.");
Object obj;
- obj.push_back(Pair("version", (int)VERSION));
+ obj.push_back(Pair("version", (int)CLIENT_VERSION));
+ obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
obj.push_back(Pair("blocks", (int)nBestHeight));
obj.push_back(Pair("connections", (int)vNodes.size()));
@@ -595,7 +606,7 @@ Value verifymessage(const Array& params, bool fHelp)
if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
return false;
- return (key.GetAddress() == addr);
+ return (CBitcoinAddress(key.GetPubKey()) == addr);
}
@@ -939,7 +950,7 @@ struct tallyitem
tallyitem()
{
nAmount = 0;
- nConf = INT_MAX;
+ nConf = std::numeric_limits<int>::max();
}
};
@@ -991,7 +1002,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
continue;
int64 nAmount = 0;
- int nConf = INT_MAX;
+ int nConf = std::numeric_limits<int>::max();
if (it != mapTally.end())
{
nAmount = (*it).second.nAmount;
@@ -1010,7 +1021,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
obj.push_back(Pair("address", address.ToString()));
obj.push_back(Pair("account", strAccount));
obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
- obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
+ obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
ret.push_back(obj);
}
}
@@ -1024,7 +1035,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
Object obj;
obj.push_back(Pair("account", (*it).first));
obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
- obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
+ obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
ret.push_back(obj);
}
}
@@ -1598,7 +1609,6 @@ Value validateaddress(const Array& params, bool fHelp)
return ret;
}
-
Value getwork(const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
@@ -1839,13 +1849,15 @@ pair<string, rpcfn_type> pCallTable[] =
make_pair("sendmany", &sendmany),
make_pair("gettransaction", &gettransaction),
make_pair("listtransactions", &listtransactions),
- make_pair("signmessage", &signmessage),
- make_pair("verifymessage", &verifymessage),
+ make_pair("signmessage", &signmessage),
+ make_pair("verifymessage", &verifymessage),
make_pair("getwork", &getwork),
make_pair("listaccounts", &listaccounts),
make_pair("settxfee", &settxfee),
make_pair("getmemorypool", &getmemorypool),
- make_pair("listsinceblock", &listsinceblock),
+ make_pair("listsinceblock", &listsinceblock),
+ make_pair("dumpprivkey", &dumpprivkey),
+ make_pair("importprivkey", &importprivkey)
};
map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
diff --git a/src/db.cpp b/src/db.cpp
index 9ac93b3506..7195e065ea 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -131,7 +131,7 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
{
bool fTmp = fReadOnly;
fReadOnly = false;
- WriteVersion(VERSION);
+ WriteVersion(CLIENT_VERSION);
fReadOnly = fTmp;
}
@@ -236,7 +236,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
{
// Update version:
ssValue.clear();
- ssValue << VERSION;
+ ssValue << CLIENT_VERSION;
}
Dbt datKey(&ssKey[0], ssKey.size());
Dbt datValue(&ssValue[0], ssValue.size());
@@ -810,7 +810,7 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
ssKey >> hash;
CWalletTx& wtx = pwallet->mapWallet[hash];
ssValue >> wtx;
- wtx.pwallet = pwallet;
+ wtx.BindWallet(pwallet);
if (wtx.GetHash() != hash)
printf("Error in wallet.dat, hash mismatch\n");
@@ -931,7 +931,7 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
{
int nMinVersion = 0;
ssValue >> nMinVersion;
- if (nMinVersion > VERSION)
+ if (nMinVersion > CLIENT_VERSION)
return DB_TOO_NEW;
}
}
@@ -956,13 +956,13 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
if (fIsEncrypted && (nFileVersion == 40000 || nFileVersion == 50000))
return DB_NEED_REWRITE;
- if (nFileVersion < VERSION) // Update
+ if (nFileVersion < CLIENT_VERSION) // Update
{
// Get rid of old debug.log file in current directory
if (nFileVersion <= 105 && !pszSetDataDir[0])
unlink("debug.log");
- WriteVersion(VERSION);
+ WriteVersion(CLIENT_VERSION);
}
return DB_LOAD_OK;
diff --git a/src/headers.h b/src/headers.h
index fd086faee8..b6903fe93e 100644
--- a/src/headers.h
+++ b/src/headers.h
@@ -21,9 +21,6 @@
// Include boost/foreach here as it defines __STDC_LIMIT_MACROS on some systems.
#include <boost/foreach.hpp>
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h
-#endif
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h> // to get BSD define
@@ -44,7 +41,6 @@
#include <stdlib.h>
#include <time.h>
#include <math.h>
-#include <limits.h>
#include <float.h>
#include <assert.h>
#include <iostream>
diff --git a/src/init.cpp b/src/init.cpp
index 0d83b345fc..1e389b226b 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -149,7 +149,10 @@ bool AppInit2(int argc, char* argv[])
//
// Parameters
//
+ // If Qt is used, parameters are parsed in qt/bitcoin.cpp's main()
+#if !defined(QT_GUI)
ParseParameters(argc, argv);
+#endif
if (mapArgs.count("-datadir"))
{
diff --git a/src/key.cpp b/src/key.cpp
new file mode 100644
index 0000000000..400b1887c5
--- /dev/null
+++ b/src/key.cpp
@@ -0,0 +1,117 @@
+// Copyright (c) 2011 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+
+// Generate a private key from just the secret parameter
+int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
+{
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+ EC_POINT *pub_key = NULL;
+
+ if (!eckey) return 0;
+
+ const EC_GROUP *group = EC_KEY_get0_group(eckey);
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+
+ pub_key = EC_POINT_new(group);
+
+ if (pub_key == NULL)
+ goto err;
+
+ if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
+ goto err;
+
+ EC_KEY_set_private_key(eckey,priv_key);
+ EC_KEY_set_public_key(eckey,pub_key);
+
+ ok = 1;
+
+err:
+
+ if (pub_key)
+ EC_POINT_free(pub_key);
+ if (ctx != NULL)
+ BN_CTX_free(ctx);
+
+ return(ok);
+}
+
+// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
+// recid selects which key is recovered
+// if check is nonzero, additional checks are performed
+int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
+{
+ if (!eckey) return 0;
+
+ int ret = 0;
+ BN_CTX *ctx = NULL;
+
+ BIGNUM *x = NULL;
+ BIGNUM *e = NULL;
+ BIGNUM *order = NULL;
+ BIGNUM *sor = NULL;
+ BIGNUM *eor = NULL;
+ BIGNUM *field = NULL;
+ EC_POINT *R = NULL;
+ EC_POINT *O = NULL;
+ EC_POINT *Q = NULL;
+ BIGNUM *rr = NULL;
+ BIGNUM *zero = NULL;
+ int n = 0;
+ int i = recid / 2;
+
+ const EC_GROUP *group = EC_KEY_get0_group(eckey);
+ if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
+ BN_CTX_start(ctx);
+ order = BN_CTX_get(ctx);
+ if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
+ x = BN_CTX_get(ctx);
+ if (!BN_copy(x, order)) { ret=-1; goto err; }
+ if (!BN_mul_word(x, i)) { ret=-1; goto err; }
+ if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
+ field = BN_CTX_get(ctx);
+ if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
+ if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
+ if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
+ if (check)
+ {
+ if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
+ if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
+ if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
+ }
+ if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
+ n = EC_GROUP_get_degree(group);
+ e = BN_CTX_get(ctx);
+ if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
+ if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
+ zero = BN_CTX_get(ctx);
+ if (!BN_zero(zero)) { ret=-1; goto err; }
+ if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
+ rr = BN_CTX_get(ctx);
+ if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
+ sor = BN_CTX_get(ctx);
+ if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
+ eor = BN_CTX_get(ctx);
+ if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
+ if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
+ if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
+
+ ret = 1;
+
+err:
+ if (ctx) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (R != NULL) EC_POINT_free(R);
+ if (O != NULL) EC_POINT_free(O);
+ if (Q != NULL) EC_POINT_free(Q);
+ return ret;
+}
diff --git a/src/key.h b/src/key.h
index df5cfeb32c..94ec55228e 100644
--- a/src/key.h
+++ b/src/key.h
@@ -14,7 +14,6 @@
#include "serialize.h"
#include "uint256.h"
-#include "base58.h"
// secp160k1
// const unsigned int PRIVATE_KEY_SIZE = 192;
@@ -39,116 +38,8 @@
// see www.keylength.com
// script supports up to 75 for single byte push
-// Generate a private key from just the secret parameter
-int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
-{
- int ok = 0;
- BN_CTX *ctx = NULL;
- EC_POINT *pub_key = NULL;
-
- if (!eckey) return 0;
-
- const EC_GROUP *group = EC_KEY_get0_group(eckey);
-
- if ((ctx = BN_CTX_new()) == NULL)
- goto err;
-
- pub_key = EC_POINT_new(group);
-
- if (pub_key == NULL)
- goto err;
-
- if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
- goto err;
-
- EC_KEY_set_private_key(eckey,priv_key);
- EC_KEY_set_public_key(eckey,pub_key);
-
- ok = 1;
-
-err:
-
- if (pub_key)
- EC_POINT_free(pub_key);
- if (ctx != NULL)
- BN_CTX_free(ctx);
-
- return(ok);
-}
-
-// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
-// recid selects which key is recovered
-// if check is nonzero, additional checks are performed
-int static inline ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
-{
- if (!eckey) return 0;
-
- int ret = 0;
- BN_CTX *ctx = NULL;
-
- BIGNUM *x = NULL;
- BIGNUM *e = NULL;
- BIGNUM *order = NULL;
- BIGNUM *sor = NULL;
- BIGNUM *eor = NULL;
- BIGNUM *field = NULL;
- EC_POINT *R = NULL;
- EC_POINT *O = NULL;
- EC_POINT *Q = NULL;
- BIGNUM *rr = NULL;
- BIGNUM *zero = NULL;
- int n = 0;
- int i = recid / 2;
-
- const EC_GROUP *group = EC_KEY_get0_group(eckey);
- if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
- BN_CTX_start(ctx);
- order = BN_CTX_get(ctx);
- if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
- x = BN_CTX_get(ctx);
- if (!BN_copy(x, order)) { ret=-1; goto err; }
- if (!BN_mul_word(x, i)) { ret=-1; goto err; }
- if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
- field = BN_CTX_get(ctx);
- if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
- if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
- if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
- if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
- if (check)
- {
- if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
- if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
- if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
- }
- if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
- n = EC_GROUP_get_degree(group);
- e = BN_CTX_get(ctx);
- if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
- if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
- zero = BN_CTX_get(ctx);
- if (!BN_zero(zero)) { ret=-1; goto err; }
- if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
- rr = BN_CTX_get(ctx);
- if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
- sor = BN_CTX_get(ctx);
- if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
- eor = BN_CTX_get(ctx);
- if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
- if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
- if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
-
- ret = 1;
-
-err:
- if (ctx) {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- if (R != NULL) EC_POINT_free(R);
- if (O != NULL) EC_POINT_free(O);
- if (Q != NULL) EC_POINT_free(Q);
- return ret;
-}
+int extern EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key);
+int extern ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check);
class key_error : public std::runtime_error
{
@@ -287,13 +178,14 @@ public:
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
{
- vchSig.clear();
- unsigned char pchSig[10000];
- unsigned int nSize = 0;
- if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
+ unsigned int nSize = ECDSA_size(pkey);
+ vchSig.resize(nSize); // Make sure it is big enough
+ if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey))
+ {
+ vchSig.clear();
return false;
- vchSig.resize(nSize);
- memcpy(&vchSig[0], pchSig, nSize);
+ }
+ vchSig.resize(nSize); // Shrink to fit actual size
return true;
}
@@ -381,12 +273,6 @@ public:
return false;
return true;
}
-
- // Get the address corresponding to this key
- CBitcoinAddress GetAddress() const
- {
- return CBitcoinAddress(GetPubKey());
- }
};
#endif
diff --git a/src/keystore.cpp b/src/keystore.cpp
index 68f57e7e0e..6cf557fafe 100644
--- a/src/keystore.cpp
+++ b/src/keystore.cpp
@@ -29,7 +29,7 @@ bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned c
bool CBasicKeyStore::AddKey(const CKey& key)
{
CRITICAL_BLOCK(cs_KeyStore)
- mapKeys[key.GetAddress()] = key.GetSecret();
+ mapKeys[CBitcoinAddress(key.GetPubKey())] = key.GetSecret();
return true;
}
@@ -116,23 +116,19 @@ bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey,
return true;
}
-bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
+bool CCryptoKeyStore::GetSecret(const CBitcoinAddress &address, CSecret& vchSecretOut) const
{
CRITICAL_BLOCK(cs_KeyStore)
{
if (!IsCrypted())
- return CBasicKeyStore::GetKey(address, keyOut);
+ return CBasicKeyStore::GetSecret(address, vchSecretOut);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end())
{
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
- CSecret vchSecret;
- if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
- return false;
- keyOut.SetSecret(vchSecret);
- return true;
+ return DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecretOut);
}
}
return false;
diff --git a/src/keystore.h b/src/keystore.h
index 4d889146fc..3b91de6fb4 100644
--- a/src/keystore.h
+++ b/src/keystore.h
@@ -19,17 +19,28 @@ public:
// Check whether a key corresponding to a given address is present in the store.
virtual bool HaveKey(const CBitcoinAddress &address) const =0;
-
- // Retrieve a key corresponding to a given address from the store.
- // Return true if succesful.
- virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
-
- // Retrieve only the public key corresponding to a given address.
- // This may succeed even if GetKey fails (e.g., encrypted wallets)
+ virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
+ {
+ CSecret vchSecret;
+ if (!GetSecret(address, vchSecret))
+ return false;
+ if (!keyOut.SetSecret(vchSecret))
+ return false;
+ return true;
+ }
+ virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
// Generate a new key, and add it to the store
virtual std::vector<unsigned char> GenerateNewKey();
+ virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret) const
+ {
+ CKey key;
+ if (!GetKey(address, key))
+ return false;
+ vchSecret = key.GetSecret();
+ return true;
+ }
};
typedef std::map<CBitcoinAddress, CSecret> KeyMap;
@@ -49,14 +60,27 @@ public:
result = (mapKeys.count(address) > 0);
return result;
}
- bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
+ void GetKeys(std::set<CBitcoinAddress> &setAddress) const
+ {
+ setAddress.clear();
+ CRITICAL_BLOCK(cs_KeyStore)
+ {
+ KeyMap::const_iterator mi = mapKeys.begin();
+ while (mi != mapKeys.end())
+ {
+ setAddress.insert((*mi).first);
+ mi++;
+ }
+ }
+ }
+ bool GetSecret(const CBitcoinAddress &address, CSecret &vchSecret) const
{
CRITICAL_BLOCK(cs_KeyStore)
{
KeyMap::const_iterator mi = mapKeys.find(address);
if (mi != mapKeys.end())
{
- keyOut.SetSecret((*mi).second);
+ vchSecret = (*mi).second;
return true;
}
}
@@ -131,8 +155,23 @@ public:
}
return false;
}
- bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
+ bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret) const;
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
+ void GetKeys(std::set<CBitcoinAddress> &setAddress) const
+ {
+ if (!IsCrypted())
+ {
+ CBasicKeyStore::GetKeys(setAddress);
+ return;
+ }
+ setAddress.clear();
+ CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
+ while (mi != mapCryptedKeys.end())
+ {
+ setAddress.insert((*mi).first);
+ mi++;
+ }
+ }
};
#endif
diff --git a/src/main.cpp b/src/main.cpp
index a7871fcc16..e2f3cc9f84 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -17,6 +17,11 @@ using namespace boost;
// Global state
//
+// Name of client reported in the 'version' message. Report the same name
+// for both bitcoind and bitcoin-qt, to make it harder for attackers to
+// target servers or GUI users specifically.
+const std::string CLIENT_NAME("bitcoin-qt");
+
CCriticalSection cs_setpwalletRegistered;
set<CWallet*> setpwalletRegistered;
@@ -361,7 +366,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
return DoS(100, error("AcceptToMemoryPool() : coinbase as individual tx"));
// To help v0.1.5 clients who would see it as a negative number
- if ((int64)nLockTime > INT_MAX)
+ if ((int64)nLockTime > std::numeric_limits<int>::max())
return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet");
// Safety limits
@@ -516,7 +521,7 @@ bool CTransaction::RemoveFromMemoryPool()
-int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const
+int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
{
if (hashBlock == 0 || nIndex == -1)
return 0;
@@ -537,7 +542,7 @@ int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const
fMerkleVerified = true;
}
- nHeightRet = pindex->nHeight;
+ pindexRet = pindex;
return pindexBest->nHeight - pindex->nHeight + 1;
}
@@ -1847,9 +1852,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Change version
if (pfrom->nVersion >= 209)
pfrom->PushMessage("verack");
- pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
+ pfrom->vSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
if (pfrom->nVersion < 209)
- pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
+ pfrom->vRecv.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
if (!pfrom->fInbound)
{
@@ -1870,7 +1875,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
// Ask the first connected node for block updates
- static int nAskedForBlocks;
+ static int nAskedForBlocks = 0;
if (!pfrom->fClient &&
(pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) &&
(nAskedForBlocks < 1 || vNodes.size() <= 1))
@@ -1902,7 +1907,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
else if (strCommand == "verack")
{
- pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
+ pfrom->vRecv.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
}
diff --git a/src/main.h b/src/main.h
index 3870cee864..67524ef4be 100644
--- a/src/main.h
+++ b/src/main.h
@@ -27,6 +27,10 @@ class CRequestTracker;
class CNode;
class CBlockIndex;
+static const int CLIENT_VERSION = 59900;
+static const bool VERSION_IS_BETA = true;
+extern const std::string CLIENT_NAME;
+
static const unsigned int MAX_BLOCK_SIZE = 1000000;
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
@@ -254,17 +258,17 @@ public:
CTxIn()
{
- nSequence = UINT_MAX;
+ nSequence = std::numeric_limits<unsigned int>::max();
}
- explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
+ explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
{
prevout = prevoutIn;
scriptSig = scriptSigIn;
nSequence = nSequenceIn;
}
- CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
+ CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
{
prevout = COutPoint(hashPrevTx, nOut);
scriptSig = scriptSigIn;
@@ -280,7 +284,7 @@ public:
bool IsFinal() const
{
- return (nSequence == UINT_MAX);
+ return (nSequence == std::numeric_limits<unsigned int>::max());
}
friend bool operator==(const CTxIn& a, const CTxIn& b)
@@ -304,7 +308,7 @@ public:
str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
else
str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
- if (nSequence != UINT_MAX)
+ if (nSequence != std::numeric_limits<unsigned int>::max())
str += strprintf(", nSequence=%u", nSequence);
str += ")";
return str;
@@ -464,7 +468,7 @@ public:
return false;
bool fNewer = false;
- unsigned int nLowest = UINT_MAX;
+ unsigned int nLowest = std::numeric_limits<unsigned int>::max();
for (int i = 0; i < vin.size(); i++)
{
if (vin[i].nSequence != old.vin[i].nSequence)
@@ -695,8 +699,8 @@ public:
int SetMerkleBranch(const CBlock* pblock=NULL);
- int GetDepthInMainChain(int& nHeightRet) const;
- int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
+ int GetDepthInMainChain(CBlockIndex* &pindexRet) const;
+ int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
int GetBlocksToMaturity() const;
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
@@ -758,6 +762,7 @@ public:
return !(a == b);
}
int GetDepthInMainChain() const;
+
};
@@ -1263,6 +1268,11 @@ public:
Set((*mi).second);
}
+ CBlockLocator(const std::vector<uint256>& vHaveIn)
+ {
+ vHave = vHaveIn;
+ }
+
IMPLEMENT_SERIALIZE
(
if (!(nType & SER_GETHASH))
@@ -1521,6 +1531,7 @@ public:
bool AppliesTo(int nVersion, std::string strSubVerIn) const
{
+ // TODO: rework for client-version-embedded-in-strSubVer ?
return (IsInEffect() &&
nMinVer <= nVersion && nVersion <= nMaxVer &&
(setSubVer.empty() || setSubVer.count(strSubVerIn)));
@@ -1528,7 +1539,7 @@ public:
bool AppliesToMe() const
{
- return AppliesTo(VERSION, ::pszSubVer);
+ return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()));
}
bool RelayTo(CNode* pnode) const
diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw
index 61f8d4881f..c96a12182d 100644
--- a/src/makefile.linux-mingw
+++ b/src/makefile.linux-mingw
@@ -64,6 +64,7 @@ LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l w
OBJS= \
obj/checkpoints.o \
obj/crypter.o \
+ obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
@@ -72,6 +73,7 @@ OBJS= \
obj/net.o \
obj/protocol.o \
obj/bitcoinrpc.o \
+ obj/rpcdump.o \
obj/script.o \
obj/util.o \
obj/wallet.o
diff --git a/src/makefile.mingw b/src/makefile.mingw
index 2cb78d97e6..ed718b89ea 100644
--- a/src/makefile.mingw
+++ b/src/makefile.mingw
@@ -61,6 +61,7 @@ LIBS += -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell
OBJS= \
obj/checkpoints.o \
obj/crypter.o \
+ obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
@@ -69,6 +70,7 @@ OBJS= \
obj/net.o \
obj/protocol.o \
obj/bitcoinrpc.o \
+ obj/rpcdump.o \
obj/script.o \
obj/util.o \
obj/wallet.o
diff --git a/src/makefile.osx b/src/makefile.osx
index de71887935..4b0b521a33 100644
--- a/src/makefile.osx
+++ b/src/makefile.osx
@@ -72,6 +72,7 @@ HEADERS = \
OBJS= \
obj/checkpoints.o \
obj/crypter.o \
+ obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
@@ -80,6 +81,7 @@ OBJS= \
obj/net.o \
obj/protocol.o \
obj/bitcoinrpc.o \
+ obj/rpcdump.o \
obj/script.o \
obj/util.o \
obj/wallet.o
diff --git a/src/makefile.unix b/src/makefile.unix
index 6c48199546..a436f968bc 100644
--- a/src/makefile.unix
+++ b/src/makefile.unix
@@ -110,6 +110,7 @@ HEADERS = \
OBJS= \
obj/checkpoints.o \
obj/crypter.o \
+ obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
@@ -118,6 +119,7 @@ OBJS= \
obj/net.o \
obj/protocol.o \
obj/bitcoinrpc.o \
+ obj/rpcdump.o \
obj/script.o \
obj/util.o \
obj/wallet.o
diff --git a/src/net.cpp b/src/net.cpp
index e0ac2abef0..9b8dbe11e8 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -249,8 +249,8 @@ bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMa
else
pszColon[0] = 0;
port = portParsed;
- if (port < 0 || port > USHRT_MAX)
- port = USHRT_MAX;
+ if (port < 0 || port > std::numeric_limits<unsigned short>::max())
+ port = std::numeric_limits<unsigned short>::max();
}
}
@@ -727,6 +727,21 @@ void CNode::Cleanup()
}
+void CNode::PushVersion()
+{
+ /// when NTP implemented, change to just nTime = GetAdjustedTime()
+ int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
+ CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
+ CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
+ RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
+ PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
+ nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
+}
+
+
+
+
+
std::map<unsigned int, int64> CNode::setBanned;
CCriticalSection CNode::cs_setBanned;
@@ -1225,6 +1240,8 @@ void MapPort(bool /* unused fMapPort */)
static const char *strDNSSeed[] = {
"bitseed.xf2.org",
"dnsseed.bluematt.me",
+ "seed.bitcoin.sipa.be",
+ "dnsseed.bitcoin.dashjr.org",
};
void ThreadDNSAddressSeed(void* parg)
@@ -1471,7 +1488,7 @@ void ThreadOpenConnections2(void* parg)
// Choose an address to connect to based on most recently seen
//
CAddress addrConnect;
- int64 nBest = INT64_MIN;
+ int64 nBest = std::numeric_limits<int64>::min();
// Only connect to one address per a.b.?.? range.
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
diff --git a/src/net.h b/src/net.h
index 03da382df3..c2637dc6ac 100644
--- a/src/net.h
+++ b/src/net.h
@@ -355,18 +355,8 @@ public:
- void PushVersion()
- {
- /// when NTP implemented, change to just nTime = GetAdjustedTime()
- int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
- CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
- CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
- RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
- PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
- nLocalHostNonce, std::string(pszSubVer), nBestHeight);
- }
-
+ void PushVersion();
void PushMessage(const char* pszCommand)
diff --git a/src/protocol.cpp b/src/protocol.cpp
index f46570e21c..27efb8f293 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -223,7 +223,7 @@ bool CAddress::IsValid() const
if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
return false;
- return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
+ return (ip != 0 && ip != INADDR_NONE && port != htons(std::numeric_limits<unsigned short>::max()));
}
unsigned char CAddress::GetByte(int n) const
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index dd326a690f..cba4e851b4 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -120,6 +120,8 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(bitcoin);
QApplication app(argc, argv);
+ ParseParameters(argc, argv);
+
// Load language files for system locale:
// - First load the translator for the base language, without territory
// - Then load the more specific locale translator
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 60c75286a7..1c49683364 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -57,6 +57,7 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
walletModel(0),
encryptWalletAction(0),
changePassphraseAction(0),
+ aboutQtAction(0),
trayIcon(0),
notificator(0)
{
@@ -209,7 +210,10 @@ void BitcoinGUI::createActions()
quitAction->setMenuRole(QAction::QuitRole);
aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About %1").arg(qApp->applicationName()), this);
aboutAction->setToolTip(tr("Show information about Bitcoin"));
- aboutAction->setMenuRole(QAction::AboutQtRole);
+ aboutAction->setMenuRole(QAction::AboutRole);
+ aboutQtAction = new QAction(tr("About &Qt"), this);
+ aboutQtAction->setToolTip(tr("Show information about Qt"));
+ aboutQtAction->setMenuRole(QAction::AboutQtRole);
optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
optionsAction->setToolTip(tr("Modify configuration options for bitcoin"));
optionsAction->setMenuRole(QAction::PreferencesRole);
@@ -226,6 +230,7 @@ void BitcoinGUI::createActions()
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
+ connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormal()));
connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
@@ -253,6 +258,7 @@ void BitcoinGUI::createMenuBar()
QMenu *help = appMenuBar->addMenu(tr("&Help"));
help->addAction(aboutAction);
+ help->addAction(aboutQtAction);
}
void BitcoinGUI::createToolBars()
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index ecb356dc35..a0905e44ad 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -82,6 +82,7 @@ private:
QAction *exportAction;
QAction *encryptWalletAction;
QAction *changePassphraseAction;
+ QAction *aboutQtAction;
QSystemTrayIcon *trayIcon;
Notificator *notificator;
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 35d0b57e7e..a68c84c957 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -102,7 +102,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
case ProxyPort:
{
int nPort = atoi(value.toString().toAscii().data());
- if (nPort > 0 && nPort < USHRT_MAX)
+ if (nPort > 0 && nPort < std::numeric_limits<unsigned short>::max())
{
addrProxy.port = htons(nPort);
walletdb.WriteSetting("addrProxy", addrProxy);
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index 77c5a01260..53cd35b2da 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -187,7 +187,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
// Sort order, unrecorded transactions sort to the top
status.sortKey = strprintf("%010d-%01d-%010u-%03d",
- (pindex ? pindex->nHeight : INT_MAX),
+ (pindex ? pindex->nHeight : std::numeric_limits<int>::max()),
(wtx.IsCoinBase() ? 1 : 0),
wtx.nTimeReceived,
idx);
diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp
new file mode 100644
index 0000000000..f3978fbce8
--- /dev/null
+++ b/src/rpcdump.cpp
@@ -0,0 +1,101 @@
+// Copyright (c) 2011 Bitcoin Developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+#include "headers.h"
+#include "init.h" // for pwalletMain
+#include "bitcoinrpc.h"
+
+// #include <boost/asio.hpp>
+// #include <boost/iostreams/concepts.hpp>
+// #include <boost/iostreams/stream.hpp>
+#include <boost/lexical_cast.hpp>
+// #ifdef USE_SSL
+// #include <boost/asio/ssl.hpp>
+// typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
+// #endif
+// #include <boost/xpressive/xpressive_dynamic.hpp>
+#include "json/json_spirit_reader_template.h"
+#include "json/json_spirit_writer_template.h"
+#include "json/json_spirit_utils.h"
+
+#define printf OutputDebugStringF
+
+// using namespace boost::asio;
+using namespace json_spirit;
+using namespace std;
+
+extern Object JSONRPCError(int code, const string& message);
+
+class CTxDump
+{
+public:
+ CBlockIndex *pindex;
+ int64 nValue;
+ bool fSpent;
+ CWalletTx* ptx;
+ int nOut;
+ CTxDump(CWalletTx* ptx = NULL, int nOut = -1)
+ {
+ pindex = NULL;
+ nValue = 0;
+ fSpent = false;
+ this->ptx = ptx;
+ this->nOut = nOut;
+ }
+};
+
+Value importprivkey(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "importprivkey <bitcoinprivkey> [label]\n"
+ "Adds a private key (as returned by dumpprivkey) to your wallet.");
+
+ string strSecret = params[0].get_str();
+ string strLabel = "";
+ if (params.size() > 1)
+ strLabel = params[1].get_str();
+ CBitcoinSecret vchSecret;
+ bool fGood = vchSecret.SetString(strSecret);
+
+ if (!fGood) throw JSONRPCError(-5,"Invalid private key");
+
+ CKey key;
+ key.SetSecret(vchSecret.GetSecret());
+ CBitcoinAddress vchAddress = CBitcoinAddress(key.GetPubKey());
+
+ CRITICAL_BLOCK(cs_main)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
+ {
+ pwalletMain->MarkDirty();
+ pwalletMain->SetAddressBookName(vchAddress, strLabel);
+
+ if (!pwalletMain->AddKey(key))
+ throw JSONRPCError(-4,"Error adding key to wallet");
+
+ pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true);
+ pwalletMain->ReacceptWalletTransactions();
+ }
+
+ MainFrameRepaint();
+
+ return Value::null;
+}
+
+Value dumpprivkey(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "dumpprivkey <bitcoinaddress>\n"
+ "Reveals the private key corresponding to <bitcoinaddress>.");
+
+ string strAddress = params[0].get_str();
+ CBitcoinAddress address;
+ if (!address.SetString(strAddress))
+ throw JSONRPCError(-5, "Invalid bitcoin address");
+ CSecret vchSecret;
+ if (!pwalletMain->GetSecret(address, vchSecret))
+ throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known");
+ return CBitcoinSecret(vchSecret).ToString();
+}
diff --git a/src/serialize.h b/src/serialize.h
index efa59808f5..54555907d8 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -10,7 +10,7 @@
#include <map>
#include <set>
#include <cassert>
-#include <climits>
+#include <limits>
#include <cstring>
#include <cstdio>
@@ -19,16 +19,8 @@
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/tuple/tuple_io.hpp>
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 int64;
-typedef unsigned __int64 uint64;
-#else
typedef long long int64;
typedef unsigned long long uint64;
-#endif
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define for if (false) ; else for
-#endif
#ifdef WIN32
#include <windows.h>
@@ -60,9 +52,7 @@ class CDataStream;
class CAutoFile;
static const unsigned int MAX_SIZE = 0x02000000;
-static const int VERSION = 59900;
-static const char* pszSubVer = "";
-static const bool VERSION_IS_BETA = true;
+static const int PROTOCOL_VERSION = 60000;
// Used to bypass the rule against non-const reference to temporary
// where it makes sense with wrappers such as CFlatData or CTxDB
@@ -91,7 +81,7 @@ enum
};
#define IMPLEMENT_SERIALIZE(statements) \
- unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \
+ unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const \
{ \
CSerActionGetSerializeSize ser_action; \
const bool fGetSize = true; \
@@ -105,7 +95,7 @@ enum
return nSerSize; \
} \
template<typename Stream> \
- void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \
+ void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const \
{ \
CSerActionSerialize ser_action; \
const bool fGetSize = false; \
@@ -115,7 +105,7 @@ enum
{statements} \
} \
template<typename Stream> \
- void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \
+ void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) \
{ \
CSerActionUnserialize ser_action; \
const bool fGetSize = false; \
@@ -199,8 +189,8 @@ template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0
inline unsigned int GetSizeOfCompactSize(uint64 nSize)
{
if (nSize < 253) return sizeof(unsigned char);
- else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short);
- else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int);
+ else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
+ else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
else return sizeof(unsigned char) + sizeof(uint64);
}
@@ -212,14 +202,14 @@ void WriteCompactSize(Stream& os, uint64 nSize)
unsigned char chSize = nSize;
WRITEDATA(os, chSize);
}
- else if (nSize <= USHRT_MAX)
+ else if (nSize <= std::numeric_limits<unsigned short>::max())
{
unsigned char chSize = 253;
unsigned short xSize = nSize;
WRITEDATA(os, chSize);
WRITEDATA(os, xSize);
}
- else if (nSize <= UINT_MAX)
+ else if (nSize <= std::numeric_limits<unsigned int>::max())
{
unsigned char chSize = 254;
unsigned int xSize = nSize;
@@ -362,43 +352,43 @@ template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_st
// vector
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
-template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
+template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
-template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION);
+template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
-template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
+template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
// others derived from vector
-extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
-template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
-template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
+extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
// pair
-template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
+template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
// 3 tuple
-template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
-template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
-template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
+template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
// 4 tuple
-template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
-template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
-template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
+template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=PROTOCOL_VERSION);
// map
-template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
+template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
// set
-template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
+template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
@@ -411,19 +401,19 @@ template<typename Stream, typename K, typename Pred, typename A> void Unserializ
// Thanks to Boost serialization for this idea.
//
template<typename T>
-inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION)
+inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=PROTOCOL_VERSION)
{
return a.GetSerializeSize((int)nType, nVersion);
}
template<typename Stream, typename T>
-inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
+inline void Serialize(Stream& os, const T& a, long nType, int nVersion=PROTOCOL_VERSION)
{
a.Serialize(os, (int)nType, nVersion);
}
template<typename Stream, typename T>
-inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION)
+inline void Unserialize(Stream& is, T& a, long nType, int nVersion=PROTOCOL_VERSION)
{
a.Unserialize(is, (int)nType, nVersion);
}
@@ -857,39 +847,39 @@ public:
typedef vector_type::const_iterator const_iterator;
typedef vector_type::reverse_iterator reverse_iterator;
- explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
+ explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION)
{
Init(nTypeIn, nVersionIn);
}
- CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
+ CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend)
{
Init(nTypeIn, nVersionIn);
}
#if !defined(_MSC_VER) || _MSC_VER >= 1300
- CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
+ CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend)
{
Init(nTypeIn, nVersionIn);
}
#endif
- CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
+ CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end())
{
Init(nTypeIn, nVersionIn);
}
- CDataStream(const std::vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
+ CDataStream(const std::vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end())
{
Init(nTypeIn, nVersionIn);
}
- CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
+ CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
{
Init(nTypeIn, nVersionIn);
}
- void Init(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
+ void Init(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION)
{
nReadPos = 0;
nType = nTypeIn;
@@ -1103,7 +1093,7 @@ public:
}
template<typename Stream>
- void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
+ void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
{
// Special case: stream << stream concatenates like stream += stream
if (!vch.empty())
@@ -1212,7 +1202,7 @@ public:
typedef FILE element_type;
- CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)
+ CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=PROTOCOL_VERSION)
{
file = filenew;
nType = nTypeIn;
diff --git a/src/uint256.h b/src/uint256.h
index 3e20201387..d3da1f26d2 100644
--- a/src/uint256.h
+++ b/src/uint256.h
@@ -11,16 +11,8 @@
#include <string>
#include <vector>
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 int64;
-typedef unsigned __int64 uint64;
-#else
typedef long long int64;
typedef unsigned long long uint64;
-#endif
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define for if (false) ; else for
-#endif
inline int Testuint256AdHoc(std::vector<std::string> vArg);
@@ -364,19 +356,19 @@ public:
}
- unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
+ unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
{
return sizeof(pn);
}
template<typename Stream>
- void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
+ void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
{
s.write((char*)pn, sizeof(pn));
}
template<typename Stream>
- void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
+ void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
{
s.read((char*)pn, sizeof(pn));
}
diff --git a/src/util.cpp b/src/util.cpp
index 236c7f7c44..a45ce33a1c 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -4,6 +4,7 @@
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
#include "strlcpy.h"
+#include <boost/algorithm/string/join.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/filesystem.hpp>
@@ -30,7 +31,7 @@ string strMiscWarning;
bool fTestNet = false;
bool fNoListen = false;
bool fLogTimestamps = false;
-
+CMedianFilter<int64> vTimeOffsets(200,0);
@@ -132,7 +133,7 @@ uint64 GetRand(uint64 nMax)
// The range of the random source must be a multiple of the modulus
// to give every possible output value an equal possibility
- uint64 nRange = (UINT64_MAX / nMax) * nMax;
+ uint64 nRange = (std::numeric_limits<uint64>::max() / nMax) * nMax;
uint64 nRand = 0;
do
RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
@@ -940,15 +941,12 @@ void AddTimeData(unsigned int ip, int64 nTime)
return;
// Add data
- static vector<int64> vTimeOffsets;
- if (vTimeOffsets.empty())
- vTimeOffsets.push_back(0);
- vTimeOffsets.push_back(nOffsetSample);
- printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60);
+ vTimeOffsets.input(nOffsetSample);
+ printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
{
- sort(vTimeOffsets.begin(), vTimeOffsets.end());
- int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
+ int64 nMedian = vTimeOffsets.median();
+ std::vector<int64> vSorted = vTimeOffsets.sorted();
// Only let other nodes change our time by so much
if (abs64(nMedian) < 70 * 60)
{
@@ -963,7 +961,7 @@ void AddTimeData(unsigned int ip, int64 nTime)
{
// If nobody has a time different than ours but within 5 minutes of ours, give a warning
bool fMatch = false;
- BOOST_FOREACH(int64 nOffset, vTimeOffsets)
+ BOOST_FOREACH(int64 nOffset, vSorted)
if (nOffset != 0 && abs64(nOffset) < 5 * 60)
fMatch = true;
@@ -977,9 +975,12 @@ void AddTimeData(unsigned int ip, int64 nTime)
}
}
}
- BOOST_FOREACH(int64 n, vTimeOffsets)
- printf("%+"PRI64d" ", n);
- printf("| nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);
+ if (fDebug) {
+ BOOST_FOREACH(int64 n, vSorted)
+ printf("%+"PRI64d" ", n);
+ printf("| ");
+ }
+ printf("nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);
}
}
@@ -1001,7 +1002,7 @@ string FormatVersion(int nVersion)
string FormatFullVersion()
{
- string s = FormatVersion(VERSION) + pszSubVer;
+ string s = FormatVersion(CLIENT_VERSION);
if (VERSION_IS_BETA) {
s += "-";
s += _("beta");
@@ -1009,6 +1010,17 @@ string FormatFullVersion()
return s;
}
+// Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014)
+std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments)
+{
+ std::ostringstream ss;
+ ss << "/";
+ ss << name << ":" << FormatVersion(nClientVersion);
+ if (!comments.empty())
+ ss << "(" << boost::algorithm::join(comments, "; ") << ")";
+ ss << "/";
+ return ss.str();
+}
diff --git a/src/util.h b/src/util.h
index 7b7eaf6dbb..bb90869962 100644
--- a/src/util.h
+++ b/src/util.h
@@ -25,19 +25,8 @@
#include <openssl/ripemd.h>
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 int64;
-typedef unsigned __int64 uint64;
-#else
typedef long long int64;
typedef unsigned long long uint64;
-#endif
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define for if (false) ; else for
-#endif
-#ifndef _MSC_VER
-#define __forceinline inline
-#endif
#define loop for (;;)
#define BEGIN(a) ((char*)&(a))
@@ -53,7 +42,7 @@ typedef unsigned long long uint64;
#define snprintf my_snprintf
#ifndef PRI64d
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)
+#if defined(_MSC_VER) || defined(__MSVCRT__)
#define PRI64d "I64d"
#define PRI64u "I64u"
#define PRI64x "I64x"
@@ -84,11 +73,7 @@ T* alignup(T* p)
#ifdef WIN32
#define MSG_NOSIGNAL 0
#define MSG_DONTWAIT 0
-#ifndef UINT64_MAX
-#define UINT64_MAX _UI64_MAX
-#define INT64_MAX _I64_MAX
-#define INT64_MIN _I64_MIN
-#endif
+
#ifndef S_IRUSR
#define S_IRUSR 0400
#define S_IWUSR 0200
@@ -204,7 +189,7 @@ void SetMockTime(int64 nMockTimeIn);
int64 GetAdjustedTime();
void AddTimeData(unsigned int ip, int64 nTime);
std::string FormatFullVersion();
-
+std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
@@ -474,15 +459,6 @@ inline bool GetBoolArg(const std::string& strArg)
-inline void heapchk()
-{
-#ifdef WIN32
- /// for debugging
- //if (_heapchk() != _HEAPOK)
- // DebugBreak();
-#endif
-}
-
// Randomize the stack to help protect against buffer overrun exploits
#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
{ \
@@ -558,7 +534,7 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end,
}
template<typename T>
-uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)
+uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
{
// Most of the time is spent allocating and deallocating CDataStream's
// buffer. If this ever needs to be optimized further, make a CStaticStream
@@ -622,6 +598,16 @@ public:
return (vSorted[size/2-1] + vSorted[size/2]) / 2;
}
}
+
+ int size() const
+ {
+ return vValues.size();
+ }
+
+ std::vector<T> sorted () const
+ {
+ return vSorted;
+ }
};
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 28babdb3e2..c6f5795c0b 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -224,6 +224,15 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
}
}
+void CWallet::MarkDirty()
+{
+ CRITICAL_BLOCK(cs_wallet)
+ {
+ BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
+ item.second.MarkDirty();
+ }
+}
+
bool CWallet::AddToWallet(const CWalletTx& wtxIn)
{
uint256 hash = wtxIn.GetHash();
@@ -232,7 +241,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
// Inserts only if not already there, returns tx inserted or tx found
pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
CWalletTx& wtx = (*ret.first).second;
- wtx.pwallet = this;
+ wtx.BindWallet(this);
bool fInsertedNew = ret.second;
if (fInsertedNew)
wtx.nTimeReceived = GetAdjustedTime();
@@ -299,7 +308,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
// Add a transaction to the wallet, or update it.
// pblock is optional, but should be provided if the transaction is known to be in a block.
// If fUpdate is true, existing transactions will be updated.
-bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
+bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
{
uint256 hash = tx.GetHash();
CRITICAL_BLOCK(cs_wallet)
@@ -586,6 +595,15 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
return ret;
}
+int CWallet::ScanForWalletTransaction(const uint256& hashTx)
+{
+ CTransaction tx;
+ tx.ReadFromDisk(COutPoint(hashTx, 0));
+ if (AddToWalletIfInvolvingMe(tx, NULL, true, true))
+ return 1;
+ return 0;
+}
+
void CWallet::ReacceptWalletTransactions()
{
CTxDB txdb("r");
@@ -764,7 +782,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
// List of values less than target
pair<int64, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
- coinLowestLarger.first = INT64_MAX;
+ coinLowestLarger.first = std::numeric_limits<int64>::max();
coinLowestLarger.second.first = NULL;
vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
int64 nTotalLower = 0;
@@ -924,7 +942,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
if (vecSend.empty() || nValue < 0)
return false;
- wtxNew.pwallet = this;
+ wtxNew.BindWallet(this);
CRITICAL_BLOCK(cs_main)
CRITICAL_BLOCK(cs_wallet)
@@ -1062,7 +1080,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
{
CWalletTx &coin = mapWallet[txin.prevout.hash];
- coin.pwallet = this;
+ coin.BindWallet(this);
coin.MarkSpent(txin.prevout.n);
coin.WriteToDisk();
vWalletUpdated.push_back(coin.GetHash());
@@ -1325,6 +1343,22 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
}
}
+int64 CWallet::AddReserveKey(const CKeyPool& keypool)
+{
+ CRITICAL_BLOCK(cs_main)
+ CRITICAL_BLOCK(cs_wallet)
+ {
+ CWalletDB walletdb(strWalletFile);
+
+ int64 nIndex = 1 + *(--setKeyPool.end());
+ if (!walletdb.WritePool(nIndex, keypool))
+ throw runtime_error("AddReserveKey() : writing added key failed");
+ setKeyPool.insert(nIndex);
+ return nIndex;
+ }
+ return -1;
+}
+
void CWallet::KeepKey(int64 nIndex)
{
// Remove from key pool
@@ -1413,3 +1447,23 @@ void CReserveKey::ReturnKey()
vchPubKey.clear();
}
+void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
+{
+ setAddress.clear();
+
+ CWalletDB walletdb(strWalletFile);
+
+ CRITICAL_BLOCK(cs_main)
+ CRITICAL_BLOCK(cs_wallet)
+ BOOST_FOREACH(const int64& id, setKeyPool)
+ {
+ CKeyPool keypool;
+ if (!walletdb.ReadPool(id, keypool))
+ throw runtime_error("GetAllReserveKeyHashes() : read failed");
+ CBitcoinAddress address(keypool.vchPubKey);
+ assert(!keypool.vchPubKey.empty());
+ if (!HaveKey(address))
+ throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
+ setAddress.insert(address);
+ }
+}
diff --git a/src/wallet.h b/src/wallet.h
index ca7cf67317..78f055a604 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -74,11 +74,13 @@ public:
bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
bool EncryptWallet(const SecureString& strWalletPassphrase);
+ void MarkDirty();
bool AddToWallet(const CWalletTx& wtxIn);
- bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false);
+ bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false);
bool EraseFromWallet(uint256 hash);
void WalletUpdateSpent(const CTransaction& prevout);
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
+ int ScanForWalletTransaction(const uint256& hashTx);
void ReacceptWalletTransactions();
void ResendWalletTransactions();
int64 GetBalance() const;
@@ -92,11 +94,13 @@ public:
bool NewKeyPool();
bool TopUpKeyPool();
+ int64 AddReserveKey(const CKeyPool& keypool);
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
void KeepKey(int64 nIndex);
void ReturnKey(int64 nIndex);
bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true);
int64 GetOldestKeyPoolTime();
+ void GetAllReserveAddresses(std::set<CBitcoinAddress>& setAddress);
bool IsMine(const CTxIn& txin) const;
int64 GetDebit(const CTxIn& txin) const;
@@ -243,9 +247,10 @@ public:
//
class CWalletTx : public CMerkleTx
{
-public:
+private:
const CWallet* pwallet;
+public:
std::vector<CMerkleTx> vtxPrev;
std::map<std::string, std::string> mapValue;
std::vector<std::pair<std::string, std::string> > vOrderForm;
@@ -389,6 +394,12 @@ public:
fChangeCached = false;
}
+ void BindWallet(CWallet *pwalletIn)
+ {
+ pwallet = pwalletIn;
+ MarkDirty();
+ }
+
void MarkSpent(unsigned int nOut)
{
if (nOut >= vout.size())