GBT: Support coinbasetxn instead of coinbasevalue

Once a Zcash GBT spec has been written, we can re-enable coinbasevalue.
This commit is contained in:
Jack Grigg
2016-09-22 22:41:45 +12:00
parent 7ccbcca62c
commit 53ddbaed16

View File

@@ -389,10 +389,10 @@ Value getblocktemplate(const Array& params, bool fHelp)
" }\n" " }\n"
" ,...\n" " ,...\n"
" ],\n" " ],\n"
" \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" // " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n"
" \"flags\" : \"flags\" (string) \n" // " \"flags\" : \"flags\" (string) \n"
" },\n" // " },\n"
" \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n" // " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
" \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n"
" \"target\" : \"xxxx\", (string) The hash target\n" " \"target\" : \"xxxx\", (string) The hash target\n"
" \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n"
@@ -415,8 +415,15 @@ Value getblocktemplate(const Array& params, bool fHelp)
LOCK(cs_main); LOCK(cs_main);
// Wallet is required because we support coinbasetxn
if (pwalletMain == NULL) {
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
}
std::string strMode = "template"; std::string strMode = "template";
Value lpval = Value::null; Value lpval = Value::null;
// TODO: Re-enable coinbasevalue once a specification has been written
bool coinbasetxn = true;
if (params.size() > 0) if (params.size() > 0)
{ {
const Object& oparam = params[0].get_obj(); const Object& oparam = params[0].get_obj();
@@ -529,7 +536,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
// Clear pindexPrev so future calls make a new block, despite any failures from here on // Clear pindexPrev so future calls make a new block, despite any failures from here on
pindexPrev = NULL; pindexPrev = NULL;
// Store the pindexBest used before CreateNewBlock, to avoid races // Store the pindexBest used before CreateNewBlockWithKey, to avoid races
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrevNew = chainActive.Tip(); CBlockIndex* pindexPrevNew = chainActive.Tip();
nStart = GetTime(); nStart = GetTime();
@@ -540,12 +547,12 @@ Value getblocktemplate(const Array& params, bool fHelp)
delete pblocktemplate; delete pblocktemplate;
pblocktemplate = NULL; pblocktemplate = NULL;
} }
CScript scriptDummy = CScript() << OP_TRUE; CReserveKey reservekey(pwalletMain);
pblocktemplate = CreateNewBlock(scriptDummy); pblocktemplate = CreateNewBlockWithKey(reservekey);
if (!pblocktemplate) if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
// Need to update only after we know CreateNewBlock succeeded // Need to update only after we know CreateNewBlockWithKey succeeded
pindexPrev = pindexPrevNew; pindexPrev = pindexPrevNew;
} }
CBlock* pblock = &pblocktemplate->block; // pointer for convenience CBlock* pblock = &pblocktemplate->block; // pointer for convenience
@@ -556,6 +563,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
static const Array aCaps = boost::assign::list_of("proposal"); static const Array aCaps = boost::assign::list_of("proposal");
Value txCoinbase = Value::null;
Array transactions; Array transactions;
map<uint256, int64_t> setTxIndex; map<uint256, int64_t> setTxIndex;
int i = 0; int i = 0;
@@ -564,7 +572,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
uint256 txHash = tx.GetHash(); uint256 txHash = tx.GetHash();
setTxIndex[txHash] = i++; setTxIndex[txHash] = i++;
if (tx.IsCoinBase()) if (tx.IsCoinBase() && !coinbasetxn)
continue; continue;
Object entry; Object entry;
@@ -585,7 +593,12 @@ Value getblocktemplate(const Array& params, bool fHelp)
entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template])); entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
transactions.push_back(entry); if (tx.IsCoinBase()) {
entry.push_back(Pair("required", true));
txCoinbase = entry;
} else {
transactions.push_back(entry);
}
} }
Object aux; Object aux;
@@ -606,8 +619,13 @@ Value getblocktemplate(const Array& params, bool fHelp)
result.push_back(Pair("version", pblock->nVersion)); result.push_back(Pair("version", pblock->nVersion));
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)); if (coinbasetxn) {
result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); assert(txCoinbase.type() == obj_type);
result.push_back(Pair("coinbasetxn", txCoinbase));
} else {
result.push_back(Pair("coinbaseaux", aux));
result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
}
result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast))); result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)));
result.push_back(Pair("target", hashTarget.GetHex())); result.push_back(Pair("target", hashTarget.GetHex()));
result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));