Browse Source

Merge pull request #5957

e2edf95 Bugfix: make CreateNewBlock return pindexPrev (Pieter Wuille)
6b04508 Introduce separate 'generate' RPC call (Pieter Wuille)
0df67f1 Simplify hash loop code (Pieter Wuille)
0.13
Wladimir J. van der Laan 10 years ago
parent
commit
57026a29bc
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 16
      qa/rpc-tests/bipdersig.py
  2. 6
      qa/rpc-tests/conflictedbalance.sh
  3. 8
      qa/rpc-tests/forknotify.py
  4. 6
      qa/rpc-tests/getblocktemplate_longpoll.py
  5. 2
      qa/rpc-tests/getblocktemplate_proposals.py
  6. 4
      qa/rpc-tests/getchaintips.py
  7. 6
      qa/rpc-tests/invalidateblock.py
  8. 2
      qa/rpc-tests/listtransactions.py
  9. 6
      qa/rpc-tests/mempool_coinbase_spends.py
  10. 6
      qa/rpc-tests/mempool_resurrect_test.py
  11. 2
      qa/rpc-tests/mempool_spendcoinbase.py
  12. 6
      qa/rpc-tests/receivedby.py
  13. 2
      qa/rpc-tests/rest.py
  14. 6
      qa/rpc-tests/smartfees.py
  15. 6
      qa/rpc-tests/txn_doublespend.py
  16. 2
      qa/rpc-tests/util.py
  17. 18
      qa/rpc-tests/wallet.py
  18. 12
      qa/rpc-tests/walletbackup.py
  19. 6
      qa/rpc-tests/zapwallettxes.py
  20. 122
      src/miner.cpp
  21. 6
      src/miner.h
  22. 1
      src/rpcclient.cpp
  23. 95
      src/rpcmining.cpp
  24. 1
      src/rpcserver.cpp
  25. 1
      src/rpcserver.h
  26. 27
      src/test/miner_tests.cpp

16
qa/rpc-tests/bipdersig.py

@ -29,14 +29,14 @@ class BIP66Test(BitcoinTestFramework):
cnt = self.nodes[0].getblockcount() cnt = self.nodes[0].getblockcount()
# Mine some old-version blocks # Mine some old-version blocks
self.nodes[1].setgenerate(True, 100) self.nodes[1].generate(100)
self.sync_all() self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 100): if (self.nodes[0].getblockcount() != cnt + 100):
raise AssertionError("Failed to mine 100 version=2 blocks") raise AssertionError("Failed to mine 100 version=2 blocks")
# Mine 750 new-version blocks # Mine 750 new-version blocks
for i in xrange(15): for i in xrange(15):
self.nodes[2].setgenerate(True, 50) self.nodes[2].generate(50)
self.sync_all() self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 850): if (self.nodes[0].getblockcount() != cnt + 850):
raise AssertionError("Failed to mine 750 version=3 blocks") raise AssertionError("Failed to mine 750 version=3 blocks")
@ -44,7 +44,7 @@ class BIP66Test(BitcoinTestFramework):
# TODO: check that new DERSIG rules are not enforced # TODO: check that new DERSIG rules are not enforced
# Mine 1 new-version block # Mine 1 new-version block
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
self.sync_all() self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 851): if (self.nodes[0].getblockcount() != cnt + 851):
raise AssertionFailure("Failed to mine a version=3 blocks") raise AssertionFailure("Failed to mine a version=3 blocks")
@ -53,26 +53,26 @@ class BIP66Test(BitcoinTestFramework):
# Mine 198 new-version blocks # Mine 198 new-version blocks
for i in xrange(2): for i in xrange(2):
self.nodes[2].setgenerate(True, 99) self.nodes[2].generate(99)
self.sync_all() self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 1049): if (self.nodes[0].getblockcount() != cnt + 1049):
raise AssertionError("Failed to mine 198 version=3 blocks") raise AssertionError("Failed to mine 198 version=3 blocks")
# Mine 1 old-version block # Mine 1 old-version block
self.nodes[1].setgenerate(True, 1) self.nodes[1].generate(1)
self.sync_all() self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 1050): if (self.nodes[0].getblockcount() != cnt + 1050):
raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks") raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks")
# Mine 1 new-version blocks # Mine 1 new-version blocks
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
self.sync_all() self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 1051): if (self.nodes[0].getblockcount() != cnt + 1051):
raise AssertionError("Failed to mine a version=3 block") raise AssertionError("Failed to mine a version=3 block")
# Mine 1 old-version blocks # Mine 1 old-version blocks
try: try:
self.nodes[1].setgenerate(True, 1) self.nodes[1].generate(1)
raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks") raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks")
except JSONRPCException: except JSONRPCException:
pass pass
@ -81,7 +81,7 @@ class BIP66Test(BitcoinTestFramework):
raise AssertionError("Accepted a version=2 block after 950 version=3 blocks") raise AssertionError("Accepted a version=2 block after 950 version=3 blocks")
# Mine 1 new-version blocks # Mine 1 new-version blocks
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
self.sync_all() self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 1052): if (self.nodes[0].getblockcount() != cnt + 1052):
raise AssertionError("Failed to mine a version=3 block") raise AssertionError("Failed to mine a version=3 block")

