Merge #502: [0.17 MERGE] Merge up to Core 3832c25f17

634e3953f MERGE FIX: Prevent mainnet unit tests from thinking they have signed blocks after custom tests (Gregory Sanders)
c42c82329 MERGE FIX: Pegin witness test cleanup (Gregory Sanders)
6c1c65249 MERGE FIX: move pegin witness test to beginning to maybe avoid dirtying other tests (Gregory Sanders)
a36ee6c0e MERGE FIX: Augment IsValidPeginWitness with err string return (Gregory Sanders)
9d9ee3d51 MERGE FIX: Adapt bitcoin_functional sync to regtest2 (Gregory Sanders)
7c97d6a81 MERGE FIX: sync up bitcoin_functional (Gregory Sanders)
949405202 MERGE FIX: enable parent chain in fedpeg-based unit tests (Gregory Sanders)
c73e56428 MERGE FIX: instantiate consensus.has_parent_chain for all chains (Gregory Sanders)
4f4fe8f6c MERGE FIX: ConnectTip: ub fix for bench (Gregory Sanders)
80857b329 MERGE FIX: TEST: fixup bitcoin functional (Gregory Sanders)
e0a8aba13 MERGE FIX: Properly parse sendtomainchain args from -cli (Gregory Sanders)
420267122 MERGE FIX: spelling linter fixes (Gregory Sanders)
01799727c MERGE FIX: fixup travis bitcoin_functional run (Gregory Sanders)
90f7d18c8 MERGE-FIX: functional tests (Gregory Sanders)
51584e73a MERGE-FIX: various compilation fixes (Gregory Sanders)
d641c29a5 travis: Run feature_dbcrash functional tests in cron job (Chun Kuan Lee)
c0d947d72 tests: Reorder tests and move most of extended tests up to normal tests (Chun Kuan Lee)
cccc362d6 build: Remove libssl from LDADD unless gui (MarcoFalke)
8e1c13e6d doc: Document -checklevel levels (Wladimir J. van der Laan)
c1dde3a94 No longer shutdown after encrypting the wallet (Andrew Chow)
d7637c5a3 After encrypting the wallet, reload the database environment (Andrew Chow)
5d296ac81 Add function to close all Db's and reload the databae environment (Andrew Chow)
a769461d5 Move BerkeleyEnvironment deletion from internal method to callsite (Andrew Chow)
9dcb6763f [qa] Use correct python index slices in example test (Suhas Daftuar)
fa8433e37 qa: Remove unneded import_deterministic_coinbase_privkeys overwrite, add comments (MarcoFalke)
e413c2ddd qa: Fix codespell error and have lint-spelling error instead of warn (MarcoFalke)
14b29a77a Fix reference to lint-locale-dependence.sh (Hennadii Stepanov)
e22136893 utils: Convert fs error messages from multibyte to utf-8 (Chun Kuan Lee)
e4ef4b459 [build] remove #ifdef ENABLE_WALLET from interfaces/node (John Newbery)
fa6ab8ada rpc: Return more specific reject reason for submitblock (MarcoFalke)
b16ab9af0 Report progress in ReplayBlocks while rolling forward (João Barbosa)
b6a253337 Remove redundant BIP174 test from rpc_psbt.json (araspitzu)
fac953983 qa: Run all tests even if wallet is not compiled (MarcoFalke)
faa669cbc qa: Premine to deterministic address with -disablewallet (MarcoFalke)
d38bf9105 Call unicode API on Windows (Chun Kuan Lee)
d0b1cee1f doc: `-help-debug` implies `-help` (Wladimir J. van der Laan)
9a565a828 Pass export privkey DER compression flag correctly (liuyujun)
fae3fbd61 logging: Replace LogPrint macros with regular functions (MarcoFalke)
e0664f7f5 build: Move interfaces/* to libbitcoin_server (Wladimir J. van der Laan)
23db9546c utils: run commands using utf-8 string on Windows (Chun Kuan Lee)
7d038dcb4 [build] remove ENABLE_WALLET ifdef from httprpc.cpp (John Newbery)
3076556cd [build] Move dummy wallet into its own .cpp file. (John Newbery)
bb6ca65f9 gui: get special folder in unicode (Chun Kuan Lee)
1c5d22585 Drop boost::scoped_array (Chun Kuan Lee)
e7a72455f Scripts and tools: increased timeout downloading (Emanuele Cisbani)
a679109be Speed up knapsack_solver_test by not recreating wallet 100 times. (lucash.dev@gmail.com)
893628be0 Drop minor GetSerializeSize template (Ben Woosley)
da74db094 Drop unused GetType() from CSizeComputer (Ben Woosley)
b9babc82d utils: Use _wfopen and _wreopen on Windows (Chun Kuan Lee)
fa7e9694e qt: Also log and print messages or questions like bitcoind (MarcoFalke)
dd031e383 noui: Move handlers to header file (MarcoFalke)
fa263bcfe qa: Fix silent merge conflict in wallet_importmulti (MarcoFalke)
98ea64cf2 Let wallet importmulti RPC accept labels for standard scriptPubKeys (Russell Yanofsky)
faa1a7494 tx pool: Use class methods to hide raw map iterator impl details (MarcoFalke)
d9d79576f Preserve a format of RPC command definitions (Kostiantyn Stepaniuk)
9256f7d13 build: avoid getifaddrs when unavailable (Cory Fields)
fa462b365 wallet: Set encrypted_batch to nullptr after delete. Avoid double free in the case of NDEBUG. (practicalswift)
faea5bfc5 doc: release notes for -enablebip61 default change (MarcoFalke)
fa14b54a8 p2p: Disable BIP 61 by default (MarcoFalke)
7177e093f depends: Remove unused Qt 4 dependencies (Chun Kuan Lee)
dc287c98f Squashed 'src/univalue/' changes from 51d3ab34ba..7890db99d6 (MarcoFalke)
946107a68 Only log "Using PATH_TO_bitcoin.conf" message on startup if conf file exists. (Alexander Leishman)
bc8aa2ba7 don't translate command line options (Michael Polzer)
fac3e22b1 qa: Read reject reasons from debug log, not p2p messages (MarcoFalke)
b2f49bd73 Integration of property based testing into Bitcoin Core (Chris Stewart)
65a449f8e Explain when reindex-chainstate can be used instead of reindex (Sjors Provoost)
e351a16a2 Remove reference to deprecated RPC call in build instructions (Michael Goldstein)
a6f16f1b1 Docs: Add disable-wallet section to OSX build instructions (Michael Goldstein)
f7e9e7046 [rpc] Remove deprecated sigrawtransaction rpc method. (John Newbery)
90c834089 [RPC] Remove warning about wallet addresses in createmultisig() (John Newbery)
df905e390 [rpc] Remove deprecated validateaddress usage. (John Newbery)
fab526751 doxygen: Remove misleading checkpoints comment in CMainParams (MarcoFalke)
2b5d6f8df Replace duplcate reference with reference to reference doc (Pieter Wuille)
89709db7a Adjust TODO link (Pieter Wuille)
9254ffcf2 Add descriptor reference documentation (Pieter Wuille)
ed2332aef test: Add test for config file parsing errors (MarcoFalke)
a66c0f78a util: Report parse errors in configuration file (Wladimir J. van der Laan)
f8a81f73a lint: Add spell check linter (codespell) (practicalswift)
ada356208 Fix typos reported by codespell (practicalswift)
e9a78e9b3 doc: Change documentation for =0 for non-boolean options (Wladimir J. van der Laan)
341f7c7b0 macOS fix: Check for correct version of flake8 to avoid spurious warnings. The brew installed flake8 version is Python 2 based and does not work. (practicalswift)
908a559f3 macOS fix: Add excludes for checks added in the newer shellcheck version installed by brew (practicalswift)
ec4d57bbb macOS fix: Work around empty (sub)expression error when using BSD grep (practicalswift)
b57d7d92f macOS fix: Avoid mapfile due to ancient version of bash shipped with macOS (practicalswift)
e4a79b4b3 appveyor: Use clcache to speed up build (Chun Kuan Lee)
f34c8c466 Make objects in range declarations immutable by default. Avoid unnecessary copying of objects in range declarations. (practicalswift)
ee3a494f3 gui: Favor macOS show / hide action in dock menu (João Barbosa)
e8c4a1e36 Add new regtest ports in doc following #10825 ports reattributions (Antoine Riard)
8ecaee13f Increase signal to noise in appveyor build output by reducing the MSVC warning count from 12 to 4 (12 is assuming the changes in #14086 are also implemented). (practicalswift)
5d62dcf9c lint: Make sure we read the command line inputs using utf-8 decoding in python (Chun Kuan Lee)
c7f7fa467 Trivial: update clang thread-safety docs url (Ben Woosley)
68bfc0bce doc: correct GetDifficulty doc after #13288 (fanquake)
83d53058a Switch nPrevNodeCount to vNodesSize. (Patrick Strateman)
fb97437ef added note that control port must be enabled and how to do that in torrc config file (Jordan Baczuk)
8dfc2f30d Test rpc_help.py failed: Check whether ZMQ is enabled or not. (Kvaciral)
190bf62be scripted-diff: Small locking rename (Russell Yanofsky)
9c4dc597d Use LOCK macros for non-recursive locks (Russell Yanofsky)
1382913e6 Make LOCK, LOCK2, TRY_LOCK work with CWaitableCriticalSection (Russell Yanofsky)
ba1f095aa MOVEONLY Move AnnotatedMixin declaration (Russell Yanofsky)
41b88e933 Add unit test for DEBUG_LOCKORDER code (Russell Yanofsky)
62b6f0f21 Add EXCLUSIVE_LOCKS_REQUIRED to CWallet::ListCoins (Russell Yanofsky)
545e85ecc Add AssertLockHeld assertions in CWallet::ListCoins (Russell Yanofsky)
ca1a09312 Add regression test: Don't assert(...) with side effects (practicalswift)
4c3c9c386 Don't assert(...) with side effects (practicalswift)
b602c9b3a tests: Add missing locking annotations and locks (practicalswift)
f05599557 blockfilter: Omit empty scripts from filter contents. (Jim Posen)
75ea00f39 Remove unused fsbridge::freopen (practicalswift)
cceedbc4b Don't close old debug log file handle prematurely when trying to re-open (on SIGHUP) (practicalswift)
fa782a308 qa: Use named args in some tests (MarcoFalke)
b4d330967 scripted-diff: Use named arguments in feature_block (MarcoFalke)
749ba35e7 scripted-diff: Pass node into p2p_segwit acceptance tests (MarcoFalke)
8550f1fb2 Add README.md to linux release tarballs (Hennadii Stepanov)
c516c3a77 [contrib] Support ARM and RISC-V symbol check (Chun Kuan Lee)
c9c32e6b8 [wallet] Kill accounts (John Newbery)
1e29379d6 Fix potential deadlock (practicalswift)
d58dc9f94 Add lock annotations (cs_args) (practicalswift)
db5e9d3c8 Add missing locks (cs_args) (practicalswift)
0e534d4dc Fix incorrect Doxygen comments (practicalswift)
fa309dc30 validation: Log FormatStateMessage on ConnectBlock error in ConnectTip (MarcoFalke)
fa587773e scripted-diff: Remove unused first argument to addUnchecked (MarcoFalke)
fe5c49766 tx pool: Use the entry's hash instead of the one passed to addUnchecked (MarcoFalke)
ddd395f96 Mark CTxMemPoolEntry members that should not be modified const (MarcoFalke)
6af6d9b23 test: Add tests for RPC help (João Barbosa)
1d9aa008d Explicitly initialize prevector _union (Ben Woosley)
b193d5a44 Removes the Boost case_conv.hpp dependency. (251)
7a208d9fa Implements custom tolower and toupper functions. (251)
e2ba043b8 Implements ParseNetwork unit test. (251)
1661a472b add unicode compatible file_lock for Windows (Chun Kuan Lee)
1cc58978b tests: Fix accidental trunction from int to bool (practicalswift)
61fe653bd fix walletcreatefundedpsbt deriv paths, add test (Gregory Sanders)
fae040010 qa: Add some actual witness in rpc_rawtransaction (MarcoFalke)
917353c8b Make SignPSBTInput operate on a private SignatureData object (Pieter Wuille)
cad5dd236 Pass HD path data through SignatureData (Pieter Wuille)
03a99586a Implement key origin lookup in CWallet (Pieter Wuille)
3b01efa0d [MOVEONLY] Move ParseHDKeypath to utilstrencodings (Pieter Wuille)
81e1dd5ce Generalize PublicOnlySigningProvider into HidingSigningProvider (Pieter Wuille)
84f1f1bfd Make SigningProvider expose key origin information (Pieter Wuille)
611ab307f Introduce KeyOriginInfo for fingerprint + path (Pieter Wuille)
16e288acd test padding non micro timestamps (John Newbery)
995dd89d8 [Tests] Make combine_logs.py handle multi-line logs (John Newbery)
4c530e010 travis: add  CXXFLAGS=-Wnopsabi at ARM job (Chun Kuan Lee)
dd777f3e1 Remove unused variable (practicalswift)
cdf408945 Remove redundant assignments (dead stores) (practicalswift)
1ac3c983b Mark single-argument constructors "explicit" (practicalswift)
bb08423d5 [doc] Add release notes for 'account' API removal (John Newbery)
1f4b865e5 [wallet] Re-sort wallet RPC commands (John Newbery)
f0dc850bf [wallet] Remove wallet account RPCs (John Newbery)
c410f4157 [tests] Remove wallet accounts test (John Newbery)
c55c5f2b1 fix missing differentiation between UNIT and FUNCTIONAL tests in travis build (Julian Fleischer)
414326952 use export LC_ALL=C.UTF-8 (Julian Fleischer)
728c82d02 make script exit if a command fails (Julian Fleischer)
506890b24 move remaining travis build steps into individual files (Julian Fleischer)
272306ea5 number .travis/ script according to build lifecycle and add README to explain (Julian Fleischer)
519e2739c move lint stage up to resemble travis build ui (Julian Fleischer)
86d34f0e6 abort script in END_FOLD on non-zero exit code (Julian Fleischer)
4f2f88c7b move script sections info individual files and comply with shellcheck (Julian Fleischer)
a9910d82c contrib: Adjust output to current test format (Akio Nakamura)
5778bf95d Report minfeefilter value in getpeerinfo rpc (Anthony Towns)
384273260 test: Add testing of value_ret for SelectCoinsBnB (Ben Woosley)
497e90c02 Remove default argument to prevector constructor to remove ambiguity (Ben Woosley)
f1640d093 Make IS_TRIVIALLY_CONSTRUCTIBLE consistent on GCC < 5 (Ben Woosley)
fad8afa38 travis: Run unit tests --with-sanitizers=undefined (MarcoFalke)
0d00fd590 depends: allow CC/CXX to be overridden during configure (Cory Fields)
7d0a8ad31 Docs: Fix help message typo optiona -> optional (Ben Woosley)
faf4a9b67 qa: Stop txindex thread before calling destructor (MarcoFalke)
0b16f679d auto generate MSVC project files (Chun Kuan Lee)
254c85b68 bench: Benchmark GCS filter creation and matching. (Jim Posen)
f33b717a8 blockfilter: Optimization on compilers with int128 support. (Jim Posen)
97b64d67d blockfilter: Unit test against BIP 158 test vectors. (Jim Posen)
a4afb9cad blockfilter: Additional helper methods to compute hash and header. (Jim Posen)
cd09c7925 blockfilter: Serialization methods on BlockFilter. (Jim Posen)
c1855f605 blockfilter: Construction of basic block filters. (Jim Posen)
53e7874e0 blockfilter: Simple test for GCSFilter construction and Match. (Jim Posen)
558c536e3 blockfilter: Implement GCSFilter Match methods. (Jim Posen)
cf70b5500 blockfilter: Implement GCSFilter constructors. (Jim Posen)
c454f0ac6 blockfilter: Declare GCSFilter class for BIP 158 impl. (Jim Posen)
9b622dc72 streams: Unit tests for BitStreamReader and BitStreamWriter. (Jim Posen)
fe943f99b streams: Implement BitStreamReader/Writer classes. (Jim Posen)
87f2d9ee4 streams: Unit test for VectorReader class. (Jim Posen)
947133dec streams: Create VectorReader stream interface for vectors. (Jim Posen)
737670c03 Use assert when running from multithreaded code as BOOST_CHECK_* are not thread safe (Jesse Cohen)
9e2de6b9d Move cs_main locking annotations from .cpp to .h (practicalswift)
9e0a51411 Add compile time checking for all cs_main runtime locking assertions (practicalswift)
870bd4c73 Update functional RBF test to check replaceable flag (dexX7)
820d31f95 Add "bip125-replaceable" flag to mempool RPCs (dexX7)
03a2d6801 Tests: add usage note to check-rpc-mappings.py (Mason Simon)
ddddce0e4 util: Replace boost::signals2 with std::function (MarcoFalke)
fa6c3dea4 p2p: Clarify control flow in ProcessMessage() (MarcoFalke)
984d72ec6 Return the script type from Solver (Ben Woosley)
23f434378 Add CMerkleTx::IsImmatureCoinBase method (Ben Woosley)
fa3e9f762 qa: Add TestNode::assert_debug_log (MarcoFalke)
00f58f8c4 rpc: Avoid locking cs_main in some wallet RPC (João Barbosa)
fa74d3d72 qa: Remove unused deserialization code in msg_version (MarcoFalke)
fa5099ceb p2p: Remove dead code for nVersion=10300 (MarcoFalke)
856334171 Bugfix: NSIS: Exclude Makefile* from docs (Luke Dashjr)
46f834537 contrib: Support github pull request gitian-build (Chun Kuan Lee)
317f2cb3f test: Check RPC settxfee errors (João Barbosa)
48618daf2 Add checks for settxfee reasonableness (Anthony Towns)
321159e53 don't report minversion wallet entry as unknown (Gregory Sanders)
19efc01ae Add PSBT documentation (Pieter Wuille)
18c49eb88 http: Add const modifier to HTTPRequest methods (João Barbosa)
3567b247f test: Add lint to prevent SIGNAL/SLOT connect style (João Barbosa)
f78558f1e qt: Use new Qt5 connect syntax (João Barbosa)

Pull request description:

Tree-SHA512: 6da8dacc63f7ca6f28ed6aa0143cc65383d9ac17fcad26c17b683397701ba170b3987fa0f246ef8408766975d7b80b62c5ff8a20cfcb78ce54d65b8a620e9e91
This commit is contained in:
Steven Roose 2019-02-12 15:02:37 +00:00
commit e51ed82876
No known key found for this signature in database
GPG key ID: 7FC91380BB4CE800
445 changed files with 6224 additions and 5131 deletions

View file

@ -5,19 +5,19 @@ language: minimal
cache:
ccache: true
directories:
- depends/built
- depends/sdk-sources
- $HOME/.ccache
- depends/built
- depends/sdk-sources
- $HOME/.ccache
stages:
- lint
- test
env:
global:
- MAKEJOBS=-j3
- RUN_TESTS=false
- RUN_UNIT_TESTS=true
- RUN_FUNCTIONAL_TESTS=true
- RUN_BENCH=false # Set to true for any one job that has debug enabled, to quickly check bench is not crashing or hitting assertions
- DOCKER_NAME_TAG=ubuntu:18.04
- LC_ALL=C.UTF-8
- BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID
- CCACHE_SIZE=100M
- CCACHE_TEMPDIR=/tmp/.ccache-temp
@ -28,55 +28,43 @@ env:
- WINEDEBUG=fixme-all
- DOCKER_PACKAGES="build-essential libtool autotools-dev automake pkg-config bsdmainutils curl git ca-certificates ccache"
before_install:
- export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
- BEGIN_FOLD () { echo ""; CURRENT_FOLD_NAME=$1; echo "travis_fold:start:${CURRENT_FOLD_NAME}"; }
- END_FOLD () { RET=$?; echo "travis_fold:end:${CURRENT_FOLD_NAME}"; return $RET; }
- set -o errexit; source .travis/test_03_before_install.sh
install:
- travis_retry docker pull $DOCKER_NAME_TAG
- env | grep -E '^(CCACHE_|WINEDEBUG|LC_ALL|BOOST_TEST_RANDOM|CONFIG_SHELL)' | tee /tmp/env
- if [[ $HOST = *-mingw32 ]]; then DOCKER_ADMIN="--cap-add SYS_ADMIN"; fi
- DOCKER_ID=$(docker run $DOCKER_ADMIN -idt --mount type=bind,src=$TRAVIS_BUILD_DIR,dst=$TRAVIS_BUILD_DIR --mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR -w $TRAVIS_BUILD_DIR --env-file /tmp/env $DOCKER_NAME_TAG)
- DOCKER_EXEC () { docker exec $DOCKER_ID bash -c "cd $PWD && $*"; }
- if [ -n "$DPKG_ADD_ARCH" ]; then DOCKER_EXEC dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi
- travis_retry DOCKER_EXEC apt-get update
- travis_retry DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES $DOCKER_PACKAGES
- set -o errexit; source .travis/test_04_install.sh
before_script:
- DOCKER_EXEC echo \> \$HOME/.bitcoin # Make sure default datadir does not exist and is never read by creating a dummy file
- mkdir -p depends/SDKs depends/sdk-sources
- if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- if [[ $HOST = *-mingw32 ]]; then DOCKER_EXEC update-alternatives --set $HOST-g++ \$\(which $HOST-g++-posix\); fi
- if [ -z "$NO_DEPENDS" ]; then DOCKER_EXEC CONFIG_SHELL= make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS; fi
- set -o errexit; source .travis/test_05_before_script.sh
script:
- export TRAVIS_COMMIT_LOG=`git log --format=fuller -1`
- OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
- BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib"
- if [ -z "$NO_DEPENDS" ]; then DOCKER_EXEC ccache --max-size=$CCACHE_SIZE; fi
- BEGIN_FOLD autogen; test -n "$CONFIG_SHELL" && DOCKER_EXEC "$CONFIG_SHELL" -c "./autogen.sh" || DOCKER_EXEC ./autogen.sh; END_FOLD
- mkdir build && cd build
- BEGIN_FOLD configure; DOCKER_EXEC ../configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false); END_FOLD
- BEGIN_FOLD distdir; DOCKER_EXEC make distdir VERSION=$HOST; END_FOLD
- cd bitcoin-$HOST
- BEGIN_FOLD configure; DOCKER_EXEC ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false); END_FOLD
- BEGIN_FOLD build; DOCKER_EXEC make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && DOCKER_EXEC make $GOAL V=1 ; false ); END_FOLD
- if [ "$RUN_TESTS" = "true" ]; then BEGIN_FOLD unit-tests; DOCKER_EXEC LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib make $MAKEJOBS check VERBOSE=1; END_FOLD; fi
- if [ "$RUN_BENCH" = "true" ]; then BEGIN_FOLD bench; DOCKER_EXEC LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib $OUTDIR/bin/bench_bitcoin -scaling=0.001 ; END_FOLD; fi
- if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then extended="--extended --exclude feature_pruning,feature_dbcrash"; fi
- if [ "$RUN_TESTS" = "true" ]; then BEGIN_FOLD functional-tests; DOCKER_EXEC test/functional/test_runner.py --combinedlogslen=4000 --coverage --quiet --failfast ${extended}; END_FOLD; fi
- if [ "$RUN_BITCOIN_TESTS" = "true" ]; then BEGIN_FOLD bitcoin-functional-tests; DOCKER_EXEC test/bitcoin_functional/functional/test_runner.py --combinedlogslen=4000 --coverage --quiet --failfast ${extended}; END_FOLD; fi
- set -o errexit; source .travis/test_06_script.sh
after_script:
- echo $TRAVIS_COMMIT_RANGE
- echo $TRAVIS_COMMIT_LOG
- echo $TRAVIS_COMMIT_RANGE
- echo $TRAVIS_COMMIT_LOG
jobs:
include:
# lint stage
- stage: lint
env:
sudo: false
cache: false
language: python
python: '3.6'
install:
- set -o errexit; source .travis/lint_04_install.sh
before_script:
- set -o errexit; source .travis/lint_05_before_script.sh
script:
- set -o errexit; source .travis/lint_06_script.sh
# ARM
- stage: test
env: >-
HOST=arm-linux-gnueabihf
PACKAGES="g++-arm-linux-gnueabihf"
DEP_OPTS="NO_QT=1"
RUN_UNIT_TESTS=false
RUN_FUNCTIONAL_TESTS=false
GOAL="install"
BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
# -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1"
# This could be removed once the ABI change warning does not show up by default
BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CXXFLAGS=-Wno-psabi"
# Win32
- stage: test
env: >-
@ -84,7 +72,6 @@ jobs:
DPKG_ADD_ARCH="i386"
DEP_OPTS="NO_QT=1"
PACKAGES="python3 nsis g++-mingw-w64-i686 wine-binfmt wine32"
RUN_TESTS=true
GOAL="install"
BITCOIN_CONFIG="--enable-reduce-exports"
# Win64
@ -93,7 +80,6 @@ jobs:
HOST=x86_64-w64-mingw32
DEP_OPTS="NO_QT=1"
PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64"
RUN_TESTS=true
GOAL="install"
BITCOIN_CONFIG="--enable-reduce-exports"
# 32-bit + dash
@ -102,7 +88,6 @@ jobs:
HOST=i686-pc-linux-gnu
PACKAGES="g++-multilib python3-zmq"
DEP_OPTS="NO_QT=1"
RUN_TESTS=true
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
CONFIG_SHELL="/bin/dash"
@ -112,19 +97,45 @@ jobs:
HOST=x86_64-unknown-linux-gnu
PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools protobuf-compiler libdbus-1-dev libharfbuzz-dev libprotobuf-dev"
DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1"
RUN_TESTS=true
RUN_BENCH=true
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --enable-debug CXXFLAGS=\"-g0 -O2\""
# x86_64 Linux (Qt5 & system libs)
# x86_64 Linux (no depends, only system libs)
- stage: test
env: >-
HOST=x86_64-unknown-linux-gnu
PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev"
NO_DEPENDS=1
RUN_TESTS=true
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --enable-glibc-back-compat --enable-reduce-exports --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER"
# x86_64 Linux (sanitizers)
- stage: test
env: >-
HOST=x86_64-unknown-linux-gnu
PACKAGES="clang python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev"
NO_DEPENDS=1
RUN_BENCH=true
RUN_FUNCTIONAL_TESTS=false # Disabled for now, can be combined with the other x86_64 linux NO_DEPENDS job when functional tests pass the sanitizers
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --enable-glibc-back-compat --enable-reduce-exports --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER --with-sanitizers=undefined CC=clang CXX=clang++"
# x86_64 Linux, No wallet
- stage: test
env: >-
HOST=x86_64-unknown-linux-gnu
PACKAGES="python3"
DEP_OPTS="NO_WALLET=1"
GOAL="install"
BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
# Cross-Mac
- stage: test
env: >-
HOST=x86_64-apple-darwin14
PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git"
OSX_SDK=10.11
RUN_UNIT_TESTS=false
RUN_FUNCTIONAL_TESTS=false
GOAL="all deploy"
BITCOIN_CONFIG="--enable-gui --enable-reduce-exports --enable-werror"
# x86_64 Linux w/ Bitcoin functional tests (Qt5 & system libs)
- stage: test
env: >-
@ -134,43 +145,3 @@ jobs:
RUN_BITCOIN_TESTS=true
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --enable-glibc-back-compat --enable-reduce-exports --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER"
# x86_64 Linux, No wallet
- stage: test
env: >-
HOST=x86_64-unknown-linux-gnu
PACKAGES="python3"
DEP_OPTS="NO_WALLET=1"
RUN_TESTS=true
GOAL="install"
BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
# Cross-Mac
- stage: test
env: >-
HOST=x86_64-apple-darwin14
PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git"
OSX_SDK=10.11
GOAL="all deploy"
BITCOIN_CONFIG="--enable-gui --enable-reduce-exports --enable-werror"
- stage: lint
env:
sudo: false
cache: false
language: python
python: '3.6'
install:
- travis_retry pip install flake8==3.5.0
before_script:
- git fetch --unshallow
script:
- if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then test/lint/commit-script-check.sh $TRAVIS_COMMIT_RANGE; fi
- test/lint/git-subtree-check.sh src/crypto/ctaes
- test/lint/git-subtree-check.sh src/secp256k1
- test/lint/git-subtree-check.sh src/univalue
- test/lint/git-subtree-check.sh src/leveldb
- test/lint/check-doc.py
- test/lint/check-rpc-mappings.py .
- test/lint/lint-all.sh
- if [ "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_EVENT_TYPE" = "cron" ]; then
while read LINE; do travis_retry gpg --keyserver hkp://subset.pool.sks-keyservers.net --recv-keys $LINE; done < contrib/verify-commits/trusted-keys &&
travis_wait 50 contrib/verify-commits/verify-commits.py;
fi

8
.travis/README.md Normal file
View file

@ -0,0 +1,8 @@
## travis build scripts
The `.travis` directory contains scripts for each build step in each build stage.
Currently the travis build defines two stages `lint` and `test`. Each stage has
it's own [lifecycle](https://docs.travis-ci.com/user/customizing-the-build/#the-build-lifecycle).
Every script in here is named and numbered according to which stage and lifecycle
step it belongs to.

10
.travis/lint_04_install.sh Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env bash
#
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C
travis_retry pip install codespell==1.13.0
travis_retry pip install flake8==3.5.0

View file

@ -0,0 +1,9 @@
#!/usr/bin/env bash
#
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C
git fetch --unshallow

24
.travis/lint_06_script.sh Executable file
View file

@ -0,0 +1,24 @@
#!/usr/bin/env bash
#
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then
test/lint/commit-script-check.sh $TRAVIS_COMMIT_RANGE
fi
test/lint/git-subtree-check.sh src/crypto/ctaes
test/lint/git-subtree-check.sh src/secp256k1
test/lint/git-subtree-check.sh src/univalue
test/lint/git-subtree-check.sh src/leveldb
test/lint/check-doc.py
test/lint/check-rpc-mappings.py .
test/lint/lint-all.sh
if [ "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_EVENT_TYPE" = "cron" ]; then
while read -r LINE; do travis_retry gpg --keyserver hkp://subset.pool.sks-keyservers.net --recv-keys $LINE; done < contrib/verify-commits/trusted-keys &&
travis_wait 50 contrib/verify-commits/verify-commits.py;
fi

View file

@ -0,0 +1,25 @@
#!/usr/bin/env bash
#
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C.UTF-8
PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
export PATH
BEGIN_FOLD () {
echo ""
CURRENT_FOLD_NAME=$1
echo "travis_fold:start:${CURRENT_FOLD_NAME}"
}
END_FOLD () {
RET=$?
echo "travis_fold:end:${CURRENT_FOLD_NAME}"
if [ $RET != 0 ]; then
echo "${CURRENT_FOLD_NAME} failed with status code ${RET}"
fi
}

26
.travis/test_04_install.sh Executable file
View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
#
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C.UTF-8
travis_retry docker pull "$DOCKER_NAME_TAG"
env | grep -E '^(CCACHE_|WINEDEBUG|LC_ALL|BOOST_TEST_RANDOM|CONFIG_SHELL)' | tee /tmp/env
if [[ $HOST = *-mingw32 ]]; then
DOCKER_ADMIN="--cap-add SYS_ADMIN"
fi
DOCKER_ID=$(docker run $DOCKER_ADMIN -idt --mount type=bind,src=$TRAVIS_BUILD_DIR,dst=$TRAVIS_BUILD_DIR --mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR -w $TRAVIS_BUILD_DIR --env-file /tmp/env $DOCKER_NAME_TAG)
DOCKER_EXEC () {
docker exec $DOCKER_ID bash -c "cd $PWD && $*"
}
if [ -n "$DPKG_ADD_ARCH" ]; then
DOCKER_EXEC dpkg --add-architecture "$DPKG_ADD_ARCH"
fi
travis_retry DOCKER_EXEC apt-get update
travis_retry DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES $DOCKER_PACKAGES

View file

@ -0,0 +1,25 @@
#!/usr/bin/env bash
#
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C.UTF-8
DOCKER_EXEC echo \> \$HOME/.bitcoin # Make sure default datadir does not exist and is never read by creating a dummy file
mkdir -p depends/SDKs depends/sdk-sources
if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then
curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz
fi
if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then
tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz
fi
if [[ $HOST = *-mingw32 ]]; then
DOCKER_EXEC update-alternatives --set $HOST-g++ \$\(which $HOST-g++-posix\)
fi
if [ -z "$NO_DEPENDS" ]; then
DOCKER_EXEC CONFIG_SHELL= make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS
fi

73
.travis/test_06_script.sh Executable file
View file

@ -0,0 +1,73 @@
#!/usr/bin/env bash
#
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C.UTF-8
TRAVIS_COMMIT_LOG=$(git log --format=fuller -1)
export TRAVIS_COMMIT_LOG
OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib"
if [ -z "$NO_DEPENDS" ]; then
DOCKER_EXEC ccache --max-size=$CCACHE_SIZE
fi
BEGIN_FOLD autogen
if [ -n "$CONFIG_SHELL" ]; then
DOCKER_EXEC "$CONFIG_SHELL" -c "./autogen.sh"
else
DOCKER_EXEC ./autogen.sh
fi
END_FOLD
mkdir build
cd build || (echo "could not enter build directory"; exit 1)
BEGIN_FOLD configure
DOCKER_EXEC ../configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
END_FOLD
BEGIN_FOLD distdir
DOCKER_EXEC make distdir VERSION=$HOST
END_FOLD
cd "bitcoin-$HOST" || (echo "could not enter distdir bitcoin-$HOST"; exit 1)
BEGIN_FOLD configure
DOCKER_EXEC ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
END_FOLD
BEGIN_FOLD build
DOCKER_EXEC make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && DOCKER_EXEC make $GOAL V=1 ; false )
END_FOLD
if [ "$RUN_UNIT_TESTS" = "true" ]; then
BEGIN_FOLD unit-tests
DOCKER_EXEC LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib make $MAKEJOBS check VERBOSE=1
END_FOLD
fi
if [ "$RUN_BENCH" = "true" ]; then
BEGIN_FOLD bench
DOCKER_EXEC LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib $OUTDIR/bin/bench_bitcoin -scaling=0.001
END_FOLD
fi
if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then
extended="--extended --exclude feature_pruning"
fi
if [ "$RUN_FUNCTIONAL_TESTS" = "true" ]; then
BEGIN_FOLD functional-tests
DOCKER_EXEC test/functional/test_runner.py --combinedlogslen=4000 --coverage --quiet --failfast ${extended}
END_FOLD
fi
if [ "$RUN_BITCOIN_TESTS" = "true" ]; then
BEGIN_FOLD bitcoin-functional-tests
DOCKER_EXEC test/bitcoin_functional/functional/test_runner.py --combinedlogslen=4000 --coverage --quiet --failfast ${extended}
END_FOLD
fi

View file

@ -5,33 +5,41 @@ configuration: Release
platform: x64
environment:
APPVEYOR_SAVE_CACHE_ON_ERROR: true
cache: C:\tools\vcpkg\installed\
CLCACHE_SERVER: 1
PACKAGES: boost-filesystem boost-signals2 boost-interprocess boost-test libevent openssl zeromq berkeleydb secp256k1 leveldb
cache:
- C:\tools\vcpkg\installed
- C:\Users\appveyor\clcache
- build_msvc\cache
init:
- cmd: set PATH=C:\Python36-x64;C:\Python36-x64\Scripts;%PATH%
install:
- cmd: pip install git+https://github.com/frerich/clcache.git
- ps: $packages = $env:PACKAGES -Split ' '
- ps: for ($i=0; $i -lt $packages.length; $i++) {
$env:ALL_PACKAGES += $packages[$i] + ":" + $env:PLATFORM + "-windows-static "
}
- cmd: git -C C:\Tools\vcpkg pull # This is a temporary fix, can be removed after appveyor update its image to include Microsoft/vcpkg#4046
- cmd: vcpkg install %ALL_PACKAGES%
- cmd: vcpkg upgrade --no-dry-run
- cmd: del /s /q C:\Tools\vcpkg\installed\%PLATFORM%-windows-static\debug # Remove unused debug library
before_build:
- ps: >-
$packages = @(
"boost-filesystem",
"boost-signals2",
"boost-interprocess",
"boost-test",
"libevent",
"openssl",
"zeromq",
"berkeleydb",
"secp256k1",
"leveldb"
)
for ($i=0; $i -lt $packages.length; $i++) {
$all_packages += $packages[$i] + ":" + $env:PLATFORM + "-windows-static "
}
git -C C:\Tools\vcpkg pull # This is a temporary fix, can be removed after appveyor update its image to include Microsoft/vcpkg#4046
Invoke-Expression -Command "vcpkg install $all_packages"
build:
project: build_msvc\bitcoin.sln
parallel: true
verbosity: minimal
- cmd: if not exist build_msvc\cache\ (del build_msvc\cache & mkdir build_msvc\cache)
- cmd: if not exist build_msvc\%PLATFORM%\%CONFIGURATION%\ (mkdir build_msvc\%PLATFORM%\%CONFIGURATION%)
- cmd: if exist build_msvc\cache\*.iobj (move build_msvc\cache\* build_msvc\%PLATFORM%\%CONFIGURATION%\)
- cmd: clcache -M 2147483648
- cmd: python build_msvc\msvc-autogen.py
- ps: $files = (Get-ChildItem -Recurse | where {$_.extension -eq ".vcxproj"}).FullName
- ps: for ($i = 0; $i -lt $files.length; $i++) {
(Get-Content $files[$i]).Replace("</RuntimeLibrary>", "</RuntimeLibrary><DebugInformationFormat>None</DebugInformationFormat>").Replace("NDEBUG;", "") | Set-Content $files[$i]
}
- ps: Start-Process clcache-server
build_script:
- cmd: msbuild /p:TrackFileAccess=false /p:CLToolExe=clcache.exe build_msvc\bitcoin.sln /m /v:q /nowarn:C4244;C4267;C4715 /nologo
after_build:
- cmd: move build_msvc\%PLATFORM%\%CONFIGURATION%\*.iobj build_msvc\cache\
- cmd: move build_msvc\%PLATFORM%\%CONFIGURATION%\*.ipdb build_msvc\cache\
- cmd: del C:\Users\appveyor\clcache\stats.txt
test_script:
- cmd: build_msvc\%PLATFORM%\Release\test_bitcoin.exe
- cmd: build_msvc\%PLATFORM%\%CONFIGURATION%\test_bitcoin.exe
deploy: off

View file

@ -8,3 +8,4 @@ packages/*
*/Release
*/x64
*.vcxproj.user
*.vcxproj

