From 12c708a4b3a799478fbb3f93fda696706177a824 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 1 Jun 2016 16:51:54 +0000 Subject: getblocktemplate: Use version/force mutation to support pre-BIP9 clients --- src/rpc/mining.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'src/rpc/mining.cpp') diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 9558b4c20e..5a06d15c53 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -345,6 +345,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) std::string strMode = "template"; UniValue lpval = NullUniValue; std::set setClientRules; + int64_t nMaxVersionPreVB = -1; if (params.size() > 0) { const UniValue& oparam = params[0].get_obj(); @@ -395,6 +396,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) const UniValue& v = aClientRules[i]; setClientRules.insert(v.get_str()); } + } else { + // NOTE: It is important that this NOT be read if versionbits is supported + const UniValue& uvMaxVersion = find_value(oparam, "maxversion"); + if (uvMaxVersion.isNum()) { + nMaxVersionPreVB = uvMaxVersion.get_int64(); + } } } @@ -529,13 +536,10 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); - static UniValue aMutable(UniValue::VARR); - if (aMutable.empty()) - { - aMutable.push_back("time"); - aMutable.push_back("transactions"); - aMutable.push_back("prevblock"); - } + UniValue aMutable(UniValue::VARR); + aMutable.push_back("time"); + aMutable.push_back("transactions"); + aMutable.push_back("prevblock"); UniValue result(UniValue::VOBJ); result.push_back(Pair("capabilities", aCaps)); @@ -574,6 +578,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) if (setClientRules.find(vbinfo.name) == setClientRules.end()) { // Not supported by the client; make sure it's safe to proceed if (!vbinfo.gbt_force) { + // If we do anything other than throw an exception here, be sure version/force isn't sent to old clients throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", vbinfo.name)); } } @@ -586,6 +591,14 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("vbavailable", vbavailable)); result.push_back(Pair("vbrequired", int(0))); + if (nMaxVersionPreVB >= 2) { + // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here + // Because BIP 34 changed how the generation transaction is serialised, we can only use version/force back to v2 blocks + // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated + // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated + aMutable.push_back("version/force"); + } + result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); result.push_back(Pair("coinbaseaux", aux)); -- cgit v1.2.3