6
qa/rpc-tests/conflictedbalance.sh

@ -84,11 +84,11 @@ WaitPeers "$B1ARGS" 1
# 2 block, 50 XBT each == 100 XBT # 2 block, 50 XBT each == 100 XBT
# These will be transactions "A" and "B" # These will be transactions "A" and "B"
$CLI $B1ARGS setgenerate true 2 $CLI $B1ARGS generate 2
WaitBlocks WaitBlocks
# 100 blocks, 0 mature == 0 XBT # 100 blocks, 0 mature == 0 XBT
$CLI $B2ARGS setgenerate true 100 $CLI $B2ARGS generate 100
WaitBlocks WaitBlocks
CheckBalance "$B1ARGS" 100 CheckBalance "$B1ARGS" 100
@ -130,7 +130,7 @@ WaitPeers "$B1ARGS" 1
# Having B2 mine the next block puts the mutated # Having B2 mine the next block puts the mutated
# transaction C in the chain: # transaction C in the chain:
$CLI $B2ARGS setgenerate true 1 $CLI $B2ARGS generate 1
WaitBlocks WaitBlocks
# B1 should still be able to spend 100, because D is conflicted # B1 should still be able to spend 100, because D is conflicted

8
qa/rpc-tests/forknotify.py

@ -34,12 +34,12 @@ class ForkNotifyTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
# Mine 51 up-version blocks # Mine 51 up-version blocks
self.nodes[1].setgenerate(True, 51) self.nodes[1].generate(51)
self.sync_all() self.sync_all()
# -alertnotify should trigger on the 51'st, # -alertnotify should trigger on the 51'st,
# but mine and sync another to give # but mine and sync another to give
# -alertnotify time to write # -alertnotify time to write
self.nodes[1].setgenerate(True, 1) self.nodes[1].generate(1)
self.sync_all() self.sync_all()
with open(self.alert_filename, 'r') as f: with open(self.alert_filename, 'r') as f:
@ -49,9 +49,9 @@ class ForkNotifyTest(BitcoinTestFramework):
raise AssertionError("-alertnotify did not warn of up-version blocks") raise AssertionError("-alertnotify did not warn of up-version blocks")
# Mine more up-version blocks, should not get more alerts: # Mine more up-version blocks, should not get more alerts:
self.nodes[1].setgenerate(True, 1) self.nodes[1].generate(1)
self.sync_all() self.sync_all()
self.nodes[1].setgenerate(True, 1) self.nodes[1].generate(1)
self.sync_all() self.sync_all()
with open(self.alert_filename, 'r') as f: with open(self.alert_filename, 'r') as f:

6
qa/rpc-tests/getblocktemplate_longpoll.py

@ -51,7 +51,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
print "Warning: this test will take about 70 seconds in the best case. Be patient." print "Warning: this test will take about 70 seconds in the best case. Be patient."
self.nodes[0].setgenerate(True, 10) self.nodes[0].generate(10)
templat = self.nodes[0].getblocktemplate() templat = self.nodes[0].getblocktemplate()
longpollid = templat['longpollid'] longpollid = templat['longpollid']
# longpollid should not change between successive invocations if nothing else happens # longpollid should not change between successive invocations if nothing else happens
@ -66,7 +66,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
assert(thr.is_alive()) assert(thr.is_alive())
# Test 2: test that longpoll will terminate if another node generates a block # Test 2: test that longpoll will terminate if another node generates a block
self.nodes[1].setgenerate(True, 1) # generate a block on another node self.nodes[1].generate(1) # generate a block on another node
# check that thread will exit now that new transaction entered mempool # check that thread will exit now that new transaction entered mempool
thr.join(5) # wait 5 seconds or until thread exits thr.join(5) # wait 5 seconds or until thread exits
assert(not thr.is_alive()) assert(not thr.is_alive())
@ -74,7 +74,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
# Test 3: test that longpoll will terminate if we generate a block ourselves # Test 3: test that longpoll will terminate if we generate a block ourselves
thr = LongpollThread(self.nodes[0]) thr = LongpollThread(self.nodes[0])
thr.start() thr.start()
self.nodes[0].setgenerate(True, 1) # generate a block on another node self.nodes[0].generate(1) # generate a block on another node
thr.join(5) # wait 5 seconds or until thread exits thr.join(5) # wait 5 seconds or until thread exits
assert(not thr.is_alive()) assert(not thr.is_alive())

2
qa/rpc-tests/getblocktemplate_proposals.py

@ -95,7 +95,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
node = self.nodes[0] node = self.nodes[0]
node.setgenerate(True, 1) # Mine a block to leave initial block download node.generate(1) # Mine a block to leave initial block download
tmpl = node.getblocktemplate() tmpl = node.getblocktemplate()
if 'coinbasetxn' not in tmpl: if 'coinbasetxn' not in tmpl:
rawcoinbase = encodeUNum(tmpl['height']) rawcoinbase = encodeUNum(tmpl['height'])

