aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am11
-rw-r--r--src/alert.cpp4
-rw-r--r--src/bitcoin-cli.cpp86
-rw-r--r--src/coincontrol.h4
-rw-r--r--src/crypter.h4
-rw-r--r--src/eccryptoverify.cpp5
-rw-r--r--src/eccryptoverify.h12
-rw-r--r--src/ecwrapper.cpp4
-rw-r--r--src/ecwrapper.h4
-rw-r--r--src/hash.cpp4
-rw-r--r--src/hash.h3
-rw-r--r--src/init.cpp23
-rw-r--r--src/key.cpp4
-rw-r--r--src/key.h4
-rw-r--r--src/leveldbwrapper.cpp3
-rw-r--r--src/main.cpp51
-rw-r--r--src/net.cpp161
-rw-r--r--src/net.h4
-rw-r--r--src/pubkey.cpp2
-rw-r--r--src/pubkey.h4
-rw-r--r--src/qt/bitcoingui.cpp6
-rw-r--r--src/qt/bitcoingui.h1
-rw-r--r--src/qt/forms/rpcconsole.ui2
-rw-r--r--src/qt/optionsdialog.cpp7
-rw-r--r--src/qt/optionsdialog.h2
-rw-r--r--src/qt/trafficgraphwidget.cpp8
-rw-r--r--src/random.cpp5
-rw-r--r--src/random.h2
-rw-r--r--src/rpcprotocol.h1
-rw-r--r--src/rpcserver.cpp24
-rw-r--r--src/rpcserver.h7
-rw-r--r--src/script/sign.cpp8
-rw-r--r--src/script/sign.h2
-rw-r--r--src/script/standard.h4
-rw-r--r--src/test/script_tests.cpp47
-rw-r--r--src/util.cpp4
-rw-r--r--src/wallet.cpp6
37 files changed, 287 insertions, 246 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 3089b2ff40..8b5d009842 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -171,6 +171,7 @@ libbitcoin_server_a_SOURCES = \
rpcnet.cpp \
rpcrawtransaction.cpp \
rpcserver.cpp \
+ script/sigcache.cpp \
timedata.cpp \
txdb.cpp \
txmempool.cpp \
@@ -232,7 +233,6 @@ libbitcoin_common_a_SOURCES = \
pubkey.cpp \
script/interpreter.cpp \
script/script.cpp \
- script/sigcache.cpp \
script/sign.cpp \
script/standard.cpp \
$(BITCOIN_CORE_H)
@@ -301,13 +301,10 @@ bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS)
# bitcoin-cli binary #
bitcoin_cli_LDADD = \
$(LIBBITCOIN_CLI) \
- $(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
- $(LIBBITCOIN_CRYPTO) \
$(BOOST_LIBS) \
$(SSL_LIBS) \
- $(CRYPTO_LIBS) \
- $(MINIUPNPC_LIBS)
+ $(CRYPTO_LIBS)
bitcoin_cli_SOURCES = \
bitcoin-cli.cpp
@@ -330,9 +327,7 @@ if USE_LIBSECP256K1
endif
bitcoin_tx_LDADD += $(BOOST_LIBS) \
- $(SSL_LIBS) \
- $(CRYPTO_LIBS) \
- $(MINIUPNPC_LIBS)
+ $(CRYPTO_LIBS)
bitcoin_tx_SOURCES = bitcoin-tx.cpp
bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES)
diff --git a/src/alert.cpp b/src/alert.cpp
index ce8dfbf507..64399a4260 100644
--- a/src/alert.cpp
+++ b/src/alert.cpp
@@ -1,14 +1,14 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "alert.h"
#include "chainparams.h"
#include "clientversion.h"
-#include "pubkey.h"
#include "net.h"
+#include "pubkey.h"
#include "timedata.h"
#include "ui_interface.h"
#include "util.h"
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 38fbc29faf..a2b95d5086 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -5,7 +5,6 @@
#include "chainparamsbase.h"
#include "clientversion.h"
-#include "init.h"
#include "rpcclient.h"
#include "rpcprotocol.h"
#include "util.h"
@@ -46,6 +45,21 @@ std::string HelpMessageCli()
//
// Start
//
+
+//
+// Exception thrown on connection error. This error is used to determine
+// when to wait if -rpcwait is given.
+//
+class CConnectionFailed : public std::runtime_error
+{
+public:
+
+ explicit inline CConnectionFailed(const std::string& msg) :
+ std::runtime_error(msg)
+ {}
+
+};
+
static bool AppInitRPC(int argc, char* argv[])
{
//
@@ -101,15 +115,9 @@ Object CallRPC(const string& strMethod, const Array& params)
SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
- bool fWait = GetBoolArg("-rpcwait", false); // -rpcwait means try until server has started
- do {
- bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
- if (fConnected) break;
- if (fWait)
- MilliSleep(1000);
- else
- throw runtime_error("couldn't connect to server");
- } while (fWait);
+ const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
+ if (!fConnected)
+ throw CConnectionFailed("couldn't connect to server");
// HTTP basic authentication
string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
@@ -168,27 +176,43 @@ int CommandLineRPC(int argc, char *argv[])
std::vector<std::string> strParams(&argv[2], &argv[argc]);
Array params = RPCConvertValues(strMethod, strParams);
- // Execute
- Object reply = CallRPC(strMethod, params);
-
- // Parse reply
- const Value& result = find_value(reply, "result");
- const Value& error = find_value(reply, "error");
-
- if (error.type() != null_type) {
- // Error
- strPrint = "error: " + write_string(error, false);
- int code = find_value(error.get_obj(), "code").get_int();
- nRet = abs(code);
- } else {
- // Result
- if (result.type() == null_type)
- strPrint = "";
- else if (result.type() == str_type)
- strPrint = result.get_str();
- else
- strPrint = write_string(result, true);
- }
+ // Execute and handle connection failures with -rpcwait
+ const bool fWait = GetBoolArg("-rpcwait", false);
+ do {
+ try {
+ const Object reply = CallRPC(strMethod, params);
+
+ // Parse reply
+ const Value& result = find_value(reply, "result");
+ const Value& error = find_value(reply, "error");
+
+ if (error.type() != null_type) {
+ // Error
+ const int code = find_value(error.get_obj(), "code").get_int();
+ if (fWait && code == RPC_IN_WARMUP)
+ throw CConnectionFailed("server in warmup");
+ strPrint = "error: " + write_string(error, false);
+ nRet = abs(code);
+ } else {
+ // Result
+ if (result.type() == null_type)
+ strPrint = "";
+ else if (result.type() == str_type)
+ strPrint = result.get_str();
+ else
+ strPrint = write_string(result, true);
+ }
+
+ // Connection succeeded, no need to retry.
+ break;
+ }
+ catch (const CConnectionFailed& e) {
+ if (fWait)
+ MilliSleep(1000);
+ else
+ throw;
+ }
+ } while (fWait);
}
catch (boost::thread_interrupted) {
throw;
diff --git a/src/coincontrol.h b/src/coincontrol.h
index c9057017d8..c8bdd3b39d 100644
--- a/src/coincontrol.h
+++ b/src/coincontrol.h
@@ -35,12 +35,12 @@ public:
return (setSelected.count(outpt) > 0);
}
- void Select(COutPoint& output)
+ void Select(const COutPoint& output)
{
setSelected.insert(output);
}
- void UnSelect(COutPoint& output)
+ void UnSelect(const COutPoint& output)
{
setSelected.erase(output);
}
diff --git a/src/crypter.h b/src/crypter.h
index 4d486c4313..b589987c4f 100644
--- a/src/crypter.h
+++ b/src/crypter.h
@@ -1,13 +1,13 @@
// Copyright (c) 2009-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CRYPTER_H
#define BITCOIN_CRYPTER_H
#include "allocators.h"
-#include "serialize.h"
#include "keystore.h"
+#include "serialize.h"
class uint256;
diff --git a/src/eccryptoverify.cpp b/src/eccryptoverify.cpp
index 0a904f44ba..435154d608 100644
--- a/src/eccryptoverify.cpp
+++ b/src/eccryptoverify.cpp
@@ -1,3 +1,8 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#include "eccryptoverify.h"
namespace {
diff --git a/src/eccryptoverify.h b/src/eccryptoverify.h
index 7740e31db1..da7e80c7c3 100644
--- a/src/eccryptoverify.h
+++ b/src/eccryptoverify.h
@@ -1,13 +1,14 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_EC_CRYPTO_VERIFY_H
-#define BITCOIN_EC_CRYPTO_VERIFY_H
+#ifndef BITCOIN_ECCRYPTOVERIFY_H
+#define BITCOIN_ECCRYPTOVERIFY_H
#include <vector>
#include <cstdlib>
+
class uint256;
namespace eccrypto {
@@ -16,4 +17,5 @@ bool Check(const unsigned char *vch);
bool CheckSignatureElement(const unsigned char *vch, int len, bool half);
} // eccrypto namespace
-#endif
+
+#endif // BITCOIN_ECCRYPTOVERIFY_H
diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp
index ebaa350264..3377dce0c1 100644
--- a/src/ecwrapper.cpp
+++ b/src/ecwrapper.cpp
@@ -193,7 +193,7 @@ bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) {
return o2i_ECPublicKey(&pkey, &pubkey, size) != NULL;
}
-bool CECKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lowS) {
+bool CECKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) {
vchSig.clear();
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
if (sig == NULL)
@@ -205,7 +205,7 @@ bool CECKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool
BIGNUM *halforder = BN_CTX_get(ctx);
EC_GROUP_get_order(group, order, ctx);
BN_rshift1(halforder, order);
- if (lowS && BN_cmp(sig->s, halforder) > 0) {
+ if (BN_cmp(sig->s, halforder) > 0) {
// enforce low S values, by negating the value (modulo the order) if above order/2.
BN_sub(sig->s, order, sig->s);
}
diff --git a/src/ecwrapper.h b/src/ecwrapper.h
index 52e9e5dab0..a7847d190c 100644
--- a/src/ecwrapper.h
+++ b/src/ecwrapper.h
@@ -28,7 +28,7 @@ public:
bool SetPrivKey(const unsigned char* privkey, size_t size, bool fSkipCheck=false);
void GetPubKey(std::vector<unsigned char>& pubkey, bool fCompressed);
bool SetPubKey(const unsigned char* pubkey, size_t size);
- bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lowS);
+ bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig);
bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig);
bool SignCompact(const uint256 &hash, unsigned char *p64, int &rec);
@@ -43,4 +43,4 @@ public:
static bool SanityCheck();
};
-#endif // BITCOIN_EC_WRAPPER_H
+#endif // BITCOIN_ECWRAPPER_H
diff --git a/src/hash.cpp b/src/hash.cpp
index 29376b45aa..2cca06ae23 100644
--- a/src/hash.cpp
+++ b/src/hash.cpp
@@ -1,3 +1,7 @@
+// Copyright (c) 2013-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#include "hash.h"
inline uint32_t ROTL32(uint32_t x, int8_t r)
diff --git a/src/hash.h b/src/hash.h
index 53a7672a8f..75695160e6 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_HASH_H
@@ -160,4 +160,5 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
void BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
+
#endif // BITCOIN_HASH_H
diff --git a/src/init.cpp b/src/init.cpp
index d622af69ef..b290d54158 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -320,7 +320,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += ".\n";
#ifdef ENABLE_WALLET
strUsage += " -gen " + strprintf(_("Generate coins (default: %u)"), 0) + "\n";
- strUsage += " -genproclimit=<n> " + strprintf(_("Set the processor limit for when generation is on (-1 = unlimited, default: %d)"), -1) + "\n";
+ strUsage += " -genproclimit=<n> " + strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1) + "\n";
#endif
strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n";
strUsage += " -logips " + strprintf(_("Include IP addresses in debug output (default: %u)"), 0) + "\n";
@@ -574,6 +574,9 @@ bool AppInit2(boost::thread_group& threadGroup)
// to protect privacy, do not listen by default if a default proxy server is specified
if (SoftSetBoolArg("-listen", false))
LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -listen=0\n");
+ // to protect privacy, do not discover addresses by default
+ if (SoftSetBoolArg("-discover", false))
+ LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -discover=0\n");
}
if (!GetBoolArg("-listen", true)) {
@@ -746,12 +749,23 @@ bool AppInit2(boost::thread_group& threadGroup)
LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
std::ostringstream strErrors;
+ LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads);
if (nScriptCheckThreads) {
- LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads);
for (int i=0; i<nScriptCheckThreads-1; i++)
threadGroup.create_thread(&ThreadScriptCheck);
}
+ /* Start the RPC server already. It will be started in "warmup" mode
+ * and not really process calls already (but it will signify connections
+ * that the server is there and will be ready later). Warmup mode will
+ * be disabled when initialisation is finished.
+ */
+ if (fServer)
+ {
+ uiInterface.InitMessage.connect(SetRPCWarmupStatus);
+ StartRPCThreads();
+ }
+
int64_t nStart;
// ********************************************************* Step 5: verify wallet database integrity
@@ -1248,17 +1262,16 @@ bool AppInit2(boost::thread_group& threadGroup)
#endif
StartNode(threadGroup);
- if (fServer)
- StartRPCThreads();
#ifdef ENABLE_WALLET
// Generate coins in the background
if (pwalletMain)
- GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", -1));
+ GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
#endif
// ********************************************************* Step 11: finished
+ SetRPCWarmupFinished();
uiInterface.InitMessage(_("Done loading"));
#ifdef ENABLE_WALLET
diff --git a/src/key.cpp b/src/key.cpp
index 1b539d073a..0ca9a681a3 100644
--- a/src/key.cpp
+++ b/src/key.cpp
@@ -102,7 +102,7 @@ CPubKey CKey::GetPubKey() const {
return result;
}
-bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lowS) const {
+bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
if (!fValid)
return false;
#ifdef USE_SECP256K1
@@ -119,7 +119,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lo
#else
CECKey key;
key.SetSecretBytes(vch);
- return key.Sign(hash, vchSig, lowS);
+ return key.Sign(hash, vchSig);
#endif
}
diff --git a/src/key.h b/src/key.h
index b35cf0cad5..0bb05482c9 100644
--- a/src/key.h
+++ b/src/key.h
@@ -13,8 +13,8 @@
#include <stdexcept>
#include <vector>
+struct CExtPubKey;
class CPubKey;
-class CExtPubKey;
/**
* secp256k1:
@@ -122,7 +122,7 @@ public:
CPubKey GetPubKey() const;
//! Create a DER-serialized signature.
- bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool lowS = true) const;
+ bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig) const;
/**
* Create a compact signature (65 bytes), which allows reconstructing the used public key.
diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp
index 8ce3e7b470..70980fede5 100644
--- a/src/leveldbwrapper.cpp
+++ b/src/leveldbwrapper.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2012-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "leveldbwrapper.h"
@@ -7,6 +7,7 @@
#include "util.h"
#include <boost/filesystem.hpp>
+
#include <leveldb/cache.h>
#include <leveldb/env.h>
#include <leveldb/filter_policy.h>
diff --git a/src/main.cpp b/src/main.cpp
index 82d52913a0..2bff781bfa 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1760,9 +1760,9 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
}
// Update the on-disk chain state.
-bool static WriteChainState(CValidationState &state) {
+bool static WriteChainState(CValidationState &state, bool forceWrite=false) {
static int64_t nLastWrite = 0;
- if (pcoinsTip->GetCacheSize() > nCoinCacheSize || (!IsInitialBlockDownload() && GetTimeMicros() > nLastWrite + 600*1000000)) {
+ if (forceWrite || pcoinsTip->GetCacheSize() > nCoinCacheSize || (!IsInitialBlockDownload() && GetTimeMicros() > nLastWrite + 600*1000000)) {
// Typical CCoins structures on disk are around 100 bytes in size.
// Pushing a new one to the database can cause it to be written
// twice (once in the log, and once in the tables). This is already
@@ -3022,6 +3022,8 @@ bool InitBlockIndex() {
return error("LoadBlockIndex() : genesis block not accepted");
if (!ActivateBestChain(state, &block))
return error("LoadBlockIndex() : genesis block cannot be activated");
+ // Force a chainstate write so that when we VerifyDB in a moment, it doesnt check stale data
+ return WriteChainState(state, true);
} catch(std::runtime_error &e) {
return error("LoadBlockIndex() : failed to initialize block database: %s", e.what());
}
@@ -3157,12 +3159,14 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
}
// process in case the block isn't known yet
- if (mapBlockIndex.count(hash) == 0) {
+ if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
CValidationState state;
if (ProcessNewBlock(state, NULL, &block, dbp))
nLoaded++;
if (state.IsError())
break;
+ } else if (hash != Params().HashGenesisBlock() && mapBlockIndex[hash]->nHeight % 1000 == 0) {
+ LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
}
// Recursively process earlier encountered successors of this block
@@ -3474,12 +3478,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else
pfrom->fRelayTxes = true;
- if (pfrom->fInbound && addrMe.IsRoutable())
- {
- pfrom->addrLocal = addrMe;
- SeenLocal(addrMe);
- }
-
// Disconnect if we connected to ourself
if (nNonce == nLocalHostNonce && nNonce > 1)
{
@@ -3488,6 +3486,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return true;
}
+ pfrom->addrLocal = addrMe;
+ if (pfrom->fInbound && addrMe.IsRoutable())
+ {
+ SeenLocal(addrMe);
+ }
+
// Be shy and don't send version until we hear
if (pfrom->fInbound)
pfrom->PushVersion();
@@ -3508,7 +3512,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
{
CAddress addr = GetLocalAddress(&pfrom->addr);
if (addr.IsRoutable())
+ {
+ pfrom->PushAddress(addr);
+ } else if (IsPeerAddrLocalGood(pfrom)) {
+ addr.SetIP(pfrom->addrLocal);
pfrom->PushAddress(addr);
+ }
}
// Get recent addresses
@@ -4371,24 +4380,18 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
static int64_t nLastRebroadcast;
if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
{
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
{
- LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
- {
- // Periodically clear setAddrKnown to allow refresh broadcasts
- if (nLastRebroadcast)
- pnode->setAddrKnown.clear();
+ // Periodically clear setAddrKnown to allow refresh broadcasts
+ if (nLastRebroadcast)
+ pnode->setAddrKnown.clear();
- // Rebroadcast our address
- if (fListen)
- {
- CAddress addr = GetLocalAddress(&pnode->addr);
- if (addr.IsRoutable())
- pnode->PushAddress(addr);
- }
- }
+ // Rebroadcast our address
+ AdvertizeLocal(pnode);
}
- nLastRebroadcast = GetTime();
+ if (!vNodes.empty())
+ nLastRebroadcast = GetTime();
}
//
diff --git a/src/net.cpp b/src/net.cpp
index 5ceb82cf8b..a66875a894 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -142,16 +142,19 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
}
// get best local address for a particular peer as a CAddress
+// Otherwise, return the unroutable 0.0.0.0 but filled in with
+// the normal parameters, since the IP may be changed to a useful
+// one by discovery.
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
{
- CAddress ret(CService("0.0.0.0",0),0);
+ CAddress ret(CService("0.0.0.0",GetListenPort()),0);
CService addr;
if (GetLocal(addr, paddrPeer))
{
ret = CAddress(addr);
- ret.nServices = nLocalServices;
- ret.nTime = GetAdjustedTime();
}
+ ret.nServices = nLocalServices;
+ ret.nTime = GetAdjustedTime();
return ret;
}
@@ -205,21 +208,38 @@ bool RecvLine(SOCKET hSocket, string& strLine)
}
}
-// used when scores of local addresses may have changed
-// pushes better local address to peers
-void static AdvertizeLocal()
+int GetnScore(const CService& addr)
{
- LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ LOCK(cs_mapLocalHost);
+ if (mapLocalHost.count(addr) == LOCAL_NONE)
+ return 0;
+ return mapLocalHost[addr].nScore;
+}
+
+// Is our peer's addrLocal potentially useful as an external IP source?
+bool IsPeerAddrLocalGood(CNode *pnode)
+{
+ return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() &&
+ !IsLimited(pnode->addrLocal.GetNetwork());
+}
+
+// pushes our own address to a peer
+void AdvertizeLocal(CNode *pnode)
+{
+ if (fListen && pnode->fSuccessfullyConnected)
{
- if (pnode->fSuccessfullyConnected)
+ CAddress addrLocal = GetLocalAddress(&pnode->addr);
+ // If discovery is enabled, sometimes give our peer the address it
+ // tells us that it sees us as in case it has a better idea of our
+ // address than we do.
+ if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
+ GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0))
{
- CAddress addrLocal = GetLocalAddress(&pnode->addr);
- if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal)
- {
- pnode->PushAddress(addrLocal);
- pnode->addrLocal = addrLocal;
- }
+ addrLocal.SetIP(pnode->addrLocal);
+ }
+ if (addrLocal.IsRoutable())
+ {
+ pnode->PushAddress(addrLocal);
}
}
}
@@ -257,8 +277,6 @@ bool AddLocal(const CService& addr, int nScore)
SetReachable(addr.GetNetwork());
}
- AdvertizeLocal();
-
return true;
}
@@ -296,12 +314,10 @@ bool SeenLocal(const CService& addr)
return false;
mapLocalHost[addr].nScore++;
}
-
- AdvertizeLocal();
-
return true;
}
+
/** check whether a given address is potentially local */
bool IsLocal(const CService& addr)
{
@@ -323,114 +339,12 @@ bool IsReachable(const CNetAddr& addr)
return IsReachable(net);
}
-bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
-{
- SOCKET hSocket;
- if (!ConnectSocket(addrConnect, hSocket))
- return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString());
-
- send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
-
- string strLine;
- while (RecvLine(hSocket, strLine))
- {
- if (strLine.empty()) // HTTP response is separated from headers by blank line
- {
- while (true)
- {
- if (!RecvLine(hSocket, strLine))
- {
- CloseSocket(hSocket);
- return false;
- }
- if (pszKeyword == NULL)
- break;
- if (strLine.find(pszKeyword) != string::npos)
- {
- strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
- break;
- }
- }
- CloseSocket(hSocket);
- if (strLine.find("<") != string::npos)
- strLine = strLine.substr(0, strLine.find("<"));
- strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
- while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
- strLine.resize(strLine.size()-1);
- CService addr(strLine,0,true);
- LogPrintf("GetMyExternalIP() received [%s] %s\n", strLine, addr.ToString());
- if (!addr.IsValid() || !addr.IsRoutable())
- return false;
- ipRet.SetIP(addr);
- return true;
- }
- }
- CloseSocket(hSocket);
- return error("GetMyExternalIP() : connection closed");
-}
-
-bool GetMyExternalIP(CNetAddr& ipRet)
-{
- CService addrConnect;
- const char* pszGet;
- const char* pszKeyword;
-
- for (int nLookup = 0; nLookup <= 1; nLookup++)
- for (int nHost = 1; nHost <= 1; nHost++)
- {
- // We should be phasing out our use of sites like these. If we need
- // replacements, we should ask for volunteers to put this simple
- // php file on their web server that prints the client IP:
- // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
- if (nHost == 1)
- {
- addrConnect = CService("91.198.22.70", 80); // checkip.dyndns.org
-
- if (nLookup == 1)
- {
- CService addrIP("checkip.dyndns.org", 80, true);
- if (addrIP.IsValid())
- addrConnect = addrIP;
- }
-
- pszGet = "GET / HTTP/1.1\r\n"
- "Host: checkip.dyndns.org\r\n"
- "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
- "Connection: close\r\n"
- "\r\n";
-
- pszKeyword = "Address:";
- }
-
- if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
- return true;
- }
-
- return false;
-}
-
-void ThreadGetMyExternalIP()
-{
- CNetAddr addrLocalHost;
- if (GetMyExternalIP(addrLocalHost))
- {
- LogPrintf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP());
- AddLocal(addrLocalHost, LOCAL_HTTP);
- }
-}
-
-
-
-
-
void AddressCurrentlyConnected(const CService& addr)
{
addrman.Connected(addr);
}
-
-
uint64_t CNode::nTotalBytesRecv = 0;
uint64_t CNode::nTotalBytesSent = 0;
CCriticalSection CNode::cs_totalBytesRecv;
@@ -1687,9 +1601,6 @@ void static Discover(boost::thread_group& threadGroup)
}
#endif
- // Don't use external IPv4 discovery, when -onlynet="IPv6"
- if (!IsLimited(NET_IPV4))
- threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "ext-ip", &ThreadGetMyExternalIP));
}
void StartNode(boost::thread_group& threadGroup)
diff --git a/src/net.h b/src/net.h
index 340158512d..e48acf5644 100644
--- a/src/net.h
+++ b/src/net.h
@@ -60,7 +60,6 @@ unsigned int SendBufferSize();
void AddOneShot(std::string strDest);
bool RecvLine(SOCKET hSocket, std::string& strLine);
-bool GetMyExternalIP(CNetAddr& ipRet);
void AddressCurrentlyConnected(const CService& addr);
CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const std::string& addrName);
@@ -96,12 +95,13 @@ enum
LOCAL_IF, // address a local interface listens on
LOCAL_BIND, // address explicit bound to
LOCAL_UPNP, // address reported by UPnP
- LOCAL_HTTP, // address reported by whatismyip.com and similar
LOCAL_MANUAL, // address explicitly specified (-externalip=)
LOCAL_MAX
};
+bool IsPeerAddrLocalGood(CNode *pnode);
+void AdvertizeLocal(CNode *pnode);
void SetLimited(enum Network net, bool fLimited = true);
bool IsLimited(enum Network net);
bool IsLimited(const CNetAddr& addr);
diff --git a/src/pubkey.cpp b/src/pubkey.cpp
index 3f16a4b4be..9c6f536f21 100644
--- a/src/pubkey.cpp
+++ b/src/pubkey.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "pubkey.h"
diff --git a/src/pubkey.h b/src/pubkey.h
index ccf9673453..37351cff0e 100644
--- a/src/pubkey.h
+++ b/src/pubkey.h
@@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_PUBKEY_H
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 77cfdceef0..450b83a8c6 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -103,9 +103,9 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
QString windowTitle = tr("Bitcoin Core") + " - ";
#ifdef ENABLE_WALLET
/* if compiled with wallet support, -disablewallet can still disable the wallet */
- bool enableWallet = !GetBoolArg("-disablewallet", false);
+ enableWallet = !GetBoolArg("-disablewallet", false);
#else
- bool enableWallet = false;
+ enableWallet = false;
#endif // ENABLE_WALLET
if(enableWallet)
{
@@ -554,7 +554,7 @@ void BitcoinGUI::optionsClicked()
if(!clientModel || !clientModel->getOptionsModel())
return;
- OptionsDialog dlg(this);
+ OptionsDialog dlg(this, enableWallet);
dlg.setModel(clientModel->getOptionsModel());
dlg.exec();
}
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 35b36811c4..662ef9d9e8 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -64,6 +64,7 @@ public:
bool setCurrentWallet(const QString& name);
void removeAllWallets();
#endif // ENABLE_WALLET
+ bool enableWallet;
protected:
void changeEvent(QEvent *e);
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui
index 898df2b080..c5ac371619 100644
--- a/src/qt/forms/rpcconsole.ui
+++ b/src/qt/forms/rpcconsole.ui
@@ -689,7 +689,7 @@
<item row="0" column="0" rowspan="2">
<widget class="QTableView" name="peerWidget">
<property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
+ <enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 67be174d55..f5a0759c92 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -30,7 +30,7 @@
#include <QMessageBox>
#include <QTimer>
-OptionsDialog::OptionsDialog(QWidget *parent) :
+OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
QDialog(parent),
ui(new Ui::OptionsDialog),
model(0),
@@ -66,6 +66,11 @@ OptionsDialog::OptionsDialog(QWidget *parent) :
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow));
#endif
+ /* remove Wallet tab in case of -disablewallet */
+ if (!enableWallet) {
+ ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWallet));
+ }
+
/* Display elements init */
QDir translations(":translations");
ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h
index 108609610d..794a39590c 100644
--- a/src/qt/optionsdialog.h
+++ b/src/qt/optionsdialog.h
@@ -24,7 +24,7 @@ class OptionsDialog : public QDialog
Q_OBJECT
public:
- explicit OptionsDialog(QWidget *parent);
+ explicit OptionsDialog(QWidget *parent, bool enableWallet);
~OptionsDialog();
void setModel(OptionsModel *model);
diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp
index 74565bb6d0..5f14b80797 100644
--- a/src/qt/trafficgraphwidget.cpp
+++ b/src/qt/trafficgraphwidget.cpp
@@ -76,10 +76,12 @@ void TrafficGraphWidget::paintEvent(QPaintEvent *)
int base = floor(log10(fMax));
float val = pow(10.0f, base);
- const QString units = tr("KB/s");
+ const QString units = tr("KB/s");
+ const float yMarginText = 2.0;
+
// draw lines
painter.setPen(axisCol);
- painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax, QString("%1 %2").arg(val).arg(units));
+ painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
for(float y = val; y < fMax; y += val) {
int yy = YMARGIN + h - h * y / fMax;
painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);
@@ -89,7 +91,7 @@ void TrafficGraphWidget::paintEvent(QPaintEvent *)
axisCol = axisCol.darker();
val = pow(10.0f, base - 1);
painter.setPen(axisCol);
- painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax, QString("%1 %2").arg(val).arg(units));
+ painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
int count = 1;
for(float y = val; y < fMax; y += val, count++) {
// don't overwrite lines drawn above
diff --git a/src/random.cpp b/src/random.cpp
index 998e7dfb08..fc9505ae73 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -82,13 +82,12 @@ void RandAddSeedPerfmon()
#endif
}
-bool GetRandBytes(unsigned char* buf, int num)
+void GetRandBytes(unsigned char* buf, int num)
{
if (RAND_bytes(buf, num) != 1) {
LogPrintf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL));
- return false;
+ assert(false);
}
- return true;
}
uint64_t GetRand(uint64_t nMax)
diff --git a/src/random.h b/src/random.h
index 161ebe8986..ec73d910c4 100644
--- a/src/random.h
+++ b/src/random.h
@@ -19,7 +19,7 @@ void RandAddSeedPerfmon();
/**
* Functions to gather random data via the OpenSSL PRNG
*/
-bool GetRandBytes(unsigned char* buf, int num);
+void GetRandBytes(unsigned char* buf, int num);
uint64_t GetRand(uint64_t nMax);
int GetRandInt(int nMax);
uint256 GetRandHash();
diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h
index 9926daaf3d..f0d0f3445c 100644
--- a/src/rpcprotocol.h
+++ b/src/rpcprotocol.h
@@ -52,6 +52,7 @@ enum RPCErrorCode
RPC_VERIFY_ERROR = -25, // General error during transaction or block submission
RPC_VERIFY_REJECTED = -26, // Transaction or block was rejected by network rules
RPC_VERIFY_ALREADY_IN_CHAIN = -27, // Transaction already in chain
+ RPC_IN_WARMUP = -28, // Client still warming up
// Aliases for backward compatibility
RPC_TRANSACTION_ERROR = RPC_VERIFY_ERROR,
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index 08ed73f6de..cc80887ba4 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -34,6 +34,10 @@ using namespace std;
static std::string strRPCUserColonPass;
static bool fRPCRunning = false;
+static bool fRPCInWarmup = true;
+static std::string rpcWarmupStatus("RPC server started");
+static CCriticalSection cs_rpcWarmup;
+
//! These are created by StartRPCThreads, destroyed in StopRPCThreads
static asio::io_service* rpc_io_service = NULL;
static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
@@ -744,6 +748,19 @@ bool IsRPCRunning()
return fRPCRunning;
}
+void SetRPCWarmupStatus(const std::string& newStatus)
+{
+ LOCK(cs_rpcWarmup);
+ rpcWarmupStatus = newStatus;
+}
+
+void SetRPCWarmupFinished()
+{
+ LOCK(cs_rpcWarmup);
+ assert(fRPCInWarmup);
+ fRPCInWarmup = false;
+}
+
void RPCRunHandler(const boost::system::error_code& err, boost::function<void(void)> func)
{
if (!err)
@@ -870,6 +887,13 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
if (!read_string(strRequest, valRequest))
throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
+ // Return immediately if in warmup
+ {
+ LOCK(cs_rpcWarmup);
+ if (fRPCInWarmup)
+ throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
+ }
+
string strReply;
// singleton request
diff --git a/src/rpcserver.h b/src/rpcserver.h
index 2f34b11d22..2a258dd89a 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -45,6 +45,13 @@ void StopRPCThreads();
/* Query whether RPC is running */
bool IsRPCRunning();
+/* Set the RPC warmup status. When this is done, all RPC calls will error out
+ * immediately with RPC_IN_WARMUP.
+ */
+void SetRPCWarmupStatus(const std::string& newStatus);
+/* Mark warmup as done. RPC calls will be processed from now on. */
+void SetRPCWarmupFinished();
+
/**
* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
* the right number of arguments are passed, just that any passed are the correct type.
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index 0eab0626e5..9dfd640dfb 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -144,9 +144,9 @@ static CScript PushAll(const vector<valtype>& values)
return result;
}
-static CScript CombineMultisig(CScript scriptPubKey, const CMutableTransaction& txTo, unsigned int nIn,
+static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
const vector<valtype>& vSolutions,
- vector<valtype>& sigs1, vector<valtype>& sigs2)
+ const vector<valtype>& sigs1, const vector<valtype>& sigs2)
{
// Combine all the signatures we've got:
set<valtype> allsigs;
@@ -199,7 +199,7 @@ static CScript CombineMultisig(CScript scriptPubKey, const CMutableTransaction&
return result;
}
-static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn,
+static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
const txnouttype txType, const vector<valtype>& vSolutions,
vector<valtype>& sigs1, vector<valtype>& sigs2)
{
@@ -244,7 +244,7 @@ static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo,
return CScript();
}
-CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn,
+CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
const CScript& scriptSig1, const CScript& scriptSig2)
{
txnouttype txType;
diff --git a/src/script/sign.h b/src/script/sign.h
index c84d3f9a94..99d5516adb 100644
--- a/src/script/sign.h
+++ b/src/script/sign.h
@@ -19,6 +19,6 @@ bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutab
// Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders,
// combine them intelligently and return the result.
-CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2);
+CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2);
#endif // BITCOIN_SCRIPT_SIGN_H
diff --git a/src/script/standard.h b/src/script/standard.h
index faa7747604..55a27881aa 100644
--- a/src/script/standard.h
+++ b/src/script/standard.h
@@ -6,15 +6,15 @@
#ifndef BITCOIN_SCRIPT_STANDARD_H
#define BITCOIN_SCRIPT_STANDARD_H
-#include "uint256.h"
#include "script/interpreter.h"
+#include "uint256.h"
#include <boost/variant.hpp>
#include <stdint.h>
-class CScript;
class CKeyID;
+class CScript;
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
class CScriptID : public uint160
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index a41552fea1..cff1664a1e 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -95,6 +95,48 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bo
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)), 0)) == expect, message);
}
+void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
+ // Parse the signature.
+ std::vector<unsigned char> r, s;
+ r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
+ s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
+ unsigned char hashtype = vchSig.back();
+
+ // Really ugly to implement mod-n negation here, but it would be feature creep to expose such functionality from libsecp256k1.
+ static const unsigned char order[33] = {
+ 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+ 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
+ 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
+ };
+ while (s.size() < 33) {
+ s.insert(s.begin(), 0x00);
+ }
+ int carry = 0;
+ for (int p = 32; p >= 1; p--) {
+ int n = (int)order[p] - s[p] - carry;
+ s[p] = (n + 256) & 0xFF;
+ carry = (n < 0);
+ }
+ assert(carry == 0);
+ if (s.size() > 1 && s[0] == 0 && s[1] < 0x80) {
+ s.erase(s.begin());
+ }
+
+ // Reconstruct the signature.
+ vchSig.clear();
+ vchSig.push_back(0x30);
+ vchSig.push_back(4 + r.size() + s.size());
+ vchSig.push_back(0x02);
+ vchSig.push_back(r.size());
+ vchSig.insert(vchSig.end(), r.begin(), r.end());
+ vchSig.push_back(0x02);
+ vchSig.push_back(s.size());
+ vchSig.insert(vchSig.end(), s.begin(), s.end());
+ vchSig.push_back(hashtype);
+}
+
namespace
{
const unsigned char vchKey0[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
@@ -194,7 +236,10 @@ public:
uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType);
std::vector<unsigned char> vchSig, r, s;
do {
- key.Sign(hash, vchSig, lenS <= 32);
+ key.Sign(hash, vchSig);
+ if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) {
+ NegateSignatureS(vchSig);
+ }
r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
} while (lenR != r.size() || lenS != s.size());
diff --git a/src/util.cpp b/src/util.cpp
index 544ffc98b8..0f5c036352 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -159,8 +159,8 @@ instance_of_cinit;
// the mutex).
static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
-// We use boost::call_once() to make sure these are initialized in
-// in a thread-safe manner the first time it is called:
+// We use boost::call_once() to make sure these are initialized
+// in a thread-safe manner the first time called:
static FILE* fileout = NULL;
static boost::mutex* mutexDebugLog = NULL;
diff --git a/src/wallet.cpp b/src/wallet.cpp
index d392149dbb..ec439c5aad 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -422,15 +422,13 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
RandAddSeedPerfmon();
vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
- if (!GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE))
- return false;
+ GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
CMasterKey kMasterKey;
RandAddSeedPerfmon();
kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
- if (!GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE))
- return false;
+ GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
CCrypter crypter;
int64_t nStartTime = GetTimeMillis();