aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.bench.include2
-rw-r--r--src/bench/bench.cpp4
-rw-r--r--src/bench/perf.cpp53
-rw-r--r--src/bench/perf.h37
-rw-r--r--src/bitcoind.cpp5
-rw-r--r--src/chainparams.cpp6
-rw-r--r--src/compat.h6
-rw-r--r--src/consensus/params.h4
-rw-r--r--src/interfaces/node.cpp3
-rw-r--r--src/interfaces/node.h9
-rw-r--r--src/interfaces/wallet.h2
-rw-r--r--src/net.cpp27
-rw-r--r--src/netaddress.cpp50
-rw-r--r--src/netaddress.h10
-rw-r--r--src/netbase.cpp6
-rw-r--r--src/validation.cpp39
-rw-r--r--src/validation.h3
-rw-r--r--src/wallet/test/wallet_tests.cpp5
18 files changed, 82 insertions, 189 deletions
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include
index 748c5b7887..3306dcf598 100644
--- a/src/Makefile.bench.include
+++ b/src/Makefile.bench.include
@@ -25,8 +25,6 @@ bench_bench_bitcoin_SOURCES = \
bench/verify_script.cpp \
bench/base58.cpp \
bench/lockedpool.cpp \
- bench/perf.cpp \
- bench/perf.h \
bench/prevector.cpp
nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES)
diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp
index 21329a5151..de3e57b04f 100644
--- a/src/bench/bench.cpp
+++ b/src/bench/bench.cpp
@@ -3,7 +3,6 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <bench/bench.h>
-#include <bench/perf.h>
#include <assert.h>
#include <iostream>
@@ -96,7 +95,6 @@ benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction f
void benchmark::BenchRunner::RunAll(Printer& printer, uint64_t num_evals, double scaling, const std::string& filter, bool is_list_only)
{
- perf_init();
if (!std::ratio_less_equal<benchmark::clock::period, std::micro>::value) {
std::cerr << "WARNING: Clock precision is worse than microsecond - benchmarks may be less accurate!\n";
}
@@ -126,8 +124,6 @@ void benchmark::BenchRunner::RunAll(Printer& printer, uint64_t num_evals, double
}
printer.footer();
-
- perf_fini();
}
bool benchmark::State::UpdateTimer(const benchmark::time_point current_time)
diff --git a/src/bench/perf.cpp b/src/bench/perf.cpp
deleted file mode 100644
index f92d08c56e..0000000000
--- a/src/bench/perf.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2016-2017 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include <bench/perf.h>
-
-#if defined(__i386__) || defined(__x86_64__)
-
-/* These architectures support querying the cycle counter
- * from user space, no need for any syscall overhead.
- */
-void perf_init(void) { }
-void perf_fini(void) { }
-
-#elif defined(__linux__)
-
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <linux/perf_event.h>
-
-static int fd = -1;
-static struct perf_event_attr attr;
-
-void perf_init(void)
-{
- attr.type = PERF_TYPE_HARDWARE;
- attr.config = PERF_COUNT_HW_CPU_CYCLES;
- fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
-}
-
-void perf_fini(void)
-{
- if (fd != -1) {
- close(fd);
- }
-}
-
-uint64_t perf_cpucycles(void)
-{
- uint64_t result = 0;
- if (fd == -1 || read(fd, &result, sizeof(result)) < (ssize_t)sizeof(result)) {
- return 0;
- }
- return result;
-}
-
-#else /* Unhandled platform */
-
-void perf_init(void) { }
-void perf_fini(void) { }
-uint64_t perf_cpucycles(void) { return 0; }
-
-#endif
diff --git a/src/bench/perf.h b/src/bench/perf.h
deleted file mode 100644
index 73ea8b9647..0000000000
--- a/src/bench/perf.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-/** Functions for measurement of CPU cycles */
-#ifndef BITCOIN_BENCH_PERF_H
-#define BITCOIN_BENCH_PERF_H
-
-#include <stdint.h>
-
-#if defined(__i386__)
-
-static inline uint64_t perf_cpucycles(void)
-{
- uint64_t x;
- __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
- return x;
-}
-
-#elif defined(__x86_64__)
-
-static inline uint64_t perf_cpucycles(void)
-{
- uint32_t hi, lo;
- __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
- return ((uint64_t)lo)|(((uint64_t)hi)<<32);
-}
-#else
-
-uint64_t perf_cpucycles(void);
-
-#endif
-
-void perf_init(void);
-void perf_fini(void);
-
-#endif // BITCOIN_BENCH_PERF_H
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 83d9719df2..0dc2dfbf7d 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -42,12 +42,9 @@
void WaitForShutdown()
{
- bool fShutdown = ShutdownRequested();
- // Tell the main threads to shutdown.
- while (!fShutdown)
+ while (!ShutdownRequested())
{
MilliSleep(200);
- fShutdown = ShutdownRequested();
}
Interrupt();
}
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 6067503b0b..121d95af90 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -75,7 +75,7 @@ public:
CMainParams() {
strNetworkID = "main";
consensus.nSubsidyHalvingInterval = 210000;
- consensus.BIP16Height = 173805; // 00000000000000ce80a7e057163a4db1d5ad7b20fb6f598c9597b9665c8fb0d4 - April 1, 2012
+ consensus.BIP16Exception = uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22");
consensus.BIP34Height = 227931;
consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8");
consensus.BIP65Height = 388381; // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0
@@ -190,7 +190,7 @@ public:
CTestNetParams() {
strNetworkID = "test";
consensus.nSubsidyHalvingInterval = 210000;
- consensus.BIP16Height = 514; // 00000000040b4e986385315e14bee30ad876d8b47f748025b26683116d21aa65
+ consensus.BIP16Exception = uint256S("0x00000000dd30457c001f4095d208cc1296b0eed002427aa599874af7a432b105");
consensus.BIP34Height = 21111;
consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8");
consensus.BIP65Height = 581885; // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
@@ -283,7 +283,7 @@ public:
CRegTestParams() {
strNetworkID = "regtest";
consensus.nSubsidyHalvingInterval = 150;
- consensus.BIP16Height = 0; // always enforce P2SH BIP16 on regtest
+ consensus.BIP16Exception = uint256();
consensus.BIP34Height = 100000000; // BIP34 has not activated on regtest (far in the future so block v1 are not rejected in tests)
consensus.BIP34Hash = uint256();
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
diff --git a/src/compat.h b/src/compat.h
index 8a0f901304..920b3f776d 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -96,6 +96,12 @@ typedef int32_t ssize_t;
size_t strnlen( const char *start, size_t max_len);
#endif // HAVE_DECL_STRNLEN
+#ifndef WIN32
+typedef void* sockopt_arg_type;
+#else
+typedef char* sockopt_arg_type;
+#endif
+
bool static inline IsSelectableSocket(const SOCKET& s) {
#ifdef WIN32
return true;
diff --git a/src/consensus/params.h b/src/consensus/params.h
index 4ef808c856..0559304fc2 100644
--- a/src/consensus/params.h
+++ b/src/consensus/params.h
@@ -49,8 +49,8 @@ struct BIP9Deployment {
struct Params {
uint256 hashGenesisBlock;
int nSubsidyHalvingInterval;
- /** Block height at which BIP16 becomes active */
- int BIP16Height;
+ /* Block hash that is excepted from BIP16 enforcement */
+ uint256 BIP16Exception;
/** Block height and hash at which BIP34 becomes active */
int BIP34Height;
uint256 BIP34Hash;
diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp
index 919748f942..ddd5496a80 100644
--- a/src/interfaces/node.cpp
+++ b/src/interfaces/node.cpp
@@ -216,9 +216,6 @@ class NodeImpl : public Node
return result;
}
CFeeRate getDustRelayFee() override { return ::dustRelayFee; }
- CFeeRate getFallbackFee() override { CHECK_WALLET(return CWallet::fallbackFee); }
- CFeeRate getPayTxFee() override { CHECK_WALLET(return ::payTxFee); }
- void setPayTxFee(CFeeRate rate) override { CHECK_WALLET(::payTxFee = rate); }
UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
{
JSONRPCRequest req;
diff --git a/src/interfaces/node.h b/src/interfaces/node.h
index f375af2f19..84e869100a 100644
--- a/src/interfaces/node.h
+++ b/src/interfaces/node.h
@@ -173,15 +173,6 @@ public:
//! Get dust relay fee.
virtual CFeeRate getDustRelayFee() = 0;
- //! Get fallback fee.
- virtual CFeeRate getFallbackFee() = 0;
-
- //! Get pay tx fee.
- virtual CFeeRate getPayTxFee() = 0;
-
- //! Set pay tx fee.
- virtual void setPayTxFee(CFeeRate rate) = 0;
-
//! Execute rpc command.
virtual UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) = 0;
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index dfe3d5f711..9d4830d189 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -6,7 +6,7 @@
#define BITCOIN_INTERFACES_WALLET_H
#include <amount.h> // For CAmount
-#include <pubkey.h> // For CTxDestination (CKeyID and CScriptID)
+#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
#include <script/ismine.h> // For isminefilter, isminetype
#include <script/standard.h> // For CTxDestination
#include <support/allocators/secure.h> // For SecureString
diff --git a/src/net.cpp b/src/net.cpp
index 356a66563f..cd076c1ce2 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1923,23 +1923,25 @@ std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
for (const std::string& strAddNode : lAddresses) {
CService service(LookupNumeric(strAddNode.c_str(), Params().GetDefaultPort()));
+ AddedNodeInfo addedNode{strAddNode, CService(), false, false};
if (service.IsValid()) {
// strAddNode is an IP:port
auto it = mapConnected.find(service);
if (it != mapConnected.end()) {
- ret.push_back(AddedNodeInfo{strAddNode, service, true, it->second});
- } else {
- ret.push_back(AddedNodeInfo{strAddNode, CService(), false, false});
+ addedNode.resolvedAddress = service;
+ addedNode.fConnected = true;
+ addedNode.fInbound = it->second;
}
} else {
// strAddNode is a name
auto it = mapConnectedByName.find(strAddNode);
if (it != mapConnectedByName.end()) {
- ret.push_back(AddedNodeInfo{strAddNode, it->second.second, true, it->second.first});
- } else {
- ret.push_back(AddedNodeInfo{strAddNode, CService(), false, false});
+ addedNode.resolvedAddress = it->second.second;
+ addedNode.fConnected = true;
+ addedNode.fInbound = it->second.first;
}
}
+ ret.emplace_back(std::move(addedNode));
}
return ret;
@@ -2088,23 +2090,16 @@ bool CConnman::BindListenPort(const CService &addrBind, std::string& strError, b
LogPrintf("%s\n", strError);
return false;
}
-#ifndef WIN32
+
// Allow binding if the port is still in TIME_WAIT state after
// the program was closed and restarted.
- setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
-#else
- setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int));
-#endif
+ setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne, sizeof(int));
// some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
// and enable it by default or not. Try to enable it, if possible.
if (addrBind.IsIPv6()) {
#ifdef IPV6_V6ONLY
-#ifdef WIN32
- setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
-#else
- setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
-#endif
+ setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int));
#endif
#ifdef WIN32
int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 4f231d73c8..18d5948f85 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -14,7 +14,7 @@ static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
// 0xFD + sha256("bitcoin")[0:5]
static const unsigned char g_internal_prefix[] = { 0xFD, 0x6B, 0x88, 0xC0, 0x87, 0x24 };
-void CNetAddr::Init()
+CNetAddr::CNetAddr()
{
memset(ip, 0, sizeof(ip));
scopeId = 0;
@@ -67,11 +67,6 @@ bool CNetAddr::SetSpecial(const std::string &strName)
return false;
}
-CNetAddr::CNetAddr()
-{
- Init();
-}
-
CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
{
SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr);
@@ -290,11 +285,6 @@ bool operator==(const CNetAddr& a, const CNetAddr& b)
return (memcmp(a.ip, b.ip, 16) == 0);
}
-bool operator!=(const CNetAddr& a, const CNetAddr& b)
-{
- return (memcmp(a.ip, b.ip, 16) != 0);
-}
-
bool operator<(const CNetAddr& a, const CNetAddr& b)
{
return (memcmp(a.ip, b.ip, 16) < 0);
@@ -469,14 +459,8 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
}
}
-void CService::Init()
+CService::CService() : port(0)
{
- port = 0;
-}
-
-CService::CService()
-{
- Init();
}
CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn)
@@ -525,11 +509,6 @@ bool operator==(const CService& a, const CService& b)
return static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) && a.port == b.port;
}
-bool operator!=(const CService& a, const CService& b)
-{
- return static_cast<CNetAddr>(a) != static_cast<CNetAddr>(b) || a.port != b.port;
-}
-
bool operator<(const CService& a, const CService& b)
{
return static_cast<CNetAddr>(a) < static_cast<CNetAddr>(b) || (static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) && a.port < b.port);
@@ -663,16 +642,16 @@ bool CSubNet::Match(const CNetAddr &addr) const
static inline int NetmaskBits(uint8_t x)
{
switch(x) {
- case 0x00: return 0; break;
- case 0x80: return 1; break;
- case 0xc0: return 2; break;
- case 0xe0: return 3; break;
- case 0xf0: return 4; break;
- case 0xf8: return 5; break;
- case 0xfc: return 6; break;
- case 0xfe: return 7; break;
- case 0xff: return 8; break;
- default: return -1; break;
+ case 0x00: return 0;
+ case 0x80: return 1;
+ case 0xc0: return 2;
+ case 0xe0: return 3;
+ case 0xf0: return 4;
+ case 0xf8: return 5;
+ case 0xfc: return 6;
+ case 0xfe: return 7;
+ case 0xff: return 8;
+ default: return -1;
}
}
@@ -724,11 +703,6 @@ bool operator==(const CSubNet& a, const CSubNet& b)
return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
}
-bool operator!=(const CSubNet& a, const CSubNet& b)
-{
- return !(a==b);
-}
-
bool operator<(const CSubNet& a, const CSubNet& b)
{
return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0));
diff --git a/src/netaddress.h b/src/netaddress.h
index 38f8709257..f8f2ab99ff 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -38,15 +38,16 @@ class CNetAddr
public:
CNetAddr();
explicit CNetAddr(const struct in_addr& ipv4Addr);
- void Init();
void SetIP(const CNetAddr& ip);
+ private:
/**
* Set raw IPv4 or IPv6 address (in network byte order)
* @note Only NET_IPV4 and NET_IPV6 are allowed for network.
*/
void SetRaw(Network network, const uint8_t *data);
+ public:
/**
* Transform an arbitrary string into a non-routable ipv6 address.
* Useful for mapping resolved addresses back to their source.
@@ -87,7 +88,7 @@ class CNetAddr
bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
friend bool operator==(const CNetAddr& a, const CNetAddr& b);
- friend bool operator!=(const CNetAddr& a, const CNetAddr& b);
+ friend bool operator!=(const CNetAddr& a, const CNetAddr& b) { return !(a == b); }
friend bool operator<(const CNetAddr& a, const CNetAddr& b);
ADD_SERIALIZE_METHODS;
@@ -124,7 +125,7 @@ class CSubNet
bool IsValid() const;
friend bool operator==(const CSubNet& a, const CSubNet& b);
- friend bool operator!=(const CSubNet& a, const CSubNet& b);
+ friend bool operator!=(const CSubNet& a, const CSubNet& b) { return !(a == b); }
friend bool operator<(const CSubNet& a, const CSubNet& b);
ADD_SERIALIZE_METHODS;
@@ -148,12 +149,11 @@ class CService : public CNetAddr
CService(const CNetAddr& ip, unsigned short port);
CService(const struct in_addr& ipv4Addr, unsigned short port);
explicit CService(const struct sockaddr_in& addr);
- void Init();
unsigned short GetPort() const;
bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const;
bool SetSockAddr(const struct sockaddr* paddr);
friend bool operator==(const CService& a, const CService& b);
- friend bool operator!=(const CService& a, const CService& b);
+ friend bool operator!=(const CService& a, const CService& b) { return !(a == b); }
friend bool operator<(const CService& a, const CService& b);
std::vector<unsigned char> GetKey() const;
std::string ToString() const;
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 5d3d2f25c8..57835b5427 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -513,11 +513,7 @@ bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, i
return false;
}
socklen_t nRetSize = sizeof(nRet);
-#ifdef WIN32
- if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
-#else
- if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
-#endif
+ if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (sockopt_arg_type)&nRet, &nRetSize) == SOCKET_ERROR)
{
LogPrintf("getsockopt() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
return false;
diff --git a/src/validation.cpp b/src/validation.cpp
index 3726cb3b14..daa33d3f5a 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1726,16 +1726,38 @@ public:
// Protected by cs_main
static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS];
+// 0.13.0 was shipped with a segwit deployment defined for testnet, but not for
+// mainnet. We no longer need to support disabling the segwit deployment
+// except for testing purposes, due to limitations of the functional test
+// environment. See test/functional/p2p-segwit.py.
+static bool IsScriptWitnessEnabled(const Consensus::Params& params)
+{
+ return params.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0;
+}
+
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams) {
AssertLockHeld(cs_main);
unsigned int flags = SCRIPT_VERIFY_NONE;
- // Start enforcing P2SH (BIP16)
- if (pindex->nHeight >= consensusparams.BIP16Height) {
+ // BIP16 didn't become active until Apr 1 2012 (on mainnet, and
+ // retroactively applied to testnet)
+ // However, only one historical block violated the P2SH rules (on both
+ // mainnet and testnet), so for simplicity, always leave P2SH
+ // on except for the one violating block.
+ if (consensusparams.BIP16Exception.IsNull() || // no bip16 exception on this chain
+ pindex->phashBlock == nullptr || // this is a new candidate block, eg from TestBlockValidity()
+ *pindex->phashBlock != consensusparams.BIP16Exception) // this block isn't the historical exception
+ {
flags |= SCRIPT_VERIFY_P2SH;
}
+ // Enforce WITNESS rules whenever P2SH is in effect (and the segwit
+ // deployment is defined).
+ if (flags & SCRIPT_VERIFY_P2SH && IsScriptWitnessEnabled(consensusparams)) {
+ flags |= SCRIPT_VERIFY_WITNESS;
+ }
+
// Start enforcing the DERSIG (BIP66) rule
if (pindex->nHeight >= consensusparams.BIP66Height) {
flags |= SCRIPT_VERIFY_DERSIG;
@@ -1751,9 +1773,7 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
}
- // Start enforcing WITNESS rules using versionbits logic.
- if (IsWitnessEnabled(pindex->pprev, consensusparams)) {
- flags |= SCRIPT_VERIFY_WITNESS;
+ if (IsNullDummyEnabled(pindex->pprev, consensusparams)) {
flags |= SCRIPT_VERIFY_NULLDUMMY;
}
@@ -3099,6 +3119,12 @@ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& pa
return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == ThresholdState::ACTIVE);
}
+bool IsNullDummyEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
+{
+ LOCK(cs_main);
+ return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == ThresholdState::ACTIVE);
+}
+
// Compute at which vout of the block's coinbase transaction the witness
// commitment occurs, or -1 if not found.
static int GetWitnessCommitmentIndex(const CBlock& block)
@@ -4091,6 +4117,9 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
int nHeight = 1;
while (nHeight <= chainActive.Height()) {
+ // Although SCRIPT_VERIFY_WITNESS is now generally enforced on all
+ // blocks in ConnectBlock, we don't need to go back and
+ // re-download/re-verify blocks from before segwit actually activated.
if (IsWitnessEnabled(chainActive[nHeight - 1], params.GetConsensus()) && !(chainActive[nHeight]->nStatus & BLOCK_OPT_WITNESS)) {
break;
}
diff --git a/src/validation.h b/src/validation.h
index 3668484696..b415a85053 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -411,6 +411,9 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
/** Check whether witness commitments are required for block. */
bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params);
+/** Check whether NULLDUMMY (BIP 147) has activated. */
+bool IsNullDummyEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params);
+
/** When there are blocks in the active chain with missing data, rewind the chainstate and remove them from the block index */
bool RewindBlockIndex(const CChainParams& params);
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index be7e39639e..57705926a3 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -142,6 +142,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
request.params.push_back((pathTemp / "wallet.backup").string());
vpwallets.insert(vpwallets.begin(), &wallet);
::dumpwallet(request);
+ vpwallets.erase(vpwallets.begin());
}
// Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME
@@ -152,8 +153,9 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
JSONRPCRequest request;
request.params.setArray();
request.params.push_back((pathTemp / "wallet.backup").string());
- vpwallets[0] = &wallet;
+ vpwallets.insert(vpwallets.begin(), &wallet);
::importwallet(request);
+ vpwallets.erase(vpwallets.begin());
LOCK(wallet.cs_wallet);
BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3U);
@@ -166,7 +168,6 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
}
SetMockTime(0);
- vpwallets.erase(vpwallets.begin());
}
// Check that GetImmatureCredit() returns a newly calculated value instead of