4
qa/rpc-tests/getchaintips.py

@ -23,8 +23,8 @@ class GetChainTipsTest (BitcoinTestFramework):
# Split the network and build two chains of different lengths. # Split the network and build two chains of different lengths.
self.split_network () self.split_network ()
self.nodes[0].setgenerate (True, 10); self.nodes[0].generate(10);
self.nodes[2].setgenerate (True, 20); self.nodes[2].generate(20);
self.sync_all () self.sync_all ()
tips = self.nodes[1].getchaintips () tips = self.nodes[1].getchaintips ()

6
qa/rpc-tests/invalidateblock.py

@ -28,12 +28,12 @@ class InvalidateTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:" print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:"
print "Mine 4 blocks on Node 0" print "Mine 4 blocks on Node 0"
self.nodes[0].setgenerate(True, 4) self.nodes[0].generate(4)
assert(self.nodes[0].getblockcount() == 4) assert(self.nodes[0].getblockcount() == 4)
besthash = self.nodes[0].getbestblockhash() besthash = self.nodes[0].getbestblockhash()
print "Mine competing 6 blocks on Node 1" print "Mine competing 6 blocks on Node 1"
self.nodes[1].setgenerate(True, 6) self.nodes[1].generate(6)
assert(self.nodes[1].getblockcount() == 6) assert(self.nodes[1].getblockcount() == 6)
print "Connect nodes to force a reorg" print "Connect nodes to force a reorg"
@ -61,7 +61,7 @@ class InvalidateTest(BitcoinTestFramework):
self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3)) self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3))
assert(self.nodes[2].getblockcount() == 2) assert(self.nodes[2].getblockcount() == 2)
print "..and then mine a block" print "..and then mine a block"
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
print "Verify all nodes are at the right height" print "Verify all nodes are at the right height"
time.sleep(5) time.sleep(5)
for i in xrange(3): for i in xrange(3):

2
qa/rpc-tests/listtransactions.py

@ -44,7 +44,7 @@ class ListTransactionsTest(BitcoinTestFramework):
{"txid":txid}, {"txid":txid},
{"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0}) {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0})
# mine a block, confirmations should change: # mine a block, confirmations should change:
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
self.sync_all() self.sync_all()
check_array_result(self.nodes[0].listtransactions(), check_array_result(self.nodes[0].listtransactions(),
{"txid":txid}, {"txid":txid},

6
qa/rpc-tests/mempool_coinbase_spends.py

@ -41,7 +41,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# Mine three blocks. After this, nodes[0] blocks # Mine three blocks. After this, nodes[0] blocks
# 101, 102, and 103 are spend-able. # 101, 102, and 103 are spend-able.
new_blocks = self.nodes[1].setgenerate(True, 4) new_blocks = self.nodes[1].generate(4)
self.sync_all() self.sync_all()
node0_address = self.nodes[0].getnewaddress() node0_address = self.nodes[0].getnewaddress()
@ -62,7 +62,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# Broadcast and mine spend_102 and 103: # Broadcast and mine spend_102 and 103:
spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw) spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw)
spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw) spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw)
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
# Create 102_1 and 103_1: # Create 102_1 and 103_1:
spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50) spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50)
@ -70,7 +70,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# Broadcast and mine 103_1: # Broadcast and mine 103_1:
spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw)
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
# ... now put spend_101 and spend_102_1 in memory pools: # ... now put spend_101 and spend_102_1 in memory pools:
spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw) spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw)

6
qa/rpc-tests/mempool_resurrect_test.py

@ -51,12 +51,12 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ] spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ]
blocks = [] blocks = []
blocks.extend(self.nodes[0].setgenerate(True, 1)) blocks.extend(self.nodes[0].generate(1))
spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ] spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ]
spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ] spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ]
blocks.extend(self.nodes[0].setgenerate(True, 1)) blocks.extend(self.nodes[0].generate(1))
# mempool should be empty, all txns confirmed # mempool should be empty, all txns confirmed
assert_equal(set(self.nodes[0].getrawmempool()), set()) assert_equal(set(self.nodes[0].getrawmempool()), set())
@ -76,7 +76,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
assert(tx["confirmations"] == 0) assert(tx["confirmations"] == 0)
# Generate another block, they should all get mined # Generate another block, they should all get mined
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
# mempool should be empty, all txns confirmed # mempool should be empty, all txns confirmed
assert_equal(set(self.nodes[0].getrawmempool()), set()) assert_equal(set(self.nodes[0].getrawmempool()), set())
for txid in spends1_id+spends2_id: for txid in spends1_id+spends2_id:

2
qa/rpc-tests/mempool_spendcoinbase.py

@ -58,7 +58,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ]) assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ])
# mine a block, spend_101 should get confirmed # mine a block, spend_101 should get confirmed
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
assert_equal(set(self.nodes[0].getrawmempool()), set()) assert_equal(set(self.nodes[0].getrawmempool()), set())
# ... and now height 102 can be spent: # ... and now height 102 can be spent:

