Browse Source

Merge #7671: [RPC] Add generatetoaddress rpc to mine to an address

d5c5c71 RPC tests for generatetoaddress (Andrew C)
fe00ca7 Create generatetoaddress rpc (Andrew C)
0.13
Wladimir J. van der Laan 9 years ago
parent
commit
e2ebd259fb
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 14
      qa/rpc-tests/disablewallet.py
  2. 12
      qa/rpc-tests/wallet.py
  3. 3
      src/rpc/client.cpp
  4. 107
      src/rpc/mining.cpp
  5. 1
      src/rpc/server.cpp
  6. 1
      src/rpc/server.h

14
qa/rpc-tests/disablewallet.py

@ -29,5 +29,19 @@ class DisableWalletTest (BitcoinTestFramework):
x = self.nodes[0].validateaddress('mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ') x = self.nodes[0].validateaddress('mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
assert(x['isvalid'] == True) assert(x['isvalid'] == True)
# Checking mining to an address without a wallet
try:
self.nodes[0].generatetoaddress(1, 'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
except JSONRPCException,e:
assert("Invalid address" not in e.error['message'])
assert("ProcessNewBlock, block not accepted" not in e.error['message'])
assert("Couldn't create new block" not in e.error['message'])
try:
self.nodes[0].generatetoaddress(1, '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy')
raise AssertionError("Must not mine to invalid address!")
except JSONRPCException,e:
assert("Invalid address" in e.error['message'])
if __name__ == '__main__': if __name__ == '__main__':
DisableWalletTest ().main () DisableWalletTest ().main ()

12
qa/rpc-tests/wallet.py

@ -262,6 +262,18 @@ class WalletTest (BitcoinTestFramework):
assert("not an integer" in errorString) assert("not an integer" in errorString)
# Mine a block from node0 to an address from node1
cbAddr = self.nodes[1].getnewaddress()
blkHash = self.nodes[0].generatetoaddress(1, cbAddr)[0]
cbTxId = self.nodes[0].getblock(blkHash)['tx'][0]
self.sync_all()
# Check that the txid and balance is found by node1
try:
self.nodes[1].gettransaction(cbTxId)
except JSONRPCException,e:
assert("Invalid or non-wallet transaction id" not in e.error['message'])
#check if wallet or blochchain maintenance changes the balance #check if wallet or blochchain maintenance changes the balance
self.sync_all() self.sync_all()
blocks = self.nodes[0].generate(2) blocks = self.nodes[0].generate(2)

3
src/rpc/client.cpp

@ -29,6 +29,9 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "getaddednodeinfo", 0 }, { "getaddednodeinfo", 0 },
{ "generate", 0 }, { "generate", 0 },
{ "generate", 1 }, { "generate", 1 },
{ "generatetoaddress", 0 },
{ "generatetoaddress", 1 },
{ "generatetoaddress", 2 },
{ "getnetworkhashps", 0 }, { "getnetworkhashps", 0 },
{ "getnetworkhashps", 1 }, { "getnetworkhashps", 1 },
{ "sendtoaddress", 1 }, { "sendtoaddress", 1 },

107
src/rpc/mining.cpp

@ -3,6 +3,7 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
#include "amount.h" #include "amount.h"
#include "chain.h" #include "chain.h"
#include "chainparams.h" #include "chainparams.h"
@ -93,42 +94,12 @@ UniValue getnetworkhashps(const UniValue& params, bool fHelp)
return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
} }
UniValue generate(const UniValue& params, bool fHelp) UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript)
{ {
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"generate numblocks ( maxtries )\n"
"\nMine up to numblocks blocks immediately (before the RPC call returns)\n"
"\nArguments:\n"
"1. numblocks (numeric, required) How many blocks are generated immediately.\n"
"2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
"\nResult\n"
"[ blockhashes ] (array) hashes of blocks generated\n"
"\nExamples:\n"
"\nGenerate 11 blocks\n"
+ HelpExampleCli("generate", "11")
);
static const int nInnerLoopCount = 0x10000; static const int nInnerLoopCount = 0x10000;
int nHeightStart = 0; int nHeightStart = 0;
int nHeightEnd = 0; int nHeightEnd = 0;
int nHeight = 0; int nHeight = 0;
int nGenerate = params[0].get_int();
uint64_t nMaxTries = 1000000;
if (params.size() > 1) {
nMaxTries = params[1].get_int();
}
boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript);
// If the keypool is exhausted, no script is returned at all. Catch this.
if (!coinbaseScript)
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
//throw an error if no script was provided
if (coinbaseScript->reserveScript.empty())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
{ // Don't keep cs_main locked { // Don't keep cs_main locked
LOCK(cs_main); LOCK(cs_main);
@ -164,12 +135,84 @@ UniValue generate(const UniValue& params, bool fHelp)
++nHeight; ++nHeight;
blockHashes.push_back(pblock->GetHash().GetHex()); blockHashes.push_back(pblock->GetHash().GetHex());
//mark script as important because it was used at least for one coinbase output //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(); coinbaseScript->KeepScript();
} }
}
return blockHashes; return blockHashes;
} }
UniValue generate(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"generate numblocks ( maxtries )\n"
"\nMine up to numblocks blocks immediately (before the RPC call returns)\n"
"\nArguments:\n"
"1. numblocks (numeric, required) How many blocks are generated immediately.\n"
"2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
"\nResult\n"
"[ blockhashes ] (array) hashes of blocks generated\n"
"\nExamples:\n"
"\nGenerate 11 blocks\n"
+ HelpExampleCli("generate", "11")
);
int nGenerate = params[0].get_int();
uint64_t nMaxTries = 1000000;
if (params.size() > 1) {
nMaxTries = params[1].get_int();
}
boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript);
// If the keypool is exhausted, no script is returned at all. Catch this.
if (!coinbaseScript)
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
//throw an error if no script was provided
if (coinbaseScript->reserveScript.empty())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
return generateBlocks(coinbaseScript, nGenerate, nMaxTries, true);
}
UniValue generatetoaddress(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() < 2 || params.size() > 3)
throw runtime_error(
"generatetoaddress numblocks address (maxtries)\n"
"\nMine blocks immediately to a specified address (before the RPC call returns)\n"
"\nArguments:\n"
"1. numblocks (numeric, required) How many blocks are generated immediately.\n"
"2. address (string, required) The address to send the newly generated bitcoin to.\n"
"3. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
"\nResult\n"
"[ blockhashes ] (array) hashes of blocks generated\n"
"\nExamples:\n"
"\nGenerate 11 blocks to myaddress\n"
+ HelpExampleCli("generatetoaddress", "11 \"myaddress\"")
);
int nGenerate = params[0].get_int();
uint64_t nMaxTries = 1000000;
if (params.size() > 2) {
nMaxTries = params[2].get_int();
}
CBitcoinAddress address(params[1].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address");
boost::shared_ptr<CReserveScript> coinbaseScript(new CReserveScript());
coinbaseScript->reserveScript = GetScriptForDestination(address.Get());
return generateBlocks(coinbaseScript, nGenerate, nMaxTries, false);
}
UniValue getmininginfo(const UniValue& params, bool fHelp) UniValue getmininginfo(const UniValue& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)

