Screw that, won't work. Need a clean diff.Oh, ok, this is the latest:
https://github.com/jgarzik/bitcoin/commit/168f5a4b30d5307281eb5bc4447afb04348e9f5d.patchBut you'd need a unified diff of all changes to that file. There's a way to do that using git on the command line but I'm not familiar with it.
Edit: Here you go. This is against the 0.3.24 release version so if you've made other custom changes you'll need to apply the patch more carefully.
--- rpc.cpp 2011-07-21 11:37:38.000000000 -0700
+++ rpc.cpp 2011-07-21 11:39:21.000000000 -0700
@@ -168,6 +168,157 @@
}
+Value BlockToValue(CBlock &block)
+{
+ Object obj;
+ obj.push_back(Pair("hash", block.GetHash().ToString().c_str()));
+ obj.push_back(Pair("version", block.nVersion));
+ obj.push_back(Pair("prev_block", block.hashPrevBlock.ToString().c_str()));
+ obj.push_back(Pair("mrkl_root", block.hashMerkleRoot.ToString().c_str()));
+ obj.push_back(Pair("time", (uint64_t)block.nTime));
+ obj.push_back(Pair("bits", (uint64_t)block.nBits));
+ obj.push_back(Pair("nonce", (uint64_t)block.nNonce));
+ obj.push_back(Pair("n_tx", (int)block.vtx.size()));
+ obj.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK)));
+
+ Array tx;
+ for (int i = 0; i < block.vtx.size(); i++) {
+ Object txobj;
+
+ txobj.push_back(Pair("hash", block.vtx[i].GetHash().ToString().c_str()));
+ txobj.push_back(Pair("version", block.vtx[i].nVersion));
+ txobj.push_back(Pair("lock_time", (uint64_t)block.vtx[i].nLockTime));
+ txobj.push_back(Pair("size",
+ (int)::GetSerializeSize(block.vtx[i], SER_NETWORK)));
+
+ Array tx_vin;
+ for (int j = 0; j < block.vtx[i].vin.size(); j++) {
+ Object vino;
+
+ Object vino_outpt;
+
+ vino_outpt.push_back(Pair("hash",
+ block.vtx[i].vin[j].prevout.hash.ToString().c_str()));
+ vino_outpt.push_back(Pair("n", (uint64_t)block.vtx[i].vin[j].prevout.n));
+
+ vino.push_back(Pair("prev_out", vino_outpt));
+
+ if (block.vtx[i].vin[j].prevout.IsNull())
+ vino.push_back(Pair("coinbase", HexStr(
+ block.vtx[i].vin[j].scriptSig.begin(),
+ block.vtx[i].vin[j].scriptSig.end(), false).c_str()));
+ else
+ vino.push_back(Pair("scriptSig",
+ block.vtx[i].vin[j].scriptSig.ToString().c_str()));
+ if (block.vtx[i].vin[j].nSequence != UINT_MAX)
+ vino.push_back(Pair("sequence", (uint64_t)block.vtx[i].vin[j].nSequence));
+
+ tx_vin.push_back(vino);
+ }
+
+ Array tx_vout;
+ for (int j = 0; j < block.vtx[i].vout.size(); j++) {
+ Object vouto;
+
+ vouto.push_back(Pair("value",
+ (double)block.vtx[i].vout[j].nValue / (double)COIN));
+ vouto.push_back(Pair("scriptPubKey",
+ block.vtx[i].vout[j].scriptPubKey.ToString().c_str()));
+
+ tx_vout.push_back(vouto);
+ }
+
+ txobj.push_back(Pair("in", tx_vin));
+ txobj.push_back(Pair("out", tx_vout));
+
+ tx.push_back(txobj);
+ }
+
+ obj.push_back(Pair("tx", tx));
+
+ Array mrkl;
+ for (int i = 0; i < block.vMerkleTree.size(); i++)
+ mrkl.push_back(block.vMerkleTree[i].ToString().c_str());
+
+ obj.push_back(Pair("mrkl_tree", mrkl));
+
+ return obj;
+}
+
+
+Value getblockbycount(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "getblockbycount height\n"
+ "Dumps the block existing at specified height");
+
+ int64 height = params[0].get_int64();
+ if (height > nBestHeight)
+ throw runtime_error(
+ "getblockbycount height\n"
+ "Dumps the block existing at specified height");
+
+ string blkname = strprintf("blk%d", height);
+
+ CBlock block;
+ CBlockIndex* pindex;
+ bool found = false;
+
+ CRITICAL_BLOCK(cs_main)
+ {
+
+ for (map::iterator mi = mapBlockIndex.begin();
+ mi != mapBlockIndex.end(); ++mi)
+ {
+ pindex = (*mi).second;
+ if ((pindex->nHeight == height) && (pindex->IsInMainChain())) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ throw runtime_error(
+ "getblockbycount height\n"
+ "Dumps the block existing at specified height");
+
+ block.ReadFromDisk(pindex);
+ block.BuildMerkleTree();
+ }
+
+ return BlockToValue(block);
+}
+
+
+Value getblockbyhash(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "getblockbyhash hash\n"
+ "Dumps the block with specified hash");
+
+ uint256 hash;
+ hash.SetHex(params[0].get_str());
+ CBlock block;
+
+ CRITICAL_BLOCK(cs_main)
+ {
+
+ map::iterator mi = mapBlockIndex.find(hash);
+ if (mi == mapBlockIndex.end())
+ throw JSONRPCError(-18, "hash not found");
+
+ CBlockIndex* pindex = (*mi).second;
+
+ block.ReadFromDisk(pindex);
+ block.BuildMerkleTree();
+ }
+
+ return BlockToValue(block);
+}
+
+
Value getblockcount(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
@@ -1434,6 +1585,8 @@
{
make_pair("help", &help),
make_pair("stop", &stop),
+ make_pair("getblockbycount", &getblockbycount),
+ make_pair("getblockbyhash", &getblockbyhash),
make_pair("getblockcount", &getblockcount),
make_pair("getblocknumber", &getblocknumber),
make_pair("getconnectioncount", &getconnectioncount),
@@ -2130,6 +2283,7 @@
if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]);
if (strMethod == "listtransactions" && n > 2) ConvertTo(params[2]);
if (strMethod == "listaccounts" && n > 0) ConvertTo(params[0]);
+ if (strMethod == "getblockbycount" && n > 0) ConvertTo(params[0]);
if (strMethod == "sendmany" && n > 1)
{
string s = params[1].get_str();
I suggest you use the -b flag to patch to make a backup of your rpc.cpp.
Works great!