6
qa/rpc-tests/receivedby.py

@ -69,7 +69,7 @@ class ReceivedByTest(BitcoinTestFramework):
{ }, { },
True) True)
#Bury Tx under 10 block so it will be returned by listreceivedbyaddress #Bury Tx under 10 block so it will be returned by listreceivedbyaddress
self.nodes[1].setgenerate(True, 10) self.nodes[1].generate(10)
self.sync_all() self.sync_all()
check_array_result(self.nodes[1].listreceivedbyaddress(), check_array_result(self.nodes[1].listreceivedbyaddress(),
{"address":addr}, {"address":addr},
@ -106,7 +106,7 @@ class ReceivedByTest(BitcoinTestFramework):
raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance)) raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance))
#Bury Tx under 10 block so it will be returned by the default getreceivedbyaddress #Bury Tx under 10 block so it will be returned by the default getreceivedbyaddress
self.nodes[1].setgenerate(True, 10) self.nodes[1].generate(10)
self.sync_all() self.sync_all()
balance = self.nodes[1].getreceivedbyaddress(addr) balance = self.nodes[1].getreceivedbyaddress(addr)
if balance != Decimal("0.1"): if balance != Decimal("0.1"):
@ -136,7 +136,7 @@ class ReceivedByTest(BitcoinTestFramework):
if balance != balance_by_account: if balance != balance_by_account:
raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance)) raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
self.nodes[1].setgenerate(True, 10) self.nodes[1].generate(10)
self.sync_all() self.sync_all()
# listreceivedbyaccount should return updated account balance # listreceivedbyaccount should return updated account balance
check_array_result(self.nodes[1].listreceivedbyaccount(), check_array_result(self.nodes[1].listreceivedbyaccount(),

2
qa/rpc-tests/rest.py

@ -90,7 +90,7 @@ class RESTTest (BitcoinTestFramework):
self.sync_all() self.sync_all()
# now mine the transactions # now mine the transactions
newblockhash = self.nodes[1].setgenerate(True, 1) newblockhash = self.nodes[1].generate(1)
self.sync_all() self.sync_all()
#check if the 3 tx show up in the new block #check if the 3 tx show up in the new block

6
qa/rpc-tests/smartfees.py

@ -51,7 +51,7 @@ class EstimateFeeTest(BitcoinTestFramework):
# Mine blocks with node2 until the memory pool clears: # Mine blocks with node2 until the memory pool clears:
count_start = self.nodes[2].getblockcount() count_start = self.nodes[2].getblockcount()
while len(self.nodes[2].getrawmempool()) > 0: while len(self.nodes[2].getrawmempool()) > 0:
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
self.sync_all() self.sync_all()
all_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ] all_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ]
@ -70,7 +70,7 @@ class EstimateFeeTest(BitcoinTestFramework):
Decimal("0.0"), min_fee, 20) Decimal("0.0"), min_fee, 20)
tx_kbytes = (len(txhex)/2)/1000.0 tx_kbytes = (len(txhex)/2)/1000.0
fees_per_kb.append(float(fee)/tx_kbytes) fees_per_kb.append(float(fee)/tx_kbytes)
self.nodes[1].setgenerate(True, 1) self.nodes[1].generate(1)
self.sync_all() self.sync_all()
all_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ] all_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ]
@ -81,7 +81,7 @@ class EstimateFeeTest(BitcoinTestFramework):
# Finish by mining a normal-sized block: # Finish by mining a normal-sized block:
while len(self.nodes[0].getrawmempool()) > 0: while len(self.nodes[0].getrawmempool()) > 0:
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
self.sync_all() self.sync_all()
final_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ] final_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ]

6
qa/rpc-tests/txn_doublespend.py

@ -58,7 +58,7 @@ class TxnMallTest(BitcoinTestFramework):
# Have node0 mine a block: # Have node0 mine a block:
if (self.options.mine_block): if (self.options.mine_block):
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
sync_blocks(self.nodes[0:2]) sync_blocks(self.nodes[0:2])
tx1 = self.nodes[0].gettransaction(txid1) tx1 = self.nodes[0].gettransaction(txid1)
@ -88,11 +88,11 @@ class TxnMallTest(BitcoinTestFramework):
# Now give doublespend to miner: # Now give doublespend to miner:
mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"]) mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"])
# ... mine a block... # ... mine a block...
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
# Reconnect the split network, and sync chain: # Reconnect the split network, and sync chain:
connect_nodes(self.nodes[1], 2) connect_nodes(self.nodes[1], 2)
self.nodes[2].setgenerate(True, 1) # Mine another block to make sure we sync self.nodes[2].generate(1) # Mine another block to make sure we sync
sync_blocks(self.nodes) sync_blocks(self.nodes)
# Re-fetch transaction info: # Re-fetch transaction info:

2
qa/rpc-tests/util.py

