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:
commit
1cd7952dde
|
@ -6,6 +6,7 @@
|
|||
|
||||
os: linux
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
env:
|
||||
global:
|
||||
- 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"
|
||||
- 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"
|
||||
exclude:
|
||||
- compiler: gcc
|
||||
install:
|
||||
- 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
|
||||
|
|
|
@ -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
|
||||
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)
|
||||
|
||||
CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER)
|
||||
|
|
15
configure.ac
15
configure.ac
|
@ -692,6 +692,21 @@ LIBS_TEMP="$LIBS"
|
|||
CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS"
|
||||
LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS"
|
||||
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"
|
||||
LIBS="$LIBS_TEMP"
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ bitcoin (0.5.3-natty0) natty; urgency=low
|
|||
bitcoin (0.5.2-natty1) natty; urgency=low
|
||||
|
||||
* 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
|
||||
capable of doing
|
||||
|
||||
|
@ -190,7 +190,7 @@ bitcoin (0.5.0~rc1-natty1) natty; urgency=low
|
|||
|
||||
* Add test_bitcoin to build test
|
||||
* Fix clean
|
||||
* Remove uneccessary build-dependancies
|
||||
* Remove unnecessary build-dependancies
|
||||
|
||||
-- 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
|
||||
|
||||
* Fix override agressive optimizations.
|
||||
* Fix override aggressive optimizations.
|
||||
* Fix tighten build-dependencies to really fit backporting to Lenny:
|
||||
+ Add fallback build-dependency on libdb4.6++-dev.
|
||||
+ Tighten unversioned Boost build-dependencies to recent versions,
|
||||
|
|
|
@ -1117,7 +1117,7 @@ EOF
|
|||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# 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.
|
||||
echo i586-pc-msdosdjgpp
|
||||
exit ;;
|
||||
|
|
12
doc/files.md
12
doc/files.md
|
@ -1,12 +1,16 @@
|
|||
Used in 0.8.0
|
||||
---------------------
|
||||
* wallet.dat: personal wallet (BDB) with keys and transactions
|
||||
* peers.dat: peer IP address database (custom format); since 0.7.0
|
||||
|
||||
* bitcoin.conf: contains configuration settings for bitcoind or bitcoin-qt
|
||||
* bitcoind.pid: stores the process id of bitcoind while running
|
||||
* 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/index/*; block index (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
|
||||
* 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
|
||||
---------------------
|
||||
|
|
|
@ -8,11 +8,6 @@ CURDIR=$(cd $(dirname "$0"); pwd)
|
|||
export BITCOINCLI=${BUILDDIR}/qa/pull-tester/run-bitcoin-cli
|
||||
export BITCOIND=${REAL_BITCOIND}
|
||||
|
||||
if [ "x${EXEEXT}" = "x.exe" ]; then
|
||||
echo "Win tests currently disabled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#Run the tests
|
||||
|
||||
testScripts=(
|
||||
|
|
|
@ -12,10 +12,6 @@ Base class for new regression tests.
|
|||
### [test_framework/util.py](test_framework/util.py)
|
||||
Generally useful functions.
|
||||
|
||||
Bash-based tests, to be ported to Python:
|
||||
-----------------------------------------
|
||||
- conflictedbalance.sh : More testing of malleable transaction handling
|
||||
|
||||
Notes
|
||||
=====
|
||||
|
||||
|
|
|
@ -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
|
|
@ -199,7 +199,7 @@ class RESTTest (BitcoinTestFramework):
|
|||
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
|
||||
|
||||
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()
|
||||
|
||||
################
|
||||
|
|
|
@ -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
|
|
@ -27,6 +27,20 @@ generator that returns TestInstance objects. See below for definition.
|
|||
|
||||
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):
|
||||
|
||||
def __init__(self, block_store, tx_store):
|
||||
|
@ -43,6 +57,10 @@ class TestNode(NodeConnCB):
|
|||
# a response
|
||||
self.pingMap = {}
|
||||
self.lastInv = []
|
||||
self.closed = False
|
||||
|
||||
def on_close(self, conn):
|
||||
self.closed = True
|
||||
|
||||
def add_connection(self, 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
|
||||
# will be synced across all connections, and the outcome of the final
|
||||
# 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
|
||||
# across all connections. (If outcome of final tx is specified as true
|
||||
# or false, then only the last tx is tested against outcome.)
|
||||
|
@ -132,6 +150,7 @@ class TestManager(object):
|
|||
def __init__(self, testgen, datadir):
|
||||
self.test_generator = testgen
|
||||
self.connections = []
|
||||
self.test_nodes = []
|
||||
self.block_store = BlockStore(datadir)
|
||||
self.tx_store = TxStore(datadir)
|
||||
self.ping_counter = 1
|
||||
|
@ -139,54 +158,40 @@ class TestManager(object):
|
|||
def add_all_connections(self, nodes):
|
||||
for i in range(len(nodes)):
|
||||
# Create a p2p connection to each node
|
||||
self.connections.append(NodeConn('127.0.0.1', p2p_port(i),
|
||||
nodes[i], TestNode(self.block_store, self.tx_store)))
|
||||
test_node = 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
|
||||
# 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):
|
||||
sleep_time = 0.05
|
||||
max_tries = 10 / sleep_time # Wait at most 10 seconds
|
||||
while max_tries > 0:
|
||||
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 veracked():
|
||||
return all(node.verack_received for node in self.test_nodes)
|
||||
return wait_until(veracked, timeout=10)
|
||||
|
||||
def wait_for_pings(self, counter):
|
||||
received_pongs = False
|
||||
while received_pongs is not True:
|
||||
time.sleep(0.05)
|
||||
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
|
||||
def received_pongs():
|
||||
return all(node.received_ping_response(counter) for node in self.test_nodes)
|
||||
return wait_until(received_pongs)
|
||||
|
||||
# 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
|
||||
# the response by using a ping (and waiting for pong with same nonce).
|
||||
def sync_blocks(self, blockhash, num_blocks):
|
||||
# Wait for nodes to request block (50ms sleep * 20 tries * num_blocks)
|
||||
max_tries = 20*num_blocks
|
||||
while max_tries > 0:
|
||||
with mininode_lock:
|
||||
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
|
||||
def blocks_requested():
|
||||
return all(
|
||||
blockhash in node.block_request_map and node.block_request_map[blockhash]
|
||||
for node in self.test_nodes
|
||||
)
|
||||
|
||||
# --> 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 ]
|
||||
raise AssertionError("Not all nodes requested block")
|
||||
# --> Answer request (we did this inline!)
|
||||
|
@ -202,18 +207,14 @@ class TestManager(object):
|
|||
# Analogous to sync_block (see above)
|
||||
def sync_transaction(self, txhash, num_events):
|
||||
# Wait for nodes to request transaction (50ms sleep * 20 tries * num_events)
|
||||
max_tries = 20*num_events
|
||||
while max_tries > 0:
|
||||
with mininode_lock:
|
||||
results = [ txhash in c.cb.tx_request_map and
|
||||
c.cb.tx_request_map[txhash] for c in self.connections ]
|
||||
if False not in results:
|
||||
break
|
||||
time.sleep(0.05)
|
||||
max_tries -= 1
|
||||
def transaction_requested():
|
||||
return all(
|
||||
txhash in node.tx_request_map and node.tx_request_map[txhash]
|
||||
for node in self.test_nodes
|
||||
)
|
||||
|
||||
# --> 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 ]
|
||||
raise AssertionError("Not all nodes requested transaction")
|
||||
# --> 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 ]
|
||||
test_number += 1
|
||||
|
||||
[ c.disconnect_node() for c in self.connections ]
|
||||
self.wait_for_disconnections()
|
||||
self.block_store.close()
|
||||
self.tx_store.close()
|
||||
[ c.disconnect_node() for c in self.connections ]
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -117,6 +117,7 @@ BITCOIN_CORE_H = \
|
|||
protocol.h \
|
||||
pubkey.h \
|
||||
random.h \
|
||||
reverselock.h \
|
||||
rpcclient.h \
|
||||
rpcprotocol.h \
|
||||
rpcserver.h \
|
||||
|
|
|
@ -59,6 +59,7 @@ BITCOIN_TESTS =\
|
|||
test/pmt_tests.cpp \
|
||||
test/policyestimator_tests.cpp \
|
||||
test/pow_tests.cpp \
|
||||
test/reverselock_tests.cpp \
|
||||
test/rpc_tests.cpp \
|
||||
test/sanity_tests.cpp \
|
||||
test/scheduler_tests.cpp \
|
||||
|
|
|
@ -265,7 +265,7 @@ public:
|
|||
* Notice that vvTried, mapAddr and vVector are never encoded explicitly;
|
||||
* 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.
|
||||
*
|
||||
* This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
|
||||
|
|
|
@ -142,13 +142,14 @@ static void RegisterLoad(const string& strInput)
|
|||
valStr.insert(valStr.size(), buf, bread);
|
||||
}
|
||||
|
||||
if (ferror(f)) {
|
||||
int error = ferror(f);
|
||||
fclose(f);
|
||||
|
||||
if (error) {
|
||||
string strErr = "Error reading file " + filename;
|
||||
throw runtime_error(strErr);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
// evaluate as JSON buffer register
|
||||
RegisterSetJson(key, valStr);
|
||||
}
|
||||
|
|
27
src/init.cpp
27
src/init.cpp
|
@ -1223,15 +1223,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
mempool.ReadFeeEstimates(est_filein);
|
||||
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
|
||||
#ifdef ENABLE_WALLET
|
||||
if (fDisableWallet) {
|
||||
|
@ -1372,7 +1363,21 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
#else // ENABLE_WALLET
|
||||
LogPrintf("No wallet support compiled in!\n");
|
||||
#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"))
|
||||
uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
|
||||
|
@ -1396,7 +1401,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
MilliSleep(10);
|
||||
}
|
||||
|
||||
// ********************************************************* Step 10: start node
|
||||
// ********************************************************* Step 11: start node
|
||||
|
||||
if (!CheckDiskSpace())
|
||||
return false;
|
||||
|
|
|
@ -58,7 +58,8 @@ CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCa
|
|||
} else {
|
||||
if (fWipe) {
|
||||
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);
|
||||
LogPrintf("Opening LevelDB in %s\n", path.string());
|
||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -1331,9 +1331,11 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
|
|||
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
|
||||
log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
|
||||
pindexNew->GetBlockTime()));
|
||||
CBlockIndex *tip = chainActive.Tip();
|
||||
assert (tip);
|
||||
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),
|
||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()));
|
||||
tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0),
|
||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
|
||||
CheckForkWarningConditions();
|
||||
}
|
||||
|
||||
|
@ -1561,7 +1563,7 @@ bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
|
|||
strMiscWarning = strMessage;
|
||||
LogPrintf("*** %s\n", strMessage);
|
||||
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);
|
||||
StartShutdown();
|
||||
return false;
|
||||
|
@ -3508,7 +3510,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
|||
}
|
||||
}
|
||||
} 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) {
|
||||
|
|
|
@ -168,7 +168,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
|
|||
// traverse the partial tree
|
||||
unsigned int nBitsUsed = 0, nHashUsed = 0;
|
||||
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)
|
||||
return uint256();
|
||||
// verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
|
||||
|
|
16
src/net.cpp
16
src/net.cpp
|
@ -554,7 +554,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
|
|||
return false;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1007,10 +1007,14 @@ void ThreadMapPort()
|
|||
#ifndef UPNPDISCOVER_SUCCESS
|
||||
/* miniupnpc 1.5 */
|
||||
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
|
||||
#else
|
||||
#elif MINIUPNPC_API_VERSION < 14
|
||||
/* miniupnpc 1.6 */
|
||||
int error = 0;
|
||||
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
|
||||
|
||||
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));
|
||||
#endif
|
||||
// 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));
|
||||
#else
|
||||
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int));
|
||||
#endif
|
||||
|
||||
// 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));
|
||||
|
||||
if (ssSend.size() == 0)
|
||||
{
|
||||
LEAVE_CRITICAL_SECTION(cs_vSend);
|
||||
return;
|
||||
|
||||
}
|
||||
// Set the size
|
||||
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
|
||||
WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
|
||||
|
|
|
@ -349,7 +349,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
|||
}
|
||||
if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Proxy authentication unsuccesful");
|
||||
return error("Proxy authentication unsuccessful");
|
||||
}
|
||||
} else if (pchRet1[1] == 0x00) {
|
||||
// Perform no authentication
|
||||
|
@ -983,7 +983,7 @@ std::vector<unsigned char> CNetAddr::GetGroup() const
|
|||
nBits -= 8;
|
||||
}
|
||||
if (nBits > 0)
|
||||
vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1));
|
||||
vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
|
||||
|
||||
return vchRet;
|
||||
}
|
||||
|
|
|
@ -249,7 +249,7 @@ unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val)
|
|||
unsigned int bucketindex = bucketMap.lower_bound(val)->second;
|
||||
unsigned int blockIndex = nBlockHeight % unconfTxs.size();
|
||||
unconfTxs[blockIndex][bucketindex]++;
|
||||
LogPrint("estimatefee", "adding to %s\n", dataTypeString);
|
||||
LogPrint("estimatefee", "adding to %s", dataTypeString);
|
||||
return bucketindex;
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe
|
|||
blocksAgo = 0;
|
||||
if (blocksAgo < 0) {
|
||||
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()) {
|
||||
|
@ -390,8 +390,9 @@ void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, boo
|
|||
mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK());
|
||||
}
|
||||
else {
|
||||
LogPrint("estimatefee", "not adding\n");
|
||||
LogPrint("estimatefee", "not adding");
|
||||
}
|
||||
LogPrint("estimatefee", "\n");
|
||||
}
|
||||
|
||||
void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry)
|
||||
|
|
|
@ -118,7 +118,7 @@ public:
|
|||
/**
|
||||
* Initialize the data structures. This is called by BlockPolicyEstimator's
|
||||
* 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 decay how much to decay the historical moving average per block
|
||||
* @param dataTypeString for logging purposes
|
||||
|
|
|
@ -764,7 +764,7 @@ void PaymentServer::setOptionsModel(OptionsModel *optionsModel)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -557,7 +557,7 @@ void RPCConsole::peerLayoutChanged()
|
|||
|
||||
if (detailNodeRow < 0)
|
||||
{
|
||||
// detail node dissapeared from table (node disconnected)
|
||||
// detail node disappeared from table (node disconnected)
|
||||
fUnselect = true;
|
||||
cachedNodeid = -1;
|
||||
ui->detailWidget->hide();
|
||||
|
|
|
@ -57,7 +57,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
|
|||
QPainter pixPaint(&pixmap);
|
||||
pixPaint.setPen(QColor(100,100,100));
|
||||
|
||||
// draw a slighly radial gradient
|
||||
// draw a slightly radial gradient
|
||||
QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio);
|
||||
gradient.setColorAt(0, Qt::white);
|
||||
gradient.setColorAt(1, QColor(247,247,247));
|
||||
|
|
|
@ -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
|
|
@ -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_v4::any(), defaultPort));
|
||||
// Prefer making the socket dual IPv6/IPv4 instead of binding
|
||||
// to both addresses seperately.
|
||||
// to both addresses separately.
|
||||
bBindAny = true;
|
||||
}
|
||||
|
||||
|
@ -755,14 +755,14 @@ void StopRPCThreads()
|
|||
{
|
||||
acceptor->cancel(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();
|
||||
BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers)
|
||||
{
|
||||
timer.second->cancel(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();
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "scheduler.h"
|
||||
|
||||
#include "reverselock.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <boost/bind.hpp>
|
||||
#include <utility>
|
||||
|
@ -65,11 +67,12 @@ void CScheduler::serviceQueue()
|
|||
Function f = taskQueue.begin()->second;
|
||||
taskQueue.erase(taskQueue.begin());
|
||||
|
||||
{
|
||||
// Unlock before calling f, so it can reschedule itself or another task
|
||||
// without deadlocking:
|
||||
lock.unlock();
|
||||
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
|
||||
f();
|
||||
lock.lock();
|
||||
}
|
||||
} catch (...) {
|
||||
--nThreadsServicingQueue;
|
||||
throw;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
////////////////////////////////////////////////
|
||||
// //
|
||||
// THE SIMPLE DEFINITON, EXCLUDING DEBUG CODE //
|
||||
// THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE //
|
||||
// //
|
||||
////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -165,8 +165,8 @@ BOOST_AUTO_TEST_CASE(AlertNotify)
|
|||
SetMockTime(11);
|
||||
const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey();
|
||||
|
||||
boost::filesystem::path temp = GetTempPath() / "alertnotify.txt";
|
||||
boost::filesystem::remove(temp);
|
||||
boost::filesystem::path temp = GetTempPath() /
|
||||
boost::filesystem::unique_path("alertnotify-%%%%.txt");
|
||||
|
||||
mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string();
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
@ -145,4 +146,20 @@ BOOST_AUTO_TEST_CASE(subnet_test)
|
|||
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()
|
||||
|
|
|
@ -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()
|
|
@ -341,7 +341,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
|
|||
minerPolicyEstimator->Write(fileout);
|
||||
}
|
||||
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 true;
|
||||
|
@ -360,7 +360,7 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
|
|||
minerPolicyEstimator->Read(filein);
|
||||
}
|
||||
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 true;
|
||||
|
|
|
@ -114,7 +114,7 @@ CTranslationInterface translationInterface;
|
|||
|
||||
/** Init OpenSSL library multithreading support */
|
||||
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) {
|
||||
ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
|
||||
|
|
|
@ -186,7 +186,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
|||
}
|
||||
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);
|
||||
}
|
||||
if (keyFail || !keyPass)
|
||||
|
|
|
@ -476,7 +476,6 @@ Value listaddressgroupings(const Array& params, bool fHelp)
|
|||
addressInfo.push_back(CBitcoinAddress(address).ToString());
|
||||
addressInfo.push_back(ValueFromAmount(balances[address]));
|
||||
{
|
||||
LOCK(pwalletMain->cs_wallet);
|
||||
if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end())
|
||||
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"
|
||||
"4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
|
||||
"\nResult:\n"
|
||||
"true|false (boolean) true if successfull.\n"
|
||||
"true|false (boolean) true if successful.\n"
|
||||
"\nExamples:\n"
|
||||
"\nMove 0.01 btc from the default account to the account named tabby\n"
|
||||
+ HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
|
||||
|
|
|
@ -2001,7 +2001,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
|
|||
if (!wtxNew.AcceptToMemoryPool(false))
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
wtxNew.RelayWalletTransaction();
|
||||
|
|
Loading…
Reference in New Issue