View file

@ -47,4 +47,10 @@ The instructions below use vcpkg to install the dependencies.
leveldb:x64-windows-static
```
- Use Python to generate *.vcxproj from Makefile
```
PS >python msvc-autogen.py
```
- Build in Visual Studio.

View file

@ -20,7 +20,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\rpc\client.cpp" />
@SOURCE_FILES@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -165,43 +165,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\src\base58.h" />
<ClInclude Include="..\..\src\bech32.h" />
<ClInclude Include="..\..\src\chainparams.h" />
<ClInclude Include="..\..\src\coins.h" />
<ClInclude Include="..\..\src\compressor.h" />
<ClInclude Include="..\..\src\key.h" />
<ClInclude Include="..\..\src\keystore.h" />
<ClInclude Include="..\..\src\netaddress.h" />
<ClInclude Include="..\..\src\netbase.h" />
<ClInclude Include="..\..\src\policy\feerate.h" />
<ClInclude Include="..\..\src\protocol.h" />
<ClInclude Include="..\..\src\scheduler.h" />
<ClInclude Include="..\..\src\script\sign.h" />
<ClInclude Include="..\..\src\script\standard.h" />
<ClInclude Include="..\..\src\warnings.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\base58.cpp" />
<ClCompile Include="..\..\src\bech32.cpp" />
<ClCompile Include="..\..\src\chainparams.cpp" />
<ClCompile Include="..\..\src\coins.cpp" />
<ClCompile Include="..\..\src\compressor.cpp" />
<ClCompile Include="..\..\src\core_read.cpp" />
<ClCompile Include="..\..\src\core_write.cpp" />
<ClCompile Include="..\..\src\key.cpp" />
<ClCompile Include="..\..\src\key_io.cpp" />
<ClCompile Include="..\..\src\keystore.cpp" />
<ClCompile Include="..\..\src\netaddress.cpp" />
<ClCompile Include="..\..\src\netbase.cpp" />
<ClCompile Include="..\..\src\policy\feerate.cpp" />
<ClCompile Include="..\..\src\protocol.cpp" />
<ClCompile Include="..\..\src\scheduler.cpp" />
<ClCompile Include="..\..\src\script\descriptor.cpp" />
<ClCompile Include="..\..\src\script\sign.cpp" />
<ClCompile Include="..\..\src\script\ismine.cpp" />
<ClCompile Include="..\..\src\script\standard.cpp" />
<ClCompile Include="..\..\src\warnings.cpp" />
@SOURCE_FILES@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -151,25 +151,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\src\crypto\aes.h" />
<ClInclude Include="..\..\src\crypto\chacha20.h" />
<ClInclude Include="..\..\src\crypto\common.h" />
<ClInclude Include="..\..\src\crypto\hmac_sha256.h" />
<ClInclude Include="..\..\src\crypto\hmac_sha512.h" />
<ClInclude Include="..\..\src\crypto\ripemd160.h" />
<ClInclude Include="..\..\src\crypto\sha1.h" />
<ClInclude Include="..\..\src\crypto\sha256.h" />
<ClInclude Include="..\..\src\crypto\sha512.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\crypto\aes.cpp" />
<ClCompile Include="..\..\src\crypto\chacha20.cpp" />
<ClCompile Include="..\..\src\crypto\hmac_sha256.cpp" />
<ClCompile Include="..\..\src\crypto\hmac_sha512.cpp" />
<ClCompile Include="..\..\src\crypto\ripemd160.cpp" />
<ClCompile Include="..\..\src\crypto\sha1.cpp" />
<ClCompile Include="..\..\src\crypto\sha256.cpp" />
<ClCompile Include="..\..\src\crypto\sha512.cpp" />
@SOURCE_FILES@
</ItemGroup>
<Import Label="configTarget" Project="..\common.vcxproj" />
</Project>

View file

@ -154,53 +154,13 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\addrdb.cpp" />
<ClCompile Include="..\..\src\addrman.cpp" />
<ClCompile Include="..\..\src\blockencodings.cpp" />
<ClCompile Include="..\..\src\bloom.cpp" />
<ClCompile Include="..\..\src\chain.cpp" />
<ClCompile Include="..\..\src\checkpoints.cpp" />
<ClCompile Include="..\..\src\consensus\tx_verify.cpp" />
<ClCompile Include="..\..\src\dbwrapper.cpp" />
<ClCompile Include="..\..\src\httprpc.cpp" />
<ClCompile Include="..\..\src\httpserver.cpp" />
<ClCompile Include="..\..\src\index\base.cpp" />
<ClCompile Include="..\..\src\init.cpp" />
<ClCompile Include="..\..\src\merkleblock.cpp" />
<ClCompile Include="..\..\src\miner.cpp" />
<ClCompile Include="..\..\src\net.cpp" />
<ClCompile Include="..\..\src\net_processing.cpp" />
<ClCompile Include="..\..\src\noui.cpp" />
<ClCompile Include="..\..\src\outputtype.cpp" />
<ClCompile Include="..\..\src\policy\fees.cpp" />
<ClCompile Include="..\..\src\policy\policy.cpp" />
<ClCompile Include="..\..\src\policy\rbf.cpp" />
<ClCompile Include="..\..\src\pow.cpp" />
<ClCompile Include="..\..\src\rest.cpp" />
<ClCompile Include="..\..\src\shutdown.cpp" />
<ClCompile Include="..\..\src\rpc\blockchain.cpp" />
<ClCompile Include="..\..\src\rpc\mining.cpp" />
<ClCompile Include="..\..\src\rpc\misc.cpp" />
<ClCompile Include="..\..\src\rpc\net.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\netrpc.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\netrpc.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)\netrpc.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)\netrpc.obj</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\rpc\rawtransaction.cpp" />
<ClCompile Include="..\..\src\rpc\server.cpp" />
<ClCompile Include="..\..\src\rpc\util.cpp" />
<ClCompile Include="..\..\src\script\ismine.cpp" />
<ClCompile Include="..\..\src\script\sigcache.cpp" />
<ClCompile Include="..\..\src\timedata.cpp" />
<ClCompile Include="..\..\src\torcontrol.cpp" />
<ClCompile Include="..\..\src\txdb.cpp" />
<ClCompile Include="..\..\src\txmempool.cpp" />
<ClCompile Include="..\..\src\ui_interface.cpp" />
<ClCompile Include="..\..\src\validation.cpp" />
<ClCompile Include="..\..\src\validationinterface.cpp" />
<ClCompile Include="..\..\src\versionbits.cpp" />
<ClCompile Include="..\..\src\index\txindex.cpp" />
@SOURCE_FILES@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -174,23 +174,7 @@
</ProjectReference>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\chainparamsbase.cpp" />
<ClCompile Include="..\..\src\clientversion.cpp" />
<ClCompile Include="..\..\src\compat\glibcxx_sanity.cpp" />
<ClCompile Include="..\..\src\compat\glibc_sanity.cpp" />
<ClCompile Include="..\..\src\compat\strnlen.cpp" />
<ClCompile Include="..\..\src\fs.cpp" />
<ClCompile Include="..\..\src\logging.cpp" />
<ClCompile Include="..\..\src\random.cpp" />
<ClCompile Include="..\..\src\rpc\protocol.cpp" />
<ClCompile Include="..\..\src\support\cleanse.cpp" />
<ClCompile Include="..\..\src\support\lockedpool.cpp" />
<ClCompile Include="..\..\src\sync.cpp" />
<ClCompile Include="..\..\src\threadinterrupt.cpp" />
<ClCompile Include="..\..\src\util.cpp" />
<ClCompile Include="..\..\src\utilmoneystr.cpp" />
<ClCompile Include="..\..\src\utilstrencodings.cpp" />
<ClCompile Include="..\..\src\utiltime.cpp" />
@SOURCE_FILES@
</ItemGroup>
<Import Label="configTarget" Project="..\common.vcxproj" />
</Project>

View file

@ -20,18 +20,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\wallet\coinselection.cpp" />
<ClCompile Include="..\..\src\wallet\coincontrol.cpp" />
<ClCompile Include="..\..\src\wallet\crypter.cpp" />
<ClCompile Include="..\..\src\wallet\db.cpp" />
<ClCompile Include="..\..\src\wallet\feebumper.cpp" />
<ClCompile Include="..\..\src\wallet\fees.cpp" />
<ClCompile Include="..\..\src\wallet\init.cpp" />
<ClCompile Include="..\..\src\wallet\rpcdump.cpp" />
<ClCompile Include="..\..\src\wallet\rpcwallet.cpp" />
<ClCompile Include="..\..\src\wallet\wallet.cpp" />
<ClCompile Include="..\..\src\wallet\walletdb.cpp" />
<ClCompile Include="..\..\src\wallet\walletutil.cpp" />
@SOURCE_FILES@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -20,10 +20,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\zmq\zmqabstractnotifier.cpp" />
<ClCompile Include="..\..\src\zmq\zmqnotificationinterface.cpp" />
<ClCompile Include="..\..\src\zmq\zmqpublishnotifier.cpp" />
<ClCompile Include="..\..\src\zmq\zmqrpc.cpp" />
@SOURCE_FILES@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -127,7 +127,7 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>..\..\src;</AdditionalIncludeDirectories>
<ExceptionHandling>false</ExceptionHandling>
<ExceptionHandling>Sync</ExceptionHandling>
<SuppressStartupBanner>false</SuppressStartupBanner>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
@ -144,7 +144,7 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>..\..\src;</AdditionalIncludeDirectories>
<ExceptionHandling>false</ExceptionHandling>
<ExceptionHandling>Sync</ExceptionHandling>
<SuppressStartupBanner>false</SuppressStartupBanner>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
@ -163,7 +163,7 @@
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>..\..\src;</AdditionalIncludeDirectories>
<ExceptionHandling>false</ExceptionHandling>
<ExceptionHandling>Sync</ExceptionHandling>
<SuppressStartupBanner>false</SuppressStartupBanner>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
@ -184,7 +184,7 @@
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>..\..\src;</AdditionalIncludeDirectories>
<ExceptionHandling>false</ExceptionHandling>
<ExceptionHandling>Sync</ExceptionHandling>
<SuppressStartupBanner>false</SuppressStartupBanner>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>

View file

@ -0,0 +1,63 @@
#!/usr/bin/env python3
import os
import re
SOURCE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src'))
libs = [
'libbitcoin_cli',
'libbitcoin_common',
'libbitcoin_crypto',
'libbitcoin_server',
'libbitcoin_util',
'libbitcoin_wallet',
'libbitcoin_zmq',
]
ignore_list = [
'rpc/net.cpp',
'interfaces/handler.cpp',
'interfaces/node.cpp',
'interfaces/wallet.cpp',
]
lib_sources = {}
def parse_makefile(makefile):
with open(makefile, 'r', encoding='utf-8') as file:
current_lib = ''
for line in file.read().splitlines():
if current_lib:
source = line.split()[0]
if source.endswith('.cpp') and not source.startswith('$') and source not in ignore_list:
lib_sources[current_lib].append(source.replace('/', '\\'))
if not line.endswith('\\'):
current_lib = ''
continue
for lib in libs:
_lib = lib.replace('-', '_')
if re.search(_lib + '.*_SOURCES \\= \\\\', line):
current_lib = lib
lib_sources[current_lib] = []
break
def main():
for makefile_name in os.listdir(SOURCE_DIR):
if 'Makefile' in makefile_name:
parse_makefile(os.path.join(SOURCE_DIR, makefile_name))
for key, value in lib_sources.items():
vcxproj_filename = os.path.abspath(os.path.join(os.path.dirname(__file__), key, key + '.vcxproj'))
content = ''
for source_filename in value:
content += ' <ClCompile Include="..\\..\\src\\' + source_filename + '" />\n'
with open(vcxproj_filename + '.in', 'r', encoding='utf-8') as vcxproj_in_file:
with open(vcxproj_filename, 'w', encoding='utf-8') as vcxproj_file:
vcxproj_file.write(vcxproj_in_file.read().replace(
'@SOURCE_FILES@\n', content))
if __name__ == '__main__':
main()

View file

@ -130,6 +130,12 @@ AC_ARG_ENABLE(gui-tests,
[use_gui_tests=$enableval],
[use_gui_tests=$use_tests])
AC_ARG_WITH([rapidcheck],
[AS_HELP_STRING([--with-rapidcheck],
[enable RapidCheck property based tests (default is yes if librapidcheck is found)])],
[use_rapidcheck=$withval],
[use_rapidcheck=auto])
AC_ARG_ENABLE(bench,
AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]),
[use_bench=$enableval],
@ -727,6 +733,10 @@ fi
AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
AC_CHECK_DECLS([getifaddrs, freeifaddrs],,,
[#include <sys/types.h>
#include <ifaddrs.h>]
)
AC_CHECK_DECLS([strnlen])
# Check for daemon(3), unrelated to --with-daemon (although used by it)
@ -1134,6 +1144,22 @@ AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT
])
CXXFLAGS="${save_CXXFLAGS}"
dnl RapidCheck Property Based Testing
enable_property_tests=no
if test "x$use_rapidcheck" = xauto; then
AC_CHECK_HEADERS([rapidcheck.h], [enable_property_tests=yes])
elif test "x$use_rapidcheck" != xno; then
enable_property_tests=yes
fi
RAPIDCHECK_LIBS=
if test "x$enable_property_tests" = xyes; then
RAPIDCHECK_LIBS=-lrapidcheck
fi
AC_SUBST(RAPIDCHECK_LIBS)
AM_CONDITIONAL([ENABLE_PROPERTY_TESTS], [test x$enable_property_tests = xyes])
dnl univalue check
need_bundled_univalue=yes

View file

@ -96,7 +96,7 @@ Comment: Site: https://bitcointalk.org/?topic=1756.0
Files: src/qt/res/icons/proxy.png
src/qt/res/src/proxy.svg
Copyright: Cristian Mircea Messel
Licese: public-domain
License: public-domain
License: Expat

View file

@ -27,7 +27,7 @@ def content_hash(filename):
pngcrush = 'pngcrush'
git = 'git'
folders = ["src/qt/res/movies", "src/qt/res/icons", "share/pixmaps"]
basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel'], universal_newlines=True).rstrip('\n')
basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel'], universal_newlines=True, encoding='utf8').rstrip('\n')
totalSaveBytes = 0
noHashChange = True
@ -50,7 +50,7 @@ for folder in folders:
sys.exit(0)
#verify
if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT, universal_newlines=True):
if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT, universal_newlines=True, encoding='utf8'):
print("PNG file "+file+" is corrupted after crushing, check out pngcursh version")
sys.exit(1)

View file

@ -36,17 +36,18 @@ import os
# (glibc) GLIBC_2_11
#
MAX_VERSIONS = {
'GCC': (4,4,0),
'CXXABI': (1,3,3),
'GLIBCXX': (3,4,13),
'GLIBC': (2,11)
'GCC': (4,4,0),
'CXXABI': (1,3,3),
'GLIBCXX': (3,4,13),
'GLIBC': (2,11),
'LIBATOMIC': (1,0)
}
# See here for a description of _IO_stdin_used:
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109
# Ignore symbols that are exported as part of every executable
IGNORE_EXPORTS = {
'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr'
'_edata', '_end', '__end__', '_init', '__bss_start', '__bss_start__', '_bss_end__', '__bss_end__', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr'
}
READELF_CMD = os.getenv('READELF', '/usr/bin/readelf')
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
@ -59,8 +60,12 @@ ALLOWED_LIBRARIES = {
'libanl.so.1', # DNS resolve
'libm.so.6', # math library
'librt.so.1', # real-time (clock)
'libatomic.so.1',
'ld-linux-x86-64.so.2', # 64-bit dynamic linker
'ld-linux.so.2', # 32-bit dynamic linker
'ld-linux-aarch64.so.1', # 64-bit ARM dynamic linker
'ld-linux-armhf.so.3', # 32-bit ARM dynamic linker
'ld-linux-riscv64-lp64d.so.1', # 64-bit RISC-V dynamic linker
# bitcoin-qt only
'libX11-xcb.so.1', # part of X11
'libX11.so.6', # part of X11
@ -69,7 +74,13 @@ ALLOWED_LIBRARIES = {
'libfreetype.so.6', # font parsing
'libdl.so.2' # programming interface to dynamic linker
}
ARCH_MIN_GLIBC_VER = {
'80386': (2,1),
'X86-64': (2,2,5),
'ARM': (2,4),
'AArch64':(2,17),
'RISC-V': (2,27)
}
class CPPFilt(object):
'''
Demangle C++ symbol names.
@ -94,23 +105,25 @@ def read_symbols(executable, imports=True):
Parse an ELF executable and return a list of (symbol,version) tuples
for dynamic, imported symbols.
'''
p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', '-h', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
(stdout, stderr) = p.communicate()
if p.returncode:
raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip()))
syms = []
for line in stdout.splitlines():
line = line.split()
if 'Machine:' in line:
arch = line[-1]
if len(line)>7 and re.match('[0-9]+:$', line[0]):
(sym, _, version) = line[7].partition('@')
is_import = line[6] == 'UND'
if version.startswith('@'):
version = version[1:]
if is_import == imports:
syms.append((sym, version))
syms.append((sym, version, arch))
return syms
def check_version(max_versions, version):
def check_version(max_versions, version, arch):
if '_' in version:
(lib, _, ver) = version.rpartition('_')
else:
@ -119,7 +132,7 @@ def check_version(max_versions, version):
ver = tuple([int(x) for x in ver.split('.')])
if not lib in max_versions:
return False
return ver <= max_versions[lib]
return ver <= max_versions[lib] or lib == 'GLIBC' and ver <= ARCH_MIN_GLIBC_VER[arch]
def read_libraries(filename):
p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
@ -142,16 +155,17 @@ if __name__ == '__main__':
retval = 0
for filename in sys.argv[1:]:
# Check imported symbols
for sym,version in read_symbols(filename, True):
if version and not check_version(MAX_VERSIONS, version):
for sym,version,arch in read_symbols(filename, True):
if version and not check_version(MAX_VERSIONS, version, arch):
print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version))
retval = 1
# Check exported symbols
for sym,version in read_symbols(filename, False):
if sym in IGNORE_EXPORTS:
continue
print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym)))
retval = 1
if arch != 'RISC-V':
for sym,version,arch in read_symbols(filename, False):
if sym in IGNORE_EXPORTS:
continue
print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym)))
retval = 1
# Check dependency libraries
for library_name in read_libraries(filename):
if library_name not in ALLOWED_LIBRARIES:

View file

@ -135,6 +135,7 @@ def main():
parser = argparse.ArgumentParser(usage='%(prog)s [options] signer version')
parser.add_argument('-c', '--commit', action='store_true', dest='commit', help='Indicate that the version argument is for a commit or branch')
parser.add_argument('-p', '--pull', action='store_true', dest='pull', help='Indicate that the version argument is the number of a github repository pull request')
parser.add_argument('-u', '--url', dest='url', default='https://github.com/bitcoin/bitcoin', help='Specify the URL of the repository. Default is %(default)s')
parser.add_argument('-v', '--verify', action='store_true', dest='verify', help='Verify the Gitian build')
parser.add_argument('-b', '--build', action='store_true', dest='build', help='Do a Gitian build')
@ -169,7 +170,7 @@ def main():
args.sign_prog = 'true' if args.detach_sign else 'gpg --detach-sign'
# Set enviroment variable USE_LXC or USE_DOCKER, let gitian-builder know that we use lxc or docker
# Set environment variable USE_LXC or USE_DOCKER, let gitian-builder know that we use lxc or docker
if args.docker:
os.environ['USE_DOCKER'] = '1'
elif not args.kvm:
@ -196,13 +197,21 @@ def main():
exit(1)
# Add leading 'v' for tags
if args.commit and args.pull:
raise Exception('Cannot have both commit and pull')
args.commit = ('' if args.commit else 'v') + args.version
print(args.commit)
if args.setup:
setup()
os.chdir('bitcoin')
if args.pull:
subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge'])
os.chdir('../gitian-builder/inputs/bitcoin')
subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge'])
args.commit = subprocess.check_output(['git', 'show', '-s', '--format=%H', 'FETCH_HEAD'], universal_newlines=True, encoding='utf8').strip()
args.version = 'pull-' + args.version
print(args.commit)
subprocess.check_call(['git', 'fetch'])
subprocess.check_call(['git', 'checkout', args.commit])
os.chdir(workdir)

View file

@ -173,18 +173,7 @@ script: |
CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}"
make ${MAKEOPTS}
make ${MAKEOPTS} -C src check-security
#TODO: This is a quick hack that disables symbol checking for arm.
# Instead, we should investigate why these are popping up.
# For aarch64, we'll need to bump up the min GLIBC version, as the abi
# support wasn't introduced until 2.17.
case $i in
aarch64-*) : ;;
arm-*) : ;;
riscv64-*) : ;;
*) make ${MAKEOPTS} -C src check-symbols ;;
esac
make ${MAKEOPTS} -C src check-symbols
make install DESTDIR=${INSTALLPATH}
cd installed
find . -name "lib*.la" -delete
@ -192,6 +181,7 @@ script: |
rm -rf ${DISTNAME}/lib/pkgconfig
find ${DISTNAME}/bin -type f -executable -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \;
find ${DISTNAME}/lib -type f -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \;
cp ../doc/README.md ${DISTNAME}/
find ${DISTNAME} -not -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
find ${DISTNAME} -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz
cd ../../

View file

@ -4,5 +4,5 @@ Utilities to generate test vectors for the data-driven Bitcoin tests.
Usage:
gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json
gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_invalid.json
PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py valid 50 > ../../src/test/data/key_io_keys_valid.json
PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py invalid 50 > ../../src/test/data/key_io_keys_invalid.json

View file

@ -1,132 +0,0 @@
#!/usr/bin/env python3
# Copyright (c) 2012-2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Generate valid and invalid base58 address and private key test vectors.
Usage:
gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json
gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_invalid.json
'''
# 2012 Wladimir J. van der Laan
# Released under MIT License
import os
from itertools import islice
from base58 import b58encode_chk, b58decode_chk, b58chars
import random
from binascii import b2a_hex
# key types
PUBKEY_ADDRESS = 0
SCRIPT_ADDRESS = 5
PUBKEY_ADDRESS_TEST = 111
SCRIPT_ADDRESS_TEST = 196
PRIVKEY = 128
PRIVKEY_TEST = 239
metadata_keys = ['isPrivkey', 'isTestnet', 'addrType', 'isCompressed']
# templates for valid sequences
templates = [
# prefix, payload_size, suffix, metadata
# None = N/A
((PUBKEY_ADDRESS,), 20, (), (False, False, 'pubkey', None)),
((SCRIPT_ADDRESS,), 20, (), (False, False, 'script', None)),
((PUBKEY_ADDRESS_TEST,), 20, (), (False, True, 'pubkey', None)),
((SCRIPT_ADDRESS_TEST,), 20, (), (False, True, 'script', None)),
((PRIVKEY,), 32, (), (True, False, None, False)),
((PRIVKEY,), 32, (1,), (True, False, None, True)),
((PRIVKEY_TEST,), 32, (), (True, True, None, False)),
((PRIVKEY_TEST,), 32, (1,), (True, True, None, True))
]
def is_valid(v):
'''Check vector v for validity'''
result = b58decode_chk(v)
if result is None:
return False
for template in templates:
prefix = bytearray(template[0])
suffix = bytearray(template[2])
if result.startswith(prefix) and result.endswith(suffix):
if (len(result) - len(prefix) - len(suffix)) == template[1]:
return True
return False
def gen_valid_vectors():
'''Generate valid test vectors'''
while True:
for template in templates:
prefix = bytearray(template[0])
payload = bytearray(os.urandom(template[1]))
suffix = bytearray(template[2])
rv = b58encode_chk(prefix + payload + suffix)
assert is_valid(rv)
metadata = {x: y for x, y in zip(metadata_keys,template[3]) if y is not None}
hexrepr = b2a_hex(payload)
if isinstance(hexrepr, bytes):
hexrepr = hexrepr.decode('utf8')
yield (rv, hexrepr, metadata)
def gen_invalid_vector(template, corrupt_prefix, randomize_payload_size, corrupt_suffix):
'''Generate possibly invalid vector'''
if corrupt_prefix:
prefix = os.urandom(1)
else:
prefix = bytearray(template[0])
if randomize_payload_size:
payload = os.urandom(max(int(random.expovariate(0.5)), 50))
else:
payload = os.urandom(template[1])
if corrupt_suffix:
suffix = os.urandom(len(template[2]))
else:
suffix = bytearray(template[2])
return b58encode_chk(prefix + payload + suffix)
def randbool(p = 0.5):
'''Return True with P(p)'''
return random.random() < p
def gen_invalid_vectors():
'''Generate invalid test vectors'''
# start with some manual edge-cases
yield "",
yield "x",
while True:
# kinds of invalid vectors:
# invalid prefix
# invalid payload length
# invalid (randomized) suffix (add random data)
# corrupt checksum
for template in templates:
val = gen_invalid_vector(template, randbool(0.2), randbool(0.2), randbool(0.2))
if random.randint(0,10)<1: # line corruption
if randbool(): # add random character to end
val += random.choice(b58chars)
else: # replace random character in the middle
n = random.randint(0, len(val))
val = val[0:n] + random.choice(b58chars) + val[n+1:]
if not is_valid(val):
yield val,
if __name__ == '__main__':
import sys
import json
iters = {'valid':gen_valid_vectors, 'invalid':gen_invalid_vectors}
try:
uiter = iters[sys.argv[1]]
except IndexError:
uiter = gen_valid_vectors
try:
count = int(sys.argv[2])
except IndexError:
count = 0
data = list(islice(uiter(), count))
json.dump(data, sys.stdout, sort_keys=True, indent=4)
sys.stdout.write('\n')

View file

@ -0,0 +1,249 @@
#!/usr/bin/env python3
# Copyright (c) 2012-2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Generate valid and invalid base58 address and private key test vectors.
Usage:
PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py valid 50 > ../../src/test/data/key_io_valid.json
PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py invalid 50 > ../../src/test/data/key_io_invalid.json
'''
# 2012 Wladimir J. van der Laan
# Released under MIT License
import os
from itertools import islice
from base58 import b58encode_chk, b58decode_chk, b58chars
import random
from binascii import b2a_hex
from segwit_addr import bech32_encode, decode, convertbits, CHARSET
# key types
PUBKEY_ADDRESS = 0
SCRIPT_ADDRESS = 5
PUBKEY_ADDRESS_TEST = 111
SCRIPT_ADDRESS_TEST = 196
PUBKEY_ADDRESS_REGTEST = 111
SCRIPT_ADDRESS_REGTEST = 196
PRIVKEY = 128
PRIVKEY_TEST = 239
PRIVKEY_REGTEST = 239
# script
OP_0 = 0x00
OP_1 = 0x51
OP_2 = 0x52
OP_16 = 0x60
OP_DUP = 0x76
OP_EQUAL = 0x87
OP_EQUALVERIFY = 0x88
OP_HASH160 = 0xa9
OP_CHECKSIG = 0xac
pubkey_prefix = (OP_DUP, OP_HASH160, 20)
pubkey_suffix = (OP_EQUALVERIFY, OP_CHECKSIG)
script_prefix = (OP_HASH160, 20)
script_suffix = (OP_EQUAL,)
p2wpkh_prefix = (OP_0, 20)
p2wsh_prefix = (OP_0, 32)
metadata_keys = ['isPrivkey', 'chain', 'isCompressed', 'tryCaseFlip']
# templates for valid sequences
templates = [
# prefix, payload_size, suffix, metadata, output_prefix, output_suffix
# None = N/A
((PUBKEY_ADDRESS,), 20, (), (False, 'main', None, None), pubkey_prefix, pubkey_suffix),
((SCRIPT_ADDRESS,), 20, (), (False, 'main', None, None), script_prefix, script_suffix),
((PUBKEY_ADDRESS_TEST,), 20, (), (False, 'test', None, None), pubkey_prefix, pubkey_suffix),
((SCRIPT_ADDRESS_TEST,), 20, (), (False, 'test', None, None), script_prefix, script_suffix),
((PUBKEY_ADDRESS_REGTEST,), 20, (), (False, 'regtest', None, None), pubkey_prefix, pubkey_suffix),
((SCRIPT_ADDRESS_REGTEST,), 20, (), (False, 'regtest', None, None), script_prefix, script_suffix),
((PRIVKEY,), 32, (), (True, 'main', False, None), (), ()),
((PRIVKEY,), 32, (1,), (True, 'main', True, None), (), ()),
((PRIVKEY_TEST,), 32, (), (True, 'test', False, None), (), ()),
((PRIVKEY_TEST,), 32, (1,), (True, 'test', True, None), (), ()),
((PRIVKEY_REGTEST,), 32, (), (True, 'regtest', False, None), (), ()),
((PRIVKEY_REGTEST,), 32, (1,), (True, 'regtest', True, None), (), ())
]
# templates for valid bech32 sequences
bech32_templates = [
# hrp, version, witprog_size, metadata, output_prefix
('bc', 0, 20, (False, 'main', None, True), p2wpkh_prefix),
('bc', 0, 32, (False, 'main', None, True), p2wsh_prefix),
('bc', 1, 2, (False, 'main', None, True), (OP_1, 2)),
('tb', 0, 20, (False, 'test', None, True), p2wpkh_prefix),
('tb', 0, 32, (False, 'test', None, True), p2wsh_prefix),
('tb', 2, 16, (False, 'test', None, True), (OP_2, 16)),
('bcrt', 0, 20, (False, 'regtest', None, True), p2wpkh_prefix),
('bcrt', 0, 32, (False, 'regtest', None, True), p2wsh_prefix),
('bcrt', 16, 40, (False, 'regtest', None, True), (OP_16, 40))
]
# templates for invalid bech32 sequences
bech32_ng_templates = [
# hrp, version, witprog_size, invalid_bech32, invalid_checksum, invalid_char
('tc', 0, 20, False, False, False),
('tb', 17, 32, False, False, False),
('bcrt', 3, 1, False, False, False),
('bc', 15, 41, False, False, False),
('tb', 0, 16, False, False, False),
('bcrt', 0, 32, True, False, False),
('bc', 0, 16, True, False, False),
('tb', 0, 32, False, True, False),
('bcrt', 0, 20, False, False, True)
]
def is_valid(v):
'''Check vector v for validity'''
if len(set(v) - set(b58chars)) > 0:
return is_valid_bech32(v)
result = b58decode_chk(v)
if result is None:
return is_valid_bech32(v)
for template in templates:
prefix = bytearray(template[0])
suffix = bytearray(template[2])
if result.startswith(prefix) and result.endswith(suffix):
if (len(result) - len(prefix) - len(suffix)) == template[1]:
return True
return is_valid_bech32(v)
def is_valid_bech32(v):
'''Check vector v for bech32 validity'''
for hrp in ['bc', 'tb', 'bcrt']:
if decode(hrp, v) != (None, None):
return True
return False
def gen_valid_base58_vector(template):
'''Generate valid base58 vector'''
prefix = bytearray(template[0])
payload = bytearray(os.urandom(template[1]))
suffix = bytearray(template[2])
dst_prefix = bytearray(template[4])
dst_suffix = bytearray(template[5])
rv = b58encode_chk(prefix + payload + suffix)
return rv, dst_prefix + payload + dst_suffix
def gen_valid_bech32_vector(template):
'''Generate valid bech32 vector'''
hrp = template[0]
witver = template[1]
witprog = bytearray(os.urandom(template[2]))
dst_prefix = bytearray(template[4])
rv = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5))
return rv, dst_prefix + witprog
def gen_valid_vectors():
'''Generate valid test vectors'''
glist = [gen_valid_base58_vector, gen_valid_bech32_vector]
tlist = [templates, bech32_templates]
while True:
for template, valid_vector_generator in [(t, g) for g, l in zip(glist, tlist) for t in l]:
rv, payload = valid_vector_generator(template)
assert is_valid(rv)
metadata = {x: y for x, y in zip(metadata_keys,template[3]) if y is not None}
hexrepr = b2a_hex(payload)
if isinstance(hexrepr, bytes):
hexrepr = hexrepr.decode('utf8')
yield (rv, hexrepr, metadata)
def gen_invalid_base58_vector(template):
'''Generate possibly invalid vector'''
# kinds of invalid vectors:
# invalid prefix
# invalid payload length
# invalid (randomized) suffix (add random data)
# corrupt checksum
corrupt_prefix = randbool(0.2)
randomize_payload_size = randbool(0.2)
corrupt_suffix = randbool(0.2)
if corrupt_prefix:
prefix = os.urandom(1)
else:
prefix = bytearray(template[0])
if randomize_payload_size:
payload = os.urandom(max(int(random.expovariate(0.5)), 50))
else:
payload = os.urandom(template[1])
if corrupt_suffix:
suffix = os.urandom(len(template[2]))
else:
suffix = bytearray(template[2])
val = b58encode_chk(prefix + payload + suffix)
if random.randint(0,10)<1: # line corruption
if randbool(): # add random character to end
val += random.choice(b58chars)
else: # replace random character in the middle
n = random.randint(0, len(val))
val = val[0:n] + random.choice(b58chars) + val[n+1:]
return val
def gen_invalid_bech32_vector(template):
'''Generate possibly invalid bech32 vector'''
no_data = randbool(0.1)
to_upper = randbool(0.1)
hrp = template[0]
witver = template[1]
witprog = bytearray(os.urandom(template[2]))
if no_data:
rv = bech32_encode(hrp, [])
else:
data = [witver] + convertbits(witprog, 8, 5)
if template[3] and not no_data:
if template[2] % 5 in {2, 4}:
data[-1] |= 1
else:
data.append(0)
rv = bech32_encode(hrp, data)
if template[4]:
i = len(rv) - random.randrange(1, 7)
rv = rv[:i] + random.choice(CHARSET.replace(rv[i], '')) + rv[i + 1:]
if template[5]:
i = len(hrp) + 1 + random.randrange(0, len(rv) - len(hrp) - 4)
rv = rv[:i] + rv[i:i + 4].upper() + rv[i + 4:]
if to_upper:
rv = rv.swapcase()
return rv
def randbool(p = 0.5):
'''Return True with P(p)'''
return random.random() < p
def gen_invalid_vectors():
'''Generate invalid test vectors'''
# start with some manual edge-cases
yield "",
yield "x",
glist = [gen_invalid_base58_vector, gen_invalid_bech32_vector]
tlist = [templates, bech32_ng_templates]
while True:
for template, invalid_vector_generator in [(t, g) for g, l in zip(glist, tlist) for t in l]:
val = invalid_vector_generator(template)
if not is_valid(val):
yield val,
if __name__ == '__main__':
import sys
import json
iters = {'valid':gen_valid_vectors, 'invalid':gen_invalid_vectors}
try:
uiter = iters[sys.argv[1]]
except IndexError:
uiter = gen_valid_vectors
try:
count = int(sys.argv[2])
except IndexError:
count = 0
data = list(islice(uiter(), count))
json.dump(data, sys.stdout, sort_keys=True, indent=4)
sys.stdout.write('\n')

View file

@ -91,7 +91,7 @@ def main():
no_sha1 = True
prev_commit = ""
initial_commit = current_commit
branch = subprocess.check_output([GIT, 'show', '-s', '--format=%H', initial_commit], universal_newlines=True).splitlines()[0]
branch = subprocess.check_output([GIT, 'show', '-s', '--format=%H', initial_commit], universal_newlines=True, encoding='utf8').splitlines()[0]
# Iterate through commits
while True:
@ -112,7 +112,7 @@ def main():
if prev_commit != "":
print("No parent of {} was signed with a trusted key!".format(prev_commit), file=sys.stderr)
print("Parents are:", file=sys.stderr)
parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', prev_commit], universal_newlines=True).splitlines()[0].split(' ')
parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', prev_commit], universal_newlines=True, encoding='utf8').splitlines()[0].split(' ')
for parent in parents:
subprocess.call([GIT, 'show', '-s', parent], stdout=sys.stderr)
else:
@ -122,25 +122,25 @@ def main():
# Check the Tree-SHA512
if (verify_tree or prev_commit == "") and current_commit not in incorrect_sha512_allowed:
tree_hash = tree_sha512sum(current_commit)
if ("Tree-SHA512: {}".format(tree_hash)) not in subprocess.check_output([GIT, 'show', '-s', '--format=format:%B', current_commit], universal_newlines=True).splitlines():
if ("Tree-SHA512: {}".format(tree_hash)) not in subprocess.check_output([GIT, 'show', '-s', '--format=format:%B', current_commit], universal_newlines=True, encoding='utf8').splitlines():
print("Tree-SHA512 did not match for commit " + current_commit, file=sys.stderr)
sys.exit(1)
# Merge commits should only have two parents
parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', current_commit], universal_newlines=True).splitlines()[0].split(' ')
parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', current_commit], universal_newlines=True, encoding='utf8').splitlines()[0].split(' ')
if len(parents) > 2:
print("Commit {} is an octopus merge".format(current_commit), file=sys.stderr)
sys.exit(1)
# Check that the merge commit is clean
commit_time = int(subprocess.check_output([GIT, 'show', '-s', '--format=format:%ct', current_commit], universal_newlines=True).splitlines()[0])
commit_time = int(subprocess.check_output([GIT, 'show', '-s', '--format=format:%ct', current_commit], universal_newlines=True, encoding='utf8').splitlines()[0])
check_merge = commit_time > time.time() - args.clean_merge * 24 * 60 * 60 # Only check commits in clean_merge days
allow_unclean = current_commit in unclean_merge_allowed
if len(parents) == 2 and check_merge and not allow_unclean:
current_tree = subprocess.check_output([GIT, 'show', '--format=%T', current_commit], universal_newlines=True).splitlines()[0]
current_tree = subprocess.check_output([GIT, 'show', '--format=%T', current_commit], universal_newlines=True, encoding='utf8').splitlines()[0]
subprocess.call([GIT, 'checkout', '--force', '--quiet', parents[0]])
subprocess.call([GIT, 'merge', '--no-ff', '--quiet', parents[1]], stdout=subprocess.DEVNULL)
recreated_tree = subprocess.check_output([GIT, 'show', '--format=format:%T', 'HEAD'], universal_newlines=True).splitlines()[0]
recreated_tree = subprocess.check_output([GIT, 'show', '--format=format:%T', 'HEAD'], universal_newlines=True, encoding='utf8').splitlines()[0]
if current_tree != recreated_tree:
print("Merge commit {} is not clean".format(current_commit), file=sys.stderr)
subprocess.call([GIT, 'diff', current_commit])

View file

@ -5,6 +5,7 @@ WORK_PATH = $(BASEDIR)/work
BASE_CACHE ?= $(BASEDIR)/built
SDK_PATH ?= $(BASEDIR)/SDKs
NO_QT ?=
RAPIDCHECK ?=
NO_WALLET ?=
NO_UPNP ?=
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
@ -14,7 +15,7 @@ HOST ?= $(BUILD)
PATCHES_PATH = $(BASEDIR)/patches
BASEDIR = $(CURDIR)
HASH_LENGTH:=11
DOWNLOAD_CONNECT_TIMEOUT:=10
DOWNLOAD_CONNECT_TIMEOUT:=30
DOWNLOAD_RETRIES:=3
HOST_ID_SALT ?= salt
BUILD_ID_SALT ?= salt
@ -93,6 +94,8 @@ qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch
wallet_packages_$(NO_WALLET) = $(wallet_packages)
upnp_packages_$(NO_UPNP) = $(upnp_packages)
rapidcheck_packages_$(RAPIDCHECK) = $(rapidcheck_packages)
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_)
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
@ -100,6 +103,10 @@ ifneq ($(qt_packages_),)
native_packages += $(qt_native_packages)
endif
ifeq ($(rapidcheck_packages_),)
packages += $(rapidcheck_packages)
endif
all_packages = $(packages) $(native_packages)
meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk

View file

@ -63,6 +63,7 @@ The following can be set when running make: make FOO=bar
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
DEBUG: disable some optimizations and enable more runtime checking
RAPIDCHECK: build rapidcheck (experimental)
HOST_ID_SALT: Optional salt to use when generating host package ids
BUILD_ID_SALT: Optional salt to use when generating build package ids

View file

@ -61,9 +61,12 @@ fi
CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS"
LDFLAGS="-L$depends_prefix/lib $LDFLAGS"
CC="@CC@"
CXX="@CXX@"
OBJC="${CC}"
if test -n "@CC@" -a -z "${CC}"; then
CC="@CC@"
fi
if test -n "@CXX@" -a -z "${CXX}"; then
CXX="@CXX@"
fi
PYTHONPATH=$depends_prefix/native/lib/python/dist-packages:$PYTHONPATH
if test -n "@AR@"; then

View file

@ -1,23 +0,0 @@
package=libICE
$(package)_version=1.0.9
$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
$(package)_sha256_hash=8f7032f2c1c64352b5423f6b48a8ebdc339cc63064af34d66a6c9aa79759e202
$(package)_dependencies=xtrans xproto
define $(package)_set_vars
$(package)_config_opts=--disable-static --disable-docs --disable-specs --without-xsltproc
$(package)_config_opts_linux=--with-pic
endef
define $(package)_config_cmds
$($(package)_autoconf)
endef
define $(package)_build_cmds
$(MAKE)
endef
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef

View file

@ -1,23 +0,0 @@
package=libSM
$(package)_version=1.2.2
$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
$(package)_sha256_hash=0baca8c9f5d934450a70896c4ad38d06475521255ca63b717a6510fdb6e287bd
$(package)_dependencies=xtrans xproto libICE
define $(package)_set_vars
$(package)_config_opts=--without-libuuid --without-xsltproc --disable-docs --disable-static
$(package)_config_opts_linux=--with-pic
endef
define $(package)_config_cmds
$($(package)_autoconf)
endef
define $(package)_build_cmds
$(MAKE)
endef
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef

View file

@ -5,6 +5,8 @@ qt_packages = qrencode protobuf zlib
qt_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
rapidcheck_packages = rapidcheck
qt_darwin_packages=qt
qt_mingw32_packages=qt

View file

@ -0,0 +1,18 @@
package=rapidcheck
$(package)_version=10fc0cb
$(package)_download_path=https://github.com/MarcoFalke/rapidcheck/archive
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=9640926223c00af45bce4c7df8b756b5458a89b2ba74cfe3e404467f13ce26df
define $(package)_config_cmds
cmake -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true .
endef
define $(package)_build_cmds
$(MAKE) && \
mkdir -p $($(package)_staging_dir)$(host_prefix)/include && \
cp -a include/* $($(package)_staging_dir)$(host_prefix)/include/ && \
cp -a extras/boost_test/include/rapidcheck/* $($(package)_staging_dir)$(host_prefix)/include/rapidcheck/ && \
mkdir -p $($(package)_staging_dir)$(host_prefix)/lib && \
cp -a librapidcheck.a $($(package)_staging_dir)$(host_prefix)/lib/
endef

View file

@ -75,6 +75,7 @@ The Bitcoin repo's [root README](/README.md) contains relevant information on th
- [Tor Support](tor.md)
- [Init Scripts (systemd/upstart/openrc)](init.md)
- [ZMQ](zmq.md)
- [PSBT support](psbt.md)
License
---------------------

View file

@ -64,6 +64,17 @@ Build Bitcoin Core
make deploy
Disable-wallet mode
--------------------
When the intention is to run only a P2P node without a wallet, Bitcoin Core may be compiled in
disable-wallet mode with:
./configure --disable-wallet
In this case there is no dependency on Berkeley DB 4.8.
Mining is also possible in disable-wallet mode using the `getblocktemplate` RPC call.
Running
-------

View file

@ -234,8 +234,7 @@ disable-wallet mode with:
In this case there is no dependency on Berkeley DB 4.8.
Mining is also possible in disable-wallet mode, but only using the `getblocktemplate` RPC
call not `getwork`.
Mining is also possible in disable-wallet mode using the `getblocktemplate` RPC call.
Additional Configure Flags
--------------------------
@ -284,4 +283,3 @@ To build executables for ARM:
For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory.

View file

@ -512,7 +512,7 @@ Strings and formatting
- *Rationale*: These functions do overflow checking, and avoid pesky locale issues.
- Avoid using locale dependent functions if possible. You can use the provided
[`lint-locale-dependence.sh`](/contrib/devtools/lint-locale-dependence.sh)
[`lint-locale-dependence.sh`](/test/lint/lint-locale-dependence.sh)
to check for accidental use of locale dependent functions.
- *Rationale*: Unnecessary locale dependence can cause bugs that are very tricky to isolate and fix.

132
doc/psbt.md Normal file
View file

@ -0,0 +1,132 @@
# PSBT Howto for Bitcoin Core
Since Bitcoin Core 0.17, an RPC interface exists for Partially Signed Bitcoin
Transactions (PSBTs, as specified in
[BIP 174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)).
This document describes the overall workflow for producing signed transactions
through the use of PSBT, and the specific RPC commands used in typical
scenarios.
## PSBT in general
PSBT is an interchange format for Bitcoin transactions that are not fully signed
yet, together with relevant metadata to help entities work towards signing it.
It is intended to simplify workflows where multiple parties need to cooperate to
produce a transaction. Examples include hardware wallets, multisig setups, and
[CoinJoin](https://bitcointalk.org/?topic=279249) transactions.
### Overall workflow
Overall, the construction of a fully signed Bitcoin transaction goes through the
following steps:
- A **Creator** proposes a particular transaction to be created. They construct
a PSBT that contains certain inputs and outputs, but no additional metadata.
- For each input, an **Updater** adds information about the UTXOs being spent by
the transaction to the PSBT. They also add information about the scripts and
public keys involved in each of the inputs (and possibly outputs) of the PSBT.
- **Signers** inspect the transaction and its metadata to decide whether they
agree with the transaction. They can use amount information from the UTXOs
to assess the values and fees involved. If they agree, they produce a
partial signature for the inputs for which they have relevant key(s).
- A **Finalizer** is run for each input to convert the partial signatures and
possibly script information into a final `scriptSig` and/or `scriptWitness`.
- An **Extractor** produces a valid Bitcoin transaction (in network format)
from a PSBT for which all inputs are finalized.
Generally, each of the above (excluding Creator and Extractor) will simply
add more and more data to a particular PSBT, until all inputs are fully signed.
In a naive workflow, they all have to operate sequentially, passing the PSBT
from one to the next, until the Extractor can convert it to a real transaction.
In order to permit parallel operation, **Combiners** can be employed which merge
metadata from different PSBTs for the same unsigned transaction.
The names above in bold are the names of the roles defined in BIP174. They're
useful in understanding the underlying steps, but in practice, software and
hardware implementations will typically implement multiple roles simultaneously.
## PSBT in Bitcoin Core
### RPCs
- **`converttopsbt` (Creator)** is a utility RPC that converts an
unsigned raw transaction to PSBT format. It ignores existing signatures.
- **`createpsbt` (Creator)** is a utility RPC that takes a list of inputs and
outputs and converts them to a PSBT with no additional information. It is
equivalent to calling `createrawtransaction` followed by `converttopsbt`.
- **`walletcreatefundedpsbt` (Creator, Updater)** is a wallet RPC that creates a
PSBT with the specified inputs and outputs, adds additional inputs and change
to it to balance it out, and adds relevant metadata. In particular, for inputs
that the wallet knows about (counting towards its normal or watch-only
balance), UTXO information will be added. For outputs and inputs with UTXO
information present, key and script information will be added which the wallet
knows about. It is equivalent to running `createrawtransaction`, followed by
`fundrawtransaction`, and `converttopsbt`.
- **`walletprocesspsbt` (Updater, Signer, Finalizer)** is a wallet RPC that takes as
input a PSBT, adds UTXO, key, and script data to inputs and outputs that miss
it, and optionally signs inputs. Where possible it also finalizes the partial
signatures.
- **`finalizepsbt` (Finalizer, Extractor)** is a utility RPC that finalizes any
partial signatures, and if all inputs are finalized, converts the result to a
fully signed transaction which can be broadcast with `sendrawtransaction`.
- **`combinepsbt` (Combiner)** is a utility RPC that implements a Combiner. It
can be used at any point in the workflow to merge information added to
different versions of the same PSBT. In particular it is useful to combine the
output of multiple Updaters or Signers.
- **`decodepsbt`** is a diagnostic utility RPC which will show all information in
a PSBT in human-readable form, as well as compute its eventual fee if known.
### Workflows
#### Multisig with multiple Bitcoin Core instances
Alice, Bob, and Carol want to create a 2-of-3 multisig address. They're all using
Bitcoin Core. We assume their wallets only contain the multisig funds. In case
they also have a personal wallet, this can be accomplished through the
multiwallet feature - possibly resulting in a need to add `-rpcwallet=name` to
the command line in case `bitcoin-cli` is used.
Setup:
- All three call `getnewaddress` to create a new address; call these addresses
*Aalice*, *Abob*, and *Acarol*.
- All three call `getaddressinfo X`, with *X* their respective address, and
remember the corresponding public keys. Call these public keys *Kalice*,
*Kbob*, and *Kcarol*.
- All three now run `addmultisigaddress 2 ["Kalice","Kbob","Kcarol"]` to teach
their wallet about the multisig script. Call the address produced by this
command *Amulti*. They may be required to explicitly specify the same
addresstype option each, to avoid constructing different versions due to
differences in configuration.
- They also run `importaddress "Amulti" "" false` to make their wallets treat
payments to *Amulti* as contributing to the watch-only balance.
- Others can verify the produced address by running
`createmultisig 2 ["Kalice","Kbob","Kcarol"]`, and expecting *Amulti* as
output. Again, it may be necessary to explicitly specify the addresstype
in order to get a result that matches. This command won't enable them to
initiate transactions later, however.
- They can now give out *D* as address others can pay to.
Later, when *V* BTC has been received on *Amulti*, and Bob and Carol want to
move the coins in their entirety to address *Asend*, with no change. Alice
does not need to be involved.
- One of them - let's assume Carol here - initiates the creation. She runs
`walletcreatefundedpsbt [] {"Asend":V} 0 false {"subtractFeeFromOutputs":[0], "includeWatching":true}`.
We call the resulting PSBT *P*. P does not contain any signatures.
- Carol needs to sign the transaction herself. In order to do so, she runs
`walletprocesspsbt P`, and gives the resulting PSBT *P2* to Bob.
- Bob inspects the PSBT using `decodepsbt "P2"` to determine if the transaction
has indeed just the expected input, and an output to *Asend*, and the fee is
reasonable. If he agrees, he calls `walletprocesspsbt "P2"` to sign. The
resulting PSBT *P3* contains both Carol's and Bob's signature.
- Now anyone can call `finalizepsbt "P2"` to extract a fully signed transaction
*T*.
- Finally anyone can broadcast the transaction using `sendrawtransaction "T"`.
In case there are more signers, it may be advantageous to let them all sign in
parallel, rather passing the PSBT from one signer to the next one. In the
above example this would translate to Carol handing a copy of *P* to each signer
separately. They can then all invoke `walletprocesspsbt P`, and end up with
their individually-signed PSBT structures. They then all send those back to
Carol (or anyone) who can combine them using `combinepsbt`. The last two steps
(`finalizepsbt` and `sendrawtransaction`) remain unchanged.

View file

@ -0,0 +1,8 @@
Account API removed
-------------------
The 'account' API was deprecated in v0.17 and has been fully removed in v0.18.
The 'label' API was introduced in v0.17 as a replacement for accounts.
See the release notes from v0.17 for a full description of the changes from the
'account' API to the 'label' API.

View file

@ -59,6 +59,16 @@ support versions of macOS older than 10.10.
Notable changes
===============
Command line option changes
---------------------------
The `-enablebip61` command line option (introduced in Bitcoin Core 0.17.0) is
used to toggle sending of BIP 61 reject messages. Reject messages have no use
case on the P2P network and are only logged for debugging by most network
nodes. The option will now by default be off for improved privacy and security
as well as reduced upload usage. The option can explicitly be turned on for
local-network debugging purposes.
Example item
------------

View file

@ -93,7 +93,7 @@ API, to create and destroy 'ephemeral' hidden services programmatically.
Bitcoin Core has been updated to make use of this.
This means that if Tor is running (and proper authentication has been configured),
Bitcoin Core automatically creates a hidden service to listen on. This will positively
Bitcoin Core automatically creates a hidden service to listen on. This will positively
affect the number of available .onion nodes.
This new feature is enabled by default if Bitcoin Core is listening (`-listen`), and
@ -102,8 +102,9 @@ and, if not disabled, configured using the `-torcontrol` and `-torpassword` sett
To show verbose debugging information, pass `-debug=tor`.
Connecting to Tor's control socket API requires one of two authentication methods to be
configured. For cookie authentication the user running bitcoind must have write access
to the `CookieAuthFile` specified in Tor configuration. In some cases, this is
configured. It also requires the control socket to be enabled, e.g. put `ControlPort 9051`
in `torrc` config file. For cookie authentication the user running bitcoind must have read
access to the `CookieAuthFile` specified in Tor configuration. In some cases this is
preconfigured and the creation of a hidden service is automatic. If permission problems
are seen with `-debug=tor` they can be resolved by adding both the user running Tor and
the user running bitcoind to the same group and setting permissions appropriately. On

View file

@ -96,6 +96,7 @@ BITCOIN_CORE_H = \
bech32.h \
bloom.h \
blockencodings.h \
blockfilter.h \
block_proof.h \
chain.h \
chainparams.h \
@ -224,6 +225,7 @@ libbitcoin_server_a_SOURCES = \
addrman.cpp \
bloom.cpp \
blockencodings.cpp \
blockfilter.cpp \
block_proof.cpp \
chain.cpp \
checkpoints.cpp \
@ -232,6 +234,8 @@ libbitcoin_server_a_SOURCES = \
httpserver.cpp \
index/base.cpp \
index/txindex.cpp \
interfaces/handler.cpp \
interfaces/node.cpp \
init.cpp \
dbwrapper.cpp \
mainchainrpc.cpp \
@ -266,6 +270,10 @@ libbitcoin_server_a_SOURCES = \
versionbits.cpp \
$(BITCOIN_CORE_H)
if !ENABLE_WALLET
libbitcoin_server_a_SOURCES += dummywallet.cpp
endif
if ENABLE_ZMQ
libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
@ -427,8 +435,6 @@ libbitcoin_util_a_SOURCES = \
compat/glibcxx_sanity.cpp \
compat/strnlen.cpp \
fs.cpp \
interfaces/handler.cpp \
interfaces/node.cpp \
logging.cpp \
random.cpp \
rpc/protocol.cpp \
@ -480,7 +486,7 @@ bitcoind_LDADD = \
$(LIBMEMENV) \
$(LIBSECP256K1)
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
# bitcoin-cli binary #
bitcoin_cli_SOURCES = bitcoin-cli.cpp
@ -498,7 +504,7 @@ bitcoin_cli_LDADD = \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO)
bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS)
bitcoin_cli_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS)
#
# bitcoin-tx binary #

View file

@ -22,6 +22,7 @@ bench_bench_bitcoin_SOURCES = \
bench/rollingbloom.cpp \
bench/crypto_hash.cpp \
bench/ccoins_caching.cpp \
bench/gcs_filter.cpp \
bench/merkle_root.cpp \
bench/mempool_eviction.cpp \
bench/verify_script.cpp \
@ -55,7 +56,7 @@ if ENABLE_WALLET
bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp
endif
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_LIBS)
bench_bench_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES)

View file

@ -8,7 +8,9 @@ TEST_SRCDIR = test
TEST_BINARY=test/test_bitcoin$(EXEEXT)
JSON_TEST_FILES = \
test/data/script_tests.json \
test/data/base58_encode_decode.json \
test/data/blockfilters.json \
test/data/key_io_valid.json \
test/data/key_io_invalid.json \
test/data/script_tests.json \
@ -27,6 +29,7 @@ BITCOIN_TEST_SUITE = \
# test_bitcoin binary #
BITCOIN_TESTS =\
test/pegin_witness_tests.cpp \
test/arith_uint256_tests.cpp \
test/scriptnum10.h \
test/addrman_tests.cpp \
@ -39,6 +42,7 @@ BITCOIN_TESTS =\
test/bip32_tests.cpp \
test/blockchain_tests.cpp \
test/blockencodings_tests.cpp \
test/blockfilter_tests.cpp \
test/bloom_tests.cpp \
test/bswap_tests.cpp \
test/checkqueue_tests.cpp \
@ -81,6 +85,7 @@ BITCOIN_TESTS =\
test/sigopcount_tests.cpp \
test/skiplist_tests.cpp \
test/streams_tests.cpp \
test/sync_tests.cpp \
test/timedata_tests.cpp \
test/torcontrol_tests.cpp \
test/transaction_tests.cpp \
@ -91,13 +96,20 @@ BITCOIN_TESTS =\
test/util_tests.cpp \
test/validation_block_tests.cpp \
test/versionbits_tests.cpp \
test/pegin_spent_tests.cpp \
test/pegin_witness_tests.cpp
test/pegin_spent_tests.cpp
# ELEMENTS IN THE END
if ENABLE_PROPERTY_TESTS
BITCOIN_TESTS += \
test/key_properties.cpp
BITCOIN_TEST_SUITE += \
test/gen/crypto_gen.cpp \
test/gen/crypto_gen.h
endif
if ENABLE_WALLET
BITCOIN_TESTS += \
wallet/test/accounting_tests.cpp \
wallet/test/psbt_wallet_tests.cpp \
wallet/test/wallet_tests.cpp \
wallet/test/wallet_crypto_tests.cpp \
@ -119,7 +131,7 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(RAPIDCHECK_LIBS)
test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
if ENABLE_ZMQ

View file

@ -62,7 +62,7 @@ uint32_t PolyMod(const data& v)
// v, it corresponds to x^2 + v0*x + v1 mod g(x). As 1 mod g(x) = 1, that is the starting value
// for `c`.
uint32_t c = 1;
for (auto v_i : v) {
for (const auto v_i : v) {
// We want to update `c` to correspond to a polynomial with one extra term. If the initial
// value of `c` consists of the coefficients of c(x) = f(x) mod g(x), we modify it to
// correspond to c'(x) = (f(x) * x + v_i) mod g(x), where v_i is the next input to
@ -149,7 +149,7 @@ std::string Encode(const std::string& hrp, const data& values) {
data combined = Cat(values, checksum);
std::string ret = hrp + '1';
ret.reserve(ret.size() + combined.size());
for (auto c : combined) {
for (const auto c : combined) {
ret += CHARSET[c];
}
return ret;

View file

@ -13,6 +13,8 @@
#include <memory>
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
static const int64_t DEFAULT_BENCH_EVALUATIONS = 5;
static const char* DEFAULT_BENCH_FILTER = ".*";
static const char* DEFAULT_BENCH_SCALING = "1.0";

View file

@ -80,18 +80,16 @@ static void SipHash_32b(benchmark::State& state)
static void FastRandom_32bit(benchmark::State& state)
{
FastRandomContext rng(true);
uint32_t x = 0;
while (state.KeepRunning()) {
x += rng.rand32();
rng.rand32();
}
}
static void FastRandom_1bit(benchmark::State& state)
{
FastRandomContext rng(true);
uint32_t x = 0;
while (state.KeepRunning()) {
x += rng.randbool();
rng.randbool();
}
}

43
src/bench/gcs_filter.cpp Normal file
View file

@ -0,0 +1,43 @@
// Copyright (c) 2018 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 <bench/bench.h>
#include <blockfilter.h>
static void ConstructGCSFilter(benchmark::State& state)
{
GCSFilter::ElementSet elements;
for (int i = 0; i < 10000; ++i) {
GCSFilter::Element element(32);
element[0] = static_cast<unsigned char>(i);
element[1] = static_cast<unsigned char>(i >> 8);
elements.insert(std::move(element));
}
uint64_t siphash_k0 = 0;
while (state.KeepRunning()) {
GCSFilter filter(siphash_k0, 0, 20, 1 << 20, elements);
siphash_k0++;
}
}
static void MatchGCSFilter(benchmark::State& state)
{
GCSFilter::ElementSet elements;
for (int i = 0; i < 10000; ++i) {
GCSFilter::Element element(32);
element[0] = static_cast<unsigned char>(i);
element[1] = static_cast<unsigned char>(i >> 8);
elements.insert(std::move(element));
}
GCSFilter filter(0, 0, 20, 1 << 20, elements);
while (state.KeepRunning()) {
filter.Match(GCSFilter::Element());
}
}
BENCHMARK(ConstructGCSFilter, 1000);
BENCHMARK(MatchGCSFilter, 50 * 1000);

View file

@ -17,10 +17,9 @@ static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& po
unsigned int sigOpCost = 4;
LockPoints lp;
std::set<std::pair<uint256, COutPoint>> setPeginsSpent;
pool.addUnchecked(tx->GetHash(), CTxMemPoolEntry(
pool.addUnchecked(CTxMemPoolEntry(
tx, nFee, nTime, nHeight,
spendsCoinbase, sigOpCost, lp,
setPeginsSpent));
spendsCoinbase, sigOpCost, lp, setPeginsSpent));
}
// Right now this is only testing eviction performance in an extremely small

View file

@ -12,7 +12,6 @@ static void RollingBloom(benchmark::State& state)
CRollingBloomFilter filter(120000, 0.000001);
std::vector<unsigned char> data(32);
uint32_t count = 0;
uint64_t match = 0;
while (state.KeepRunning()) {
count++;
data[0] = count;
@ -25,7 +24,7 @@ static void RollingBloom(benchmark::State& state)
data[1] = count >> 16;
data[2] = count >> 8;
data[3] = count;
match += filter.contains(data);
filter.contains(data);
}
}

View file

@ -24,6 +24,8 @@
#include <univalue.h>
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
static const bool DEFAULT_NAMED=false;
@ -33,6 +35,7 @@ static void SetupCliArgs()
{
const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST);
gArgs.AddArg("-?", "This help message", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-version", "Print version and exit", false, OptionsCategory::OPTIONS);
@ -43,9 +46,9 @@ static void SetupCliArgs()
gArgs.AddArg("-named", strprintf("Pass named instead of positional arguments (default: %s)", DEFAULT_NAMED), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcclienttimeout=<n>", strprintf("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)", DEFAULT_HTTP_CLIENT_TIMEOUT), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcconnect=<ip>", strprintf("Send commands to node running on <ip> (default: %s)", DEFAULT_RPCCONNECT), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpccookiefile=<loc>", _("Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)"), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcport=<port>", strprintf("Connect to JSON-RPC on <port> (default: %u or testnet: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcport=<port>", strprintf("Connect to JSON-RPC on <port> (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcwait", "Wait for RPC server to start", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcwallet=<walletname>", "Send RPC for non-default wallet on RPC server (needs to exactly match corresponding -wallet option passed to bitcoind)", false, OptionsCategory::OPTIONS);

View file

@ -31,6 +31,8 @@ static bool fCreateBlank;
static std::map<std::string,UniValue> registers;
static const int CONTINUE_EXECUTION=-1;
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
static void SetupBitcoinTxArgs()
{
gArgs.AddArg("-?", "This help message", false, OptionsCategory::OPTIONS);
@ -383,7 +385,7 @@ static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& s
CScript scriptPubKey = GetScriptForMultisig(required, pubkeys);
if (bSegWit) {
for (CPubKey& pubkey : pubkeys) {
for (const CPubKey& pubkey : pubkeys) {
if (!pubkey.IsCompressed()) {
throw std::runtime_error("Uncompressed pubkeys are not useable for SegWit outputs");
}

View file

@ -23,6 +23,8 @@
#include <stdio.h>
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
/* Introduction text for doxygen: */
/*! \mainpage Developer documentation

View file

@ -168,7 +168,7 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c
break;
}
LogPrint(BCLog::CMPCTBLOCK, "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), GetSerializeSize(cmpctblock, SER_NETWORK, PROTOCOL_VERSION));
LogPrint(BCLog::CMPCTBLOCK, "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), GetSerializeSize(cmpctblock, PROTOCOL_VERSION));
return READ_STATUS_OK;
}

261
src/blockfilter.cpp Normal file
View file

@ -0,0 +1,261 @@
// Copyright (c) 2018 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 <blockfilter.h>
#include <hash.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <streams.h>
/// SerType used to serialize parameters in GCS filter encoding.
static constexpr int GCS_SER_TYPE = SER_NETWORK;
/// Protocol version used to serialize parameters in GCS filter encoding.
static constexpr int GCS_SER_VERSION = 0;
template <typename OStream>
static void GolombRiceEncode(BitStreamWriter<OStream>& bitwriter, uint8_t P, uint64_t x)
{
// Write quotient as unary-encoded: q 1's followed by one 0.
uint64_t q = x >> P;
while (q > 0) {
int nbits = q <= 64 ? static_cast<int>(q) : 64;
bitwriter.Write(~0ULL, nbits);
q -= nbits;
}
bitwriter.Write(0, 1);
// Write the remainder in P bits. Since the remainder is just the bottom
// P bits of x, there is no need to mask first.
bitwriter.Write(x, P);
}
template <typename IStream>
static uint64_t GolombRiceDecode(BitStreamReader<IStream>& bitreader, uint8_t P)
{
// Read unary-encoded quotient: q 1's followed by one 0.
uint64_t q = 0;
while (bitreader.Read(1) == 1) {
++q;
}
uint64_t r = bitreader.Read(P);
return (q << P) + r;
}
// Map a value x that is uniformly distributed in the range [0, 2^64) to a
// value uniformly distributed in [0, n) by returning the upper 64 bits of
// x * n.
//
// See: https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
static uint64_t MapIntoRange(uint64_t x, uint64_t n)
{
#ifdef __SIZEOF_INT128__
return (static_cast<unsigned __int128>(x) * static_cast<unsigned __int128>(n)) >> 64;
#else
// To perform the calculation on 64-bit numbers without losing the
// result to overflow, split the numbers into the most significant and
// least significant 32 bits and perform multiplication piece-wise.
//
// See: https://stackoverflow.com/a/26855440
uint64_t x_hi = x >> 32;
uint64_t x_lo = x & 0xFFFFFFFF;
uint64_t n_hi = n >> 32;
uint64_t n_lo = n & 0xFFFFFFFF;
uint64_t ac = x_hi * n_hi;
uint64_t ad = x_hi * n_lo;
uint64_t bc = x_lo * n_hi;
uint64_t bd = x_lo * n_lo;
uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF);
uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32);
return upper64;
#endif
}
uint64_t GCSFilter::HashToRange(const Element& element) const
{
uint64_t hash = CSipHasher(m_siphash_k0, m_siphash_k1)
.Write(element.data(), element.size())
.Finalize();
return MapIntoRange(hash, m_F);
}
std::vector<uint64_t> GCSFilter::BuildHashedSet(const ElementSet& elements) const
{
std::vector<uint64_t> hashed_elements;
hashed_elements.reserve(elements.size());
for (const Element& element : elements) {
hashed_elements.push_back(HashToRange(element));
}
std::sort(hashed_elements.begin(), hashed_elements.end());
return hashed_elements;
}
GCSFilter::GCSFilter(uint64_t siphash_k0, uint64_t siphash_k1, uint8_t P, uint32_t M)
: m_siphash_k0(siphash_k0), m_siphash_k1(siphash_k1), m_P(P), m_M(M), m_N(0), m_F(0)
{}
GCSFilter::GCSFilter(uint64_t siphash_k0, uint64_t siphash_k1, uint8_t P, uint32_t M,
std::vector<unsigned char> encoded_filter)
: GCSFilter(siphash_k0, siphash_k1, P, M)
{
m_encoded = std::move(encoded_filter);
VectorReader stream(GCS_SER_TYPE, GCS_SER_VERSION, m_encoded, 0);
uint64_t N = ReadCompactSize(stream);
m_N = static_cast<uint32_t>(N);
if (m_N != N) {
throw std::ios_base::failure("N must be <2^32");
}
m_F = static_cast<uint64_t>(m_N) * static_cast<uint64_t>(m_M);
// Verify that the encoded filter contains exactly N elements. If it has too much or too little
// data, a std::ios_base::failure exception will be raised.
BitStreamReader<VectorReader> bitreader(stream);
for (uint64_t i = 0; i < m_N; ++i) {
GolombRiceDecode(bitreader, m_P);
}
if (!stream.empty()) {
throw std::ios_base::failure("encoded_filter contains excess data");
}
}
GCSFilter::GCSFilter(uint64_t siphash_k0, uint64_t siphash_k1, uint8_t P, uint32_t M,
const ElementSet& elements)
: GCSFilter(siphash_k0, siphash_k1, P, M)
{
size_t N = elements.size();
m_N = static_cast<uint32_t>(N);
if (m_N != N) {
throw std::invalid_argument("N must be <2^32");
}
m_F = static_cast<uint64_t>(m_N) * static_cast<uint64_t>(m_M);
CVectorWriter stream(GCS_SER_TYPE, GCS_SER_VERSION, m_encoded, 0);
WriteCompactSize(stream, m_N);
if (elements.empty()) {
return;
}
BitStreamWriter<CVectorWriter> bitwriter(stream);
uint64_t last_value = 0;
for (uint64_t value : BuildHashedSet(elements)) {
uint64_t delta = value - last_value;
GolombRiceEncode(bitwriter, m_P, delta);
last_value = value;
}
bitwriter.Flush();
}
bool GCSFilter::MatchInternal(const uint64_t* element_hashes, size_t size) const
{
VectorReader stream(GCS_SER_TYPE, GCS_SER_VERSION, m_encoded, 0);
// Seek forward by size of N
uint64_t N = ReadCompactSize(stream);
assert(N == m_N);
BitStreamReader<VectorReader> bitreader(stream);
uint64_t value = 0;
size_t hashes_index = 0;
for (uint32_t i = 0; i < m_N; ++i) {
uint64_t delta = GolombRiceDecode(bitreader, m_P);
value += delta;
while (true) {
if (hashes_index == size) {
return false;
} else if (element_hashes[hashes_index] == value) {
return true;
} else if (element_hashes[hashes_index] > value) {
break;
}
hashes_index++;
}
}
return false;
}
bool GCSFilter::Match(const Element& element) const
{
uint64_t query = HashToRange(element);
return MatchInternal(&query, 1);
}
bool GCSFilter::MatchAny(const ElementSet& elements) const
{
const std::vector<uint64_t> queries = BuildHashedSet(elements);
return MatchInternal(queries.data(), queries.size());
}
static GCSFilter::ElementSet BasicFilterElements(const CBlock& block,
const CBlockUndo& block_undo)
{
GCSFilter::ElementSet elements;
for (const CTransactionRef& tx : block.vtx) {
for (const CTxOut& txout : tx->vout) {
const CScript& script = txout.scriptPubKey;
if (script.empty() || script[0] == OP_RETURN) continue;
elements.emplace(script.begin(), script.end());
}
}
for (const CTxUndo& tx_undo : block_undo.vtxundo) {
for (const Coin& prevout : tx_undo.vprevout) {
const CScript& script = prevout.out.scriptPubKey;
if (script.empty()) continue;
elements.emplace(script.begin(), script.end());
}
}
return elements;
}
BlockFilter::BlockFilter(BlockFilterType filter_type, const CBlock& block, const CBlockUndo& block_undo)
: m_filter_type(filter_type), m_block_hash(block.GetHash())
{
switch (m_filter_type) {
case BlockFilterType::BASIC:
m_filter = GCSFilter(m_block_hash.GetUint64(0), m_block_hash.GetUint64(1),
BASIC_FILTER_P, BASIC_FILTER_M,
BasicFilterElements(block, block_undo));
break;
default:
throw std::invalid_argument("unknown filter_type");
}
}
uint256 BlockFilter::GetHash() const
{
const std::vector<unsigned char>& data = GetEncodedFilter();
uint256 result;
CHash256().Write(data.data(), data.size()).Finalize(result.begin());
return result;
}
uint256 BlockFilter::ComputeHeader(const uint256& prev_header) const
{
const uint256& filter_hash = GetHash();
uint256 result;
CHash256()
.Write(filter_hash.begin(), filter_hash.size())
.Write(prev_header.begin(), prev_header.size())
.Finalize(result.begin());
return result;
}

145
src/blockfilter.h Normal file
View file

@ -0,0 +1,145 @@
// Copyright (c) 2018 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_BLOCKFILTER_H
#define BITCOIN_BLOCKFILTER_H
#include <set>
#include <stdint.h>
#include <vector>
#include <primitives/block.h>
#include <serialize.h>
#include <uint256.h>
#include <undo.h>
/**
* This implements a Golomb-coded set as defined in BIP 158. It is a
* compact, probabilistic data structure for testing set membership.
*/
class GCSFilter
{
public:
typedef std::vector<unsigned char> Element;
typedef std::set<Element> ElementSet;
private:
uint64_t m_siphash_k0;
uint64_t m_siphash_k1;
uint8_t m_P; //!< Golomb-Rice coding parameter
uint32_t m_M; //!< Inverse false positive rate
uint32_t m_N; //!< Number of elements in the filter
uint64_t m_F; //!< Range of element hashes, F = N * M
std::vector<unsigned char> m_encoded;
/** Hash a data element to an integer in the range [0, N * M). */
uint64_t HashToRange(const Element& element) const;
std::vector<uint64_t> BuildHashedSet(const ElementSet& elements) const;
/** Helper method used to implement Match and MatchAny */
bool MatchInternal(const uint64_t* sorted_element_hashes, size_t size) const;
public:
/** Constructs an empty filter. */
GCSFilter(uint64_t siphash_k0 = 0, uint64_t siphash_k1 = 0, uint8_t P = 0, uint32_t M = 0);
/** Reconstructs an already-created filter from an encoding. */
GCSFilter(uint64_t siphash_k0, uint64_t siphash_k1, uint8_t P, uint32_t M,
std::vector<unsigned char> encoded_filter);
/** Builds a new filter from the params and set of elements. */
GCSFilter(uint64_t siphash_k0, uint64_t siphash_k1, uint8_t P, uint32_t M,
const ElementSet& elements);
uint8_t GetP() const { return m_P; }
uint32_t GetN() const { return m_N; }
uint32_t GetM() const { return m_M; }
const std::vector<unsigned char>& GetEncoded() const { return m_encoded; }
/**
* Checks if the element may be in the set. False positives are possible
* with probability 1/M.
*/
bool Match(const Element& element) const;
/**
* Checks if any of the given elements may be in the set. False positives
* are possible with probability 1/M per element checked. This is more
* efficient that checking Match on multiple elements separately.
*/
bool MatchAny(const ElementSet& elements) const;
};
constexpr uint8_t BASIC_FILTER_P = 19;
constexpr uint32_t BASIC_FILTER_M = 784931;
enum BlockFilterType : uint8_t
{
BASIC = 0,
};
/**
* Complete block filter struct as defined in BIP 157. Serialization matches
* payload of "cfilter" messages.
*/
class BlockFilter
{
private:
BlockFilterType m_filter_type;
uint256 m_block_hash;
GCSFilter m_filter;
public:
// Construct a new BlockFilter of the specified type from a block.
BlockFilter(BlockFilterType filter_type, const CBlock& block, const CBlockUndo& block_undo);
BlockFilterType GetFilterType() const { return m_filter_type; }
const GCSFilter& GetFilter() const { return m_filter; }
const std::vector<unsigned char>& GetEncodedFilter() const
{
return m_filter.GetEncoded();
}
// Compute the filter hash.
uint256 GetHash() const;
// Compute the filter header given the previous one.
uint256 ComputeHeader(const uint256& prev_header) const;
template <typename Stream>
void Serialize(Stream& s) const {
s << m_block_hash
<< static_cast<uint8_t>(m_filter_type)
<< m_filter.GetEncoded();
}
template <typename Stream>
void Unserialize(Stream& s) {
std::vector<unsigned char> encoded_filter;
uint8_t filter_type;
s >> m_block_hash
>> filter_type
>> encoded_filter;
m_filter_type = static_cast<BlockFilterType>(filter_type);
switch (m_filter_type) {
case BlockFilterType::BASIC:
m_filter = GCSFilter(m_block_hash.GetUint64(0), m_block_hash.GetUint64(1),
BASIC_FILTER_P, BASIC_FILTER_M, std::move(encoded_filter));
break;
default:
throw std::ios_base::failure("unknown filter_type");
}
}
};
#endif // BITCOIN_BLOCKFILTER_H

View file

@ -153,11 +153,11 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
insert(COutPoint(hash, i));
else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
{
txnouttype type;
std::vector<std::vector<unsigned char> > vSolutions;
if (Solver(txout.scriptPubKey, type, vSolutions) &&
(type == TX_PUBKEY || type == TX_MULTISIG))
txnouttype type = Solver(txout.scriptPubKey, vSolutions);
if (type == TX_PUBKEY || type == TX_MULTISIG) {
insert(COutPoint(hash, i));
}
}
break;
}

View file

@ -4,9 +4,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
#include <consensus/merkle.h>
#include <chainparamsseeds.h>
#include <consensus/merkle.h>
#include <tinyformat.h>
#include <util.h>
#include <utilstrencodings.h>
@ -17,7 +17,6 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
static CScript StrHexToScriptWithDefault(std::string strScript, const CScript defaultScript)
{
CScript returnScript;
@ -105,14 +104,6 @@ static void AppendInitialIssuance(CBlock& genesis_block, const COutPoint& prevou
/**
* Main network
*/
/**
* What makes a good checkpoint block?
* + Is surrounded by blocks with reasonable timestamps
* (no blocks before with a timestamp after, none after with
* timestamp before)
* + Contains no strange transactions
*/
class CMainParams : public CChainParams {
public:
CMainParams() {
@ -155,6 +146,8 @@ public:
anyonecanspend_aremine = false;
enforce_pak = false;
multi_data_permitted = false;
consensus.has_parent_chain = false;
g_signed_blocks = false;
/**
* The message start string is designed to be unlikely to occur in normal data.
@ -275,6 +268,7 @@ public:
anyonecanspend_aremine = false;
enforce_pak = false;
multi_data_permitted = false;
consensus.has_parent_chain = false;
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
@ -370,6 +364,7 @@ public:
anyonecanspend_aremine = false;
enforce_pak = false;
multi_data_permitted = false;
consensus.has_parent_chain = false;
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;

View file

@ -177,7 +177,7 @@ void CCoinsViewCache::SetPeginSpent(const std::pair<uint256, COutPoint> &outpoin
else
hadSpent = it->second.peginSpent;
// If we aren't changing spentness, dont do anything at all
// If we aren't changing spentness, don't do anything at all
if (hadSpent == fSpent)
return;
@ -326,7 +326,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
return true;
}
static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION);
static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), PROTOCOL_VERSION);
static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT;
const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)

View file

@ -303,8 +303,8 @@ public:
* Note that lightweight clients may not know anything besides the hash of previous transactions,
* so may not be able to calculate this.
*
* @param[in] tx transaction for which we are checking input total
* @return Sum of value of all inputs (scriptSigs)
* @param[in] tx transaction for which we are checking input total
* @return Sum of value of all inputs (scriptSigs)
*/
CAmount GetValueIn(const CTransaction& tx) const;

View file

@ -14,10 +14,10 @@
// GCC 4.8 is missing some C++11 type_traits,
// https://www.gnu.org/software/gcc/gcc-5/changes.html
#if defined(__GNUC__) && __GNUC__ < 5
#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivial
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
#define IS_TRIVIALLY_CONSTRUCTIBLE std::has_trivial_default_constructor
#else
#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_constructible
#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_default_constructible
#endif
#ifdef WIN32

View file

@ -159,7 +159,8 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.vin[i].m_is_pegin && !IsValidPeginWitness(tx.vin[i].m_pegin_witness, tx.vin[i].prevout)) {
std::string err;
if (tx.vin[i].m_is_pegin && !IsValidPeginWitness(tx.vin[i].m_pegin_witness, tx.vin[i].prevout, err, true)) {
continue;
}
@ -184,7 +185,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
if (tx.vout.empty())
return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty");
// Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize");
// Check for negative or overflow output values
@ -239,7 +240,8 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
const COutPoint &prevout = tx.vin[i].prevout;
if (tx.vin[i].m_is_pegin) {
// Check existence and validity of pegin witness
if (!IsValidPeginWitness(tx.vin[i].m_pegin_witness, prevout)) {
std::string err;
if (!IsValidPeginWitness(tx.vin[i].m_pegin_witness, prevout, err, true)) {
return state.DoS(0, false, REJECT_PEGIN, "bad-pegin-witness");
}
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.vin[i].m_pegin_witness.stack[2]), prevout);

View file

@ -97,16 +97,16 @@ public:
// weight = (stripped_size * 3) + total_size.
static inline int64_t GetTransactionWeight(const CTransaction& tx)
{
return ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
return ::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, PROTOCOL_VERSION);
}
static inline int64_t GetBlockWeight(const CBlock& block)
{
return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION);
return ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, PROTOCOL_VERSION);
}
static inline int64_t GetTransactionInputWeight(const CTxIn& txin)
{
// scriptWitness size is added here because witnesses and txins are split up in segwit serialization.
return ::GetSerializeSize(txin, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, SER_NETWORK, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, SER_NETWORK, PROTOCOL_VERSION);
return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION);
}
#endif // BITCOIN_CONSENSUS_VALIDATION_H

View file

@ -141,8 +141,7 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
out.pushKV("hex", HexStr(script.begin(), script.end()));
std::vector<std::vector<unsigned char>> solns;
txnouttype type;
Solver(script, type, solns);
txnouttype type = Solver(script, solns);
out.pushKV("type", GetTxnOutputType(type));
CTxDestination address;
@ -202,7 +201,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
entry.pushKV("txid", tx.GetHash().GetHex());
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
entry.pushKV("version", tx.nVersion);
entry.pushKV("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION));
entry.pushKV("size", (int)::GetSerializeSize(tx, PROTOCOL_VERSION));
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
entry.pushKV("weight", GetTransactionWeight(tx));
entry.pushKV("locktime", (int64_t)tx.nLockTime);

View file

@ -397,7 +397,7 @@ public:
std::array<uint32_t, 8> locs = compute_hashes(e);
// Make sure we have not already inserted this element
// If we have, make sure that it does not get deleted
for (uint32_t loc : locs)
for (const uint32_t loc : locs)
if (table[loc] == e) {
please_keep(loc);
epoch_flags[loc] = last_epoch;
@ -405,7 +405,7 @@ public:
}
for (uint8_t depth = 0; depth < depth_limit; ++depth) {
// First try to insert to an empty slot, if one exists
for (uint32_t loc : locs) {
for (const uint32_t loc : locs) {
if (!collection_flags.bit_is_set(loc))
continue;
table[loc] = std::move(e);
@ -467,7 +467,7 @@ public:
inline bool contains(const Element& e, const bool erase) const
{
std::array<uint32_t, 8> locs = compute_hashes(e);
for (uint32_t loc : locs)
for (const uint32_t loc : locs)
if (table[loc] == e) {
if (erase)
allow_erase(loc);

View file

@ -78,7 +78,7 @@ static void SetMaxOpenFiles(leveldb::Options *options) {
// do not interfere with select() loops. On 64-bit Unix hosts this value is
// also OK, because up to that amount LevelDB will use an mmap
// implementation that does not use extra file descriptors (the fds are
// closed after being mmaped).
// closed after being mmap'ed).
//
// Increasing the value beyond the default is dangerous because LevelDB will
// fall back to a non-mmap implementation when the file count is too large.

51
src/dummywallet.cpp Normal file
View file

@ -0,0 +1,51 @@
// Copyright (c) 2018 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 <stdio.h>
#include <util.h>
#include <walletinitinterface.h>
class CWallet;
class DummyWalletInit : public WalletInitInterface {
public:
bool HasWalletSupport() const override {return false;}
void AddWalletOptions() const override;
bool ParameterInteraction() const override {return true;}
void RegisterRPC(CRPCTable &) const override {}
bool Verify() const override {return true;}
bool Open() const override {LogPrintf("No wallet support compiled in!\n"); return true;}
void Start(CScheduler& scheduler) const override {}
void Flush() const override {}
void Stop() const override {}
void Close() const override {}
};
void DummyWalletInit::AddWalletOptions() const
{
std::vector<std::string> opts = {"-addresstype", "-changetype", "-disablewallet", "-discardfee=<amt>", "-fallbackfee=<amt>",
"-keypool=<n>", "-mintxfee=<amt>", "-paytxfee=<amt>", "-rescan", "-salvagewallet", "-spendzeroconfchange", "-txconfirmtarget=<n>",
"-upgradewallet", "-wallet=<path>", "-walletbroadcast", "-walletdir=<dir>", "-walletnotify=<cmd>", "-walletrbf", "-zapwallettxes=<mode>",
"-dblogsize=<n>", "-flushwallet", "-privdb", "-walletrejectlongchains"};
gArgs.AddHiddenArgs(opts);
}
const WalletInitInterface& g_wallet_init_interface = DummyWalletInit();
std::vector<std::shared_ptr<CWallet>> GetWallets()
{
throw std::logic_error("Wallet function called in non-wallet build.");
}
namespace interfaces {
class Wallet;
std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet)
{
throw std::logic_error("Wallet function called in non-wallet build.");
}
} // namespace interfaces

View file

@ -1,15 +1,116 @@
#include <fs.h>
#ifndef WIN32
#include <fcntl.h>
#else
#include <codecvt>
#include <windows.h>
#endif
namespace fsbridge {
FILE *fopen(const fs::path& p, const char *mode)
{
#ifndef WIN32
return ::fopen(p.string().c_str(), mode);
#else
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> utf8_cvt;
return ::_wfopen(p.wstring().c_str(), utf8_cvt.from_bytes(mode).c_str());
#endif
}
FILE *freopen(const fs::path& p, const char *mode, FILE *stream)
#ifndef WIN32
static std::string GetErrorReason() {
return std::strerror(errno);
}
FileLock::FileLock(const fs::path& file)
{
return ::freopen(p.string().c_str(), mode, stream);
fd = open(file.string().c_str(), O_RDWR);
if (fd == -1) {
reason = GetErrorReason();
}
}
FileLock::~FileLock()
{
if (fd != -1) {
close(fd);
}
}
bool FileLock::TryLock()
{
if (fd == -1) {
return false;
}
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
if (fcntl(fd, F_SETLK, &lock) == -1) {
reason = GetErrorReason();
return false;
}
return true;
}
#else
static std::string GetErrorReason() {
wchar_t* err;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<WCHAR*>(&err), 0, nullptr);
std::wstring err_str(err);
LocalFree(err);
return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().to_bytes(err_str);
}
FileLock::FileLock(const fs::path& file)
{
hFile = CreateFileW(file.wstring().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile == INVALID_HANDLE_VALUE) {
reason = GetErrorReason();
}
}
FileLock::~FileLock()
{
if (hFile != INVALID_HANDLE_VALUE) {
CloseHandle(hFile);
}
}
bool FileLock::TryLock()
{
if (hFile == INVALID_HANDLE_VALUE) {
return false;
}
_OVERLAPPED overlapped = {0};
if (!LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 0, 0, &overlapped)) {
reason = GetErrorReason();
return false;
}
return true;
}
#endif
std::string get_filesystem_error_message(const fs::filesystem_error& e)
{
#ifndef WIN32
return e.what();
#else
// Convert from Multi Byte to utf-16
std::string mb_string(e.what());
int size = MultiByteToWideChar(CP_ACP, 0, mb_string.c_str(), mb_string.size(), nullptr, 0);
std::wstring utf16_string(size, L'\0');
MultiByteToWideChar(CP_ACP, 0, mb_string.c_str(), mb_string.size(), &*utf16_string.begin(), size);
// Convert from utf-16 to utf-8
return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>().to_bytes(utf16_string);
#endif
}
} // fsbridge

View file

@ -18,7 +18,28 @@ namespace fs = boost::filesystem;
/** Bridge operations to C stdio */
namespace fsbridge {
FILE *fopen(const fs::path& p, const char *mode);
FILE *freopen(const fs::path& p, const char *mode, FILE *stream);
class FileLock
{
public:
FileLock() = delete;
FileLock(const FileLock&) = delete;
FileLock(FileLock&&) = delete;
explicit FileLock(const fs::path& file);
~FileLock();
bool TryLock();
std::string GetReason() { return reason; }
private:
std::string reason;
#ifndef WIN32
int fd = -1;
#else
void* hFile = (void*)-1; // INVALID_HANDLE_VALUE
#endif
};
std::string get_filesystem_error_message(const fs::filesystem_error& e);
};
#endif // BITCOIN_FS_H

View file

@ -14,6 +14,7 @@
#include <util.h>
#include <utilstrencodings.h>
#include <ui_interface.h>
#include <walletinitinterface.h>
#include <crypto/hmac_sha256.h>
#include <stdio.h>
@ -240,10 +241,9 @@ bool StartHTTPRPC()
return false;
RegisterHTTPHandler("/", true, HTTPReq_JSONRPC);
#ifdef ENABLE_WALLET
// ifdef can be removed once we switch to better endpoint support and API versioning
RegisterHTTPHandler("/wallet/", false, HTTPReq_JSONRPC);
#endif
if (g_wallet_init_interface.HasWalletSupport()) {
RegisterHTTPHandler("/wallet/", false, HTTPReq_JSONRPC);
}
struct event_base* eventBase = EventBase();
assert(eventBase);
httpRPCTimerInterface = MakeUnique<HTTPRPCTimerInterface>(eventBase);
@ -260,9 +260,9 @@ void StopHTTPRPC()
{
LogPrint(BCLog::RPC, "Stopping HTTP RPC server\n");
UnregisterHTTPHandler("/", true);
#ifdef ENABLE_WALLET
UnregisterHTTPHandler("/wallet/", false);
#endif
if (g_wallet_init_interface.HasWalletSupport()) {
UnregisterHTTPHandler("/wallet/", false);
}
if (httpRPCTimerInterface) {
RPCUnsetTimerInterface(httpRPCTimerInterface.get());
httpRPCTimerInterface.reset();

View file

@ -69,7 +69,7 @@ class WorkQueue
{
private:
/** Mutex protects entire object */
std::mutex cs;
Mutex cs;
std::condition_variable cond;
std::deque<std::unique_ptr<WorkItem>> queue;
bool running;
@ -88,7 +88,7 @@ public:
/** Enqueue a work item */
bool Enqueue(WorkItem* item)
{
std::unique_lock<std::mutex> lock(cs);
LOCK(cs);
if (queue.size() >= maxDepth) {
return false;
}
@ -102,7 +102,7 @@ public:
while (true) {
std::unique_ptr<WorkItem> i;
{
std::unique_lock<std::mutex> lock(cs);
WAIT_LOCK(cs, lock);
while (running && queue.empty())
cond.wait(lock);
if (!running)
@ -116,7 +116,7 @@ public:
/** Interrupt and exit loops */
void Interrupt()
{
std::unique_lock<std::mutex> lock(cs);
LOCK(cs);
running = false;
cond.notify_all();
}
@ -536,7 +536,7 @@ HTTPRequest::~HTTPRequest()
// evhttpd cleans up the request, as long as a reply was sent.
}
std::pair<bool, std::string> HTTPRequest::GetHeader(const std::string& hdr)
std::pair<bool, std::string> HTTPRequest::GetHeader(const std::string& hdr) const
{
const struct evkeyvalq* headers = evhttp_request_get_input_headers(req);
assert(headers);
@ -606,7 +606,7 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
req = nullptr; // transferred back to main thread
}
CService HTTPRequest::GetPeer()
CService HTTPRequest::GetPeer() const
{
evhttp_connection* con = evhttp_request_get_connection(req);
CService peer;
@ -620,12 +620,12 @@ CService HTTPRequest::GetPeer()
return peer;
}
std::string HTTPRequest::GetURI()
std::string HTTPRequest::GetURI() const
{
return evhttp_request_get_uri(req);
}
HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod()
HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod() const
{
switch (evhttp_request_get_command(req)) {
case EVHTTP_REQ_GET:

View file

@ -74,21 +74,21 @@ public:
/** Get requested URI.
*/
std::string GetURI();
std::string GetURI() const;
/** Get CService (address:ip) for the origin of the http request.
*/
CService GetPeer();
CService GetPeer() const;
/** Get request method.
*/
RequestMethod GetRequestMethod();
RequestMethod GetRequestMethod() const;
/**
* Get the request header specified by hdr, or an empty string.
* Return a pair (isPresent,string).
*/
std::pair<bool, std::string> GetHeader(const std::string& hdr);
std::pair<bool, std::string> GetHeader(const std::string& hdr) const;
/**
* Read request body.

View file

@ -250,7 +250,7 @@ bool TxIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
vPos.reserve(block.vtx.size());
for (const auto& tx : block.vtx) {
vPos.emplace_back(tx->GetHash(), pos);
pos.nTxOffset += ::GetSerializeSize(*tx, SER_DISK, CLIENT_VERSION);
pos.nTxOffset += ::GetSerializeSize(*tx, CLIENT_VERSION);
}
return m_db->WriteTxs(vPos);
}

View file

@ -53,13 +53,13 @@
#ifndef WIN32
#include <signal.h>
#include <sys/stat.h>
#endif
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/bind.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/thread.hpp>
#include <openssl/crypto.h>
@ -78,33 +78,6 @@ static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
std::unique_ptr<CConnman> g_connman;
std::unique_ptr<PeerLogicValidation> peerLogic;
#if !(ENABLE_WALLET)
class DummyWalletInit : public WalletInitInterface {
public:
void AddWalletOptions() const override;
bool ParameterInteraction() const override {return true;}
void RegisterRPC(CRPCTable &) const override {}
bool Verify() const override {return true;}
bool Open() const override {LogPrintf("No wallet support compiled in!\n"); return true;}
void Start(CScheduler& scheduler) const override {}
void Flush() const override {}
void Stop() const override {}
void Close() const override {}
};
void DummyWalletInit::AddWalletOptions() const
{
std::vector<std::string> opts = {"-addresstype", "-changetype", "-disablewallet", "-discardfee=<amt>", "-fallbackfee=<amt>",
"-keypool=<n>", "-mintxfee=<amt>", "-paytxfee=<amt>", "-rescan", "-salvagewallet", "-spendzeroconfchange", "-txconfirmtarget=<n>",
"-upgradewallet", "-wallet=<path>", "-walletbroadcast", "-walletdir=<dir>", "-walletnotify=<cmd>", "-walletrbf", "-zapwallettxes=<mode>",
"-dblogsize=<n>", "-flushwallet", "-privdb", "-walletrejectlongchains"};
gArgs.AddHiddenArgs(opts);
}
const WalletInitInterface& g_wallet_init_interface = DummyWalletInit();
#endif
#ifdef WIN32
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
// accessing block files don't count towards the fd_set size limit
@ -347,8 +320,10 @@ void SetupServerArgs()
{
const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST);
const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN);
const auto testnetChainParams = CreateChainParams(CBaseChainParams::TESTNET);
const auto regtestChainParams = CreateChainParams(CBaseChainParams::REGTEST);
// Hidden Options
std::vector<std::string> hidden_args = {"-rpcssl", "-benchmark", "-h", "-help", "-socks", "-tor", "-debugnet", "-whitelistalwaysrelay",
@ -390,7 +365,7 @@ void SetupServerArgs()
"Warning: Reverting this setting requires re-downloading the entire blockchain. "
"(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >=%u = automatically prune block files to stay under the specified target size in MiB)", MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-reindex", "Rebuild chain state and block index from the blk*.dat files on disk", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks. When in pruning mode or if blocks on disk might be corrupted, use full -reindex instead.", false, OptionsCategory::OPTIONS);
#ifndef WIN32
gArgs.AddArg("-sysperms", "Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)", false, OptionsCategory::OPTIONS);
#else
@ -420,7 +395,7 @@ void SetupServerArgs()
gArgs.AddArg("-onlynet=<net>", "Make outgoing connections only through network <net> (ipv4, ipv6 or onion). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks.", false, OptionsCategory::CONNECTION);
gArgs.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u or testnet: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort()), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet: %u, regtest: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-proxy=<ip:port>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled)", false, OptionsCategory::CONNECTION);
gArgs.AddArg("-proxyrandomize", strprintf("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)", DEFAULT_PROXYRANDOMIZE), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-seednode=<ip>", "Connect to a node to retrieve peer addresses, and disconnect. This option can be specified multiple times to connect to multiple nodes.", false, OptionsCategory::CONNECTION);
@ -455,9 +430,16 @@ void SetupServerArgs()
#endif
gArgs.AddArg("-checkblocks=<n>", strprintf("How many blocks to check at startup (default: %u, 0 = all)", DEFAULT_CHECKBLOCKS), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-checklevel=<n>", strprintf("How thorough the block verification of -checkblocks is (0-4, default: %u)", DEFAULT_CHECKLEVEL), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. (default: %u)", defaultChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u)", defaultChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-checklevel=<n>", strprintf("How thorough the block verification of -checkblocks is: "
"level 0 reads the blocks from disk, "
"level 1 verifies block validity, "
"level 2 verifies undo data, "
"level 3 checks disconnection of tip blocks, "
"and level 4 tries to reconnect the blocks, "
"each level includes the checks of the previous levels "
"(0-4, default: %u)", DEFAULT_CHECKLEVEL), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-deprecatedrpc=<method>", "Allows deprecated RPC method(s) to be used", true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages", true, OptionsCategory::DEBUG_TEST);
@ -471,7 +453,7 @@ void SetupServerArgs()
gArgs.AddArg("-debug=<category>", "Output debugging information (default: -nodebug, supplying <category> is optional). "
"If <category> is not supplied or if <category> = 1, output all debugging information. <category> can be: " + ListLogCategories() + ".", false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-debugexclude=<category>", strprintf("Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories."), false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-help-debug", "Show all debugging options (usage: --help -help-debug)", false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-help-debug", "Print help message with debugging options and exit", false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS), true, OptionsCategory::DEBUG_TEST);
@ -511,7 +493,7 @@ void SetupServerArgs()
gArgs.AddArg("-rpcbind=<addr>[:port]", "Bind to given address to listen for JSON-RPC connections. This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost, or if -rpcallowip has been specified, 0.0.0.0 and :: i.e., all addresses)", false, OptionsCategory::RPC);
gArgs.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", false, OptionsCategory::RPC);
gArgs.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", false, OptionsCategory::RPC);
gArgs.AddArg("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()), false, OptionsCategory::RPC);
gArgs.AddArg("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), false, OptionsCategory::RPC);
gArgs.AddArg("-rpcserialversion", strprintf("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)", DEFAULT_RPC_SERIALIZE_VERSION), false, OptionsCategory::RPC);
gArgs.AddArg("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT), true, OptionsCategory::RPC);
gArgs.AddArg("-rpcthreads=<n>", strprintf("Set the number of threads to service RPC calls (default: %d)", DEFAULT_HTTP_THREADS), false, OptionsCategory::RPC);
@ -548,7 +530,7 @@ void SetupServerArgs()
gArgs.AddArg("-mainchainrpccookiefile=<file>", "The bitcoind cookie auth path which the daemon will use to connect to the trusted bitcoind to validate peg-ins. (default: `<datadir>/regtest/.cookie`)", false, OptionsCategory::ELEMENTS);
gArgs.AddArg("-mainchainrpctimeout=<n>", strprintf("Timeout in seconds during mainchain RPC requests, or 0 for no timeout. (default: %d)", DEFAULT_HTTP_CLIENT_TIMEOUT), false, OptionsCategory::ELEMENTS);
gArgs.AddArg("-peginconfirmationdepth=<n>", strprintf("Pegin claims must be this deep to be considered valid. (default: %d)", DEFAULT_PEGIN_CONFIRMATION_DEPTH), false, OptionsCategory::ELEMENTS);
gArgs.AddArg("-recheckpeginblockinterval=<n>", strprintf("The interval in seconds at which a peg-in witness failing block is re-evaluated in case of intermittant peg-in witness failure. 0 means never. (default: %u)", 120), false, OptionsCategory::ELEMENTS);
gArgs.AddArg("-recheckpeginblockinterval=<n>", strprintf("The interval in seconds at which a peg-in witness failing block is re-evaluated in case of intermittent peg-in witness failure. 0 means never. (default: %u)", 120), false, OptionsCategory::ELEMENTS);
gArgs.AddArg("-parentpubkeyprefix", strprintf("The byte prefix, in decimal, of the parent chain's base58 pubkey address. (default: %d)", 111), false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-parentscriptprefix", strprintf("The byte prefix, in decimal, of the parent chain's base58 script address. (default: %d)", 196), false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-parent_bech32_hrp", strprintf("The human-readable part of the parent chain's bech32 encoding. (default: %s)", "bc"), false, OptionsCategory::CHAINPARAMS);
@ -594,17 +576,17 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex
}
static bool fHaveGenesis = false;
static CWaitableCriticalSection cs_GenesisWait;
static CConditionVariable condvar_GenesisWait;
static Mutex g_genesis_wait_mutex;
static std::condition_variable g_genesis_wait_cv;
static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex)
{
if (pBlockIndex != nullptr) {
{
WaitableLock lock_GenesisWait(cs_GenesisWait);
LOCK(g_genesis_wait_mutex);
fHaveGenesis = true;
}
condvar_GenesisWait.notify_all();
g_genesis_wait_cv.notify_all();
}
}
@ -1251,7 +1233,19 @@ bool AppInitMain()
LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime()));
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
LogPrintf("Using data directory %s\n", GetDataDir().string());
LogPrintf("Using config file %s\n", GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string());
// Only log conf file usage message if conf file actually exists.
fs::path config_file_path = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
if (fs::exists(config_file_path)) {
LogPrintf("Config file: %s\n", config_file_path.string());
} else if (gArgs.IsArgSet("-conf")) {
// Warn if no conf file exists at path provided by user
InitWarning(strprintf(_("The specified config file %s does not exist\n"), config_file_path.string()));
} else {
// Not categorizing as "Warning" because it's the default behavior
LogPrintf("Config file: %s (not found, skipping)\n", config_file_path.string());
}
LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);
// Warn about relative -datadir path.
@ -1669,12 +1663,12 @@ bool AppInitMain()
// Wait for genesis block to be processed
{
WaitableLock lock(cs_GenesisWait);
WAIT_LOCK(g_genesis_wait_mutex, lock);
// We previously could hang here if StartShutdown() is called prior to
// ThreadImport getting started, so instead we just wait on a timer to
// check ShutdownRequested() regularly.
while (!fHaveGenesis && !ShutdownRequested()) {
condvar_GenesisWait.wait_for(lock, std::chrono::milliseconds(500));
g_genesis_wait_cv.wait_for(lock, std::chrono::milliseconds(500));
}
uiInterface.NotifyBlockTip_disconnect(BlockNotifyGenesisWait);
}

View file

@ -13,9 +13,6 @@
class CScheduler;
class CWallet;
class WalletInitInterface;
extern const WalletInitInterface& g_wallet_init_interface;
namespace boost
{
class thread_group;

View file

@ -15,7 +15,7 @@ namespace {
class HandlerImpl : public Handler
{
public:
HandlerImpl(boost::signals2::connection connection) : m_connection(std::move(connection)) {}
explicit HandlerImpl(boost::signals2::connection connection) : m_connection(std::move(connection)) {}
void disconnect() override { m_connection.disconnect(); }

View file

@ -32,19 +32,18 @@
#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif
#ifdef ENABLE_WALLET
#include <wallet/fees.h>
#include <wallet/wallet.h>
#define CHECK_WALLET(x) x
#else
#define CHECK_WALLET(x) throw std::logic_error("Wallet function called in non-wallet build.")
#endif
#include <atomic>
#include <boost/thread/thread.hpp>
#include <univalue.h>
class CWallet;
std::vector<std::shared_ptr<CWallet>> GetWallets();
namespace interfaces {
class Wallet;
namespace {
class NodeImpl : public Node
@ -221,15 +220,11 @@ class NodeImpl : public Node
}
std::vector<std::unique_ptr<Wallet>> getWallets() override
{
#ifdef ENABLE_WALLET
std::vector<std::unique_ptr<Wallet>> wallets;
for (const std::shared_ptr<CWallet>& wallet : GetWallets()) {
wallets.emplace_back(MakeWallet(wallet));
}
return wallets;
#else
throw std::logic_error("Node::getWallets() called in non-wallet build.");
#endif
}
std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
{
@ -249,8 +244,7 @@ class NodeImpl : public Node
}
std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
{
CHECK_WALLET(
return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::shared_ptr<CWallet> wallet) { fn(MakeWallet(wallet)); })));
return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::shared_ptr<CWallet> wallet) { fn(MakeWallet(wallet)); }));
}
std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
{

View file

@ -31,7 +31,7 @@ namespace {
class PendingWalletTxImpl : public PendingWalletTx
{
public:
PendingWalletTxImpl(CWallet& wallet) : m_wallet(wallet), m_key(&wallet) {}
explicit PendingWalletTxImpl(CWallet& wallet) : m_wallet(wallet), m_key(&wallet) {}
const CTransaction& get() override { return *m_tx; }
@ -39,12 +39,11 @@ public:
bool commit(WalletValueMap value_map,
WalletOrderForm order_form,
std::string from_account,
std::string& reject_reason) override
{
LOCK2(cs_main, m_wallet.cs_wallet);
CValidationState state;
if (!m_wallet.CommitTransaction(m_tx, std::move(value_map), std::move(order_form), std::move(from_account), m_key, g_connman.get(), state)) {
if (!m_wallet.CommitTransaction(m_tx, std::move(value_map), std::move(order_form), m_key, g_connman.get(), state)) {
reject_reason = state.GetRejectReason();
return false;
}
@ -57,7 +56,7 @@ public:
};
//! Construct wallet tx struct.
WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx)
static WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
WalletTx result;
result.tx = wtx.tx;
@ -85,7 +84,7 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx)
}
//! Construct wallet tx status struct.
WalletTxStatus MakeWalletTxStatus(const CWalletTx& wtx)
static WalletTxStatus MakeWalletTxStatus(const CWalletTx& wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
WalletTxStatus result;
auto mi = ::mapBlockIndex.find(wtx.hashBlock);
@ -104,7 +103,7 @@ WalletTxStatus MakeWalletTxStatus(const CWalletTx& wtx)
}
//! Construct wallet TxOut struct.
WalletTxOut MakeWalletTxOut(CWallet& wallet, const CWalletTx& wtx, int n, int depth)
static WalletTxOut MakeWalletTxOut(CWallet& wallet, const CWalletTx& wtx, int n, int depth) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
WalletTxOut result;
result.txout = wtx.tx->vout[n];
@ -117,7 +116,7 @@ WalletTxOut MakeWalletTxOut(CWallet& wallet, const CWalletTx& wtx, int n, int de
class WalletImpl : public Wallet
{
public:
WalletImpl(const std::shared_ptr<CWallet>& wallet) : m_shared_wallet(wallet), m_wallet(*wallet.get()) {}
explicit WalletImpl(const std::shared_ptr<CWallet>& wallet) : m_shared_wallet(wallet), m_wallet(*wallet.get()) {}
bool encryptWallet(const SecureString& wallet_passphrase) override
{

View file

@ -289,7 +289,6 @@ public:
//! Send pending transaction and commit to wallet.
virtual bool commit(WalletValueMap value_map,
WalletOrderForm order_form,
std::string from_account,
std::string& reject_reason) = 0;
};
@ -367,8 +366,8 @@ struct WalletTxOut
bool is_spent = false;
};
//! Return implementation of Wallet interface. This function will be undefined
//! in builds where ENABLE_WALLET is false.
//! Return implementation of Wallet interface. This function is defined in
//! dummywallet.cpp and throws if the wallet component is not compiled.
std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet);
} // namespace interfaces

View file

@ -89,7 +89,7 @@ static int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *ou
* will be set to the number of bytes used in the buffer.
* key32 must point to a 32-byte raw private key.
*/
static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) {
static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, bool compressed) {
assert(*privkeylen >= CKey::PRIVATE_KEY_SIZE);
secp256k1_pubkey pubkey;
size_t pubkeylen = 0;
@ -170,7 +170,7 @@ CPrivKey CKey::GetPrivKey() const {
size_t privkeylen;
privkey.resize(PRIVATE_KEY_SIZE);
privkeylen = PRIVATE_KEY_SIZE;
ret = ec_privkey_export_der(secp256k1_context_sign, privkey.data(), &privkeylen, begin(), fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
ret = ec_privkey_export_der(secp256k1_context_sign, privkey.data(), &privkeylen, begin(), fCompressed);
assert(ret);
privkey.resize(privkeylen);
return privkey;

View file

@ -27,7 +27,7 @@ private:
const bool for_parent;
public:
DestinationEncoder(const CChainParams& params, const bool for_parent) : m_params(params), for_parent(for_parent) {}
explicit DestinationEncoder(const CChainParams& params, const bool for_parent) : m_params(params), for_parent(for_parent) {}
std::string operator()(const CKeyID& id) const
{
@ -76,7 +76,7 @@ public:
}
std::string operator()(const CNoDestination& no) const { return {}; }
std::string operator()(const NullData& nd) const { return {}; }
std::string operator()(const NullData& null) const { return {}; }
};
CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, const bool for_parent)

View file

@ -219,13 +219,13 @@ void BCLog::Logger::LogPrintStr(const std::string &str)
// reopen the log file, if requested
if (m_reopen_file) {
m_reopen_file = false;
m_fileout = fsbridge::freopen(m_file_path, "a", m_fileout);
if (!m_fileout) {
return;
FILE* new_fileout = fsbridge::fopen(m_file_path, "a");
if (new_fileout) {
setbuf(new_fileout, nullptr); // unbuffered
fclose(m_fileout);
m_fileout = new_fileout;
}
setbuf(m_fileout, nullptr); // unbuffered
}
FileWriteStr(strTimestamped, m_fileout);
}
}

View file

@ -125,42 +125,31 @@ std::vector<CLogCategoryActive> ListActiveLogCategories();
/** Return true if str parses as a log category and set the flag */
bool GetLogCategory(BCLog::LogFlags& flag, const std::string& str);
/** Get format string from VA_ARGS for error reporting */
template<typename... Args> std::string FormatStringFromLogArgs(const char *fmt, const Args&... args) { return fmt; }
static inline void MarkUsed() {}
template<typename T, typename... Args> static inline void MarkUsed(const T& t, const Args&... args)
{
(void)t;
MarkUsed(args...);
}
// Be conservative when using LogPrintf/error or other things which
// unconditionally log to debug.log! It should not be the case that an inbound
// peer can fill up a user's disk with debug.log entries.
#ifdef USE_COVERAGE
#define LogPrintf(...) do { MarkUsed(__VA_ARGS__); } while(0)
#define LogPrint(category, ...) do { MarkUsed(__VA_ARGS__); } while(0)
#else
#define LogPrintf(...) do { \
if (g_logger->Enabled()) { \
std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \
try { \
_log_msg_ = tfm::format(__VA_ARGS__); \
} catch (tinyformat::format_error &fmterr) { \
/* Original format string will have newline so don't add one here */ \
_log_msg_ = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + FormatStringFromLogArgs(__VA_ARGS__); \
} \
g_logger->LogPrintStr(_log_msg_); \
} \
} while(0)
template <typename... Args>
static inline void LogPrintf(const char* fmt, const Args&... args)
{
if (g_logger->Enabled()) {
std::string log_msg;
try {
log_msg = tfm::format(fmt, args...);
} catch (tinyformat::format_error& fmterr) {
/* Original format string will have newline so don't add one here */
log_msg = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + fmt;
}
g_logger->LogPrintStr(log_msg);
}
}
#define LogPrint(category, ...) do { \
if (LogAcceptCategory((category))) { \
LogPrintf(__VA_ARGS__); \
} \
} while(0)
#endif
template <typename... Args>
static inline void LogPrint(const BCLog::LogFlags& category, const Args&... args)
{
if (LogAcceptCategory((category))) {
LogPrintf(args...);
}
}
#endif // BITCOIN_LOGGING_H

View file

@ -125,7 +125,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
// Pad block weight to account for OP_RETURN commitments with two compressed pubkeys
for (const auto& commitment : commitments) {
CTxOut output(0, commitment);
nBlockWeight += ::GetSerializeSize(output, SER_NETWORK, PROTOCOL_VERSION)*WITNESS_SCALE_FACTOR;
nBlockWeight += ::GetSerializeSize(output, PROTOCOL_VERSION)*WITNESS_SCALE_FACTOR;
}
// END PAK

View file

@ -344,7 +344,7 @@ CNode* CConnman::FindNode(const CService& addr)
bool CConnman::CheckIncomingNonce(uint64_t nonce)
{
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
for (const CNode* pnode : vNodes) {
if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
return false;
}
@ -715,6 +715,7 @@ void CNode::copyStats(CNodeStats &stats)
X(nRecvBytes);
}
X(fWhitelisted);
X(minFeeFilter);
// It is common for nodes with good ping times to suddenly become lagged,
// due to a new block arriving or other large transfer.
@ -1226,7 +1227,7 @@ void CConnman::ThreadSocketHandler()
if(vNodesSize != nPrevNodeCount) {
nPrevNodeCount = vNodesSize;
if(clientInterface)
clientInterface->NotifyNumConnectionsChanged(nPrevNodeCount);
clientInterface->NotifyNumConnectionsChanged(vNodesSize);
}
//
@ -1613,7 +1614,7 @@ void CConnman::ThreadDNSAddressSeed()
LOCK(cs_vNodes);
int nRelevant = 0;
for (auto pnode : vNodes) {
for (const CNode* pnode : vNodes) {
nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
}
if (nRelevant >= 2) {
@ -1732,7 +1733,7 @@ int CConnman::GetExtraOutboundCount()
int nOutbound = 0;
{
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
for (const CNode* pnode : vNodes) {
if (!pnode->fInbound && !pnode->m_manual_connection && !pnode->fFeeler && !pnode->fDisconnect && !pnode->fOneShot && pnode->fSuccessfullyConnected) {
++nOutbound;
}
@ -1802,7 +1803,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
std::set<std::vector<unsigned char> > setConnected;
{
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
for (const CNode* pnode : vNodes) {
if (!pnode->fInbound && !pnode->m_manual_connection) {
// Netgroups for inbound and addnode peers are not excluded because our goal here
// is to not use multiple of our limited outbound slots on a single netgroup
@ -2064,7 +2065,7 @@ void CConnman::ThreadMessageHandler()
pnode->Release();
}
std::unique_lock<std::mutex> lock(mutexMsgProc);
WAIT_LOCK(mutexMsgProc, lock);
if (!fMoreWork) {
condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this] { return fMsgProcWake; });
}
@ -2166,7 +2167,7 @@ void Discover()
}
}
}
#else
#elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
// Get local host ip
struct ifaddrs* myaddrs;
if (getifaddrs(&myaddrs) == 0)
@ -2346,7 +2347,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
flagInterruptMsgProc = false;
{
std::unique_lock<std::mutex> lock(mutexMsgProc);
LOCK(mutexMsgProc);
fMsgProcWake = false;
}

View file

@ -427,7 +427,7 @@ private:
bool fMsgProcWake;
std::condition_variable condMsgProc;
std::mutex mutexMsgProc;
Mutex mutexMsgProc;
std::atomic<bool> flagInterruptMsgProc;
CThreadInterrupt interruptNet;
@ -558,6 +558,7 @@ public:
double dPingTime;
double dPingWait;
double dMinPing;
CAmount minFeeFilter;
// Our address, as reported by the peer
std::string addrLocal;
// Address of this peer

View file

@ -70,7 +70,7 @@ struct COrphanTx {
NodeId fromPeer;
int64_t nTimeExpire;
};
static CCriticalSection g_cs_orphans;
CCriticalSection g_cs_orphans;
std::map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(g_cs_orphans);
void EraseOrphansFor(NodeId peer);
@ -442,7 +442,7 @@ static void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) EXCLUSIV
* lNodesAnnouncingHeaderAndIDs, and keeping that list under a certain size by
* removing the first element if necessary.
*/
static void MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid, CConnman* connman)
static void MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid, CConnman* connman) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);
CNodeState* nodestate = State(nodeid);
@ -831,7 +831,7 @@ void Misbehaving(NodeId pnode, int howmuch, const std::string& message) EXCLUSIV
// active chain if they are no more than a month older (both in time, and in
// best equivalent proof of work) than the best header chain we know about and
// we fully-validated them at some point.
static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams)
static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);
if (chainActive.Contains(pindex)) return true;
@ -882,7 +882,7 @@ void PeerLogicValidation::BlockConnected(const std::shared_ptr<const CBlock>& pb
// Erase orphan transactions included or precluded by this block
if (vOrphanErase.size()) {
int nErased = 0;
for (uint256 &orphanHash : vOrphanErase) {
for (const uint256& orphanHash : vOrphanErase) {
nErased += EraseOrphanTx(orphanHash);
}
LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx included or conflicted by block\n", nErased);
@ -1260,7 +1260,7 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
}
}
void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnman* connman, const std::atomic<bool>& interruptMsgProc)
void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnman* connman, const std::atomic<bool>& interruptMsgProc) LOCKS_EXCLUDED(cs_main)
{
AssertLockNotHeld(cs_main);
@ -1618,8 +1618,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
return true;
}
else if (strCommand == NetMsgType::VERSION)
{
if (strCommand == NetMsgType::VERSION) {
// Each connection can only send one version message
if (pfrom->nVersion != 0)
{
@ -1662,8 +1661,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
return false;
}
if (nVersion < MIN_PEER_PROTO_VERSION)
{
if (nVersion < MIN_PEER_PROTO_VERSION) {
// disconnect from peers older than this proto version
LogPrint(BCLog::NET, "peer=%d using obsolete version %i; disconnecting\n", pfrom->GetId(), nVersion);
if (enable_bip61) {
@ -1674,8 +1672,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
return false;
}
if (nVersion == 10300)
nVersion = 300;
if (!vRecv.empty())
vRecv >> addrFrom >> nNonce;
if (!vRecv.empty()) {
@ -1796,9 +1792,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
return true;
}
else if (pfrom->nVersion == 0)
{
if (pfrom->nVersion == 0) {
// Must have a version message before anything else
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 1);
@ -1842,18 +1836,17 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion));
}
pfrom->fSuccessfullyConnected = true;
return true;
}
else if (!pfrom->fSuccessfullyConnected)
{
if (!pfrom->fSuccessfullyConnected) {
// Must have a verack message before anything else
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 1);
return false;
}
else if (strCommand == NetMsgType::ADDR)
{
if (strCommand == NetMsgType::ADDR) {
std::vector<CAddress> vAddr;
vRecv >> vAddr;
@ -1900,16 +1893,16 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
pfrom->fGetAddr = false;
if (pfrom->fOneShot)
pfrom->fDisconnect = true;
return true;
}
else if (strCommand == NetMsgType::SENDHEADERS)
{
if (strCommand == NetMsgType::SENDHEADERS) {
LOCK(cs_main);
State(pfrom->GetId())->fPreferHeaders = true;
return true;
}
else if (strCommand == NetMsgType::SENDCMPCT)
{
if (strCommand == NetMsgType::SENDCMPCT) {
bool fAnnounceUsingCMPCTBLOCK = false;
uint64_t nCMPCTBLOCKVersion = 0;
vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
@ -1929,11 +1922,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
State(pfrom->GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1);
}
}
return true;
}
else if (strCommand == NetMsgType::INV)
{
if (strCommand == NetMsgType::INV) {
std::vector<CInv> vInv;
vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ)
@ -1987,11 +1979,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
}
}
}
return true;
}
else if (strCommand == NetMsgType::GETDATA)
{
if (strCommand == NetMsgType::GETDATA) {
std::vector<CInv> vInv;
vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ)
@ -2009,11 +2000,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
ProcessGetData(pfrom, chainparams, connman, interruptMsgProc);
return true;
}
else if (strCommand == NetMsgType::GETBLOCKS)
{
if (strCommand == NetMsgType::GETBLOCKS) {
CBlockLocator locator;
uint256 hashStop;
vRecv >> locator >> hashStop;
@ -2078,11 +2068,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
break;
}
}
return true;
}
else if (strCommand == NetMsgType::GETBLOCKTXN)
{
if (strCommand == NetMsgType::GETBLOCKTXN) {
BlockTransactionsRequest req;
vRecv >> req;
@ -2128,11 +2117,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
assert(ret);
SendBlockTransactions(block, req, pfrom, connman);
return true;
}
else if (strCommand == NetMsgType::GETHEADERS)
{
if (strCommand == NetMsgType::GETHEADERS) {
CBlockLocator locator;
uint256 hashStop;
vRecv >> locator >> hashStop;
@ -2196,11 +2184,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// in the SendMessages logic.
nodestate->pindexBestHeaderSent = pindex ? pindex : chainActive.Tip();
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::HEADERS, vHeaders));
return true;
}
else if (strCommand == NetMsgType::TX)
{
if (strCommand == NetMsgType::TX) {
// Stop processing the transaction early if
// We are in blocks only mode and peer is either not whitelisted or whitelistrelay is off
if (!fRelayTxes && (!pfrom->fWhitelisted || !gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)))
@ -2301,7 +2288,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
}
}
for (uint256 hash : vEraseQueue)
for (const uint256& hash : vEraseQueue)
EraseOrphanTx(hash);
}
else if (fMissingInputs)
@ -2384,10 +2371,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
Misbehaving(pfrom->GetId(), nDoS);
}
}
return true;
}
else if (strCommand == NetMsgType::CMPCTBLOCK && !fImporting && !fReindex) // Ignore blocks received while importing
if (strCommand == NetMsgType::CMPCTBLOCK && !fImporting && !fReindex) // Ignore blocks received while importing
{
CBlockHeaderAndShortTxIDs cmpctblock;
vRecv >> cmpctblock;
@ -2605,10 +2592,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
MarkBlockAsReceived(pblock->GetHash());
}
}
return true;
}
else if (strCommand == NetMsgType::BLOCKTXN && !fImporting && !fReindex) // Ignore blocks received while importing
if (strCommand == NetMsgType::BLOCKTXN && !fImporting && !fReindex) // Ignore blocks received while importing
{
BlockTransactions resp;
vRecv >> resp;
@ -2680,10 +2667,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
mapBlockSource.erase(pblock->GetHash());
}
}
return true;
}
else if (strCommand == NetMsgType::HEADERS && !fImporting && !fReindex) // Ignore headers received while importing
if (strCommand == NetMsgType::HEADERS && !fImporting && !fReindex) // Ignore headers received while importing
{
std::vector<CBlockHeader> headers;
@ -2708,7 +2695,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
return ProcessHeadersMessage(pfrom, connman, headers, chainparams, should_punish);
}
else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing
if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing
{
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
vRecv >> *pblock;
@ -2734,11 +2721,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
LOCK(cs_main);
mapBlockSource.erase(pblock->GetHash());
}
return true;
}
else if (strCommand == NetMsgType::GETADDR)
{
if (strCommand == NetMsgType::GETADDR) {
// This asymmetric behavior for inbound and outbound connections was introduced
// to prevent a fingerprinting attack: an attacker can send specific fake addresses
// to users' AddrMan and later request them by sending getaddr messages.
@ -2762,11 +2748,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
FastRandomContext insecure_rand;
for (const CAddress &addr : vAddr)
pfrom->PushAddress(addr, insecure_rand);
return true;
}
else if (strCommand == NetMsgType::MEMPOOL)
{
if (strCommand == NetMsgType::MEMPOOL) {
if (!(pfrom->GetLocalServices() & NODE_BLOOM) && !pfrom->fWhitelisted)
{
LogPrint(BCLog::NET, "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->GetId());
@ -2783,11 +2768,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
LOCK(pfrom->cs_inventory);
pfrom->fSendMempool = true;
return true;
}
else if (strCommand == NetMsgType::PING)
{
if (strCommand == NetMsgType::PING) {
if (pfrom->nVersion > BIP0031_VERSION)
{
uint64_t nonce = 0;
@ -2805,11 +2789,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// return very quickly.
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::PONG, nonce));
}
return true;
}
else if (strCommand == NetMsgType::PONG)
{
if (strCommand == NetMsgType::PONG) {
int64_t pingUsecEnd = nTimeReceived;
uint64_t nonce = 0;
size_t nAvail = vRecv.in_avail();
@ -2862,11 +2845,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
if (bPingFinished) {
pfrom->nPingNonceSent = 0;
}
return true;
}
else if (strCommand == NetMsgType::FILTERLOAD)
{
if (strCommand == NetMsgType::FILTERLOAD) {
CBloomFilter filter;
vRecv >> filter;
@ -2883,11 +2865,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
pfrom->pfilter->UpdateEmptyFull();
pfrom->fRelayTxes = true;
}
return true;
}
else if (strCommand == NetMsgType::FILTERADD)
{
if (strCommand == NetMsgType::FILTERADD) {
std::vector<unsigned char> vData;
vRecv >> vData;
@ -2908,19 +2889,19 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
}
return true;
}
else if (strCommand == NetMsgType::FILTERCLEAR)
{
if (strCommand == NetMsgType::FILTERCLEAR) {
LOCK(pfrom->cs_filter);
if (pfrom->GetLocalServices() & NODE_BLOOM) {
pfrom->pfilter.reset(new CBloomFilter());
}
pfrom->fRelayTxes = true;
return true;
}
else if (strCommand == NetMsgType::FEEFILTER) {
if (strCommand == NetMsgType::FEEFILTER) {
CAmount newFeeFilter = 0;
vRecv >> newFeeFilter;
if (MoneyRange(newFeeFilter)) {
@ -2930,24 +2911,21 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
}
LogPrint(BCLog::NET, "received: feefilter of %s from peer=%d\n", CFeeRate(newFeeFilter).ToString(), pfrom->GetId());
}
return true;
}
else if (strCommand == NetMsgType::NOTFOUND) {
if (strCommand == NetMsgType::NOTFOUND) {
// We do not care about the NOTFOUND message, but logging an Unknown Command
// message would be undesirable as we transmit it ourselves.
return true;
}
else {
// Ignore unknown commands for extensibility
LogPrint(BCLog::NET, "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->GetId());
}
// Ignore unknown commands for extensibility
LogPrint(BCLog::NET, "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->GetId());
return true;
}
static bool SendRejectsAndCheckIfBanned(CNode* pnode, CConnman* connman, bool enable_bip61)
static bool SendRejectsAndCheckIfBanned(CNode* pnode, CConnman* connman, bool enable_bip61) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);
CNodeState &state = *State(pnode->GetId());

View file

@ -15,7 +15,7 @@ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
/** Default number of orphan+recently-replaced txn to keep around for block reconstruction */
static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN = 100;
/** Default for BIP61 (sending reject messages) */
static constexpr bool DEFAULT_ENABLE_BIP61 = true;
static constexpr bool DEFAULT_ENABLE_BIP61{false};
class PeerLogicValidation final : public CValidationInterface, public NetEventsInterface {
private:
@ -61,7 +61,7 @@ public:
bool SendMessages(CNode* pto) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing);
/** Consider evicting an outbound peer based on the amount of time they've been behind our tip */
void ConsiderEviction(CNode *pto, int64_t time_in_seconds);
void ConsiderEviction(CNode *pto, int64_t time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Evict extra outbound peers. If we think our tip may be stale, connect to an extra outbound */
void CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams);
/** If we have extra outbound peers, try to disconnect the one with the oldest block announcement */

View file

@ -17,10 +17,10 @@
#ifndef WIN32
#include <fcntl.h>
#else
#include <codecvt>
#endif
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
#if !defined(MSG_NOSIGNAL)
#define MSG_NOSIGNAL 0
#endif
@ -37,7 +37,7 @@ static const int SOCKS5_RECV_TIMEOUT = 20 * 1000;
static std::atomic<bool> interruptSocks5Recv(false);
enum Network ParseNetwork(std::string net) {
boost::to_lower(net);
Downcase(net);
if (net == "ipv4") return NET_IPV4;
if (net == "ipv6") return NET_IPV6;
if (net == "onion") return NET_ONION;
@ -651,13 +651,13 @@ bool LookupSubNet(const char* pszName, CSubNet& ret)
#ifdef WIN32
std::string NetworkErrorString(int err)
{
char buf[256];
wchar_t buf[256];
buf[0] = 0;
if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
buf, sizeof(buf), nullptr))
buf, ARRAYSIZE(buf), nullptr))
{
return strprintf("%s (%d)", buf, err);
return strprintf("%s (%d)", std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().to_bytes(buf), err);
}
else
{

View file

@ -12,7 +12,9 @@
#include <stdint.h>
#include <string>
static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
#include <boost/signals2/connection.hpp>
bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
{
bool fSecure = style & CClientUIInterface::SECURE;
style &= ~CClientUIInterface::SECURE;
@ -39,19 +41,18 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str
return false;
}
static bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style)
bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style)
{
return noui_ThreadSafeMessageBox(message, caption, style);
}
static void noui_InitMessage(const std::string& message)
void noui_InitMessage(const std::string& message)
{
LogPrintf("init message: %s\n", message);
}
void noui_connect()
{
// Connect bitcoind signal handlers
uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox);
uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion);
uiInterface.InitMessage_connect(noui_InitMessage);

View file

@ -5,6 +5,16 @@
#ifndef BITCOIN_NOUI_H
#define BITCOIN_NOUI_H
extern void noui_connect();
#include <string>
/** Non-GUI handler, which logs and prints messages. */
bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style);
/** Non-GUI handler, which logs and prints questions. */
bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style);
/** Non-GUI handler, which only logs a message. */
void noui_InitMessage(const std::string& message);
/** Connect all bitcoind signal handlers */
void noui_connect();
#endif // BITCOIN_NOUI_H

View file

@ -64,7 +64,7 @@ bool GetAmountFromParentChainPegin(CAmount& amount, const CTransaction& txBTC, u
// return false;
//}
//amount = txBTC.vout[nOut].nValue.GetAmount();
//TODO(rebase) reenable above for CA/CT
//TODO(rebase) re-enable above for CA/CT
amount = txBTC.vout[nOut].nValue;
return true;
}
@ -228,9 +228,10 @@ bool CheckParentProofOfWork(uint256 hash, unsigned int nBits, const Consensus::P
return true;
}
bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& prevout, bool check_depth) {
bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& prevout, std::string& err_msg, bool check_depth) {
// 0) Return false if !consensus.has_parent_chain
if (!Params().GetConsensus().has_parent_chain) {
err_msg = "Parent chain is not enabled on this network.";
return false;
}
@ -249,6 +250,7 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
const std::vector<std::vector<unsigned char> >& stack = pegin_witness.stack;
// Must include all elements
if (stack.size() != 6) {
err_msg = "Not enough stack items.";
return false;
}
@ -257,15 +259,18 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
try {
stream >> value;
} catch (...) {
err_msg = "Could not deserialize value.";
return false;
}
if (!MoneyRange(value)) {
err_msg = "Value was not in valid value range.";
return false;
}
// Get asset type
if (stack[1].size() != 32) {
err_msg = "Asset type was not 32 bytes.";
return false;
}
//TODO(rebase) CA
@ -273,6 +278,7 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
// Get genesis blockhash
if (stack[2].size() != 32) {
err_msg = "Parent genesis blockchaash was not 32 bytes.";
return false;
}
uint256 gen_hash(stack[2]);
@ -280,6 +286,7 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
// Get claim_script, sanity check size
CScript claim_script(stack[3].begin(), stack[3].end());
if (claim_script.size() > 100) {
err_msg = "Claim script is too large.";
return false;
}
@ -290,14 +297,17 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
if (Params().GetConsensus().ParentChainHasPow()) {
Sidechain::Bitcoin::CMerkleBlock merkle_block_pow;
if (!GetBlockAndTxFromMerkleBlock(block_hash, tx_hash, merkle_block_pow, stack[5])) {
err_msg = "Could not extract block and tx from merkleblock.";
return false;
}
if (!CheckParentProofOfWork(block_hash, merkle_block_pow.header.nBits, Params().GetConsensus())) {
err_msg = "Parent proof of work is invalid or insufficient.";
return false;
}
Sidechain::Bitcoin::CTransactionRef pegtx;
if (!CheckPeginTx(stack[4], pegtx, prevout, value, claim_script)) {
err_msg = "Peg-in tx is invalid.";
return false;
}
@ -305,15 +315,18 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
} else {
CMerkleBlock merkle_block;
if (!GetBlockAndTxFromMerkleBlock(block_hash, tx_hash, merkle_block, stack[5])) {
err_msg = "Could not extract block and tx from merkleblock.";
return false;
}
if (!CheckProofSignedParent(merkle_block.header, Params().GetConsensus())) {
err_msg = "Parent signed block is invalid.";
return false;
}
CTransactionRef pegtx;
if (!CheckPeginTx(stack[4], pegtx, prevout, value, claim_script)) {
err_msg = "Peg-in tx is invalid.";
return false;
}
@ -322,11 +335,13 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
// Check that the merkle proof corresponds to the txid
if (prevout.hash != tx_hash) {
err_msg = "Merkle proof and txid mismatch.";
return false;
}
// Check the genesis block corresponds to a valid peg (only one for now)
if (gen_hash != Params().ParentGenesisBlockHash()) {
err_msg = "Parent genesis block mismatch.";
return false;
}
@ -339,6 +354,7 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
// Finally, validate peg-in via rpc call
if (check_depth && gArgs.GetBoolArg("-validatepegin", DEFAULT_VALIDATE_PEGIN)) {
if (!IsConfirmedBitcoinBlock(block_hash, Params().GetConsensus().pegin_min_depth, num_txs)) {
err_msg = "Needs more confirmations.";
return false;
}
}

View file

@ -18,7 +18,7 @@ bool GetAmountFromParentChainPegin(CAmount& amount, const CTransaction& txBTC, u
/** Check whether a parent chain block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckParentProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
/** Checks pegin witness for validity */
bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& prevout, bool check_depth = true);
bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& prevout, std::string& err_msg, bool check_depth);
// Constructs unblinded output to be used in amount and scriptpubkey checks during pegin
CTxOut GetPeginOutputFromWitness(const CScriptWitness& pegin_witness);

View file

@ -22,51 +22,6 @@ class CTxMemPoolEntry;
class CTxMemPool;
class TxConfirmStats;
/** \class CBlockPolicyEstimator
* The BlockPolicyEstimator is used for estimating the feerate needed
* for a transaction to be included in a block within a certain number of
* blocks.
*
* At a high level the algorithm works by grouping transactions into buckets
* based on having similar feerates and then tracking how long it
* takes transactions in the various buckets to be mined. It operates under
* the assumption that in general transactions of higher feerate will be
* included in blocks before transactions of lower feerate. So for
* example if you wanted to know what feerate you should put on a transaction to
* be included in a block within the next 5 blocks, you would start by looking
* at the bucket with the highest feerate transactions and verifying that a
* sufficiently high percentage of them were confirmed within 5 blocks and
* then you would look at the next highest feerate bucket, and so on, stopping at
* the last bucket to pass the test. The average feerate of transactions in this
* bucket will give you an indication of the lowest feerate you can put on a
* transaction and still have a sufficiently high chance of being confirmed
* within your desired 5 blocks.
*
* Here is a brief description of the implementation:
* When a transaction enters the mempool, we track the height of the block chain
* at entry. All further calculations are conducted only on this set of "seen"
* transactions. Whenever a block comes in, we count the number of transactions
* in each bucket and the total amount of feerate paid in each bucket. Then we
* calculate how many blocks Y it took each transaction to be mined. We convert
* from a number of blocks to a number of periods Y' each encompassing "scale"
* blocks. This is tracked in 3 different data sets each up to a maximum
* number of periods. Within each data set we have an array of counters in each
* feerate bucket and we increment all the counters from Y' up to max periods
* representing that a tx was successfully confirmed in less than or equal to
* that many periods. We want to save a history of this information, so at any
* time we have a counter of the total number of transactions that happened in a
* given feerate bucket and the total number that were confirmed in each of the
* periods or less for any bucket. We save this history by keeping an
* exponentially decaying moving average of each one of these stats. This is
* done for a different decay in each of the 3 data sets to keep relevant data
* from different time horizons. Furthermore we also keep track of the number
* unmined (in mempool or left mempool without being included in a block)
* transactions in each bucket and for how many blocks they have been
* outstanding and use both of these numbers to increase the number of transactions
* we've seen in that feerate bucket when calculating an estimate for any number
* of confirmations below the number of blocks they've been outstanding.
*/
/* Identifier for each of the 3 different TxConfirmStats which will track
* history over different time horizons. */
enum class FeeEstimateHorizon {
@ -130,7 +85,50 @@ struct FeeCalculation
int returnedTarget = 0;
};
/**
/** \class CBlockPolicyEstimator
* The BlockPolicyEstimator is used for estimating the feerate needed
* for a transaction to be included in a block within a certain number of
* blocks.
*
* At a high level the algorithm works by grouping transactions into buckets
* based on having similar feerates and then tracking how long it
* takes transactions in the various buckets to be mined. It operates under
* the assumption that in general transactions of higher feerate will be
* included in blocks before transactions of lower feerate. So for
* example if you wanted to know what feerate you should put on a transaction to
* be included in a block within the next 5 blocks, you would start by looking
* at the bucket with the highest feerate transactions and verifying that a
* sufficiently high percentage of them were confirmed within 5 blocks and
* then you would look at the next highest feerate bucket, and so on, stopping at
* the last bucket to pass the test. The average feerate of transactions in this
* bucket will give you an indication of the lowest feerate you can put on a
* transaction and still have a sufficiently high chance of being confirmed
* within your desired 5 blocks.
*
* Here is a brief description of the implementation:
* When a transaction enters the mempool, we track the height of the block chain
* at entry. All further calculations are conducted only on this set of "seen"
* transactions. Whenever a block comes in, we count the number of transactions
* in each bucket and the total amount of feerate paid in each bucket. Then we
* calculate how many blocks Y it took each transaction to be mined. We convert
* from a number of blocks to a number of periods Y' each encompassing "scale"
* blocks. This is tracked in 3 different data sets each up to a maximum
* number of periods. Within each data set we have an array of counters in each
* feerate bucket and we increment all the counters from Y' up to max periods
* representing that a tx was successfully confirmed in less than or equal to
* that many periods. We want to save a history of this information, so at any
* time we have a counter of the total number of transactions that happened in a
* given feerate bucket and the total number that were confirmed in each of the
* periods or less for any bucket. We save this history by keeping an
* exponentially decaying moving average of each one of these stats. This is
* done for a different decay in each of the 3 data sets to keep relevant data
* from different time horizons. Furthermore we also keep track of the number
* unmined (in mempool or left mempool without being included in a block)
* transactions in each bucket and for how many blocks they have been
* outstanding and use both of these numbers to increase the number of transactions
* we've seen in that feerate bucket when calculating an estimate for any number
* of confirmations below the number of blocks they've been outstanding.
*
* We want to be able to estimate feerates that are needed on tx's to be included in
* a certain number of blocks. Every time a block is added to the best chain, this class records
* stats on the transactions included in that block

View file

@ -36,7 +36,7 @@ CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
if (txout.scriptPubKey.IsUnspendable())
return 0;
size_t nSize = GetSerializeSize(txout, SER_DISK, 0);
size_t nSize = GetSerializeSize(txout);
int witnessversion = 0;
std::vector<unsigned char> witnessprogram;
@ -59,12 +59,12 @@ bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
{
std::vector<std::vector<unsigned char> > vSolutions;
if (!Solver(scriptPubKey, whichType, vSolutions))
return false;
whichType = Solver(scriptPubKey, vSolutions);
CChainParams params = Params();
if (whichType == TX_MULTISIG)
{
if (whichType == TX_NONSTANDARD || whichType == TX_WITNESS_UNKNOWN) {
return false;
} else if (whichType == TX_MULTISIG) {
unsigned char m = vSolutions.front()[0];
unsigned char n = vSolutions.back()[0];
// Support up to x-of-3 multisig txns as standard
@ -77,10 +77,11 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
// If we're enforcing pak let through larger peg-out scripts
return true;
} else if (whichType == TX_NULL_DATA &&
(!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes))
(!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) {
return false;
}
return whichType != TX_NONSTANDARD && whichType != TX_WITNESS_UNKNOWN;
return true;
}
bool IsStandardTx(const CTransaction& tx, std::string& reason)
@ -188,14 +189,10 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;
std::vector<std::vector<unsigned char> > vSolutions;
txnouttype whichType;
// get the scriptPubKey corresponding to this input:
const CScript& prevScript = prev.scriptPubKey;
if (!Solver(prevScript, whichType, vSolutions))
txnouttype whichType = Solver(prev.scriptPubKey, vSolutions);
if (whichType == TX_NONSTANDARD) {
return false;
if (whichType == TX_SCRIPTHASH)
{
} else if (whichType == TX_SCRIPTHASH) {
std::vector<std::vector<unsigned char> > stack;
// convert the scriptSig into a stack, so we can inspect the redeemScript
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE))

Some files were not shown because too many files have changed in this diff Show more