From ada4eca6ec1a88a7937e4cef6ecc11d86310d45b Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 13 Feb 2017 00:01:55 +0000 Subject: [PATCH] If -spkreuse=0, ensure transactions in mempool always have unique scriptPubKeys Exceptions: - Multiple inputs in the same transaction are allowed to spend against the same scriptPubKey - The same scriptPubKey may be used in the mempool as both first an output, and then spent in a later transaction's input --- src/init.cpp | 11 +++++++++++ src/kernel/mempool_entry.h | 11 +++++++++++ src/policy/policy.h | 1 + src/txmempool.cpp | 21 ++++++++++++++++++++ src/txmempool.h | 6 ++++++ src/validation.cpp | 39 ++++++++++++++++++++++++++++++++++++++ src/validation.h | 7 +++++++ 7 files changed, 96 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 5e91512c5e..9919b30804 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -589,6 +589,7 @@ void SetupServerArgs(ArgsManager& argsman) OptionsCategory::NODE_RELAY); argsman.AddArg("-minrelaytxfee=", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); + argsman.AddArg("-spkreuse", strprintf("Accept transactions reusing addresses or other pubkey scripts (default: %s)", DEFAULT_SPKREUSE), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); argsman.AddArg("-whitelistforcerelay", strprintf("Add 'forcerelay' permission to whitelisted peers with default permissions. This will relay transactions even if the transactions were already in the mempool. (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); argsman.AddArg("-whitelistrelay", strprintf("Add 'relay' permission to whitelisted peers with default permissions. This will accept relayed transactions even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); @@ -969,6 +970,16 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb if (!g_wallet_init_interface.ParameterInteraction()) return false; + { + std::string strSpkReuse = gArgs.GetArg("-spkreuse", DEFAULT_SPKREUSE); + // Uses string values so future versions can implement other modes + if (strSpkReuse == "allow" || gArgs.GetBoolArg("-spkreuse", false)) { + SpkReuseMode = SRM_ALLOW; + } else { + SpkReuseMode = SRM_REJECT; + } + } + // Option to startup with mocktime set (used for regression testing): SetMockTime(args.GetIntArg("-mocktime", 0)); // SetMockTime(0) is a no-op diff --git a/src/kernel/mempool_entry.h b/src/kernel/mempool_entry.h index e1ba4296ef..96e0d4a62b 100644 --- a/src/kernel/mempool_entry.h +++ b/src/kernel/mempool_entry.h @@ -35,6 +35,15 @@ struct LockPoints { CBlockIndex* maxInputBlock{nullptr}; }; +enum MemPool_SPK_State { + MSS_UNSEEN = 0, + MSS_SPENT = 1, + MSS_CREATED = 2, + MSS_BOTH = 3, +}; + +typedef std::map SPKStates_t; + struct CompareIteratorByHash { // SFINAE for T where T is either a pointer type (e.g., a txiter) or a reference_wrapper // (e.g. a wrapped CTxMemPoolEntry&) @@ -169,6 +178,8 @@ public: mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms + + SPKStates_t mapSPK; }; #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H diff --git a/src/policy/policy.h b/src/policy/policy.h index 7dd4205b74..3ae476fb61 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -54,6 +54,7 @@ static constexpr unsigned int MAX_STANDARD_SCRIPTSIG_SIZE{1650}; * only increase the dust limit after prior releases were already not creating * outputs below the new threshold */ static constexpr unsigned int DUST_RELAY_TX_FEE{3000}; +static const std::string DEFAULT_SPKREUSE{"allow"}; /** Default for -minrelaytxfee, minimum relay fee for transactions */ static constexpr unsigned int DEFAULT_MIN_RELAY_TX_FEE{1000}; /** Default for -limitancestorcount, max number of in-mempool ancestors */ diff --git a/src/txmempool.cpp b/src/txmempool.cpp index fb6e102c5d..d49fa01da1 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -10,10 +10,12 @@ #include #include #include +#include #include #include #include #include +#include