Merge #7938: [0.12.2] Backports

c3d1bc3 CBase58Data::SetString: cleanse the full vector (Kaz Wesley)
43c14ac Fix headers announcements edge case (Suhas Daftuar)
06c73a1 Removed call to `TryCreateDirectory` from `GetDefaultDataDir` in `src/util.cpp`. (Alexander Regueiro)
7e71785 Use txid as key in mapAlreadyAskedFor (Suhas Daftuar)
5583a3d Add curl to Gitian setup instrustions (BtcDrak)
d3ead9b Avoid "Unknown command" messages when receiving getaddr on outbound connections. (R E Broadley)
a5bc6a1 Remove vfReachable and modify IsReachable to only use vfLimited. (Patrick Strateman)
52c1011 Clarify description of blockindex (Matthew Zipkin)
21b2f82 Don't resend wallet txs that aren't in our own mempool (Alex Morcos)
66d5408 Fix memleak in TorController [rework] (Wladimir J. van der Laan)
1c3d38b Remove spurious dollar sign. Fixes #7189. (Chris Moore)
64fd0ce fix spelling of advertise in src and doc (jloughry)
a9e73f7 Fix and cleanup listreceivedbyX documentation (instagibbs)
9095594 Do not download transactions during inital sync (ptschip)
This commit is contained in:
Wladimir J. van der Laan 2016-06-09 10:22:37 +02:00
commit 20d00a180e
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
15 changed files with 103 additions and 59 deletions

View File

@ -384,7 +384,7 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[
dnl qt version is set to 'auto' and the preferred version wasn't found. Now try the other. dnl qt version is set to 'auto' and the preferred version wasn't found. Now try the other.
if test x$have_qt = xno && test x$bitcoin_qt_want_version = xauto; then if test x$have_qt = xno && test x$bitcoin_qt_want_version = xauto; then
if test x$auto_priority_version = x$qt5; then if test x$auto_priority_version = xqt5; then
PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt; bitcoin_qt_got_major_vers=4], [have_qt=no]) PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt; bitcoin_qt_got_major_vers=4], [have_qt=no])
else else
PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt5; bitcoin_qt_got_major_vers=5], [have_qt=no]) PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt5; bitcoin_qt_got_major_vers=5], [have_qt=no])

View File

@ -252,7 +252,7 @@ First we need to log in as `root` to set up dependencies and make sure that our
user can use the sudo command. Type/paste the following in the terminal: user can use the sudo command. Type/paste the following in the terminal:
```bash ```bash
apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils make ubuntu-archive-keyring apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils make ubuntu-archive-keyring curl
adduser debian sudo adduser debian sudo
``` ```

View File

@ -52,7 +52,7 @@ your bitcoind's P2P listen port (8333 by default).
this option, and this can be a .onion address. Given the above this option, and this can be a .onion address. Given the above
configuration, you can find your onion address in configuration, you can find your onion address in
/var/lib/tor/bitcoin-service/hostname. Onion addresses are given /var/lib/tor/bitcoin-service/hostname. Onion addresses are given
preference for your node to advertize itself with, for connections preference for your node to advertise itself with, for connections
coming from unroutable addresses (such as 127.0.0.1, where the coming from unroutable addresses (such as 127.0.0.1, where the
Tor proxy typically runs). Tor proxy typically runs).

View File

@ -18,6 +18,11 @@ def txFromHex(hexstring):
class ListTransactionsTest(BitcoinTestFramework): class ListTransactionsTest(BitcoinTestFramework):
def setup_nodes(self):
#This test requires mocktime
enable_mocktime()
return start_nodes(4, self.options.tmpdir)
def run_test(self): def run_test(self):
# Simple send, 0 to 1: # Simple send, 0 to 1:
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)

View File

@ -27,6 +27,11 @@ def get_sub_array_from_array(object_array, to_match):
class ReceivedByTest(BitcoinTestFramework): class ReceivedByTest(BitcoinTestFramework):
def setup_nodes(self):
#This test requires mocktime
enable_mocktime()
return start_nodes(4, self.options.tmpdir)
def run_test(self): def run_test(self):
''' '''
listreceivedbyaddress Test listreceivedbyaddress Test

View File

