aboutsummaryrefslogtreecommitdiff
path: root/src/bitcoinrpc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bitcoinrpc.cpp')
-rw-r--r--src/bitcoinrpc.cpp176
1 files changed, 166 insertions, 10 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index 1e7ffe6310..6e2eac5a7e 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -4,7 +4,6 @@
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
-#include "cryptopp/sha.h"
#include "db.h"
#include "net.h"
#include "init.h"
@@ -1258,6 +1257,70 @@ Value listaccounts(const Array& params, bool fHelp)
return ret;
}
+Value listsinceblock(const Array& params, bool fHelp)
+{
+ if (fHelp)
+ throw runtime_error(
+ "listsinceblock [blockid] [target-confirmations]\n"
+ "Get all transactions in blocks since block [blockid], or all transactions if omitted");
+
+ CBlockIndex *pindex = NULL;
+ int target_confirms = 1;
+
+ if (params.size() > 0)
+ {
+ uint256 blockId = 0;
+
+ blockId.SetHex(params[0].get_str());
+ pindex = CBlockLocator(blockId).GetBlockIndex();
+ }
+
+ if (params.size() > 1)
+ {
+ target_confirms = params[1].get_int();
+
+ if (target_confirms < 1)
+ throw JSONRPCError(-8, "Invalid parameter");
+ }
+
+ int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1;
+
+ Array transactions;
+
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++)
+ {
+ CWalletTx tx = (*it).second;
+
+ if (depth == -1 || tx.GetDepthInMainChain() < depth)
+ ListTransactions(tx, "*", 0, true, transactions);
+ }
+
+ uint256 lastblock;
+
+ if (target_confirms == 1)
+ {
+ printf("oops!\n");
+ lastblock = hashBestChain;
+ }
+ else
+ {
+ int target_height = pindexBest->nHeight + 1 - target_confirms;
+
+ CBlockIndex *block;
+ for (block = pindexBest;
+ block && block->nHeight > target_height;
+ block = block->pprev);
+
+ lastblock = block ? block->GetBlockHash() : 0;
+ }
+
+ Object ret;
+ ret.push_back(Pair("transactions", transactions));
+ ret.push_back(Pair("lastblock", lastblock.GetHex()));
+
+ return ret;
+}
+
Value gettransaction(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
@@ -1628,7 +1691,7 @@ Value getwork(const Array& params, bool fHelp)
// Byte reverse
for (int i = 0; i < 128/4; i++)
- ((unsigned int*)pdata)[i] = CryptoPP::ByteReverse(((unsigned int*)pdata)[i]);
+ ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
// Get saved block
if (!mapNewBlock.count(pdata->hashMerkleRoot))
@@ -1645,6 +1708,93 @@ 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));
+
+ union {
+ int32_t nBits;
+ char cBits[4];
+ } uBits;
+ uBits.nBits = htonl((int32_t)pblock->nBits);
+ result.push_back(Pair("bits", HexStr(BEGIN(uBits.cBits), END(uBits.cBits))));
+
+ return result;
+ }
+ else
+ {
+ // Parse parameters
+ CDataStream ssBlock(ParseHex(params[0].get_str()));
+ CBlock pblock;
+ ssBlock >> pblock;
+
+ return ProcessBlock(NULL, &pblock);
+ }
+}
+
+
@@ -1698,6 +1848,8 @@ pair<string, rpcfn_type> pCallTable[] =
make_pair("getwork", &getwork),
make_pair("listaccounts", &listaccounts),
make_pair("settxfee", &settxfee),
+ make_pair("getmemorypool", &getmemorypool),
+ make_pair("listsinceblock", &listsinceblock),
};
map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
@@ -1723,6 +1875,7 @@ string pAllowInSafeMode[] =
"walletlock",
"validateaddress",
"getwork",
+ "getmemorypool",
};
set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
@@ -1744,6 +1897,7 @@ string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeader
<< "Host: 127.0.0.1\r\n"
<< "Content-Type: application/json\r\n"
<< "Content-Length: " << strMsg.size() << "\r\n"
+ << "Connection: close\r\n"
<< "Accept: application/json\r\n";
BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders)
s << item.first << ": " << item.second << "\r\n";
@@ -1784,12 +1938,13 @@ static string HTTPReply(int nStatus, const string& strMsg)
"</HEAD>\r\n"
"<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
"</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
- string strStatus;
- if (nStatus == 200) strStatus = "OK";
- else if (nStatus == 400) strStatus = "Bad Request";
- else if (nStatus == 403) strStatus = "Forbidden";
- else if (nStatus == 404) strStatus = "Not Found";
- else if (nStatus == 500) strStatus = "Internal Server Error";
+ const char *cStatus;
+ if (nStatus == 200) cStatus = "OK";
+ else if (nStatus == 400) cStatus = "Bad Request";
+ else if (nStatus == 403) cStatus = "Forbidden";
+ else if (nStatus == 404) cStatus = "Not Found";
+ else if (nStatus == 500) cStatus = "Internal Server Error";
+ else cStatus = "";
return strprintf(
"HTTP/1.1 %d %s\r\n"
"Date: %s\r\n"
@@ -1800,7 +1955,7 @@ static string HTTPReply(int nStatus, const string& strMsg)
"\r\n"
"%s",
nStatus,
- strStatus.c_str(),
+ cStatus,
rfc1123Time().c_str(),
strMsg.size(),
FormatFullVersion().c_str(),
@@ -2138,7 +2293,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
@@ -2319,6 +2474,7 @@ int CommandLineRPC(int argc, char *argv[])
if (strMethod == "listtransactions" && n > 2) ConvertTo<boost::int64_t>(params[2]);
if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "sendmany" && n > 1)
{
string s = params[1].get_str();