Merge pull request #6703

45bfa13 PARTIAL: typofixes (found by misspell_fixer) (Veres Lajos)
21c406e add support for miniupnpc api version 14 (Pavel Vasin)
13bd5a7 rpc-tests: re-enable rpc-tests for Windows (Cory Fields)
ccc4ad6 net: Set SO_REUSEADDR for Windows too (Cory Fields)
1f6772e add unit test for CNetAddr::GetGroup. (Alex Morcos)
13642a5 Fix masking of irrelevant bits in address groups. (Alex Morcos)
6b51b9b Replace boost::reverse_lock with our own. (Casey Rodarmor)
626c5e6 Make sure we re-acquire lock if a task throws (Casey Rodarmor)
4877053 Add missing files to files.md (fanquake)
f171fee Handle leveldb::DestroyDB() errors on wipe failure (Adam Weiss)
c5b89fe Fix race condition on test node shutdown (Casey Rodarmor)
4a37410 Handle no chain tip available in InvalidChainFound() (Ross Nicoll)
f6d29a6 Use unique name for AlertNotify tempfile (Casey Rodarmor)
e6adac7 Delay initial pruning until after wallet init (Adam Weiss)
e0020d4 Make sure LogPrint strings are line-terminated (J Ross Nicoll)
7ff9d12 Make sure LogPrintf strings are line-terminated (Wladimir J. van der Laan)
5a39133 build: fix libressl detection (Cory Fields)
f6355e6 Avoid leaking file descriptors in RegisterLoad (Casey Rodarmor)
60457d3 locking: fix a few small issues uncovered by -Wthread-safety (Cory Fields)
a496e11 Remove bash test note from rpc-tests readme (fanquake)
49c6a64 tests: Remove old sh-based test framework (Wladimir J. van der Laan)
a37567d Add autogen.sh to source tarball. (randy-waterhouse)
1f4d7cf travis: for travis generating an extra build (Cory Fields)
This commit is contained in:
Wladimir J. van der Laan
2015-09-23 14:09:42 +02:00
40 changed files with 268 additions and 398 deletions

View File

@@ -6,6 +6,7 @@
os: linux os: linux
language: cpp language: cpp
compiler: gcc
env: env:
global: global:
- MAKEJOBS=-j3 - MAKEJOBS=-j3
@@ -41,6 +42,8 @@ matrix:
env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
- compiler: ": Cross-Mac" - compiler: ": Cross-Mac"
env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy"
exclude:
- compiler: gcc
install: install:
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi

View File

@@ -202,6 +202,8 @@ check-local:
@qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool $(COMPARISON_TOOL_REORG_TESTS) 2>&1 @qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool $(COMPARISON_TOOL_REORG_TESTS) 2>&1
endif endif
dist_noinst_SCRIPTS = autogen.sh
EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.sh qa/pull-tester/run-bitcoin-cli qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.sh qa/pull-tester/run-bitcoin-cli qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING)
CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER)

View File

@@ -692,6 +692,21 @@ LIBS_TEMP="$LIBS"
CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS" CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS"
LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS" LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS"
AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),) AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),)
AC_MSG_CHECKING(for a supported OpenSSL version)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <openssl/rand.h>
]],
[[RAND_egd(NULL);]])],
[AC_MSG_RESULT(yes)],
[
AC_ARG_WITH([libressl],
[AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])],
[AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])],
[AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])]
)]
)
CFLAGS="$CFLAGS_TEMP" CFLAGS="$CFLAGS_TEMP"
LIBS="$LIBS_TEMP" LIBS="$LIBS_TEMP"

View File

@@ -149,7 +149,7 @@ bitcoin (0.5.3-natty0) natty; urgency=low
bitcoin (0.5.2-natty1) natty; urgency=low bitcoin (0.5.2-natty1) natty; urgency=low
* Remove mentions on anonymity in package descriptions and manpage. * Remove mentions on anonymity in package descriptions and manpage.
These should never have been there, bitcoin isnt anonymous without These should never have been there, bitcoin isn't anonymous without
a ton of work that virtually no users will ever be willing and a ton of work that virtually no users will ever be willing and
capable of doing capable of doing
@@ -190,7 +190,7 @@ bitcoin (0.5.0~rc1-natty1) natty; urgency=low
* Add test_bitcoin to build test * Add test_bitcoin to build test
* Fix clean * Fix clean
* Remove uneccessary build-dependancies * Remove unnecessary build-dependancies
-- Matt Corallo <matt@bluematt.me> Wed, 26 Oct 2011 14:37:18 -0400 -- Matt Corallo <matt@bluematt.me> Wed, 26 Oct 2011 14:37:18 -0400
@@ -350,7 +350,7 @@ bitcoin (0.3.20.01~dfsg-1) unstable; urgency=low
bitcoin (0.3.19~dfsg-6) unstable; urgency=low bitcoin (0.3.19~dfsg-6) unstable; urgency=low
* Fix override agressive optimizations. * Fix override aggressive optimizations.
* Fix tighten build-dependencies to really fit backporting to Lenny: * Fix tighten build-dependencies to really fit backporting to Lenny:
+ Add fallback build-dependency on libdb4.6++-dev. + Add fallback build-dependency on libdb4.6++-dev.
+ Tighten unversioned Boost build-dependencies to recent versions, + Tighten unversioned Boost build-dependencies to recent versions,

View File