@ -26,6 +26,26 @@ from .authproxy import AuthServiceProxy, JSONRPCException
COVERAGE_DIR = None COVERAGE_DIR = None
#Set Mocktime default to OFF.
#MOCKTIME is only needed for scripts that use the
#cached version of the blockchain. If the cached
#version of the blockchain is used without MOCKTIME
#then the mempools will not sync due to IBD.
MOCKTIME = 0
def enable_mocktime():
#For backwared compatibility of the python scripts
#with previous versions of the cache, set MOCKTIME
#to Jan 1, 2014 + (201 * 10 * 60)
global MOCKTIME
MOCKTIME = 1388534400 + (201 * 10 * 60)
def disable_mocktime():
global MOCKTIME
MOCKTIME = 0
def get_mocktime():
return MOCKTIME
def enable_coverage(dirname): def enable_coverage(dirname):
"""Maintain a log of which RPC calls are made during testing.""" """Maintain a log of which RPC calls are made during testing."""
@ -168,9 +188,10 @@ def initialize_chain(test_dir):
# Create a 200-block-long chain; each of the 4 nodes # Create a 200-block-long chain; each of the 4 nodes
# gets 25 mature blocks and 25 immature. # gets 25 mature blocks and 25 immature.
# blocks are created with timestamps 10 minutes apart, starting # blocks are created with timestamps 10 minutes apart
# at 1 Jan 2014 # starting from 2010 minutes in the past
block_time = 1388534400 enable_mocktime()
block_time = get_mocktime() - (201 * 10 * 60)
for i in range(2): for i in range(2):
for peer in range(4): for peer in range(4):
for j in range(25): for j in range(25):
@ -183,6 +204,7 @@ def initialize_chain(test_dir):
# Shut them down, and clean up cache directories: # Shut them down, and clean up cache directories:
stop_nodes(rpcs) stop_nodes(rpcs)
wait_bitcoinds() wait_bitcoinds()
disable_mocktime()
for i in range(4): for i in range(4):
os.remove(log_filename("cache", i, "debug.log")) os.remove(log_filename("cache", i, "debug.log"))
os.remove(log_filename("cache", i, "db.log")) os.remove(log_filename("cache", i, "db.log"))
@ -232,7 +254,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=
if binary is None: if binary is None:
binary = os.getenv("BITCOIND", "bitcoind") binary = os.getenv("BITCOIND", "bitcoind")
# RPC tests still depend on free transactions # RPC tests still depend on free transactions
args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-blockprioritysize=50000" ] args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-blockprioritysize=50000", "-mocktime="+str(get_mocktime()) ]
if extra_args is not None: args.extend(extra_args) if extra_args is not None: args.extend(extra_args)
bitcoind_processes[i] = subprocess.Popen(args) bitcoind_processes[i] = subprocess.Popen(args)
devnull = open(os.devnull, "w") devnull = open(os.devnull, "w")

View File

@ -172,7 +172,7 @@ bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
vchData.resize(vchTemp.size() - nVersionBytes); vchData.resize(vchTemp.size() - nVersionBytes);
if (!vchData.empty()) if (!vchData.empty())
memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size()); memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
memory_cleanse(&vchTemp[0], vchData.size()); memory_cleanse(&vchTemp[0], vchTemp.size());
return true; return true;
} }

View File

@ -1175,6 +1175,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// -proxy sets a proxy for all outgoing network traffic // -proxy sets a proxy for all outgoing network traffic
// -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
std::string proxyArg = GetArg("-proxy", ""); std::string proxyArg = GetArg("-proxy", "");
SetLimited(NET_TOR);
if (proxyArg != "" && proxyArg != "0") { if (proxyArg != "" && proxyArg != "0") {
proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize); proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize);
if (!addrProxy.IsValid()) if (!addrProxy.IsValid())
@ -1184,7 +1185,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
SetProxy(NET_IPV6, addrProxy); SetProxy(NET_IPV6, addrProxy);
SetProxy(NET_TOR, addrProxy); SetProxy(NET_TOR, addrProxy);
SetNameProxy(addrProxy); SetNameProxy(addrProxy);
SetReachable(NET_TOR); // by default, -proxy sets onion as reachable, unless -noonion later SetLimited(NET_TOR, false); // by default, -proxy sets onion as reachable, unless -noonion later
} }
// -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
@ -1193,13 +1194,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
std::string onionArg = GetArg("-onion", ""); std::string onionArg = GetArg("-onion", "");
if (onionArg != "") { if (onionArg != "") {
if (onionArg == "0") { // Handle -noonion/-onion=0 if (onionArg == "0") { // Handle -noonion/-onion=0
SetReachable(NET_TOR, false); // set onions as unreachable SetLimited(NET_TOR); // set onions as unreachable
} else { } else {
proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize); proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize);
if (!addrOnion.IsValid()) if (!addrOnion.IsValid())
return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg)); return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg));
SetProxy(NET_TOR, addrOnion); SetProxy(NET_TOR, addrOnion);
SetReachable(NET_TOR); SetLimited(NET_TOR, false);
} }
} }