@ -109,7 +109,7 @@ def initialize_chain(test_dir):
for peer in range(4): for peer in range(4):
for j in range(25): for j in range(25):
set_node_times(rpcs, block_time) set_node_times(rpcs, block_time)
rpcs[peer].setgenerate(True, 1) rpcs[peer].generate(1)
block_time += 10*60 block_time += 10*60
# Must sync before next peer starts generating blocks # Must sync before next peer starts generating blocks
sync_blocks(rpcs) sync_blocks(rpcs)

18
qa/rpc-tests/wallet.py

@ -40,14 +40,14 @@ class WalletTest (BitcoinTestFramework):
def run_test (self): def run_test (self):
print "Mining blocks..." print "Mining blocks..."
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
walletinfo = self.nodes[0].getwalletinfo() walletinfo = self.nodes[0].getwalletinfo()
assert_equal(walletinfo['immature_balance'], 50) assert_equal(walletinfo['immature_balance'], 50)
assert_equal(walletinfo['balance'], 0) assert_equal(walletinfo['balance'], 0)
self.sync_all() self.sync_all()
self.nodes[1].setgenerate(True, 101) self.nodes[1].generate(101)
self.sync_all() self.sync_all()
assert_equal(self.nodes[0].getbalance(), 50) assert_equal(self.nodes[0].getbalance(), 50)
@ -63,11 +63,11 @@ class WalletTest (BitcoinTestFramework):
assert_equal(walletinfo['immature_balance'], 0) assert_equal(walletinfo['immature_balance'], 0)
# Have node0 mine a block, thus they will collect their own fee. # Have node0 mine a block, thus they will collect their own fee.
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
self.sync_all() self.sync_all()
# Have node1 generate 100 blocks (so node0 can recover the fee) # Have node1 generate 100 blocks (so node0 can recover the fee)
self.nodes[1].setgenerate(True, 100) self.nodes[1].generate(100)
self.sync_all() self.sync_all()
# node0 should end up with 100 btc in block rewards plus fees, but # node0 should end up with 100 btc in block rewards plus fees, but
@ -96,7 +96,7 @@ class WalletTest (BitcoinTestFramework):
self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], True) self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], True)
# Have node1 mine a block to confirm transactions: # Have node1 mine a block to confirm transactions:
self.nodes[1].setgenerate(True, 1) self.nodes[1].generate(1)
self.sync_all() self.sync_all()
assert_equal(self.nodes[0].getbalance(), 0) assert_equal(self.nodes[0].getbalance(), 0)
@ -107,28 +107,28 @@ class WalletTest (BitcoinTestFramework):
address = self.nodes[0].getnewaddress("test") address = self.nodes[0].getnewaddress("test")
self.nodes[2].settxfee(Decimal('0.001')) self.nodes[2].settxfee(Decimal('0.001'))
txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) txid = self.nodes[2].sendtoaddress(address, 10, "", "", False)
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
self.sync_all() self.sync_all()
assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000')) assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000'))
assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000')) assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000'))
# Send 10 BTC with subtract fee from amount # Send 10 BTC with subtract fee from amount
txid = self.nodes[2].sendtoaddress(address, 10, "", "", True) txid = self.nodes[2].sendtoaddress(address, 10, "", "", True)
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
self.sync_all() self.sync_all()
assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000')) assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000'))
assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000')) assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000'))
# Sendmany 10 BTC # Sendmany 10 BTC
txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", []) txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [])
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
self.sync_all() self.sync_all()
assert_equal(self.nodes[2].getbalance(), Decimal('69.99800000')) assert_equal(self.nodes[2].getbalance(), Decimal('69.99800000'))
assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000')) assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000'))
# Sendmany 10 BTC with subtract fee from amount # Sendmany 10 BTC with subtract fee from amount
txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address]) txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address])
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
self.sync_all() self.sync_all()
assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')) assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000'))
assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000')) assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000'))

12
qa/rpc-tests/walletbackup.py

@ -77,7 +77,7 @@ class WalletBackupTest(BitcoinTestFramework):
# Have the miner (node3) mine a block. # Have the miner (node3) mine a block.
# Must sync mempools before mining. # Must sync mempools before mining.
sync_mempools(self.nodes) sync_mempools(self.nodes)
self.nodes[3].setgenerate(True, 1) self.nodes[3].generate(1)
# As above, this mirrors the original bash test. # As above, this mirrors the original bash test.
def start_three(self): def start_three(self):
@ -101,13 +101,13 @@ class WalletBackupTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
logging.info("Generating initial blockchain") logging.info("Generating initial blockchain")
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
sync_blocks(self.nodes) sync_blocks(self.nodes)
self.nodes[1].setgenerate(True, 1) self.nodes[1].generate(1)
sync_blocks(self.nodes) sync_blocks(self.nodes)
self.nodes[2].setgenerate(True, 1) self.nodes[2].generate(1)
sync_blocks(self.nodes) sync_blocks(self.nodes)
self.nodes[3].setgenerate(True, 100) self.nodes[3].generate(100)
sync_blocks(self.nodes) sync_blocks(self.nodes)
assert_equal(self.nodes[0].getbalance(), 50) assert_equal(self.nodes[0].getbalance(), 50)
@ -134,7 +134,7 @@ class WalletBackupTest(BitcoinTestFramework):
self.do_one_round() self.do_one_round()
# Generate 101 more blocks, so any fees paid mature # Generate 101 more blocks, so any fees paid mature
self.nodes[3].setgenerate(True, 101) self.nodes[3].generate(101)
self.sync_all() self.sync_all()
balance0 = self.nodes[0].getbalance() balance0 = self.nodes[0].getbalance()