@@ -1117,7 +1117,7 @@ EOF
# uname -m prints for DJGPP always 'pc', but it prints nothing about # uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586. # the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub # Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that # prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build. # this is a cross-build.
echo i586-pc-msdosdjgpp echo i586-pc-msdosdjgpp
exit ;; exit ;;

View File

@@ -1,12 +1,16 @@
Used in 0.8.0
--------------------- * bitcoin.conf: contains configuration settings for bitcoind or bitcoin-qt
* wallet.dat: personal wallet (BDB) with keys and transactions * bitcoind.pid: stores the process id of bitcoind while running
* peers.dat: peer IP address database (custom format); since 0.7.0
* blocks/blk000??.dat: block data (custom, 128 MiB per file); since 0.8.0 * blocks/blk000??.dat: block data (custom, 128 MiB per file); since 0.8.0
* blocks/rev000??.dat; block undo data (custom); since 0.8.0 (format changed since pre-0.8) * blocks/rev000??.dat; block undo data (custom); since 0.8.0 (format changed since pre-0.8)
* blocks/index/*; block index (LevelDB); since 0.8.0 * blocks/index/*; block index (LevelDB); since 0.8.0
* chainstate/*; block chain state database (LevelDB); since 0.8.0 * chainstate/*; block chain state database (LevelDB); since 0.8.0
* database/*: BDB database environment; only used for wallet since 0.8.0 * database/*: BDB database environment; only used for wallet since 0.8.0
* db.log: wallet database log file
* debug.log: contains debug information and general logging generated by bitcoind or bitcoin-qt
* fee_estimates.dat: stores statistics used to estimate minimum transaction fees and priorities required for confirmation; since 0.10.0
* peers.dat: peer IP address database (custom format); since 0.7.0
* wallet.dat: personal wallet (BDB) with keys and transactions
Only used in pre-0.8.0 Only used in pre-0.8.0
--------------------- ---------------------

View File

@@ -8,11 +8,6 @@ CURDIR=$(cd $(dirname "$0"); pwd)
export BITCOINCLI=${BUILDDIR}/qa/pull-tester/run-bitcoin-cli export BITCOINCLI=${BUILDDIR}/qa/pull-tester/run-bitcoin-cli
export BITCOIND=${REAL_BITCOIND} export BITCOIND=${REAL_BITCOIND}
if [ "x${EXEEXT}" = "x.exe" ]; then
echo "Win tests currently disabled"
exit 0
fi
#Run the tests #Run the tests
testScripts=( testScripts=(

View File

@@ -12,10 +12,6 @@ Base class for new regression tests.
### [test_framework/util.py](test_framework/util.py) ### [test_framework/util.py](test_framework/util.py)
Generally useful functions. Generally useful functions.
Bash-based tests, to be ported to Python:
-----------------------------------------
- conflictedbalance.sh : More testing of malleable transaction handling
Notes Notes
===== =====

View File

@@ -1,147 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Test marking of spent outputs
# Create a transaction graph with four transactions,
# A/B/C/D
# C spends A
# D spends B and C
# Then simulate C being mutated, to create C'
# that is mined.
# A is still (correctly) considered spent.
# B should be treated as unspent
if [ $# -lt 1 ]; then
echo "Usage: $0 path_to_binaries"
echo "e.g. $0 ../../src"
echo "Env vars BITCOIND and BITCOINCLI may be used to specify the exact binaries used"
exit 1
fi
set -f
BITCOIND=${BITCOIND:-${1}/bitcoind}
CLI=${BITCOINCLI:-${1}/bitcoin-cli}
DIR="${BASH_SOURCE%/*}"
SENDANDWAIT="${DIR}/send.sh"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/util.sh"
D=$(mktemp -d test.XXXXX)
# Two nodes; one will play the part of merchant, the
# other an evil transaction-mutating miner.
D1=${D}/node1
CreateDataDir $D1 port=11000 rpcport=11001
B1ARGS="-datadir=$D1 -debug=mempool"
$BITCOIND $B1ARGS &
B1PID=$!
D2=${D}/node2
CreateDataDir $D2 port=11010 rpcport=11011
B2ARGS="-datadir=$D2 -debug=mempool"
$BITCOIND $B2ARGS &
B2PID=$!
# Wait until both nodes are at the same block number
function WaitBlocks {
while :
do
sleep 1
declare -i BLOCKS1=$( GetBlocks $B1ARGS )
declare -i BLOCKS2=$( GetBlocks $B2ARGS )
if (( BLOCKS1 == BLOCKS2 ))
then
break
fi
done
}
# Wait until node has $N peers
function WaitPeers {
while :
do
declare -i PEERS=$( $CLI $1 getconnectioncount )
if (( PEERS == "$2" ))
then
break
fi
sleep 1
done
}
echo "Generating test blockchain..."
# Start with B2 connected to B1:
$CLI $B2ARGS addnode 127.0.0.1:11000 onetry
WaitPeers "$B1ARGS" 1
# 2 block, 50 XBT each == 100 XBT
# These will be transactions "A" and "B"
$CLI $B1ARGS generate 2
WaitBlocks
# 100 blocks, 0 mature == 0 XBT
$CLI $B2ARGS generate 100
WaitBlocks
CheckBalance "$B1ARGS" 100
CheckBalance "$B2ARGS" 0
# restart B2 with no connection
$CLI $B2ARGS stop > /dev/null 2>&1
wait $B2PID
$BITCOIND $B2ARGS &
B2PID=$!
B1ADDRESS=$( $CLI $B1ARGS getnewaddress )
B2ADDRESS=$( $CLI $B2ARGS getnewaddress )
# Transaction C: send-to-self, spend A
TXID_C=$( $CLI $B1ARGS sendtoaddress $B1ADDRESS 50.0)
# Transaction D: spends B and C
TXID_D=$( $CLI $B1ARGS sendtoaddress $B2ADDRESS 100.0)
CheckBalance "$B1ARGS" 0
# Mutate TXID_C and add it to B2's memory pool:
RAWTX_C=$( $CLI $B1ARGS getrawtransaction $TXID_C )
# ... mutate C to create C'
L=${RAWTX_C:82:2}
NEWLEN=$( printf "%x" $(( 16#$L + 1 )) )
MUTATEDTX_C=${RAWTX_C:0:82}${NEWLEN}4c${RAWTX_C:84}
# ... give mutated tx1 to B2:
MUTATEDTXID=$( $CLI $B2ARGS sendrawtransaction $MUTATEDTX_C )
echo "TXID_C: " $TXID_C
echo "Mutated: " $MUTATEDTXID
# Re-connect nodes, and have both nodes mine some blocks:
$CLI $B2ARGS addnode 127.0.0.1:11000 onetry
WaitPeers "$B1ARGS" 1
# Having B2 mine the next block puts the mutated
# transaction C in the chain:
$CLI $B2ARGS generate 1
WaitBlocks
# B1 should still be able to spend 100, because D is conflicted
# so does not count as a spend of B
CheckBalance "$B1ARGS" 100
$CLI $B2ARGS stop > /dev/null 2>&1
wait $B2PID
$CLI $B1ARGS stop > /dev/null 2>&1
wait $B1PID
echo "Tests successful, cleaning up"
rm -rf $D
exit 0

View File

@@ -199,7 +199,7 @@ class RESTTest (BitcoinTestFramework):
response = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True) response = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True)
assert_equal(response.status, 200) #must be a 500 because we exceeding the limits assert_equal(response.status, 200) #must be a 500 because we exceeding the limits
self.nodes[0].generate(1) #generate block to not affect upcomming tests self.nodes[0].generate(1) #generate block to not affect upcoming tests
self.sync_all() self.sync_all()
################ ################

View File

@@ -1,31 +0,0 @@
#!/bin/bash
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
TIMEOUT=10
SIGNAL=HUP
PIDFILE=.send.pid
if [ $# -eq 0 ]; then
echo -e "Usage:\t$0 <cmd>"
echo -e "\tRuns <cmd> and wait ${TIMEOUT} seconds or until SIG${SIGNAL} is received."
echo -e "\tReturns: 0 if SIG${SIGNAL} is received, 1 otherwise."
echo -e "Or:\t$0 -STOP"
echo -e "\tsends SIG${SIGNAL} to running send.sh"
exit 0
fi
if [ $1 = "-STOP" ]; then
if [ -s ${PIDFILE} ]; then
kill -s ${SIGNAL} $(<$PIDFILE 2>/dev/null) 2>/dev/null
fi
exit 0
fi
trap '[[ ${PID} ]] && kill ${PID}' ${SIGNAL}
trap 'rm -f ${PIDFILE}' EXIT
echo $$ > ${PIDFILE}
"$@"
sleep ${TIMEOUT} & PID=$!
wait ${PID} && exit 1
exit 0

View File

@@ -27,6 +27,20 @@ generator that returns TestInstance objects. See below for definition.
global mininode_lock global mininode_lock
def wait_until(predicate, attempts=float('inf'), timeout=float('inf')):
attempt = 0
elapsed = 0
while attempt < attempts and elapsed < timeout:
with mininode_lock:
if predicate():
return True
attempt += 1
elapsed += 0.05
time.sleep(0.05)
return False
class TestNode(NodeConnCB): class TestNode(NodeConnCB):
def __init__(self, block_store, tx_store): def __init__(self, block_store, tx_store):
@@ -43,6 +57,10 @@ class TestNode(NodeConnCB):
# a response # a response
self.pingMap = {} self.pingMap = {}
self.lastInv = [] self.lastInv = []
self.closed = False
def on_close(self, conn):
self.closed = True
def add_connection(self, conn): def add_connection(self, conn):
self.conn = conn self.conn = conn
@@ -116,7 +134,7 @@ class TestNode(NodeConnCB):
# is reached) and then sent out in one inv message. Then the final block # is reached) and then sent out in one inv message. Then the final block
# will be synced across all connections, and the outcome of the final # will be synced across all connections, and the outcome of the final
# block will be tested. # block will be tested.
# sync_every_tx: analagous to behavior for sync_every_block, except if outcome # sync_every_tx: analogous to behavior for sync_every_block, except if outcome
# on the final tx is None, then contents of entire mempool are compared # on the final tx is None, then contents of entire mempool are compared
# across all connections. (If outcome of final tx is specified as true # across all connections. (If outcome of final tx is specified as true
# or false, then only the last tx is tested against outcome.) # or false, then only the last tx is tested against outcome.)
@@ -132,6 +150,7 @@ class TestManager(object):
def __init__(self, testgen, datadir): def __init__(self, testgen, datadir):
self.test_generator = testgen self.test_generator = testgen
self.connections = [] self.connections = []
self.test_nodes = []
self.block_store = BlockStore(datadir) self.block_store = BlockStore(datadir)
self.tx_store = TxStore(datadir) self.tx_store = TxStore(datadir)
self.ping_counter = 1 self.ping_counter = 1
@@ -139,54 +158,40 @@ class TestManager(object):
def add_all_connections(self, nodes): def add_all_connections(self, nodes):
for i in range(len(nodes)): for i in range(len(nodes)):
# Create a p2p connection to each node # Create a p2p connection to each node
self.connections.append(NodeConn('127.0.0.1', p2p_port(i), test_node = TestNode(self.block_store, self.tx_store)
nodes[i], TestNode(self.block_store, self.tx_store))) self.test_nodes.append(test_node)
self.connections.append(NodeConn('127.0.0.1', p2p_port(i), nodes[i], test_node))
# Make sure the TestNode (callback class) has a reference to its # Make sure the TestNode (callback class) has a reference to its
# associated NodeConn # associated NodeConn
self.connections[-1].cb.add_connection(self.connections[-1]) test_node.add_connection(self.connections[-1])
def wait_for_disconnections(self):
def disconnected():
return all(node.closed for node in self.test_nodes)
return wait_until(disconnected, timeout=10)
def wait_for_verack(self): def wait_for_verack(self):
sleep_time = 0.05 def veracked():
max_tries = 10 / sleep_time # Wait at most 10 seconds return all(node.verack_received for node in self.test_nodes)
while max_tries > 0: return wait_until(veracked, timeout=10)
done = True
with mininode_lock:
for c in self.connections:
if c.cb.verack_received is False:
done = False
break
if done:
break
time.sleep(sleep_time)
def wait_for_pings(self, counter): def wait_for_pings(self, counter):
received_pongs = False def received_pongs():
while received_pongs is not True: return all(node.received_ping_response(counter) for node in self.test_nodes)
time.sleep(0.05) return wait_until(received_pongs)
received_pongs = True
with mininode_lock:
for c in self.connections:
if c.cb.received_ping_response(counter) is not True:
received_pongs = False
break
# sync_blocks: Wait for all connections to request the blockhash given # sync_blocks: Wait for all connections to request the blockhash given
# then send get_headers to find out the tip of each node, and synchronize # then send get_headers to find out the tip of each node, and synchronize
# the response by using a ping (and waiting for pong with same nonce). # the response by using a ping (and waiting for pong with same nonce).
def sync_blocks(self, blockhash, num_blocks): def sync_blocks(self, blockhash, num_blocks):
# Wait for nodes to request block (50ms sleep * 20 tries * num_blocks) def blocks_requested():
max_tries = 20*num_blocks return all(
while max_tries > 0: blockhash in node.block_request_map and node.block_request_map[blockhash]
with mininode_lock: for node in self.test_nodes
results = [ blockhash in c.cb.block_request_map and )
c.cb.block_request_map[blockhash] for c in self.connections ]
if False not in results:
break
time.sleep(0.05)
max_tries -= 1
# --> error if not requested # --> error if not requested
if max_tries == 0: if not wait_until(blocks_requested, attempts=20*num_blocks):
# print [ c.cb.block_request_map for c in self.connections ] # print [ c.cb.block_request_map for c in self.connections ]
raise AssertionError("Not all nodes requested block") raise AssertionError("Not all nodes requested block")
# --> Answer request (we did this inline!) # --> Answer request (we did this inline!)
@@ -202,18 +207,14 @@ class TestManager(object):
# Analogous to sync_block (see above) # Analogous to sync_block (see above)
def sync_transaction(self, txhash, num_events): def sync_transaction(self, txhash, num_events):
# Wait for nodes to request transaction (50ms sleep * 20 tries * num_events) # Wait for nodes to request transaction (50ms sleep * 20 tries * num_events)
max_tries = 20*num_events def transaction_requested():
while max_tries > 0: return all(
with mininode_lock: txhash in node.tx_request_map and node.tx_request_map[txhash]
results = [ txhash in c.cb.tx_request_map and for node in self.test_nodes
c.cb.tx_request_map[txhash] for c in self.connections ] )
if False not in results:
break
time.sleep(0.05)
max_tries -= 1
# --> error if not requested # --> error if not requested
if max_tries == 0: if not wait_until(transaction_requested, attempts=20*num_events):
# print [ c.cb.tx_request_map for c in self.connections ] # print [ c.cb.tx_request_map for c in self.connections ]
raise AssertionError("Not all nodes requested transaction") raise AssertionError("Not all nodes requested transaction")
# --> Answer request (we did this inline!) # --> Answer request (we did this inline!)
@@ -336,6 +337,7 @@ class TestManager(object):
print "Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ] print "Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ]
test_number += 1 test_number += 1
[ c.disconnect_node() for c in self.connections ]
self.wait_for_disconnections()
self.block_store.close() self.block_store.close()
self.tx_store.close() self.tx_store.close()
[ c.disconnect_node() for c in self.connections ]

View File

@@ -1,103 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Functions used by more than one test
function echoerr {
echo "$@" 1>&2;
}
# Usage: ExtractKey <key> "<json_object_string>"
# Warning: this will only work for the very-well-behaved
# JSON produced by bitcoind, do NOT use it to try to
# parse arbitrary/nested/etc JSON.
function ExtractKey {
echo $2 | tr -d ' "{}\n' | awk -v RS=',' -F: "\$1 ~ /$1/ { print \$2}"
}
function CreateDataDir {
DIR=$1
mkdir -p $DIR
CONF=$DIR/bitcoin.conf
echo "regtest=1" >> $CONF
echo "keypool=2" >> $CONF
echo "rpcuser=rt" >> $CONF
echo "rpcpassword=rt" >> $CONF
echo "rpcwait=1" >> $CONF
echo "walletnotify=${SENDANDWAIT} -STOP" >> $CONF
shift
while (( "$#" )); do
echo $1 >> $CONF
shift
done
}
function AssertEqual {
if (( $( echo "$1 == $2" | bc ) == 0 ))
then
echoerr "AssertEqual: $1 != $2"
declare -f CleanUp > /dev/null 2>&1
if [[ $? -eq 0 ]] ; then
CleanUp
fi
exit 1
fi
}
# CheckBalance -datadir=... amount account minconf
function CheckBalance {
declare -i EXPECT="$2"
B=$( $CLI $1 getbalance $3 $4 )
if (( $( echo "$B == $EXPECT" | bc ) == 0 ))
then
echoerr "bad balance: $B (expected $2)"
declare -f CleanUp > /dev/null 2>&1
if [[ $? -eq 0 ]] ; then
CleanUp
fi
exit 1
fi
}
# Use: Address <datadir> [account]
function Address {
$CLI $1 getnewaddress $2
}
# Send from to amount
function Send {
from=$1
to=$2
amount=$3
address=$(Address $to)
txid=$( ${SENDANDWAIT} $CLI $from sendtoaddress $address $amount )
}
# Use: Unspent <datadir> <n'th-last-unspent> <var>
function Unspent {
local r=$( $CLI $1 listunspent | awk -F'[ |:,"]+' "\$2 ~ /$3/ { print \$3 }" | tail -n $2 | head -n 1)
echo $r
}
# Use: CreateTxn1 <datadir> <n'th-last-unspent> <destaddress>
# produces hex from signrawtransaction
function CreateTxn1 {
TXID=$(Unspent $1 $2 txid)
AMOUNT=$(Unspent $1 $2 amount)
VOUT=$(Unspent $1 $2 vout)
RAWTXN=$( $CLI $1 createrawtransaction "[{\"txid\":\"$TXID\",\"vout\":$VOUT}]" "{\"$3\":$AMOUNT}")
ExtractKey hex "$( $CLI $1 signrawtransaction $RAWTXN )"
}
# Use: SendRawTxn <datadir> <hex_txn_data>
function SendRawTxn {
${SENDANDWAIT} $CLI $1 sendrawtransaction $2
}
# Use: GetBlocks <datadir>
# returns number of blocks from getinfo
function GetBlocks {
$CLI $1 getblockcount
}

View File

@@ -117,6 +117,7 @@ BITCOIN_CORE_H = \
protocol.h \ protocol.h \
pubkey.h \ pubkey.h \
random.h \ random.h \
reverselock.h \
rpcclient.h \ rpcclient.h \
rpcprotocol.h \ rpcprotocol.h \
rpcserver.h \ rpcserver.h \

View File

@@ -59,6 +59,7 @@ BITCOIN_TESTS =\
test/pmt_tests.cpp \ test/pmt_tests.cpp \
test/policyestimator_tests.cpp \ test/policyestimator_tests.cpp \
test/pow_tests.cpp \ test/pow_tests.cpp \
test/reverselock_tests.cpp \
test/rpc_tests.cpp \ test/rpc_tests.cpp \
test/sanity_tests.cpp \ test/sanity_tests.cpp \
test/scheduler_tests.cpp \ test/scheduler_tests.cpp \

View File

@@ -265,7 +265,7 @@ public:
* Notice that vvTried, mapAddr and vVector are never encoded explicitly; * Notice that vvTried, mapAddr and vVector are never encoded explicitly;
* they are instead reconstructed from the other information. * they are instead reconstructed from the other information.
* *
* vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change, * vvNew is serialized, but only used if ADDRMAN_UNKNOWN_BUCKET_COUNT didn't change,
* otherwise it is reconstructed as well. * otherwise it is reconstructed as well.
* *
* This format is more complex, but significantly smaller (at most 1.5 MiB), and supports * This format is more complex, but significantly smaller (at most 1.5 MiB), and supports

View File

@@ -142,13 +142,14 @@ static void RegisterLoad(const string& strInput)
valStr.insert(valStr.size(), buf, bread); valStr.insert(valStr.size(), buf, bread);
} }
if (ferror(f)) { int error = ferror(f);
fclose(f);
if (error) {
string strErr = "Error reading file " + filename; string strErr = "Error reading file " + filename;
throw runtime_error(strErr); throw runtime_error(strErr);
} }
fclose(f);
// evaluate as JSON buffer register // evaluate as JSON buffer register
RegisterSetJson(key, valStr); RegisterSetJson(key, valStr);
} }

View File

@@ -1223,15 +1223,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
mempool.ReadFeeEstimates(est_filein); mempool.ReadFeeEstimates(est_filein);
fFeeEstimatesInitialized = true; fFeeEstimatesInitialized = true;
// if prune mode, unset NODE_NETWORK and prune block files
if (fPruneMode) {
LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
nLocalServices &= ~NODE_NETWORK;
if (!fReindex) {
PruneAndFlush();
}
}
// ********************************************************* Step 8: load wallet // ********************************************************* Step 8: load wallet
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
if (fDisableWallet) { if (fDisableWallet) {
@@ -1372,7 +1363,21 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#else // ENABLE_WALLET #else // ENABLE_WALLET
LogPrintf("No wallet support compiled in!\n"); LogPrintf("No wallet support compiled in!\n");
#endif // !ENABLE_WALLET #endif // !ENABLE_WALLET
// ********************************************************* Step 9: import blocks
// ********************************************************* Step 9: data directory maintenance
// if pruning, unset the service bit and perform the initial blockstore prune
// after any wallet rescanning has taken place.
if (fPruneMode) {
uiInterface.InitMessage(_("Pruning blockstore..."));
LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
nLocalServices &= ~NODE_NETWORK;
if (!fReindex) {
PruneAndFlush();
}
}
// ********************************************************* Step 10: import blocks
if (mapArgs.count("-blocknotify")) if (mapArgs.count("-blocknotify"))
uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
@@ -1396,7 +1401,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
MilliSleep(10); MilliSleep(10);
} }
// ********************************************************* Step 10: start node // ********************************************************* Step 11: start node
if (!CheckDiskSpace()) if (!CheckDiskSpace())
return false; return false;

View File

@@ -58,7 +58,8 @@ CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCa
} else { } else {
if (fWipe) { if (fWipe) {
LogPrintf("Wiping LevelDB in %s\n", path.string()); LogPrintf("Wiping LevelDB in %s\n", path.string());
leveldb::DestroyDB(path.string(), options); leveldb::Status result = leveldb::DestroyDB(path.string(), options);
HandleError(result);
} }
TryCreateDirectory(path); TryCreateDirectory(path);
LogPrintf("Opening LevelDB in %s\n", path.string()); LogPrintf("Opening LevelDB in %s\n", path.string());

View File

@@ -1331,9 +1331,11 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
pindexNew->GetBlockTime())); pindexNew->GetBlockTime()));
CBlockIndex *tip = chainActive.Tip();
assert (tip);
LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__, LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0),
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime())); DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
CheckForkWarningConditions(); CheckForkWarningConditions();
} }
@@ -1561,7 +1563,7 @@ bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
strMiscWarning = strMessage; strMiscWarning = strMessage;
LogPrintf("*** %s\n", strMessage); LogPrintf("*** %s\n", strMessage);
uiInterface.ThreadSafeMessageBox( uiInterface.ThreadSafeMessageBox(
userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
"", CClientUIInterface::MSG_ERROR); "", CClientUIInterface::MSG_ERROR);
StartShutdown(); StartShutdown();
return false; return false;
@@ -3508,7 +3510,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
} }
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
LogPrintf("%s: Deserialize or I/O error - %s", __func__, e.what()); LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
} }
} }
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {

View File

@@ -168,7 +168,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
// traverse the partial tree // traverse the partial tree
unsigned int nBitsUsed = 0, nHashUsed = 0; unsigned int nBitsUsed = 0, nHashUsed = 0;
uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch);
// verify that no problems occured during the tree traversal // verify that no problems occurred during the tree traversal
if (fBad) if (fBad)
return uint256(); return uint256();
// verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)

View File

@@ -554,7 +554,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
return false; return false;
if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) { if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId()); LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId());
return false; return false;
} }
@@ -1007,10 +1007,14 @@ void ThreadMapPort()
#ifndef UPNPDISCOVER_SUCCESS #ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */ /* miniupnpc 1.5 */
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
#else #elif MINIUPNPC_API_VERSION < 14
/* miniupnpc 1.6 */ /* miniupnpc 1.6 */
int error = 0; int error = 0;
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
#else
/* miniupnpc 1.9.20150730 */
int error = 0;
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
#endif #endif
struct UPNPUrls urls; struct UPNPUrls urls;
@@ -1502,8 +1506,10 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste
setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
#endif #endif
// Allow binding if the port is still in TIME_WAIT state after // Allow binding if the port is still in TIME_WAIT state after
// the program was closed and restarted. Not an issue on windows! // the program was closed and restarted.
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
#else
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int));
#endif #endif
// Set to non-blocking, incoming connections will also inherit this // Set to non-blocking, incoming connections will also inherit this
@@ -2052,8 +2058,10 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
Fuzz(GetArg("-fuzzmessagestest", 10)); Fuzz(GetArg("-fuzzmessagestest", 10));
if (ssSend.size() == 0) if (ssSend.size() == 0)
{
LEAVE_CRITICAL_SECTION(cs_vSend);
return; return;
}
// Set the size // Set the size
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE; unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize); WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);