View File

@ -391,7 +391,7 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Pa
mapBlocksInFlight[hash] = std::make_pair(nodeid, it); mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
} }
/** Check whether the last unknown block a peer advertized is not yet known. */ /** Check whether the last unknown block a peer advertised is not yet known. */
void ProcessBlockAvailability(NodeId nodeid) { void ProcessBlockAvailability(NodeId nodeid) {
CNodeState *state = State(nodeid); CNodeState *state = State(nodeid);
assert(state != NULL); assert(state != NULL);
@ -4639,11 +4639,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CAddress addr = GetLocalAddress(&pfrom->addr); CAddress addr = GetLocalAddress(&pfrom->addr);
if (addr.IsRoutable()) if (addr.IsRoutable())
{ {
LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString()); LogPrintf("ProcessMessages: advertising address %s\n", addr.ToString());
pfrom->PushAddress(addr); pfrom->PushAddress(addr);
} else if (IsPeerAddrLocalGood(pfrom)) { } else if (IsPeerAddrLocalGood(pfrom)) {
addr.SetIP(pfrom->addrLocal); addr.SetIP(pfrom->addrLocal);
LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString()); LogPrintf("ProcessMessages: advertising address %s\n", addr.ToString());
pfrom->PushAddress(addr); pfrom->PushAddress(addr);
} }
} }
@ -4845,7 +4845,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
{ {
if (fBlocksOnly) if (fBlocksOnly)
LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id); LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id);
else if (!fAlreadyHave && !fImporting && !fReindex) else if (!fAlreadyHave && !fImporting && !fReindex && !IsInitialBlockDownload())
pfrom->AskFor(inv); pfrom->AskFor(inv);
} }
@ -5001,7 +5001,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CValidationState state; CValidationState state;
pfrom->setAskFor.erase(inv.hash); pfrom->setAskFor.erase(inv.hash);
mapAlreadyAskedFor.erase(inv); mapAlreadyAskedFor.erase(inv.hash);
if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
{ {
@ -5247,13 +5247,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
} }
else if (strCommand == NetMsgType::GETADDR)
{
// This asymmetric behavior for inbound and outbound connections was introduced // This asymmetric behavior for inbound and outbound connections was introduced
// to prevent a fingerprinting attack: an attacker can send specific fake addresses // to prevent a fingerprinting attack: an attacker can send specific fake addresses
// to users' AddrMan and later request them by sending getaddr messages. // to users' AddrMan and later request them by sending getaddr messages.
// Making nodes which are behind NAT and can only make outgoing connections ignore // Making nodes which are behind NAT and can only make outgoing connections ignore
// the getaddr message mitigates the attack. // the getaddr message mitigates the attack.
else if ((strCommand == NetMsgType::GETADDR) && (pfrom->fInbound)) if (!pfrom->fInbound) {
{ LogPrint("net", "Ignoring \"getaddr\" from outbound connection. peer=%d\n", pfrom->id);
return true;
}
pfrom->vAddrToSend.clear(); pfrom->vAddrToSend.clear();
vector<CAddress> vAddr = addrman.GetAddr(); vector<CAddress> vAddr = addrman.GetAddr();
BOOST_FOREACH(const CAddress &addr, vAddr) BOOST_FOREACH(const CAddress &addr, vAddr)
@ -5652,7 +5657,7 @@ bool SendMessages(CNode* pto)
// Address refresh broadcast // Address refresh broadcast
int64_t nNow = GetTimeMicros(); int64_t nNow = GetTimeMicros();
if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
AdvertizeLocal(pto); AdvertiseLocal(pto);
pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL); pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
} }
@ -5765,7 +5770,21 @@ bool SendMessages(CNode* pto)
fRevertToInv = true; fRevertToInv = true;
break; break;
} }
assert(pBestIndex == NULL || pindex->pprev == pBestIndex); if (pBestIndex != NULL && pindex->pprev != pBestIndex) {
// This means that the list of blocks to announce don't
// connect to each other.
// This shouldn't really be possible to hit during
// regular operation (because reorgs should take us to
// a chain that has some block not on the prior chain,
// which should be caught by the prior check), but one
// way this could happen is by using invalidateblock /
// reconsiderblock repeatedly on the tip, causing it to
// be added multiple times to vBlockHashesToAnnounce.
// Robustly deal with this rare situation by reverting
// to an inv.
fRevertToInv = true;
break;
}
pBestIndex = pindex; pBestIndex = pindex;
if (fFoundStartingHeader) { if (fFoundStartingHeader) {
// add this to the headers message // add this to the headers message

View File

@ -77,7 +77,6 @@ bool fListen = true;
uint64_t nLocalServices = NODE_NETWORK; uint64_t nLocalServices = NODE_NETWORK;
CCriticalSection cs_mapLocalHost; CCriticalSection cs_mapLocalHost;
map<CNetAddr, LocalServiceInfo> mapLocalHost; map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfReachable[NET_MAX] = {};
static bool vfLimited[NET_MAX] = {}; static bool vfLimited[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL; static CNode* pnodeLocalHost = NULL;
uint64_t nLocalHostNonce = 0; uint64_t nLocalHostNonce = 0;
@ -92,7 +91,7 @@ CCriticalSection cs_vNodes;
map<CInv, CDataStream> mapRelay; map<CInv, CDataStream> mapRelay;
deque<pair<int64_t, CInv> > vRelayExpiration; deque<pair<int64_t, CInv> > vRelayExpiration;
CCriticalSection cs_mapRelay; CCriticalSection cs_mapRelay;
limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ); limitedmap<uint256, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
static deque<string> vOneShots; static deque<string> vOneShots;
CCriticalSection cs_vOneShots; CCriticalSection cs_vOneShots;
@ -203,7 +202,7 @@ bool IsPeerAddrLocalGood(CNode *pnode)
} }
// pushes our own address to a peer // pushes our own address to a peer
void AdvertizeLocal(CNode *pnode) void AdvertiseLocal(CNode *pnode)
{ {
if (fListen && pnode->fSuccessfullyConnected) if (fListen && pnode->fSuccessfullyConnected)
{ {
@ -218,20 +217,12 @@ void AdvertizeLocal(CNode *pnode)
} }
if (addrLocal.IsRoutable()) if (addrLocal.IsRoutable())
{ {
LogPrintf("AdvertizeLocal: advertizing address %s\n", addrLocal.ToString()); LogPrintf("AdvertiseLocal: advertising address %s\n", addrLocal.ToString());
pnode->PushAddress(addrLocal); pnode->PushAddress(addrLocal);
} }
} }
} }
void SetReachable(enum Network net, bool fFlag)
{
LOCK(cs_mapLocalHost);
vfReachable[net] = fFlag;
if (net == NET_IPV6 && fFlag)
vfReachable[NET_IPV4] = true;
}
// learn a new local address // learn a new local address
bool AddLocal(const CService& addr, int nScore) bool AddLocal(const CService& addr, int nScore)
{ {
@ -254,7 +245,6 @@ bool AddLocal(const CService& addr, int nScore)
info.nScore = nScore + (fAlready ? 1 : 0); info.nScore = nScore + (fAlready ? 1 : 0);
info.nPort = addr.GetPort(); info.nPort = addr.GetPort();
} }
SetReachable(addr.GetNetwork());
} }
return true; return true;
@ -317,7 +307,7 @@ bool IsLocal(const CService& addr)
bool IsReachable(enum Network net) bool IsReachable(enum Network net)
{ {
LOCK(cs_mapLocalHost); LOCK(cs_mapLocalHost);
return vfReachable[net] && !vfLimited[net]; return !vfLimited[net];
} }
/** check whether a given address is in a network we can probably connect to */ /** check whether a given address is in a network we can probably connect to */
@ -2419,7 +2409,7 @@ void CNode::AskFor(const CInv& inv)
// We're using mapAskFor as a priority queue, // We're using mapAskFor as a priority queue,
// the key is the earliest time the request can be sent // the key is the earliest time the request can be sent
int64_t nRequestTime; int64_t nRequestTime;
limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv); limitedmap<uint256, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv.hash);
if (it != mapAlreadyAskedFor.end()) if (it != mapAlreadyAskedFor.end())
nRequestTime = it->second; nRequestTime = it->second;
else else
@ -2438,7 +2428,7 @@ void CNode::AskFor(const CInv& inv)
if (it != mapAlreadyAskedFor.end()) if (it != mapAlreadyAskedFor.end())
mapAlreadyAskedFor.update(it, nRequestTime); mapAlreadyAskedFor.update(it, nRequestTime);
else else
mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime)); mapAlreadyAskedFor.insert(std::make_pair(inv.hash, nRequestTime));
mapAskFor.insert(std::make_pair(nRequestTime, inv)); mapAskFor.insert(std::make_pair(nRequestTime, inv));
} }