6
qa/rpc-tests/zapwallettxes.py

@ -23,9 +23,9 @@ class ZapWalletTXesTest (BitcoinTestFramework):
def run_test (self): def run_test (self):
print "Mining blocks..." print "Mining blocks..."
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
self.sync_all() self.sync_all()
self.nodes[1].setgenerate(True, 101) self.nodes[1].generate(101)
self.sync_all() self.sync_all()
assert_equal(self.nodes[0].getbalance(), 50) assert_equal(self.nodes[0].getbalance(), 50)
@ -33,7 +33,7 @@ class ZapWalletTXesTest (BitcoinTestFramework):
txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
self.sync_all() self.sync_all()
self.nodes[0].setgenerate(True, 1) self.nodes[0].generate(1)
self.sync_all() self.sync_all()
txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)

122
src/miner.cpp

@ -87,7 +87,7 @@ void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev)
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
} }
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev)
{ {
// Create new block // Create new block
auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate()); auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
@ -132,7 +132,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
{ {
LOCK2(cs_main, mempool.cs); LOCK2(cs_main, mempool.cs);
CBlockIndex* pindexPrev = chainActive.Tip(); pindexPrev = chainActive.Tip();
const int nHeight = pindexPrev->nHeight + 1; const int nHeight = pindexPrev->nHeight + 1;
CCoinsViewCache view(pcoinsTip); CCoinsViewCache view(pcoinsTip);
@ -365,45 +365,34 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
// //
// ScanHash scans nonces looking for a hash with at least some zero bits. // ScanHash scans nonces looking for a hash with at least some zero bits.
// The nonce is usually preserved between calls, but periodically or if the // The nonce is usually preserved between calls, but periodically the block is
// nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at // rebuilt and nNonce starts over at zero.
// zero.
// //
bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash) bool static ScanHash(CBlockHeader *pblock, uint256 *phash)
{ {
// Write the first 76 bytes of the block header to a double-SHA256 state.
CHash256 hasher;
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << *pblock;
assert(ss.size() == 80);
hasher.Write((unsigned char*)&ss[0], 76);
while (true) { while (true) {
nNonce++; pblock->nNonce++;
*phash = pblock->GetHash();
// Write the last 4 bytes of the block header (the nonce) to a copy of
// the double-SHA256 state, and compute the result.
CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash);
// Return the nonce if the hash has at least some zero bits, // Return the nonce if the hash has at least some zero bits,
// caller will check if it has enough to reach the target // caller will check if it has enough to reach the target
if (((uint16_t*)phash)[15] == 0) if (((uint16_t*)phash)[15] == 0)
return true; return true;
// If nothing found after trying for a while, return -1 // If nothing found after trying for a while, return false.
if ((nNonce & 0xfff) == 0) if ((pblock->nNonce & 0xfff) == 0)
return false; return false;
} }
} }
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CBlockIndex*& pindexPrev)
{ {
CPubKey pubkey; CPubKey pubkey;
if (!reservekey.GetReservedKey(pubkey)) if (!reservekey.GetReservedKey(pubkey))
return NULL; return NULL;
CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
return CreateNewBlock(scriptPubKey); return CreateNewBlock(scriptPubKey, pindexPrev);
} }
static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
@ -435,6 +424,56 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese
return true; return true;
} }
bool static ScanLoop(CBlock *pblock, CBlockIndex *pindexPrev, CWallet *pwallet, CReserveKey& reservekey)
{
UpdateTime(pblock, pindexPrev);
arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
uint256 hash;
if (ScanHash(pblock, &hash)) {
if (UintToArith256(hash) <= hashTarget) {
// Found a solution
SetThreadPriority(THREAD_PRIORITY_NORMAL);
LogPrintf("BitcoinMiner:\n");
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
ProcessBlockFound(pblock, *pwallet, reservekey);
SetThreadPriority(THREAD_PRIORITY_LOWEST);
return true;
}
}
return false;
}
bool MineBlock(CWallet *pwallet, uint256& hash)
{
CReserveKey reservekey(pwallet);
unsigned int nExtraNonce = 0;
while (true) {
CBlockIndex *pindexPrev;
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev));
if (!pblocktemplate.get()) {
return false;
}
CBlock *pblock = &pblocktemplate->block;
IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
while (true) {
if (ScanLoop(pblock, pindexPrev, pwallet, reservekey)) {
hash = pblock->GetHash();
return true;
}
boost::this_thread::interruption_point();
if (pblock->nNonce >= 0xffff0000)
break;
}
}
}
void static BitcoinMiner(CWallet *pwallet) void static BitcoinMiner(CWallet *pwallet)
{ {
LogPrintf("BitcoinMiner started\n"); LogPrintf("BitcoinMiner started\n");
@ -458,9 +497,9 @@ void static BitcoinMiner(CWallet *pwallet)
// Create new block // Create new block
// //
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrev = chainActive.Tip(); CBlockIndex* pindexPrev;
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey)); auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev));
if (!pblocktemplate.get()) if (!pblocktemplate.get())
{ {
LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
@ -476,52 +515,23 @@ void static BitcoinMiner(CWallet *pwallet)
// Search // Search
// //
int64_t nStart = GetTime(); int64_t nStart = GetTime();
arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
uint256 hash;
uint32_t nNonce = 0;
while (true) { while (true) {
// Check if something found // Check if something found
if (ScanHash(pblock, nNonce, &hash)) if (ScanLoop(pblock, pindexPrev, pwallet, reservekey))
{ break;
if (UintToArith256(hash) <= hashTarget)
{
// Found a solution
pblock->nNonce = nNonce;
assert(hash == pblock->GetHash());
SetThreadPriority(THREAD_PRIORITY_NORMAL);
LogPrintf("BitcoinMiner:\n");
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
ProcessBlockFound(pblock, *pwallet, reservekey);
SetThreadPriority(THREAD_PRIORITY_LOWEST);
// In regression test mode, stop mining after a block is found.
if (Params().MineBlocksOnDemand())
throw boost::thread_interrupted();
break;
}
}
// Check for stop or if block needs to be rebuilt // Check for stop or if block needs to be rebuilt
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
// Regtest mode doesn't require peers // Regtest mode doesn't require peers
if (vNodes.empty() && Params().MiningRequiresPeers()) if (vNodes.empty() && Params().MiningRequiresPeers())
break; break;
if (nNonce >= 0xffff0000) if (pblock->nNonce >= 0xffff0000)
break; break;
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60) if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
break; break;
if (pindexPrev != chainActive.Tip()) if (pindexPrev != chainActive.Tip())
break; break;
// Update nTime every few seconds
UpdateTime(pblock, pindexPrev);
if (Params().AllowMinDifficultyBlocks())
{
// Changing pblock->nTime can change work required on testnet:
hashTarget.SetCompact(pblock->nBits);
}
} }
} }
} }

