X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Frpcmining.cpp;h=d5bc43b2ee9516bcc37b147bb8e2d5c26bd02692;hb=a348ee6f5081803ad1ae860c29075b08d772dd08;hp=57a413b128faa2e74135174cd96973453b2c879a;hpb=0c086a6fcd51476a57156a008d6f485b2d2db7aa;p=novacoin.git diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 57a413b..d5bc43b 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -8,11 +8,37 @@ #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; +extern uint64_t nStakeInputsMapSize; + +Value getsubsidy(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getsubsidy [nTarget]\n" + "Returns proof-of-work subsidy value for the specified value of target."); + + unsigned int nBits = 0; + + if (params.size() != 0) + { + CBigNum bnTarget(uint256(params[0].get_str())); + nBits = bnTarget.GetCompact(); + } + else + { + nBits = GetNextTargetRequired(pindexBest, false); + } + + return (uint64_t)GetProofOfWorkReward(nBits); +} + Value getmininginfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -20,62 +46,109 @@ Value getmininginfo(const Array& params, bool fHelp) "getmininginfo\n" "Returns an object containing mining-related information."); - double dStakeKernelsTriedAvg = 0; - int nPoWInterval = 72, nPoSInterval = 72, nStakesHandled = 0, nStakesTime = 0; - int64 nTargetSpacingWorkMin = 30, nTargetSpacingWork = 30; + 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)); + + 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", GetPoWMHashPS())); + obj.push_back(Pair("netstakeweight", GetPoSKernelPS())); + obj.push_back(Pair("errors", GetWarnings("statusbar"))); + obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); - CBlockIndex* pindex = pindexGenesisBlock; - CBlockIndex* pindexPrevWork = pindexGenesisBlock; - CBlockIndex* pindexPrevStake = NULL; + 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; +} - while (pindex) +Value scaninput(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 4 || params.size() < 2) + throw runtime_error( + "scaninput [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) { - if (pindex->IsProofOfWork()) - { - int64 nActualSpacingWork = pindex->GetBlockTime() - pindexPrevWork->GetBlockTime(); - nTargetSpacingWork = ((nPoWInterval - 1) * nTargetSpacingWork + nActualSpacingWork + nActualSpacingWork) / (nPoWInterval + 1); - nTargetSpacingWork = max(nTargetSpacingWork, nTargetSpacingWorkMin); - pindexPrevWork = pindex; - } + CBigNum bnTarget(nPoWBase); + bnTarget *= 1000; + bnTarget /= (int) (params[2].get_real() * 1000); + nBits = bnTarget.GetCompact(); + } - pindex = pindex->pnext; + 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"); - pindex = pindexBest; + if (hashBlock == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to find transaction in the blockchain"); - while (pindex && nStakesHandled < nPoSInterval) - { - if (pindex->IsProofOfStake()) + 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 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 solution; + if (ScanMidstateForward(ctx, nBits, tx.nTime, tx.vout[nOut].nValue, interval, solution)) { - dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0; - nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0; - pindexPrevStake = pindex; - nStakesHandled++; - } + Object r; + r.push_back(Pair("hash", solution.first.GetHex())); + r.push_back(Pair("time", DateTimeStrFormat(solution.second))); - pindex = pindex->pprev; + return r; + } } + else + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); - double dNetworkMhps = GetDifficulty() * 4294.967296 / nTargetSpacingWork; - double dNetworkWeight = dStakeKernelsTriedAvg / nStakesTime; - - Object obj; - 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())); - obj.push_back(Pair("blockvalue", (uint64_t)GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits))); - obj.push_back(Pair("netmhashps", dNetworkMhps)); - obj.push_back(Pair("netstakeweight", dNetworkWeight)); - obj.push_back(Pair("errors", GetWarnings("statusbar"))); - obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); - obj.push_back(Pair("stakeweight", (uint64_t)pwalletMain->GetStakeWeight(*pwalletMain, STAKE_NORMAL))); - obj.push_back(Pair("minweight", (uint64_t)pwalletMain->GetStakeWeight(*pwalletMain, STAKE_MINWEIGHT))); - obj.push_back(Pair("maxweight", (uint64_t)pwalletMain->GetStakeWeight(*pwalletMain, STAKE_MAXWEIGHT))); - obj.push_back(Pair("stakeinterest", (uint64_t)GetProofOfStakeReward(0, GetLastBlockIndex(pindexBest, true)->nBits, GetLastBlockIndex(pindexBest, true)->nTime, true))); - obj.push_back(Pair("testnet", fTestNet)); - return obj; + return Value::null; } Value getworkex(const Array& params, bool fHelp) @@ -102,7 +175,7 @@ Value getworkex(const Array& params, bool fHelp) // 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)) @@ -200,12 +273,6 @@ Value getworkex(const Array& params, bool fHelp) 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); } } @@ -239,7 +306,7 @@ Value getwork(const Array& params, bool fHelp) // 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)) @@ -319,12 +386,6 @@ Value getwork(const Array& params, bool fHelp) 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); } } @@ -381,7 +442,7 @@ Value getblocktemplate(const Array& params, bool fHelp) // 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)) @@ -506,12 +567,6 @@ Value submitblock(const Array& params, bool fHelp) 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";