View File

@ -134,7 +134,7 @@ enum
}; };
bool IsPeerAddrLocalGood(CNode *pnode); bool IsPeerAddrLocalGood(CNode *pnode);
void AdvertizeLocal(CNode *pnode); void AdvertiseLocal(CNode *pnode);
void SetLimited(enum Network net, bool fLimited = true); void SetLimited(enum Network net, bool fLimited = true);
bool IsLimited(enum Network net); bool IsLimited(enum Network net);
bool IsLimited(const CNetAddr& addr); bool IsLimited(const CNetAddr& addr);
@ -146,7 +146,6 @@ bool IsLocal(const CService& addr);
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
bool IsReachable(enum Network net); bool IsReachable(enum Network net);
bool IsReachable(const CNetAddr &addr); bool IsReachable(const CNetAddr &addr);
void SetReachable(enum Network net, bool fFlag = true);
CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
@ -164,7 +163,7 @@ extern CCriticalSection cs_vNodes;
extern std::map<CInv, CDataStream> mapRelay; extern std::map<CInv, CDataStream> mapRelay;
extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration; extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
extern CCriticalSection cs_mapRelay; extern CCriticalSection cs_mapRelay;
extern limitedmap<CInv, int64_t> mapAlreadyAskedFor; extern limitedmap<uint256, int64_t> mapAlreadyAskedFor;
extern std::vector<std::string> vAddedNodes; extern std::vector<std::string> vAddedNodes;
extern CCriticalSection cs_vAddedNodes; extern CCriticalSection cs_vAddedNodes;

