Skip to content

Commit c353025

Browse files
committed
Merge bitcoin/bitcoin#29081: refactor: Remove gmtime*
fa9f36b build: Remove HAVE_GMTIME_R (MarcoFalke) fa72dcb refactor: FormatISO8601* without gmtime* (MarcoFalke) fa2c486 Revert "time: add runtime sanity check" (MarcoFalke) Pull request description: Now that the `ChronoSanityCheck` has passed for everyone with C++17 and is guaranteed by C++20 to always pass, remove it. Also, remove `gmtime_r` and `gmtime_s` and replace them with `year_month_day`+`hh_mm_ss` from C++20. ACKs for top commit: sipa: utACK fa9f36b fanquake: ACK fa9f36b - more std lib & even less stuff to port. Tree-SHA512: a9e7e805b757b7dade0bcc3f95273a7dc4f68622630d74838339789dd203ad7542d36b2e090a93b2bc5a7ecc383207dd7ec82c68147108bdac7ce44f088c8c9a
2 parents eb78ebc + fa9f36b commit c353025

File tree

6 files changed

+20
-100
lines changed

6 files changed

+20
-100
lines changed

configure.ac

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,22 +1086,6 @@ if test "$use_thread_local" = "yes" || test "$use_thread_local" = "auto"; then
10861086
LDFLAGS="$TEMP_LDFLAGS"
10871087
fi
10881088

1089-
dnl check for gmtime_r(), fallback to gmtime_s() if that is unavailable
1090-
dnl fail if neither are available.
1091-
AC_MSG_CHECKING([for gmtime_r])
1092-
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <ctime>]],
1093-
[[ gmtime_r((const time_t *) nullptr, (struct tm *) nullptr); ]])],
1094-
[ AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_GMTIME_R], [1], [Define this symbol if gmtime_r is available]) ],
1095-
[ AC_MSG_RESULT([no]);
1096-
AC_MSG_CHECKING([for gmtime_s]);
1097-
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <ctime>]],
1098-
[[ gmtime_s((struct tm *) nullptr, (const time_t *) nullptr); ]])],
1099-
[ AC_MSG_RESULT([yes])],
1100-
[ AC_MSG_RESULT([no]); AC_MSG_ERROR([Both gmtime_r and gmtime_s are unavailable]) ]
1101-
)
1102-
]
1103-
)
1104-
11051089
dnl Check for different ways of gathering OS randomness
11061090
AC_MSG_CHECKING([for Linux getrandom function])
11071091
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@@ -1862,7 +1846,6 @@ AC_SUBST(MINIUPNPC_CPPFLAGS)
18621846
AC_SUBST(MINIUPNPC_LIBS)
18631847
AC_SUBST(NATPMP_CPPFLAGS)
18641848
AC_SUBST(NATPMP_LIBS)
1865-
AC_SUBST(HAVE_GMTIME_R)
18661849
AC_SUBST(HAVE_FDATASYNC)
18671850
AC_SUBST(HAVE_FULLFSYNC)
18681851
AC_SUBST(HAVE_O_CLOEXEC)

src/kernel/checks.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include <key.h>
88
#include <random.h>
9-
#include <util/time.h>
109
#include <util/translation.h>
1110

1211
#include <memory>
@@ -23,10 +22,6 @@ util::Result<void> SanityChecks(const Context&)
2322
return util::Error{Untranslated("OS cryptographic RNG sanity check failure. Aborting.")};
2423
}
2524

26-
if (!ChronoSanityCheck()) {
27-
return util::Error{Untranslated("Clock epoch mismatch. Aborting.")};
28-
}
29-
3025
return {};
3126
}
3227

src/test/sanity_tests.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
#include <key.h>
66
#include <test/util/setup_common.h>
7-
#include <util/time.h>
87

98
#include <boost/test/unit_test.hpp>
109

@@ -13,7 +12,6 @@ BOOST_FIXTURE_TEST_SUITE(sanity_tests, BasicTestingSetup)
1312
BOOST_AUTO_TEST_CASE(basic_sanity)
1413
{
1514
BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "secp256k1 sanity test");
16-
BOOST_CHECK_MESSAGE(ChronoSanityCheck() == true, "chrono epoch test");
1715
}
1816

1917
BOOST_AUTO_TEST_SUITE_END()

src/test/util_tests.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,18 @@ BOOST_AUTO_TEST_CASE(util_TrimString)
290290

291291
BOOST_AUTO_TEST_CASE(util_FormatISO8601DateTime)
292292
{
293+
BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890963199), "32767-12-31T23:59:59Z");
294+
BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890876800), "32767-12-31T00:00:00Z");
293295
BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z");
294296
BOOST_CHECK_EQUAL(FormatISO8601DateTime(0), "1970-01-01T00:00:00Z");
295297
}
296298

297299
BOOST_AUTO_TEST_CASE(util_FormatISO8601Date)
298300
{
301+
BOOST_CHECK_EQUAL(FormatISO8601Date(971890963199), "32767-12-31");
302+
BOOST_CHECK_EQUAL(FormatISO8601Date(971890876800), "32767-12-31");
299303
BOOST_CHECK_EQUAL(FormatISO8601Date(1317425777), "2011-09-30");
304+
BOOST_CHECK_EQUAL(FormatISO8601Date(0), "1970-01-01");
300305
}
301306

302307
BOOST_AUTO_TEST_CASE(util_FormatMoney)

src/util/time.cpp