View File

@@ -349,7 +349,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
} }
if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) { if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
CloseSocket(hSocket); CloseSocket(hSocket);
return error("Proxy authentication unsuccesful"); return error("Proxy authentication unsuccessful");
} }
} else if (pchRet1[1] == 0x00) { } else if (pchRet1[1] == 0x00) {
// Perform no authentication // Perform no authentication
@@ -983,7 +983,7 @@ std::vector<unsigned char> CNetAddr::GetGroup() const
nBits -= 8; nBits -= 8;
} }
if (nBits > 0) if (nBits > 0)
vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1)); vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
return vchRet; return vchRet;
} }

View File

@@ -249,7 +249,7 @@ unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val)
unsigned int bucketindex = bucketMap.lower_bound(val)->second; unsigned int bucketindex = bucketMap.lower_bound(val)->second;
unsigned int blockIndex = nBlockHeight % unconfTxs.size(); unsigned int blockIndex = nBlockHeight % unconfTxs.size();
unconfTxs[blockIndex][bucketindex]++; unconfTxs[blockIndex][bucketindex]++;
LogPrint("estimatefee", "adding to %s\n", dataTypeString); LogPrint("estimatefee", "adding to %s", dataTypeString);
return bucketindex; return bucketindex;
} }
@@ -261,7 +261,7 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe
blocksAgo = 0; blocksAgo = 0;
if (blocksAgo < 0) { if (blocksAgo < 0) {
LogPrint("estimatefee", "Blockpolicy error, blocks ago is negative for mempool tx\n"); LogPrint("estimatefee", "Blockpolicy error, blocks ago is negative for mempool tx\n");
return; //This can't happen becasue we call this with our best seen height, no entries can have higher return; //This can't happen because we call this with our best seen height, no entries can have higher
} }
if (blocksAgo >= (int)unconfTxs.size()) { if (blocksAgo >= (int)unconfTxs.size()) {
@@ -390,8 +390,9 @@ void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, boo
mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK()); mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK());
} }
else { else {
LogPrint("estimatefee", "not adding\n"); LogPrint("estimatefee", "not adding");
} }
LogPrint("estimatefee", "\n");
} }
void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry) void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry)