View File

@ -394,6 +394,9 @@ TorController::TorController(struct event_base* base, const std::string& target)
target(target), conn(base), reconnect(true), reconnect_ev(0), target(target), conn(base), reconnect(true), reconnect_ev(0),
reconnect_timeout(RECONNECT_TIMEOUT_START) reconnect_timeout(RECONNECT_TIMEOUT_START)
{ {
reconnect_ev = event_new(base, -1, 0, reconnect_cb, this);
if (!reconnect_ev)
LogPrintf("tor: Failed to create event for reconnection: out of memory?\n");
// Start connection attempts immediately // Start connection attempts immediately
if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1), if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1),
boost::bind(&TorController::disconnected_cb, this, _1) )) { boost::bind(&TorController::disconnected_cb, this, _1) )) {
@ -409,8 +412,10 @@ TorController::TorController(struct event_base* base, const std::string& target)
TorController::~TorController() TorController::~TorController()
{ {
if (reconnect_ev) if (reconnect_ev) {
event_del(reconnect_ev); event_free(reconnect_ev);
reconnect_ev = 0;
}
if (service.IsValid()) { if (service.IsValid()) {
RemoveLocal(service); RemoveLocal(service);
} }
@ -430,7 +435,7 @@ void TorController::add_onion_cb(TorControlConnection& conn, const TorControlRep
} }
service = CService(service_id+".onion", GetListenPort(), false); service = CService(service_id+".onion", GetListenPort(), false);
LogPrintf("tor: Got service ID %s, advertizing service %s\n", service_id, service.ToString()); LogPrintf("tor: Got service ID %s, advertising service %s\n", service_id, service.ToString());
if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) { if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) {
LogPrint("tor", "tor: Cached service private key to %s\n", GetPrivateKeyFile()); LogPrint("tor", "tor: Cached service private key to %s\n", GetPrivateKeyFile());
} else { } else {
@ -455,7 +460,7 @@ void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& r
if (GetArg("-onion", "") == "") { if (GetArg("-onion", "") == "") {
proxyType addrOnion = proxyType(CService("127.0.0.1", 9050), true); proxyType addrOnion = proxyType(CService("127.0.0.1", 9050), true);
SetProxy(NET_TOR, addrOnion); SetProxy(NET_TOR, addrOnion);
SetReachable(NET_TOR); SetLimited(NET_TOR, false);
} }
// Finally - now create the service // Finally - now create the service
@ -611,7 +616,7 @@ void TorController::connected_cb(TorControlConnection& conn)
void TorController::disconnected_cb(TorControlConnection& conn) void TorController::disconnected_cb(TorControlConnection& conn)
{ {
// Stop advertizing service when disconnected // Stop advertising service when disconnected
if (service.IsValid()) if (service.IsValid())
RemoveLocal(service); RemoveLocal(service);
service = CService(); service = CService();
@ -622,7 +627,7 @@ void TorController::disconnected_cb(TorControlConnection& conn)
// Single-shot timer for reconnect. Use exponential backoff. // Single-shot timer for reconnect. Use exponential backoff.
struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0)); struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0));
reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); if (reconnect_ev)
event_add(reconnect_ev, &time); event_add(reconnect_ev, &time);
reconnect_timeout *= RECONNECT_TIMEOUT_EXP; reconnect_timeout *= RECONNECT_TIMEOUT_EXP;
} }