1
src/rpc/server.cpp

@ -299,6 +299,7 @@ static const CRPCCommand vRPCCommands[] =
/* Coin generation */ /* Coin generation */
{ "generating", "generate", &generate, true }, { "generating", "generate", &generate, true },
{ "generating", "generatetoaddress", &generatetoaddress, true },
/* Raw transactions */ /* Raw transactions */
{ "rawtransactions", "createrawtransaction", &createrawtransaction, true }, { "rawtransactions", "createrawtransaction", &createrawtransaction, true },

1
src/rpc/server.h

@ -193,6 +193,7 @@ extern UniValue listbanned(const UniValue& params, bool fHelp);
extern UniValue clearbanned(const UniValue& params, bool fHelp); extern UniValue clearbanned(const UniValue& params, bool fHelp);
extern UniValue generate(const UniValue& params, bool fHelp); extern UniValue generate(const UniValue& params, bool fHelp);
extern UniValue generatetoaddress(const UniValue& params, bool fHelp);
extern UniValue getnetworkhashps(const UniValue& params, bool fHelp); extern UniValue getnetworkhashps(const UniValue& params, bool fHelp);
extern UniValue getmininginfo(const UniValue& params, bool fHelp); extern UniValue getmininginfo(const UniValue& params, bool fHelp);
extern UniValue prioritisetransaction(const UniValue& params, bool fHelp); extern UniValue prioritisetransaction(const UniValue& params, bool fHelp);

Loading…
Cancel
Save