util: Disallow negative mocktime

Signed-off-by: practicalswift <practicalswift@users.noreply.github.com>
pull/826/head
MarcoFalke 4 years ago committed by practicalswift
parent f5f2f97168
commit 3ddbf22ed1

@ -365,13 +365,13 @@ static RPCHelpMan signmessagewithprivkey()
static RPCHelpMan setmocktime() static RPCHelpMan setmocktime()
{ {
return RPCHelpMan{"setmocktime", return RPCHelpMan{"setmocktime",
"\nSet the local time to given timestamp (-regtest only)\n", "\nSet the local time to given timestamp (-regtest only)\n",
{ {
{"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, UNIX_EPOCH_TIME + "\n" {"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, UNIX_EPOCH_TIME + "\n"
" Pass 0 to go back to using the system time."}, "Pass 0 to go back to using the system time."},
}, },
RPCResult{RPCResult::Type::NONE, "", ""}, RPCResult{RPCResult::Type::NONE, "", ""},
RPCExamples{""}, RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{ {
if (!Params().IsMockableChain()) { if (!Params().IsMockableChain()) {
@ -386,7 +386,10 @@ static RPCHelpMan setmocktime()
LOCK(cs_main); LOCK(cs_main);
RPCTypeCheck(request.params, {UniValue::VNUM}); RPCTypeCheck(request.params, {UniValue::VNUM});
int64_t time = request.params[0].get_int64(); const int64_t time{request.params[0].get_int64()};
if (time < 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Mocktime can not be negative: %s.", time));
}
SetMockTime(time); SetMockTime(time);
if (request.context.Has<NodeContext>()) { if (request.context.Has<NodeContext>()) {
for (const auto& chain_client : request.context.Get<NodeContext>().chain_clients) { for (const auto& chain_client : request.context.Get<NodeContext>().chain_clients) {

@ -9,6 +9,8 @@
#include <util/time.h> #include <util/time.h>
#include <util/check.h>
#include <atomic> #include <atomic>
#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp>
#include <ctime> #include <ctime>
@ -18,7 +20,7 @@
void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); } void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); }
static std::atomic<int64_t> nMockTime(0); //!< For unit testing static std::atomic<int64_t> nMockTime(0); //!< For testing
int64_t GetTime() int64_t GetTime()
{ {
@ -46,6 +48,7 @@ template std::chrono::microseconds GetTime();
void SetMockTime(int64_t nMockTimeIn) void SetMockTime(int64_t nMockTimeIn)
{ {
Assert(nMockTimeIn >= 0);
nMockTime.store(nMockTimeIn, std::memory_order_relaxed); nMockTime.store(nMockTimeIn, std::memory_order_relaxed);
} }

@ -10,6 +10,7 @@ Test corresponds to code in rpc/server.cpp.
import time import time
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_raises_rpc_error
class UptimeTest(BitcoinTestFramework): class UptimeTest(BitcoinTestFramework):
@ -18,8 +19,12 @@ class UptimeTest(BitcoinTestFramework):
self.setup_clean_chain = True self.setup_clean_chain = True
def run_test(self): def run_test(self):
self._test_negative_time()
self._test_uptime() self._test_uptime()
def _test_negative_time(self):
assert_raises_rpc_error(-8, "Mocktime can not be negative: -1.", self.nodes[0].setmocktime, -1)
def _test_uptime(self): def _test_uptime(self):
wait_time = 10 wait_time = 10
self.nodes[0].setmocktime(int(time.time() + wait_time)) self.nodes[0].setmocktime(int(time.time() + wait_time))

Loading…
Cancel
Save