Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) { Object result; result.push_back(Pair("hash", block.GetHash().GetHex())); CMerkleTx txGen(block.vtx[0]); txGen.SetMerkleBranch(&block); result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain())); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); int algo = block.GetAlgo(); result.push_back(Pair("pow_algo_id", algo)); result.push_back(Pair("pow_algo", GetAlgoName(algo))); result.push_back(Pair("pow_hash", block.GetPoWHash(algo).GetHex())); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); Array txs; BOOST_FOREACH(const CTransaction&tx, block.vtx) txs.push_back(tx.GetHash().GetHex()); result.push_back(Pair("tx", txs)); result.push_back(Pair("time", block.GetBlockTime())); result.push_back(Pair("nonce", (uint64_t)block.nNonce)); result.push_back(Pair("bits", HexBits(block.nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex, miningAlgo))); result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); if (blockindex->pprev) result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); CBlockIndex *pnext = chainActive.Next(blockindex); if (pnext) result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); return result; }
Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail) { Object result; result.push_back(Pair("hash", block.GetHash().GetHex())); CMerkleTx txGen(block.vtx[0]); txGen.SetMerkleBranch(&block); result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain())); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); int algo = block.GetAlgo(); result.push_back(Pair("algo_id", algo)); result.push_back(Pair("algo", GetAlgoName(algo))); result.push_back(Pair("mined_hash", block.GetPoWHash(algo).GetHex())); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); result.push_back(Pair("mint", ValueFromAmount(blockindex->nMint))); result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime())); result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce)); result.push_back(Pair("bits", HexBits(block.nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); if (blockindex->pprev) result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); if (blockindex->pnext) result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex())); result.push_back(Pair("flags", strprintf("%s%s", blockindex->IsProofOfStake()? "proof-of-stake" : "proof-of-work", blockindex->GeneratedStakeModifier()? " stake-modifier": ""))); result.push_back(Pair("proofhash", blockindex->IsProofOfStake()? blockindex->hashProofOfStake.GetHex() : blockindex->GetBlockHash().GetHex())); result.push_back(Pair("entropybit", (int)blockindex->GetStakeEntropyBit())); result.push_back(Pair("modifier", strprintf("%016"PRI64x, blockindex->nStakeModifier))); result.push_back(Pair("modifierchecksum", strprintf("%08x", blockindex->nStakeModifierChecksum))); Array txinfo; BOOST_FOREACH (const CTransaction& tx, block.vtx) { if (fPrintTransactionDetail) { Object entry; entry.push_back(Pair("txid", tx.GetHash().GetHex())); TxToJSON(tx, 0, entry); txinfo.push_back(entry); } else txinfo.push_back(tx.GetHash().GetHex()); } result.push_back(Pair("tx", txinfo)); result.push_back(Pair("signature", HexStr(block.vchBlockSig.begin(), block.vchBlockSig.end()))); return result; }
Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { Object result; result.push_back(Pair("hash", block.GetHash().GetHex())); int confirmations = -1; // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; result.push_back(Pair("confirmations", confirmations)); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion.GetFullVersion())); int algo = block.GetAlgo(); result.push_back(Pair("pow_algo_id", algo)); result.push_back(Pair("pow_algo", GetAlgoName(algo))); result.push_back(Pair("pow_hash", block.GetPoWHash(algo).GetHex())); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); Array txs; BOOST_FOREACH(const CTransaction&tx, block.vtx) { if(txDetails) { Object objTx; TxToJSON(tx, uint256(), objTx); txs.push_back(objTx); } else txs.push_back(tx.GetHash().GetHex()); } result.push_back(Pair("tx", txs)); result.push_back(Pair("time", block.GetBlockTime())); result.push_back(Pair("nonce", (uint64_t)block.nNonce)); result.push_back(Pair("bits", strprintf("%08x", block.nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex, miningAlgo))); result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); if (block.auxpow) result.push_back(Pair("auxpow", auxpowToJSON(*block.auxpow))); if (blockindex->pprev) result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); CBlockIndex *pnext = chainActive.Next(blockindex); if (pnext) result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); return result; }
Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) { Object result; result.push_back(Pair("hash", block.GetHash().GetHex())); CMerkleTx txGen(block.vtx[0]); txGen.SetMerkleBranch(&block); result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain())); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); Array txs; BOOST_FOREACH(const CTransaction&tx, block.vtx) txs.push_back(tx.GetHash().GetHex()); result.push_back(Pair("tx", txs)); result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime())); result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce)); result.push_back(Pair("bits", HexBits(block.nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); //result.push_back(Pair("boinchash", block.hashBoinc)); MiningCPID bb = DeserializeBoincBlock(block.hashBoinc); uint256 blockhash = block.GetPoWHash(); std::string sblockhash = blockhash.GetHex(); result.push_back(Pair("BlockType", block.BlockType)); result.push_back(Pair("CPID", bb.cpid)); result.push_back(Pair("ProjectName", bb.projectname)); result.push_back(Pair("BlockDiffBytes", (double)bb.diffbytes)); result.push_back(Pair("RAC", bb.rac)); result.push_back(Pair("NetworkRAC", bb.NetworkRAC)); //if (block.hashBoinc.length() > 10) //{ //result.push_back(Pair("BoincHash",block.hashBoinc.substr(0,100))); //} result.push_back(Pair("PoBDifficulty", bb.pobdifficulty)); result.push_back(Pair("AES512SkeinHash", bb.aesskein)); std::string skein2 = aes_complex_hash(blockhash); result.push_back(Pair("AESCalcHash",skein2)); uint256 boincpowhash = block.hashMerkleRoot + bb.nonce; int iav = TestAESHash(bb.rac, (unsigned int)bb.diffbytes, boincpowhash, bb.aesskein); result.push_back(Pair("AES512Valid",iav)); result.push_back(Pair("ClientVersion",bb.clientversion)); std::string hbd = AdvancedDecrypt(bb.enccpid); bool IsCpidValid = IsCPIDValid(bb.cpid, bb.enccpid); result.push_back(Pair("CPIDValid",IsCpidValid)); result.push_back(Pair("PoWHash",blockhash.GetHex())); //Subsidy 6-29-2014 result.push_back(Pair("Subsidy", ValueFromAmount(GetBlockValueByHash(block.GetHash())))); if (blockindex->pprev) result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); if (blockindex->pnext) result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex())); return result; }
Value getworkaux(const Array& params, bool fHelp) { if (fHelp || params.size() < 1) throw runtime_error( "getworkaux <aux>\n" "getworkaux '' <data>\n" "getworkaux 'submit' <data>\n" "getworkaux '' <data> <chain-index> <branch>*\n" " get work with auxiliary data in coinbase, for multichain mining\n" "<aux> is the merkle root of the auxiliary chain block hashes, concatenated with the aux chain merkle tree size and a nonce\n" "<chain-index> is the aux chain index in the aux chain merkle tree\n" "<branch> is the optional merkle branch of the aux chain\n" "If <data> is not specified, returns formatted hash data to work on:\n" " \"midstate\" : precomputed hash state after hashing the first half of the data\n" " \"data\" : block data\n" " \"hash1\" : formatted hash buffer for second hash\n" " \"target\" : little endian hash target\n" "If <data> is specified and 'submit', tries to solve the block for this (parent) chain and returns true if it was successful." "If <data> is specified and empty first argument, returns the aux merkle root, with size and nonce." "If <data> and <chain-index> are specified, creates an auxiliary proof of work for the chain specified and returns:\n" " \"aux\" : merkle root of auxiliary chain block hashes\n" " \"auxpow\" : aux proof of work to submit to aux chain\n" ); if (vNodes.empty()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Skeincoin is not connected!"); if (IsInitialBlockDownload()) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Skeincoin is downloading blocks..."); static map<uint256, pair<CBlock*, unsigned int> > mapNewBlock; static vector<CBlockTemplate*> vNewBlockTemplate; static CReserveKey reservekey(pwalletMain); if (params.size() == 1) { static vector<unsigned char> vchAuxPrev; vector<unsigned char> vchAux = ParseHex(params[0].get_str()); // Update block static unsigned int nTransactionsUpdatedLast; static CBlockIndex* pindexPrev; static int64 nStart; static CBlockTemplate* pblocktemplate; if (pindexPrev != pindexBest || vchAux != vchAuxPrev || (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)) { if (pindexPrev != pindexBest) { // Deallocate old blocks since they're obsolete now mapNewBlock.clear(); BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate) delete pblocktemplate; vNewBlockTemplate.clear(); } nTransactionsUpdatedLast = nTransactionsUpdated; pindexPrev = pindexBest; vchAuxPrev = vchAux; nStart = GetTime(); // Create new block pblocktemplate = CreateNewBlock(reservekey); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); vNewBlockTemplate.push_back(pblocktemplate); } CBlock* pblock = &pblocktemplate->block; // Update nTime pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); pblock->nNonce = 0; // Update nExtraNonce static unsigned int nExtraNonce = 0; static int64 nPrevTime = 0; IncrementExtraNonceWithAux(pblock, pindexPrev, nExtraNonce, nPrevTime, vchAux); // Save mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, nExtraNonce); // Prebuild hash buffers char pmidstate[32]; char pdata[128]; char phash1[64]; FormatHashBuffers(pblock, pmidstate, pdata, phash1); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); Object result; result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); return result; } else { if (params[0].get_str() != "submit" && params[0].get_str() != "") throw JSONRPCError(RPC_INVALID_PARAMETER, "<aux> must be the empty string or 'submit' if work is being submitted"); // Parse parameters vector<unsigned char> vchData = ParseHex(params[1].get_str()); if (vchData.size() != 128) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter"); CBlock* pdata = (CBlock*)&vchData[0]; // Byte reverse for (int i = 0; i < 128/4; i++) ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]); // Get saved block if (!mapNewBlock.count(pdata->hashMerkleRoot)) return false; CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first; unsigned int nExtraNonce = mapNewBlock[pdata->hashMerkleRoot].second; pblock->nTime = pdata->nTime; pblock->nNonce = pdata->nNonce; // Get the aux merkle root from the coinbase CScript script = pblock->vtx[0].vin[0].scriptSig; opcodetype opcode; CScript::const_iterator pc = script.begin(); script.GetOp(pc, opcode); script.GetOp(pc, opcode); script.GetOp(pc, opcode); if (opcode != OP_2) throw JSONRPCError(RPC_MISC_ERROR, "invalid aux pow script"); vector<unsigned char> vchAux; script.GetOp(pc, opcode, vchAux); RemoveMergedMiningHeader(vchAux); pblock->vtx[0].vin[0].scriptSig = MakeCoinbaseWithAux(pblock->nBits, nExtraNonce, vchAux); pblock->hashMerkleRoot = pblock->BuildMerkleTree(); if (params.size() > 2) { // Requested aux proof of work int nChainIndex = params[2].get_int(); CAuxPow pow(pblock->vtx[0]); for (int i = 3 ; (unsigned int)i < params.size() ; i++) { uint256 nHash; nHash.SetHex(params[i].get_str()); pow.vChainMerkleBranch.push_back(nHash); } pow.SetMerkleBranch(pblock); pow.nChainIndex = nChainIndex; pow.parentBlock = *pblock; CDataStream ss(SER_GETHASH|SER_BLOCKHEADERONLY, PROTOCOL_VERSION); ss << pow; Object result; result.push_back(Pair("auxpow", HexStr(ss.begin(), ss.end()))); return result; } else { if (params[0].get_str() == "submit") { return CheckWork(pblock, *pwalletMain, reservekey); } else { Object result; result.push_back(Pair("aux", HexStr(vchAux.begin(), vchAux.end()))); result.push_back(Pair("hash", pblock->GetPoWHash().GetHex())); return result; } } } }
UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript) { static const int nInnerLoopCount = 0x10000; int nHeightEnd = 0; int nHeight = 0; { // Don't keep cs_main locked LOCK(cs_main); nHeight = chainActive.Height(); nHeightEnd = nHeight+nGenerate; } unsigned int nExtraNonce = 0; UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd && !ShutdownRequested()) { std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(Params()).CreateNewBlock(coinbaseScript->reserveScript)); if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); CBlock *pblock = &pblocktemplate->block; { LOCK(cs_main); IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); } while (nMaxTries > 0 && pblock->nNonce < nInnerLoopCount && !CheckProofOfWork(pblock->GetPoWHash(), pblock->nBits, Params().GetConsensus())) { ++pblock->nNonce; --nMaxTries; } if (nMaxTries == 0) { break; } if (pblock->nNonce == nInnerLoopCount) { continue; } std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock); if (!ProcessNewBlock(Params(), shared_pblock, true, nullptr)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); //mark script as important because it was used at least for one coinbase output if the script came from the wallet if (keepScript) { coinbaseScript->KeepScript(); } } return blockHashes; }