Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/mining.cpp
Show First 20 Lines • Show All 320 Lines • ▼ Show 20 Lines | if (state.IsInvalid()) { | ||||
} | } | ||||
return strRejectReason; | return strRejectReason; | ||||
} | } | ||||
// Should be impossible. | // Should be impossible. | ||||
return "valid?"; | return "valid?"; | ||||
} | } | ||||
std::string gbt_vb_name(const Consensus::DeploymentPos pos) { | |||||
const struct BIP9DeploymentInfo &vbinfo = VersionBitsDeploymentInfo[pos]; | |||||
std::string s = vbinfo.name; | |||||
if (!vbinfo.gbt_force) { | |||||
s.insert(s.begin(), '!'); | |||||
} | |||||
return s; | |||||
} | |||||
static UniValue getblocktemplate(const Config &config, | static UniValue getblocktemplate(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() > 1) { | if (request.fHelp || request.params.size() > 1) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"getblocktemplate ( TemplateRequest )\n" | "getblocktemplate ( TemplateRequest )\n" | ||||
"\nIf the request parameters include a 'mode' key, that is used to " | "\nIf the request parameters include a 'mode' key, that is used to " | ||||
"explicitly select between the default 'template' request or a " | "explicitly select between the default 'template' request or a " | ||||
"'proposal'.\n" | "'proposal'.\n" | ||||
Show All 16 Lines | if (request.fHelp || request.params.size() > 1) { | ||||
" \"mode\":\"template\" (string, optional) This must be " | " \"mode\":\"template\" (string, optional) This must be " | ||||
"set to \"template\", \"proposal\" (see BIP 23), or omitted\n" | "set to \"template\", \"proposal\" (see BIP 23), or omitted\n" | ||||
" \"capabilities\":[ (array, optional) A list of " | " \"capabilities\":[ (array, optional) A list of " | ||||
"strings\n" | "strings\n" | ||||
" \"support\" (string) client side supported " | " \"support\" (string) client side supported " | ||||
"feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', " | "feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', " | ||||
"'serverlist', 'workid'\n" | "'serverlist', 'workid'\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ],\n" | |||||
" \"rules\":[ (array, optional) A list of " | |||||
"strings\n" | |||||
" \"support\" (string) client side supported " | |||||
"softfork deployment\n" | |||||
" ,...\n" | |||||
" ]\n" | " ]\n" | ||||
" }\n" | " }\n" | ||||
"\n" | "\n" | ||||
"\nResult:\n" | "\nResult:\n" | ||||
"{\n" | "{\n" | ||||
" \"version\" : n, (numeric) The preferred " | " \"version\" : n, (numeric) The preferred " | ||||
"block version\n" | "block version\n" | ||||
" \"rules\" : [ \"rulename\", ... ], (array of strings) " | |||||
"specific block rules that are to be enforced\n" | |||||
" \"vbavailable\" : { (json object) set of " | |||||
"pending, supported versionbit (BIP 9) softfork deployments\n" | |||||
" \"rulename\" : bitnumber (numeric) identifies the " | |||||
"bit number as indicating acceptance and readiness for the named " | |||||
"softfork rule\n" | |||||
" ,...\n" | |||||
" },\n" | |||||
" \"vbrequired\" : n, (numeric) bit mask of " | |||||
"versionbits the server requires set in submissions\n" | |||||
" \"previousblockhash\" : \"xxxx\", (string) The hash of " | " \"previousblockhash\" : \"xxxx\", (string) The hash of " | ||||
"current highest block\n" | "current highest block\n" | ||||
" \"transactions\" : [ (array) contents of " | " \"transactions\" : [ (array) contents of " | ||||
"non-coinbase transactions that should be included in the next " | "non-coinbase transactions that should be included in the next " | ||||
"block\n" | "block\n" | ||||
" {\n" | " {\n" | ||||
" \"data\" : \"xxxx\", (string) transaction " | " \"data\" : \"xxxx\", (string) transaction " | ||||
"data encoded in hexadecimal (byte-for-byte)\n" | "data encoded in hexadecimal (byte-for-byte)\n" | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() > 1) { | ||||
HelpExampleRpc("getblocktemplate", "")); | HelpExampleRpc("getblocktemplate", "")); | ||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
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 (request.params.size() > 0) { | if (request.params.size() > 0) { | ||||
const UniValue &oparam = request.params[0].get_obj(); | const UniValue &oparam = request.params[0].get_obj(); | ||||
const UniValue &modeval = find_value(oparam, "mode"); | const UniValue &modeval = find_value(oparam, "mode"); | ||||
if (modeval.isStr()) { | if (modeval.isStr()) { | ||||
strMode = modeval.get_str(); | strMode = modeval.get_str(); | ||||
} else if (modeval.isNull()) { | } else if (modeval.isNull()) { | ||||
/* Do nothing */ | /* Do nothing */ | ||||
} else { | } else { | ||||
Show All 34 Lines | if (request.params.size() > 0) { | ||||
} | } | ||||
CValidationState state; | CValidationState state; | ||||
BlockValidationOptions validationOptions = | BlockValidationOptions validationOptions = | ||||
BlockValidationOptions(false, true); | BlockValidationOptions(false, true); | ||||
TestBlockValidity(config, state, block, pindexPrev, | TestBlockValidity(config, state, block, pindexPrev, | ||||
validationOptions); | validationOptions); | ||||
return BIP22ValidationResult(config, state); | return BIP22ValidationResult(config, state); | ||||
} | } | ||||
const UniValue &aClientRules = find_value(oparam, "rules"); | |||||
if (aClientRules.isArray()) { | |||||
for (size_t i = 0; i < aClientRules.size(); ++i) { | |||||
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(); | |||||
} | |||||
} | |||||
} | } | ||||
if (strMode != "template") { | if (strMode != "template") { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); | throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); | ||||
} | } | ||||
if (!g_connman) { | if (!g_connman) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | if (pindexPrev != chainActive.Tip() || | ||||
} | } | ||||
// Need to update only after we know CreateNewBlock succeeded | // Need to update only after we know CreateNewBlock succeeded | ||||
pindexPrev = pindexPrevNew; | pindexPrev = pindexPrevNew; | ||||
} | } | ||||
// pointer for convenience | // pointer for convenience | ||||
CBlock *pblock = &pblocktemplate->block; | CBlock *pblock = &pblocktemplate->block; | ||||
const Consensus::Params &consensusParams = | |||||
config.GetChainParams().GetConsensus(); | |||||
// Update nTime | // Update nTime | ||||
UpdateTime(pblock, config, pindexPrev); | UpdateTime(pblock, config, pindexPrev); | ||||
pblock->nNonce = 0; | pblock->nNonce = 0; | ||||
UniValue aCaps(UniValue::VARR); | UniValue aCaps(UniValue::VARR); | ||||
aCaps.push_back("proposal"); | aCaps.push_back("proposal"); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | static UniValue getblocktemplate(const Config &config, | ||||
UniValue aMutable(UniValue::VARR); | UniValue aMutable(UniValue::VARR); | ||||
aMutable.push_back("time"); | aMutable.push_back("time"); | ||||
aMutable.push_back("transactions"); | aMutable.push_back("transactions"); | ||||
aMutable.push_back("prevblock"); | aMutable.push_back("prevblock"); | ||||
UniValue result(UniValue::VOBJ); | UniValue result(UniValue::VOBJ); | ||||
result.push_back(Pair("capabilities", aCaps)); | result.push_back(Pair("capabilities", aCaps)); | ||||
UniValue aRules(UniValue::VARR); | |||||
UniValue vbavailable(UniValue::VOBJ); | |||||
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { | |||||
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j); | |||||
ThresholdState state = VersionBitsState(pindexPrev, consensusParams, | |||||
pos, versionbitscache); | |||||
switch (state) { | |||||
case THRESHOLD_DEFINED: | |||||
case THRESHOLD_FAILED: | |||||
// Not exposed to GBT at all | |||||
break; | |||||
case THRESHOLD_LOCKED_IN: { | |||||
// Ensure bit is set in block version, then fallthrough to get | |||||
// vbavailable set. | |||||
pblock->nVersion |= VersionBitsMask(consensusParams, pos); | |||||
} | |||||
// FALLTHROUGH | |||||
case THRESHOLD_STARTED: { | |||||
const struct BIP9DeploymentInfo &vbinfo = | |||||
VersionBitsDeploymentInfo[pos]; | |||||
vbavailable.push_back(Pair( | |||||
gbt_vb_name(pos), consensusParams.vDeployments[pos].bit)); | |||||
if (setClientRules.find(vbinfo.name) == setClientRules.end()) { | |||||
if (!vbinfo.gbt_force) { | |||||
// If the client doesn't support this, don't indicate it | |||||
// in the [default] version | |||||
pblock->nVersion &= | |||||
~VersionBitsMask(consensusParams, pos); | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
case THRESHOLD_ACTIVE: { | |||||
// Add to rules only | |||||
const struct BIP9DeploymentInfo &vbinfo = | |||||
VersionBitsDeploymentInfo[pos]; | |||||
aRules.push_back(gbt_vb_name(pos)); | |||||
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)); | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
result.push_back(Pair("version", pblock->nVersion)); | result.push_back(Pair("version", pblock->nVersion)); | ||||
result.push_back(Pair("rules", aRules)); | |||||
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 | |||||
// serialized, 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)); | ||||
result.push_back(Pair("coinbasevalue", | result.push_back(Pair("coinbasevalue", | ||||
int64_t(pblock->vtx[0]->vout[0].nValue / SATOSHI))); | int64_t(pblock->vtx[0]->vout[0].nValue / SATOSHI))); | ||||
result.push_back(Pair("longpollid", | result.push_back(Pair("longpollid", | ||||
chainActive.Tip()->GetBlockHash().GetHex() + | chainActive.Tip()->GetBlockHash().GetHex() + | ||||
i64tostr(nTransactionsUpdatedLast))); | i64tostr(nTransactionsUpdatedLast))); | ||||
result.push_back(Pair("target", hashTarget.GetHex())); | result.push_back(Pair("target", hashTarget.GetHex())); | ||||
result.push_back( | result.push_back( | ||||
Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast() + 1)); | Pair("mintime", int64_t(pindexPrev->GetMedianTimePast()) + 1)); | ||||
result.push_back(Pair("mutable", aMutable)); | result.push_back(Pair("mutable", aMutable)); | ||||
result.push_back(Pair("noncerange", "00000000ffffffff")); | result.push_back(Pair("noncerange", "00000000ffffffff")); | ||||
// FIXME: Allow for mining block greater than 1M. | // FIXME: Allow for mining block greater than 1M. | ||||
result.push_back( | result.push_back( | ||||
Pair("sigoplimit", GetMaxBlockSigOpsCount(DEFAULT_MAX_BLOCK_SIZE))); | Pair("sigoplimit", GetMaxBlockSigOpsCount(DEFAULT_MAX_BLOCK_SIZE))); | ||||
result.push_back(Pair("sizelimit", DEFAULT_MAX_BLOCK_SIZE)); | result.push_back(Pair("sizelimit", DEFAULT_MAX_BLOCK_SIZE)); | ||||
result.push_back(Pair("curtime", pblock->GetBlockTime())); | result.push_back(Pair("curtime", pblock->GetBlockTime())); | ||||
result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); | result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); | ||||
result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight + 1))); | result.push_back(Pair("height", int64_t(pindexPrev->nHeight) + 1)); | ||||
return result; | return result; | ||||
} | } | ||||
class submitblock_StateCatcher : public CValidationInterface { | class submitblock_StateCatcher : public CValidationInterface { | ||||
public: | public: | ||||
uint256 hash; | uint256 hash; | ||||
bool found; | bool found; | ||||
▲ Show 20 Lines • Show All 149 Lines • Show Last 20 Lines |