Browse Source

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)
pull/4/head
Wladimir J. van der Laan 9 years ago
parent
commit
1cd7952dde
No known key found for this signature in database GPG Key ID: 74810B012346C9A6
  1. 3
      .travis.yml
  2. 2
      Makefile.am
  3. 15
      configure.ac
  4. 6
      contrib/debian/changelog
  5. 2
      depends/config.guess
  6. 12
      doc/files.md
  7. 5
      qa/pull-tester/rpc-tests.sh
  8. 4
      qa/rpc-tests/README.md
  9. 147
      qa/rpc-tests/conflictedbalance.sh
  10. 2
      qa/rpc-tests/rest.py
  11. 31
      qa/rpc-tests/send.sh
  12. 96
      qa/rpc-tests/test_framework/comptool.py
  13. 103
      qa/rpc-tests/util.sh
  14. 1
      src/Makefile.am
  15. 1
      src/Makefile.test.include
  16. 2
      src/addrman.h
  17. 7
      src/bitcoin-tx.cpp
  18. 27
      src/init.cpp
  19. 3
      src/leveldbwrapper.cpp
  20. 10
      src/main.cpp
  21. 2
      src/merkleblock.cpp
  22. 16
      src/net.cpp
  23. 4
      src/netbase.cpp
  24. 7
      src/policy/fees.cpp
  25. 2
      src/policy/fees.h
  26. 2
      src/qt/paymentserver.cpp
  27. 2
      src/qt/rpcconsole.cpp
  28. 2
      src/qt/splashscreen.cpp
  29. 31
      src/reverselock.h
  30. 6
      src/rpcserver.cpp
  31. 13
      src/scheduler.cpp
  32. 2
      src/sync.h
  33. 4
      src/test/alert_tests.cpp
  34. 17
      src/test/netbase_tests.cpp
  35. 64
      src/test/reverselock_tests.cpp
  36. 4
      src/txmempool.cpp
  37. 2
      src/util.cpp
  38. 2
      src/wallet/crypter.cpp
  39. 3
      src/wallet/rpcwallet.cpp
  40. 2
      src/wallet/wallet.cpp

3
.travis.yml

@ -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

2
Makefile.am

@ -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

@ -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"

6
contrib/debian/changelog

@ -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,

2
depends/config.guess

@ -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

@ -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
---------------------

5
qa/pull-tester/rpc-tests.sh

@ -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=(

4
qa/rpc-tests/README.md

@ -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
=====

147
qa/rpc-tests/conflictedbalance.sh

@ -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

2
qa/rpc-tests/rest.py

@ -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()
################

31
qa/rpc-tests/send.sh

@ -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

96
qa/rpc-tests/test_framework/comptool.py

@ -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 ]

103
qa/rpc-tests/util.sh

@ -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
}

1
src/Makefile.am

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

1
src/Makefile.test.include

@ -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 \

2
src/addrman.h

@ -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

7
src/bitcoin-tx.cpp

@ -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

@ -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;

3
src/leveldbwrapper.cpp

@ -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

@ -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) {

2
src/merkleblock.cpp

@ -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

@ -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);

4
src/netbase.cpp

@ -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;
}

7
src/policy/fees.cpp

@ -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)

2
src/policy/fees.h

@ -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

2
src/qt/paymentserver.cpp

@ -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);
}

2
src/qt/rpcconsole.cpp

@ -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();

2
src/qt/splashscreen.cpp

@ -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));

31
src/reverselock.h

@ -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

6
src/rpcserver.cpp

@ -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();

13
src/scheduler.cpp

@ -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();
f();
lock.lock();
{
// Unlock before calling f, so it can reschedule itself or another task
// without deadlocking:
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
f();
}
} catch (...) {
--nThreadsServicingQueue;
throw;

2
src/sync.h

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

4
src/test/alert_tests.cpp

@ -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();

17
src/test/netbase_tests.cpp

@ -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()

64
src/test/reverselock_tests.cpp

@ -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()

4
src/txmempool.cpp

@ -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;

2
src/util.cpp

@ -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]);

2
src/wallet/crypter.cpp

@ -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)

3
src/wallet/rpcwallet.cpp

@ -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") +

2
src/wallet/wallet.cpp

@ -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…
Cancel
Save