aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorForrest Voight <forrest@forre.st>2011-09-06 18:15:46 -0400
committerForrest Voight <forrest@forre.st>2011-10-01 14:42:54 -0400
commit074d584a04ee80123001728ad63d4fd7e9adb828 (patch)
tree65dd48771c3b9c89346475897c06d701550ceffc
parentf4769e44a326f61bdf47fa39346e1293b97e31c4 (diff)
downloadbitcoin-074d584a04ee80123001728ad63d4fd7e9adb828.tar.xz
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.
-rw-r--r--src/bitcoinrpc.cpp84
-rw-r--r--src/main.cpp2
-rw-r--r--src/main.h1
3 files changed, 85 insertions, 2 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index 1e7ffe6310..cd546abde8 100644
--- a/src/bitcoinrpc.cpp
+++ b/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("listaccounts", &listaccounts),
make_pair("settxfee", &settxfee),
+ make_pair("getmemorypool", &getmemorypool),
};
map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
@@ -1723,6 +1804,7 @@ string pAllowInSafeMode[] =
"walletlock",
"validateaddress",
"getwork",
+ "getmemorypool",
};
set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
@@ -2138,7 +2220,7 @@ void ThreadRPCServer2(void* parg)
if (valMethod.type() != str_type)
throw JSONRPCError(-32600, "Method must be a string");
string strMethod = valMethod.get_str();
- if (strMethod != "getwork")
+ if (strMethod != "getwork" && strMethod != "getmemorypool")
printf("ThreadRPCServer method=%s\n", strMethod.c_str());
// Parse params
diff --git a/src/main.cpp b/src/main.cpp
index 472c80a33a..750290ccc5 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1338,7 +1338,7 @@ bool CBlock::AcceptBlock()
return true;
}
-bool static ProcessBlock(CNode* pfrom, CBlock* pblock)
+bool ProcessBlock(CNode* pfrom, CBlock* pblock)
{
// Check for duplicate
uint256 hash = pblock->GetHash();
diff --git a/src/main.h b/src/main.h
index 1106bb9785..329035dc5a 100644
--- a/src/main.h
+++ b/src/main.h
@@ -85,6 +85,7 @@ class CTxIndex;
void RegisterWallet(CWallet* pwalletIn);
void UnregisterWallet(CWallet* pwalletIn);
+bool ProcessBlock(CNode* pfrom, CBlock* pblock);
bool CheckDiskSpace(uint64 nAdditionalBytes=0);
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
FILE* AppendBlockFile(unsigned int& nFileRet);