6
src/miner.h

@ -24,9 +24,11 @@ struct CBlockTemplate
/** Run the miner threads */ /** Run the miner threads */
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
/** Create a single block */
bool MineBlock(CWallet *pwallet, uint256& hash);
/** Generate a new block, without valid proof-of-work */ /** Generate a new block, without valid proof-of-work */
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev);
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CBlockIndex*& pindexPrev);
/** Modify the extranonce in a block */ /** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev);

1
src/rpcclient.cpp

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

95
src/rpcmining.cpp

@ -113,6 +113,45 @@ Value getgenerate(const Array& params, bool fHelp)
return GetBoolArg("-gen", false); return GetBoolArg("-gen", false);
} }
Value generate(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 1)
throw runtime_error(
"generate numblocks\n"
"\nMine blocks immediately (before the RPC call returns)\n"
"1. numblocks (numeric) How many blocks are generated immediately.\n"
"\nResult\n"
"[ blockhashes ] (array) hashes of blocks generated\n"
"\nExamples:\n"
"\nGenerate 11 blocks\n"
+ HelpExampleCli("generate", "11")
);
if (pwalletMain == NULL)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
int nHeightStart = 0;
int nHeightEnd = 0;
int nHeight = 0;
int nGenerate = params[0].get_int();
{ // Don't keep cs_main locked
LOCK(cs_main);
nHeightStart = chainActive.Height();
nHeight = nHeightStart;
nHeightEnd = nHeightStart+nGenerate;
}
Array blockHashes;
while (nHeight < nHeightEnd) {
uint256 hash;
if (!MineBlock(pwalletMain, hash))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
++nHeight;
blockHashes.push_back(hash.GetHex());
}
return blockHashes;
}
Value setgenerate(const Array& params, bool fHelp) Value setgenerate(const Array& params, bool fHelp)
{ {
@ -125,9 +164,6 @@ Value setgenerate(const Array& params, bool fHelp)
"\nArguments:\n" "\nArguments:\n"
"1. generate (boolean, required) Set to true to turn on generation, off to turn off.\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" "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n"
" Note: in -regtest mode, genproclimit controls how many blocks are generated immediately.\n"
"\nResult\n"
"[ blockhashes ] (array, -regtest only) hashes of blocks generated\n"
"\nExamples:\n" "\nExamples:\n"
"\nSet the generation on with a limit of one processor\n" "\nSet the generation on with a limit of one processor\n"
+ HelpExampleCli("setgenerate", "true 1") + + HelpExampleCli("setgenerate", "true 1") +
@ -154,52 +190,9 @@ Value setgenerate(const Array& params, bool fHelp)
fGenerate = false; fGenerate = false;
} }
// -regtest mode: don't return until nGenProcLimit blocks are generated mapArgs["-gen"] = (fGenerate ? "1" : "0");
if (fGenerate && Params().MineBlocksOnDemand()) mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
{ GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
int nHeightStart = 0;
int nHeightEnd = 0;
int nHeight = 0;
int nGenerate = (nGenProcLimit > 0 ? nGenProcLimit : 1);
CReserveKey reservekey(pwalletMain);
{ // Don't keep cs_main locked
LOCK(cs_main);
nHeightStart = chainActive.Height();
nHeight = nHeightStart;
nHeightEnd = nHeightStart+nGenerate;
}
unsigned int nExtraNonce = 0;
Array blockHashes;
while (nHeight < nHeightEnd)
{
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
if (!pblocktemplate.get())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
CBlock *pblock = &pblocktemplate->block;
{
LOCK(cs_main);
IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce);
}
while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
// 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;
}
CValidationState state;
if (!ProcessNewBlock(state, NULL, pblock))
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
++nHeight;
blockHashes.push_back(pblock->GetHash().GetHex());
}
return blockHashes;
}
else // Not -regtest: start generate thread, return immediately
{
mapArgs["-gen"] = (fGenerate ? "1" : "0");
mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
}
return Value::null; return Value::null;
} }
@ -482,7 +475,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
// Store the pindexBest used before CreateNewBlock, to avoid races // Store the pindexBest used before CreateNewBlock, to avoid races
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrevNew = chainActive.Tip(); CBlockIndex* pindexPrevNew;
nStart = GetTime(); nStart = GetTime();
// Create new block // Create new block
@ -492,7 +485,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
pblocktemplate = NULL; pblocktemplate = NULL;
} }
CScript scriptDummy = CScript() << OP_TRUE; CScript scriptDummy = CScript() << OP_TRUE;
pblocktemplate = CreateNewBlock(scriptDummy); pblocktemplate = CreateNewBlock(scriptDummy, pindexPrevNew);
if (!pblocktemplate) if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");

1
src/rpcserver.cpp

@ -312,6 +312,7 @@ static const CRPCCommand vRPCCommands[] =
/* Coin generation */ /* Coin generation */
{ "generating", "getgenerate", &getgenerate, true, false }, { "generating", "getgenerate", &getgenerate, true, false },
{ "generating", "setgenerate", &setgenerate, true, false }, { "generating", "setgenerate", &setgenerate, true, false },
{ "generating", "generate", &generate, true, false },
#endif #endif
/* Raw transactions */ /* Raw transactions */