View File

@@ -118,7 +118,7 @@ public:
/** /**
* Initialize the data structures. This is called by BlockPolicyEstimator's * Initialize the data structures. This is called by BlockPolicyEstimator's
* constructor with default values. * constructor with default values.
* @param defaultBuckets contains the upper limits for the bucket boundries * @param defaultBuckets contains the upper limits for the bucket boundaries
* @param maxConfirms max number of confirms to track * @param maxConfirms max number of confirms to track
* @param decay how much to decay the historical moving average per block * @param decay how much to decay the historical moving average per block
* @param dataTypeString for logging purposes * @param dataTypeString for logging purposes

View File

@@ -764,7 +764,7 @@ void PaymentServer::setOptionsModel(OptionsModel *optionsModel)
void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) void PaymentServer::handlePaymentACK(const QString& paymentACKMsg)
{ {
// currently we don't futher process or store the paymentACK message // currently we don't further process or store the paymentACK message
Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL);
} }

View File

@@ -557,7 +557,7 @@ void RPCConsole::peerLayoutChanged()
if (detailNodeRow < 0) if (detailNodeRow < 0)
{ {
// detail node dissapeared from table (node disconnected) // detail node disappeared from table (node disconnected)
fUnselect = true; fUnselect = true;
cachedNodeid = -1; cachedNodeid = -1;
ui->detailWidget->hide(); ui->detailWidget->hide();

View File

@@ -57,7 +57,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
QPainter pixPaint(&pixmap); QPainter pixPaint(&pixmap);
pixPaint.setPen(QColor(100,100,100)); pixPaint.setPen(QColor(100,100,100));
// draw a slighly radial gradient // draw a slightly radial gradient
QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio); QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio);
gradient.setColorAt(0, Qt::white); gradient.setColorAt(0, Qt::white);
gradient.setColorAt(1, QColor(247,247,247)); gradient.setColorAt(1, QColor(247,247,247));

31
src/reverselock.h Normal file
View File

@@ -0,0 +1,31 @@
// Copyright (c) 2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_REVERSELOCK_H
#define BITCOIN_REVERSELOCK_H
/**
* An RAII-style reverse lock. Unlocks on construction and locks on destruction.
*/
template<typename Lock>
class reverse_lock
{
public:
explicit reverse_lock(Lock& lock) : lock(lock) {
lock.unlock();
}
~reverse_lock() {
lock.lock();
}
private:
reverse_lock(reverse_lock const&);
reverse_lock& operator=(reverse_lock const&);
Lock& lock;
};
#endif // BITCOIN_REVERSELOCK_H

