Skip to content

Commit 40f673f

Browse files
committed
Merge 10282 via timebomb_knots
2 parents d011e71 + 0567077 commit 40f673f

File tree

8 files changed

+53
-2
lines changed

8 files changed

+53
-2
lines changed

src/bitcoind.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ static bool ParseArgs(ArgsManager& args, int argc, char* argv[])
128128
return InitError(Untranslated(strprintf("Command line contains unexpected token '%s', see bitcoind -h for a list of options.", argv[i])));
129129
}
130130
}
131+
132+
g_software_expiry = args.GetIntArg("-softwareexpiry", DEFAULT_SOFTWARE_EXPIRY);
133+
if (IsThisSoftwareExpired(GetTime())) {
134+
tfm::format(std::cerr, "This software is expired, and may be out of consensus. You must choose to upgrade or override this expiration.\n");
135+
exit(EXIT_FAILURE);
136+
}
137+
131138
return true;
132139
}
133140

src/clientversion.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,13 @@ std::string LicenseInfo()
9999
strprintf(_("Distributed under the MIT software license, see the accompanying file %s or %s").translated, "COPYING", "<https://opensource.org/licenses/MIT>") +
100100
"\n";
101101
}
102+
103+
int64_t g_software_expiry{DEFAULT_SOFTWARE_EXPIRY};
104+
105+
bool IsThisSoftwareExpired(int64_t nTime)
106+
{
107+
if (g_software_expiry <= 0) {
108+
return false;
109+
}
110+
return (nTime > g_software_expiry);
111+
}

src/clientversion.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#if !defined(WINDRES_PREPROC)
2727

28+
#include <cstdint>
2829
#include <string>
2930
#include <vector>
3031

@@ -44,6 +45,14 @@ std::string CopyrightHolders(const std::string& strPrefix);
4445
/** Returns licensing information (for -version) */
4546
std::string LicenseInfo();
4647

48+
static constexpr int64_t SECONDS_PER_YEAR = 31558060;
49+
static constexpr int POSIX_EPOCH_YEAR = 1970;
50+
static constexpr int64_t DEFAULT_SOFTWARE_EXPIRY_OFFSET = 26784000; // Around Nov 7
51+
static constexpr int64_t DEFAULT_SOFTWARE_EXPIRY = ((COPYRIGHT_YEAR - POSIX_EPOCH_YEAR) * SECONDS_PER_YEAR) + (SECONDS_PER_YEAR * 2) + DEFAULT_SOFTWARE_EXPIRY_OFFSET;
52+
extern int64_t g_software_expiry;
53+
54+
bool IsThisSoftwareExpired(int64_t nTime);
55+
4756
#endif // WINDRES_PREPROC
4857

4958
#endif // BITCOIN_CLIENTVERSION_H

src/init.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ void SetupServerArgs(ArgsManager& argsman)
528528
argsman.AddArg("-reindex", "If enabled, wipe chain state and block index, and rebuild them from blk*.dat files on disk. Also wipe and rebuild other optional indexes that are active. If an assumeutxo snapshot was loaded, its chainstate will be wiped as well. The snapshot can then be reloaded via RPC. Setting this to auto automatically reindexes the block database if it is corrupted.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
529529
argsman.AddArg("-reindex-chainstate", "If enabled, wipe chain state, and rebuild it from blk*.dat files on disk. If an assumeutxo snapshot was loaded, its chainstate will be wiped as well. The snapshot can then be reloaded via RPC.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
530530
argsman.AddArg("-settings=<file>", strprintf("Specify path to dynamic settings data file. Can be disabled with -nosettings. File is written at runtime and not meant to be edited by users (use %s instead for custom settings). Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME, BITCOIN_SETTINGS_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
531+
argsman.AddArg("-softwareexpiry", strprintf("Stop working after this POSIX timestamp (default: %s)", DEFAULT_SOFTWARE_EXPIRY), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
531532
#if HAVE_SYSTEM
532533
argsman.AddArg("-startupnotify=<cmd>", "Execute command on startup.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
533534
argsman.AddArg("-shutdownnotify=<cmd>", "Execute command immediately before beginning shutdown. The need for shutdown may be urgent, so be careful not to delay it long (if the command doesn't require interaction with the server, consider having it fork into the background).", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);

src/qt/bitcoin.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <qt/bitcoin.h>
88

99
#include <chainparams.h>
10+
#include <clientversion.h>
1011
#include <common/args.h>
1112
#include <common/init.h>
1213
#include <common/system.h>
@@ -652,6 +653,12 @@ int GuiMain(int argc, char* argv[])
652653
// Re-initialize translations after changing application name (language in network-specific settings can be different)
653654
initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
654655

656+
g_software_expiry = gArgs.GetIntArg("-softwareexpiry", DEFAULT_SOFTWARE_EXPIRY);
657+
if (IsThisSoftwareExpired(GetTime())) {
658+
QMessageBox::critical(nullptr, QObject::tr("Software expired"), QObject::tr("This software is expired, and may be out of consensus. You must choose to upgrade or override this expiration."));
659+
return EXIT_FAILURE;
660+
}
661+
655662
#ifdef ENABLE_WALLET
656663
/// 8. URI IPC sending
657664
// - Do this early as we don't want to bother initializing if we are just calling IPC

src/test/fuzz/tx_pool.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <clientversion.h>
56
#include <consensus/validation.h>
67
#include <node/context.h>
78
#include <node/mempool_args.h>
@@ -115,7 +116,7 @@ void MockTime(FuzzedDataProvider& fuzzed_data_provider, const Chainstate& chains
115116
{
116117
const auto time = ConsumeTime(fuzzed_data_provider,
117118
chainstate.m_chain.Tip()->GetMedianTimePast() + 1,
118-
std::numeric_limits<decltype(chainstate.m_chain.Tip()->nTime)>::max());
119+
DEFAULT_SOFTWARE_EXPIRY - 1);
119120
SetMockTime(time);
120121
}
121122

src/validation.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4455,6 +4455,19 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
44554455
strprintf("rejected nVersion=0x%08x block", block.nVersion));
44564456
}
44574457

4458+
if (IsThisSoftwareExpired(block.nTime)) {
4459+
// Wait an extra day before we start rejecting blocks
4460+
CBlockIndex const *blockindex_old = pindexPrev;
4461+
for (int i = 0; i < 144; ++i) {
4462+
assert(blockindex_old);
4463+
blockindex_old = blockindex_old->pprev;
4464+
}
4465+
assert(blockindex_old);
4466+
if (IsThisSoftwareExpired(blockindex_old->GetMedianTimePast())) {
4467+
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "node-expired", "node software has expired");
4468+
}
4469+
}
4470+
44584471
return true;
44594472
}
44604473

test/functional/test_framework/test_node.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ def __init__(self, i, datadir_path, *, chain, rpchost, timewait, timeout_factor,
130130
"--error-exitcode=1", "--quiet"] + self.args
131131

132132
if self.version is None:
133-
self.args.append("-walletimplicitsegwit")
133+
self.args += [
134+
"-softwareexpiry=0",
135+
"-walletimplicitsegwit",
136+
]
134137

135138
if self.version_is_at_least(190000):
136139
self.args.append("-logthreadnames")

0 commit comments

Comments
 (0)