1
src/rpcserver.h

@ -162,6 +162,7 @@ extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fH
extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value generate(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);

27
src/test/miner_tests.cpp

@ -62,7 +62,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
Checkpoints::fEnabled = false; Checkpoints::fEnabled = false;
// Simple block creation, nothing special yet: // Simple block creation, nothing special yet:
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); CBlockIndex* pindexPrev;
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
// We can't make transactions until we have inputs // We can't make transactions until we have inputs
// Therefore, load 100 blocks :) // Therefore, load 100 blocks :)
@ -90,7 +91,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
delete pblocktemplate; delete pblocktemplate;
// Just to make sure we can still make simple blocks // Just to make sure we can still make simple blocks
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
// block sigops > limit: 1000 CHECKMULTISIG + 1 // block sigops > limit: 1000 CHECKMULTISIG + 1
@ -108,7 +109,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
tx.vin[0].prevout.hash = hash; tx.vin[0].prevout.hash = hash;
} }
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -128,14 +129,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
tx.vin[0].prevout.hash = hash; tx.vin[0].prevout.hash = hash;
} }
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
// orphan in mempool // orphan in mempool
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -153,7 +154,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue = 5900000000LL; tx.vout[0].nValue = 5900000000LL;
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -164,7 +165,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue = 0; tx.vout[0].nValue = 0;
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -182,7 +183,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue -= 1000000; tx.vout[0].nValue -= 1000000;
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -196,17 +197,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].scriptPubKey = CScript() << OP_2; tx.vout[0].scriptPubKey = CScript() << OP_2;
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
// subsidy changing // subsidy changing
int nHeight = chainActive.Height(); int nHeight = chainActive.Height();
chainActive.Tip()->nHeight = 209999; chainActive.Tip()->nHeight = 209999;
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
chainActive.Tip()->nHeight = 210000; chainActive.Tip()->nHeight = 210000;
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
chainActive.Tip()->nHeight = nHeight; chainActive.Tip()->nHeight = nHeight;
@ -238,7 +239,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11));
BOOST_CHECK(!IsFinalTx(tx2)); BOOST_CHECK(!IsFinalTx(tx2));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
// Neither tx should have make it into the template. // Neither tx should have make it into the template.
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1);
@ -251,7 +252,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 1)); BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 1));
BOOST_CHECK(IsFinalTx(tx2)); BOOST_CHECK(IsFinalTx(tx2));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3);
delete pblocktemplate; delete pblocktemplate;

Loading…
Cancel
Save