aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2016-03-23 13:24:34 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2016-03-23 13:24:53 +0100
commite2ebd259fbe80c030ddc1caabbcd755b7f5f8f8e (patch)
treeb569906ba76ebe1dc314e203f59af3bdc6ef5362
parent909b72b10b4dcd8588fed4659595403d34cbebde (diff)
parentd5c5c713e67368802b6a4ab2b6b69962364c251b (diff)
Merge #7671: [RPC] Add generatetoaddress rpc to mine to an address
d5c5c71 RPC tests for generatetoaddress (Andrew C) fe00ca7 Create generatetoaddress rpc (Andrew C)
-rwxr-xr-xqa/rpc-tests/disablewallet.py14
-rwxr-xr-xqa/rpc-tests/wallet.py12
-rw-r--r--src/rpc/client.cpp3
-rw-r--r--src/rpc/mining.cpp109
-rw-r--r--src/rpc/server.cpp1
-rw-r--r--src/rpc/server.h1
6 files changed, 107 insertions, 33 deletions
diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py
index 6964348d55..5af8158467 100755
--- a/qa/rpc-tests/disablewallet.py
+++ b/qa/rpc-tests/disablewallet.py
@@ -29,5 +29,19 @@ class DisableWalletTest (BitcoinTestFramework):
x = self.nodes[0].validateaddress('mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
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__':
DisableWalletTest ().main ()
diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py
index f686e6be6c..df176601a5 100755
--- a/qa/rpc-tests/wallet.py
+++ b/qa/rpc-tests/wallet.py
@@ -262,6 +262,18 @@ class WalletTest (BitcoinTestFramework):
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
self.sync_all()
blocks = self.nodes[0].generate(2)
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 45fb6c1642..89420b93d7 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -29,6 +29,9 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "getaddednodeinfo", 0 },
{ "generate", 0 },
{ "generate", 1 },
+ { "generatetoaddress", 0 },
+ { "generatetoaddress", 1 },
+ { "generatetoaddress", 2 },
{ "getnetworkhashps", 0 },
{ "getnetworkhashps", 1 },
{ "sendtoaddress", 1 },
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index c33082fca0..a2abbb323d 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -3,6 +3,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "base58.h"
#include "amount.h"
#include "chain.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);
}
-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;
int nHeightStart = 0;
int nHeightEnd = 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
LOCK(cs_main);
@@ -164,12 +135,84 @@ UniValue generate(const UniValue& params, bool fHelp)
++nHeight;
blockHashes.push_back(pblock->GetHash().GetHex());
- //mark script as important because it was used at least for one coinbase output
- coinbaseScript->KeepScript();
+ //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;
}
+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)
{
if (fHelp || params.size() != 0)
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 33fa1437e2..1303a3bb13 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -299,6 +299,7 @@ static const CRPCCommand vRPCCommands[] =
/* Coin generation */
{ "generating", "generate", &generate, true },
+ { "generating", "generatetoaddress", &generatetoaddress, true },
/* Raw transactions */
{ "rawtransactions", "createrawtransaction", &createrawtransaction, true },
diff --git a/src/rpc/server.h b/src/rpc/server.h
index 38cb32e7f2..35e114feef 100644
--- a/src/rpc/server.h
+++ b/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 generate(const UniValue& params, bool fHelp);
+extern UniValue generatetoaddress(const UniValue& params, bool fHelp);
extern UniValue getnetworkhashps(const UniValue& params, bool fHelp);
extern UniValue getmininginfo(const UniValue& params, bool fHelp);
extern UniValue prioritisetransaction(const UniValue& params, bool fHelp);