Browse Source

Added RPC call 'getmemorypool' that provides everything needed to construct a block with a custom generation transaction and submit a solution

getmemorypool [data]
If [data] is not specified, returns data needed to construct a block to work on:
  "version" : block version
  "previousblockhash" : hash of current highest block
  "transactions" : contents of non-coinbase transactions that should be included in the next block
  "coinbasevalue" : maximum allowable input to coinbase transaction, including the generation award and transaction fees
  "time" : timestamp appropriate for next block
  "bits" : compressed target of next block
If [data] is specified, tries to solve the block and returns true if it was successful.
miguelfreitas
Forrest Voight 13 years ago
parent
commit
074d584a04
  1. 84
      src/bitcoinrpc.cpp
  2. 2
      src/main.cpp
  3. 1
      src/main.h

84
src/bitcoinrpc.cpp

@ -1645,6 +1645,86 @@ Value getwork(const Array& params, bool fHelp)
} }
Value getmemorypool(const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
"getmemorypool [data]\n"
"If [data] is not specified, returns data needed to construct a block to work on:\n"
" \"version\" : block version\n"
" \"previousblockhash\" : hash of current highest block\n"
" \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n"
" \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n"
" \"time\" : timestamp appropriate for next block\n"
" \"bits\" : compressed target of next block\n"
"If [data] is specified, tries to solve the block and returns true if it was successful.");
if (params.size() == 0)
{
if (vNodes.empty())
throw JSONRPCError(-9, "Bitcoin is not connected!");
if (IsInitialBlockDownload())
throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
static CReserveKey reservekey(pwalletMain);
// Update block
static unsigned int nTransactionsUpdatedLast;
static CBlockIndex* pindexPrev;
static int64 nStart;
static CBlock* pblock;
if (pindexPrev != pindexBest ||
(nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5))
{
nTransactionsUpdatedLast = nTransactionsUpdated;
pindexPrev = pindexBest;
nStart = GetTime();
// Create new block
if(pblock)
delete pblock;
pblock = CreateNewBlock(reservekey);
if (!pblock)
throw JSONRPCError(-7, "Out of memory");
}
// Update nTime
pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
pblock->nNonce = 0;
Array transactions;
BOOST_FOREACH(CTransaction tx, pblock->vtx) {
if(tx.IsCoinBase())
continue;
CDataStream ssTx;
ssTx << tx;
transactions.push_back(HexStr(ssTx.begin(), ssTx.end()));
}
Object result;
result.push_back(Pair("version", pblock->nVersion));
result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
result.push_back(Pair("transactions", transactions));
result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
result.push_back(Pair("time", (int64_t)pblock->nTime));
result.push_back(Pair("bits", (int64_t)pblock->nBits));
return result;
}
else
{
// Parse parameters
CDataStream ssBlock(ParseHex(params[0].get_str()));
CBlock pblock;
ssBlock >> pblock;
return ProcessBlock(NULL, &pblock);
}
}
@ -1698,6 +1778,7 @@ pair<string, rpcfn_type> pCallTable[] =
make_pair("getwork", &getwork), make_pair("getwork", &getwork),
make_pair("listaccounts", &listaccounts), make_pair("listaccounts", &listaccounts),
make_pair("settxfee", &settxfee), make_pair("settxfee", &settxfee),
make_pair("getmemorypool", &getmemorypool),
}; };
map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
@ -1723,6 +1804,7 @@ string pAllowInSafeMode[] =
"walletlock", "walletlock",
"validateaddress", "validateaddress",
"getwork", "getwork",
"getmemorypool",
}; };
set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0])); set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
@ -2138,7 +2220,7 @@ void ThreadRPCServer2(void* parg)
if (valMethod.type() != str_type) if (valMethod.type() != str_type)
throw JSONRPCError(-32600, "Method must be a string"); throw JSONRPCError(-32600, "Method must be a string");
string strMethod = valMethod.get_str(); string strMethod = valMethod.get_str();
if (strMethod != "getwork") if (strMethod != "getwork" && strMethod != "getmemorypool")
printf("ThreadRPCServer method=%s\n", strMethod.c_str()); printf("ThreadRPCServer method=%s\n", strMethod.c_str());
// Parse params // Parse params

2
src/main.cpp

@ -1338,7 +1338,7 @@ bool CBlock::AcceptBlock()
return true; return true;
} }
bool static ProcessBlock(CNode* pfrom, CBlock* pblock) bool ProcessBlock(CNode* pfrom, CBlock* pblock)
{ {
// Check for duplicate // Check for duplicate
uint256 hash = pblock->GetHash(); uint256 hash = pblock->GetHash();

1
src/main.h

@ -85,6 +85,7 @@ class CTxIndex;
void RegisterWallet(CWallet* pwalletIn); void RegisterWallet(CWallet* pwalletIn);
void UnregisterWallet(CWallet* pwalletIn); void UnregisterWallet(CWallet* pwalletIn);
bool ProcessBlock(CNode* pfrom, CBlock* pblock);
bool CheckDiskSpace(uint64 nAdditionalBytes=0); bool CheckDiskSpace(uint64 nAdditionalBytes=0);
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
FILE* AppendBlockFile(unsigned int& nFileRet); FILE* AppendBlockFile(unsigned int& nFileRet);

Loading…
Cancel
Save