2017-11-09 19:34:51 +01:00
/*
* This file is part of the Flowee project
* Copyright (C) 2010 Satoshi Nakamoto
* Copyright (C) 2009-2015 The Bitcoin Core developers
2021-01-20 19:21:53 +01:00
* Copyright (C) 2017-2021 Tom Zander <tom@flowee.org>
2017-11-09 19:34:51 +01:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2012-08-21 02:21:33 -04:00
2018-01-15 15:26:12 +00:00
# include "Application.h"
2018-02-12 14:15:24 +01:00
# include "SettingsDefaults.h"
2018-01-15 15:26:12 +00:00
# include <validation/Engine.h>
2021-11-02 10:23:33 +01:00
# include "primitives/Block.h"
2015-07-05 14:17:46 +02:00
# include "chain.h"
2013-05-07 15:16:25 +02:00
# include "chainparams.h"
2014-09-14 12:43:56 +02:00
# include "core_io.h"
2013-04-13 00:13:08 -05:00
# include "main.h"
2013-07-31 09:43:35 -04:00
# include "miner.h"
2015-01-24 15:29:29 +01:00
# include "net.h"
2017-02-14 11:17:46 +01:00
# include "BlocksDB.h"
2014-03-10 08:46:53 -07:00
# include "pow.h"
2014-09-14 12:43:56 +02:00
# include "rpcserver.h"
2015-07-05 14:17:46 +02:00
# include "txmempool.h"
2014-08-21 16:11:09 +02:00
# include "util.h"
2026-05-14 13:13:40 +02:00
# include "utiltime.h"
2015-07-05 14:17:46 +02:00
# include "utilstrencodings.h"
2015-03-24 22:14:44 +01:00
# include "validationinterface.h"
2018-12-30 15:33:11 +01:00
# include <streaming/BufferPool.h>
2014-05-10 14:54:20 +02:00
2013-04-13 00:13:08 -05:00
# include <stdint.h>
2014-03-17 08:19:54 -04:00
# include <boost/assign/list_of.hpp>
2015-07-01 08:32:30 +02:00
# include <boost/shared_ptr.hpp>
2018-12-30 15:33:11 +01:00
# include <boost/foreach.hpp>
2014-05-10 14:54:20 +02:00
2015-09-04 16:11:34 +02:00
# include <univalue.h>
2012-08-21 02:21:33 -04:00
2014-11-20 10:19:29 +08:00
/**
* Return average network hashes per second based on the last 'lookup' blocks,
* or from the last difficulty change if 'lookup' is nonpositive.
* If 'height' is nonnegative, compute the estimate at the time when a given block was found.
*/
2015-05-13 21:29:19 +02:00
UniValue GetNetworkHashPS ( int lookup , int height ) {
2013-12-29 03:14:06 -08:00
CBlockIndex * pb = chainActive . Tip ( ) ;
if ( height > = 0 & & height < chainActive . Height ( ) )
pb = chainActive [ height ] ;
2013-05-17 00:57:05 -10:00
if ( pb = = NULL | | ! pb - > nHeight )
return 0 ;
// If lookup is -1, then use blocks since last difficulty change.
if ( lookup < = 0 )
2015-04-10 18:35:09 +02:00
lookup = pb - > nHeight % Params ( ) . GetConsensus ( ) . DifficultyAdjustmentInterval ( ) + 1 ;
2013-05-17 00:57:05 -10:00
// If lookup is larger than chain, then set it to chain length.
if ( lookup > pb - > nHeight )
lookup = pb - > nHeight ;
CBlockIndex * pb0 = pb ;
2013-04-13 00:13:08 -05:00
int64_t minTime = pb0 - > GetBlockTime ( ) ;
int64_t maxTime = minTime ;
2013-05-17 00:57:05 -10:00
for ( int i = 0 ; i < lookup ; i + + ) {
pb0 = pb0 - > pprev ;
2013-04-13 00:13:08 -05:00
int64_t time = pb0 - > GetBlockTime ( ) ;
2013-05-17 00:57:05 -10:00
minTime = std : : min ( time , minTime ) ;
maxTime = std : : max ( time , maxTime ) ;
}
// In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
if ( minTime = = maxTime )
return 0 ;
2014-12-16 15:43:03 +01:00
arith_uint256 workDiff = pb - > nChainWork - pb0 - > nChainWork ;
2013-04-13 00:13:08 -05:00
int64_t timeDiff = maxTime - minTime ;
2013-05-17 00:57:05 -10:00
2016-02-08 10:49:27 -05:00
return workDiff . getdouble ( ) / timeDiff ;
2013-05-17 00:57:05 -10:00
}
2015-05-18 14:02:18 +02:00
UniValue getnetworkhashps ( const UniValue & params , bool fHelp )
2013-05-17 00:57:05 -10:00
{
if ( fHelp | | params . size ( ) > 2 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2013-10-29 22:29:44 +11:00
" getnetworkhashps ( blocks height ) \n "
" \n Returns the estimated network hashes per second based on the last n blocks. \n "
2013-05-17 00:57:05 -10:00
" Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change. \n "
2013-10-29 22:29:44 +11:00
" Pass in [height] to estimate the network speed at the time when a certain block was found. \n "
" \n Arguments: \n "
" 1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks since last difficulty change. \n "
" 2. height (numeric, optional, default=-1) To estimate at the time of the given height. \n "
" \n Result: \n "
" x (numeric) Hashes per second estimated \n "
" \n Examples: \n "
+ HelpExampleCli ( " getnetworkhashps " , " " )
+ HelpExampleRpc ( " getnetworkhashps " , " " )
) ;
2013-05-17 00:57:05 -10:00
2014-10-19 04:46:17 -04:00
LOCK ( cs_main ) ;
2013-05-17 00:57:05 -10:00
return GetNetworkHashPS ( params . size ( ) > 0 ? params [ 0 ] . get_int ( ) : 120 , params . size ( ) > 1 ? params [ 1 ] . get_int ( ) : - 1 ) ;
}
2015-05-18 14:02:18 +02:00
UniValue getgenerate ( const UniValue & params , bool fHelp )
2012-08-21 02:21:33 -04:00
{
if ( fHelp | | params . size ( ) ! = 0 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2012-08-21 02:21:33 -04:00
" getgenerate \n "
2013-10-29 22:29:44 +11:00
" \n Return if the server is set to generate coins or not. The default is false. \n "
2018-02-12 14:15:24 +01:00
" It is set with the command line argument -gen (or " + std : : string ( Settings : : hubConfFilename ( ) ) + " setting gen) \n "
2013-10-29 22:29:44 +11:00
" It can also be set with the setgenerate call. \n "
" \n Result \n "
" true|false (boolean) If the server is set to generate coins or not \n "
" \n Examples: \n "
+ HelpExampleCli ( " getgenerate " , " " )
+ HelpExampleRpc ( " getgenerate " , " " )
) ;
2012-08-21 02:21:33 -04:00
2014-10-19 04:46:17 -04:00
LOCK ( cs_main ) ;
2018-02-12 14:15:24 +01:00
return GetBoolArg ( " -gen " , Settings : : DefaultGenerateCoins ) ;
2012-08-21 02:21:33 -04:00
}
2015-05-18 14:02:18 +02:00
UniValue generate ( const UniValue & params , bool fHelp )
2015-03-31 20:28:28 -07:00
{
2016-05-05 14:36:07 +01:00
if ( fHelp | | params . size ( ) < 2 | | params . size ( ) > 2 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2016-05-05 14:36:07 +01:00
" generate numblocks coinbase \n "
2015-03-31 20:28:28 -07:00
" \n Mine blocks immediately (before the RPC call returns) \n "
2015-04-10 07:33:06 +02:00
" \n Note: this function can only be used on the regtest network \n "
2015-09-04 11:05:17 +02:00
" \n Arguments: \n "
2015-09-03 13:29:10 -04:00
" 1. numblocks (numeric, required) How many blocks are generated immediately. \n "
2019-03-09 22:00:02 +01:00
" 2. coinbase (string, required) the hash160 (bitcoin address) for the coinbase \n "
2015-03-31 20:28:28 -07:00
" \n Result \n "
" [ blockhashes ] (array) hashes of blocks generated \n "
" \n Examples: \n "
" \n Generate 11 blocks \n "
+ HelpExampleCli ( " generate " , " 11 " )
) ;
2015-04-10 07:33:06 +02:00
if ( ! Params ( ) . MineBlocksOnDemand ( ) )
throw JSONRPCError ( RPC_METHOD_NOT_FOUND , " This method can only be used on regtest " ) ;
2015-03-31 20:28:28 -07:00
int nHeightStart = 0 ;
int nHeightEnd = 0 ;
int nHeight = 0 ;
int nGenerate = params [ 0 ] . get_int ( ) ;
2015-04-10 12:49:01 +02:00
2016-05-05 14:36:07 +01:00
CScript coinbase = Mining : : ScriptForCoinbase ( params [ 1 ] . get_str ( ) ) ;
2015-03-31 20:28:28 -07:00
{ // Don't keep cs_main locked
LOCK ( cs_main ) ;
nHeightStart = chainActive . Height ( ) ;
nHeight = nHeightStart ;
nHeightEnd = nHeightStart + nGenerate ;
}
2016-05-05 14:36:07 +01:00
Mining * miningInstance = Mining : : instance ( ) ;
miningInstance - > SetCoinbase ( coinbase ) ;
2015-04-10 07:33:06 +02:00
unsigned int nExtraNonce = 0 ;
2015-05-10 14:48:35 +02:00
UniValue blockHashes ( UniValue : : VARR ) ;
2018-01-15 15:26:12 +00:00
Streaming : : BufferPool pool ;
auto * bv = Application : : instance ( ) - > validation ( ) ;
2015-04-10 07:33:06 +02:00
while ( nHeight < nHeightEnd )
{
2018-01-15 15:26:12 +00:00
std : : unique_ptr < CBlockTemplate > pblocktemplate ( miningInstance - > CreateNewBlock ( ) ) ;
2015-04-10 07:33:06 +02:00
if ( ! pblocktemplate . get ( ) )
2015-04-10 12:49:01 +02:00
throw JSONRPCError ( RPC_INTERNAL_ERROR , " Couldn't create new block " ) ;
2021-11-02 09:36:09 +01:00
MutableBlock * pblock = & pblocktemplate - > block ;
2015-04-10 07:33:06 +02:00
{
LOCK ( cs_main ) ;
2016-05-05 14:36:07 +01:00
miningInstance - > IncrementExtraNonce ( pblock , chainActive . Tip ( ) , nExtraNonce ) ;
2015-04-10 07:33:06 +02:00
}
2021-11-02 09:28:35 +01:00
while ( ! CheckProofOfWork ( pblock - > createHash ( ) , pblock - > nBits , Params ( ) . GetConsensus ( ) ) ) {
2015-04-10 07:33:06 +02:00
// Yes, there is a chance every nonce could fail to satisfy the -regtest
// target -- 1 in 2^(2^32). That ain't gonna happen.
+ + pblock - > nNonce ;
}
2018-01-15 15:26:12 +00:00
2021-11-02 10:18:24 +01:00
auto blockFuture = bv - > addBlock ( Block : : fromOldBlock ( * pblock , & pool ) ,
2018-01-15 15:26:12 +00:00
Validation : : ForwardGoodToPeers | Validation : : SaveGoodToDisk ) . start ( ) ;
2015-03-31 20:28:28 -07:00
+ + nHeight ;
2021-11-02 09:28:35 +01:00
blockHashes . push_back ( pblock - > createHash ( ) . GetHex ( ) ) ;
2018-01-15 15:26:12 +00:00
blockFuture . waitUntilFinished ( ) ;
2015-03-31 20:28:28 -07:00
}
return blockHashes ;
}
2012-08-21 02:21:33 -04:00
2015-05-18 14:02:18 +02:00
UniValue setgenerate ( const UniValue & params , bool fHelp )
2012-08-21 02:21:33 -04:00
{
if ( fHelp | | params . size ( ) < 1 | | params . size ( ) > 2 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2013-10-29 22:29:44 +11:00
" setgenerate generate ( genproclimit ) \n "
" \n Set 'generate' true or false to turn generation on or off. \n "
" Generation is limited to 'genproclimit' processors, -1 is unlimited. \n "
" See the getgenerate call for the current setting. \n "
" \n Arguments: \n "
" 1. generate (boolean, required) Set to true to turn on generation, off to turn off. \n "
" 2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited. \n "
" \n Examples: \n "
" \n Set the generation on with a limit of one processor \n "
+ HelpExampleCli ( " setgenerate " , " true 1 " ) +
" \n Check the setting \n "
+ HelpExampleCli ( " getgenerate " , " " ) +
" \n Turn off generation \n "
+ HelpExampleCli ( " setgenerate " , " false " ) +
" \n Using json rpc \n "
+ HelpExampleRpc ( " setgenerate " , " true, 1 " )
) ;
2012-08-21 02:21:33 -04:00
2015-04-21 10:14:06 +02:00
if ( Params ( ) . MineBlocksOnDemand ( ) )
throw JSONRPCError ( RPC_METHOD_NOT_FOUND , " Use the generate method instead of setgenerate on this network " ) ;
2013-11-21 14:07:55 +10:00
2012-08-21 02:21:33 -04:00
bool fGenerate = true ;
if ( params . size ( ) > 0 )
fGenerate = params [ 0 ] . get_bool ( ) ;
2018-02-12 14:15:24 +01:00
int nGenProcLimit = GetArg ( " -genproclimit " , Settings : : DefaultGenerateThreads ) ;
2012-08-21 02:21:33 -04:00
if ( params . size ( ) > 1 )
{
2013-11-21 14:07:55 +10:00
nGenProcLimit = params [ 1 ] . get_int ( ) ;
2012-08-21 02:21:33 -04:00
if ( nGenProcLimit = = 0 )
fGenerate = false ;
}
2015-03-31 20:28:28 -07:00
mapArgs [ " -gen " ] = ( fGenerate ? " 1 " : " 0 " ) ;
mapArgs [ " -genproclimit " ] = itostr ( nGenProcLimit ) ;
2016-05-05 14:36:07 +01:00
std : : string coinbase = GetArg ( " -gencoinbase " , " " ) ;
if ( coinbase . empty ( ) )
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Please use the commandline argument -gencoinbase to set a coinbase " ) ;
Mining : : GenerateBitcoins ( fGenerate , nGenProcLimit , Params ( ) , coinbase ) ;
2013-11-21 14:07:55 +10:00
2014-08-20 15:15:16 -04:00
return NullUniValue ;
2012-08-21 02:21:33 -04:00
}
2015-05-18 14:02:18 +02:00
UniValue getmininginfo ( const UniValue & params , bool fHelp )
2012-08-21 02:21:33 -04:00
{
if ( fHelp | | params . size ( ) ! = 0 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2012-08-21 02:21:33 -04:00
" getmininginfo \n "
2013-10-29 22:29:44 +11:00
" \n Returns a json object containing mining-related information. "
" \n Result: \n "
" { \n "
" \" blocks \" : nnn, (numeric) The current block \n "
" \" currentblocksize \" : nnn, (numeric) The last block size \n "
" \" currentblocktx \" : nnn, (numeric) The last block transaction \n "
" \" difficulty \" : xxx.xxxxx (numeric) The current difficulty \n "
" \" errors \" : \" ... \" (string) Current errors \n "
" \" generate \" : true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls) \n "
" \" genproclimit \" : n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls) \n "
" \" pooledtx \" : n (numeric) The size of the mem pool \n "
" \" testnet \" : true|false (boolean) If using testnet or not \n "
2014-06-12 14:52:12 +02:00
" \" chain \" : \" xxxx \" , (string) current network name as defined in BIP70 (main, test, regtest) \n "
2013-10-29 22:29:44 +11:00
" } \n "
" \n Examples: \n "
+ HelpExampleCli ( " getmininginfo " , " " )
+ HelpExampleRpc ( " getmininginfo " , " " )
) ;
2012-08-21 02:21:33 -04:00
2014-10-19 04:46:17 -04:00
LOCK ( cs_main ) ;
2015-05-10 14:48:35 +02:00
UniValue obj ( UniValue : : VOBJ ) ;
2013-10-10 23:07:44 +02:00
obj . push_back ( Pair ( " blocks " , ( int ) chainActive . Height ( ) ) ) ;
2013-04-28 17:37:50 +02:00
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 ( " errors " , GetWarnings ( " statusbar " ) ) ) ;
2018-02-12 14:15:24 +01:00
obj . push_back ( Pair ( " genproclimit " , ( int ) GetArg ( " -genproclimit " , Settings : : DefaultGenerateThreads ) ) ) ;
2013-05-17 00:57:05 -10:00
obj . push_back ( Pair ( " networkhashps " , getnetworkhashps ( params , false ) ) ) ;
2013-04-28 17:37:50 +02:00
obj . push_back ( Pair ( " pooledtx " , ( uint64_t ) mempool . size ( ) ) ) ;
2014-08-31 22:32:52 +02:00
obj . push_back ( Pair ( " testnet " , Params ( ) . TestnetToBeDeprecatedFieldRPC ( ) ) ) ;
2014-06-12 14:52:12 +02:00
obj . push_back ( Pair ( " chain " , Params ( ) . NetworkIDString ( ) ) ) ;
2013-12-08 15:26:08 +01:00
obj . push_back ( Pair ( " generate " , getgenerate ( params , false ) ) ) ;
2012-08-21 02:21:33 -04:00
return obj ;
}
2019-06-15 13:05:11 +02:00
// NOTE: Unlike wallet RPC (which use BCH values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
2015-05-18 14:02:18 +02:00
UniValue prioritisetransaction ( const UniValue & params , bool fHelp )
2012-07-11 18:52:41 +00:00
{
if ( fHelp | | params . size ( ) ! = 3 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2012-07-11 18:52:41 +00:00
" prioritisetransaction <txid> <priority delta> <fee delta> \n "
2014-07-15 02:11:55 +02:00
" Accepts the transaction into mined blocks at a higher (or lower) priority \n "
" \n Arguments: \n "
" 1. \" txid \" (string, required) The transaction id. \n "
" 2. priority delta (numeric, required) The priority to add or subtract. \n "
" The transaction selection algorithm considers the tx as it would have a higher priority. \n "
" (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n "
2014-12-01 12:51:45 +00:00
" 3. fee delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative). \n "
2014-07-15 02:11:55 +02:00
" The fee is not actually paid, only the algorithm for selecting transactions into a block \n "
" considers the transaction as it would have paid a higher (or lower) fee. \n "
" \n Result \n "
" true (boolean) Returns true \n "
" \n Examples: \n "
2014-12-01 12:51:45 +00:00
+ HelpExampleCli ( " prioritisetransaction " , " \" txid \" 0.0 10000 " )
+ HelpExampleRpc ( " prioritisetransaction " , " \" txid \" , 0.0, 10000 " )
2014-07-15 02:11:55 +02:00
) ;
2012-07-11 18:52:41 +00:00
2014-10-19 04:46:17 -04:00
LOCK ( cs_main ) ;
2014-07-15 02:11:55 +02:00
2014-10-19 04:46:17 -04:00
uint256 hash = ParseHashStr ( params [ 0 ] . get_str ( ) , " txid " ) ;
2021-01-20 19:21:53 +01:00
int64_t nAmount = params [ 2 ] . get_int64 ( ) ;
2014-07-15 02:11:55 +02:00
mempool . PrioritiseTransaction ( hash , params [ 0 ] . get_str ( ) , params [ 1 ] . get_real ( ) , nAmount ) ;
2012-07-11 18:52:41 +00:00
return true ;
}
2015-05-18 14:02:18 +02:00
UniValue getblocktemplate ( const UniValue & params , bool fHelp )
2012-08-21 02:21:33 -04:00
{
2012-10-24 12:39:46 -04:00
if ( fHelp | | params . size ( ) > 1 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2013-10-29 22:29:44 +11:00
" getblocktemplate ( \" jsonrequestobject \" ) \n "
" \n If the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'. \n "
" It returns data needed to construct a block to work on. \n "
2018-01-25 23:40:50 +00:00
" See https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki for full specification. \n "
2013-10-29 22:29:44 +11:00
" \n Arguments: \n "
" 1. \" jsonrequestobject \" (string, optional) A json object in the following spec \n "
" { \n "
" \" mode \" : \" template \" (string, optional) This must be set to \" template \" or omitted \n "
" \" capabilities \" :[ (array, optional) A list of strings \n "
" \" support \" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid' \n "
" ,... \n "
" ] \n "
" } \n "
" \n "
" \n Result: \n "
" { \n "
" \" version \" : n, (numeric) The block version \n "
" \" previousblockhash \" : \" xxxx \" , (string) The hash of current highest block \n "
" \" transactions \" : [ (array) contents of non-coinbase transactions that should be included in the next block \n "
" { \n "
" \" data \" : \" xxxx \" , (string) transaction data encoded in hexadecimal (byte-for-byte) \n "
" \" hash \" : \" xxxx \" , (string) hash/id encoded in little-endian hexadecimal \n "
" \" depends \" : [ (array) array of numbers \n "
" n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is \n "
" ,... \n "
" ], \n "
" \" fee \" : n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one \n "
" \" sigops \" : n, (numeric) total number of SigOps, as counted for purposes of block limits; if key is not present, sigop count is unknown and clients MUST NOT assume there aren't any \n "
" \" required \" : true|false (boolean) if provided and true, this transaction must be in the final block \n "
" } \n "
" ,... \n "
" ], \n "
" \" coinbaseaux \" : { (json object) data that should be included in the coinbase's scriptSig content \n "
" \" flags \" : \" flags \" (string) \n "
" }, \n "
" \" coinbasevalue \" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis) \n "
" \" coinbasetxn \" : { ... }, (json object) information for coinbase transaction \n "
" \" target \" : \" xxxx \" , (string) The hash target \n "
" \" mintime \" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT) \n "
" \" mutable \" : [ (array of string) list of ways the block template may be changed \n "
" \" value \" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock' \n "
" ,... \n "
" ], \n "
" \" noncerange \" : \" 00000000ffffffff \" , (string) A range of valid nonces \n "
" \" sigoplimit \" : n, (numeric) limit of sigops in blocks \n "
2016-11-21 16:25:50 +01:00
" \" sizelimit \" : n, (numeric) limit of block size. (deprecated) \n "
2013-10-29 22:29:44 +11:00
" \" curtime \" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT) \n "
" \" bits \" : \" xxx \" , (string) compressed target of next block \n "
" \" height \" : n (numeric) The height of the next block \n "
" } \n "
" \n Examples: \n "
+ HelpExampleCli ( " getblocktemplate " , " " )
+ HelpExampleRpc ( " getblocktemplate " , " " )
) ;
2012-08-21 02:21:33 -04:00
std : : string strMode = " template " ;
2015-05-13 21:29:19 +02:00
UniValue lpval = NullUniValue ;
2012-08-21 02:21:33 -04:00
if ( params . size ( ) > 0 )
{
2015-05-18 14:02:18 +02:00
const UniValue & oparam = params [ 0 ] . get_obj ( ) ;
const UniValue & modeval = find_value ( oparam , " mode " ) ;
2014-08-20 15:15:16 -04:00
if ( modeval . isStr ( ) )
2012-08-21 02:21:33 -04:00
strMode = modeval . get_str ( ) ;
2014-08-20 15:15:16 -04:00
else if ( modeval . isNull ( ) )
2012-09-01 07:12:50 +00:00
{
/* Do nothing */
}
2012-08-21 02:21:33 -04:00
else
2012-10-04 09:34:44 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid mode " ) ;
2012-05-13 04:43:24 +00:00
lpval = find_value ( oparam , " longpollid " ) ;
2012-09-10 02:55:03 +00:00
if ( strMode = = " proposal " )
{
2015-05-18 14:02:18 +02:00
const UniValue & dataval = find_value ( oparam , " data " ) ;
2015-06-04 21:39:44 +02:00
if ( ! dataval . isStr ( ) )
2012-09-10 02:55:03 +00:00
throw JSONRPCError ( RPC_TYPE_ERROR , " Missing data String key for proposal " ) ;
2021-11-02 09:36:09 +01:00
MutableBlock block ;
2012-09-10 02:55:03 +00:00
if ( ! DecodeHexBlk ( block , dataval . get_str ( ) ) )
throw JSONRPCError ( RPC_DESERIALIZATION_ERROR , " Block decode failed " ) ;
2021-11-02 09:28:35 +01:00
uint256 hash = block . createHash ( ) ;
2018-01-15 15:26:12 +00:00
CBlockIndex * pindex = Blocks : : Index : : get ( hash ) ;
if ( pindex ) {
2012-09-10 02:55:03 +00:00
if ( pindex - > IsValid ( BLOCK_VALID_SCRIPTS ) )
return " duplicate " ;
if ( pindex - > nStatus & BLOCK_FAILED_MASK )
return " duplicate-invalid " ;
return " duplicate-inconclusive " ;
}
CBlockIndex * const pindexPrev = chainActive . Tip ( ) ;
// TestBlockValidity only supports blocks built on the current Tip
if ( block . hashPrevBlock ! = pindexPrev - > GetBlockHash ( ) )
return " inconclusive-not-best-prevblk " ;
2021-11-02 10:18:24 +01:00
auto settings = Application : : instance ( ) - > validation ( ) - > addBlock ( Block : : fromOldBlock ( block ) , 0 ) ;
2018-01-15 15:26:12 +00:00
settings . setCheckPoW ( false ) ;
settings . setOnlyCheckValidity ( true ) ;
settings . start ( ) ;
settings . waitUntilFinished ( ) ;
2018-01-25 23:40:50 +00:00
if ( settings . error ( ) . empty ( ) )
return NullUniValue ;
return settings . error ( ) ;
2012-09-10 02:55:03 +00:00
}
2012-08-21 02:21:33 -04:00
}
if ( strMode ! = " template " )
2012-10-04 09:34:44 +02:00
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid mode " ) ;
2012-08-21 02:21:33 -04:00
if ( vNodes . empty ( ) )
2012-10-04 09:34:44 +02:00
throw JSONRPCError ( RPC_CLIENT_NOT_CONNECTED , " Bitcoin is not connected! " ) ;
2012-08-21 02:21:33 -04:00
if ( IsInitialBlockDownload ( ) )
2012-10-04 09:34:44 +02:00
throw JSONRPCError ( RPC_CLIENT_IN_INITIAL_DOWNLOAD , " Bitcoin is downloading blocks... " ) ;
2012-08-21 02:21:33 -04:00
static unsigned int nTransactionsUpdatedLast ;
2012-05-13 04:43:24 +00:00
2018-01-25 23:40:50 +00:00
LOCK ( cs_main ) ;
2014-08-20 15:15:16 -04:00
if ( ! lpval . isNull ( ) )
2012-05-13 04:43:24 +00:00
{
// Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
uint256 hashWatchedChain ;
boost : : system_time checktxtime ;
unsigned int nTransactionsUpdatedLastLP ;
2014-08-20 15:15:16 -04:00
if ( lpval . isStr ( ) )
2012-05-13 04:43:24 +00:00
{
// Format: <hashBestChain><nTransactionsUpdatedLast>
std : : string lpstr = lpval . get_str ( ) ;
hashWatchedChain . SetHex ( lpstr . substr ( 0 , 64 ) ) ;
nTransactionsUpdatedLastLP = atoi64 ( lpstr . substr ( 64 ) ) ;
}
else
{
// NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
hashWatchedChain = chainActive . Tip ( ) - > GetBlockHash ( ) ;
nTransactionsUpdatedLastLP = nTransactionsUpdatedLast ;
}
// Release the wallet and main lock while waiting
2019-10-10 17:42:16 +02:00
LEAVE_CRITICAL_SECTION ( cs_main )
2012-05-13 04:43:24 +00:00
{
checktxtime = boost : : get_system_time ( ) + boost : : posix_time : : minutes ( 1 ) ;
boost : : unique_lock < boost : : mutex > lock ( csBestBlock ) ;
while ( chainActive . Tip ( ) - > GetBlockHash ( ) = = hashWatchedChain & & IsRPCRunning ( ) )
{
if ( ! cvBlockChange . timed_wait ( lock , checktxtime ) )
{
// Timeout: Check transactions for update
if ( mempool . GetTransactionsUpdated ( ) ! = nTransactionsUpdatedLastLP )
break ;
checktxtime + = boost : : posix_time : : seconds ( 10 ) ;
}
}
}
2019-10-10 17:42:16 +02:00
ENTER_CRITICAL_SECTION ( cs_main )
2012-05-13 04:43:24 +00:00
if ( ! IsRPCRunning ( ) )
throw JSONRPCError ( RPC_CLIENT_NOT_CONNECTED , " Shutting down " ) ;
// TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
}
// Update block
2012-08-21 02:21:33 -04:00
static CBlockIndex * pindexPrev ;
2013-04-13 00:13:08 -05:00
static int64_t nStart ;
2012-12-19 15:21:21 -05:00
static CBlockTemplate * pblocktemplate ;
2013-10-10 23:07:44 +02:00
if ( pindexPrev ! = chainActive . Tip ( ) | |
2013-08-27 15:51:57 +10:00
( mempool . GetTransactionsUpdated ( ) ! = nTransactionsUpdatedLast & & GetTime ( ) - nStart > 5 ) )
2012-08-21 02:21:33 -04:00
{
// Clear pindexPrev so future calls make a new block, despite any failures from here on
pindexPrev = NULL ;
// Store the pindexBest used before CreateNewBlock, to avoid races
2013-08-27 15:51:57 +10:00
nTransactionsUpdatedLast = mempool . GetTransactionsUpdated ( ) ;
2015-04-10 07:33:06 +02:00
CBlockIndex * pindexPrevNew = chainActive . Tip ( ) ;
2012-08-21 02:21:33 -04:00
nStart = GetTime ( ) ;
// Create new block
2012-12-19 15:21:21 -05:00
if ( pblocktemplate )
2012-08-21 02:21:33 -04:00
{
2012-12-19 15:21:21 -05:00
delete pblocktemplate ;
pblocktemplate = NULL ;
2012-08-21 02:21:33 -04:00
}
2016-05-05 14:36:07 +01:00
Mining mining ;
2013-08-24 00:45:17 -04:00
CScript scriptDummy = CScript ( ) < < OP_TRUE ;
2016-05-05 14:36:07 +01:00
mining . SetCoinbase ( scriptDummy ) ;
2019-10-10 17:42:16 +02:00
LEAVE_CRITICAL_SECTION ( cs_main )
2018-01-15 15:26:12 +00:00
pblocktemplate = mining . CreateNewBlock ( * Application : : instance ( ) - > validation ( ) ) ;
2012-12-19 15:21:21 -05:00
if ( ! pblocktemplate )
2012-10-04 09:34:44 +02:00
throw JSONRPCError ( RPC_OUT_OF_MEMORY , " Out of memory " ) ;
2019-10-10 17:42:16 +02:00
ENTER_CRITICAL_SECTION ( cs_main )
2012-08-21 02:21:33 -04:00
// Need to update only after we know CreateNewBlock succeeded
pindexPrev = pindexPrevNew ;
}
2021-11-02 09:36:09 +01:00
MutableBlock * pblock = & pblocktemplate - > block ; // pointer for convenience
2012-08-21 02:21:33 -04:00
// Update nTime
2026-04-15 21:35:08 +02:00
Mining : : UpdateTime ( * pblock , Params ( ) . GetConsensus ( ) , pindexPrev ) ;
2012-08-21 02:21:33 -04:00
pblock - > nNonce = 0 ;
2015-05-10 14:48:35 +02:00
UniValue aCaps ( UniValue : : VARR ) ; aCaps . push_back ( " proposal " ) ;
2012-09-10 02:55:03 +00:00
2015-05-10 14:48:35 +02:00
UniValue transactions ( UniValue : : VARR ) ;
2017-06-30 00:08:19 -04:00
std : : map < uint256 , int64_t > setTxIndex ;
2018-07-23 18:05:43 +02:00
size_t i = 0 ;
2015-05-31 15:36:44 +02:00
BOOST_FOREACH ( const CTransaction & tx , pblock - > vtx ) {
2012-08-21 02:21:33 -04:00
uint256 txHash = tx . GetHash ( ) ;
setTxIndex [ txHash ] = i + + ;
if ( tx . IsCoinBase ( ) )
continue ;
2015-05-10 14:48:35 +02:00
UniValue entry ( UniValue : : VOBJ ) ;
2012-08-21 02:21:33 -04:00
2014-06-23 23:10:24 -04:00
entry . push_back ( Pair ( " data " , EncodeHexTx ( tx ) ) ) ;
2012-08-21 02:21:33 -04:00
2016-12-08 15:31:52 +01:00
entry . push_back ( Pair ( " hash " , txHash . GetHex ( ) ) ) ;
2012-08-21 02:21:33 -04:00
2015-05-10 14:48:35 +02:00
UniValue deps ( UniValue : : VARR ) ;
2012-07-01 18:54:00 +02:00
BOOST_FOREACH ( const CTxIn & in , tx . vin )
2012-08-21 02:21:33 -04:00
{
2012-07-01 18:54:00 +02:00
if ( setTxIndex . count ( in . prevout . hash ) )
deps . push_back ( setTxIndex [ in . prevout . hash ] ) ;
2012-08-21 02:21:33 -04:00
}
2012-07-01 18:54:00 +02:00
entry . push_back ( Pair ( " depends " , deps ) ) ;
2018-07-23 18:05:43 +02:00
assert ( i > 0 ) ;
size_t index_in_template = i - 1 ;
2013-01-03 23:58:36 -05:00
entry . push_back ( Pair ( " fee " , pblocktemplate - > vTxFees [ index_in_template ] ) ) ;
2020-04-12 23:48:32 +02:00
entry . push_back ( Pair ( " sigops " , 0 ) ) ;
2012-08-21 02:21:33 -04:00
transactions . push_back ( entry ) ;
}
2014-12-16 15:43:03 +01:00
arith_uint256 hashTarget = arith_uint256 ( ) . SetCompact ( pblock - > nBits ) ;
2012-08-21 02:21:33 -04:00
2015-05-10 14:48:35 +02:00
static UniValue aMutable ( UniValue : : VARR ) ;
2012-08-21 02:21:33 -04:00
if ( aMutable . empty ( ) )
{
aMutable . push_back ( " time " ) ;
aMutable . push_back ( " transactions " ) ;
aMutable . push_back ( " prevblock " ) ;
}
2015-05-10 14:48:35 +02:00
UniValue result ( UniValue : : VOBJ ) ;
2012-09-10 02:55:03 +00:00
result . push_back ( Pair ( " capabilities " , aCaps ) ) ;
2012-08-21 02:21:33 -04:00
result . push_back ( Pair ( " version " , pblock - > nVersion ) ) ;
result . push_back ( Pair ( " previousblockhash " , pblock - > hashPrevBlock . GetHex ( ) ) ) ;
result . push_back ( Pair ( " transactions " , transactions ) ) ;
result . push_back ( Pair ( " coinbasevalue " , ( int64_t ) pblock - > vtx [ 0 ] . vout [ 0 ] . nValue ) ) ;
2012-05-13 04:43:24 +00:00
result . push_back ( Pair ( " longpollid " , chainActive . Tip ( ) - > GetBlockHash ( ) . GetHex ( ) + i64tostr ( nTransactionsUpdatedLast ) ) ) ;
2012-08-21 02:21:33 -04:00
result . push_back ( Pair ( " target " , hashTarget . GetHex ( ) ) ) ;
result . push_back ( Pair ( " mintime " , ( int64_t ) pindexPrev - > GetMedianTimePast ( ) + 1 ) ) ;
result . push_back ( Pair ( " mutable " , aMutable ) ) ;
result . push_back ( Pair ( " noncerange " , " 00000000ffffffff " ) ) ;
2016-11-21 16:25:50 +01:00
int64_t sizeLimit = 32E6 ; // lets have a nice big default, the goal is to remove this from the API
2020-04-12 23:48:32 +02:00
result . push_back ( Pair ( " sigoplimit " , 100000 ) ) ; // obsolete
2016-11-21 16:25:50 +01:00
result . push_back ( Pair ( " sizelimit " , sizeLimit ) ) ;
2021-11-02 09:28:35 +01:00
result . push_back ( Pair ( " curtime " , pblock - > blockTime ( ) ) ) ;
2014-06-27 13:28:08 +02:00
result . push_back ( Pair ( " bits " , strprintf ( " %08x " , pblock - > nBits ) ) ) ;
2012-08-21 02:21:33 -04:00
result . push_back ( Pair ( " height " , ( int64_t ) ( pindexPrev - > nHeight + 1 ) ) ) ;
return result ;
}
2015-05-18 14:02:18 +02:00
UniValue submitblock ( const UniValue & params , bool fHelp )
2012-08-21 02:21:33 -04:00
{
if ( fHelp | | params . size ( ) < 1 | | params . size ( ) > 2 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2013-10-29 22:29:44 +11:00
" submitblock \" hexdata \" ( \" jsonparametersobject \" ) \n "
" \n Attempts to submit new block to network. \n "
" The 'jsonparametersobject' parameter is currently ignored. \n "
" See https://en.bitcoin.it/wiki/BIP_0022 for full specification. \n "
" \n Arguments \n "
" 1. \" hexdata \" (string, required) the hex-encoded block data to submit \n "
" 2. \" jsonparametersobject \" (string, optional) object of optional parameters \n "
" { \n "
" \" workid \" : \" id \" (string, optional) if the server provided a workid, it MUST be included with submissions \n "
" } \n "
" \n Result: \n "
" \n Examples: \n "
+ HelpExampleCli ( " submitblock " , " \" mydata \" " )
+ HelpExampleRpc ( " submitblock " , " \" mydata \" " )
) ;
2012-08-21 02:21:33 -04:00
2021-11-02 09:36:09 +01:00
MutableBlock block ;
2014-11-18 19:09:20 +00:00
if ( ! DecodeHexBlk ( block , params [ 0 ] . get_str ( ) ) )
2012-10-04 09:34:44 +02:00
throw JSONRPCError ( RPC_DESERIALIZATION_ERROR , " Block decode failed " ) ;
2012-08-21 02:21:33 -04:00
2021-11-02 09:28:35 +01:00
uint256 hash = block . createHash ( ) ;
2015-04-13 17:55:41 +01:00
{
2018-01-15 15:26:12 +00:00
CBlockIndex * pindex = Blocks : : Index : : get ( hash ) ;
if ( pindex ) {
2021-03-24 18:54:01 +01:00
if ( Blocks : : DB : : instance ( ) - > headerChain ( ) . Contains ( pindex ) )
2015-04-13 17:55:41 +01:00
return " duplicate " ;
if ( pindex - > nStatus & BLOCK_FAILED_MASK )
return " duplicate-invalid " ;
// Otherwise, we might only have the header - process the block before returning
}
2012-08-21 02:21:33 -04:00
}
2021-11-02 10:18:24 +01:00
auto future = Application : : instance ( ) - > validation ( ) - > addBlock ( Block : : fromOldBlock ( block ) , Validation : : SaveGoodToDisk | Validation : : ForwardGoodToPeers ) ;
2021-03-24 18:54:01 +01:00
future . start ( ) ;
2018-01-15 15:26:12 +00:00
future . waitUntilFinished ( ) ;
auto index = future . blockIndex ( ) ;
if ( index & & future . error ( ) . empty ( ) & & index - > IsValid ( ) ) // all Ok
return NullUniValue ;
2021-03-24 18:54:01 +01:00
if ( ! future . error ( ) . empty ( ) )
2018-01-15 15:26:12 +00:00
throw JSONRPCError ( RPC_VERIFY_ERROR , future . error ( ) ) ;
if ( index )
return " rejected " ;
return " accepted " ;
2012-08-21 02:21:33 -04:00
}
2014-03-17 08:19:54 -04:00
2015-05-18 14:02:18 +02:00
UniValue estimatefee ( const UniValue & params , bool fHelp )
2014-03-17 08:19:54 -04:00
{
if ( fHelp | | params . size ( ) ! = 1 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2014-03-17 08:19:54 -04:00
" estimatefee nblocks \n "
2015-07-08 21:40:14 +02:00
" \n Estimates the approximate fee per kilobyte needed for a transaction to begin \n "
" confirmation within nblocks blocks. \n "
2014-03-17 08:19:54 -04:00
" \n Arguments: \n "
" 1. nblocks (numeric) \n "
" \n Result: \n "
2015-07-08 21:40:14 +02:00
" n (numeric) estimated fee-per-kilobyte \n "
2014-03-17 08:19:54 -04:00
" \n "
2015-07-08 21:40:14 +02:00
" A negative value is returned if not enough transactions and blocks \n "
" have been observed to make an estimate. \n "
2014-03-17 08:19:54 -04:00
" \n Example: \n "
+ HelpExampleCli ( " estimatefee " , " 6 " )
) ;
2014-08-20 15:15:16 -04:00
RPCTypeCheck ( params , boost : : assign : : list_of ( UniValue : : VNUM ) ) ;
2019-06-28 12:38:46 +02:00
return - 1.0 ;
2014-03-17 08:19:54 -04:00
}
2015-05-18 14:02:18 +02:00
UniValue estimatepriority ( const UniValue & params , bool fHelp )
2014-03-17 08:19:54 -04:00
{
if ( fHelp | | params . size ( ) ! = 1 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2014-03-17 08:19:54 -04:00
" estimatepriority nblocks \n "
2015-07-08 21:40:14 +02:00
" \n Estimates the approximate priority a zero-fee transaction needs to begin \n "
" confirmation within nblocks blocks. \n "
2014-03-17 08:19:54 -04:00
" \n Arguments: \n "
" 1. nblocks (numeric) \n "
" \n Result: \n "
2015-07-08 21:40:14 +02:00
" n (numeric) estimated priority \n "
2014-03-17 08:19:54 -04:00
" \n "
2015-07-08 21:40:14 +02:00
" A negative value is returned if not enough transactions and blocks \n "
" have been observed to make an estimate. \n "
2014-03-17 08:19:54 -04:00
" \n Example: \n "
+ HelpExampleCli ( " estimatepriority " , " 6 " )
) ;
2014-08-20 15:15:16 -04:00
RPCTypeCheck ( params , boost : : assign : : list_of ( UniValue : : VNUM ) ) ;
2019-06-28 12:38:46 +02:00
return - 1 ;
2014-03-17 08:19:54 -04:00
}
2015-11-16 15:26:57 -05:00
UniValue estimatesmartfee ( const UniValue & params , bool fHelp )
{
if ( fHelp | | params . size ( ) ! = 1 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2015-11-16 15:26:57 -05:00
" estimatesmartfee nblocks \n "
" \n WARNING: This interface is unstable and may disappear or change! \n "
" \n Estimates the approximate fee per kilobyte needed for a transaction to begin \n "
" confirmation within nblocks blocks if possible and return the number of blocks \n "
" for which the estimate is valid. \n "
" \n Arguments: \n "
" 1. nblocks (numeric) \n "
" \n Result: \n "
" { \n "
2019-06-15 13:05:11 +02:00
" \" feerate \" : x.x, (numeric) estimate fee-per-kilobyte (in BCH) \n "
2015-11-16 15:26:57 -05:00
" \" blocks \" : n (numeric) block number where estimate was found \n "
" } \n "
" \n "
" A negative value is returned if not enough transactions and blocks \n "
" have been observed to make an estimate for any number of blocks. \n "
" However it will not return a value below the mempool reject fee. \n "
" \n Example: \n "
+ HelpExampleCli ( " estimatesmartfee " , " 6 " )
) ;
RPCTypeCheck ( params , boost : : assign : : list_of ( UniValue : : VNUM ) ) ;
UniValue result ( UniValue : : VOBJ ) ;
2019-06-28 12:38:46 +02:00
result . push_back ( Pair ( " feerate " , - 1 ) ) ;
result . push_back ( Pair ( " blocks " , 0 ) ) ;
2015-11-16 15:26:57 -05:00
return result ;
}
UniValue estimatesmartpriority ( const UniValue & params , bool fHelp )
{
if ( fHelp | | params . size ( ) ! = 1 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2015-11-16 15:26:57 -05:00
" estimatesmartpriority nblocks \n "
" \n WARNING: This interface is unstable and may disappear or change! \n "
" \n Estimates the approximate priority a zero-fee transaction needs to begin \n "
" confirmation within nblocks blocks if possible and return the number of blocks \n "
" for which the estimate is valid. \n "
" \n Arguments: \n "
" 1. nblocks (numeric) \n "
" \n Result: \n "
" { \n "
" \" priority \" : x.x, (numeric) estimated priority \n "
" \" blocks \" : n (numeric) block number where estimate was found \n "
" } \n "
" \n "
" A negative value is returned if not enough transactions and blocks \n "
" have been observed to make an estimate for any number of blocks. \n "
" However if the mempool reject fee is set it will return 1e9 * MAX_MONEY. \n "
" \n Example: \n "
+ HelpExampleCli ( " estimatesmartpriority " , " 6 " )
) ;
RPCTypeCheck ( params , boost : : assign : : list_of ( UniValue : : VNUM ) ) ;
UniValue result ( UniValue : : VOBJ ) ;
2019-06-28 12:38:46 +02:00
result . push_back ( Pair ( " priority " , - 1 ) ) ;
result . push_back ( Pair ( " blocks " , 0 ) ) ;
2015-11-16 15:26:57 -05:00
return result ;
}
2016-05-10 11:25:39 +01:00
UniValue setcoinbase ( const UniValue & params , bool fHelp )
{
if ( fHelp | | params . size ( ) ! = 1 )
2017-06-30 00:08:19 -04:00
throw std : : runtime_error (
2016-05-10 11:25:39 +01:00
" setcoinbase pubkey \n "
" \n when called this registers a public key to be used as a coinbase for subsequent \n "
" calls to getblocktemplate \n "
" \n Arguments: \n "
" 1. pubkey (hex) the raw (hex encoded) pubkey \n "
" \n "
) ;
auto script = Mining : : ScriptForCoinbase ( params [ 0 ] . get_str ( ) ) ;
Mining : : instance ( ) - > SetCoinbase ( script ) ;
return UniValue ( UniValue : : VOBJ ) ;
}
2020-12-18 15:35:45 +01:00
UniValue validateblocktemplate ( const UniValue & params , bool fHelp )
{
if ( fHelp | | params . size ( ) < 1 | | params . size ( ) > 1 )
throw std : : runtime_error (
" validateblocktemplate \" hexdata \" \n "
" \n Returns whether this block template will be accepted if a hash solution is found. \n "
" See https://en.bitcoin.it/wiki/BIP_0022 for full specification. \n "
" \n Arguments \n "
" 1. \" hexdata \" (string, required) the hex-encoded block to validate (same format as submitblock) \n "
" \n Result: \n "
" true (boolean) submitted block template is valid \n "
" JSONRPCException if submitted block template is invalid \n " ) ;
2021-11-02 10:18:24 +01:00
Block block ;
2020-12-18 15:35:45 +01:00
{ // go via the old serialization since it does extra checks right here.
2021-11-02 09:36:09 +01:00
MutableBlock oldBlock ;
2020-12-18 15:35:45 +01:00
if ( ! DecodeHexBlk ( oldBlock , params [ 0 ] . get_str ( ) ) )
throw JSONRPCError ( RPC_DESERIALIZATION_ERROR , " Block decode failed " ) ;
2021-11-02 10:18:24 +01:00
block = Block : : fromOldBlock ( oldBlock ) ;
2020-12-18 15:35:45 +01:00
}
auto pindexPrev = Blocks : : Index : : get ( block . previousBlockId ( ) ) ;
if ( ! pindexPrev )
throw std : : runtime_error ( " invalid block: unknown parent " ) ;
if ( pindexPrev ! = chainActive . Tip ( ) )
throw std : : runtime_error ( " invalid block: does not build on chain tip " ) ;
auto settings = Application : : instance ( ) - > validation ( ) - > addBlock ( block , 0 ) ;
settings . setCheckMerkleRoot ( true ) ;
settings . setCheckPoW ( false ) ;
settings . setOnlyCheckValidity ( true ) ;
logInfo ( Log : : RPC ) < < " Block submitted for validation " < < block . createHash ( ) < < block . size ( ) < < " bytes " ;
settings . start ( ) ;
logInfo ( Log : : RPC ) < < " Validation started " ;
settings . waitUntilFinished ( ) ;
logInfo ( Log : : RPC ) < < " Validation finished with: " < < settings . error ( ) ;
if ( ! settings . error ( ) . empty ( ) )
throw std : : runtime_error ( std : : string ( " invalid block: " ) + settings . error ( ) ) ;
return UniValue ( true ) ;
}