From 06ec5681600b483ba9986414f74cdbe6f28d60d4 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sat, 19 Jan 2019 09:09:17 +0000 Subject: [PATCH 01/49] Protocol and Transifex updates --- .tx/config | 7 + dash-docs/protocol-documentation.md | 349 ++++++++++++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 .tx/config create mode 100644 dash-docs/protocol-documentation.md diff --git a/.tx/config b/.tx/config new file mode 100644 index 0000000000000..aab35abf48af3 --- /dev/null +++ b/.tx/config @@ -0,0 +1,7 @@ +[main] +host = https://www.transifex.com + +[absolute.qt-translation-012x] +file_filter = src/qt/locale/absolute_.ts +source_file = src/qt/locale/absolute_en.ts +source_lang = en diff --git a/dash-docs/protocol-documentation.md b/dash-docs/protocol-documentation.md new file mode 100644 index 0000000000000..ba3cb32dc1ff1 --- /dev/null +++ b/dash-docs/protocol-documentation.md @@ -0,0 +1,349 @@ +Protocol Documentation - 0.12.1 +===================================== + +This document describes the protocol extensions for all additional functionality build into the Dash protocol. This doesn't include any of the Bitcoin protocol, which has been left intact in the Dash project. For more information about the core protocol, please see https://en.bitcoin.it/w/index.php?title#Protocol_documentation&action#edit + +## Common Structures + +### Simple types + +uint256 => char[32] + +CScript => uchar[] + +### COutPoint + +Bitcoin Outpoint https://bitcoin.org/en/glossary/outpoint + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 32 | hash | uint256 | Hash of transactional output which is being referenced +| 4 | n | uint32_t | Index of transaction which is being referenced + + +### CTxIn + +Bitcoin Input https://bitcoin.org/en/glossary/input + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 36 | prevout | [COutPoint](#coutpoint) | The previous output from an existing transaction, in the form of an unspent output +| 1+ | script length | var_int | The length of the signature script +| ? | script | CScript | The script which is validated for this input to be spent +| 4 | nSequence | uint_32t | Transaction version as defined by the sender. Intended for "replacement" of transactions when information is updated before inclusion into a block. + +### CTxOut + +Bitcoin Output https://bitcoin.org/en/glossary/output + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 8 | nValue | int64_t | Transfered value +| ? | scriptPubKey | CScript | The script for indicating what conditions must be fulfilled for this output to be further spent + +### CTransaction + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 4 | nVersion | int32_t | Transaction data format version +| 1+ | tx_in count | var_int | Number of Transaction inputs +| 41+ | vin | [CTxIn](#ctxin) | A list of 1 or more transaction inputs +| 1+ | tx_out count | var_int | Number of Transaction outputs +| 9+ | vout | [CTxOut](#ctxout) | A list of 1 or more transaction outputs +| 4 | nLockTime | uint32_t | The block number or timestamp at which this transaction is unlocked + +### CPubKey + +Bitcoin Public Key https://bitcoin.org/en/glossary/public-key + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 33-65 | vch | char[] | The public portion of a keypair which can be used to verify signatures made with the private portion of the keypair. + +### CService + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 16 | IP | CNetAddr | IP Address +| 2 | Port | uint16 | IP Port + +## Message Types + +### MNANNOUNCE - "mnb" + +CMasternodeBroadcast + +Whenever a masternode comes online or a client is syncing, they will send this message which describes the masternode entry and how to validate messages from it. + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 41 | vin | [CTxIn](#ctxin) | The unspent output which is holding 1000 DASH +| # | addr | [CService](#cservice) | IPv4 address of the masternode +| 33-65 | pubKeyCollateralAddress | [CPubKey](#cpubkey) | CPubKey of the main 1000 DASH unspent output +| 33-65 | pubKeyMasternode | [CPubKey](#cpubkey) | CPubKey of the secondary signing key (For all other messaging other than announce message) +| 71-73 | sig | char[] | Signature of this message (verifiable via pubKeyCollateralAddress) +| 8 | sigTime | int64_t | Time which the signature was created +| 4 | nProtocolVersion | int | The protocol version of the masternode +| # | lastPing | CMasternodePing | The last known ping of the masternode +| 8 | nLastDsq | int64_t | The last time the masternode sent a DSQ message (for mixing) (DEPRECATED) + +### MNPING - "mnp" + +CMasternodePing + +Every few minutes, masternodes ping the network with a message that propagates the whole network. + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 41 | vin | [CTxIn](#ctxin) | The unspent output of the masternode which is signing the message +| 32 | blockHash | uint256 | Current chaintip blockhash minus 12 +| 8 | sigTime | int64_t | Signature time for this ping +| 71-73 | vchSig | char[] | Signature of this message by masternode (verifiable via pubKeyMasternode) + +### MASTERNODEPAYMENTVOTE - "mnw" + +CMasternodePaymentVote + +When a new block is found on the network, a masternode quorum will be determined and those 10 selected masternodes will issue a masternode payment vote message to pick the next winning node. + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 41 | vinMasternode | [CTxIn](#ctxin) | The unspent output of the masternode which is signing the message +| 4 | nBlockHeight | int | The blockheight which the payee should be paid +| ? | payeeAddress | CScript | The address to pay to +| 71-73 | sig | char[] | Signature of the masternode which is signing the message + +### DSTX - "dstx" + +CDarksendBroadcastTx + +Masternodes can broadcast subsidised transactions without fees for the sake of security in mixing. This is done via the DSTX message. + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| # | tx | [CTransaction](#ctransaction) | The transaction +| 41 | vin | [CTxIn](#ctxin) | Masternode unspent output +| 71-73 | vchSig | char[] | Signature of this message by masternode (verifiable via pubKeyMasternode) +| 8 | sigTime | int64_t | Time this message was signed + +### DSSTATUSUPDATE - "dssu" + +Mixing pool status update + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 4 | nMsgSessionID | int | Session ID +| 4 | nMsgState | int | Current state of mixing process +| 4 | nMsgEntriesCount | int | Number of entries in the mixing pool +| 4 | nMsgStatusUpdate | int | Update state and/or signal if entry was accepted or not +| 4 | nMsgMessageID | int | ID of the typical masternode reply message + +### DSQUEUE - "dsq" + +CDarksendQueue + +Asks users to sign final mixing tx message. + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 4 | nDenom | int | Which denomination is allowed in this mixing session +| 41 | vin | [CTxIn](#ctxin) | unspend output from masternode which is hosting this session +| 8 | nTime | int64_t | the time this DSQ was created +| 1 | fReady | bool | if the mixing pool is ready to be executed +| 66 | vchSig | char[] | Signature of this message by masternode (verifiable via pubKeyMasternode) + +### DSACCEPT - "dsa" + +Response to DSQ message which allows the user to join a mixing pool + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 4 | nDenom | int | denomination that will be exclusively used when submitting inputs into the pool +| 41+ | txCollateral | int | collateral tx that will be charged if this client acts maliciousely + +### DSVIN - "dsi" + +CDarkSendEntry + +When queue is ready user is expected to send his entry to start actual mixing + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| ? | vecTxDSIn | CTxDSIn[] | vector of users inputs (CTxDSIn serialization is equal to [CTxIn](#ctxin) serialization) +| 8 | nAmount | int64_t | depreciated since 12.1, it's used for backwards compatibility only and can be removed with future protocol bump +| ? | txCollateral | [CTransaction](#ctransaction) | Collateral transaction which is used to prevent misbehavior and also to charge fees randomly +| ? | vecTxOut | CTxOut[] | vector of user outputs + +### DSSIGNFINALTX - "dss" + +User's signed inputs for a group transaction in a mixing session + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| # | inputs | [CTxIn](#ctxin)[] | signed inputs for mixing session + + +### TXLOCKREQUEST - "ix" + +CTxLockRequest + +Transaction Lock Request, serialization is the same as for [CTransaction](#ctransaction). + +### TXLOCKVOTE - "txlvote" + +CTxLockVote + +Transaction Lock Vote + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 32 | txHash | uint256 | txid of the transaction to lock +| 36 | outpoint | [COutPoint](#coutpoint) | The utxo to lock in this transaction +| 36 | outpointMasternode | [COutPoint](#coutpoint) | The utxo of the masternode which is signing the vote +| 71-73 | vchMasternodeSignature | char[] | Signature of this message by masternode (verifiable via pubKeyMasternode) + +### MNGOVERNANCEOBJECT - "govobj" + +Governance Object + +A proposal, contract or setting. + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 32 | nHashParent | uint256 | Parent object, 0 is root +| 4 | nRevision | int | Object revision in the system +| 8 | nTime | int64_t | Time which this object was created +| 32 | nCollateralHash | uint256 | Hash of the collateral fee transaction +| 0-16384 | strData | string | Data field - can be used for anything +| 4 | nObjectType | int | ???? +| 41 | vinMasternode | [CTxIn](#ctxin) | Unspent output for the masternode which is signing this object +| 66* | vchSig | char[] | Signature of the masternode (unclear if 66 is the correct size, but this is what it appears to be in most cases) + +### MNGOVERNANCEOBJECTVOTE - "govobjvote" + +Governance Vote + +Masternodes use governance voting in response to new proposals, contracts, settings or finalized budgets. + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 41+ | vinMasternode | [CTxIn](#ctxin) | Unspent output for the masternode which is voting +| 32 | nParentHash | uint256 | Object which we're voting on (proposal, contract, setting or final budget) +| 4 | nVoteOutcome | int | ??? +| 4 | nVoteSignal | int | ??? +| 8 | nTime | int64_t | Time which the vote was created +| 66* | vchSig | char[] | Signature of the masternode (unclear if 66 is the correct size, but this is what it appears to be in most cases) + +### SPORK - "spork" + +Spork + +Spork + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 4 | nSporkID | int | +| 8 | nValue | int64_t | +| 8 | nTimeSigned | int64_t | +| 66* | vchSig | char[] | Unclear if 66 is the correct size, but this is what it appears to be in most cases + +#### Defined Sporks (per src/sporks.h) + +| Spork ID | Number | Name | Description | +| ---------- | ---------- | ----------- | ----------- | +| 10001 | 2 | INSTANTSEND_ENABLED | Turns on and off InstantSend network wide +| 10002 | 3 | INSTANTSEND_BLOCK_FILTERING | Turns on and off InstantSend block filtering +| 10004 | 5 | INSTANTSEND_MAX_VALUE | Controls the max value for an InstantSend transaction (currently 2000 dash) +| 10007 | 8 | MASTERNODE_PAYMENT_ENFORCEMENT | Requires masternodes to be paid by miners when blocks are processed +| 10008 | 9 | SUPERBLOCKS_ENABLED | Superblocks are enabled (the 10% comes to fund the dash treasury) +| 10009 | 10 | MASTERNODE_PAY_UPDATED_NODES | Only current protocol version masternode's will be paid (not older nodes) +| 10011 | 12 | RECONSIDER_BLOCKS | +| 10012 | 13 | OLD_SUPERBLOCK_FLAG | +| 10013 | 14 | REQUIRE_SENTINEL_FLAG | Only masternode's running sentinel will be paid + +## Undocumented messages + +### MASTERNODEPAYMENTBLOCK - "mnwb" + +Masternode Payment Block + +*NOTE: Per src/protocol.cpp, there is no message for this (only inventory)* + +### MNVERIFY - "mnv" + +Masternode Verify + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 41 | vin1 | [CTxIn](#ctxin) | The unspent output which is holding 1000 DASH for masternode 1 +| 41 | vin2 | [CTxIn](#ctxin) | The unspent output which is holding 1000 DASH for masternode 2 +| # | addr | [CService](#cservice) | IPv4 address / port of the masternode +| 4 | nonce | int | Nonce +| 4 | nBlockHeight | int | The blockheight +| 66* | vchSig1 | char[] | Signature of by masternode 1 (unclear if 66 is the correct size, but this is what it appears to be in most cases) +| 66* | vchSig2 | char[] | Signature of by masternode 2 (unclear if 66 is the correct size, but this is what it appears to be in most cases) + +### DSFINALTX - "dsf" + +Darksend Final Transaction + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 4 | nSessionID | int | +| # | txFinal | [CTransaction](#ctransaction) | Final mixing transaction + +### DSCOMPLETE - "dsc" + +Darksend Complete + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 4 | nSessionID | int | +| 4 | nMessageID | int | + +### MNGOVERNANCESYNC - "govsync" + +Governance Sync + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 32 | nHash | uint256 | +| # | filter | CBloomFilter | + +### DSEG - "dseg" + +Masternode List/Entry Sync + +Get Masternode list or specific entry + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 41 | vin | [CTxIn](#ctxin) | The unspent output which is holding 1000 DASH + +### SYNCSTATUSCOUNT - "ssc" + +Sync Status Count + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 4 | nItemID | int | Masternode Sync Item ID +| 4 | nCount | int | Masternode Sync Count + +#### Defined Sync Item IDs (per src/masternode-sync.h) + +| Item ID | Name | Description | +| ---------- | ---------- | ----------- | +| 2 | MASTERNODE_SYNC_LIST | +| 3 | MASTERNODE_SYNC_MNW | +| 4 | MASTERNODE_SYNC_GOVERNANCE | +| 10 | MASTERNODE_SYNC_GOVOBJ | +| 11 | MASTERNODE_SYNC_GOVOBJ_VOTE | + +### MASTERNODEPAYMENTSYNC - "mnget" + +Masternode Payment Sync + +| Field Size | Field Name | Data type | Description | +| ---------- | ----------- | --------- | -------- | +| 4 | nMnCount | int | + From 3778d515a4bc8a316cf882ba9ca59af13d2b044b Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sat, 19 Jan 2019 09:12:21 +0000 Subject: [PATCH 02/49] Ignore files in gitignore Ignore split-debug.sh Add additional file sets --- .gitignore | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 133 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 04559e952097e..2247255edc0bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,135 @@ +*.sublime-project +*.sublime-workspace +todo.txt +reset-files.bash -object_script..Release -object_script..Debug -Makefile.Release -Makefile.Debug +*.tar.gz + +*.exe +src/absolute +src/absoluted +src/absolute-cli +src/absolute-tx +src/test/test_absolute +src/qt/test/test_absolute-qt +src/bench/bench_absolute + +# autoreconf +Makefile.in +aclocal.m4 +autom4te.cache/ +build-aux/config.guess +build-aux/config.sub +build-aux/depcomp +build-aux/install-sh +build-aux/ltmain.sh +build-aux/m4/libtool.m4 +build-aux/m4/lt~obsolete.m4 +build-aux/m4/ltoptions.m4 +build-aux/m4/ltsugar.m4 +build-aux/m4/ltversion.m4 +build-aux/missing +build-aux/compile +build-aux/test-driver +config.log +config.status +configure +libtool +src/config/absolute-config.h +src/config/absolute-config.h.in +src/config/stamp-h1 +share/setup.nsi +share/qt/Info.plist + +src/univalue/gen + +src/qt/*.moc +src/qt/moc_*.cpp +src/qt/forms/ui_*.h + +src/qt/test/moc*.cpp +libconftest.dylib* + +.deps +.dirstamp +.libs +.*.swp +*.*~* +*.bak +*.rej +*.orig +*.pyc +*.o +*.o-* +*.patch +.absolute +*.a +*.pb.cc +*.pb.h + +*.log +*.trs +*.dmg + +*.json.h +*.raw.h + +#libtool object files +*.lo +*.la + +# Compilation and Qt preprocessor part +*.qm Makefile -Makefile.Release -Makefile.Release +absolute-qt +Absolute-Qt.app + +# Unit-tests +Makefile.test +absolute-qt_test +src/test/buildenv.py + +# Resources cpp +qrc_*.cpp + +# Mac specific +.DS_Store +build + +#lcov +*.gcno +*.gcda +/*.info +test_absolute.coverage/ +total.coverage/ +coverage_percent.txt + +#build tests +linux-coverage-build +linux-build +win32-build +qa/pull-tester/run-bitcoind-for-test.sh +qa/pull-tester/tests_config.py +qa/pull-tester/cache/* +qa/pull-tester/test.*/* +qa/tmp +cache/ +share/BitcoindComparisonTool.jar + +!src/leveldb*/Makefile + +.cproject +.project +.autotools +/doc/doxygen/ + +libabsoluteconsensus.pc +contrib/devtools/split-debug.sh +src/qt/absolute-qt.bash +qa/pull-tester/tests-config.sh + +#development symlinks +absolute-cli +absoluted +absolute-qt +make From bb20ca3f11feeae8f2c94a7b3adf1af61098a526 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sat, 19 Jan 2019 09:21:48 +0000 Subject: [PATCH 03/49] Gitian set correct PATH for wrappers fa61756 [gitian] set correct PATH for wrappers (MarcoFalke) --- contrib/gitian-descriptors/gitian-linux.yml | 5 ++++- contrib/gitian-descriptors/gitian-osx.yml | 5 ++++- contrib/gitian-descriptors/gitian-win.yml | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index ff7e5c9f899e3..4291b78b72cc4 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -81,10 +81,11 @@ script: | done done } - export PATH=${WRAP_DIR}:${PATH} # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} cd absolute chmod 777 depends/config.sub @@ -96,8 +97,10 @@ script: | done # Faketime for binaries + export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host chmod 777 ./autogen.sh ./autogen.sh diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 2a07578e7f6ee..040cafeb431bf 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -76,10 +76,11 @@ script: | done done } - export PATH=${WRAP_DIR}:${PATH} # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} cd absolute BASEPREFIX=`pwd`/depends @@ -92,8 +93,10 @@ script: | make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done # Faketime for binaries + export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host ./autogen.sh diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 2cc72ee83ce70..310e081510749 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -94,12 +94,13 @@ script: | done } - export PATH=${WRAP_DIR}:${PATH} # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" create_per-host_linker_wrapper "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} cd absolute chmod 777 depends/config.sub chmod 777 depends/config.guess @@ -110,9 +111,11 @@ script: | done # Faketime for binaries + export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_linker_wrapper "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host chmod 777 ./autogen.sh ./autogen.sh From 5fe07706f2a05e87692632eadef82315807b2c5d Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sat, 19 Jan 2019 09:40:44 +0000 Subject: [PATCH 04/49] Sync ax_pthread with upstream draft4 0e209f9 [trivial] Sync ax_pthread with upstream draft (fanquake) --- build-aux/m4/ax_pthread.m4 | 550 ++++++++++++++++++------------------- 1 file changed, 275 insertions(+), 275 deletions(-) diff --git a/build-aux/m4/ax_pthread.m4 b/build-aux/m4/ax_pthread.m4 index d218d1af73817..4c4051ea376f7 100644 --- a/build-aux/m4/ax_pthread.m4 +++ b/build-aux/m4/ax_pthread.m4 @@ -82,7 +82,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 22 +#serial 23 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ @@ -100,22 +100,22 @@ ax_pthread_ok=no # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then - ax_pthread_save_CC="$CC" - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) - AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) - AC_MSG_RESULT([$ax_pthread_ok]) - if test "x$ax_pthread_ok" = "xno"; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - CC="$ax_pthread_save_CC" - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -152,50 +152,50 @@ ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread -- case $host_os in - freebsd*) + freebsd*) - # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) - # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) - ax_pthread_flags="-kthread lthread $ax_pthread_flags" - ;; + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; - hpux*) + hpux*) - # From the cc(1) man page: "[-mt] Sets various -D flags to enable - # multi-threading and also sets -lpthread." + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." - ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" - ;; + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; - openedition*) + openedition*) - # IBM z/OS requires a feature-test macro to be defined in order to - # enable POSIX threads at all, so give the user a hint if this is - # not set. (We don't define these ourselves, as they can affect - # other portions of the system API in unpredictable ways.) + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) - AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], - [ -# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) - AX_PTHREAD_ZOS_MISSING -# endif - ], - [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) - ;; + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; - solaris*) + solaris*) - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (N.B.: The stubs are missing - # pthread_cleanup_push, or rather a function called by this macro, - # so we could check for that, but who knows whether they'll stub - # that too in a future libc.) So we'll check first for the - # standard Solaris way of linking pthreads (-mt -lpthread). + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). - ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" - ;; + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; esac # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) @@ -208,17 +208,17 @@ AS_IF([test "x$GCC" = "xyes"], # correctly enabled case $host_os in - darwin* | hpux* | linux* | osf* | solaris*) - ax_pthread_check_macro="_REENTRANT" - ;; + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; - aix* | freebsd*) - ax_pthread_check_macro="_THREAD_SAFE" - ;; + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; - *) - ax_pthread_check_macro="--" - ;; + *) + ax_pthread_check_macro="--" + ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], @@ -231,13 +231,13 @@ AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then - AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], - [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ -# if defined(__clang__) && defined(__llvm__) - AX_PTHREAD_CC_IS_CLANG -# endif - ], - [ax_cv_PTHREAD_CLANG=yes]) + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" @@ -249,222 +249,222 @@ ax_pthread_clang_warning=no if test "x$ax_pthread_clang" = "xyes"; then - # Clang takes -pthread; it has never supported any other flag - - # (Note 1: This will need to be revisited if a system that Clang - # supports has POSIX threads in a separate library. This tends not - # to be the way of modern systems, but it's conceivable.) - - # (Note 2: On some systems, notably Darwin, -pthread is not needed - # to get POSIX threads support; the API is always present and - # active. We could reasonably leave PTHREAD_CFLAGS empty. But - # -pthread does define _REENTRANT, and while the Darwin headers - # ignore this macro, third-party headers might not.) - - PTHREAD_CFLAGS="-pthread" - PTHREAD_LIBS= - - ax_pthread_ok=yes - - # However, older versions of Clang make a point of warning the user - # that, in an invocation where only linking and no compilation is - # taking place, the -pthread option has no effect ("argument unused - # during compilation"). They expect -pthread to be passed in only - # when source code is being compiled. - # - # Problem is, this is at odds with the way Automake and most other - # C build frameworks function, which is that the same flags used in - # compilation (CFLAGS) are also used in linking. Many systems - # supported by AX_PTHREAD require exactly this for POSIX threads - # support, and in fact it is often not straightforward to specify a - # flag that is used only in the compilation phase and not in - # linking. Such a scenario is extremely rare in practice. - # - # Even though use of the -pthread flag in linking would only print - # a warning, this can be a nuisance for well-run software projects - # that build with -Werror. So if the active version of Clang has - # this misfeature, we search for an option to squash it. - - AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown - # Create an alternate version of $ac_link that compiles and - # links in two steps (.c -> .o, .o -> exe) instead of one - # (.c -> exe), because the warning occurs only in the second - # step - ax_pthread_save_ac_link="$ac_link" - ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' - ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` - ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" - ax_pthread_save_CFLAGS="$CFLAGS" - for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do - AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) - CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" - ac_link="$ax_pthread_save_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [ac_link="$ax_pthread_2step_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [break]) - ]) - done - ac_link="$ax_pthread_save_ac_link" - CFLAGS="$ax_pthread_save_CFLAGS" - AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) - ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" - ]) - - case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in - no | unknown) ;; - *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; - esac + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac fi # $ax_pthread_clang = yes if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do - case $ax_pthread_try_flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -mt,pthread) - AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) - PTHREAD_CFLAGS="-mt" - PTHREAD_LIBS="-lpthread" - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) - PTHREAD_CFLAGS="$ax_pthread_try_flag" - ;; - - pthread-config) - AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - - *) - AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) - PTHREAD_LIBS="-l$ax_pthread_try_flag" - ;; - esac - - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include -# if $ax_pthread_check_cond -# error "$ax_pthread_check_macro must be defined" -# endif - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) - - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" - - AC_MSG_RESULT([$ax_pthread_ok]) - AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -mt,pthread) + AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_CACHE_CHECK([for joinable pthread attribute], - [ax_cv_PTHREAD_JOINABLE_ATTR], - [ax_cv_PTHREAD_JOINABLE_ATTR=unknown - for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $ax_pthread_attr; return attr /* ; */])], - [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], - []) - done - ]) - AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ - test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ - test "x$ax_pthread_joinable_attr_defined" != "xyes"], - [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], - [$ax_cv_PTHREAD_JOINABLE_ATTR], - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - ax_pthread_joinable_attr_defined=yes - ]) - - AC_CACHE_CHECK([whether more special flags are required for pthreads], - [ax_cv_PTHREAD_SPECIAL_FLAGS], - [ax_cv_PTHREAD_SPECIAL_FLAGS=no - case $host_os in - solaris*) - ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" - ;; - esac - ]) - AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ - test "x$ax_pthread_special_flags_added" != "xyes"], - [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" - ax_pthread_special_flags_added=yes]) - - AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - [ax_cv_PTHREAD_PRIO_INHERIT], - [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) - ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ - test "x$ax_pthread_prio_inherit_defined" != "xyes"], - [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) - ax_pthread_prio_inherit_defined=yes - ]) - - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" - - # More AIX lossage: compile with *_r variant - if test "x$GCC" != "xyes"; then - case $host_os in - aix*) - AS_CASE(["x/$CC"], - [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], - [#handle absolute path differently from PATH based program lookup - AS_CASE(["x$CC"], - [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) - ;; - esac - fi + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" @@ -475,11 +475,11 @@ AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then - ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) - : + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : else - ax_pthread_ok=no - $2 + ax_pthread_ok=no + $2 fi AC_LANG_POP ])dnl AX_PTHREAD From 2a9f118324304a65a294df39f413c98070c44dbb Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:04:23 +0000 Subject: [PATCH 05/49] Add bitcoin address label to request payment QR code 1c2a1ba Add address label to request payment QR Code (QT) (Francesco 'makevoid' Canessa) --- src/qt/forms/receiverequestdialog.ui | 2 +- src/qt/receiverequestdialog.cpp | 22 +++++++++++++++++----- src/qt/receiverequestdialog.h | 1 + 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/qt/forms/receiverequestdialog.ui b/src/qt/forms/receiverequestdialog.ui index 4fa906469eeaa..224812a196ee2 100644 --- a/src/qt/forms/receiverequestdialog.ui +++ b/src/qt/forms/receiverequestdialog.ui @@ -27,7 +27,7 @@ 300 - 300 + 320 diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 94de6b23d246b..628a82bf37468 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -45,7 +45,7 @@ QImage QRImageWidget::exportImage() { if(!pixmap()) return QImage(); - return pixmap()->toImage().scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE); + return pixmap()->toImage(); } void QRImageWidget::mousePressEvent(QMouseEvent *event) @@ -167,20 +167,32 @@ void ReceiveRequestDialog::update() ui->lblQRCode->setText(tr("Error encoding URI into QR Code.")); return; } - QImage myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); - myImage.fill(0xffffff); + QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + qrImage.fill(0xffffff); unsigned char *p = code->data; for (int y = 0; y < code->width; y++) { for (int x = 0; x < code->width; x++) { - myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); p++; } } QRcode_free(code); - ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300)); + QImage qrAddrImage = QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE+20, QImage::Format_RGB32); + qrAddrImage.fill(0xffffff); + QPainter painter(&qrAddrImage); + painter.drawImage(0, 0, qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE)); + QFont font = GUIUtil::fixedPitchFont(); + font.setPixelSize(12); + painter.setFont(font); + QRect paddedRect = qrAddrImage.rect(); + paddedRect.setHeight(QR_IMAGE_SIZE+12); + painter.drawText(paddedRect, Qt::AlignBottom|Qt::AlignCenter, info.address); + painter.end(); + + ui->lblQRCode->setPixmap(QPixmap::fromImage(qrAddrImage)); ui->btnSaveAs->setEnabled(true); } } diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 4cab4caff1ace..676745a858f6c 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -10,6 +10,7 @@ #include #include #include +#include class OptionsModel; From b509a98053fcff4cf9aea68258f7ad4d4002a754 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:08:07 +0000 Subject: [PATCH 06/49] Add a link in about to Repo and website Add website links to about dialog --- src/init.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 303a5deb318af..b16264deb0cc5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -590,11 +590,20 @@ std::string HelpMessage(HelpMessageMode mode) std::string LicenseInfo() { + const std::string URL_SOURCE_CODE = ""; + const std::string URL_WEBSITE = ""; // todo: remove urls from translations on next change return CopyrightHolders(_("Copyright (C)"), 2019, COPYRIGHT_YEAR) + "\n" + "\n" + - _("This is experimental software.") + "\n" + + strprintf(_("Please contribute if you find %s useful. " + "Visit %s for further information about the software."), + PACKAGE_NAME, URL_WEBSITE) + + "\n" + + strprintf(_("The source code is available from %s."), + URL_SOURCE_CODE) + "\n" + + "\n" + + _("This is experimental software.") + "\n" + _("Distributed under the MIT software license, see the accompanying file COPYING or .") + "\n" + "\n" + _("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.") + From e1f80a661cfa3f14f0076a0a4ed4aadab0723008 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:10:29 +0000 Subject: [PATCH 07/49] Do not set extra flags for unfiltered DNS seed results Do not set extra flags for unfiltered DNS seed results (Pieter Wuille) --- src/chainparams.cpp | 7 ------- src/chainparams.h | 4 +--- src/net.cpp | 12 +++++++++++- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 014cda359e886..3f0f0a2504bdd 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -23,13 +23,6 @@ #include "chainparamsseeds.h" -std::string CDNSSeedData::getHost(uint64_t requiredServiceBits) const { - //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK) - if (!supportsServiceBitsFiltering || requiredServiceBits == NODE_NETWORK) - return host; - - return strprintf("x%x.%s", requiredServiceBits, host); -} static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { CMutableTransaction txNew; diff --git a/src/chainparams.h b/src/chainparams.h index 68a8418b2aa0a..3d502f8e995b3 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -13,11 +13,9 @@ #include -class CDNSSeedData { -public: +struct CDNSSeedData { std::string name, host; bool supportsServiceBitsFiltering; - std::string getHost(uint64_t requiredServiceBits) const; CDNSSeedData(const std::string &strName, const std::string &strHost, bool supportsServiceBitsFilteringIn = false) : name(strName), host(strHost), supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {} }; diff --git a/src/net.cpp b/src/net.cpp index 4739b224b795b..5dbbf71fe476e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1498,6 +1498,16 @@ void MapPort(bool) } #endif +static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredServiceBits) +{ + //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK) + if (!data.supportsServiceBitsFiltering || *requiredServiceBits == NODE_NETWORK) { + *requiredServiceBits = NODE_NETWORK; + return data.host; + } + + return strprintf("x%x.%s", *requiredServiceBits, data.host); +} void CConnman::ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute @@ -1525,7 +1535,7 @@ void CConnman::ThreadDNSAddressSeed() std::vector vIPs; std::vector vAdd; ServiceFlags requiredServiceBits = nRelevantServices; - if (LookupHost(seed.getHost(requiredServiceBits).c_str(), vIPs, 0, true)) + if (LookupHost(GetDNSHost(seed, &requiredServiceBits).c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) { From 178db9ba4a072784964b74e66e20cc608a5340d5 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:14:53 +0000 Subject: [PATCH 08/49] RPC Fix createrawtx sequence number unsigned in 6fa950a [RPC] Fix createrawtx sequence number unsigned int parsing (Jonas Schnelli) --- qa/rpc-tests/rawtransactions.py | 14 ++++++++++++++ src/rpc/rawtransaction.cpp | 9 +++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index cbb4e05a27b19..72f29f1f366f6 100644 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -143,5 +143,19 @@ def run_test(self): rawtx = self.nodes[0].createrawtransaction(inputs, outputs) decrawtx= self.nodes[0].decoderawtransaction(rawtx) assert_equal(decrawtx['vin'][0]['sequence'], 1000) + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : -1}] + outputs = { self.nodes[0].getnewaddress() : 1 } + assert_raises(JSONRPCException, self.nodes[0].createrawtransaction, inputs, outputs) + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967296}] + outputs = { self.nodes[0].getnewaddress() : 1 } + assert_raises(JSONRPCException, self.nodes[0].createrawtransaction, inputs, outputs) + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967294}] + outputs = { self.nodes[0].getnewaddress() : 1 } + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + decrawtx= self.nodes[0].decoderawtransaction(rawtx) + assert_equal(decrawtx['vin'][0]['sequence'], 4294967294) if __name__ == '__main__': RawTransactionsTest().main() diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 65125ce7e51cd..844e5ef551639 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -428,8 +428,13 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits::max() - 1 : std::numeric_limits::max()); // set the sequence number if passed in the parameters object const UniValue& sequenceObj = find_value(o, "sequence"); - if (sequenceObj.isNum()) - nSequence = sequenceObj.get_int(); + if (sequenceObj.isNum()) { + int64_t seqNr64 = sequenceObj.get_int64(); + if (seqNr64 < 0 || seqNr64 > std::numeric_limits::max()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range"); + else + nSequence = (uint32_t)seqNr64; + } CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence); rawTx.vin.push_back(in); From 3f15d742bc60f9f3ddb54fe46736daa9d0091515 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:40:28 +0000 Subject: [PATCH 09/49] Mining Select transactions using feerate-with-a ...ancestors 29fac19 Add unit tests for ancestor feerate mining (Suhas Daftuar) c82a4e9 Use ancestor-feerate based transaction selection for mining (Suhas Daftuar) --- src/miner.cpp | 226 ++++++++++++++++++++++++++++++++------- src/miner.h | 119 +++++++++++++++++++++ src/test/miner_tests.cpp | 110 +++++++++++++++++++ 3 files changed, 416 insertions(+), 39 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 2def32d296bb2..0452afcabfbc1 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -29,6 +29,7 @@ #include "masternode-sync.h" #include "validationinterface.h" +#include #include #include #include @@ -139,7 +140,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) : pblock->GetBlockTime(); addPriorityTxs(); - addScoreTxs(); + addPackageTxs(); nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; @@ -194,6 +195,39 @@ bool BlockAssembler::isStillDependent(CTxMemPool::txiter iter) return false; } +void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet) +{ + for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) { + // Only test txs not already in the block + if (inBlock.count(*iit)) { + testSet.erase(iit++); + } + else { + iit++; + } + } +} + +bool BlockAssembler::TestPackage(uint64_t packageSize, unsigned int packageSigOps) +{ + if (nBlockSize + packageSize >= nBlockMaxSize) + return false; + if (nBlockSigOps + packageSigOps >= MaxBlockSigOps(fDIP0001ActiveAtTip)) + return false; + return true; +} + +// Perform transaction-level checks before adding to block: +// - transaction finality (locktime) +bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& package) +{ + BOOST_FOREACH (const CTxMemPool::txiter it, package) { + if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff)) + return false; + } + return true; +} + bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter) { if (nBlockSize + iter->GetTxSize() >= nBlockMaxSize) { @@ -257,59 +291,173 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) } } -void BlockAssembler::addScoreTxs() +void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, + indexed_modified_transaction_set &mapModifiedTx) { - std::priority_queue, ScoreCompare> clearedTxs; - CTxMemPool::setEntries waitSet; - CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().begin(); + BOOST_FOREACH(const CTxMemPool::txiter it, alreadyAdded) { + CTxMemPool::setEntries descendants; + mempool.CalculateDescendants(it, descendants); + // Insert all descendants (not yet in block) into the modified set + BOOST_FOREACH(CTxMemPool::txiter desc, descendants) { + if (alreadyAdded.count(desc)) + continue; + modtxiter mit = mapModifiedTx.find(desc); + if (mit == mapModifiedTx.end()) { + CTxMemPoolModifiedEntry modEntry(desc); + modEntry.nSizeWithAncestors -= it->GetTxSize(); + modEntry.nModFeesWithAncestors -= it->GetModifiedFee(); + modEntry.nSigOpCountWithAncestors -= it->GetSigOpCount(); + mapModifiedTx.insert(modEntry); + } else { + mapModifiedTx.modify(mit, update_for_parent_inclusion(it)); + } + } + } +} + +// Skip entries in mapTx that are already in a block or are present +// in mapModifiedTx (which implies that the mapTx ancestor state is +// stale due to ancestor inclusion in the block) +// Also skip transactions that we've already failed to add. This can happen if +// we consider a transaction in mapModifiedTx and it fails: we can then +// potentially consider it again while walking mapTx. It's currently +// guaranteed to fail again, but as a belt-and-suspenders check we put it in +// failedTx and avoid re-evaluation, since the re-evaluation would be using +// cached size/sigops/fee values that are not actually correct. +bool BlockAssembler::SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx) +{ + assert (it != mempool.mapTx.end()); + if (mapModifiedTx.count(it) || inBlock.count(it) || failedTx.count(it)) + return true; + return false; +} + +void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector& sortedEntries) +{ + // Sort package by ancestor count + // If a transaction A depends on transaction B, then A's ancestor count + // must be greater than B's. So this is sufficient to validly order the + // transactions for block inclusion. + sortedEntries.clear(); + sortedEntries.insert(sortedEntries.begin(), package.begin(), package.end()); + std::sort(sortedEntries.begin(), sortedEntries.end(), CompareTxIterByAncestorCount()); +} + +// This transaction selection algorithm orders the mempool based +// on feerate of a transaction including all unconfirmed ancestors. +// Since we don't remove transactions from the mempool as we select them +// for block inclusion, we need an alternate method of updating the feerate +// of a transaction with its not-yet-selected ancestors as we go. +// This is accomplished by walking the in-mempool descendants of selected +// transactions and storing a temporary modified state in mapModifiedTxs. +// Each time through the loop, we compare the best transaction in +// mapModifiedTxs with the next transaction in the mempool to decide what +// transaction package to work on next. +void BlockAssembler::addPackageTxs() +{ + // mapModifiedTx will store sorted packages after they are modified + // because some of their txs are already in the block + indexed_modified_transaction_set mapModifiedTx; + // Keep track of entries that failed inclusion, to avoid duplicate work + CTxMemPool::setEntries failedTx; + + // Start by adding all descendants of previously added txs to mapModifiedTx + // and modifying them for their already included ancestors + UpdatePackagesForAdded(inBlock, mapModifiedTx); + + CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().begin(); CTxMemPool::txiter iter; - while (!blockFinished && (mi != mempool.mapTx.get().end() || !clearedTxs.empty())) + while (mi != mempool.mapTx.get().end() || !mapModifiedTx.empty()) { - // If no txs that were previously postponed are available to try - // again, then try the next highest score tx - if (clearedTxs.empty()) { + // First try to find a new transaction in mapTx to evaluate. + if (mi != mempool.mapTx.get().end() && + SkipMapTxEntry(mempool.mapTx.project<0>(mi), mapModifiedTx, failedTx)) { + ++mi; + continue; + } + + // Now that mi is not stale, determine which transaction to evaluate: + // the next entry from mapTx, or the best from mapModifiedTx? + bool fUsingModified = false; + + modtxscoreiter modit = mapModifiedTx.get().begin(); + if (mi == mempool.mapTx.get().end()) { + // We're out of entries in mapTx; use the entry from mapModifiedTx + iter = modit->iter; + fUsingModified = true; + } else { + // Try to compare the mapTx entry to the mapModifiedTx entry iter = mempool.mapTx.project<0>(mi); - mi++; + if (modit != mapModifiedTx.get().end() && + CompareModifiedEntry()(*modit, CTxMemPoolModifiedEntry(iter))) { + // The best entry in mapModifiedTx has higher score + // than the one from mapTx. + // Switch which transaction (package) to consider + iter = modit->iter; + fUsingModified = true; + } else { + // Either no entry in mapModifiedTx, or it's worse than mapTx. + // Increment mi for the next loop iteration. + ++mi; + } } - // If a previously postponed tx is available to try again, then it - // has higher score than all untried so far txs - else { - iter = clearedTxs.top(); - clearedTxs.pop(); + // We skip mapTx entries that are inBlock, and mapModifiedTx shouldn't + // contain anything that is inBlock. + assert(!inBlock.count(iter)); + + uint64_t packageSize = iter->GetSizeWithAncestors(); + CAmount packageFees = iter->GetModFeesWithAncestors(); + unsigned int packageSigOps = iter->GetSigOpCountWithAncestors(); + if (fUsingModified) { + packageSize = modit->nSizeWithAncestors; + packageFees = modit->nModFeesWithAncestors; + packageSigOps = modit->nSigOpCountWithAncestors; } - // If tx already in block, skip (added by addPriorityTxs) - if (inBlock.count(iter)) { - continue; + if (packageFees < ::minRelayTxFee.GetFee(packageSize)) { + // Everything else we might consider has a lower fee rate + return; } - // If tx is dependent on other mempool txs which haven't yet been included - // then put it in the waitSet - if (isStillDependent(iter)) { - waitSet.insert(iter); + if (!TestPackage(packageSize, packageSigOps)) { + if (fUsingModified) { + // Since we always look at the best entry in mapModifiedTx, + // we must erase failed entries so that we can consider the + // next best entry on the next loop iteration + mapModifiedTx.get().erase(modit); + failedTx.insert(iter); + } continue; } - // If the fee rate is below the min fee rate for mining, then we're done - // adding txs based on score (fee rate) - if (iter->GetModifiedFee() < ::minRelayTxFee.GetFee(iter->GetTxSize()) && nBlockSize >= nBlockMinSize) { - return; - } + CTxMemPool::setEntries ancestors; + uint64_t nNoLimit = std::numeric_limits::max(); + std::string dummy; + mempool.CalculateMemPoolAncestors(*iter, ancestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); - // If this tx fits in the block add it, otherwise keep looping - if (TestForBlock(iter)) { - AddToBlock(iter); + onlyUnconfirmed(ancestors); + ancestors.insert(iter); - // This tx was successfully added, so - // add transactions that depend on this one to the priority queue to try again - BOOST_FOREACH(CTxMemPool::txiter child, mempool.GetMemPoolChildren(iter)) - { - if (waitSet.count(child)) { - clearedTxs.push(child); - waitSet.erase(child); - } + // Test if all tx's are Final + if (!TestPackageTransactions(ancestors)) { + if (fUsingModified) { + mapModifiedTx.get().erase(modit); + failedTx.insert(iter); } + continue; + } + // Package can be added. Sort the entries in a valid order. + vector sortedEntries; + SortForBlock(ancestors, iter, sortedEntries); + + for (size_t i=0; i= nBlockPrioritySize || !AllowFree(actualPriority)) { - return; + break; } // This tx was successfully added, so diff --git a/src/miner.h b/src/miner.h index 540063dfcefb1..ed05c1d150326 100644 --- a/src/miner.h +++ b/src/miner.h @@ -11,6 +11,8 @@ #include #include +#include "boost/multi_index_container.hpp" +#include "boost/multi_index/ordered_index.hpp" class CBlockIndex; class CChainParams; @@ -30,6 +32,103 @@ struct CBlockTemplate std::vector vTxSigOps; }; +// Container for tracking updates to ancestor feerate as we include (parent) +// transactions in a block +struct CTxMemPoolModifiedEntry { + CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) + { + iter = entry; + nSizeWithAncestors = entry->GetSizeWithAncestors(); + nModFeesWithAncestors = entry->GetModFeesWithAncestors(); + nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors(); + } + + CTxMemPool::txiter iter; + uint64_t nSizeWithAncestors; + CAmount nModFeesWithAncestors; + unsigned int nSigOpCountWithAncestors; +}; + +/** Comparator for CTxMemPool::txiter objects. + * It simply compares the internal memory address of the CTxMemPoolEntry object + * pointed to. This means it has no meaning, and is only useful for using them + * as key in other indexes. + */ +struct CompareCTxMemPoolIter { + bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const + { + return &(*a) < &(*b); + } +}; + +struct modifiedentry_iter { + typedef CTxMemPool::txiter result_type; + result_type operator() (const CTxMemPoolModifiedEntry &entry) const + { + return entry.iter; + } +}; + +// This matches the calculation in CompareTxMemPoolEntryByAncestorFee, +// except operating on CTxMemPoolModifiedEntry. +// TODO: refactor to avoid duplication of this logic. +struct CompareModifiedEntry { + bool operator()(const CTxMemPoolModifiedEntry &a, const CTxMemPoolModifiedEntry &b) + { + double f1 = (double)a.nModFeesWithAncestors * b.nSizeWithAncestors; + double f2 = (double)b.nModFeesWithAncestors * a.nSizeWithAncestors; + if (f1 == f2) { + return CTxMemPool::CompareIteratorByHash()(a.iter, b.iter); + } + return f1 > f2; + } +}; + +// A comparator that sorts transactions based on number of ancestors. +// This is sufficient to sort an ancestor package in an order that is valid +// to appear in a block. +struct CompareTxIterByAncestorCount { + bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) + { + if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) + return a->GetCountWithAncestors() < b->GetCountWithAncestors(); + return CTxMemPool::CompareIteratorByHash()(a, b); + } +}; + +typedef boost::multi_index_container< + CTxMemPoolModifiedEntry, + boost::multi_index::indexed_by< + boost::multi_index::ordered_unique< + modifiedentry_iter, + CompareCTxMemPoolIter + >, + // sorted by modified ancestor fee rate + boost::multi_index::ordered_non_unique< + // Reuse same tag from CTxMemPool's similar index + boost::multi_index::tag, + boost::multi_index::identity, + CompareModifiedEntry + > + > +> indexed_modified_transaction_set; + +typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter; +typedef indexed_modified_transaction_set::index::type::iterator modtxscoreiter; + +struct update_for_parent_inclusion +{ + update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} + + void operator() (CTxMemPoolModifiedEntry &e) + { + e.nModFeesWithAncestors -= iter->GetFee(); + e.nSizeWithAncestors -= iter->GetTxSize(); + e.nSigOpCountWithAncestors -= iter->GetSigOpCount(); + } + + CTxMemPool::txiter iter; +}; /** Generate a new block, without valid proof-of-work */ class BlockAssembler { @@ -75,12 +174,32 @@ class BlockAssembler void addScoreTxs(); /** Add transactions based on tx "priority" */ void addPriorityTxs(); + /** Add transactions based on feerate including unconfirmed ancestors */ + void addPackageTxs(); // helper function for addScoreTxs and addPriorityTxs /** Test if tx will still "fit" in the block */ bool TestForBlock(CTxMemPool::txiter iter); /** Test if tx still has unconfirmed parents not yet in block */ bool isStillDependent(CTxMemPool::txiter iter); + // helper functions for addPackageTxs() + /** Remove confirmed (inBlock) entries from given set */ + void onlyUnconfirmed(CTxMemPool::setEntries& testSet); + /** Test if a new package would "fit" in the block */ + bool TestPackage(uint64_t packageSize, unsigned int packageSigOps); + /** Perform checks on each transaction in a package: + * locktime + * These checks should always succeed, and they're here + * only as an extra check in case of suboptimal node configuration */ + bool TestPackageTransactions(const CTxMemPool::setEntries& package); + /** Return true if given transaction from mapTx has already been evaluated, + * or if the transaction's cached data in mapTx is incorrect. */ + bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx); + /** Sort the package in an order that is valid to appear in a block */ + void SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector& sortedEntries); + /** Add descendants of given transactions to mapModifiedTx with ancestor + * state updated assuming given transactions are inBlock. */ + void UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx); }; /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 9e76bba90b806..773de190aae0b 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -72,6 +72,115 @@ bool TestSequenceLocks(const CTransaction &tx, int flags) return CheckSequenceLocks(tx, flags); } +// Test suite for ancestor feerate transaction selection. +// Implemented as an additional function, rather than a separate test case, +// to allow reusing the blockchain created in CreateNewBlock_validity. +// Note that this test assumes blockprioritysize is 0. +void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector& txFirst) +{ + // Disable free transactions, otherwise TX selection is non-deterministic + SoftSetArg("-blockprioritysize", "0"); + + // Test the ancestor feerate transaction selection. + TestMemPoolEntryHelper entry; + + // Test that a medium fee transaction will be selected after a higher fee + // rate package with a low fee rate parent. + CMutableTransaction tx; + tx.vin.resize(1); + tx.vin[0].scriptSig = CScript() << OP_1; + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vin[0].prevout.n = 0; + tx.vout.resize(1); + tx.vout[0].nValue = 5000000000LL - 1000; + // This tx has a low fee: 1000 satoshis + uint256 hashParentTx = tx.GetHash(); // save this txid for later use + mempool.addUnchecked(hashParentTx, entry.Fee(1000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + + // This tx has a medium fee: 10000 satoshis + tx.vin[0].prevout.hash = txFirst[1]->GetHash(); + tx.vout[0].nValue = 5000000000LL - 10000; + uint256 hashMediumFeeTx = tx.GetHash(); + mempool.addUnchecked(hashMediumFeeTx, entry.Fee(10000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + + // This tx has a high fee, but depends on the first transaction + tx.vin[0].prevout.hash = hashParentTx; + tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee + uint256 hashHighFeeTx = tx.GetHash(); + mempool.addUnchecked(hashHighFeeTx, entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + + CBlockTemplate *pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + BOOST_CHECK(pblocktemplate->block.vtx[1].GetHash() == hashParentTx); + BOOST_CHECK(pblocktemplate->block.vtx[2].GetHash() == hashHighFeeTx); + BOOST_CHECK(pblocktemplate->block.vtx[3].GetHash() == hashMediumFeeTx); + + // Test that a package below the min relay fee doesn't get included + tx.vin[0].prevout.hash = hashHighFeeTx; + tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee + uint256 hashFreeTx = tx.GetHash(); + mempool.addUnchecked(hashFreeTx, entry.Fee(0).FromTx(tx)); + size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + + // Calculate a fee on child transaction that will put the package just + // below the min relay fee (assuming 1 child tx of the same size). + CAmount feeToUse = minRelayTxFee.GetFee(2*freeTxSize) - 1; + + tx.vin[0].prevout.hash = hashFreeTx; + tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; + uint256 hashLowFeeTx = tx.GetHash(); + mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + // Verify that the free tx and the low fee tx didn't get selected + for (size_t i=0; iblock.vtx.size(); ++i) { + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx); + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx); + } + + // Test that packages above the min relay fee do get included, even if one + // of the transactions is below the min relay fee + // Remove the low fee transaction and replace with a higher fee transaction + std::list dummy; + mempool.removeRecursive(tx, dummy); + tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee + hashLowFeeTx = tx.GetHash(); + mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse+2).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + BOOST_CHECK(pblocktemplate->block.vtx[4].GetHash() == hashFreeTx); + BOOST_CHECK(pblocktemplate->block.vtx[5].GetHash() == hashLowFeeTx); + + // Test that transaction selection properly updates ancestor fee + // calculations as ancestor transactions get included in a block. + // Add a 0-fee transaction that has 2 outputs. + tx.vin[0].prevout.hash = txFirst[2]->GetHash(); + tx.vout.resize(2); + tx.vout[0].nValue = 5000000000LL - 100000000; + tx.vout[1].nValue = 100000000; // 1BTC output + uint256 hashFreeTx2 = tx.GetHash(); + mempool.addUnchecked(hashFreeTx2, entry.Fee(0).SpendsCoinbase(true).FromTx(tx)); + + // This tx can't be mined by itself + tx.vin[0].prevout.hash = hashFreeTx2; + tx.vout.resize(1); + feeToUse = minRelayTxFee.GetFee(freeTxSize); + tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse; + uint256 hashLowFeeTx2 = tx.GetHash(); + mempool.addUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + + // Verify that this tx isn't selected. + for (size_t i=0; iblock.vtx.size(); ++i) { + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx2); + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx2); + } + + // This tx will be mineable, and should cause hashLowFeeTx2 to be selected + // as well. + tx.vin[0].prevout.n = 1; + tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee + mempool.addUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + BOOST_CHECK(pblocktemplate->block.vtx[8].GetHash() == hashLowFeeTx2); +} // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { @@ -385,6 +494,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) chainActive.Tip()->nHeight--; SetMockTime(0); mempool.clear(); + TestPackageSelection(chainparams, scriptPubKey, txFirst); BOOST_FOREACH(CTransaction *_tx, txFirst) delete _tx; From e33c5edc48bf0cb7051f5d1fdf3fe7698f94e19d Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:43:40 +0000 Subject: [PATCH 10/49] Qa mininode: fail on send_message instead of si.. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …lent return facb6c0 [qa] mininode: fail on send_message instead of silent return (MarcoFalke) --- qa/rpc-tests/test_framework/mininode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index b03ed1fdb59f2..ed9666b72371d 100644 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1320,7 +1320,7 @@ def got_data(self): def send_message(self, message, pushbuf=False): if self.state != "connected" and not pushbuf: - return + raise IOError('Not connected, no pushbuf') self.show_debug_msg("Send %s" % repr(message)) command = message.command data = message.serialize() From d4006e1b3ec5c615a2a29b49b1d269a029e636b0 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:46:13 +0000 Subject: [PATCH 11/49] Wallet tests Don't use floating point faa91b1 [wallet] tests: Don't use floating point (MarcoFalke) --- src/wallet/test/wallet_tests.cpp | 46 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 387b223589340..0a4f06ba88175 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -27,7 +27,7 @@ typedef set > CoinSet; BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) -static CWallet wallet; +static const CWallet wallet; static vector vCoins; static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) @@ -188,11 +188,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // empty the wallet and start again, now with fractions of a cent, to test small change avoidance empty_wallet(); - add_coin(0.1*MIN_CHANGE); - add_coin(0.2*MIN_CHANGE); - add_coin(0.3*MIN_CHANGE); - add_coin(0.4*MIN_CHANGE); - add_coin(0.5*MIN_CHANGE); + add_coin(MIN_CHANGE * 1 / 10); + add_coin(MIN_CHANGE * 2 / 10); + add_coin(MIN_CHANGE * 3 / 10); + add_coin(MIN_CHANGE * 4 / 10); + add_coin(MIN_CHANGE * 5 / 10); // try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE // we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly @@ -207,8 +207,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount // if we add more small coins: - add_coin(0.6*MIN_CHANGE); - add_coin(0.7*MIN_CHANGE); + add_coin(MIN_CHANGE * 6 / 10); + add_coin(MIN_CHANGE * 7 / 10); // and try again to make 1.0 * MIN_CHANGE BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); @@ -229,9 +229,9 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // sometimes it will fail, and so we use the next biggest coin: empty_wallet(); - add_coin(0.5 * MIN_CHANGE); - add_coin(0.6 * MIN_CHANGE); - add_coin(0.7 * MIN_CHANGE); + add_coin(MIN_CHANGE * 5 / 10); + add_coin(MIN_CHANGE * 6 / 10); + add_coin(MIN_CHANGE * 7 / 10); add_coin(1111 * MIN_CHANGE); BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin @@ -239,9 +239,9 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) empty_wallet(); - add_coin(0.4 * MIN_CHANGE); - add_coin(0.6 * MIN_CHANGE); - add_coin(0.8 * MIN_CHANGE); + add_coin(MIN_CHANGE * 4 / 10); + add_coin(MIN_CHANGE * 6 / 10); + add_coin(MIN_CHANGE * 8 / 10); add_coin(1111 * MIN_CHANGE); BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount @@ -249,17 +249,17 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // test avoiding small change empty_wallet(); - add_coin(0.05 * MIN_CHANGE); - add_coin(1 * MIN_CHANGE); - add_coin(100 * MIN_CHANGE); + add_coin(MIN_CHANGE * 5 / 100); + add_coin(MIN_CHANGE * 1); + add_coin(MIN_CHANGE * 100); // trying to make 100.01 from these three coins - BOOST_CHECK( wallet.SelectCoinsMinConf(100.01 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 101.05 * MIN_CHANGE); // we should get all coins + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 10001 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE * 10105 / 100); // we should get all coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change - BOOST_CHECK( wallet.SelectCoinsMinConf(99.9 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); @@ -310,7 +310,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // add 75 cents in small change. not enough to make 90 cents, // then try making 90 cents. there are multiple competing "smallest bigger" coins, // one of which should be picked at random - add_coin( 5*CENT); add_coin(10*CENT); add_coin(15*CENT); add_coin(20*CENT); add_coin(25*CENT); + add_coin(5 * CENT); + add_coin(10 * CENT); + add_coin(15 * CENT); + add_coin(20 * CENT); + add_coin(25 * CENT); fails = 0; for (int i = 0; i < RANDOM_REPEATS; i++) From e91f889e4bbf2d532d70a28df92c333d6f538f3c Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:51:54 +0000 Subject: [PATCH 12/49] New and only new blocks relayed when pruning New and only new blocks relayed when pruning update to old release notes --- doc/release-notes/bitcoin/release-notes-0.12.0.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/release-notes/bitcoin/release-notes-0.12.0.md b/doc/release-notes/bitcoin/release-notes-0.12.0.md index 85c020a9cd0bf..cf74a17975207 100644 --- a/doc/release-notes/bitcoin/release-notes-0.12.0.md +++ b/doc/release-notes/bitcoin/release-notes-0.12.0.md @@ -104,9 +104,6 @@ announcing their headers directly, instead of just announcing the hash. In a reorganization, all new headers are sent, instead of just the new tip. This can often prevent an extra roundtrip before the actual block is downloaded. -With this change, pruning nodes are now able to relay new blocks to compatible -peers. - Memory pool limiting -------------------- @@ -188,6 +185,14 @@ the OP_RETURN. The limit on OP_RETURN output size is now applied to the entire serialized scriptPubKey, 83 bytes by default. (the previous 80 byte default plus three bytes overhead) +Relay: New and only new blocks relayed when pruning +--------------------------------------------------- + +When running in pruned mode, the client will now relay new blocks. When +responding to the `getblocks` message, only hashes of blocks that are on disk +and are likely to remain there for some reasonable time window (1 hour) will be +returned (previously all relevant hashes were returned). + Relay and Mining: Priority transactions --------------------------------------- @@ -887,5 +892,3 @@ Thanks to everyone who directly contributed to this release: - zathras-crypto As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). - - From 2513d1fe7cde6cb8f811031dac7013c9a74ad27d Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:54:43 +0000 Subject: [PATCH 13/49] Address update for rpc features --- doc/release-notes/dash/release-notes-0.12.2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes/dash/release-notes-0.12.2.md b/doc/release-notes/dash/release-notes-0.12.2.md index 885712edfa60c..8b511da0cade4 100644 --- a/doc/release-notes/dash/release-notes-0.12.2.md +++ b/doc/release-notes/dash/release-notes-0.12.2.md @@ -58,7 +58,7 @@ RPC changes ----------- There are few changes in existing RPC in this release: -- There is no more `bcconfirmations` field in RPC output and `confirmations` shows blockchain only confirmations by default now. You can change this behaviour by switching new `addlockconf` param to `true`. There is a new rpc field `instantlock` which indicates whether a given transaction is locked via InstantSend. For more info and examples please see https://github.com/dashpay/absolute/blob/v0.12.2.x/doc/instantsend.md; +- There is no more `bcconfirmations` field in RPC output and `confirmations` shows blockchain only confirmations by default now. You can change this behaviour by switching new `addlockconf` param to `true`. There is a new rpc field `instantlock` which indicates whether a given transaction is locked via InstantSend. - `gobject list` and `gobject diff` accept `funding`, `delete` and `endorsed` filtering options now, in addition to `valid` and `all` currently available; - `vin` field in `masternode` commands is renamed to `outpoint` and shows data in short format now; - `getblocktemplate` output is extended with versionbits-related information; From a810f59eb7212ddcc36e71ab6b2e27d4bcb84983 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 10:56:31 +0000 Subject: [PATCH 14/49] Clarify documentation for running a tor node --- doc/tor.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/doc/tor.md b/doc/tor.md index 3ce352a691fc8..2bd45cf4b3026 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -122,12 +122,22 @@ Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket API, to create and destroy 'ephemeral' hidden services programmatically. Absolute Core has been updated to make use of this. -This means that if Tor is running (and proper authorization is available), -Absolute Core automatically creates a hidden service to listen on, without -manual configuration. This will positively affect the number of available -.onion nodes. +This means that if Tor is running (and proper authentication has been configured), +Absolute 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 Absolute Core is listening, and a connection to Tor can be made. It can be configured with the `-listenonion`, `-torcontrol` and `-torpassword` settings. 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 absoluted must have write 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 absoluted to the same group and setting permissions appropriately. On +Debian-based systems the user running absoluted can be added to the debian-tor group, +which has the appropriate permissions. An alternative authentication method is the use +of the `-torpassword` flag and a `hash-password` which can be enabled and specified in +Tor configuration. From fb8cf3256dd9ff68c1d4f13cf23bb812480888bd Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 15:57:12 +0000 Subject: [PATCH 15/49] Bump to Qt5.6.1 2759597 Only pass -lQt5PlatformSupport if >=Qt5.6 (Jonas Schnelli) 59d063d Use runtime linking of QT libdbus, use custom/temp. SDK URL (Jonas Schnelli) 6194d9a Fix bitcoin_qt.m4 and fix-xcb-include-order.patch (Jonas Schnelli) f6eb4e2 [depends] OpenSSL 1.0.1k - update config_opts (fanquake) f25209a depends: bump OSX toolchain (Cory Fields) --- .travis.yml | 4 +- build-aux/m4/bitcoin_qt.m4 | 20 ++++- contrib/gitian-descriptors/gitian-osx.yml | 4 +- depends/hosts/darwin.mk | 4 +- depends/packages/native_cctools.mk | 20 +++-- depends/packages/openssl.mk | 39 ++++++++- depends/packages/qt.mk | 86 ++++++++++--------- .../patches/qt/fix-xcb-include-order.patch | 21 +++-- src/qt/absolute.cpp | 3 + 9 files changed, 136 insertions(+), 65 deletions(-) diff --git a/.travis.yml b/.travis.yml index 016e7242ed435..ce175cb4d93ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,10 +49,11 @@ env: # No wallet - HOST=x86_64-unknown-linux-gnu PPA="ppa:bitcoin/bitcoin" PACKAGES="python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" # Cross-Mac - - HOST=x86_64-apple-darwin11 PPA="ppa:bitcoin/bitcoin" PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" + - HOST=x86_64-apple-darwin11 PPA="ppa:bitcoin/bitcoin" PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" OSX_SDK=10.11 GOAL="deploy" before_install: + - git clone https://github.com/absolute-community/absolute_hash - travis_retry sudo apt-get install python3-pip python3-dev - travis_retry sudo add-apt-repository ppa:ubuntu-wine/ppa -y - export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g") @@ -68,6 +69,7 @@ install: - if [ -n "$DPKG_ADD_ARCH" ]; then sudo dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi + - cd absolute_hash && python3 setup.py install --user && cd .. before_script: - unset CC; unset CXX - unset DISPLAY diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index dd3e621c43561..363433a91c9d9 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -346,8 +346,9 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" fi fi - m4_ifdef([PKG_CHECK_MODULES],[ if test x$use_pkgconfig = xyes; then + : dnl + m4_ifdef([PKG_CHECK_MODULES],[ PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) if test x$TARGET_OS = xlinux; then PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"]) @@ -357,8 +358,23 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ elif test x$TARGET_OS = xdarwin; then PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"]) fi - fi ]) + else + if test x$TARGET_OS = xwindows; then + AC_CACHE_CHECK(for Qt >= 5.6, bitcoin_cv_need_platformsupport,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[#include ]],[[ + #if QT_VERSION < 0x050600 + choke; + #endif + ]])], + [bitcoin_cv_need_platformsupport=yes], + [bitcoin_cv_need_platformsupport=no]) + ]) + if test x$bitcoin_cv_need_platformsupport = xyes; then + BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}PlatformSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXPlatformSupport not found))) + fi + fi + fi else if test x$qt_plugin_path != x; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 040cafeb431bf..6161d2b1908a0 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -31,7 +31,7 @@ remotes: - "url": "https://github.com/absolute-community/absolute.git" "dir": "absolute" files: -- "MacOSX10.9.sdk.tar.gz" +- "MacOSX10.11.sdk.tar.gz" script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin11" @@ -86,7 +86,7 @@ script: | BASEPREFIX=`pwd`/depends mkdir -p ${BASEPREFIX}/SDKs - tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.9.sdk.tar.gz + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz # Build dependencies for each host for i in $HOSTS; do diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index dbe6d00795e00..985649619ffec 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,7 +1,7 @@ OSX_MIN_VERSION=10.7 -OSX_SDK_VERSION=10.9 +OSX_SDK_VERSION=10.11 OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk -LD64_VERSION=241.9 +LD64_VERSION=253.9 darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++ diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index b5603a8d48c60..797480c25eb2f 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,14 +1,14 @@ package=native_cctools -$(package)_version=ee31ae567931c426136c94aad457c7b51d844beb +$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6 $(package)_download_path=https://github.com/theuni/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=ef107e6ab1b3994cb22e14f4f5c59ea0c0b5a988e6b21d42ed9616b018bbcbf9 +$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a $(package)_build_subdir=cctools -$(package)_clang_version=3.3 +$(package)_clang_version=3.7.1 $(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version) -$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz -$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz -$(package)_clang_sha256_hash=60d8f69f032d62ef61bf527857ebb933741ec3352d4d328c5516aa520662dab7 +$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz +$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz +$(package)_clang_sha256_hash=99b28a6b48e793705228a390471991386daa33a9717cd9ca007fcdde69608fd9 $(package)_extra_sources=$($(package)_clang_file_name) define $(package)_fetch_cmds @@ -23,6 +23,7 @@ define $(package)_extract_cmds $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \ tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ + rm -f toolchain/lib/libc++abi.so* && \ echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \ echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \ chmod +x toolchain/bin/$(host)-dsymutil && \ @@ -30,7 +31,7 @@ define $(package)_extract_cmds endef define $(package)_set_vars -$(package)_config_opts=--target=$(host) --disable-libuuid +$(package)_config_opts=--target=$(host) --disable-lto-support $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib $(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ @@ -53,10 +54,11 @@ define $(package)_stage_cmds cd $($(package)_extract_dir)/toolchain && \ mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \ mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \ - cp -P bin/clang bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ + cp bin/clang $($(package)_staging_prefix_dir)/bin/ &&\ + cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \ - cp bin/$(host)-dsymutil $($(package)_staging_prefix_dir)/bin && \ + cp bin/llvm-dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ if `test -d include/c++/`; then cp -rf include/c++/ $($(package)_staging_prefix_dir)/include/; fi && \ if `test -d lib/c++/`; then cp -rf lib/c++/ $($(package)_staging_prefix_dir)/lib/; fi endef diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index fe6eb97dead0c..5ee9f17a63235 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -6,9 +6,42 @@ $(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fce define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" -$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl no-zlib no-shared no-dso -$(package)_config_opts+=no-krb5 no-capieng no-dtls1 no-gost no-gmp no-heartbeats no-jpake no-md2 -$(package)_config_opts+=no-rc5 no-rdrand no-rfc3779 no-rsax no-sctp no-sha0 no-static_engine no-ssl2 no-ssl3 +$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl +$(package)_config_opts+=no-camellia +$(package)_config_opts+=no-capieng +$(package)_config_opts+=no-cast +$(package)_config_opts+=no-comp +$(package)_config_opts+=no-dso +$(package)_config_opts+=no-dtls1 +$(package)_config_opts+=no-ec_nistp_64_gcc_128 +$(package)_config_opts+=no-gost +$(package)_config_opts+=no-gmp +$(package)_config_opts+=no-heartbeats +$(package)_config_opts+=no-idea +$(package)_config_opts+=no-jpake +$(package)_config_opts+=no-krb5 +$(package)_config_opts+=no-libunbound +$(package)_config_opts+=no-md2 +$(package)_config_opts+=no-mdc2 +$(package)_config_opts+=no-rc4 +$(package)_config_opts+=no-rc5 +$(package)_config_opts+=no-rdrand +$(package)_config_opts+=no-rfc3779 +$(package)_config_opts+=no-rsax +$(package)_config_opts+=no-sctp +$(package)_config_opts+=no-seed +$(package)_config_opts+=no-sha0 +$(package)_config_opts+=no-shared +$(package)_config_opts+=no-ssl-trace +$(package)_config_opts+=no-ssl2 +$(package)_config_opts+=no-ssl3 +$(package)_config_opts+=no-static_engine +$(package)_config_opts+=no-store +$(package)_config_opts+=no-unit-test +$(package)_config_opts+=no-weak-ssl-ciphers +$(package)_config_opts+=no-whirlpool +$(package)_config_opts+=no-zlib +$(package)_config_opts+=no-zlib-dynamic $(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags) $(package)_config_opts_linux=-fPIC -Wa,--noexecstack $(package)_config_opts_x86_64_linux=linux-x86_64 diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index b7a2413750d09..6abbd6cfbfdf7 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,20 +1,20 @@ PACKAGE=qt -$(package)_version=5.5.0 -$(package)_download_path=http://download.qt.io/archive/qt/5.5/$($(package)_version)/submodules +$(package)_version=5.6.1 +$(package)_download_path=http://download.qt.io/official_releases/qt/5.6/$($(package)_version)/submodules $(package)_suffix=opensource-src-$($(package)_version).tar.gz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=7e82b1318f88e56a2a9376e069aa608d4fd96b48cb0e1b880ae658b0a1af0561 +$(package)_sha256_hash=0ac67cf8d66d52b995f96c31c4b48117a1afb3db99eaa93e20ccd8f7f55f7fde $(package)_dependencies=openssl -$(package)_linux_dependencies=freetype fontconfig dbus libxcb libX11 xproto libXext +$(package)_linux_dependencies=freetype fontconfig libxcb libX11 xproto libXext $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib -$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch mingw-uuidof.patch pidlist_absolute.patch +$(package)_patches=mac-qmake.conf mingw-uuidof.patch pidlist_absolute.patch fix-xcb-include-order.patch fix_qt_pkgconfig.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=c4bd6db6e426965c6f8824c54e81f68bbd61e2bae1bcadc328c6e81c45902a0d +$(package)_qttranslations_sha256_hash=dcc1534d247babca1840cb6d0a000671801a341ea352d0535474f86adadaf028 $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=d9e06bd19ecc86afba5e95d45a906d1bc1ad579aa70001e36143c1aaf695bdd6 +$(package)_qttools_sha256_hash=e0f845de28c31230dfa428f0190ccb3b91d1fc02481b1f064698ae4ef8376aa1 $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) @@ -22,21 +22,34 @@ $(package)_extra_sources += $($(package)_qttools_file_name) define $(package)_set_vars $(package)_config_opts_release = -release $(package)_config_opts_debug = -debug -$(package)_config_opts += -opensource -confirm-license +$(package)_config_opts += -bindir $(build_prefix)/bin +$(package)_config_opts += -c++11 +$(package)_config_opts += -confirm-license +$(package)_config_opts += -dbus-runtime +$(package)_config_opts += -hostprefix $(build_prefix) +$(package)_config_opts += -no-alsa $(package)_config_opts += -no-audio-backend +$(package)_config_opts += -no-cups +$(package)_config_opts += -no-egl +$(package)_config_opts += -no-eglfs +$(package)_config_opts += -no-feature-style-windowsmobile +$(package)_config_opts += -no-feature-style-windowsce +$(package)_config_opts += -no-freetype +$(package)_config_opts += -no-gif $(package)_config_opts += -no-glib +$(package)_config_opts += -no-gstreamer $(package)_config_opts += -no-icu -$(package)_config_opts += -no-cups $(package)_config_opts += -no-iconv -$(package)_config_opts += -no-gif -$(package)_config_opts += -no-freetype +$(package)_config_opts += -no-kms +$(package)_config_opts += -no-linuxfb +$(package)_config_opts += -no-libudev +$(package)_config_opts += -no-mitshm +$(package)_config_opts += -no-mtdev $(package)_config_opts += -no-nis -$(package)_config_opts += -pch +$(package)_config_opts += -no-pulseaudio +$(package)_config_opts += -no-openvg +$(package)_config_opts += -no-reduce-relocations $(package)_config_opts += -no-qml-debug -$(package)_config_opts += -nomake examples -$(package)_config_opts += -nomake tests -$(package)_config_opts += -no-feature-style-windowsmobile -$(package)_config_opts += -no-feature-style-windowsce $(package)_config_opts += -no-sql-db2 $(package)_config_opts += -no-sql-ibase $(package)_config_opts += -no-sql-oci @@ -46,36 +59,25 @@ $(package)_config_opts += -no-sql-odbc $(package)_config_opts += -no-sql-psql $(package)_config_opts += -no-sql-sqlite $(package)_config_opts += -no-sql-sqlite2 -$(package)_config_opts += -prefix $(host_prefix) -$(package)_config_opts += -hostprefix $(build_prefix) -$(package)_config_opts += -bindir $(build_prefix)/bin -$(package)_config_opts += -c++11 +$(package)_config_opts += -no-use-gold-linker +$(package)_config_opts += -no-xinput2 +$(package)_config_opts += -no-xrender +$(package)_config_opts += -nomake examples +$(package)_config_opts += -nomake tests +$(package)_config_opts += -opensource $(package)_config_opts += -openssl-linked -$(package)_config_opts += -v -$(package)_config_opts += -static -$(package)_config_opts += -silent +$(package)_config_opts += -optimized-qmake +$(package)_config_opts += -pch $(package)_config_opts += -pkg-config +$(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -qt-libpng $(package)_config_opts += -qt-libjpeg -$(package)_config_opts += -qt-zlib $(package)_config_opts += -qt-pcre -$(package)_config_opts += -no-pulseaudio -$(package)_config_opts += -no-openvg -$(package)_config_opts += -no-xrender -$(package)_config_opts += -no-alsa -$(package)_config_opts += -no-mtdev -$(package)_config_opts += -no-gstreamer -$(package)_config_opts += -no-mitshm -$(package)_config_opts += -no-kms -$(package)_config_opts += -no-reduce-relocations -$(package)_config_opts += -no-egl -$(package)_config_opts += -no-eglfs -$(package)_config_opts += -no-linuxfb -$(package)_config_opts += -no-xinput2 -$(package)_config_opts += -no-libudev -$(package)_config_opts += -no-use-gold-linker +$(package)_config_opts += -qt-zlib $(package)_config_opts += -reduce-exports -$(package)_config_opts += -optimized-qmake +$(package)_config_opts += -static +$(package)_config_opts += -silent +$(package)_config_opts += -v ifneq ($(build_os),darwin) $(package)_config_opts_darwin = -xplatform macx-clang-linux @@ -124,14 +126,16 @@ define $(package)_preprocess_cmds sed -i.old "s/src_plugins.depends = src_sql src_xml src_network/src_plugins.depends = src_xml src_network/" qtbase/src/src.pro && \ sed -i.old "s|X11/extensions/XIproto.h|X11/X.h|" qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp && \ sed -i.old 's/if \[ "$$$$XPLATFORM_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/if \[ "$$$$BUILD_ON_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/' qtbase/configure && \ + sed -i.old 's/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0)/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, kCGMouseButtonLeft)/' qtbase/src/plugins/platforms/cocoa/qcocoacursor.mm && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/Info.plist.lib qtbase/mkspecs/macx-clang-linux/ &&\ cp -f qtbase/mkspecs/macx-clang/Info.plist.app qtbase/mkspecs/macx-clang-linux/ &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ - patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \ patch -p1 < $($(package)_patch_dir)/mingw-uuidof.patch && \ patch -p1 < $($(package)_patch_dir)/pidlist_absolute.patch && \ + patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \ + patch -p1 < $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ echo "QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ diff --git a/depends/patches/qt/fix-xcb-include-order.patch b/depends/patches/qt/fix-xcb-include-order.patch index ae469ea94bff0..a717023f26c40 100644 --- a/depends/patches/qt/fix-xcb-include-order.patch +++ b/depends/patches/qt/fix-xcb-include-order.patch @@ -1,15 +1,18 @@ --- old/qtbase/src/plugins/platforms/xcb/xcb_qpa_lib.pro 2015-03-17 02:06:42.705930685 +0000 +++ new/qtbase/src/plugins/platforms/xcb/xcb_qpa_lib.pro 2015-03-17 02:08:41.281926351 +0000 -@@ -94,8 +94,6 @@ +@@ -74,8 +74,6 @@ + DEFINES += $$QMAKE_DEFINES_XCB LIBS += $$QMAKE_LIBS_XCB -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB -QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB + CONFIG += qpa/genericunixfontdatabase -@@ -104,7 +102,8 @@ + +@@ -87,7 +85,8 @@ contains(QT_CONFIG, xcb-qt) { DEFINES += XCB_USE_RENDER XCB_DIR = ../../../3rdparty/xcb @@ -18,28 +21,36 @@ + QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static } else { - LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms + LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms -lxcb-xinerama --- old/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:07:04.641929383 +0000 +++ new/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:10:15.485922059 +0000 -@@ -8,7 +8,8 @@ +@@ -9,7 +9,8 @@ + XCB_DIR = ../../../../3rdparty/xcb + -INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude +QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude +QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude + QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB --- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-07-24 16:02:59.530038830 -0400 +++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-07-24 16:01:22.106037459 -0400 -@@ -11,3 +11,9 @@ +@@ -6,6 +6,13 @@ qxcbmain.cpp OTHER_FILES += xcb.json README + +contains(QT_CONFIG, xcb-qt) { + DEFINES += XCB_USE_RENDER + XCB_DIR = ../../../3rdparty/xcb + QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB + QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB +} ++ + PLUGIN_TYPE = platforms + PLUGIN_CLASS_NAME = QXcbIntegrationPlugin + !equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - diff --git a/src/qt/absolute.cpp b/src/qt/absolute.cpp index 76715377a857a..3e9cb490a4d8f 100644 --- a/src/qt/absolute.cpp +++ b/src/qt/absolute.cpp @@ -578,6 +578,9 @@ int main(int argc, char *argv[]) // Generate high-dpi pixmaps QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif +#if QT_VERSION >= 0x050600 + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif #ifdef Q_OS_MAC QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif From 55a344d963cd5492c6922a931d747972cea4cbaa Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 15:58:59 +0000 Subject: [PATCH 16/49] Test_framework Use different rpc_auth_pair fad1845 [qa] test_framework: Use different rpc_auth_pair for each node (MarcoFalke) --- qa/rpc-tests/test_framework/util.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index a25adb66dc2ee..b374c3560b267 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -170,17 +170,21 @@ def initialize_datadir(dirname, n): datadir = os.path.join(dirname, "node"+str(n)) if not os.path.isdir(datadir): os.makedirs(datadir) + rpc_u, rpc_p = rpc_auth_pair(n) with open(os.path.join(datadir, "absolute.conf"), 'w') as f: f.write("regtest=1\n") - f.write("rpcuser=rt\n") - f.write("rpcpassword=rt\n") + f.write("rpcuser=" + rpc_u + "\n") + f.write("rpcpassword=" + rpc_p + "\n") f.write("port="+str(p2p_port(n))+"\n") f.write("rpcport="+str(rpc_port(n))+"\n") f.write("listenonion=0\n") return datadir +def rpc_auth_pair(n): + return 'rpcuser💻' + str(n), 'rpcpass🔑' + str(n) def rpc_url(i, rpchost=None): - return "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i)) + rpc_u, rpc_p = rpc_auth_pair(i) + return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, rpchost or '127.0.0.1', rpc_port(i)) def wait_for_bitcoind_start(process, url, i): ''' From b4f3f198c05195efea03872fd1f2da0993f8ba19 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:00:29 +0000 Subject: [PATCH 17/49] Stop treating importaddress'ed scripts as change 595b22e Stop treating importaddress'ed scripts as change (Pieter Wuille) --- src/wallet/rpcdump.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 5ad734a8af223..b04857a6751a8 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -169,6 +169,11 @@ void ImportScript(const CScript& script, const string& strLabel, bool isRedeemSc if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel); + } else { + CTxDestination destination; + if (ExtractDestination(script, destination)) { + pwalletMain->SetAddressBook(destination, strLabel, "receive"); + } } } @@ -197,6 +202,8 @@ UniValue importaddress(const UniValue& params, bool fHelp) "4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n" "\nNote: This call can take minutes to complete if rescan is true.\n" "If you have the full public key, you should call importpubkey instead of this.\n" + "\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\n" + "as change, and not show up in many RPCs.\n" "\nExamples:\n" "\nImport a script with rescan\n" + HelpExampleCli("importaddress", "\"myscript\"") + From 1b895f03fa89367acb3458afc5cbc7635166f433 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:09:20 +0000 Subject: [PATCH 18/49] Fixes for verify-commits script 1e9aab0 Remove sipa's old revoked key from verify-commits (Peter Todd) 966151e Add README for verify-commits (Peter Todd) 11164ec Remove keys that are no longer used for merging (Peter Todd) 22421fa Remove pointless warning (Peter Todd) 9523e8a Make verify-commits path-independent (Matt Corallo) f7d4a25 Make verify-commits POSIX-compliant (Matt Corallo) --- contrib/verify-commits/README.md | 26 +++++++++++++++++++++ contrib/verify-commits/allow-revsig-commits | 2 -- contrib/verify-commits/gpg.sh | 10 ++++---- contrib/verify-commits/trusted-git-root | 2 +- contrib/verify-commits/trusted-keys | 4 ---- contrib/verify-commits/verify-commits.sh | 17 ++++++-------- 6 files changed, 39 insertions(+), 22 deletions(-) create mode 100644 contrib/verify-commits/README.md diff --git a/contrib/verify-commits/README.md b/contrib/verify-commits/README.md new file mode 100644 index 0000000000000..e9e3f65da292a --- /dev/null +++ b/contrib/verify-commits/README.md @@ -0,0 +1,26 @@ +Tooling for verification of PGP signed commits +---------------------------------------------- + +This is an incomplete work in progress, but currently includes a pre-push hook +script (`pre-push-hook.sh`) for maintainers to ensure that their own commits +are PGP signed (nearly always merge commits), as well as a script to verify +commits against a trusted keys list. + + +Using verify-commits.sh safely +------------------------------ + +Remember that you can't use an untrusted script to verify itself. This means +that checking out code, then running `verify-commits.sh` against `HEAD` is +_not_ safe, because the version of `verify-commits.sh` that you just ran could +be backdoored. Instead, you need to use a trusted version of verify-commits +prior to checkout to make sure you're checking out only code signed by trusted +keys: + + git fetch origin && \ + ./contrib/verify-commits/verify-commits.sh origin/master && \ + git checkout origin/master + +Note that the above isn't a good UI/UX yet, and needs significant improvements +to make it more convenient and reduce the chance of errors; pull-reqs +improving this process would be much appreciated. diff --git a/contrib/verify-commits/allow-revsig-commits b/contrib/verify-commits/allow-revsig-commits index 31aeb8f3d38bb..e69de29bb2d1d 100644 --- a/contrib/verify-commits/allow-revsig-commits +++ b/contrib/verify-commits/allow-revsig-commits @@ -1,2 +0,0 @@ -586a29253dabec3ca0f1ccba9091daabd16b8411 -eddaba7b5692288087a926da5733e86b47274e4e diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh index 0218b82e11dd3..375d711725707 100644 --- a/contrib/verify-commits/gpg.sh +++ b/contrib/verify-commits/gpg.sh @@ -1,8 +1,9 @@ #!/bin/sh -INPUT=$(/dev/null); do case "$LINE" in "[GNUPG:] VALIDSIG "*) @@ -13,10 +14,9 @@ for LINE in $(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null); do "[GNUPG:] REVKEYSIG "*) [ "$BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG" != 1 ] && exit 1 while read KEY; do - case "$LINE" in "[GNUPG:] REVKEYSIG ${KEY:24:40} "*) + case "$LINE" in "[GNUPG:] REVKEYSIG ${KEY#????????????????????????} "*) REVSIG=true - GOODREVSIG="[GNUPG:] GOODSIG ${KEY:24:40} " - ;; + GOODREVSIG="[GNUPG:] GOODSIG ${KEY#????????????????????????} " esac done < ./contrib/verify-commits/trusted-keys ;; diff --git a/contrib/verify-commits/trusted-git-root b/contrib/verify-commits/trusted-git-root index 838b8d1ea84bd..c60f8ab695e9c 100644 --- a/contrib/verify-commits/trusted-git-root +++ b/contrib/verify-commits/trusted-git-root @@ -1 +1 @@ -165e323d851cc87213c7673c6f278e87a6f2e752 +82bcf405f6db1d55b684a1f63a4aabad376cdad7 diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys index a0d0f82db3f43..5b64a44abfdf4 100644 --- a/contrib/verify-commits/trusted-keys +++ b/contrib/verify-commits/trusted-keys @@ -1,7 +1,3 @@ 71A3B16735405025D447E8F274810B012346C9A6 -1F4410F6A89268CE3197A84C57896D2FF8F0B657 -01CDF4627A3B88AAE4A571C87588242FBE38D3A8 -AF8BE07C7049F3A26B239D5325B3083201782B2F -81291FA67D2C379A006A053FEAB5AF94D9E9ABE7 3F1888C6DCA92A6499C4911FDBA1A67379A1A931 32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh index 9ba781008a658..30db7f8fb0d1f 100644 --- a/contrib/verify-commits/verify-commits.sh +++ b/contrib/verify-commits/verify-commits.sh @@ -1,25 +1,21 @@ #!/bin/sh +# Not technically POSIX-compliant due to use of "local", but almost every +# shell anyone uses today supports it, so its probably fine DIR=$(dirname "$0") -echo "Please verify all commits in the following list are not evil:" -git log "$DIR" +[ "/${DIR#/}" != "$DIR" ] && DIR=$(dirname "$(pwd)/$0") VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root") -IS_REVSIG_ALLOWED () { - while read LINE; do - [ "$LINE" = "$1" ] && return 0 - done < "${DIR}/allow-revsig-commits" - return 1 -} +REVSIG_ALLOWED=$(cat "${DIR}/allow-revsig-commits") HAVE_FAILED=false IS_SIGNED () { if [ $1 = $VERIFIED_ROOT ]; then return 0; fi - if IS_REVSIG_ALLOWED "$1"; then + if [ "${REVSIG_ALLOWED#*$1}" != "$REVSIG_ALLOWED" ]; then export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=1 else export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=0 @@ -27,7 +23,8 @@ IS_SIGNED () { if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then return 1; fi - local PARENTS=$(git show -s --format=format:%P $1) + local PARENTS + PARENTS=$(git show -s --format=format:%P $1) for PARENT in $PARENTS; do if IS_SIGNED $PARENT > /dev/null; then return 0; From c6c632de70a950cb386f82bf88a538741e4883c7 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:15:30 +0000 Subject: [PATCH 19/49] Evict orphans which are included or precluded by MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …accepted blocks. 54326a6 Increase maximum orphan size to 100,000 bytes. (Gregory Maxwell) 8c99d1b Treat orphans as implicit inv for parents, discard when parents rejected. (Gregory Maxwell) 11cc143 Adds an expiration time for orphan tx. (Gregory Maxwell) db0ffe8 This eliminates the primary leak that causes the orphan map to always grow to its maximum size. (Gregory Maxwell) 1b0bcc5 Track orphan by prev COutPoint rather than prev hash (Pieter Wuille) --- src/net_processing.cpp | 112 +++++++++++++++++++++++++++++------------ src/net_processing.h | 6 +++ src/test/DoS_tests.cpp | 2 +- src/validation.cpp | 24 +++++++++ src/validation.h | 2 - 5 files changed, 112 insertions(+), 34 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 3d78eb0388940..9feff2b51a335 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -52,12 +52,21 @@ int64_t nTimeBestReceived = 0; // Used only to inform the wallet of when we last extern FeeFilterRounder filterRounder; +struct IteratorComparator +{ + template + bool operator()(const I& a, const I& b) + { + return &(*a) < &(*b); + } +}; struct COrphanTx { CTransaction tx; NodeId fromPeer; + int64_t nTimeExpire; }; map mapOrphanTransactions GUARDED_BY(cs_main); -map > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);; +map::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Internal stuff @@ -521,40 +530,42 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c // large transaction with a missing parent then we assume // it will rebroadcast it later, after the parent transaction(s) // have been mined or received. - // 10,000 orphans, each of which is at most 5,000 bytes big is - // at most 500 megabytes of orphans: + // 100 orphans, each of which is at most 99,999 bytes big is + // at most 10 megabytes of orphans and somewhat more byprev index (in the worst case): unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION); - if (sz > 5000) + if (sz > MAX_STANDARD_TX_SIZE) { LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString()); return false; } - mapOrphanTransactions[hash].tx = tx; - mapOrphanTransactions[hash].fromPeer = peer; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash); + auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME}); + assert(ret.second); + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first); + } - LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(), + LogPrint("mempool", "stored orphan tx %s (mapsz %u outsz %u)\n", hash.ToString(), mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size()); return true; } -void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +int EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { map::iterator it = mapOrphanTransactions.find(hash); if (it == mapOrphanTransactions.end()) - return; + return 0; BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin) { - map >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash); + auto itPrev = mapOrphanTransactionsByPrev.find(txin.prevout); if (itPrev == mapOrphanTransactionsByPrev.end()) continue; - itPrev->second.erase(hash); + itPrev->second.erase(it); if (itPrev->second.empty()) mapOrphanTransactionsByPrev.erase(itPrev); } mapOrphanTransactions.erase(it); + return 1; } void EraseOrphansFor(NodeId peer) @@ -566,8 +577,7 @@ void EraseOrphansFor(NodeId peer) map::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid if (maybeErase->second.fromPeer == peer) { - EraseOrphanTx(maybeErase->second.tx.GetHash()); - ++nErased; + nErased += EraseOrphanTx(maybeErase->second.tx.GetHash()); } } if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer); @@ -577,6 +587,26 @@ void EraseOrphansFor(NodeId peer) unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { unsigned int nEvicted = 0; + static int64_t nNextSweep; + int64_t nNow = GetTime(); + if (nNextSweep <= nNow) { + // Sweep out expired orphan pool entries: + int nErased = 0; + int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL; + map::iterator iter = mapOrphanTransactions.begin(); + while (iter != mapOrphanTransactions.end()) + { + map::iterator maybeErase = iter++; + if (maybeErase->second.nTimeExpire <= nNow) { + nErased += EraseOrphanTx(maybeErase->second.tx.GetHash()); + } else { + nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime); + } + } + // Sweep again 5 minutes after the next entry that expires in order to batch the linear scan. + nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL; + if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx due to expiration\n", nErased); + } while (mapOrphanTransactions.size() > nMaxOrphans) { // Evict a random orphan: @@ -1533,7 +1563,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - vector vWorkQueue; + deque vWorkQueue; vector vEraseQueue; CTransaction tx; CTxLockRequest txLockRequest; @@ -1615,7 +1645,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, mempool.check(pcoinsTip); connman.RelayTransaction(tx); - vWorkQueue.push_back(inv.hash); + for (unsigned int i = 0; i < tx.vout.size(); i++) { + vWorkQueue.emplace_back(inv.hash, i); + } pfrom->nLastTXTime = GetTime(); @@ -1626,18 +1658,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Recursively process any orphan transactions that depended on this one set setMisbehaving; - for (unsigned int i = 0; i < vWorkQueue.size(); i++) - { - map >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]); + while (!vWorkQueue.empty()) { + auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front()); + vWorkQueue.pop_front(); if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; - for (set::iterator mi = itByPrev->second.begin(); + for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { - const uint256& orphanHash = *mi; - const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx; - NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer; + const CTransaction& orphanTx = (*mi)->second.tx; + const uint256& orphanHash = orphanTx.GetHash(); + NodeId fromPeer = (*mi)->second.fromPeer; bool fMissingInputs2 = false; // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get @@ -1651,7 +1683,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString()); connman.RelayTransaction(orphanTx); - vWorkQueue.push_back(orphanHash); + for (unsigned int i = 0; i < orphanTx.vout.size(); i++) { + vWorkQueue.emplace_back(orphanHash, i); + } vEraseQueue.push_back(orphanHash); } else if (!fMissingInputs2) @@ -1680,13 +1714,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (fMissingInputs) { - AddOrphanTx(tx, pfrom->GetId()); + bool fRejectedParents = false; // It may be the case that the orphans parents have all been rejected + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + if (recentRejects->contains(txin.prevout.hash)) { + fRejectedParents = true; + break; + } + } + if (!fRejectedParents) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + CInv inv(MSG_TX, txin.prevout.hash); + pfrom->AddInventoryKnown(inv); + if (!AlreadyHave(inv)) pfrom->AskFor(inv); + } + AddOrphanTx(tx, pfrom->GetId()); - // DoS prevention: do not allow mapOrphanTransactions to grow unbounded - unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS)); - unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx); - if (nEvicted > 0) - LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted); + // DoS prevention: do not allow mapOrphanTransactions to grow unbounded + unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS)); + unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx); + if (nEvicted > 0) + LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted); + } else { + LogPrint("mempool", "not keeping orphan with rejected parents %s\n",tx.GetHash().ToString()); + } } else { assert(recentRejects); recentRejects->insert(tx.GetHash()); diff --git a/src/net_processing.h b/src/net_processing.h index 13fceb55c3f7f..6354f7d47b18d 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -9,6 +9,12 @@ #include "net.h" #include "validationinterface.h" +/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ +static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; +/** Expiration time for orphan transactions in seconds */ +static const int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60; +/** Minimum time between orphan transactions expire time checks in seconds */ +static const int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60; /** Headers download timeout expressed in microseconds * Timeout = base + per_header * (expected number of headers) */ static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE = 15 * 60 * 1000000; // 15 minutes diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 505e4418b05c1..5713654d5c4e8 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); - tx.vin.resize(500); + tx.vin.resize(2777); for (unsigned int j = 0; j < tx.vin.size(); j++) { tx.vin[j].prevout.n = j; diff --git a/src/validation.cpp b/src/validation.cpp index dbaad224f4242..bc308125405b9 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2092,6 +2092,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); + std::vector vOrphanErase; std::vector prevheights; CAmount nFees = 0; int nInputs = 0; @@ -2131,6 +2132,21 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd prevheights[j] = view.AccessCoin(tx.vin[j].prevout).nHeight; } + // Which orphan pool entries must we evict? + //for (size_t j = 0; j < tx.vin.size(); j++) { + // auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); + // if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; + // for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { + // const CTransaction& orphanTx = (*mi)->second.tx; + // const uint256& orphanHash = orphanTx.GetHash(); + // vOrphanErase.push_back(orphanHash); + // } + //} + // TODO This is a temporary solution while backporting Bitcoin 0.13 changes into Dash + // It is needed because the splitting of main.cpp into validation.cpp/net_processing.cpp was done out of order + // When we catch up with backporting, the above loop will be at the correct place in net_processing.cpp + // and this hack can be removed + LoopMapOrphanTransactionsByPrev(tx, vOrphanErase); if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) { return state.DoS(100, error("%s: contains a non-BIP68-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); @@ -2315,6 +2331,14 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd static uint256 hashPrevBestCoinBase; GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); hashPrevBestCoinBase = block.vtx[0].GetHash(); + // Erase orphan transactions include or precluded by this block + if (vOrphanErase.size()) { + int nErased = 0; + BOOST_FOREACH(uint256 &orphanHash, vOrphanErase) { + nErased += EraseOrphanTx(orphanHash); + } + LogPrint("mempool", "Erased %d orphan tx included or conflicted by block\n", nErased); + } int64_t nTime6 = GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5; LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001); diff --git a/src/validation.h b/src/validation.h index 6928e3935a026..802a31cce58ec 100644 --- a/src/validation.h +++ b/src/validation.h @@ -63,8 +63,6 @@ static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.2 * COIN; // "smallest denom static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN; //! -maxtxfee will warn if called with a higher fee than this amount (in nABS) static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB; -/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ -static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default for -limitancestorcount, max number of in-mempool ancestors */ static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25; /** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */ From c587ef7146c1d9ad9afe8961a279714c4c742986 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:17:03 +0000 Subject: [PATCH 20/49] Stop trimming when mapTx is empty ad0752e Stop trimming when mapTx is empty (Pieter Wuille) --- src/txmempool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 30d2b40ed92b4..2e0bded69ee7a 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1215,7 +1215,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpends unsigned nTxnRemoved = 0; CFeeRate maxFeeRateRemoved(0); - while (DynamicMemoryUsage() > sizelimit) { + while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) { indexed_transaction_set::index::type::iterator it = mapTx.get().begin(); // We set the new mempool min fee to the feerate of the removed set, plus the From 499737626b5a6a1876a0981f59184006e530c8d6 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:19:19 +0000 Subject: [PATCH 21/49] Qa assert 'changePosition out of bounds' fa58f94 [qa] pull-tester: Start longest test first (MarcoFalke) fa3b379 [qa] pull-tester: Fix assertion and check for run_parallel (MarcoFalke) fa32465 [qa] fundrawtransaction: Create get_unspent() (MarcoFalke) fa8ce3b [qa] assert 'changePosition out of bounds' (MarcoFalke) --- qa/pull-tester/rpc-tests.py | 7 ++- qa/rpc-tests/fundrawtransaction.py | 94 +++++++----------------------- 2 files changed, 26 insertions(+), 75 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index fc559a701abba..281f8acebf8a5 100644 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -110,6 +110,8 @@ #Tests testScripts = [ + # longest test should go first, to favor running tests in parallel + 'p2p-fullblocktest.py', # NOTE: needs dash_hash to pass 'walletbackup.py', 'bip68-112-113-p2p.py', 'wallet.py', @@ -139,7 +141,6 @@ 'timestampindex.py', 'spentindex.py', 'decodescript.py', - 'p2p-fullblocktest.py', # NOTE: needs absolute_hash to pass 'blockchain.py', 'disablewallet.py', 'sendheaders.py', # NOTE: needs absolute_hash to pass @@ -206,7 +207,7 @@ def runtests(): if coverage: flags.append(coverage.flag) - if len(test_list) > 1: + if len(test_list) > 1 and run_parallel > 1: # Populate cache subprocess.check_output([RPC_TESTS_DIR + 'create_cache.py'] + flags) @@ -270,7 +271,7 @@ def get_next(self): log_stdout, log_stderr)) if not self.jobs: - raise IndexError('%s from empty list' % __name__) + raise IndexError('pop from empty list') while True: # Return first proc that finishes time.sleep(.5) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index b677a25d3c9e7..1fa1b3b75e02c 100644 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -6,7 +6,11 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -# Create one-input, one-output, no-fee transaction: +def get_unspent(listunspent, amount): + for utx in listunspent: + if utx['amount'] == amount: + return utx + raise AssertionError('Could not find unspent with amount={}'.format(amount)) class RawTransactionsTest(BitcoinTestFramework): def __init__(self): @@ -71,7 +75,7 @@ def run_test(self): rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) - assert(len(dec_tx['vin']) > 0) #test if we have enought inputs + assert(len(dec_tx['vin']) > 0) #test that we have enough inputs ############################## # simple test with two coins # @@ -123,14 +127,7 @@ def run_test(self): ######################################################################### # test a fundrawtransaction with a VIN greater than the required amount # ######################################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : 10 } @@ -151,14 +148,7 @@ def run_test(self): ##################################################################### # test a fundrawtransaction with which will not get a change output # ##################################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : Decimal(50) - fee - feeTolerance } @@ -180,14 +170,7 @@ def run_test(self): #################################################### # test a fundrawtransaction with an invalid option # #################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert_equal(utx!=False, True) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] outputs = { self.nodes[0].getnewaddress() : Decimal(40) } @@ -205,14 +188,7 @@ def run_test(self): ############################################################ # test a fundrawtransaction with an invalid change address # ############################################################ - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert_equal(utx!=False, True) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] outputs = { self.nodes[0].getnewaddress() : Decimal(40) } @@ -231,14 +207,7 @@ def run_test(self): ############################################################ # test a fundrawtransaction with a provided change address # ############################################################ - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert_equal(utx!=False, True) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] outputs = { self.nodes[0].getnewaddress() : Decimal(40) } @@ -247,6 +216,12 @@ def run_test(self): assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) change = self.nodes[2].getnewaddress() + try: + rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 2}) + except JSONRPCException as e: + assert('changePosition out of bounds' == e.error['message']) + else: + assert(False) rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0}) dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) out = dec_tx['vout'][0]; @@ -257,14 +232,7 @@ def run_test(self): ######################################################################### # test a fundrawtransaction with a VIN smaller than the required amount # ######################################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 10: - utx = aUtx - break - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 10) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : 10 } @@ -299,17 +267,8 @@ def run_test(self): ########################################### # test a fundrawtransaction with two VINs # ########################################### - utx = False - utx2 = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 10: - utx = aUtx - if aUtx['amount'] == 50: - utx2 = aUtx - - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 10) + utx2 = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] outputs = { self.nodes[0].getnewaddress() : 60 } @@ -341,17 +300,8 @@ def run_test(self): ######################################################### # test a fundrawtransaction with two VINs and two vOUTs # ######################################################### - utx = False - utx2 = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 10: - utx = aUtx - if aUtx['amount'] == 50: - utx2 = aUtx - - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 10) + utx2 = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] outputs = { self.nodes[0].getnewaddress() : 60, self.nodes[0].getnewaddress() : 10 } From 0d3bcd71d63b4e4ced34c4df0968a72ca113ba6b Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:28:25 +0000 Subject: [PATCH 22/49] Doc Update OS X build notes for 10.11 SDK e5a680d [Doc] Update OS X build notes for 10.11 SDK (fanquake) --- doc/{README_osx.txt => README_osx.md} | 27 ++++++++++++++------------- doc/build/build-osx.md | 8 +++++--- doc/release-process.md | 14 ++++---------- 3 files changed, 23 insertions(+), 26 deletions(-) rename doc/{README_osx.txt => README_osx.md} (81%) diff --git a/doc/README_osx.txt b/doc/README_osx.md similarity index 81% rename from doc/README_osx.txt rename to doc/README_osx.md index c13efaa145c83..13732d15fc75f 100644 --- a/doc/README_osx.txt +++ b/doc/README_osx.md @@ -1,21 +1,19 @@ Deterministic OS X Dmg Notes. Working OS X DMGs are created in Linux by combining a recent clang, -the Apple's binutils (ld, ar, etc), and DMG authoring tools. +the Apple binutils (ld, ar, etc) and DMG authoring tools. Apple uses clang extensively for development and has upstreamed the necessary functionality so that a vanilla clang can take advantage. It supports the use of -F, -target, -mmacosx-version-min, and --sysroot, which are all necessary -when building for OS X. A pre-compiled version of 3.2 is used because it was not -available in the Precise repositories at the time this work was started. In the -future, it can be switched to use system packages instead. +when building for OS X. Apple's version of binutils (called cctools) contains lots of functionality missing in the FSF's binutils. In addition to extra linker options for frameworks and sysroots, several other tools are needed as well such as install_name_tool, lipo, and nmedit. These do not build under linux, so they have been patched to do so. The work here was used as a starting point: -https://github.com/mingwandroid/toolchain4 +[mingwandroid/toolchain4](https://github.com/mingwandroid/toolchain4). In order to build a working toolchain, the following source packages are needed from Apple: cctools, dyld, and ld64. @@ -29,15 +27,19 @@ originally done in toolchain4. To complicate things further, all builds must target an Apple SDK. These SDKs are free to download, but not redistributable. -To obtain it, register for a developer account, then download the Xcode 6.1.1 dmg: -https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg +To obtain it, register for a developer account, then download the [Xcode 7.3.1 dmg](https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/Xcode_7.3.1/Xcode_7.3.1.dmg). This file is several gigabytes in size, but only a single directory inside is -needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk +needed: +``` +Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk +``` Unfortunately, the usual linux tools (7zip, hpmount, loopback mount) are incapable of opening this file. To create a tarball suitable for Gitian input, mount the dmg in OS X, then create it with: - $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk +``` + $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.11.sdk.tar.gz MacOSX10.11.sdk +``` The Gitian descriptors build 2 sets of files: Linux tools, then Apple binaries @@ -48,15 +50,14 @@ fully deterministic and may be freely redistributed. genisoimage is used to create the initial DMG. It is not deterministic as-is, so it has been patched. A system genisoimage will work fine, but it will not be deterministic because the file-order will change between invocations. -The patch can be seen here: -https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff +The patch can be seen here: [theuni/osx-cross-depends](https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff). No effort was made to fix this cleanly, so it likely leaks memory badly. But it's only used for a single invocation, so that's no real concern. genisoimage cannot compress DMGs, so afterwards, the 'dmg' tool from the libdmg-hfsplus project is used to compress it. There are several bugs in this tool and its maintainer has seemingly abandoned the project. It has been forked -and is available (with fixes) here: https://github.com/theuni/libdmg-hfsplus . +and is available (with fixes) here: [theuni/libdmg-hfsplus](https://github.com/theuni/libdmg-hfsplus). The 'dmg' tool has the ability to create DMGs from scratch as well, but this functionality is broken. Only the compression feature is currently used. @@ -77,6 +78,6 @@ build process to remain somewhat deterministic. Here's how it works: that have been previously (deterministically) built in order to create a final dmg. - The Apple keyholder uses this unsigned app to create a detached signature, - using the script that is also included there. + using the script that is also included there. Detached signatures are available from this [repository](https://github.com/bitcoin-core/bitcoin-detached-sigs). - Builders feed the unsigned app + detached signature back into Gitian. It uses the pre-built tools to recombine the pieces into a deterministic dmg. diff --git a/doc/build/build-osx.md b/doc/build/build-osx.md index bee8bff8496c2..895ef137b624b 100644 --- a/doc/build/build-osx.md +++ b/doc/build/build-osx.md @@ -5,11 +5,13 @@ The built-in one is located in `/Applications/Utilities/Terminal.app`. Preparation ----------- -Download and install [Xcode](https://developer.apple.com/xcode/download). +Install the OS X command line tools: -Once installed, run `xcode-select --install` to install the OS X command line tools. +O`xcode-select --install` -Install [Homebrew](http://brew.sh). +When the popup appears, click `Install`. + +Then install [Homebrew](http://brew.sh). Dependencies ---------------------- diff --git a/doc/release-process.md b/doc/release-process.md index f5d8ca7bdb276..c126ef119d867 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -1,12 +1,12 @@ Release Process ==================== -* Update translations, see [translation_process.md](https://github.com/absolute-community/absolute/blob/master/doc/translation_process.md#syncing-with-transifex) +* Update translations, see [translation_process.md](https://github.com/absolute-community/absolute/blob/master/doc/translation_process.md#synchronising-translations). * Update hardcoded [seeds](/contrib/seeds) * * * -###First time / New builders +### First time / New builders Check out the source code in the following directory hierarchy. cd /path/to/your/toplevel/build @@ -53,7 +53,7 @@ Check out the source code in the following directory hierarchy. git pull popd - Ensure gitian-builder is up-to-date to take advantage of new caching features (`e9741525c` or later is recommended). + Ensure gitian-builder is up-to-date: pushd ./gitian-builder git pull @@ -64,13 +64,7 @@ Check out the source code in the following directory hierarchy. wget -P inputs https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch wget -P inputs http://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz - Register and download the Apple SDK: see [OS X readme](README_osx.txt) for details. - - https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg - - Using a Mac, create a tarball for the 10.9 SDK and copy it to the inputs directory: - - tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk + Create the OS X SDK tarball, see the [OS X readme](README_osx.md) for details, and copy it into the inputs directory. ### Optional: Seed the Gitian sources cache and offline git repositories From 8df78e90507d4d0819fc7c8f32caf639af2018a3 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:30:22 +0000 Subject: [PATCH 23/49] Enable mempool consistency checks in unit tests 3775ff9 Enable mempool consistency checks in unit tests (Pieter Wuille) --- src/test/test_absolute.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/test_absolute.cpp b/src/test/test_absolute.cpp index b4a40d6171efe..2d9589556c851 100644 --- a/src/test/test_absolute.cpp +++ b/src/test/test_absolute.cpp @@ -59,6 +59,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pathTemp = GetTempPath() / strprintf("test_absolute_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); boost::filesystem::create_directories(pathTemp); mapArgs["-datadir"] = pathTemp.string(); + mempool.setSanityCheck(1.0); pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); From 9229d4d50f68803fcfc83c20f24fe5ff27c8fd39 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:32:03 +0000 Subject: [PATCH 24/49] Trivial capitalize BIP32 in option help a1c92c2 trivial: capitalize BIP32 in option help (Wladimir J. van der Laan) --- src/wallet/wallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c40e783b36c4a..0f4f59658d201 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4524,9 +4524,9 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after bip39/bip44. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); + strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP39/BIP44. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); strUsage += HelpMessageOpt("-mnemonic", _("User defined mnemonic for HD wallet (bip39). Only has effect during wallet creation/first start (default: randomly generated)")); - strUsage += HelpMessageOpt("-mnemonicpassphrase", _("User defined mnemonic passphrase for HD wallet (bip39). Only has effect during wallet creation/first start (default: empty string)")); + strUsage += HelpMessageOpt("-mnemonicpassphrase", _("User defined mnemonic passphrase for HD wallet (BIP39). Only has effect during wallet creation/first start (default: empty string)")); strUsage += HelpMessageOpt("-hdseed", _("User defined seed for HD wallet (should be in hex). Only has effect during wallet creation/first start (default: randomly generated)")); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); From b989a76dec8841506ac4e59c9babe5676a22830a Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:33:50 +0000 Subject: [PATCH 25/49] Doc Add OSX ZMQ requirement to QA readme d241487 [doc] Add OS X ZMQ requirement to QA readme (fanquake) --- qa/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qa/README.md b/qa/README.md index e8b9a98c79893..7f0259e2e81a5 100644 --- a/qa/README.md +++ b/qa/README.md @@ -16,6 +16,11 @@ The python3-zmq library is required. On Ubuntu or Debian it can be installed via sudo apt-get install python3-zmq ``` +OS X +------ +``` +pip3 install pyzmq +``` Running tests ============= @@ -36,7 +41,7 @@ Run all possible tests with qa/pull-tester/rpc-tests.py -extended By default, tests will be run in parallel if you want to specify how many -tests should be run in parallel, append `-paralell=n` (default n=4). +tests should be run in parallel, append `-parallel=n` (default n=4). If you want to create a basic coverage report for the rpc test suite, append `--coverage`. From 048cc84ad5b7c3d2f50bf4c39aec0e7bd2bd6729 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:36:31 +0000 Subject: [PATCH 26/49] BUG bitcoin-qt crash d7828ab check that transactionView->selectionModel()->selectedRows(0) exists (fsb4000) --- src/qt/transactionview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 6e39bdb25d19c..44a1b74f26761 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -404,6 +404,8 @@ void TransactionView::contextualMenu(const QPoint &point) { QModelIndex index = transactionView->indexAt(point); QModelIndexList selection = transactionView->selectionModel()->selectedRows(0); + if (selection.empty()) + return; // check if transaction can be abandoned, disable context menu action in case it doesn't uint256 hash; From 2d98c038473e85353725a7addc9b5945561a4486 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:36:47 +0000 Subject: [PATCH 27/49] Trivial Add aarch64 to depends .gitignore f70bcfc [trivial] Add aarch64 to depends .gitignore (fanquake) --- depends/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/.gitignore b/depends/.gitignore index 1f163897b9ef7..3cb4b9ac15557 100644 --- a/depends/.gitignore +++ b/depends/.gitignore @@ -7,3 +7,4 @@ x86_64* i686* mips* arm* +aarch64* From 13724857952af60d2b951a6d55f8760e6f367d0d Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:41:46 +0000 Subject: [PATCH 28/49] Windows Add testnet link to installer 975a41d windows: Add testnet icon for testnet link (Wladimir J. van der Laan) 0ce8e99 windows: Add testnet link to installer (Wladimir J. van der Laan) --- share/setup.nsi.in | 2 ++ src/Makefile.qt.include | 1 + src/qt/res/absolute-qt-res.rc | 1 + src/qt/res/icons/bitcoin_testnet.ico | Bin 0 -> 67646 bytes 4 files changed, 4 insertions(+) create mode 100644 src/qt/res/icons/bitcoin_testnet.ico diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 0282a6d226ec3..34c2f95cd43a9 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -92,6 +92,7 @@ Section -post SEC0001 !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory $SMPROGRAMS\$StartMenuGroup CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" "-testnet" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" 1 CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" @@ -139,6 +140,7 @@ Section -un.post UNSEC0001 DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" Delete /REBOOTOK "$SMSTARTUP\Absolute.lnk" Delete /REBOOTOK $INSTDIR\uninstall.exe Delete /REBOOTOK $INSTDIR\debug.log diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index aa82bf6123c9b..d8aaa9f8ce594 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -169,6 +169,7 @@ BITCOIN_QT_H = \ RES_ICONS = \ qt/res/icons/bitcoin.ico \ + qt/res/icons/bitcoin_testnet.ico \ qt/res/icons/bitcoin.png \ qt/res/icons/chevron.png \ qt/res/icons/warning.png \ diff --git a/src/qt/res/absolute-qt-res.rc b/src/qt/res/absolute-qt-res.rc index 8ce6c2cdca32f..eea5615e7c69c 100644 --- a/src/qt/res/absolute-qt-res.rc +++ b/src/qt/res/absolute-qt-res.rc @@ -1,4 +1,5 @@ IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico" +IDI_ICON2 ICON DISCARDABLE "icons/bitcoin_testnet.ico" #include // needed for VERSIONINFO #include "../../clientversion.h" // holds the needed client version information diff --git a/src/qt/res/icons/bitcoin_testnet.ico b/src/qt/res/icons/bitcoin_testnet.ico new file mode 100644 index 0000000000000000000000000000000000000000..3ab80af66890843f7a14ee9c8fbbfc99265a5afe GIT binary patch literal 67646 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 literal 0 HcmV?d00001 From 2b58a380b7d1e6b17a5e4160601bc08c6de8089a Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:42:38 +0000 Subject: [PATCH 29/49] Tests Increase sync_blocks() timeouts in pruning.py 36f1b9d Tests: Increase sync_blocks() timeouts in pruning.py (Suhas Daftuar) --- qa/rpc-tests/pruning.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 928ccb40b983f..ec7eee1476284 100644 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -150,14 +150,14 @@ def reorg_test(self): print("Reconnect nodes") connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[2], 1) - sync_blocks(self.nodes[0:3]) + sync_blocks(self.nodes[0:3], timeout=120) print("Verify height on node 2:",self.nodes[2].getblockcount()) print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)) print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)") self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects - sync_blocks(self.nodes[0:3]) + sync_blocks(self.nodes[0:3], timeout=300) usage = calc_usage(self.prunedir) print("Usage should be below target:", usage) From fd82920789226c41febbfd090b43e9b4d025afa9 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:48:14 +0000 Subject: [PATCH 30/49] Wallet Revert input selection post-pruning 20f3cd7 wallet: Revert input selection post-pruning (Wladimir J. van der Laan) --- src/wallet/test/wallet_tests.cpp | 13 ------------- src/wallet/wallet.cpp | 9 --------- 2 files changed, 22 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 0a4f06ba88175..31935a1324181 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -350,19 +350,6 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset) BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); - empty_wallet(); - - // Test trimming - for (int i = 0; i < 100; i++) - add_coin(10 * COIN); - for (int i = 0; i < 100; i++) - add_coin(1000 * COIN); - - BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); - // We need all 100 larger coins and exactly one small coin. - // Superfluous small coins must be trimmed from the set: - BOOST_CHECK_EQUAL(nValueRet, 100010 * COIN); - BOOST_CHECK_EQUAL(setCoinsRet.size(), 101); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 0f4f59658d201..7aa21cb950ad5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2539,15 +2539,6 @@ static void ApproximateBestSubset(vector= nTargetValue ) - { - vfBest[i] = false; - nBest -= vValue[i].first; - } - } } // move denoms down From 45076d0ef0d111c28ceb93afa988f87752842aaa Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:48:31 +0000 Subject: [PATCH 31/49] Qt Network-specific example address 4f44cb6 qt: Network-specific example address (Wladimir J. van der Laan) --- src/qt/guiutil.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 275f6f813fd61..7e9eb20d6e54d 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -110,6 +110,22 @@ QFont fixedPitchFont() #endif } +// Just some dummy data to generate an convincing random-looking (but consistent) address +static const uint8_t dummydata[] = {0xeb,0x15,0x23,0x1d,0xfc,0xeb,0x60,0x92,0x58,0x86,0xb6,0x7d,0x06,0x52,0x99,0x92,0x59,0x15,0xae,0xb1,0x72,0xc0,0x66,0x47}; + +// Generate a dummy address with invalid CRC, starting with the network prefix. +static std::string DummyAddress(const CChainParams ¶ms) +{ + std::vector sourcedata = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); + sourcedata.insert(sourcedata.end(), dummydata, dummydata + sizeof(dummydata)); + for(int i=0; i<256; ++i) { // Try every trailing byte + std::string s = EncodeBase58(begin_ptr(sourcedata), end_ptr(sourcedata)); + if (!CBitcoinAddress(s).IsValid()) + return s; + sourcedata[sourcedata.size()-1] += 1; + } + return ""; +} void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) { parent->setFocusProxy(widget); @@ -118,7 +134,8 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) #if QT_VERSION >= 0x040700 // We don't want translators to use own addresses in translations // and this is the only place, where this address is supplied. - widget->setPlaceholderText(QObject::tr("Enter a Absolute address (e.g. %1)").arg("AaCk5RXBVuJxKZn984uLK4cmFHC9p5hbBT")); + widget->setPlaceholderText(QObject::tr("Enter a Absolute address (e.g. %1)").arg( + QString::fromStdString(DummyAddress(Params())))); #endif widget->setValidator(new BitcoinAddressEntryValidator(parent)); widget->setCheckValidator(new BitcoinAddressCheckValidator(parent)); From 1b768361b85665ea4e55452fef028d454dde436d Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:49:49 +0000 Subject: [PATCH 32/49] Build require boost for bench cf2ef78 build: require boost for bench (Cory Fields) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d0d9b9c19629b..403787ad975f4 100644 --- a/configure.ac +++ b/configure.ac @@ -592,7 +592,7 @@ BITCOIN_QT_INIT dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt5]) -if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then +if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then use_boost=no else use_boost=yes From 091a63acd2a9e7818fb901b92399a9eaaf9504e6 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:51:24 +0000 Subject: [PATCH 33/49] Doc Update bips.md for CSV softfork. ab0c35a [Doc] Update bips.md for CSV softfork. (fanquake) --- doc/bips.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/bips.md b/doc/bips.md index b4b62e781ec61..eae067ccfcdbc 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -17,11 +17,11 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)). * [`BIP 65`](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki): The CHECKLOCKTIMEVERIFY softfork was merged in **v0.12.0** ([PR #6351](https://github.com/bitcoin/bitcoin/pull/6351)), and backported to **v0.11.2** and **v0.10.4**. Mempool-only CLTV was added in [PR #6124](https://github.com/bitcoin/bitcoin/pull/6124). * [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). -* [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)). +* [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)), and have been activated since *block 419328*. * [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). * [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)). -* [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)). -* [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)). +* [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)) and has been activated since *block 419328*. +* [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)) and have been activated since *block 419328*. * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). * [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). From 90b508c957836820bdcd07e76f693bab5ba68e2f Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:56:14 +0000 Subject: [PATCH 34/49] Gitian: Don't require sudo for Linux. 099d4b0 gitian: use a wrapped gcc/g++ to avoid the need for a system change (Cory Fields) --- contrib/gitian-descriptors/gitian-linux.yml | 37 ++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 4291b78b72cc4..4a2a66ba3ae75 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -32,11 +32,7 @@ remotes: "dir": "absolute" files: [] script: | - #unlock sudo - echo "ubuntu" | sudo -S true - sudo mkdir -p /usr/include/i386-linux-gnu/ - sudo ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/i386-linux-gnu/asm WRAP_DIR=$HOME/wrapped HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" @@ -87,13 +83,46 @@ script: | create_per-host_faketime_wrappers "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} + EXTRA_INCLUDES_BASE=$WRAP_DIR/extra_includes + mkdir -p $EXTRA_INCLUDES_BASE + + # x86 needs /usr/include/i386-linux-gnu/asm pointed to /usr/include/x86_64-linux-gnu/asm, + # but we can't write there. Instead, create a link here and force it to be included in the + # search paths by wrapping gcc/g++. + + mkdir -p $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu + rm -f $WRAP_DIR/extra_includes/i686-pc-linux-gnu/asm + ln -s /usr/include/x86_64-linux-gnu/asm $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu/asm + + for prog in gcc g++; do + rm -f ${WRAP_DIR}/${prog} + cat << EOF > ${WRAP_DIR}/${prog} + #!/bin/bash + REAL="`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1`" + for var in "\$@" + do + if [ "\$var" = "-m32" ]; then + export C_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" + export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" + break + fi + done + \$REAL \$@ + EOF + chmod +x ${WRAP_DIR}/${prog} + done cd absolute chmod 777 depends/config.sub chmod 777 depends/config.guess BASEPREFIX=`pwd`/depends # Build dependencies for each host for i in $HOSTS; do + EXTRA_INCLUDES="$EXTRA_INCLUDES_BASE/$i" + if [ -d "$EXTRA_INCLUDES" ]; then + export HOST_ID_SALT="$EXTRA_INCLUDES" + fi make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + unset HOST_ID_SALT done # Faketime for binaries From ca39770bfbe624333a90af8e0db3631b30f2a28c Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 16:58:04 +0000 Subject: [PATCH 35/49] Fix pkg-config issues for 0.13 b556bed build: fix Windows builds without pkg-config (Cory Fields) 0c928cb build: Fix Qt5PlatformSupport check without pkg-config (Cory Fields) --- configure.ac | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 403787ad975f4..48ae32155bd1a 100644 --- a/configure.ac +++ b/configure.ac @@ -87,9 +87,6 @@ AC_PATH_TOOL(OBJCOPY, objcopy) AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files) -dnl pkg-config check. -PKG_PROG_PKG_CONFIG - # Enable wallet AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--disable-wallet], @@ -384,6 +381,15 @@ case $host in ;; esac +if test x$use_pkgconfig = xyes; then + m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) + m4_ifdef([PKG_PROG_PKG_CONFIG], [ + PKG_PROG_PKG_CONFIG + if test x"$PKG_CONFIG" = "x"; then + AC_MSG_ERROR(pkg-config not found.) + fi + ]) +fi if test x$use_comparison_tool != xno; then AC_SUBST(JAVA_COMPARISON_TOOL, $use_comparison_tool) fi @@ -762,11 +768,7 @@ fi if test x$use_pkgconfig = xyes; then - if test x"$PKG_CONFIG" = "x"; then - AC_MSG_ERROR(pkg-config not found.) - fi - - : #NOP + : dnl m4_ifdef( [PKG_CHECK_MODULES], [ @@ -1067,6 +1069,13 @@ AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) +AC_SUBST(CRYPTO_LIBS) +AC_SUBST(SSL_LIBS) +AC_SUBST(EVENT_LIBS) +AC_SUBST(EVENT_PTHREADS_LIBS) +AC_SUBST(ZMQ_LIBS) +AC_SUBST(PROTOBUF_LIBS) +AC_SUBST(QR_LIBS) AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) From cdd1d3c46c736f63312621668609a5480f835d00 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 17:04:39 +0000 Subject: [PATCH 36/49] bash-completion: Adapt for 0.12 and 0.13 1ba3db6 bash-completion: Adapt for 0.12 and 0.13 (Christian von Roques) --- contrib/absolute-cli.bash-completion | 154 +++++++++++++++++++++++++++ contrib/absolute-tx.bash-completion | 57 ++++++++++ contrib/absoluted.bash-completion | 106 ++---------------- 3 files changed, 220 insertions(+), 97 deletions(-) create mode 100644 contrib/absolute-cli.bash-completion create mode 100644 contrib/absolute-tx.bash-completion diff --git a/contrib/absolute-cli.bash-completion b/contrib/absolute-cli.bash-completion new file mode 100644 index 0000000000000..20cb1f53f28f6 --- /dev/null +++ b/contrib/absolute-cli.bash-completion @@ -0,0 +1,154 @@ +# bash programmable completion for absolute-cli(1) +# Copyright (c) 2012-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# call $absolute-cli for RPC +_absolute_rpc() { + # determine already specified args necessary for RPC + local rpcargs=() + for i in ${COMP_LINE}; do + case "$i" in + -conf=*|-datadir=*|-regtest|-rpc*|-testnet) + rpcargs=( "${rpcargs[@]}" "$i" ) + ;; + esac + done + $absolute_cli "${rpcargs[@]}" "$@" +} + +# Add wallet accounts to COMPREPLY +_absolute_accounts() { + local accounts + accounts=$(_absolute_rpc listaccounts | awk -F '"' '{ print $2 }') + COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) +} + +_absolute_cli() { + local cur prev words=() cword + local absolute_cli + + # save and use original argument to invoke absolute-cli for -help, help and RPC + # as absolute-cli might not be in $PATH + absolute_cli="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n = cur prev words cword + + if ((cword > 5)); then + case ${words[cword-5]} in + sendtoaddress) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 4)); then + case ${words[cword-4]} in + importaddress|listtransactions|setban) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + signrawtransaction) + COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 3)); then + case ${words[cword-3]} in + addmultisigaddress) + _absolute_accounts + return 0 + ;; + getbalance|gettxout|importaddress|importpubkey|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 2)); then + case ${words[cword-2]} in + addnode) + COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) ) + return 0 + ;; + setban) + COMPREPLY=( $( compgen -W "add remove" -- "$cur" ) ) + return 0 + ;; + fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + move|setaccount) + _absolute_accounts + return 0 + ;; + esac + fi + + case "$prev" in + backupwallet|dumpwallet|importwallet) + _filedir + return 0 + ;; + getaddednodeinfo|getrawmempool|lockunspent|setgenerate) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) + _absolute_accounts + return 0 + ;; + esac + + case "$cur" in + -conf=*) + cur="${cur#*=}" + _filedir + return 0 + ;; + -datadir=*) + cur="${cur#*=}" + _filedir -d + return 0 + ;; + -*=*) # prevent nonsense completions + return 0 + ;; + *) + local helpopts commands + + # only parse -help if senseful + if [[ -z "$cur" || "$cur" =~ ^- ]]; then + helpopts=$($absolute_cli -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + fi + + # only parse help if senseful + if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then + commands=$(_absolute_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }') + fi + + COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) ) + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + return 0 + ;; + esac +} && +complete -F _absolute_cli absolute-cli + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/absolute-tx.bash-completion b/contrib/absolute-tx.bash-completion new file mode 100644 index 0000000000000..fe6d61808d7c6 --- /dev/null +++ b/contrib/absolute-tx.bash-completion @@ -0,0 +1,57 @@ +# bash programmable completion for absolute-tx(1) +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +_absolute_tx() { + local cur prev words=() cword + local absolute_tx + + # save and use original argument to invoke absolute-tx for -help + # it might not be in $PATH + absolute_tx="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n =: cur prev words cword + + case "$cur" in + load=*:*) + cur="${cur#load=*:}" + _filedir + return 0 + ;; + *=*) # prevent attempts to complete other arguments + return 0 + ;; + esac + + if [[ "$cword" == 1 || ( "$prev" != "-create" && "$prev" == -* ) ]]; then + # only options (or an uncompletable hex-string) allowed + # parse absolute-tx -help for options + local helpopts + helpopts=$($absolute_tx -help | sed -e '/^ -/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) + else + # only commands are allowed + # parse -help for commands + local helpcmds + helpcmds=$($absolute_tx -help | sed -e '1,/Commands:/d' -e 's/=.*/=/' -e '/^ [a-z]/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpcmds" -- "$cur" ) ) + fi + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + + return 0 +} && +complete -F _absolute_tx absolute-tx + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/absoluted.bash-completion b/contrib/absoluted.bash-completion index fdde5b4233072..019373b1a6930 100644 --- a/contrib/absoluted.bash-completion +++ b/contrib/absoluted.bash-completion @@ -1,102 +1,21 @@ # bash programmable completion for absoluted(1) and absolute-cli(1) -# Copyright (c) 2012,2014 Christian von Roques +# Copyright (c) 2012-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -have absoluted && { - -# call $absoluted for RPC -_absolute_rpc() { - # determine already specified args necessary for RPC - local rpcargs=() - for i in ${COMP_LINE}; do - case "$i" in - -conf=*|-proxy*|-rpc*) - rpcargs=( "${rpcargs[@]}" "$i" ) - ;; - esac - done - $absoluted "${rpcargs[@]}" "$@" -} - -# Add absolute accounts to COMPREPLY -_absolute_accounts() { - local accounts - accounts=$(_absolute_rpc listaccounts | awk '/".*"/ { a=$1; gsub(/"/, "", a); print a}') - COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) -} - _absoluted() { local cur prev words=() cword local absoluted - # save and use original argument to invoke absoluted - # absoluted might not be in $PATH + # save and use original argument to invoke absoluted for -help + # it might not be in $PATH absoluted="$1" COMPREPLY=() _get_comp_words_by_ref -n = cur prev words cword - if ((cword > 4)); then - case ${words[cword-4]} in - listtransactions) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - signrawtransaction) - COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) - return 0 - ;; - esac - fi - - if ((cword > 3)); then - case ${words[cword-3]} in - addmultisigaddress) - _absolute_accounts - return 0 - ;; - getbalance|gettxout|importaddress|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - esac - fi - - if ((cword > 2)); then - case ${words[cword-2]} in - addnode) - COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) ) - return 0 - ;; - getblock|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - move|setaccount) - _absolute_accounts - return 0 - ;; - esac - fi - - case "$prev" in - backupwallet|dumpwallet|importwallet) - _filedir - return 0 - ;; - getmempool|lockunspent|setgenerate) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) - _absolute_accounts - return 0 - ;; - esac - case "$cur" in - -conf=*|-pid=*|-loadblock=*|-wallet=*) + -conf=*|-pid=*|-loadblock=*|-rootcertificates=*|-rpccookiefile=*|-wallet=*) cur="${cur#*=}" _filedir return 0 @@ -110,20 +29,14 @@ _absoluted() { return 0 ;; *) - local helpopts commands - # only parse --help if senseful + # only parse -help if senseful if [[ -z "$cur" || "$cur" =~ ^- ]]; then - helpopts=$($absoluted --help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) - fi - - # only parse help if senseful - if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then - commands=$(_absolute_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }') + local helpopts + helpopts=$($absoluted -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) fi - COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) ) - # Prevent space if an argument is desired if [[ $COMPREPLY == *= ]]; then compopt -o nospace @@ -131,10 +44,9 @@ _absoluted() { return 0 ;; esac -} +} && complete -F _absoluted absoluted absolute-cli -} # Local variables: # mode: shell-script From d7f66add07150891e7d4a4d603f10413646d702a Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 17:08:44 +0000 Subject: [PATCH 37/49] Improve handling of unconnecting headers e91cf4b Add test for handling of unconnecting headers (Suhas Daftuar) 96fa953 Improve handling of unconnecting headers (Suhas Daftuar) --- qa/rpc-tests/sendheaders.py | 101 ++++++++++++++++++++++++++++++++++++ src/net_processing.cpp | 37 ++++++++++++- src/validation.h | 2 + 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 6ab17d59b3878..d434e4def8183 100644 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -63,6 +63,20 @@ Expect: getdata request for 14 more blocks. f. Announce 1 more header that builds on that fork. Expect: no response. +Part 5: Test handling of headers that don't connect. +a. Repeat 10 times: + 1. Announce a header that doesn't connect. + Expect: getheaders message + 2. Send headers chain. + Expect: getdata for the missing blocks, tip update. +b. Then send 9 more headers that don't connect. + Expect: getheaders message each time. +c. Announce a header that does connect. + Expect: no response. +d. Announce 49 headers that don't connect. + Expect: getheaders message each time. +e. Announce one more that doesn't connect. + Expect: disconnect. ''' class BaseNode(NodeConnCB): @@ -77,6 +91,8 @@ def __init__(self): self.last_getdata = None self.sleep_time = 0.05 self.block_announced = False + self.last_getheaders = None + self.disconnected = False def clear_last_announcement(self): with mininode_lock: @@ -127,6 +143,11 @@ def on_getdata(self, conn, message): def on_pong(self, conn, message): self.last_pong = message + def on_getheaders(self, conn, message): + self.last_getheaders = message + + def on_close(self, conn): + self.disconnected = True # Test whether the last announcement we received had the # right header or the right inv # inv and headers should be lists of block hashes @@ -178,6 +199,10 @@ def wait_for_block(self, blockhash, timeout=60): self.sync(test_function, timeout) return + def wait_for_getheaders(self, timeout=60): + test_function = lambda: self.last_getheaders != None + self.sync(test_function, timeout) + return def wait_for_getdata(self, hash_list, timeout=60): if hash_list == []: return @@ -186,6 +211,11 @@ def wait_for_getdata(self, hash_list, timeout=60): self.sync(test_function, timeout) return + def wait_for_disconnect(self, timeout=60): + test_function = lambda: self.disconnected + self.sync(test_function, timeout) + return + def send_header_for_blocks(self, new_blocks): headers_message = msg_headers() headers_message.headers = [ CBlockHeader(b) for b in new_blocks ] @@ -509,6 +539,77 @@ def run_test(self): assert_equal(test_node.last_getdata, None) print("Part 4: success!") + # Now deliver all those blocks we announced. + [ test_node.send_message(msg_block(x)) for x in blocks ] + + print("Part 5: Testing handling of unconnecting headers") + # First we test that receipt of an unconnecting header doesn't prevent + # chain sync. + for i in range(10): + test_node.last_getdata = None + blocks = [] + # Create two more blocks. + for j in range(2): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + # Send the header of the second block -> this won't connect. + with mininode_lock: + test_node.last_getheaders = None + test_node.send_header_for_blocks([blocks[1]]) + test_node.wait_for_getheaders(timeout=1) + test_node.send_header_for_blocks(blocks) + test_node.wait_for_getdata([x.sha256 for x in blocks]) + [ test_node.send_message(msg_block(x)) for x in blocks ] + test_node.sync_with_ping() + assert_equal(int(self.nodes[0].getbestblockhash(), 16), blocks[1].sha256) + + blocks = [] + # Now we test that if we repeatedly don't send connecting headers, we + # don't go into an infinite loop trying to get them to connect. + MAX_UNCONNECTING_HEADERS = 10 + for j in range(MAX_UNCONNECTING_HEADERS+1): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + + for i in range(1, MAX_UNCONNECTING_HEADERS): + # Send a header that doesn't connect, check that we get a getheaders. + with mininode_lock: + test_node.last_getheaders = None + test_node.send_header_for_blocks([blocks[i]]) + test_node.wait_for_getheaders(timeout=1) + + # Next header will connect, should re-set our count: + test_node.send_header_for_blocks([blocks[0]]) + + # Remove the first two entries (blocks[1] would connect): + blocks = blocks[2:] + + # Now try to see how many unconnecting headers we can send + # before we get disconnected. Should be 5*MAX_UNCONNECTING_HEADERS + for i in range(5*MAX_UNCONNECTING_HEADERS - 1): + # Send a header that doesn't connect, check that we get a getheaders. + with mininode_lock: + test_node.last_getheaders = None + test_node.send_header_for_blocks([blocks[i%len(blocks)]]) + test_node.wait_for_getheaders(timeout=1) + + # Eventually this stops working. + with mininode_lock: + self.last_getheaders = None + test_node.send_header_for_blocks([blocks[-1]]) + + # Should get disconnected + test_node.wait_for_disconnect() + with mininode_lock: + self.last_getheaders = True + + print("Part 5: success!") # Finally, check that the inv node never received a getdata request, # throughout the test diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 9feff2b51a335..b080ea069f334 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -165,6 +165,8 @@ struct CNodeState { CBlockIndex *pindexLastCommonBlock; //! The best header we have sent our peer. CBlockIndex *pindexBestHeaderSent; + //! Length of current-streak of unconnecting headers announcements + int nUnconnectingHeaders; //! Whether we've started headers synchronization with this peer. bool fSyncStarted; //! When to potentially disconnect peer for stalling headers download @@ -189,6 +191,7 @@ struct CNodeState { hashLastUnknownBlock.SetNull(); pindexLastCommonBlock = NULL; pindexBestHeaderSent = NULL; + nUnconnectingHeaders = 0; fSyncStarted = false; nHeadersSyncTimeout = 0; nStallingSince = 0; @@ -1808,6 +1811,34 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CBlockIndex *pindexLast = NULL; { LOCK(cs_main); + CNodeState *nodestate = State(pfrom->GetId()); + + // If this looks like it could be a block announcement (nCount < + // MAX_BLOCKS_TO_ANNOUNCE), use special logic for handling headers that + // don't connect: + // - Send a getheaders message in response to try to connect the chain. + // - The peer can send up to MAX_UNCONNECTING_HEADERS in a row that + // don't connect before giving DoS points + // - Once a headers message is received that is valid and does connect, + // nUnconnectingHeaders gets reset back to 0. + if (nCount > 0 && mapBlockIndex.find(headers[0].hashPrevBlock) == mapBlockIndex.end() && nCount < MAX_BLOCKS_TO_ANNOUNCE) { + nodestate->nUnconnectingHeaders++; + connman.PushMessage(pfrom, NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()); + LogPrint("net", "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n", + headers[0].GetHash().ToString(), + headers[0].hashPrevBlock.ToString(), + pindexBestHeader->nHeight, + pfrom->id, nodestate->nUnconnectingHeaders); + // Set hashLastUnknownBlock for this peer, so that if we + // eventually get the headers - even from a different peer - + // we can use this peer to download. + UpdateBlockAvailability(pfrom->GetId(), headers.back().GetHash()); + + if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) { + Misbehaving(pfrom->GetId(), 20); + } + return true; + } uint256 hashLastBlock; for (const CBlockHeader& header : headers) { if (!hashLastBlock.IsNull() && header.hashPrevBlock != hashLastBlock) { @@ -1832,6 +1863,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { LOCK(cs_main); + CNodeState *nodestate = State(pfrom->GetId()); + if (nodestate->nUnconnectingHeaders > 0) { + LogPrint("net", "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom->id, nodestate->nUnconnectingHeaders); + } + nodestate->nUnconnectingHeaders = 0; if (pindexLast) UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash()); @@ -1858,7 +1894,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus()); - CNodeState *nodestate = State(pfrom->GetId()); // If this set of headers is valid and ends in a block with at least as // much work as our tip, download as much as possible. if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && chainActive.Tip()->nChainWork <= pindexLast->nChainWork) { diff --git a/src/validation.h b/src/validation.h index 802a31cce58ec..2efb47f96bd6b 100644 --- a/src/validation.h +++ b/src/validation.h @@ -144,6 +144,8 @@ static const bool DEFAULT_FEEFILTER = true; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; +/** Maximum number of unconnecting headers announcements before DoS score */ +static const int MAX_UNCONNECTING_HEADERS = 10; static const bool DEFAULT_PEERBLOOMFILTERS = true; struct BlockHasher { From a891673740e9ae682cce67dcae745c70b23f4b34 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 17:14:47 +0000 Subject: [PATCH 38/49] Mining-related fixups for PR13.0 c1d61fb Add warning if -blockminsize is used. (Suhas Daftuar) 27362dd Remove -blockminsize option (Suhas Daftuar) d2e46e1 Remove addScoreTxs() (Suhas Daftuar) 6dd4bc2 Exclude witness transactions in addPackageTxs() pre-segwit activation (Suhas Daftuar) f15c2cd CreateNewBlock: add support for size-accounting to addPackageTxs (Suhas Daftuar) --- contrib/devtools/check-doc.py | 2 +- src/init.cpp | 3 ++- src/miner.cpp | 5 ----- src/miner.h | 8 +++----- src/policy/policy.h | 3 +-- 5 files changed, 7 insertions(+), 14 deletions(-) diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py index 8c73cf1e8a735..fa1e137587a63 100644 --- a/contrib/devtools/check-doc.py +++ b/contrib/devtools/check-doc.py @@ -21,7 +21,7 @@ REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"') REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")') # list unsupported, deprecated and duplicate args as they need no documentation -SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay']) +SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-blockminsize']) def main(): used = check_output(CMD_GREP_ARGS, shell=True) diff --git a/src/init.cpp b/src/init.cpp index b16264deb0cc5..88539f77aaf9c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -563,7 +563,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); strUsage += HelpMessageGroup(_("Block creation options:")); - strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE)); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); if (showDebug) @@ -1044,6 +1043,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-whitelistalwaysrelay", false)) InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.")); + if (mapArgs.count("-blockminsize")) + InitWarning("Unsupported argument -blockminsize ignored."); // Checkmempool and checkblockindex default to true in regtest mode int ratio = std::min(std::max(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); if (ratio != 0) { diff --git a/src/miner.cpp b/src/miner.cpp index 0452afcabfbc1..bab9d229cfd0a 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -84,11 +84,6 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams) nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MaxBlockSize(fDIP0001ActiveAtTip)-1000), nBlockMaxSize)); - - // Minimum block size you want to create; block will be filled with free transactions - // until there are no more or the block reaches this size: - nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); - nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); } void BlockAssembler::resetBlock() diff --git a/src/miner.h b/src/miner.h index ed05c1d150326..981d72b1eb1dd 100644 --- a/src/miner.h +++ b/src/miner.h @@ -139,7 +139,7 @@ class BlockAssembler CBlock* pblock; // Configuration parameters for the block size - unsigned int nBlockMaxSize, nBlockMinSize; + unsigned int nBlockMaxSize; // Information on the current status of the block uint64_t nBlockSize; @@ -153,7 +153,7 @@ class BlockAssembler int64_t nLockTimeCutoff; const CChainParams& chainparams; - // Variables used for addScoreTxs and addPriorityTxs + // Variables used for addPriorityTxs int lastFewTxs; bool blockFinished; @@ -170,14 +170,12 @@ class BlockAssembler void AddToBlock(CTxMemPool::txiter iter); // Methods for how to add transactions to a block. - /** Add transactions based on modified feerate */ - void addScoreTxs(); /** Add transactions based on tx "priority" */ void addPriorityTxs(); /** Add transactions based on feerate including unconfirmed ancestors */ void addPackageTxs(); - // helper function for addScoreTxs and addPriorityTxs + // helper function for addPriorityTxs /** Test if tx will still "fit" in the block */ bool TestForBlock(CTxMemPool::txiter iter); /** Test if tx still has unconfirmed parents not yet in block */ diff --git a/src/policy/policy.h b/src/policy/policy.h index 69383c2e39a6c..8da0f3884287c 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -14,9 +14,8 @@ class CCoinsViewCache; -/** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/ +/** Default for -blockmaxsize, which controls the maximum size of block the mining code will create **/ static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; -static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 10000; // was 50000 in 0.12.0 and it is 0 in Bitcoin since 0.12 /** The maximum size for transactions we're willing to relay/mine */ From 94a272a8d2732e656ae903032a3e5ba181114deb Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 17:15:48 +0000 Subject: [PATCH 39/49] Bump univalue version --- src/univalue/configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/univalue/configure.ac b/src/univalue/configure.ac index 0515b632bdf9a..93d3ba945d143 100644 --- a/src/univalue/configure.ac +++ b/src/univalue/configure.ac @@ -1,7 +1,7 @@ m4_define([libunivalue_major_version], [1]) m4_define([libunivalue_minor_version], [1]) -m4_define([libunivalue_micro_version], [1]) -m4_define([libunivalue_interface_age], [1]) +m4_define([libunivalue_micro_version], [2]) +m4_define([libunivalue_interface_age], [2]) # If you need a modifier for the version number. # Normally empty, but can be used to make "fixup" releases. m4_define([libunivalue_extraversion], []) @@ -14,7 +14,7 @@ m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_inter m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()]) -AC_INIT([univalue], [1.0.1], +AC_INIT([univalue], [1.0.2], [http://github.com/jgarzik/univalue/]) dnl make the compilation flags quiet unless V=1 is used From 8a7948905455afeebf7db26f8fee49dab12ef4b6 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 17:47:48 +0000 Subject: [PATCH 40/49] Temporarily fix build error cased by out-of-order backporting Absification of naming. Can be removed when we catch up with backporting. You'll notice it's time for this when you get conflicts while merging the affected backported PR. --- dash-docs/protocol-documentation.md | 4 ++-- src/net_processing.cpp | 14 ++++++++++++++ src/validation.cpp | 5 ++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/dash-docs/protocol-documentation.md b/dash-docs/protocol-documentation.md index ba3cb32dc1ff1..d069ea0db6d57 100644 --- a/dash-docs/protocol-documentation.md +++ b/dash-docs/protocol-documentation.md @@ -253,9 +253,9 @@ Spork | ---------- | ---------- | ----------- | ----------- | | 10001 | 2 | INSTANTSEND_ENABLED | Turns on and off InstantSend network wide | 10002 | 3 | INSTANTSEND_BLOCK_FILTERING | Turns on and off InstantSend block filtering -| 10004 | 5 | INSTANTSEND_MAX_VALUE | Controls the max value for an InstantSend transaction (currently 2000 dash) +| 10004 | 5 | INSTANTSEND_MAX_VALUE | Controls the max value for an InstantSend transaction (currently 2000 ABS) | 10007 | 8 | MASTERNODE_PAYMENT_ENFORCEMENT | Requires masternodes to be paid by miners when blocks are processed -| 10008 | 9 | SUPERBLOCKS_ENABLED | Superblocks are enabled (the 10% comes to fund the dash treasury) +| 10008 | 9 | SUPERBLOCKS_ENABLED | Superblocks are enabled (the 10% comes to fund the absolute treasury) | 10009 | 10 | MASTERNODE_PAY_UPDATED_NODES | Only current protocol version masternode's will be paid (not older nodes) | 10011 | 12 | RECONSIDER_BLOCKS | | 10012 | 13 | OLD_SUPERBLOCK_FLAG | diff --git a/src/net_processing.cpp b/src/net_processing.cpp index b080ea069f334..84e5842b76174 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -522,6 +522,20 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals) // mapOrphanTransactions // +// TODO This is a temporary solution while backporting Bitcoin 0.13 changes into Dash +// See caller of this method +void LoopMapOrphanTransactionsByPrev(const CTransaction &tx, std::vector &vOrphanErase) +{ + for (size_t j = 0; j < tx.vin.size(); j++) { + auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); + if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; + for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { + const CTransaction& orphanTx = (*mi)->second.tx; + const uint256& orphanHash = orphanTx.GetHash(); + vOrphanErase.push_back(orphanHash); + } + } +} bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { uint256 hash = tx.GetHash(); diff --git a/src/validation.cpp b/src/validation.cpp index bc308125405b9..289e2f6d867ee 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -105,6 +105,9 @@ CTxMemPool mempool(::minRelayTxFee); FeeFilterRounder filterRounder(::minRelayTxFee); map mapRejectedBlocks GUARDED_BY(cs_main); +// TODO temporary hack for backporting +void LoopMapOrphanTransactionsByPrev(const CTransaction &tx, std::vector &vOrphanErase); +int EraseOrphanTx(uint256 hash); /** * Returns true if there are nRequired or more blocks of minVersion or above * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards. @@ -2142,7 +2145,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd // vOrphanErase.push_back(orphanHash); // } //} - // TODO This is a temporary solution while backporting Bitcoin 0.13 changes into Dash + // TODO This is a temporary solution while backporting Bitcoin 0.13 changes into Absolute // It is needed because the splitting of main.cpp into validation.cpp/net_processing.cpp was done out of order // When we catch up with backporting, the above loop will be at the correct place in net_processing.cpp // and this hack can be removed From b036954406aeb57bc6534f2d5ee13b5adc51d6ba Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 18:16:35 +0000 Subject: [PATCH 41/49] Clean up for misc addresses and statements --- contrib/gitian-descriptors/README.md | 2 +- contrib/gitian-descriptors/gitian-win-signer.yml | 2 +- src/absoluted.cpp | 2 +- src/secp256k1/.gitignore | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/contrib/gitian-descriptors/README.md b/contrib/gitian-descriptors/README.md index e88528b3fd42e..4f53e113dbcfe 100644 --- a/contrib/gitian-descriptors/README.md +++ b/contrib/gitian-descriptors/README.md @@ -61,5 +61,5 @@ Here's a description of Gavin's setup on OSX 10.6: 5. Still inside Ubuntu, tell gitian-builder to use LXC, then follow the "Once you've got the right hardware and software" instructions above: export USE_LXC=1 - git clone git://github.com/absolute-community/absolute/issues + git clone git://github.com/absolute-community/absolute ... etc diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml index 3f320cd1ccaf3..8eda3c5164ec0 100644 --- a/contrib/gitian-descriptors/gitian-win-signer.yml +++ b/contrib/gitian-descriptors/gitian-win-signer.yml @@ -8,7 +8,7 @@ packages: - "libssl-dev" - "autoconf" remotes: -- "url": "https://github.com/absolute-community/absolute-detached-sigs" +- "url": "https://github.com/absolute-community/absolute.detached.signatures" "dir": "signature" files: - "osslsigncode-1.7.1.tar.gz" diff --git a/src/absoluted.cpp b/src/absoluted.cpp index eb47d9a4e3e02..5a69d6b01320f 100644 --- a/src/absoluted.cpp +++ b/src/absoluted.cpp @@ -33,7 +33,7 @@ * * \section intro_sec Introduction * - * This is the developer documentation of the reference client for an experimental new digital currency called Absolute (https://www.absolutecoin.net/), + * This is the developer documentation of the reference client for an experimental digital currency called Absolute (https://www.absolutecoin.net/), * which enables instant payments to anyone, anywhere in the world. Absolute uses peer-to-peer technology to operate * with no central authority: managing transactions and issuing money are carried out collectively by the network. * diff --git a/src/secp256k1/.gitignore b/src/secp256k1/.gitignore index 298bdb528b8bc..e0b7b7a48a31f 100644 --- a/src/secp256k1/.gitignore +++ b/src/secp256k1/.gitignore @@ -25,6 +25,7 @@ config.status libtool .deps/ .dirstamp +build-aux/ *.lo *.o *~ From 78992f9c382a480747b03206cda24fd7c22b8a9f Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 18:19:29 +0000 Subject: [PATCH 42/49] Fix crash on exit when -createwalletbackups=0 --- src/qt/overviewpage.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 510ce99985d12..e4e2be7159ff4 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -133,7 +133,8 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) currentWatchOnlyBalance(-1), currentWatchUnconfBalance(-1), currentWatchImmatureBalance(-1), - txdelegate(new TxViewDelegate(platformStyle, this)) + txdelegate(new TxViewDelegate(platformStyle, this)), + timer(nullptr) { ui->setupUi(this); QString theme = GUIUtil::getThemeName(); @@ -196,7 +197,7 @@ void OverviewPage::handleOutOfSyncWarningClicks() OverviewPage::~OverviewPage() { - if(!fLiteMode && !fMasterNode) disconnect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus())); + if(timer) disconnect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus())); delete ui; } From 7aa2172ec02c39188aa45bc80859c7b7b62931b9 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 18:21:30 +0000 Subject: [PATCH 43/49] Swap iterations and fUseInstantSend parameters in ApproximateBestSubs Fix edge case for IS Introduced a fix for a instant send related edge case. Somehow the parameters got mixed up and fUseInstantSend was passed as "iterations". --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 7aa21cb950ad5..36036732b7b3c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2492,7 +2492,7 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const } static void ApproximateBestSubset(vector > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue, - vector& vfBest, CAmount& nBest, int iterations = 1000, bool fUseInstantSend = false) + vector& vfBest, CAmount& nBest, bool fUseInstantSend = false, int iterations = 1000) { vector vfIncluded; From 58023f34cf49fcae04b708e5336adc8072c9daf1 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 18:36:23 +0000 Subject: [PATCH 44/49] Vote on IS only if it was accepted to mempool --- src/instantx.cpp | 22 ++++++++++++++++------ src/instantx.h | 1 + src/net_processing.cpp | 1 + 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/instantx.cpp b/src/instantx.cpp index 3e7c7becf6646..02e471d26c5a0 100644 --- a/src/instantx.cpp +++ b/src/instantx.cpp @@ -123,15 +123,11 @@ bool CInstantSend::ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CCo } LogPrintf("CInstantSend::ProcessTxLockRequest -- accepted, txid=%s\n", txHash.ToString()); - std::map::iterator itLockCandidate = mapTxLockCandidates.find(txHash); - CTxLockCandidate& txLockCandidate = itLockCandidate->second; - Vote(txLockCandidate, connman); - ProcessOrphanTxLockVotes(connman); - // Masternodes will sometimes propagate votes before the transaction is known to the client. // If this just happened - lock inputs, resolve conflicting locks, update transaction status // forcing external script notification. - TryToFinalizeLockCandidate(txLockCandidate); + std::map::iterator itLockCandidate = mapTxLockCandidates.find(txHash); + TryToFinalizeLockCandidate(itLockCandidate->second); return true; } @@ -183,6 +179,18 @@ void CInstantSend::CreateEmptyTxLockCandidate(const uint256& txHash) mapTxLockCandidates.insert(std::make_pair(txHash, CTxLockCandidate(txLockRequest))); } +void CInstantSend::Vote(const uint256& txHash, CConnman& connman) +{ + AssertLockHeld(cs_main); + LOCK(cs_instantsend); + + std::map::iterator itLockCandidate = mapTxLockCandidates.find(txHash); + if (itLockCandidate == mapTxLockCandidates.end()) return; + Vote(itLockCandidate->second, connman); + // Let's see if our vote changed smth + TryToFinalizeLockCandidate(itLockCandidate->second); +} + void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman) { if(!fMasterNode) return; @@ -191,6 +199,8 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman) LOCK2(cs_main, cs_instantsend); uint256 txHash = txLockCandidate.GetHash(); + // We should never vote on a Transaction Lock Request that was not (yet) accepted by the mempool + if(mapLockRequestAccepted.find(txHash) == mapLockRequestAccepted.end()) return; // check if we need to vote on this candidate's outpoints, // it's possible that we need to vote for several of them std::map::iterator itOutpointLock = txLockCandidate.mapOutPointLocks.begin(); diff --git a/src/instantx.h b/src/instantx.h index 564f6a9e57b33..a53a022bdb70c 100644 --- a/src/instantx.h +++ b/src/instantx.h @@ -87,6 +87,7 @@ class CInstantSend void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, CConnman& connman); bool ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CConnman& connman); + void Vote(const uint256& txHash, CConnman& connman); bool AlreadyHave(const uint256& hash); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 84e5842b76174..b1baccc41bf42 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1658,6 +1658,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrintf("TXLOCKREQUEST -- Transaction Lock Request accepted, txid=%s, peer=%d\n", tx.GetHash().ToString(), pfrom->id); instantsend.AcceptLockRequest(txLockRequest); + instantsend.Vote(tx.GetHash(), connman); } mempool.check(pcoinsTip); From 93404fceb57d9d5bbf2ecdaa77527c80113c8352 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 18:37:23 +0000 Subject: [PATCH 45/49] Fix -liquidityprovider option --- src/privatesend-client.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index 07573271615da..720a09bfbff0f 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -1003,13 +1003,24 @@ bool CPrivateSendClient::SubmitDenominate(CConnman& connman) std::vector vecTxOutRet; // Submit transaction to the pool if we get here - // Try to use only inputs with the same number of rounds starting from the highest number of rounds possible - for(int i = nPrivateSendRounds; i > 0; i--) { - if(PrepareDenominate(i - 1, i, strError, vecTxDSInRet, vecTxOutRet)) { - LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i); - return SendDenominate(vecTxDSInRet, vecTxOutRet, connman); + if (nLiquidityProvider) { + // Try to use only inputs with the same number of rounds starting from the lowest number of rounds possible + for(int i = 0; i< nPrivateSendRounds; i++) { + if(PrepareDenominate(i, i + 1, strError, vecTxDSInRet, vecTxOutRet)) { + LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i); + return SendDenominate(vecTxDSInRet, vecTxOutRet, connman); + } + LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError); + } + } else { + // Try to use only inputs with the same number of rounds starting from the highest number of rounds possible + for(int i = nPrivateSendRounds; i > 0; i--) { + if(PrepareDenominate(i - 1, i, strError, vecTxDSInRet, vecTxOutRet)) { + LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i); + return SendDenominate(vecTxDSInRet, vecTxOutRet, connman); + } + LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError); } - LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError); } // We failed? That's strange but let's just make final attempt and try to mix everything From bddbbd2f9b5d7371ed3746bb32f0831d1e433b97 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 18:42:17 +0000 Subject: [PATCH 46/49] Lodgepole/feature/backport-11847 --- src/txmempool.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/txmempool.h b/src/txmempool.h index 493b78768a3b4..732c6ccb2cdbc 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -222,7 +222,7 @@ struct mempoolentry_txid class CompareTxMemPoolEntryByDescendantScore { public: - bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const { bool fUseADescendants = UseDescendantScore(a); bool fUseBDescendants = UseDescendantScore(b); @@ -244,7 +244,7 @@ class CompareTxMemPoolEntryByDescendantScore } // Calculate which score to use for an entry (avoiding division). - bool UseDescendantScore(const CTxMemPoolEntry &a) + bool UseDescendantScore(const CTxMemPoolEntry &a) const { double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants(); double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize(); @@ -259,7 +259,7 @@ class CompareTxMemPoolEntryByDescendantScore class CompareTxMemPoolEntryByScore { public: - bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const { double f1 = (double)a.GetModifiedFee() * b.GetTxSize(); double f2 = (double)b.GetModifiedFee() * a.GetTxSize(); @@ -273,7 +273,7 @@ class CompareTxMemPoolEntryByScore class CompareTxMemPoolEntryByEntryTime { public: - bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const { return a.GetTime() < b.GetTime(); } From da0651ce494ea99188da266a40fc6d453fd1ca9c Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 18:43:48 +0000 Subject: [PATCH 47/49] Skip existing masternode conections on mixing --- src/privatesend-client.cpp | 41 ++++++++++++-------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index 720a09bfbff0f..1371f49628ab9 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -874,23 +874,19 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CCon vecMasternodesUsed.push_back(dsq.vin.prevout); - CNode* pnodeFound = NULL; - bool fDisconnect = false; - connman.ForNode(infoMn.addr, CConnman::AllNodes, [&pnodeFound, &fDisconnect](CNode* pnode) { - pnodeFound = pnode; - if(pnodeFound->fDisconnect) { - fDisconnect = true; - } else { - pnodeFound->AddRef(); - } + bool fSkip = false; + connman.ForNode(infoMn.addr, CConnman::AllNodes, [&fSkip](CNode* pnode) { + fSkip = pnode->fDisconnect || pnode->fMasternode; return true; }); - if (fDisconnect) + if (fSkip) { + LogPrintf("CPrivateSendClient::JoinExistingQueue -- skipping masternode connection, addr=%s\n", infoMn.addr.ToString()); continue; + } LogPrintf("CPrivateSendClient::JoinExistingQueue -- attempt to connect to masternode from queue, addr=%s\n", infoMn.addr.ToString()); // connect to Masternode and submit the queue request - CNode* pnode = (pnodeFound && pnodeFound->fMasternode) ? pnodeFound : connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, false, true); + CNode* pnode = connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true); if(pnode) { infoMixingMasternode = infoMn; nSessionDenom = dsq.nDenom; @@ -901,9 +897,6 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CCon strAutoDenomResult = _("Mixing in progress..."); SetState(POOL_STATE_QUEUE); nTimeLastSuccessfulStep = GetTimeMillis(); - if(pnodeFound) { - pnodeFound->Release(); - } return true; } else { LogPrintf("CPrivateSendClient::JoinExistingQueue -- can't connect, addr=%s\n", infoMn.addr.ToString()); @@ -948,24 +941,19 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA continue; } - CNode* pnodeFound = NULL; - bool fDisconnect = false; - connman.ForNode(infoMn.addr, CConnman::AllNodes, [&pnodeFound, &fDisconnect](CNode* pnode) { - pnodeFound = pnode; - if(pnodeFound->fDisconnect) { - fDisconnect = true; - } else { - pnodeFound->AddRef(); - } + bool fSkip = false; + connman.ForNode(infoMn.addr, CConnman::AllNodes, [&fSkip](CNode* pnode) { + fSkip = pnode->fDisconnect || pnode->fMasternode; return true; }); - if (fDisconnect) { + if (fSkip) { + LogPrintf("CPrivateSendClient::StartNewQueue -- skipping masternode connection, addr=%s\n", infoMn.addr.ToString()); nTries++; continue; } LogPrintf("CPrivateSendClient::StartNewQueue -- attempt %d connection to Masternode %s\n", nTries, infoMn.addr.ToString()); - CNode* pnode = (pnodeFound && pnodeFound->fMasternode) ? pnodeFound : connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, false, true); + CNode* pnode = connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true); if(pnode) { LogPrintf("CPrivateSendClient::StartNewQueue -- connected, addr=%s\n", infoMn.addr.ToString()); infoMixingMasternode = infoMn; @@ -983,9 +971,6 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA strAutoDenomResult = _("Mixing in progress..."); SetState(POOL_STATE_QUEUE); nTimeLastSuccessfulStep = GetTimeMillis(); - if(pnodeFound) { - pnodeFound->Release(); - } return true; } else { LogPrintf("CPrivateSendClient::StartNewQueue -- can't connect, addr=%s\n", infoMn.addr.ToString()); From 12931c79d7b234a0cb11ca2cb1ccb37cb4ff5604 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 18:45:02 +0000 Subject: [PATCH 48/49] Protect CKeyHolderStorage via mutex --- src/privatesend-util.cpp | 3 +++ src/privatesend-util.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/privatesend-util.cpp b/src/privatesend-util.cpp index 00d6b0cd254b5..e53255987c95b 100644 --- a/src/privatesend-util.cpp +++ b/src/privatesend-util.cpp @@ -28,12 +28,14 @@ CScript CKeyHolder::GetScriptForDestination() const const CKeyHolder& CKeyHolderStorage::AddKey(CWallet* pwallet) { + LOCK(cs_storage); storage.emplace_back(std::unique_ptr(new CKeyHolder(pwallet))); LogPrintf("CKeyHolderStorage::%s -- storage size %lld\n", __func__, storage.size()); return *storage.back(); } void CKeyHolderStorage::KeepAll(){ + LOCK(cs_storage); if (storage.size() > 0) { for (auto &key : storage) { key->KeepKey(); @@ -45,6 +47,7 @@ void CKeyHolderStorage::KeepAll(){ void CKeyHolderStorage::ReturnAll() { + LOCK(cs_storage); if (storage.size() > 0) { for (auto &key : storage) { key->ReturnKey(); diff --git a/src/privatesend-util.h b/src/privatesend-util.h index 173685602117c..050f3b7ef8ae3 100644 --- a/src/privatesend-util.h +++ b/src/privatesend-util.h @@ -28,6 +28,7 @@ class CKeyHolderStorage { private: std::vector > storage; + mutable CCriticalSection cs_storage; public: const CKeyHolder& AddKey(CWallet* pwalletIn); From 209082ff4ef8090b032cd22f7e6561ae203aa219 Mon Sep 17 00:00:00 2001 From: CryptoCentric Date: Sun, 20 Jan 2019 18:46:07 +0000 Subject: [PATCH 49/49] Avoid reference leakage in CKeyHolderStorage::AddKey --- src/privatesend-client.cpp | 6 +++--- src/privatesend-util.cpp | 4 ++-- src/privatesend-util.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index 1371f49628ab9..8e96427f11ad9 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -1097,7 +1097,7 @@ bool CPrivateSendClient::PrepareDenominate(int nMinRounds, int nMaxRounds, std:: vecTxDSIn.erase(it); vCoins.erase(it2); - CScript scriptDenom = keyHolderStorage.AddKey(pwalletMain).GetScriptForDestination(); + CScript scriptDenom = keyHolderStorage.AddKey(pwalletMain); // add new output CTxOut txout(nValueDenom, scriptDenom); @@ -1273,7 +1273,7 @@ bool CPrivateSendClient::CreateDenominated(const CompactTallyItem& tallyItem, bo // ****** Add an output for mixing collaterals ************ / if(fCreateMixingCollaterals) { - CScript scriptCollateral = keyHolderStorageDenom.AddKey(pwalletMain).GetScriptForDestination(); + CScript scriptCollateral = keyHolderStorageDenom.AddKey(pwalletMain); vecSend.push_back((CRecipient){ scriptCollateral, CPrivateSend::GetMaxCollateralAmount(), false }); nValueLeft -= CPrivateSend::GetMaxCollateralAmount(); } @@ -1308,7 +1308,7 @@ bool CPrivateSendClient::CreateDenominated(const CompactTallyItem& tallyItem, bo // add each output up to 11 times until it can't be added again while(nValueLeft - nDenomValue >= 0 && nOutputs <= 10) { - CScript scriptDenom = keyHolderStorageDenom.AddKey(pwalletMain).GetScriptForDestination(); + CScript scriptDenom = keyHolderStorageDenom.AddKey(pwalletMain); vecSend.push_back((CRecipient){ scriptDenom, nDenomValue, false }); diff --git a/src/privatesend-util.cpp b/src/privatesend-util.cpp index e53255987c95b..ff831d325fc6e 100644 --- a/src/privatesend-util.cpp +++ b/src/privatesend-util.cpp @@ -26,12 +26,12 @@ CScript CKeyHolder::GetScriptForDestination() const } -const CKeyHolder& CKeyHolderStorage::AddKey(CWallet* pwallet) +CScript CKeyHolderStorage::AddKey(CWallet* pwallet) { LOCK(cs_storage); storage.emplace_back(std::unique_ptr(new CKeyHolder(pwallet))); LogPrintf("CKeyHolderStorage::%s -- storage size %lld\n", __func__, storage.size()); - return *storage.back(); + return storage.back()->GetScriptForDestination(); } void CKeyHolderStorage::KeepAll(){ diff --git a/src/privatesend-util.h b/src/privatesend-util.h index 050f3b7ef8ae3..c673951f8638b 100644 --- a/src/privatesend-util.h +++ b/src/privatesend-util.h @@ -31,7 +31,7 @@ class CKeyHolderStorage mutable CCriticalSection cs_storage; public: - const CKeyHolder& AddKey(CWallet* pwalletIn); + CScript AddKey(CWallet* pwalletIn); void KeepAll(); void ReturnAll();