Your personal deterministic Vanga.
{ "getinfo", &getinfo, true, false },
{ "getsubsidy", &getsubsidy, true, false },
{ "getmininginfo", &getmininginfo, true, false },
+ { "scaninput", &scaninput, true, true },
{ "getnewaddress", &getnewaddress, true, false },
{ "getnettotals", &getnettotals, true, true },
{ "getaccountaddress", &getaccountaddress, true, false },
if (strMethod == "getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "scaninput" && n > 1) ConvertTo<int>(params[1]);
+ if (strMethod == "scaninput" && n > 2) ConvertTo<double>(params[2]);
+ if (strMethod == "scaninput" && n > 3) ConvertTo<int>(params[3]);
+
if (strMethod == "sendalert" && n > 2) ConvertTo<boost::int64_t>(params[2]);
if (strMethod == "sendalert" && n > 3) ConvertTo<boost::int64_t>(params[3]);
if (strMethod == "sendalert" && n > 4) ConvertTo<boost::int64_t>(params[4]);
extern json_spirit::Value getsubsidy(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value scaninput(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getworkex(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
return false;
}
+// Scan given input for kernel solutions
+bool ScanInputForStakeKernelHash(CTransaction &tx, uint32_t nOut, uint32_t nBits, uint32_t nSearchInterval, std::pair<uint256, uint32_t> &solution)
+{
+ CBlock block;
+ CTxIndex txindex;
+ uint256 hashProofOfStake;
+
+ int nTime = GetTime();
+
+ CTxDB txdb("r");
+
+ // Load transaction index item
+ if (!txdb.ReadTxIndex(tx.GetHash(), txindex))
+ return false;
+
+ // Read block header
+ if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
+ return false;
+
+ uint64_t nStakeModifier = 0;
+ if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier))
+ return false;
+
+ // Transaction offset inside block
+ uint32_t nTxOffset = txindex.pos.nTxPos - txindex.pos.nBlockPos;
+
+ uint32_t nBlockTime = block.nTime;
+ CBigNum bnTargetPerCoinDay;
+ bnTargetPerCoinDay.SetCompact(nBits);
+ int64_t nValueIn = tx.vout[nOut].nValue;
+
+ // Search backward in time from the given timestamp
+ // Search nSearchInterval seconds back
+ // Stopping search in case of shutting down
+ for (unsigned int n=0; n<nSearchInterval && !fShutdown; n++)
+ {
+ uint32_t nTimeTx = nTime + n;
+ CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)tx.nTime, (int64_t)nTimeTx) / COIN / (24 * 60 * 60);
+ CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
+
+ // Build kernel
+ CDataStream ss(SER_GETHASH, 0);
+ ss << nStakeModifier;
+ ss << nBlockTime << nTxOffset << tx.nTime << nOut << nTimeTx;
+
+ // Calculate kernel hash
+ hashProofOfStake = Hash(ss.begin(), ss.end());
+
+ if (bnTargetProofOfStake >= CBigNum(hashProofOfStake))
+ {
+ solution.first = hashProofOfStake;
+ solution.second = nTimeTx;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
// Check kernel hash target and coinstake signature
bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake)
{
// Scan given coins set for kernel solution
bool ScanForStakeKernelHash(MetaMap &mapMeta, uint32_t nBits, uint32_t nTime, uint32_t nSearchInterval, CoinsSet::value_type &kernelcoin, uint32_t &nTimeTx, uint32_t &nBlockTime, uint64_t &nKernelsTried, uint64_t &nCoinDaysTried);
+bool ScanInputForStakeKernelHash(CTransaction &tx, uint32_t nOut, uint32_t nBits, uint32_t nSearchInterval, std::pair<uint256, uint32_t> &solution);
+
// Check kernel hash target and coinstake signature
// Sets hashProofOfStake on success return
bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake);
#include "txdb.h"
#include "init.h"
#include "miner.h"
+#include "kernel.h"
#include "bitcoinrpc.h"
using namespace json_spirit;
using namespace std;
+extern uint256 nPoWBase;
+
Value getsubsidy(const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
return obj;
}
+Value scaninput(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 4 || params.size() < 2)
+ throw runtime_error(
+ "scaninput <txid> <nout> [difficulty] [days]\n"
+ "Scan specified input for suitable kernel solutions.\n"
+ " [difficulty] - upper limit for difficulty, current difficulty by default;\n"
+ " [days] - time window, 365 days by default.\n"
+ );
+
+
+ uint256 hash;
+ hash.SetHex(params[0].get_str());
+
+ uint32_t nOut = params[1].get_int(), nBits = GetNextTargetRequired(pindexBest, true), nDays = 365;
+
+ if (params.size() > 2)
+ {
+ CBigNum bnTarget(nPoWBase);
+ bnTarget *= 1000;
+ bnTarget /= (int) (params[2].get_real() * 1000);
+ nBits = bnTarget.GetCompact();
+ }
+
+ if (params.size() > 3)
+ {
+ nDays = params[3].get_int();
+ }
+
+ CTransaction tx;
+ uint256 hashBlock = 0;
+ if (GetTransaction(hash, tx, hashBlock))
+ {
+ std::pair<uint256, uint32_t> solution;
+ if (ScanInputForStakeKernelHash(tx, nOut, nBits, nDays * 86400, solution))
+ {
+ Object r;
+ r.push_back(Pair("hash", solution.first.GetHex()));
+ r.push_back(Pair("time", DateTimeStrFormat(solution.second)));
+
+ return r;
+ }
+ }
+ else
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
+
+ return Value::null;
+}
+
Value getworkex(const Array& params, bool fHelp)
{
if (fHelp || params.size() > 2)