diff --git a/README.md b/README.md index 8008106592..b8760f3b86 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Zen 2.0.18 +Zen 2.0.19 ============== What is Horizen? diff --git a/configure.ac b/configure.ac index 2bb303dcfe..03dab14c0c 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 2) define(_CLIENT_VERSION_MINOR, 0) -define(_CLIENT_VERSION_REVISION, 18) +define(_CLIENT_VERSION_REVISION, 19) define(_CLIENT_VERSION_BUILD, 50) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index e6fd34d795..9b88b4b273 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -1,8 +1,8 @@ package=openssl -$(package)_version=1.1.1c +$(package)_version=1.1.1d $(package)_download_path=https://www.openssl.org/source $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=f6fb3079ad15076154eda9413fed42877d668e7069d9b87396d0804fdb3f4c90 +$(package)_sha256_hash=1e3a91bc1f9dfce01af26026f856e064eab4c8ee0a8f457b5ae30b40b8b711f2 define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" diff --git a/doc/authors.md b/doc/authors.md index 1e89112b31..144165dd61 100644 --- a/doc/authors.md +++ b/doc/authors.md @@ -1,108 +1,140 @@ Zcash Contributors ================== -Jack Grigg (558) -Simon Liu (286) -Sean Bowe (193) -Daira Hopwood (102) -Wladimir J. van der Laan (71) -Taylor Hornby (65) -Nathan Wilcox (56) -Jay Graber (53) -Jonas Schnelli (49) +Jack Grigg (976) +FranckDG (438) +Simon Liu (390) +cronicc (285) +Sean Bowe (213) +Daira Hopwood (184) +Wladimir J. van der Laan (173) +Nathan Wilcox (156) +Alberto Sala (140) +Taylor Hornby (113) +Jonas Schnelli (99) +Jay Graber (97) +pierstab (67) +Cory Fields (62) +syd (43) +joshuayabut (40) Kevin Gallagher (38) -Cory Fields (28) -Pieter Wuille (16) -syd (13) -nomnombtc (9) -Paige Peterson (9) -fanquake (8) -MarcoFalke (7) -Luke Dashjr (6) +Jake Tarren (37) +Pieter Wuille (32) +hellcatz (29) +nomnombtc (27) +PeaStew (21) +tarrenj (18) +Luke Dashjr (18) +zebambam (17) +Paige Peterson (17) +fanquake (16) +Code Particle (16) +MarcoFalke (15) +Ariel Gabizon (15) +kozyilmaz (12) +Reza Barazesh (12) +Peter Todd (12) +Matt Corallo (12) +Karl-Johan Alm (12) +Gregory Maxwell (11) +g666 (10) +Philip Kaufmann (10) +Pavel Janík (9) +Jonathan "Duke" Leto (8) +str4d (6) +pstab (6) +kpcyrd (6) +Smrtz (6) +Per Grön (6) +Patrick Strateman (6) +Larry Ruane (6) +Jason Davies (6) +Jack Gavigan (6) +Gavin Andresen (6) +Daniel Cousens (6) +Boris P (6) +Bjorn Hjortsberg (6) +Amgad Abdelhafez (6) +nickolay (5) +fgius (5) +ca333 (5) +Stefano (5) +Oleksandr Iozhytsia (5) +João Barbosa (5) Johnathan Corgan (5) -Gregory Maxwell (5) -Ariel Gabizon (5) -kozyilmaz (4) -Zclassic Team (4) -Philip Kaufmann (4) -Peter Todd (4) -Patrick Strateman (4) -Matt Corallo (4) -Karl-Johan Alm (4) +Homu (5) +paveljanik (4) +codeparticle (4) +Kent (4) +Joshua Yabut (4) Jeff Garzik (4) David Mercer (4) -Daniel Cousens (4) +zathras-crypto (3) +unsystemizer (3) +practicalswift (3) +mruddy (3) lpescher (3) -Pavel Janík (3) -João Barbosa (3) +instagibbs (3) +emilrus (3) +dexX7 (3) +daniel (3) +calebogden (3) +Stephen (3) +Ross Nicoll (3) +René Nyffenegger (3) +Pavel Vasin (3) +Paul Georgiou (3) +Nathaniel Mahieu (3) +Murilo Santana (3) +Matt Quinn (3) +Leo Arias (3) +Kevin Pan (3) +Jorge Timón (3) +Ian Kelling (3) +Forrest Voight (3) +Florian Schmaus (3) +Duke Leto (3) +Daniel Kraft (3) +Casey Rodarmor (3) +Bruno Arueira (3) +Boris Hajduk (3) +Bob McElrath (3) +Ariel (3) +Anthony Towns (3) +Allan Niemerg (3) Alfie John (3) -str4d (2) -paveljanik (2) -kpcyrd (2) +Alex van der Peet (3) +Alberto Garoffolo (3) +Adam Weiss (3) +Adam Brown (3) +pier (2) +koljenovic (2) aniemerg (2) Scott (2) Robert C. Seacord (2) -Per Grön (2) +Marius Kjærstad (2) Joe Turgeon (2) -Jason Davies (2) -Jack Gavigan (2) +JOSEPH NICHOLAS R. ALCANTARA (2) +Igor Mikheiko (2) ITH4Coinomia (2) -Gavin Andresen (2) -Bjorn Hjortsberg (2) -Amgad Abdelhafez (2) -zathras-crypto (1) -unsystemizer (1) -practicalswift (1) -mruddy (1) +Franck De Girolami (2) mrbandrews (1) kazcw (1) isle2983 (1) -instagibbs (1) -emilrus (1) -dexX7 (1) -daniel (1) -calebogden (1) ayleph (1) Tom Ritter (1) -Stephen (1) S. Matthew English (1) -Ross Nicoll (1) -René Nyffenegger (1) -Pavel Vasin (1) -Paul Georgiou (1) Paragon Initiative Enterprises, LLC (1) -Nathaniel Mahieu (1) -Murilo Santana (1) -Matt Quinn (1) Louis Nyffenegger (1) -Leo Arias (1) Lars-Magnus Skog (1) -Kevin Pan (1) -Jorge Timón (1) -Jonathan "Duke" Leto (1) Jeffrey Walton (1) -Ian Kelling (1) Gaurav Rana (1) -Forrest Voight (1) -Florian Schmaus (1) Ethan Heilman (1) Eran Tromer (1) -Duke Leto (1) -Daniel Kraft (1) Christian von Roques (1) Chirag Davé (1) -Casey Rodarmor (1) Cameron Boehmer (1) Bryan Stitt (1) -Bruno Arueira (1) -Boris Hajduk (1) -Bob McElrath (1) Bitcoin Error Log (1) -Ariel (1) -Anthony Towns (1) -Allan Niemerg (1) -Alex van der Peet (1) Alex (1) -Adam Weiss (1) -Adam Brown (1) 4ZEC (1) diff --git a/doc/man/zen-cli.1 b/doc/man/zen-cli.1 index 1e9649694b..38eb39c660 100644 --- a/doc/man/zen-cli.1 +++ b/doc/man/zen-cli.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH ZEN-CLI "1" "July 2019" "zen-cli v2.0.18" "User Commands" +.TH ZEN-CLI "1" "October 2019" "zen-cli v2.0.19" "User Commands" .SH NAME -zen-cli \- manual page for zen-cli v2.0.18 +zen-cli \- manual page for zen-cli v2.0.19 .SH DESCRIPTION -Horizen RPC client version v2.0.18 +Horizen RPC client version v2.0.19 .SS "Usage:" .TP zen\-cli [options] [params] diff --git a/doc/man/zen-tx.1 b/doc/man/zen-tx.1 index 73fee9ae06..b8770f6136 100644 --- a/doc/man/zen-tx.1 +++ b/doc/man/zen-tx.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH ZEN-TX "1" "July 2019" "zen-tx v2.0.18" "User Commands" +.TH ZEN-TX "1" "October 2019" "zen-tx v2.0.19" "User Commands" .SH NAME -zen-tx \- manual page for zen-tx v2.0.18 +zen-tx \- manual page for zen-tx v2.0.19 .SH DESCRIPTION -Zencash zen\-tx utility version v2.0.18 +Zencash zen\-tx utility version v2.0.19 .SS "Usage:" .TP zen\-tx [options] [commands] diff --git a/doc/man/zend.1 b/doc/man/zend.1 index 32549f2b9f..479f05e23c 100644 --- a/doc/man/zend.1 +++ b/doc/man/zend.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH ZEND "1" "July 2019" "zend v2.0.18" "User Commands" +.TH ZEND "1" "October 2019" "zend v2.0.19" "User Commands" .SH NAME -zend \- manual page for zend v2.0.18 +zend \- manual page for zend v2.0.19 .SH DESCRIPTION -Zen Daemon version v2.0.18 +Zen Daemon version v2.0.19 .SS "Usage:" .TP zend [options] @@ -51,7 +51,7 @@ Specify data directory \fB\-disabledeprecation=\fR .IP Disable block\-height node deprecation and automatic shutdown (example: -\fB\-disabledeprecation\fR=\fI\,2\/\fR.0.18) +\fB\-disabledeprecation\fR=\fI\,2\/\fR.0.19) .HP \fB\-exportdir=\fR .IP @@ -328,24 +328,6 @@ Enable publish raw block in
.IP Enable publish raw transaction in
.PP -AMQP 1.0 notification options: -.HP -\fB\-amqppubhashblock=\fR
-.IP -Enable publish hash block in
-.HP -\fB\-amqppubhashtx=\fR
-.IP -Enable publish hash transaction in
-.HP -\fB\-amqppubrawblock=\fR
-.IP -Enable publish raw block in
-.HP -\fB\-amqppubrawtx=\fR
-.IP -Enable publish raw transaction in
-.PP Debugging/Testing options: .HP \fB\-debug=\fR diff --git a/doc/release-notes/release-notes-v2.0.19.md b/doc/release-notes/release-notes-v2.0.19.md new file mode 100644 index 0000000000..4558280df8 --- /dev/null +++ b/doc/release-notes/release-notes-v2.0.19.md @@ -0,0 +1,11 @@ +Changelog +========= + +cronicc (6): + Add new dns seeders + Update OpenSSL to 1.1.1d + Set mainnet/testnet checkpoint blocks + Set version to 2.0.19 + Set deprecation block 680000 + Generate manpages + diff --git a/qa/rpc-tests/getblocktemplate_blockmaxcomplexity.py b/qa/rpc-tests/getblocktemplate_blockmaxcomplexity.py index 61b0ac0b88..e2897c2a32 100755 --- a/qa/rpc-tests/getblocktemplate_blockmaxcomplexity.py +++ b/qa/rpc-tests/getblocktemplate_blockmaxcomplexity.py @@ -6,7 +6,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.authproxy import JSONRPCException from test_framework.util import assert_equal, initialize_chain_clean, \ - start_node, connect_nodes + start_node, connect_nodes, sync_mempools from decimal import Decimal @@ -71,6 +71,8 @@ def run_test(self): tx_rawtx = self.nodes[0].createrawtransaction(tx_inputs, tx_outputs) tx_rawtx = self.nodes[0].signrawtransaction(tx_rawtx) tx_rawtx = self.nodes[0].sendrawtransaction(tx_rawtx['hex']) + # Wait for wallet to catch up with mempool for listunspent call + sync_mempools([self.nodes[0]]) # Create transaction 3 transactions with 2 inputs each # Each transaction complexity will be equal to 2*2=4 @@ -85,6 +87,8 @@ def run_test(self): tx_rawtx = self.nodes[0].createrawtransaction(tx_inputs, tx_outputs) tx_rawtx = self.nodes[0].signrawtransaction(tx_rawtx) tx_rawtx = self.nodes[0].sendrawtransaction(tx_rawtx['hex']) + # Wait for wallet to catch up with mempool for listunspent call + sync_mempools([self.nodes[0]]) self.sync_all() diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index c18517572b..b3628e45b6 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -120,10 +120,12 @@ def _request(self, method, path, postdata): return self._get_response() except Exception as e: # If connection was closed, try again. + # Python 2.7 error message was changed in https://github.com/python/cpython/pull/2825 # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset. # ConnectionResetError happens on FreeBSD with Python 3.4. # These classes don't exist in Python 2.x, so we can't refer to them directly. - if ((isinstance(e, httplib.BadStatusLine) and e.line == "''") + if ((isinstance(e, httplib.BadStatusLine) + and e.line in ("''", "No status line received - the server has closed the connection")) or e.__class__.__name__ in ('BrokenPipeError', 'ConnectionResetError')): self.__conn.close() self.__conn.request(method, path, postdata, headers) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 4215670e27..fbe0cfdad8 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -64,7 +64,7 @@ def sync_blocks(rpc_connections, wait=1, p=False, limit_loop=0): def sync_mempools(rpc_connections, wait=1): """ Wait until everybody has the same transactions in their memory - pools + pools, and has notified all internal listeners of them """ while True: pool = set(rpc_connections[0].getrawmempool()) @@ -76,6 +76,15 @@ def sync_mempools(rpc_connections, wait=1): break time.sleep(wait) + # Now that the mempools are in sync, wait for the internal + # notifications to finish + while True: + notified = [ x.getmempoolinfo()['fullyNotified'] for x in rpc_connections ] + if notified == [ True ] * len(notified): + break + time.sleep(wait) + + bitcoind_processes = {} ''' diff --git a/qa/rpc-tests/wallet_treestate.py b/qa/rpc-tests/wallet_treestate.py index 39d4dacc5a..3a9eb4b05b 100755 --- a/qa/rpc-tests/wallet_treestate.py +++ b/qa/rpc-tests/wallet_treestate.py @@ -6,7 +6,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal, initialize_chain_clean, \ - start_nodes, connect_nodes_bi, wait_and_assert_operationid_status + start_nodes, connect_nodes_bi, wait_and_assert_operationid_status, sync_mempools import time from decimal import Decimal @@ -93,6 +93,9 @@ def run_test (self): # Wait for Tx 2 to be created wait_and_assert_operationid_status(self.nodes[0], myopid) + # Wait for wallet to catch up with mempool + sync_mempools([self.nodes[0]]) + # Note that a bug existed in v1.0.0-1.0.3 where Tx 2 creation would fail with an error: # "Witness for spendable note does not have same anchor as change input" diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 5afee10020..9605cee5f5 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -101,11 +101,11 @@ class CMainParams : public CChainParams { vFixedSeeds.clear(); vSeeds.clear(); - vSeeds.push_back(CDNSSeedData("horizen.global", "dnsseed.horizen.global")); - vSeeds.push_back(CDNSSeedData("zenseed.network", "dnsseed.zenseed.network")); - vSeeds.push_back(CDNSSeedData("zenchain.info", "node1.zenchain.info")); - vSeeds.push_back(CDNSSeedData("zenseed.network", "mainnet.zenseed.network")); - vSeeds.push_back(CDNSSeedData("horizen.global", "mainnet.horizen.global")); + vSeeds.push_back(CDNSSeedData("dnsseed.horizen.global", "dnsseed.horizen.global")); // dns seeder + vSeeds.push_back(CDNSSeedData("dnsseed.zensystem.io", "dnsseed.zensystem.io")); // dns seeder + vSeeds.push_back(CDNSSeedData("mainnet.horizen.global", "mainnet.horizen.global")); // fixed seed + vSeeds.push_back(CDNSSeedData("mainnet.zensytem.io", "mainnet.zensystem.io")); // fixed seed + vSeeds.push_back(CDNSSeedData("node1.zenchain.info", "node1.zenchain.info")); // fixed seed // guarantees the first 2 characters, when base58 encoded, are "zn" // guarantees the first 2 characters, when base58 encoded, are "t1" @@ -146,11 +146,12 @@ class CMainParams : public CChainParams { ( 294072, uint256S("0x000000005f9ceecc87d9e5eaab2cf548c787231829ad6f609975fadd10fff5be")) ( 429014, uint256S("0x000000000dc4f58375d9fa6dc4cb1bfc4b0afefbf4f7e1ee2cc755d6ca3b40b0")) ( 491000, uint256S("0x0000000018d0b189de58bcd8ff5048d2e4d1c652b98912ff002c8f07c6f81b8c")) - ( 543000, uint256S("0x00000000111469e247ecb152e57c371147775b56173260950075dcb471614fed")), - 1561970026, // * UNIX timestamp of last checkpoint block - 8879326, // * total number of transactions between genesis and last checkpoint + ( 543000, uint256S("0x00000000111469e247ecb152e57c371147775b56173260950075dcb471614fed")) + ( 596000, uint256S("0x000000000656846513b2d3faf3a70f59dc22fffcb8e14401ec5a17eec8994410")), + 1569977374, // * UNIX timestamp of last checkpoint block + 10471870, // * total number of transactions between genesis and last checkpoint // (the tx=... number in the SetBestChain debug.log lines) - 9418 // * estimated number of transactions per day after checkpoint + 10120 // * estimated number of transactions per day after checkpoint // total number of tx / (checkpoint block height / (24 * 24)) }; @@ -196,11 +197,11 @@ class CTestNetParams : public CMainParams { vFixedSeeds.clear(); vSeeds.clear(); - - vSeeds.push_back(CDNSSeedData("horizen.global", "dnsseed.testnet.horizen.global")); - vSeeds.push_back(CDNSSeedData("blockoperations.com", "zpool2.blockoperations.com")); - vSeeds.push_back(CDNSSeedData("scottrockcafe.com", "node.scottrockcafe.com")); - vSeeds.push_back(CDNSSeedData("horizen.global", "testnet.horizen.global")); + vSeeds.push_back(CDNSSeedData("dnsseed.testnet.horizen.global", "dnsseed.testnet.horizen.global")); // dns seeder + vSeeds.push_back(CDNSSeedData("dnsseed.testnet.zensystem.io", "dnsseed.testnet.zensystem.io")); // dns seeder + vSeeds.push_back(CDNSSeedData("testnet.horizen.global", "testnet.horizen.global")); // fixed seed + vSeeds.push_back(CDNSSeedData("tesntet.zensytem.io", "tesntet.zensystem.io")); // fixed seed + vSeeds.push_back(CDNSSeedData("node1.zenchain.info", "node1.zenchain.info")); // fixed seed // guarantees the first 2 characters, when base58 encoded, are "zt" // guarantees the first 2 characters, when base58 encoded, are "tm" @@ -239,11 +240,12 @@ class CTestNetParams : public CMainParams { (38000, uint256S("0x001e9a2d2e2892b88e9998cf7b079b41d59dd085423a921fe8386cecc42287b8")) (362210, uint256S("0x00023d5c074a7c2ccf130dac34b2b6f77e3c4466cfed0b72c3f3715157c92949")) (423000, uint256S("0x000d04b28067fe99445961f795ee7436f1dbbffc3a045f6890868e605209d170")) - (467550, uint256S("0x0007f73f339ea99e920e83da38d7537ce7d0028d48e709c88b1b89adf521b4f9")), - 1561953209, // * UNIX timestamp of last checkpoint block - 981759, // * total number of transactions between genesis and last checkpoint + (467550, uint256S("0x0007f73f339ea99e920e83da38d7537ce7d0028d48e709c88b1b89adf521b4f9")) + (520000, uint256S("0x00052e65426a0ffbb90893208a6c89a82816abbed328fa2be5a647828609e61a")), + 1569935276, // * UNIX timestamp of last checkpoint block + 1090788, // * total number of transactions between genesis and last checkpoint // (the tx=... number in the SetBestChain debug.log lines) - 1209 // total number of tx / (checkpoint block height / (24 * 24)) + 1208 // total number of tx / (checkpoint block height / (24 * 24)) }; // commented out - seems to make no sense but kept around for reference just in case diff --git a/src/clientversion.h b/src/clientversion.h index 64bca19e3e..298339a3a3 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -34,7 +34,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 18 +#define CLIENT_VERSION_REVISION 19 #define CLIENT_VERSION_BUILD 50 //! Set to true for release, false for prerelease or test build diff --git a/src/deprecation.h b/src/deprecation.h index 0dcb9baaa7..a610b902ce 100644 --- a/src/deprecation.h +++ b/src/deprecation.h @@ -5,7 +5,7 @@ #ifndef ZCASH_DEPRECATION_H #define ZCASH_DEPRECATION_H -static const int APPROX_RELEASE_HEIGHT = 545488; +static const int APPROX_RELEASE_HEIGHT = 615488; static const int WEEKS_UNTIL_DEPRECATION = 16; static const int DEPRECATION_HEIGHT = APPROX_RELEASE_HEIGHT + (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 24); diff --git a/src/init.cpp b/src/init.cpp index d842a9198c..14357b4cb2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -39,6 +39,7 @@ #endif #include #include +#include #ifndef WIN32 #include @@ -686,6 +687,22 @@ void ThreadImport(std::vector vImportFiles) } } +void ThreadNotifyRecentlyAdded() +{ + while (true) { + // Run the notifier on an integer second in the steady clock. + auto now = std::chrono::steady_clock::now().time_since_epoch(); + auto nextFire = std::chrono::duration_cast( + now + std::chrono::seconds(1)); + std::this_thread::sleep_until( + std::chrono::time_point(nextFire)); + + boost::this_thread::interruption_point(); + + mempool.NotifyRecentlyAdded(); + } +} + /** Sanity checks * Ensure that Bitcoin is running in a usable environment with all * necessary library support. @@ -1754,6 +1771,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0); #endif + // Start the thread that notifies listeners of transactions that have been + // recently added to the mempool. + threadGroup.create_thread(boost::bind(&TraceThread, "txnotify", &ThreadNotifyRecentlyAdded)); + if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) StartTorControl(threadGroup, scheduler); diff --git a/src/main.cpp b/src/main.cpp index 69d2a9d670..9ae08b6feb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1426,8 +1426,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa pool.addUnchecked(hash, entry, !IsInitialBlockDownload()); } - SyncWithWallets(tx, NULL); - return true; } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d3d5cf897e..3e9a48ca4d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -864,6 +864,10 @@ UniValue mempoolInfoToJSON() ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + if (Params().NetworkIDString() == "regtest") { + ret.push_back(Pair("fullyNotified", mempool.IsFullyNotified())); + } + return ret; } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 94fed6425d..c2bb532a2c 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -14,6 +14,7 @@ #include "util.h" #include "utilmoneystr.h" #include "version.h" +#include "validationinterface.h" #include "main.h" using namespace std; @@ -99,6 +100,8 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, LOCK(cs); mapTx[hash] = entry; const CTransaction& tx = mapTx[hash].GetTx(); + mapRecentlyAddedTx[tx.GetHash()] = &tx; + nRecentlyAddedSequence += 1; for (unsigned int i = 0; i < tx.vin.size(); i++) mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { @@ -149,6 +152,7 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem txToRemove.push_back(it->second.ptx->GetHash()); } } + mapRecentlyAddedTx.erase(hash); BOOST_FOREACH(const CTxIn& txin, tx.vin) mapNextTx.erase(txin.prevout); BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) { @@ -490,6 +494,49 @@ bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const return true; } +void CTxMemPool::NotifyRecentlyAdded() +{ + uint64_t recentlyAddedSequence; + std::vector txs; + { + LOCK(cs); + recentlyAddedSequence = nRecentlyAddedSequence; + for (const auto& kv : mapRecentlyAddedTx) { + txs.push_back(*(kv.second)); + } + mapRecentlyAddedTx.clear(); + } + + // A race condition can occur here between these SyncWithWallets calls, and + // the ones triggered by block logic (in ConnectTip and DisconnectTip). It + // is harmless because calling SyncWithWallets(_, NULL) does not alter the + // wallet transaction's block information. + for (auto tx : txs) { + try { + SyncWithWallets(tx, NULL); + } catch (const boost::thread_interrupted&) { + throw; + } catch (const std::exception& e) { + PrintExceptionContinue(&e, "CTxMemPool::NotifyRecentlyAdded()"); + } catch (...) { + PrintExceptionContinue(NULL, "CTxMemPool::NotifyRecentlyAdded()"); + } + } + + // Update the notified sequence number. We only need this in regtest mode, + // and should not lock on cs after calling SyncWithWallets otherwise. + if (Params().NetworkIDString() == "regtest") { + LOCK(cs); + nNotifiedSequence = recentlyAddedSequence; + } +} + +bool CTxMemPool::IsFullyNotified() { + assert(Params().NetworkIDString() == "regtest"); + LOCK(cs); + return nRecentlyAddedSequence == nNotifiedSequence; +} + CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } bool CCoinsViewMemPool::GetNullifier(const uint256 &nf) const { diff --git a/src/txmempool.h b/src/txmempool.h index cd0f9a54bf..3b4628973f 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -98,6 +98,10 @@ class CTxMemPool uint64_t totalTxSize = 0; //! sum of all mempool tx' byte sizes uint64_t cachedInnerUsage; //! sum of dynamic memory usage of all the map elements (NOT the maps themselves) + std::map mapRecentlyAddedTx; + uint64_t nRecentlyAddedSequence = 0; + uint64_t nNotifiedSequence = 0; + public: mutable CCriticalSection cs; std::map mapTx; @@ -140,6 +144,9 @@ class CTxMemPool void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta); void ClearPrioritisation(const uint256 hash); + void NotifyRecentlyAdded(); + bool IsFullyNotified(); + unsigned long size() { LOCK(cs); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index fe0af5c70d..cbc063d49f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1182,6 +1182,13 @@ bool CWallet::UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx) * Add a transaction to the wallet, or update it. * pblock is optional, but should be provided if the transaction is known to be in a block. * If fUpdate is true, existing transactions will be updated. + * + * If pblock is null, this transaction has either recently entered the mempool from the + * network, is re-entering the mempool after a block was disconnected, or is exiting the + * mempool because it conflicts with another transaction. In all these cases, if there is + * an existing wallet transaction, the wallet transaction's Merkle branch data is _not_ + * updated; instead, the transaction being in the mempool or conflicted is determined on + * the fly in CMerkleTx::GetDepthInMainChain(). */ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate) { @@ -1214,7 +1221,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock) { - LOCK2(cs_main, cs_wallet); + LOCK(cs_wallet); if (!AddToWalletIfInvolvingMe(tx, pblock, true)) return; // Not one of ours @@ -3594,9 +3601,8 @@ CWalletKey::CWalletKey(int64_t nExpires) nTimeExpires = nExpires; } -int CMerkleTx::SetMerkleBranch(const CBlock& block) +void CMerkleTx::SetMerkleBranch(const CBlock& block) { - AssertLockHeld(cs_main); CBlock blockTmp; // Update the tx's hashBlock @@ -3611,21 +3617,10 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) vMerkleBranch.clear(); nIndex = -1; LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n"); - return 0; } // Fill in merkle branch vMerkleBranch = block.GetMerkleBranch(nIndex); - - // Is the tx in a block that's in the main chain - BlockMap::iterator mi = mapBlockIndex.find(hashBlock); - if (mi == mapBlockIndex.end()) - return 0; - const CBlockIndex* pindex = (*mi).second; - if (!pindex || !chainActive.Contains(pindex)) - return 0; - - return chainActive.Height() - pindex->nHeight + 1; } int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index ad8c456ac0..a84d633278 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -315,7 +315,7 @@ class CMerkleTx : public CTransaction READWRITE(nIndex); } - int SetMerkleBranch(const CBlock& block); + void SetMerkleBranch(const CBlock& block); /**