diff options
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | Makefile.am | 19 | ||||
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | doc/bips.md | 1 | ||||
-rw-r--r-- | doc/developer-notes.md | 33 | ||||
-rw-r--r-- | src/Makefile.am | 16 | ||||
-rw-r--r-- | src/consensus/consensus.h | 6 | ||||
-rw-r--r-- | src/main.cpp | 40 | ||||
-rw-r--r-- | src/main.h | 4 | ||||
-rw-r--r-- | src/miner.cpp | 8 | ||||
-rw-r--r-- | src/policy/policy.h | 3 | ||||
-rw-r--r-- | src/rpcblockchain.cpp | 3 | ||||
-rw-r--r-- | src/test/miner_tests.cpp | 7 |
13 files changed, 140 insertions, 20 deletions
diff --git a/.gitignore b/.gitignore index a8035731d1..a8722aa593 100644 --- a/.gitignore +++ b/.gitignore @@ -85,15 +85,13 @@ src/test/buildenv.py # Resources cpp qrc_*.cpp -# Qt creator -*.pro.user - # Mac specific .DS_Store build #lcov *.gcno +*.gcda /*.info test_bitcoin.coverage/ total.coverage/ @@ -107,6 +105,9 @@ 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 diff --git a/Makefile.am b/Makefile.am index 8a7140398f..f0961c64ec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -39,7 +39,7 @@ OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) $ COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \ leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \ - baseline_filtered.info block_test_filtered.info \ + baseline_filtered.info block_test_filtered.info rpc_test.info rpc_test_filtered.info \ leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info dist-hook: @@ -170,7 +170,7 @@ test_bitcoin_filtered.info: test_bitcoin.info block_test.info: test_bitcoin_filtered.info $(MKDIR_P) qa/tmp - -@TIMEOUT=15 qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool 0 + -@TIMEOUT=15 qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool $(COMPARISON_TOOL_REORG_TESTS) $(LCOV) -c -d $(abs_builddir)/src --t BitcoinJBlockTest -o $@ $(LCOV) -z -d $(abs_builddir)/src $(LCOV) -z -d $(abs_builddir)/src/leveldb @@ -178,11 +178,20 @@ block_test.info: test_bitcoin_filtered.info block_test_filtered.info: block_test.info $(LCOV) -r $< "/usr/include/*" -o $@ +rpc_test.info: test_bitcoin_filtered.info + -@TIMEOUT=15 python qa/pull-tester/rpc-tests.py $(EXTENDED_RPC_TESTS) + $(LCOV) -c -d $(abs_builddir)/src --t rpc-tests -o $@ + $(LCOV) -z -d $(abs_builddir)/src + $(LCOV) -z -d $(abs_builddir)/src/leveldb + +rpc_test_filtered.info: rpc_test.info + $(LCOV) -r $< "/usr/include/*" -o $@ + test_bitcoin_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -o $@ -total_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info block_test_filtered.info - $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -a block_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt +total_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info block_test_filtered.info rpc_test_filtered.info + $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -a block_test_filtered.info -a rpc_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt test_bitcoin.coverage/.dirstamp: test_bitcoin_coverage.info $(GENHTML) -s $< -o $(@D) @@ -211,4 +220,4 @@ CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) .INTERMEDIATE: $(COVERAGE_INFO) clean-local: - rm -rf test_bitcoin.coverage/ total.coverage/ $(OSX_APP) + rm -rf coverage_percent.txt test_bitcoin.coverage/ total.coverage/ qa/tmp/ cache/ $(OSX_APP) diff --git a/configure.ac b/configure.ac index 4318aafa55..25ace88f32 100644 --- a/configure.ac +++ b/configure.ac @@ -58,6 +58,7 @@ AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) AC_PATH_PROG(JAVA, java) +AC_PATH_PROG(PYTHON, python) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) @@ -106,6 +107,11 @@ AC_ARG_ENABLE([comparison-tool-reorg-tests], [use_comparison_tool_reorg_tests=$enableval], [use_comparison_tool_reorg_tests=no]) +AC_ARG_ENABLE([extended-rpc-tests], + AS_HELP_STRING([--enable-extended-rpc-tests],[enable expensive RPC tests when using lcov (default no)]), + [use_extended_rpc_tests=$enableval], + [use_extended_rpc_tests=no]) + AC_ARG_WITH([qrencode], [AS_HELP_STRING([--with-qrencode], [enable QR code support (default is yes if qt is enabled and libqrencode is found)])], @@ -341,6 +347,10 @@ else AC_SUBST(COMPARISON_TOOL_REORG_TESTS, 0) fi +if test x$use_extended_rpc_tests != xno; then + AC_SUBST(EXTENDED_RPC_TESTS, -extended) +fi + if test x$use_lcov = xyes; then if test x$LCOV = x; then AC_MSG_ERROR("lcov testing requested but lcov not found") @@ -351,6 +361,9 @@ if test x$use_lcov = xyes; then if test x$JAVA = x; then AC_MSG_ERROR("lcov testing requested but java not found") fi + if test x$PYTHON = x; then + AC_MSG_ERROR("lcov testing requested but python not found") + fi if test x$GENHTML = x; then AC_MSG_ERROR("lcov testing requested but genhtml not found") fi diff --git a/doc/bips.md b/doc/bips.md index c84bd966f5..c780e2dde0 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -14,6 +14,7 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.12.0**): * [`BIP 37`](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki): The bloom filtering for transaction relaying, partial merkle trees for blocks, and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since **v0.8.0** ([PR #1795](https://github.com/bitcoin/bitcoin/pull/1795)). * [`BIP 42`](https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki): The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in **v0.9.2** ([PR #3842](https://github.com/bitcoin/bitcoin/pull/3842)). * [`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 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, but only enforced for peer versions `>=70011` as of **v0.12.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579)). diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 4189d22187..7fe292f1f8 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -171,3 +171,36 @@ Threads - BitcoinMiner : Generates bitcoins (if wallet is enabled). - Shutdown : Does an orderly shutdown of everything. + +Ignoring IDE/editor files +-------------------------- + +In closed-source environments in which everyone uses the same IDE it is common +to add temporary files it produces to the project-wide `.gitignore` file. + +However, in open source software such as Bitcoin Core, where everyone uses +their own editors/IDE/tools, it is less common. Only you know what files your +editor produces and this may change from version to version. The canonical way +to do this is thus to create your local gitignore. Add this to `~/.gitconfig`: + +``` +[core] + excludesfile = /home/.../.gitignore_global +``` + +(alternatively, type the command `git config --global core.excludesfile ~/.gitignore_global` +on a terminal) + +Then put your favourite tool's temporary filenames in that file, e.g. +``` +# NetBeans +nbproject/ +``` + +Another option is to create a per-repository excludes file `.git/info/exclude`. +These are not committed but apply only to one repository. + +If a set of tools is used by the build system or scripts the repository (for +example, lcov) it is perfectly acceptable to add its files to `.gitignore` +and commit them. + diff --git a/src/Makefile.am b/src/Makefile.am index 312643cec3..f35b9dc898 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -412,7 +412,19 @@ libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BIT endif # -CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno +CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a +CLEANFILES += *.gcda *.gcno +CLEANFILES += compat/*.gcda compat/*.gcno +CLEANFILES += consensus/*.gcda consensus/*.gcno +CLEANFILES += crypto/*.gcda crypto/*.gcno +CLEANFILES += policy/*.gcda policy/*.gcno +CLEANFILES += primitives/*.gcda primitives/*.gcno +CLEANFILES += script/*.gcda script/*.gcno +CLEANFILES += support/*.gcda support/*.gcno +CLEANFILES += univalue/*.gcda univalue/*.gcno +CLEANFILES += wallet/*.gcda wallet/*.gcno +CLEANFILES += wallet/test/*.gcda wallet/test/*.gcno +CLEANFILES += zmq/*.gcda zmq/*.gcno DISTCLEANFILES = obj/build.h @@ -422,7 +434,7 @@ clean-local: -$(MAKE) -C leveldb clean -$(MAKE) -C secp256k1 clean -$(MAKE) -C univalue clean - rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno + -rm -f leveldb/*/*.gcda leveldb/*/*.gcno leveldb/helpers/memenv/*.gcda leveldb/helpers/memenv/*.gcno -rm -f config.h .rc.o: diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index f937844e9f..6d6ce7e099 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -13,4 +13,10 @@ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ static const int COINBASE_MATURITY = 100; +/** Flags for LockTime() */ +enum { + /* Use GetMedianTimePast() instead of nTime for end point timestamp. */ + LOCKTIME_MEDIAN_TIME_PAST = (1 << 1), +}; + #endif // BITCOIN_CONSENSUS_CONSENSUS_H diff --git a/src/main.cpp b/src/main.cpp index 30df2744a3..499f2c3f76 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -650,10 +650,35 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) return true; } -bool CheckFinalTx(const CTransaction &tx) +bool CheckFinalTx(const CTransaction &tx, int flags) { AssertLockHeld(cs_main); - return IsFinalTx(tx, chainActive.Height() + 1, GetAdjustedTime()); + + // By convention a negative value for flags indicates that the + // current network-enforced consensus rules should be used. In + // a future soft-fork scenario that would mean checking which + // rules would be enforced for the next block and setting the + // appropriate flags. At the present time no soft-forks are + // scheduled, so no flags are set. + flags = std::max(flags, 0); + + // CheckFinalTx() uses chainActive.Height()+1 to evaluate + // nLockTime because when IsFinalTx() is called within + // CBlock::AcceptBlock(), the height of the block *being* + // evaluated is what is used. Thus if we want to know if a + // transaction can be part of the *next* block, we need to call + // IsFinalTx() with one more than chainActive.Height(). + const int nBlockHeight = chainActive.Height() + 1; + + // Timestamps on the other hand don't get any special treatment, + // because we can't know what timestamp the next block will have, + // and there aren't timestamp applications where it matters. + // However this changes once median past time-locks are enforced: + const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST) + ? chainActive.Tip()->GetMedianTimePast() + : GetAdjustedTime(); + + return IsFinalTx(tx, nBlockHeight, nBlockTime); } unsigned int GetLegacySigOpCount(const CTransaction& tx) @@ -797,7 +822,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Only accept nLockTime-using transactions that can be mined in the next // block; we don't want our mempool filled up with transactions that can't // be mined yet. - if (!CheckFinalTx(tx)) + if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS)) return state.DoS(0, false, REJECT_NONSTANDARD, "non-final"); // is it already in the memory pool? @@ -2723,10 +2748,15 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn const Consensus::Params& consensusParams = Params().GetConsensus(); // Check that all transactions are finalized - BOOST_FOREACH(const CTransaction& tx, block.vtx) - if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) { + BOOST_FOREACH(const CTransaction& tx, block.vtx) { + int nLockTimeFlags = 0; + int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST) + ? pindexPrev->GetMedianTimePast() + : block.GetBlockTime(); + if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) { return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); } + } // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): diff --git a/src/main.h b/src/main.h index 202d2c772b..65732d770f 100644 --- a/src/main.h +++ b/src/main.h @@ -308,8 +308,10 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime); * Check if transaction will be final in the next block to be created. * * Calls IsFinalTx() with current block height and appropriate block time. + * + * See consensus/consensus.h for flag definitions. */ -bool CheckFinalTx(const CTransaction &tx); +bool CheckFinalTx(const CTransaction &tx, int flags = -1); /** * Closure representing one script verification diff --git a/src/miner.cpp b/src/miner.cpp index 42c8bb970b..053d9cdbc4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -148,6 +148,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) CBlockIndex* pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; pblock->nTime = GetAdjustedTime(); + const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); CCoinsViewCache view(pcoinsTip); // Priority order to process transactions @@ -162,7 +163,12 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) mi != mempool.mapTx.end(); ++mi) { const CTransaction& tx = mi->GetTx(); - if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, pblock->nTime)) + + int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) + ? nMedianTimePast + : pblock->GetBlockTime(); + + if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff)) continue; COrphan* porphan = NULL; diff --git a/src/policy/policy.h b/src/policy/policy.h index 0ea0d435ad..7027f1402f 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -43,6 +43,9 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY /** For convenience, standard but not mandatory verify flags. */ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; +/** Used as the flags parameter to CheckFinalTx() in non-consensus code */ +static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_MEDIAN_TIME_PAST; + bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); /** * Check for standard transaction types diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 20c0c1fb2f..4786d72a3f 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -773,6 +773,9 @@ UniValue mempoolInfoToJSON() ret.push_back(Pair("size", (int64_t) mempool.size())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + ret.push_back(Pair("maxmempool", (int64_t) maxmempool)); + ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK()))); return ret; } diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 91a3a5738e..827525783a 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -4,6 +4,7 @@ #include "chainparams.h" #include "coins.h" +#include "consensus/consensus.h" #include "consensus/validation.h" #include "main.h" #include "miner.h" @@ -229,7 +230,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.nLockTime = chainActive.Tip()->nHeight+1; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(!CheckFinalTx(tx)); + BOOST_CHECK(!CheckFinalTx(tx, LOCKTIME_MEDIAN_TIME_PAST)); // time locked tx2.vin.resize(1); @@ -243,7 +244,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1; hash = tx2.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(!CheckFinalTx(tx2)); + BOOST_CHECK(!CheckFinalTx(tx2, LOCKTIME_MEDIAN_TIME_PAST)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); @@ -261,7 +262,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) //BOOST_CHECK(CheckFinalTx(tx2)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); - BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 2); delete pblocktemplate; chainActive.Tip()->nHeight--; |