X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Frpcmining.cpp;h=d5bc43b2ee9516bcc37b147bb8e2d5c26bd02692;hb=a348ee6f5081803ad1ae860c29075b08d772dd08;hp=3b22686f04cb5a66555733af6021063c6d849e6c;hpb=13bf5cb62f87ee7135ae1fcfc95b7da180681859;p=novacoin.git diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 3b22686..d5bc43b 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -5,12 +5,40 @@ #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; +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) @@ -18,17 +46,111 @@ Value getmininginfo(const Array& params, bool fHelp) "getmininginfo\n" "Returns an object containing mining-related information."); - Object obj; + 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", 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("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 [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 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)) + { + 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) @@ -53,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)) @@ -151,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); } } @@ -190,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)) @@ -270,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); } } @@ -332,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)) @@ -457,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";