getblocktemplate: Use version/force mutation to support pre-BIP9 clients

This commit is contained in:
Luke Dashjr 2016-06-01 16:51:54 +00:00
parent 98790608a4
commit 12c708a4b3

View File

@ -345,6 +345,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
std::string strMode = "template"; std::string strMode = "template";
UniValue lpval = NullUniValue; UniValue lpval = NullUniValue;
std::set<std::string> setClientRules; std::set<std::string> setClientRules;
int64_t nMaxVersionPreVB = -1;
if (params.size() > 0) if (params.size() > 0)
{ {
const UniValue& oparam = params[0].get_obj(); const UniValue& oparam = params[0].get_obj();
@ -395,6 +396,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
const UniValue& v = aClientRules[i]; const UniValue& v = aClientRules[i];
setClientRules.insert(v.get_str()); 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); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
static UniValue aMutable(UniValue::VARR); UniValue aMutable(UniValue::VARR);
if (aMutable.empty()) aMutable.push_back("time");
{ aMutable.push_back("transactions");
aMutable.push_back("time"); aMutable.push_back("prevblock");
aMutable.push_back("transactions");
aMutable.push_back("prevblock");
}
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
result.push_back(Pair("capabilities", aCaps)); result.push_back(Pair("capabilities", aCaps));
@ -574,6 +578,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
if (setClientRules.find(vbinfo.name) == setClientRules.end()) { if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
// Not supported by the client; make sure it's safe to proceed // Not supported by the client; make sure it's safe to proceed
if (!vbinfo.gbt_force) { 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)); 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("vbavailable", vbavailable));
result.push_back(Pair("vbrequired", int(0))); 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("previousblockhash", pblock->hashPrevBlock.GetHex()));
result.push_back(Pair("transactions", transactions)); result.push_back(Pair("transactions", transactions));
result.push_back(Pair("coinbaseaux", aux)); result.push_back(Pair("coinbaseaux", aux));