#include "main.h"
#include "db.h"
+#include "txdb.h"
#include "init.h"
+#include "miner.h"
+#include "kernel.h"
#include "bitcoinrpc.h"
using namespace json_spirit;
using namespace std;
-Value getmininginfo(const Array& params, bool fHelp)
+extern uint256 nPoWBase;
+extern uint64_t nStakeInputsMapSize;
+
+Value getsubsidy(const Array& params, bool fHelp)
{
- if (fHelp || params.size() != 0)
+ if (fHelp || params.size() > 1)
throw runtime_error(
- "getmininginfo\n"
- "Returns an object containing mining-related information.");
-
- int64 nTargetSpacingWorkMin = 30;
- int64 nTargetSpacingWork = nTargetSpacingWorkMin;
- int64 nPoWInterval = 72;
- int64 nTargetSpacingStake = 600;
+ "getsubsidy [nTarget]\n"
+ "Returns proof-of-work subsidy value for the specified value of target.");
- CBlockIndex* pindex = pindexGenesisBlock;
- CBlockIndex* pindexPrevWork = pindexGenesisBlock;
+ unsigned int nBits = 0;
- while (pindex)
+ if (params.size() != 0)
{
- if (pindex->IsProofOfWork())
- {
- int64 nActualSpacingWork = pindex->GetBlockTime() - pindexPrevWork->GetBlockTime();
- nTargetSpacingWork = ((nPoWInterval - 1) * nTargetSpacingWork + nActualSpacingWork + nActualSpacingWork) / (nPoWInterval + 1);
- nTargetSpacingWork = max(nTargetSpacingWork, nTargetSpacingWorkMin);
- pindexPrevWork = pindex;
- }
-
- pindex = pindex->pnext;
+ CBigNum bnTarget(uint256(params[0].get_str()));
+ nBits = bnTarget.GetCompact();
+ }
+ else
+ {
+ nBits = GetNextTargetRequired(pindexBest, false);
}
- double dNetworkMhps = GetDifficulty() * 4294.967296 / nTargetSpacingWork;
- int nNetworkWeight = GetDifficulty(GetLastBlockIndex(pindexBest, true)) * 4294967296 / nTargetSpacingStake;
+ return (uint64_t)GetProofOfWorkReward(nBits);
+}
- Object obj;
+Value getmininginfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getmininginfo\n"
+ "Returns an object containing mining-related information.");
+
+ Object obj, diff, weight;
obj.push_back(Pair("blocks", (int)nBestHeight));
obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize));
obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx));
- obj.push_back(Pair("difficulty", (double)GetDifficulty()));
+
+ diff.push_back(Pair("proof-of-work", GetDifficulty()));
+ diff.push_back(Pair("proof-of-stake", GetDifficulty(GetLastBlockIndex(pindexBest, true))));
+ diff.push_back(Pair("search-interval", (int)nLastCoinStakeSearchInterval));
+ obj.push_back(Pair("difficulty", diff));
+
obj.push_back(Pair("blockvalue", (uint64_t)GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits)));
- obj.push_back(Pair("netmhashps", dNetworkMhps));
- obj.push_back(Pair("netstakeweight", (uint64_t) nNetworkWeight));
+ obj.push_back(Pair("netmhashps", GetPoWMHashPS()));
+ obj.push_back(Pair("netstakeweight", GetPoSKernelPS()));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
- obj.push_back(Pair("stakeweight", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain, STAKE_NORMAL)));
- obj.push_back(Pair("minweight", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain, STAKE_MINWEIGHT)));
- obj.push_back(Pair("maxweight", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain, STAKE_MAXWEIGHT)));
- obj.push_back(Pair("passiveweight", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain, STAKE_BELOWMIN)));
- obj.push_back(Pair("stakeinterest", (uint64_t)GetProofOfStakeReward(0, GetLastBlockIndex(pindexBest, true)->nBits, GetLastBlockIndex(pindexBest, true)->nTime, true)));
+
+ obj.push_back(Pair("stakeinputs", (uint64_t)nStakeInputsMapSize));
+ obj.push_back(Pair("stakeinterest", (int64_t)GetProofOfStakeReward(0, GetLastBlockIndex(pindexBest, true)->nBits, GetLastBlockIndex(pindexBest, true)->nTime, true)));
+
obj.push_back(Pair("testnet", fTestNet));
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))
+ {
+ if (nOut > tx.vout.size())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Incorrect output number");
+
+ if (hashBlock == 0)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to find transaction in the blockchain");
+
+ CTxDB txdb("r");
+
+ CBlock block;
+ CTxIndex txindex;
+
+ // Load transaction index item
+ if (!txdb.ReadTxIndex(tx.GetHash(), txindex))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to read block index item");
+
+ // Read block header
+ if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "CBlock::ReadFromDisk() failed");
+
+ uint64_t nStakeModifier = 0;
+ if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No kernel stake modifier generated yet");
+
+ std::pair<uint32_t, uint32_t> interval;
+ interval.first = GetTime();
+ // Only count coins meeting min age requirement
+ if (nStakeMinAge + block.nTime > interval.first)
+ interval.first += (nStakeMinAge + block.nTime - interval.first);
+ interval.second = interval.first + nDays * 86400;
+
+ SHA256_CTX ctx;
+ GetKernelMidstate(nStakeModifier, block.nTime, txindex.pos.nTxPos - txindex.pos.nBlockPos, tx.nTime, nOut, ctx);
+
+ std::pair<uint256, uint32_t> solution;
+ if (ScanMidstateForward(ctx, nBits, tx.nTime, tx.vout[nOut].nValue, interval, 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)
// Update block
static unsigned int nTransactionsUpdatedLast;
static CBlockIndex* pindexPrev;
- static int64 nStart;
+ static int64_t nStart;
static CBlock* pblock;
if (pindexPrev != pindexBest ||
(nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
- if (!fTestNet && pblock->GetBlockTime() < CHAINCHECKS_SWITCH_TIME)
- {
- if (!pblock->SignBlock(*pwalletMain))
- throw JSONRPCError(-100, "Unable to sign block, wallet locked?");
- }
-
return CheckWork(pblock, *pwalletMain, reservekey);
}
}
// Update block
static unsigned int nTransactionsUpdatedLast;
static CBlockIndex* pindexPrev;
- static int64 nStart;
+ static int64_t nStart;
static CBlock* pblock;
if (pindexPrev != pindexBest ||
(nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
- if (!fTestNet && pblock->GetBlockTime() < CHAINCHECKS_SWITCH_TIME)
- {
- if (!pblock->SignBlock(*pwalletMain))
- throw JSONRPCError(-100, "Unable to sign block, wallet locked?");
- }
-
return CheckWork(pblock, *pwalletMain, reservekey);
}
}
// Update block
static unsigned int nTransactionsUpdatedLast;
static CBlockIndex* pindexPrev;
- static int64 nStart;
+ static int64_t nStart;
static CBlock* pblock;
if (pindexPrev != pindexBest ||
(nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5))
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
}
- if (!fTestNet && block.GetBlockTime() < CHAINCHECKS_SWITCH_TIME)
- {
- if (!block.SignBlock(*pwalletMain))
- throw JSONRPCError(-100, "Unable to sign block, wallet locked?");
- }
-
bool fAccepted = ProcessBlock(NULL, &block);
if (!fAccepted)
return "rejected";