Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/mining.cpp
Show First 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | return RPCHelpMan{ | ||||
return GetNetworkHashPS( | return GetNetworkHashPS( | ||||
!request.params[0].isNull() ? request.params[0].get_int() : 120, | !request.params[0].isNull() ? request.params[0].get_int() : 120, | ||||
!request.params[1].isNull() ? request.params[1].get_int() : -1, | !request.params[1].isNull() ? request.params[1].get_int() : -1, | ||||
chainman.ActiveChain()); | chainman.ActiveChain()); | ||||
}, | }, | ||||
}; | }; | ||||
} | } | ||||
static bool GenerateBlock(const Config &config, ChainstateManager &chainman, | static bool GenerateBlock(ChainstateManager &chainman, CBlock &block, | ||||
CBlock &block, uint64_t &max_tries, | uint64_t &max_tries, BlockHash &block_hash) { | ||||
BlockHash &block_hash) { | |||||
block_hash.SetNull(); | block_hash.SetNull(); | ||||
block.hashMerkleRoot = BlockMerkleRoot(block); | block.hashMerkleRoot = BlockMerkleRoot(block); | ||||
const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); | const Consensus::Params ¶ms = chainman.GetConsensus(); | ||||
while (max_tries > 0 && | while (max_tries > 0 && | ||||
block.nNonce < std::numeric_limits<uint32_t>::max() && | block.nNonce < std::numeric_limits<uint32_t>::max() && | ||||
!CheckProofOfWork(block.GetHash(), block.nBits, params) && | !CheckProofOfWork(block.GetHash(), block.nBits, params) && | ||||
!ShutdownRequested()) { | !ShutdownRequested()) { | ||||
++block.nNonce; | ++block.nNonce; | ||||
--max_tries; | --max_tries; | ||||
} | } | ||||
if (max_tries == 0 || ShutdownRequested()) { | if (max_tries == 0 || ShutdownRequested()) { | ||||
return false; | return false; | ||||
} | } | ||||
if (block.nNonce == std::numeric_limits<uint32_t>::max()) { | if (block.nNonce == std::numeric_limits<uint32_t>::max()) { | ||||
return true; | return true; | ||||
} | } | ||||
std::shared_ptr<const CBlock> shared_pblock = | std::shared_ptr<const CBlock> shared_pblock = | ||||
std::make_shared<const CBlock>(block); | std::make_shared<const CBlock>(block); | ||||
if (!chainman.ProcessNewBlock(config, shared_pblock, | if (!chainman.ProcessNewBlock(shared_pblock, | ||||
/*force_processing=*/true, | /*force_processing=*/true, | ||||
/*min_pow_checked=*/true, nullptr)) { | /*min_pow_checked=*/true, nullptr)) { | ||||
throw JSONRPCError(RPC_INTERNAL_ERROR, | throw JSONRPCError(RPC_INTERNAL_ERROR, | ||||
"ProcessNewBlock, block not accepted"); | "ProcessNewBlock, block not accepted"); | ||||
} | } | ||||
block_hash = block.GetHash(); | block_hash = block.GetHash(); | ||||
return true; | return true; | ||||
} | } | ||||
static UniValue generateBlocks(const Config &config, | static UniValue generateBlocks(ChainstateManager &chainman, | ||||
ChainstateManager &chainman, | |||||
const CTxMemPool &mempool, | const CTxMemPool &mempool, | ||||
const CScript &coinbase_script, int nGenerate, | const CScript &coinbase_script, int nGenerate, | ||||
uint64_t nMaxTries) { | uint64_t nMaxTries) { | ||||
UniValue blockHashes(UniValue::VARR); | UniValue blockHashes(UniValue::VARR); | ||||
while (nGenerate > 0 && !ShutdownRequested()) { | while (nGenerate > 0 && !ShutdownRequested()) { | ||||
std::unique_ptr<CBlockTemplate> pblocktemplate( | std::unique_ptr<CBlockTemplate> pblocktemplate( | ||||
BlockAssembler{config, chainman.ActiveChainstate(), &mempool} | BlockAssembler{chainman.GetConfig(), chainman.ActiveChainstate(), | ||||
&mempool} | |||||
.CreateNewBlock(coinbase_script)); | .CreateNewBlock(coinbase_script)); | ||||
if (!pblocktemplate.get()) { | if (!pblocktemplate.get()) { | ||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); | throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); | ||||
} | } | ||||
CBlock *pblock = &pblocktemplate->block; | CBlock *pblock = &pblocktemplate->block; | ||||
BlockHash block_hash; | BlockHash block_hash; | ||||
if (!GenerateBlock(config, chainman, *pblock, nMaxTries, block_hash)) { | if (!GenerateBlock(chainman, *pblock, nMaxTries, block_hash)) { | ||||
break; | break; | ||||
} | } | ||||
if (!block_hash.IsNull()) { | if (!block_hash.IsNull()) { | ||||
--nGenerate; | --nGenerate; | ||||
blockHashes.push_back(block_hash.GetHex()); | blockHashes.push_back(block_hash.GetHex()); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | return RPCHelpMan{ | ||||
coinbase_script, error)) { | coinbase_script, error)) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); | ||||
} | } | ||||
NodeContext &node = EnsureAnyNodeContext(request.context); | NodeContext &node = EnsureAnyNodeContext(request.context); | ||||
const CTxMemPool &mempool = EnsureMemPool(node); | const CTxMemPool &mempool = EnsureMemPool(node); | ||||
ChainstateManager &chainman = EnsureChainman(node); | ChainstateManager &chainman = EnsureChainman(node); | ||||
return generateBlocks(config, chainman, mempool, coinbase_script, | return generateBlocks(chainman, mempool, coinbase_script, | ||||
num_blocks, max_tries); | num_blocks, max_tries); | ||||
}, | }, | ||||
}; | }; | ||||
} | } | ||||
static RPCHelpMan generate() { | static RPCHelpMan generate() { | ||||
return RPCHelpMan{"generate", | return RPCHelpMan{"generate", | ||||
"has been replaced by the -generate cli option. Refer to " | "has been replaced by the -generate cli option. Refer to " | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | return RPCHelpMan{ | ||||
} | } | ||||
NodeContext &node = EnsureAnyNodeContext(request.context); | NodeContext &node = EnsureAnyNodeContext(request.context); | ||||
const CTxMemPool &mempool = EnsureMemPool(node); | const CTxMemPool &mempool = EnsureMemPool(node); | ||||
ChainstateManager &chainman = EnsureChainman(node); | ChainstateManager &chainman = EnsureChainman(node); | ||||
CScript coinbase_script = GetScriptForDestination(destination); | CScript coinbase_script = GetScriptForDestination(destination); | ||||
return generateBlocks(config, chainman, mempool, coinbase_script, | return generateBlocks(chainman, mempool, coinbase_script, | ||||
num_blocks, max_tries); | num_blocks, max_tries); | ||||
}, | }, | ||||
}; | }; | ||||
} | } | ||||
static RPCHelpMan generateblock() { | static RPCHelpMan generateblock() { | ||||
return RPCHelpMan{ | return RPCHelpMan{ | ||||
"generateblock", | "generateblock", | ||||
▲ Show 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | return RPCHelpMan{ | ||||
strprintf("TestBlockValidity failed: %s", | strprintf("TestBlockValidity failed: %s", | ||||
state.ToString())); | state.ToString())); | ||||
} | } | ||||
} | } | ||||
BlockHash block_hash; | BlockHash block_hash; | ||||
uint64_t max_tries{DEFAULT_MAX_TRIES}; | uint64_t max_tries{DEFAULT_MAX_TRIES}; | ||||
if (!GenerateBlock(config, chainman, block, max_tries, | if (!GenerateBlock(chainman, block, max_tries, block_hash) || | ||||
block_hash) || | |||||
block_hash.IsNull()) { | block_hash.IsNull()) { | ||||
throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block."); | throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block."); | ||||
} | } | ||||
// Block to make sure wallet/indexers sync before returning | // Block to make sure wallet/indexers sync before returning | ||||
SyncWithValidationInterfaceQueue(); | SyncWithValidationInterfaceQueue(); | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
▲ Show 20 Lines • Show All 699 Lines • ▼ Show 20 Lines | return RPCHelpMan{ | ||||
} | } | ||||
} | } | ||||
} | } | ||||
bool new_block; | bool new_block; | ||||
auto sc = | auto sc = | ||||
std::make_shared<submitblock_StateCatcher>(block.GetHash()); | std::make_shared<submitblock_StateCatcher>(block.GetHash()); | ||||
RegisterSharedValidationInterface(sc); | RegisterSharedValidationInterface(sc); | ||||
bool accepted = chainman.ProcessNewBlock(config, blockptr, | bool accepted = chainman.ProcessNewBlock(blockptr, | ||||
/*force_processing=*/true, | /*force_processing=*/true, | ||||
/*min_pow_checked=*/true, | /*min_pow_checked=*/true, | ||||
/*new_block=*/&new_block); | /*new_block=*/&new_block); | ||||
UnregisterSharedValidationInterface(sc); | UnregisterSharedValidationInterface(sc); | ||||
if (!new_block && accepted) { | if (!new_block && accepted) { | ||||
return "duplicate"; | return "duplicate"; | ||||
} | } | ||||
Show All 36 Lines | return RPCHelpMan{ | ||||
throw JSONRPCError(RPC_VERIFY_ERROR, | throw JSONRPCError(RPC_VERIFY_ERROR, | ||||
"Must submit previous header (" + | "Must submit previous header (" + | ||||
h.hashPrevBlock.GetHex() + | h.hashPrevBlock.GetHex() + | ||||
") first"); | ") first"); | ||||
} | } | ||||
} | } | ||||
BlockValidationState state; | BlockValidationState state; | ||||
chainman.ProcessNewBlockHeaders(config, {h}, | chainman.ProcessNewBlockHeaders({h}, | ||||
/*min_pow_checked=*/true, state); | /*min_pow_checked=*/true, state); | ||||
if (state.IsValid()) { | if (state.IsValid()) { | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
if (state.IsError()) { | if (state.IsError()) { | ||||
throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString()); | throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString()); | ||||
} | } | ||||
throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason()); | throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason()); | ||||
▲ Show 20 Lines • Show All 45 Lines • Show Last 20 Lines |