Skip to content

Commit

Permalink
Avoid exceeding maximum safe Javascript integer
Browse files Browse the repository at this point in the history
Some JSON libraries cannot parse integers greater than 2^53-1.

So clamp "no limit" 2^64 sigop/sighash limits to 2^53-1 before
returning them.

A couple of implementation notes:

Changing the constant returned by the consensus/params.h methods
from uint64_t::max to 2^53-1 would be another fix, but that felt
like a layering violation: the consensus code shouldn't care about
details of representing numbers in JSON.

Also, I didn't define JSON_NUMBER_LIMIT in a .h file because it
isn't clear where it belongs (util.h? one of the json/ .h?) and
because at this point it makes sense to try to create patches
that change fewer files.

Fixes issue# 45.
  • Loading branch information
gavinandresen committed Aug 24, 2015
1 parent c8983e0 commit 36e492f
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/rpcmining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,10 +582,17 @@ Value getblocktemplate(const Array& params, bool fHelp)
result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
result.push_back(Pair("mutable", aMutable));
result.push_back(Pair("noncerange", "00000000ffffffff"));
result.push_back(Pair("sigoplimit", Params().GetConsensus().MaxBlockLegacySigops(nBlockTime, sizeForkTime.load())));
result.push_back(Pair("sizelimit", Params().GetConsensus().MaxBlockSize(nBlockTime, sizeForkTime.load())));
result.push_back(Pair("accuratesigoplimit", Params().GetConsensus().MaxBlockAccurateSigops(nBlockTime, sizeForkTime.load())));
result.push_back(Pair("sighashlimit", Params().GetConsensus().MaxBlockSighashBytes(nBlockTime, sizeForkTime.load())));
// Some JSON libraries can't parse full-64-bit integers. So limit the limits to
// the safe javascript number limit, which is 2^53-1
// (see http://www.ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer )
uint64_t JSON_NUMBER_LIMIT = 9007199254740991;
uint64_t sigoplimit = Params().GetConsensus().MaxBlockLegacySigops(nBlockTime, sizeForkTime.load());
result.push_back(Pair("sigoplimit", std::min(JSON_NUMBER_LIMIT, sigoplimit)));
uint64_t accuratesigoplimit = Params().GetConsensus().MaxBlockAccurateSigops(nBlockTime, sizeForkTime.load());
result.push_back(Pair("accuratesigoplimit", std::min(JSON_NUMBER_LIMIT, accuratesigoplimit)));
uint64_t sighashlimit = Params().GetConsensus().MaxBlockSighashBytes(nBlockTime, sizeForkTime.load());
result.push_back(Pair("sighashlimit", std::min(JSON_NUMBER_LIMIT, sighashlimit)));
result.push_back(Pair("curtime", nBlockTime));
result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
Expand Down

0 comments on commit 36e492f

Please sign in to comment.