Lines changed: 15 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,21 @@
33
// Distributed under the MIT software license, see the accompanying
44
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

6-
#if defined(HAVE_CONFIG_H)
7-
#include <config/bitcoin-config.h>
8-
#endif
6+
#include <util/time.h>
97

108
#include <compat/compat.h>
119
#include <tinyformat.h>
12-
#include <util/time.h>
1310
#include <util/check.h>
1411

1512
#include <atomic>
1613
#include <chrono>
17-
#include <ctime>
18-
#include <locale>
19-
#include <thread>
20-
#include <sstream>
2114
#include <string>
15+
#include <thread>
2216

2317
void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); }
2418

2519
static std::atomic<int64_t> nMockTime(0); //!< For testing
2620

27-
bool ChronoSanityCheck()
28-
{
29-
// std::chrono::system_clock.time_since_epoch and time_t(0) are not guaranteed
30-
// to use the Unix epoch timestamp, prior to C++20, but in practice they almost
31-
// certainly will. Any differing behavior will be assumed to be an error, unless
32-
// certain platforms prove to consistently deviate, at which point we'll cope
33-
// with it by adding offsets.
34-
35-
// Create a new clock from time_t(0) and make sure that it represents 0
36-
// seconds from the system_clock's time_since_epoch. Then convert that back
37-
// to a time_t and verify that it's the same as before.
38-
const time_t time_t_epoch{};
39-
auto clock = std::chrono::system_clock::from_time_t(time_t_epoch);
40-
if (std::chrono::duration_cast<std::chrono::seconds>(clock.time_since_epoch()).count() != 0) {
41-
return false;
42-
}
43-
44-
time_t time_val = std::chrono::system_clock::to_time_t(clock);
45-
if (time_val != time_t_epoch) {
46-
return false;
47-
}
48-
49-
// Check that the above zero time is actually equal to the known unix timestamp.
50-
struct tm epoch;
51-
#ifdef HAVE_GMTIME_R
52-
if (gmtime_r(&time_val, &epoch) == nullptr) {
53-
#else
54-
if (gmtime_s(&epoch, &time_val) != 0) {
55-
#endif
56-
return false;
57-
}
58-
59-
if ((epoch.tm_sec != 0) ||
60-
(epoch.tm_min != 0) ||
61-
(epoch.tm_hour != 0) ||
62-
(epoch.tm_mday != 1) ||
63-
(epoch.tm_mon != 0) ||
64-
(epoch.tm_year != 70)) {
65-
return false;
66-
}
67-
return true;
68-
}
69-
7021
NodeClock::time_point NodeClock::now() noexcept
7122
{
7223
const std::chrono::seconds mocktime{nMockTime.load(std::memory_order_relaxed)};
@@ -96,30 +47,21 @@ std::chrono::seconds GetMockTime()
9647

9748
int64_t GetTime() { return GetTime<std::chrono::seconds>().count(); }
9849

99-
std::string FormatISO8601DateTime(int64_t nTime) {
100-
struct tm ts;
101-
time_t time_val = nTime;
102-
#ifdef HAVE_GMTIME_R
103-
if (gmtime_r(&time_val, &ts) == nullptr) {
104-
#else
105-
if (gmtime_s(&ts, &time_val) != 0) {
106-
#endif
107-
return {};
108-
}
109-
return strprintf("%04i-%02i-%02iT%02i:%02i:%02iZ", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec);
50+
std::string FormatISO8601DateTime(int64_t nTime)
51+
{
52+
const std::chrono::sys_seconds secs{std::chrono::seconds{nTime}};
53+
const auto days{std::chrono::floor<std::chrono::days>(secs)};
54+
const std::chrono::year_month_day ymd{days};
55+
const std::chrono::hh_mm_ss hms{secs - days};
56+
return strprintf("%04i-%02u-%02uT%02i:%02i:%02iZ", signed{ymd.year()}, unsigned{ymd.month()}, unsigned{ymd.day()}, hms.hours().count(), hms.minutes().count(), hms.seconds().count());
11057
}
11158

112-
std::string FormatISO8601Date(int64_t nTime) {
113-
struct tm ts;
114-
time_t time_val = nTime;
115-
#ifdef HAVE_GMTIME_R
116-
if (gmtime_r(&time_val, &ts) == nullptr) {
117-
#else
118-
if (gmtime_s(&ts, &time_val) != 0) {
119-
#endif
120-
return {};
121-
}
122-
return strprintf("%04i-%02i-%02i", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday);
59+
std::string FormatISO8601Date(int64_t nTime)
60+
{
61+
const std::chrono::sys_seconds secs{std::chrono::seconds{nTime}};
62+
const auto days{std::chrono::floor<std::chrono::days>(secs)};
63+
const std::chrono::year_month_day ymd{days};
64+
return strprintf("%04i-%02u-%02u", signed{ymd.year()}, unsigned{ymd.month()}, unsigned{ymd.day()});
12365
}
12466

12567
struct timeval MillisToTimeval(int64_t nTimeout)

src/util/time.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,4 @@ struct timeval MillisToTimeval(int64_t nTimeout);
116116
*/
117117
struct timeval MillisToTimeval(std::chrono::milliseconds ms);
118118

119-
/** Sanity check epoch match normal Unix epoch */
120-
bool ChronoSanityCheck();
121-
122119
#endif // BITCOIN_UTIL_TIME_H

0 commit comments

Comments
 (0)