Merge pull request #6703
45bfa13PARTIAL: typofixes (found by misspell_fixer) (Veres Lajos)21c406eadd support for miniupnpc api version 14 (Pavel Vasin)13bd5a7rpc-tests: re-enable rpc-tests for Windows (Cory Fields)ccc4ad6net: Set SO_REUSEADDR for Windows too (Cory Fields)1f6772eadd unit test for CNetAddr::GetGroup. (Alex Morcos)13642a5Fix masking of irrelevant bits in address groups. (Alex Morcos)6b51b9bReplace boost::reverse_lock with our own. (Casey Rodarmor)626c5e6Make sure we re-acquire lock if a task throws (Casey Rodarmor)4877053Add missing files to files.md (fanquake)f171feeHandle leveldb::DestroyDB() errors on wipe failure (Adam Weiss)c5b89feFix race condition on test node shutdown (Casey Rodarmor)4a37410Handle no chain tip available in InvalidChainFound() (Ross Nicoll)f6d29a6Use unique name for AlertNotify tempfile (Casey Rodarmor)e6adac7Delay initial pruning until after wallet init (Adam Weiss)e0020d4Make sure LogPrint strings are line-terminated (J Ross Nicoll)7ff9d12Make sure LogPrintf strings are line-terminated (Wladimir J. van der Laan)5a39133build: fix libressl detection (Cory Fields)f6355e6Avoid leaking file descriptors in RegisterLoad (Casey Rodarmor)60457d3locking: fix a few small issues uncovered by -Wthread-safety (Cory Fields)a496e11Remove bash test note from rpc-tests readme (fanquake)49c6a64tests: Remove old sh-based test framework (Wladimir J. van der Laan)a37567dAdd autogen.sh to source tarball. (randy-waterhouse)1f4d7cftravis: for travis generating an extra build (Cory Fields)
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
15
configure.ac
15
configure.ac
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
2
depends/config.guess
vendored
2
depends/config.guess
vendored
@@ -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 ;;
|
||||||
|
|||||||
12
doc/files.md
12
doc/files.md
@@ -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
|
||||||
---------------------
|
---------------------
|
||||||
|
|||||||
@@ -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=(
|
||||||
|
|||||||
@@ -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
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
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()
|
||||||
|
|
||||||
################
|
################
|
||||||
|
|||||||
@@ -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
|
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 ]
|
|
||||||
|
|||||||
@@ -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 \
|
protocol.h \
|
||||||
pubkey.h \
|
pubkey.h \
|
||||||
random.h \
|
random.h \
|
||||||
|
reverselock.h \
|
||||||
rpcclient.h \
|
rpcclient.h \
|
||||||
rpcprotocol.h \
|
rpcprotocol.h \
|
||||||
rpcserver.h \
|
rpcserver.h \
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/init.cpp
27
src/init.cpp
@@ -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;
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
10
src/main.cpp
10
src/main.cpp
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
16
src/net.cpp
16
src/net.cpp
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
31
src/reverselock.h
Normal 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
|
||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
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();
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
64
src/test/reverselock_tests.cpp
Normal file
64
src/test/reverselock_tests.cpp
Normal 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()
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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") +
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user