View File

@@ -673,7 +673,7 @@ void StartRPCThreads()
vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort)); vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort));
vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort)); vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort));
// Prefer making the socket dual IPv6/IPv4 instead of binding // Prefer making the socket dual IPv6/IPv4 instead of binding
// to both addresses seperately. // to both addresses separately.
bBindAny = true; bBindAny = true;
} }
@@ -755,14 +755,14 @@ void StopRPCThreads()
{ {
acceptor->cancel(ec); acceptor->cancel(ec);
if (ec) if (ec)
LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message()); LogPrintf("%s: Warning: %s when cancelling acceptor\n", __func__, ec.message());
} }
rpc_acceptors.clear(); rpc_acceptors.clear();
BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers) BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers)
{ {
timer.second->cancel(ec); timer.second->cancel(ec);
if (ec) if (ec)
LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message()); LogPrintf("%s: Warning: %s when cancelling timer\n", __func__, ec.message());
} }
deadlineTimers.clear(); deadlineTimers.clear();

View File

@@ -4,6 +4,8 @@
#include "scheduler.h" #include "scheduler.h"
#include "reverselock.h"
#include <assert.h> #include <assert.h>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <utility> #include <utility>
@@ -65,11 +67,12 @@ void CScheduler::serviceQueue()
Function f = taskQueue.begin()->second; Function f = taskQueue.begin()->second;
taskQueue.erase(taskQueue.begin()); taskQueue.erase(taskQueue.begin());
// Unlock before calling f, so it can reschedule itself or another task {
// without deadlocking: // Unlock before calling f, so it can reschedule itself or another task
lock.unlock(); // without deadlocking:
f(); reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
lock.lock(); f();
}
} catch (...) { } catch (...) {
--nThreadsServicingQueue; --nThreadsServicingQueue;
throw; throw;

View File

@@ -16,7 +16,7 @@
//////////////////////////////////////////////// ////////////////////////////////////////////////
// // // //
// THE SIMPLE DEFINITON, EXCLUDING DEBUG CODE // // THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE //
// // // //
//////////////////////////////////////////////// ////////////////////////////////////////////////

View File

@@ -165,8 +165,8 @@ BOOST_AUTO_TEST_CASE(AlertNotify)
SetMockTime(11); SetMockTime(11);
const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey(); const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey();
boost::filesystem::path temp = GetTempPath() / "alertnotify.txt"; boost::filesystem::path temp = GetTempPath() /
boost::filesystem::remove(temp); boost::filesystem::unique_path("alertnotify-%%%%.txt");
mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string(); mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string();

View File

@@ -7,6 +7,7 @@
#include <string> #include <string>
#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
using namespace std; using namespace std;
@@ -145,4 +146,20 @@ BOOST_AUTO_TEST_CASE(subnet_test)
BOOST_CHECK(!CSubNet("fuzzy").IsValid()); BOOST_CHECK(!CSubNet("fuzzy").IsValid());
} }
BOOST_AUTO_TEST_CASE(netbase_getgroup)
{
BOOST_CHECK(CNetAddr("127.0.0.1").GetGroup() == boost::assign::list_of(0)); // Local -> !Routable()
BOOST_CHECK(CNetAddr("257.0.0.1").GetGroup() == boost::assign::list_of(0)); // !Valid -> !Routable()
BOOST_CHECK(CNetAddr("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable()
BOOST_CHECK(CNetAddr("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable()
BOOST_CHECK(CNetAddr("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4
BOOST_CHECK(CNetAddr("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145
BOOST_CHECK(CNetAddr("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052
BOOST_CHECK(CNetAddr("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964
BOOST_CHECK(CNetAddr("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC4380
BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor
BOOST_CHECK(CNetAddr("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(4)(112)(175)); //he.net
BOOST_CHECK(CNetAddr("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(32)(1)); //IPv6
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@@ -0,0 +1,64 @@
// Copyright (c) 2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "reverselock.h"
#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
BOOST_FIXTURE_TEST_SUITE(reverselock_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(reverselock_basics)
{
boost::mutex mutex;
boost::unique_lock<boost::mutex> lock(mutex);
BOOST_CHECK(lock.owns_lock());
{
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
BOOST_CHECK(!lock.owns_lock());
}
BOOST_CHECK(lock.owns_lock());
}
BOOST_AUTO_TEST_CASE(reverselock_errors)
{
boost::mutex mutex;
boost::unique_lock<boost::mutex> lock(mutex);
// Make sure trying to reverse lock an unlocked lock fails
lock.unlock();
BOOST_CHECK(!lock.owns_lock());
bool failed = false;
try {
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
} catch(...) {
failed = true;
}
BOOST_CHECK(failed);
BOOST_CHECK(!lock.owns_lock());
// Make sure trying to lock a lock after it has been reverse locked fails
failed = false;
bool locked = false;
lock.lock();
BOOST_CHECK(lock.owns_lock());
try {
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
lock.lock();
locked = true;
} catch(...) {
failed = true;
}
BOOST_CHECK(locked && failed);
BOOST_CHECK(lock.owns_lock());
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -341,7 +341,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
minerPolicyEstimator->Write(fileout); minerPolicyEstimator->Write(fileout);
} }
catch (const std::exception&) { catch (const std::exception&) {
LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)"); LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)\n");
return false; return false;
} }
return true; return true;
@@ -360,7 +360,7 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
minerPolicyEstimator->Read(filein); minerPolicyEstimator->Read(filein);
} }
catch (const std::exception&) { catch (const std::exception&) {
LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)"); LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)\n");
return false; return false;
} }
return true; return true;

View File

@@ -114,7 +114,7 @@ CTranslationInterface translationInterface;
/** Init OpenSSL library multithreading support */ /** Init OpenSSL library multithreading support */
static CCriticalSection** ppmutexOpenSSL; static CCriticalSection** ppmutexOpenSSL;
void locking_callback(int mode, int i, const char* file, int line) void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS
{ {
if (mode & CRYPTO_LOCK) { if (mode & CRYPTO_LOCK) {
ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]); ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]);

View File

@@ -186,7 +186,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
} }
if (keyPass && keyFail) if (keyPass && keyFail)
{ {
LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all."); LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n");
assert(false); assert(false);
} }
if (keyFail || !keyPass) if (keyFail || !keyPass)

View File

@@ -476,7 +476,6 @@ Value listaddressgroupings(const Array& params, bool fHelp)
addressInfo.push_back(CBitcoinAddress(address).ToString()); addressInfo.push_back(CBitcoinAddress(address).ToString());
addressInfo.push_back(ValueFromAmount(balances[address])); addressInfo.push_back(ValueFromAmount(balances[address]));
{ {
LOCK(pwalletMain->cs_wallet);
if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end()) if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end())
addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name); addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name);
} }
@@ -796,7 +795,7 @@ Value movecmd(const Array& params, bool fHelp)
"3. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "3. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
"4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" "4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
"\nResult:\n" "\nResult:\n"
"true|false (boolean) true if successfull.\n" "true|false (boolean) true if successful.\n"
"\nExamples:\n" "\nExamples:\n"
"\nMove 0.01 btc from the default account to the account named tabby\n" "\nMove 0.01 btc from the default account to the account named tabby\n"
+ HelpExampleCli("move", "\"\" \"tabby\" 0.01") + + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +

View File

@@ -2001,7 +2001,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
if (!wtxNew.AcceptToMemoryPool(false)) if (!wtxNew.AcceptToMemoryPool(false))
{ {
// This must not fail. The transaction has already been signed and recorded. // This must not fail. The transaction has already been signed and recorded.
LogPrintf("CommitTransaction(): Error: Transaction not valid"); LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
return false; return false;
} }
wtxNew.RelayWalletTransaction(); wtxNew.RelayWalletTransaction();