View File

@ -471,9 +471,7 @@ boost::filesystem::path GetDefaultDataDir()
pathRet = fs::path(pszHome); pathRet = fs::path(pszHome);
#ifdef MAC_OSX #ifdef MAC_OSX
// Mac // Mac
pathRet /= "Library/Application Support"; return pathRet / "Library/Application Support/Bitcoin";
TryCreateDirectory(pathRet);
return pathRet / "Bitcoin";
#else #else
// Unix // Unix
return pathRet / ".bitcoin"; return pathRet / ".bitcoin";

View File

@ -1246,7 +1246,7 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp)
"\nList balances by receiving address.\n" "\nList balances by receiving address.\n"
"\nArguments:\n" "\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
"2. includeempty (numeric, optional, default=false) Whether to include addresses that haven't received any payments.\n" "2. includeempty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
"3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n" "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
"\nResult:\n" "\nResult:\n"
@ -1284,7 +1284,7 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp)
"\nDEPRECATED. List balances by account.\n" "\nDEPRECATED. List balances by account.\n"
"\nArguments:\n" "\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
"2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n" "2. includeempty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n"
"3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n" "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
"\nResult:\n" "\nResult:\n"
@ -1446,7 +1446,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp)
" \"trusted\": xxx (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n" " \"trusted\": xxx (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
" \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
" category of transactions.\n" " category of transactions.\n"
" \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n" " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n"
" category of transactions.\n" " category of transactions.\n"
" \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n" " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
" \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
@ -1639,7 +1639,7 @@ UniValue listsinceblock(const UniValue& params, bool fHelp)
" \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n" " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n"
" \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
" \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
" \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n"
" \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n" " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
" \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
" \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n" " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
@ -1723,7 +1723,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp)
" \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n" " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
" \"confirmations\" : n, (numeric) The number of confirmations\n" " \"confirmations\" : n, (numeric) The number of confirmations\n"
" \"blockhash\" : \"hash\", (string) The block hash\n" " \"blockhash\" : \"hash\", (string) The block hash\n"
" \"blockindex\" : xx, (numeric) The block index\n" " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n"
" \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n" " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
" \"txid\" : \"transactionid\", (string) The transaction id.\n" " \"txid\" : \"transactionid\", (string) The transaction id.\n"
" \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n" " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"

View File

@ -1264,7 +1264,7 @@ bool CWalletTx::RelayWalletTransaction()
assert(pwallet->GetBroadcastTransactions()); assert(pwallet->GetBroadcastTransactions());
if (!IsCoinBase()) if (!IsCoinBase())
{ {
if (GetDepthInMainChain() == 0 && !isAbandoned()) { if (GetDepthInMainChain() == 0 && !isAbandoned() && InMempool()) {
LogPrintf("Relaying wtx %s\n", GetHash().ToString()); LogPrintf("Relaying wtx %s\n", GetHash().ToString());
RelayTransaction((CTransaction)*this); RelayTransaction((CTransaction)*this);
return true; return true;