Auto merge of #3762 - str4d:2074-detach-wallet-from-miner, r=Eirik0

Detach wallet from miner

Cherry-picked from upstream PR bitcoin/bitcoin#5994.

Part of #2074.
This commit is contained in:
Homu 2019-03-12 13:01:31 -07:00
commit 1cbe5075d6
41 changed files with 283 additions and 345 deletions

View File

@ -9,6 +9,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
connect_nodes_bi,
get_coinbase_address,
initialize_chain_clean,
start_nodes,
wait_and_assert_operationid_status,
@ -56,7 +57,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
assert_equal(blk["finalsaplingroot"], SAPLING_TREE_EMPTY_ROOT)
# Node 0 shields some funds
taddr0 = self.nodes[0].getnewaddress()
taddr0 = get_coinbase_address(self.nodes[0])
saplingAddr0 = self.nodes[0].z_getnewaddress('sapling')
recipients = []
recipients.append({"address": saplingAddr0, "amount": Decimal('20')})

View File

@ -7,7 +7,8 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Py
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, initialize_chain_clean, \
start_node, connect_nodes, wait_and_assert_operationid_status
start_node, connect_nodes, wait_and_assert_operationid_status, \
get_coinbase_address
from test_framework.authproxy import JSONRPCException
from decimal import Decimal
@ -43,7 +44,7 @@ class MempoolUpgradeActivationTest(BitcoinTestFramework):
self.sync_all()
# Shield some ZEC
node1_taddr = self.nodes[1].getnewaddress()
node1_taddr = get_coinbase_address(self.nodes[1])
node0_zaddr = self.nodes[0].z_getnewaddress('sprout')
recipients = [{'address': node0_zaddr, 'amount': Decimal('10')}]
myopid = self.nodes[1].z_sendmany(node1_taddr, recipients, 1, Decimal('0'))

View File

@ -8,7 +8,8 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Py
from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.util import assert_equal, initialize_chain_clean, \
start_node, connect_nodes, wait_and_assert_operationid_status
start_node, connect_nodes, wait_and_assert_operationid_status, \
get_coinbase_address
from decimal import Decimal
@ -50,7 +51,7 @@ class MempoolTxInputLimitTest(BitcoinTestFramework):
node0_zaddr = self.nodes[0].z_getnewaddress('sprout')
# Send three inputs from node 0 taddr to zaddr to get out of coinbase
node0_taddr = self.nodes[0].getnewaddress()
node0_taddr = get_coinbase_address(self.nodes[0])
recipients = []
recipients.append({"address":node0_zaddr, "amount":Decimal('30.0')-Decimal('0.0001')}) # utxo amount less fee
myopid = self.nodes[0].z_sendmany(node0_taddr, recipients)

View File

@ -8,7 +8,8 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Py
from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.util import assert_equal, initialize_chain_clean, \
start_node, connect_nodes_bi, wait_and_assert_operationid_status
start_node, connect_nodes_bi, wait_and_assert_operationid_status, \
get_coinbase_address
from decimal import Decimal
@ -48,7 +49,7 @@ class PaymentDisclosureTest (BitcoinTestFramework):
assert_equal(self.nodes[1].getbalance(), 10)
assert_equal(self.nodes[2].getbalance(), 30)
mytaddr = self.nodes[0].getnewaddress()
mytaddr = get_coinbase_address(self.nodes[0])
myzaddr = self.nodes[0].z_getnewaddress('sprout')
# Check that Node 2 has payment disclosure disabled.

View File

@ -27,12 +27,12 @@ class SignOfflineTest (BitcoinTestFramework):
assert_equal(0, len(offline_node.getpeerinfo())) # make sure node 1 has no peers
privkeys = [self.nodes[0].dumpprivkey(self.nodes[0].getnewaddress())]
taddr = self.nodes[0].getnewaddress()
tx = self.nodes[0].listunspent()[0]
txid = tx['txid']
scriptpubkey = tx['scriptPubKey']
privkeys = [self.nodes[0].dumpprivkey(tx['address'])]
create_inputs = [{'txid': txid, 'vout': 0}]
sign_inputs = [{'txid': txid, 'vout': 0, 'scriptPubKey': scriptpubkey, 'amount': 10}]

View File

@ -419,3 +419,19 @@ def wait_and_assert_operationid_status(node, myopid, in_status='success', in_err
return result # if there was an error return the result
else:
return txid # otherwise return the txid
# Find a coinbase address on the node, filtering by the number of UTXOs it has.
# If no filter is provided, returns the coinbase address on the node containing
# the greatest number of spendable UTXOs.
# The default cached chain has one address per coinbase output.
def get_coinbase_address(node, expected_utxos=None):
addrs = [utxo['address'] for utxo in node.listunspent() if utxo['generated']]
assert(len(set(addrs)) > 0)
if expected_utxos is None:
addrs = [(addrs.count(a), a) for a in set(addrs)]
return sorted(addrs, reverse=True)[0][1]
addrs = [a for a in set(addrs) if addrs.count(a) == expected_utxos]
assert(len(addrs) > 0)
return addrs[0]

View File

@ -10,7 +10,8 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Py
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, initialize_chain_clean, \
initialize_datadir, start_nodes, start_node, connect_nodes_bi, \
bitcoind_processes, wait_and_assert_operationid_status
bitcoind_processes, wait_and_assert_operationid_status, \
get_coinbase_address
from decimal import Decimal
@ -48,7 +49,7 @@ class Wallet1941RegressionTest (BitcoinTestFramework):
self.nodes[0].setmocktime(starttime)
self.nodes[0].generate(101)
mytaddr = self.nodes[0].getnewaddress() # where coins were mined
mytaddr = get_coinbase_address(self.nodes[0])
myzaddr = self.nodes[0].z_getnewaddress('sprout')
# Send 10 coins to our zaddr.

View File

@ -8,7 +8,7 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Py
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, initialize_chain_clean, \
start_nodes, stop_nodes, connect_nodes_bi, \
wait_and_assert_operationid_status, wait_bitcoinds
wait_and_assert_operationid_status, wait_bitcoinds, get_coinbase_address
from decimal import Decimal
class WalletAnchorForkTest (BitcoinTestFramework):
@ -45,7 +45,7 @@ class WalletAnchorForkTest (BitcoinTestFramework):
# At this point in time, commitment tree is the empty root
# Node 0 creates a joinsplit transaction
mytaddr0 = self.nodes[0].getnewaddress()
mytaddr0 = get_coinbase_address(self.nodes[0])
myzaddr0 = self.nodes[0].z_getnewaddress('sprout')
recipients = []
recipients.append({"address":myzaddr0, "amount": Decimal('10.0') - Decimal('0.0001')})

View File

@ -6,7 +6,12 @@
import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x."
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, start_nodes, wait_and_assert_operationid_status
from test_framework.util import (
assert_equal,
get_coinbase_address,
start_nodes,
wait_and_assert_operationid_status,
)
from decimal import Decimal
@ -35,12 +40,10 @@ class WalletListNotes(BitcoinTestFramework):
self.sync_all()
assert_equal(201, self.nodes[0].getblockcount())
mining_addr = self.nodes[0].listunspent()[0]['address']
# Shield coinbase funds (must be a multiple of 10, no change allowed pre-sapling)
receive_amount_10 = Decimal('10.0') - Decimal('0.0001')
recipients = [{"address":sproutzaddr, "amount":receive_amount_10}]
myopid = self.nodes[0].z_sendmany(mining_addr, recipients)
myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients)
txid_1 = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
@ -119,7 +122,7 @@ class WalletListNotes(BitcoinTestFramework):
# so send from coin base)
receive_amount_2 = Decimal('2.0') - Decimal('0.0001')
recipients = [{"address": saplingzaddr, "amount":receive_amount_2}]
myopid = self.nodes[0].z_sendmany(mining_addr, recipients)
myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients)
txid_3 = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
unspent_tx = self.nodes[0].z_listunspent(0)

View File

@ -7,7 +7,8 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Py
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_true, bitcoind_processes, \
connect_nodes_bi, start_node, start_nodes, wait_and_assert_operationid_status
connect_nodes_bi, start_node, start_nodes, wait_and_assert_operationid_status, \
get_coinbase_address
from decimal import Decimal
@ -22,7 +23,8 @@ class WalletNullifiersTest (BitcoinTestFramework):
myzaddr0 = self.nodes[0].z_getnewaddress('sprout')
# send node 0 taddr to zaddr to get out of coinbase
mytaddr = self.nodes[0].getnewaddress()
# Tests using the default cached chain have one address per coinbase output
mytaddr = get_coinbase_address(self.nodes[0])
recipients = []
recipients.append({"address":myzaddr0, "amount":Decimal('10.0')-Decimal('0.0001')}) # utxo amount less fee

View File

@ -7,7 +7,8 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Py
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, initialize_chain_clean, \
start_nodes, connect_nodes_bi, wait_and_assert_operationid_status, assert_greater_than
start_nodes, connect_nodes_bi, wait_and_assert_operationid_status, \
assert_greater_than, get_coinbase_address
from test_framework.authproxy import JSONRPCException
from decimal import Decimal
@ -34,7 +35,7 @@ class WalletOverwinterTxTest (BitcoinTestFramework):
self.sync_all()
# Node 0 has reward from blocks 1 to 98 which are spendable.
taddr0 = self.nodes[0].getnewaddress()
taddr0 = get_coinbase_address(self.nodes[0])
taddr1 = self.nodes[1].getnewaddress()
taddr2 = self.nodes[2].getnewaddress()
zaddr2 = self.nodes[2].z_getnewaddress('sprout')

View File

@ -8,6 +8,7 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Py
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal, assert_true,
get_coinbase_address,
start_nodes, stop_nodes,
initialize_chain_clean, connect_nodes_bi, wait_bitcoinds,
wait_and_assert_operationid_status
@ -58,7 +59,7 @@ class WalletPersistenceTest (BitcoinTestFramework):
self.sync_all()
# Node 0 shields funds to Sapling address
taddr0 = self.nodes[0].getnewaddress()
taddr0 = get_coinbase_address(self.nodes[0])
recipients = []
recipients.append({"address": sapling_addr, "amount": Decimal('20')})
myopid = self.nodes[0].z_sendmany(taddr0, recipients, 1, 0)

View File

@ -9,7 +9,8 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.mininode import COIN
from test_framework.util import assert_equal, initialize_chain_clean, \
start_nodes, connect_nodes_bi, wait_and_assert_operationid_status
start_nodes, connect_nodes_bi, wait_and_assert_operationid_status, \
get_coinbase_address
import sys
import timeit
@ -75,7 +76,7 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework):
assert_equal("Coinbase funds can only be sent to a zaddr" in errorString, True)
# Prepare to send taddr->zaddr
mytaddr = self.nodes[0].getnewaddress()
mytaddr = get_coinbase_address(self.nodes[0])
myzaddr = self.nodes[0].z_getnewaddress('sprout')
# Node 3 will test that watch only address utxos are not selected

View File

@ -9,6 +9,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.util import (
assert_equal,
get_coinbase_address,
start_nodes,
wait_and_assert_operationid_status,
)
@ -34,18 +35,18 @@ class WalletSaplingTest(BitcoinTestFramework):
self.sync_all()
# Verify RPCs disallow Sapling value transfer if Sapling is not active
tmp_taddr = self.nodes[3].getnewaddress()
tmp_taddr = get_coinbase_address(self.nodes[3])
tmp_zaddr = self.nodes[3].z_getnewaddress('sapling')
try:
recipients = []
recipients.append({"address": tmp_zaddr, "amount": Decimal('20')})
recipients.append({"address": tmp_zaddr, "amount": Decimal('10')})
self.nodes[3].z_sendmany(tmp_taddr, recipients, 1, 0)
raise AssertionError("Should have thrown an exception")
except JSONRPCException as e:
assert_equal("Invalid parameter, Sapling has not activated", e.error['message'])
try:
recipients = []
recipients.append({"address": tmp_taddr, "amount": Decimal('20')})
recipients.append({"address": tmp_taddr, "amount": Decimal('10')})
self.nodes[3].z_sendmany(tmp_zaddr, recipients, 1, 0)
raise AssertionError("Should have thrown an exception")
except JSONRPCException as e:
@ -75,9 +76,6 @@ class WalletSaplingTest(BitcoinTestFramework):
self.nodes[2].generate(2)
self.sync_all()
taddr0 = self.nodes[0].getnewaddress()
# Skip over the address containing node 1's coinbase
self.nodes[1].getnewaddress()
taddr1 = self.nodes[1].getnewaddress()
saplingAddr0 = self.nodes[0].z_getnewaddress('sapling')
saplingAddr1 = self.nodes[1].z_getnewaddress('sapling')
@ -95,10 +93,9 @@ class WalletSaplingTest(BitcoinTestFramework):
# Node 0 shields some funds
# taddr -> Sapling
# -> taddr (change)
recipients = []
recipients.append({"address": saplingAddr0, "amount": Decimal('20')})
myopid = self.nodes[0].z_sendmany(taddr0, recipients, 1, 0)
recipients.append({"address": saplingAddr0, "amount": Decimal('10')})
myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0)
mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
@ -107,6 +104,11 @@ class WalletSaplingTest(BitcoinTestFramework):
mempool = self.nodes[0].getrawmempool(True)
assert(Decimal(mempool[mytxid]['startingpriority']) == Decimal('1E+16'))
# Shield another coinbase UTXO
myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0)
mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
self.nodes[2].generate(1)
self.sync_all()

View File

@ -9,7 +9,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.util import assert_equal, initialize_chain_clean, \
start_node, connect_nodes_bi, sync_blocks, sync_mempools, \
wait_and_assert_operationid_status
wait_and_assert_operationid_status, get_coinbase_address
from decimal import Decimal
@ -46,17 +46,13 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
print "Mining blocks..."
self.nodes[0].generate(1)
do_not_shield_taddr = self.nodes[0].getnewaddress()
self.nodes[0].generate(4)
walletinfo = self.nodes[0].getwalletinfo()
assert_equal(walletinfo['immature_balance'], 50)
assert_equal(walletinfo['balance'], 0)
self.sync_all()
self.nodes[2].generate(1)
self.nodes[2].getnewaddress()
self.nodes[2].generate(1)
self.nodes[2].getnewaddress()
self.nodes[2].generate(1)
self.sync_all()
self.nodes[1].generate(101)
@ -65,8 +61,10 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
assert_equal(self.nodes[1].getbalance(), 10)
assert_equal(self.nodes[2].getbalance(), 30)
do_not_shield_taddr = get_coinbase_address(self.nodes[0], 1)
# Prepare to send taddr->zaddr
mytaddr = self.nodes[0].getnewaddress()
mytaddr = get_coinbase_address(self.nodes[0], 4)
myzaddr = self.nodes[0].z_getnewaddress(self.addr_type)
# Shielding will fail when trying to spend from watch-only address
@ -145,7 +143,7 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
self.sync_all()
self.nodes[1].generate(100)
self.sync_all()
mytaddr = self.nodes[0].getnewaddress()
mytaddr = get_coinbase_address(self.nodes[0], 800)
def verify_locking(first, second, limit):
result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, limit)
@ -186,7 +184,7 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
if self.addr_type == 'sprout':
# Verify maximum number of utxos which node 2 can shield is limited by option -mempooltxinputlimit
# This option is used when the limit parameter is set to 0.
mytaddr = self.nodes[2].getnewaddress()
mytaddr = get_coinbase_address(self.nodes[2], 20)
result = self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 0)
assert_equal(result["shieldingUTXOs"], Decimal('7'))
assert_equal(result["remainingUTXOs"], Decimal('13'))
@ -198,7 +196,7 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
# Verify maximum number of utxos which node 0 can shield is set by default limit parameter of 50
self.nodes[0].generate(200)
self.sync_all()
mytaddr = self.nodes[0].getnewaddress()
mytaddr = get_coinbase_address(self.nodes[0], 100)
result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'))
assert_equal(result["shieldingUTXOs"], Decimal('50'))
assert_equal(result["remainingUTXOs"], Decimal('50'))

View File

@ -7,7 +7,8 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Py
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, initialize_chain_clean, \
start_nodes, connect_nodes_bi, wait_and_assert_operationid_status
start_nodes, connect_nodes_bi, wait_and_assert_operationid_status, \
get_coinbase_address
import time
from decimal import Decimal
@ -35,7 +36,7 @@ class WalletTreeStateTest (BitcoinTestFramework):
self.nodes[1].generate(101)
self.sync_all()
mytaddr = self.nodes[0].getnewaddress() # where coins were mined
mytaddr = get_coinbase_address(self.nodes[0])
myzaddr = self.nodes[0].z_getnewaddress('sprout')
# Spend coinbase utxos to create three notes of 9.99990000 each

View File

@ -167,8 +167,6 @@ BITCOIN_CORE_H = \
net.h \
netbase.h \
noui.h \
paymentdisclosure.h \
paymentdisclosuredb.h \
policy/fees.h \
pow.h \
prevector.h \
@ -211,6 +209,7 @@ BITCOIN_CORE_H = \
util.h \
utilmoneystr.h \
utilstrencodings.h \
utiltest.h \
utiltime.h \
validationinterface.h \
version.h \
@ -219,6 +218,8 @@ BITCOIN_CORE_H = \
wallet/asyncrpcoperation_shieldcoinbase.h \
wallet/crypter.h \
wallet/db.h \
wallet/paymentdisclosure.h \
wallet/paymentdisclosuredb.h \
wallet/rpcwallet.h \
wallet/wallet.h \
wallet/wallet_ismine.h \
@ -259,8 +260,6 @@ libbitcoin_server_a_SOURCES = \
miner.cpp \
net.cpp \
noui.cpp \
paymentdisclosure.cpp \
paymentdisclosuredb.cpp \
policy/fees.cpp \
pow.cpp \
rest.cpp \
@ -301,8 +300,6 @@ endif
libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_wallet_a_SOURCES = \
utiltest.cpp \
utiltest.h \
zcbenchmarks.cpp \
zcbenchmarks.h \
wallet/asyncrpcoperation_mergetoaddress.cpp \
@ -310,8 +307,8 @@ libbitcoin_wallet_a_SOURCES = \
wallet/asyncrpcoperation_shieldcoinbase.cpp \
wallet/crypter.cpp \
wallet/db.cpp \
paymentdisclosure.cpp \
paymentdisclosuredb.cpp \
wallet/paymentdisclosure.cpp \
wallet/paymentdisclosuredb.cpp \
wallet/rpcdisclosure.cpp \
wallet/rpcdump.cpp \
wallet/rpcwallet.cpp \
@ -384,6 +381,7 @@ libbitcoin_common_a_SOURCES = \
script/sign.cpp \
script/standard.cpp \
transaction_builder.cpp \
utiltest.cpp \
$(BITCOIN_CORE_H) \
$(LIBZCASH_H)

View File

@ -42,12 +42,12 @@ zcash_gtest_SOURCES += \
gtest/test_txid.cpp \
gtest/test_libzcash_utils.cpp \
gtest/test_proofs.cpp \
gtest/test_paymentdisclosure.cpp \
gtest/test_pedersen_hash.cpp \
gtest/test_checkblock.cpp \
gtest/test_zip32.cpp
if ENABLE_WALLET
zcash_gtest_SOURCES += \
wallet/gtest/test_paymentdisclosure.cpp \
wallet/gtest/test_wallet.cpp
endif

View File

@ -5,99 +5,70 @@
#include "key.h"
#include "miner.h"
#include "util.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#endif
#include <boost/optional.hpp>
using ::testing::Return;
#ifdef ENABLE_WALLET
class MockReserveKey : public CReserveKey {
public:
MockReserveKey() : CReserveKey(nullptr) { }
MOCK_METHOD1(GetReservedKey, bool(CPubKey &pubkey));
};
#endif
TEST(Miner, GetMinerScriptPubKey) {
TEST(Miner, GetScriptForMinerAddress) {
SelectParams(CBaseChainParams::MAIN);
boost::optional<CScript> scriptPubKey;
#ifdef ENABLE_WALLET
MockReserveKey reservekey;
EXPECT_CALL(reservekey, GetReservedKey(::testing::_))
.WillRepeatedly(Return(false));
#endif
// No miner address set
#ifdef ENABLE_WALLET
scriptPubKey = GetMinerScriptPubKey(reservekey);
#else
scriptPubKey = GetMinerScriptPubKey();
#endif
EXPECT_FALSE((bool) scriptPubKey);
{
boost::shared_ptr<CReserveScript> coinbaseScript;
GetScriptForMinerAddress(coinbaseScript);
EXPECT_FALSE((bool) coinbaseScript);
}
mapArgs["-mineraddress"] = "notAnAddress";
#ifdef ENABLE_WALLET
scriptPubKey = GetMinerScriptPubKey(reservekey);
#else
scriptPubKey = GetMinerScriptPubKey();
#endif
EXPECT_FALSE((bool) scriptPubKey);
{
boost::shared_ptr<CReserveScript> coinbaseScript;
GetScriptForMinerAddress(coinbaseScript);
EXPECT_FALSE((bool) coinbaseScript);
}
// Partial address
mapArgs["-mineraddress"] = "t1T8yaLVhNqxA5KJcmiqq";
#ifdef ENABLE_WALLET
scriptPubKey = GetMinerScriptPubKey(reservekey);
#else
scriptPubKey = GetMinerScriptPubKey();
#endif
EXPECT_FALSE((bool) scriptPubKey);
{
boost::shared_ptr<CReserveScript> coinbaseScript;
GetScriptForMinerAddress(coinbaseScript);
EXPECT_FALSE((bool) coinbaseScript);
}
// Typo in address
mapArgs["-mineraddress"] = "t1TByaLVhNqxA5KJcmiqqFN88e8DNp2PBfF";
#ifdef ENABLE_WALLET
scriptPubKey = GetMinerScriptPubKey(reservekey);
#else
scriptPubKey = GetMinerScriptPubKey();
#endif
EXPECT_FALSE((bool) scriptPubKey);
{
boost::shared_ptr<CReserveScript> coinbaseScript;
GetScriptForMinerAddress(coinbaseScript);
EXPECT_FALSE((bool) coinbaseScript);
}
// Set up expected scriptPubKey for t1T8yaLVhNqxA5KJcmiqqFN88e8DNp2PBfF
CKeyID keyID;
keyID.SetHex("eb88f1c65b39a823479ac9c7db2f4a865960a165");
CScript expectedScriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
CScript expectedCoinbaseScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
// Valid address
mapArgs["-mineraddress"] = "t1T8yaLVhNqxA5KJcmiqqFN88e8DNp2PBfF";
#ifdef ENABLE_WALLET
scriptPubKey = GetMinerScriptPubKey(reservekey);
#else
scriptPubKey = GetMinerScriptPubKey();
#endif
EXPECT_TRUE((bool) scriptPubKey);
EXPECT_EQ(expectedScriptPubKey, *scriptPubKey);
{
boost::shared_ptr<CReserveScript> coinbaseScript;
GetScriptForMinerAddress(coinbaseScript);
EXPECT_TRUE((bool) coinbaseScript);
EXPECT_EQ(expectedCoinbaseScript, coinbaseScript->reserveScript);
}
// Valid address with leading whitespace
mapArgs["-mineraddress"] = " t1T8yaLVhNqxA5KJcmiqqFN88e8DNp2PBfF";
#ifdef ENABLE_WALLET
scriptPubKey = GetMinerScriptPubKey(reservekey);
#else
scriptPubKey = GetMinerScriptPubKey();
#endif
EXPECT_TRUE((bool) scriptPubKey);
EXPECT_EQ(expectedScriptPubKey, *scriptPubKey);
{
boost::shared_ptr<CReserveScript> coinbaseScript;
GetScriptForMinerAddress(coinbaseScript);
EXPECT_TRUE((bool) coinbaseScript);
EXPECT_EQ(expectedCoinbaseScript, coinbaseScript->reserveScript);
}
// Valid address with trailing whitespace
mapArgs["-mineraddress"] = "t1T8yaLVhNqxA5KJcmiqqFN88e8DNp2PBfF ";
#ifdef ENABLE_WALLET
scriptPubKey = GetMinerScriptPubKey(reservekey);
#else
scriptPubKey = GetMinerScriptPubKey();
#endif
EXPECT_TRUE((bool) scriptPubKey);
EXPECT_EQ(expectedScriptPubKey, *scriptPubKey);
{
boost::shared_ptr<CReserveScript> coinbaseScript;
GetScriptForMinerAddress(coinbaseScript);
EXPECT_TRUE((bool) coinbaseScript);
EXPECT_EQ(expectedCoinbaseScript, coinbaseScript->reserveScript);
}
}

View File

@ -204,11 +204,7 @@ void Shutdown()
pwalletMain->Flush(false);
#endif
#ifdef ENABLE_MINING
#ifdef ENABLE_WALLET
GenerateBitcoins(false, NULL, 0);
#else
GenerateBitcoins(false, 0);
#endif
GenerateBitcoins(false, 0, Params());
#endif
StopNode();
StopTorControl();
@ -1741,7 +1737,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#ifdef ENABLE_WALLET
bool minerAddressInLocalWallet = false;
if (pwalletMain) {
// Address has alreday been validated
// Address has already been validated
CTxDestination addr = DecodeDestination(mapArgs["-mineraddress"]);
CKeyID keyID = boost::get<CKeyID>(addr);
minerAddressInLocalWallet = pwalletMain->HaveKey(keyID);
@ -1750,6 +1746,22 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
return InitError(_("-mineraddress is not in the local wallet. Either use a local address, or set -minetolocalwallet=0"));
}
#endif // ENABLE_WALLET
// This is leveraging the fact that boost::signals2 executes connected
// handlers in-order. Further up, the wallet is connected to this signal
// if the wallet is enabled. The wallet's ScriptForMining handler does
// nothing if -mineraddress is set, and GetScriptForMinerAddress() does
// nothing if -mineraddress is not set (or set to an invalid address).
//
// The upshot is that when ScriptForMining(script) is called:
// - If -mineraddress is set (whether or not the wallet is enabled), the
// CScript argument is set to -mineraddress.
// - If the wallet is enabled and -mineraddress is not set, the CScript
// argument is set to a wallet address.
// - If the wallet is disabled and -mineraddress is not set, the CScript
// argument is not modified; in practice this means it is empty, and
// GenerateBitcoins() returns an error.
GetMainSignals().ScriptForMining.connect(GetScriptForMinerAddress);
}
#endif // ENABLE_MINING
@ -1820,12 +1832,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#ifdef ENABLE_MINING
// Generate coins in the background
#ifdef ENABLE_WALLET
if (pwalletMain || !GetArg("-mineraddress", "").empty())
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
#else
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1));
#endif
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params());
#endif
// ********************************************************* Step 11: finished

View File

@ -28,9 +28,7 @@
#include "ui_interface.h"
#include "util.h"
#include "utilmoneystr.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#endif
#include "validationinterface.h"
#include "sodium.h"
@ -400,48 +398,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
return pblocktemplate.release();
}
#ifdef ENABLE_WALLET
boost::optional<CScript> GetMinerScriptPubKey(CReserveKey& reservekey)
#else
boost::optional<CScript> GetMinerScriptPubKey()
#endif
{
CKeyID keyID;
CTxDestination addr = DecodeDestination(GetArg("-mineraddress", ""));
if (IsValidDestination(addr)) {
keyID = boost::get<CKeyID>(addr);
} else {
#ifdef ENABLE_WALLET
CPubKey pubkey;
if (!reservekey.GetReservedKey(pubkey)) {
return boost::optional<CScript>();
}
keyID = pubkey.GetID();
#else
return boost::optional<CScript>();
#endif
}
CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
return scriptPubKey;
}
#ifdef ENABLE_WALLET
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
{
boost::optional<CScript> scriptPubKey = GetMinerScriptPubKey(reservekey);
#else
CBlockTemplate* CreateNewBlockWithKey()
{
boost::optional<CScript> scriptPubKey = GetMinerScriptPubKey();
#endif
if (!scriptPubKey) {
return NULL;
}
return CreateNewBlock(*scriptPubKey);
}
//////////////////////////////////////////////////////////////////////////////
//
// Internal miner
@ -449,6 +405,30 @@ CBlockTemplate* CreateNewBlockWithKey()
#ifdef ENABLE_MINING
class MinerAddressScript : public CReserveScript
{
// CReserveScript requires implementing this function, so that if an
// internal (not-visible) wallet address is used, the wallet can mark it as
// important when a block is mined (so it then appears to the user).
// If -mineraddress is set, the user already knows about and is managing the
// address, so we don't need to do anything here.
void KeepScript() {}
};
void GetScriptForMinerAddress(boost::shared_ptr<CReserveScript> &script)
{
CTxDestination addr = DecodeDestination(GetArg("-mineraddress", ""));
if (!IsValidDestination(addr)) {
return;
}
boost::shared_ptr<MinerAddressScript> mAddr(new MinerAddressScript());
CKeyID keyID = boost::get<CKeyID>(addr);
script = mAddr;
script->reserveScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
}
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
{
// Update nExtraNonce
@ -468,11 +448,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
}
#ifdef ENABLE_WALLET
static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
#else
static bool ProcessBlockFound(CBlock* pblock)
#endif // ENABLE_WALLET
static bool ProcessBlockFound(CBlock* pblock, const CChainParams& chainparams)
{
LogPrintf("%s\n", pblock->ToString());
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
@ -484,18 +460,8 @@ static bool ProcessBlockFound(CBlock* pblock)
return error("ZcashMiner: generated block is stale");
}
#ifdef ENABLE_WALLET
if (GetArg("-mineraddress", "").empty()) {
// Remove key from key pool
reservekey.KeepKey();
}
// Track how many getdata requests this block gets
{
LOCK(wallet.cs_wallet);
wallet.mapRequestCount[pblock->GetHash()] = 0;
}
#endif
// Inform about the new block
GetMainSignals().BlockFound(pblock->GetHash());
// Process this block the same as if we had received it from another node
CValidationState state;
@ -507,25 +473,18 @@ static bool ProcessBlockFound(CBlock* pblock)
return true;
}
#ifdef ENABLE_WALLET
void static BitcoinMiner(CWallet *pwallet)
#else
void static BitcoinMiner()
#endif
void static BitcoinMiner(const CChainParams& chainparams)
{
LogPrintf("ZcashMiner started\n");
SetThreadPriority(THREAD_PRIORITY_LOWEST);
RenameThread("zcash-miner");
const CChainParams& chainparams = Params();
#ifdef ENABLE_WALLET
// Each thread has its own key
CReserveKey reservekey(pwallet);
#endif
// Each thread has its own counter
unsigned int nExtraNonce = 0;
boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript);
unsigned int n = chainparams.EquihashN();
unsigned int k = chainparams.EquihashK();
@ -544,6 +503,10 @@ void static BitcoinMiner()
miningTimer.start();
try {
//throw an error if no script was provided
if (!coinbaseScript->reserveScript.size())
throw std::runtime_error("No coinbase script available (mining requires a wallet or -mineraddress)");
while (true) {
if (chainparams.MiningRequiresPeers()) {
// Busy-wait for the network to come online so we don't waste time mining
@ -568,11 +531,7 @@ void static BitcoinMiner()
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrev = chainActive.Tip();
#ifdef ENABLE_WALLET
unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
#else
unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey());
#endif
unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript));
if (!pblocktemplate.get())
{
if (GetArg("-mineraddress", "").empty()) {
@ -620,11 +579,7 @@ void static BitcoinMiner()
solver, pblock->nNonce.ToString());
std::function<bool(std::vector<unsigned char>)> validBlock =
#ifdef ENABLE_WALLET
[&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
#else
[&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams]
#endif
[&pblock, &hashTarget, &chainparams, &m_cs, &cancelSolver, &coinbaseScript]
(std::vector<unsigned char> soln) {
// Write the solution to the hash and compute the result.
LogPrint("pow", "- Checking solution against target\n");
@ -639,17 +594,13 @@ void static BitcoinMiner()
SetThreadPriority(THREAD_PRIORITY_NORMAL);
LogPrintf("ZcashMiner:\n");
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
#ifdef ENABLE_WALLET
if (ProcessBlockFound(pblock, *pwallet, reservekey))
#else
if (ProcessBlockFound(pblock))
#endif
{
if (ProcessBlockFound(pblock, chainparams)) {
// Ignore chain updates caused by us
std::lock_guard<std::mutex> lock{m_cs};
cancelSolver = false;
}
SetThreadPriority(THREAD_PRIORITY_LOWEST);
coinbaseScript->KeepScript();
// In regression test mode, stop mining after a block is found.
if (chainparams.MineBlocksOnDemand()) {
@ -754,11 +705,7 @@ void static BitcoinMiner()
c.disconnect();
}
#ifdef ENABLE_WALLET
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
#else
void GenerateBitcoins(bool fGenerate, int nThreads)
#endif
void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams)
{
static boost::thread_group* minerThreads = NULL;
@ -778,11 +725,7 @@ void GenerateBitcoins(bool fGenerate, int nThreads)
minerThreads = new boost::thread_group();
for (int i = 0; i < nThreads; i++) {
#ifdef ENABLE_WALLET
minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
#else
minerThreads->create_thread(&BitcoinMiner);
#endif
minerThreads->create_thread(boost::bind(&BitcoinMiner, boost::cref(chainparams)));
}
}

View File

@ -12,11 +12,8 @@
#include <stdint.h>
class CBlockIndex;
class CChainParams;
class CScript;
#ifdef ENABLE_WALLET
class CReserveKey;
class CWallet;
#endif
namespace Consensus { struct Params; };
struct CBlockTemplate
@ -28,23 +25,14 @@ struct CBlockTemplate
/** Generate a new block, without valid proof-of-work */
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
#ifdef ENABLE_WALLET
boost::optional<CScript> GetMinerScriptPubKey(CReserveKey& reservekey);
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
#else
boost::optional<CScript> GetMinerScriptPubKey();
CBlockTemplate* CreateNewBlockWithKey();
#endif
#ifdef ENABLE_MINING
/** Get script for -mineraddress */
void GetScriptForMinerAddress(boost::shared_ptr<CReserveScript> &script);
/** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
/** Run the miner threads */
#ifdef ENABLE_WALLET
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
#else
void GenerateBitcoins(bool fGenerate, int nThreads);
#endif
void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams);
#endif
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);

View File

@ -21,13 +21,11 @@
#include "txmempool.h"
#include "util.h"
#include "validationinterface.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#endif
#include <stdint.h>
#include <boost/assign/list_of.hpp>
#include <boost/shared_ptr.hpp>
#include <univalue.h>
@ -174,15 +172,6 @@ UniValue generate(const UniValue& params, bool fHelp)
+ HelpExampleCli("generate", "11")
);
if (GetArg("-mineraddress", "").empty()) {
#ifdef ENABLE_WALLET
if (!pwalletMain) {
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set");
}
#else
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "zcashd compiled without wallet and -mineraddress not set");
#endif
}
if (!Params().MineBlocksOnDemand())
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest");
@ -190,9 +179,13 @@ UniValue generate(const UniValue& params, bool fHelp)
int nHeightEnd = 0;
int nHeight = 0;
int nGenerate = params[0].get_int();
#ifdef ENABLE_WALLET
CReserveKey reservekey(pwalletMain);
#endif
boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript);
//throw an error if no script was provided
if (!coinbaseScript->reserveScript.size())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet or -mineraddress)");
{ // Don't keep cs_main locked
LOCK(cs_main);
@ -206,13 +199,9 @@ UniValue generate(const UniValue& params, bool fHelp)
unsigned int k = Params().EquihashK();
while (nHeight < nHeightEnd)
{
#ifdef ENABLE_WALLET
std::unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
#else
std::unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey());
#endif
std::unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript));
if (!pblocktemplate.get())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
CBlock *pblock = &pblocktemplate->block;
{
LOCK(cs_main);
@ -262,11 +251,13 @@ endloop:
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
++nHeight;
blockHashes.push_back(pblock->GetHash().GetHex());
//mark script as important because it was used at least for one coinbase output
coinbaseScript->KeepScript();
}
return blockHashes;
}
UniValue setgenerate(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
@ -289,15 +280,6 @@ UniValue setgenerate(const UniValue& params, bool fHelp)
+ HelpExampleRpc("setgenerate", "true, 1")
);
if (GetArg("-mineraddress", "").empty()) {
#ifdef ENABLE_WALLET
if (!pwalletMain) {
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set");
}
#else
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "zcashd compiled without wallet and -mineraddress not set");
#endif
}
if (Params().MineBlocksOnDemand())
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network");
@ -315,17 +297,12 @@ UniValue setgenerate(const UniValue& params, bool fHelp)
mapArgs["-gen"] = (fGenerate ? "1" : "0");
mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
#ifdef ENABLE_WALLET
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
#else
GenerateBitcoins(fGenerate, nGenProcLimit);
#endif
GenerateBitcoins(fGenerate, nGenProcLimit, Params());
return NullUniValue;
}
#endif
UniValue getmininginfo(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
@ -629,16 +606,22 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
delete pblocktemplate;
pblocktemplate = NULL;
}
#ifdef ENABLE_WALLET
CReserveKey reservekey(pwalletMain);
pblocktemplate = CreateNewBlockWithKey(reservekey);
#else
pblocktemplate = CreateNewBlockWithKey();
#endif
boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript);
// Throw an error if no script was provided
if (!coinbaseScript->reserveScript.size())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet or -mineraddress)");
pblocktemplate = CreateNewBlock(coinbaseScript->reserveScript);
if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
// Need to update only after we know CreateNewBlockWithKey succeeded
// Mark script as important because it was used at least for one coinbase output
coinbaseScript->KeepScript();
// Need to update only after we know CreateNewBlock succeeded
pindexPrev = pindexPrevNew;
}
CBlock* pblock = &pblocktemplate->block; // pointer for convenience

View File

@ -587,4 +587,13 @@ public:
}
};
class CReserveScript
{
public:
CScript reserveScript;
virtual void KeepScript() {}
CReserveScript() {}
virtual ~CReserveScript() {}
};
#endif // BITCOIN_SCRIPT_SCRIPT_H

View File

@ -22,9 +22,13 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1));
g_signals.BlockFound.connect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1));
}
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.BlockFound.disconnect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1));
g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1));
g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
@ -37,6 +41,8 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
}
void UnregisterAllValidationInterfaces() {
g_signals.BlockFound.disconnect_all_slots();
g_signals.ScriptForMining.disconnect_all_slots();
g_signals.BlockChecked.disconnect_all_slots();
g_signals.Broadcast.disconnect_all_slots();
g_signals.Inventory.disconnect_all_slots();

View File

@ -7,12 +7,14 @@
#define BITCOIN_VALIDATIONINTERFACE_H
#include <boost/signals2/signal.hpp>
#include <boost/shared_ptr.hpp>
#include "zcash/IncrementalMerkleTree.hpp"
class CBlock;
class CBlockIndex;
struct CBlockLocator;
class CReserveScript;
class CTransaction;
class CValidationInterface;
class CValidationState;
@ -40,6 +42,8 @@ protected:
virtual void Inventory(const uint256 &hash) {}
virtual void ResendWalletTransactions(int64_t nBestBlockTime) {}
virtual void BlockChecked(const CBlock&, const CValidationState&) {}
virtual void GetScriptForMining(boost::shared_ptr<CReserveScript>&) {};
virtual void ResetRequestCount(const uint256 &hash) {};
friend void ::RegisterValidationInterface(CValidationInterface*);
friend void ::UnregisterValidationInterface(CValidationInterface*);
friend void ::UnregisterAllValidationInterfaces();
@ -64,6 +68,10 @@ struct CMainSignals {
boost::signals2::signal<void (int64_t nBestBlockTime)> Broadcast;
/** Notifies listeners of a block validation result */
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
/** Notifies listeners that a key for mining is required (coinbase) */
boost::signals2::signal<void (boost::shared_ptr<CReserveScript>&)> ScriptForMining;
/** Notifies listeners that a block has been successfully mined */
boost::signals2::signal<void (const uint256 &)> BlockFound;
};
CMainSignals& GetMainSignals();

View File

@ -23,6 +23,7 @@
#include "utiltime.h"
#include "wallet.h"
#include "walletdb.h"
#include "wallet/paymentdisclosuredb.h"
#include "zcash/IncrementalMerkleTree.hpp"
#include <chrono>
@ -30,8 +31,6 @@
#include <string>
#include <thread>
#include "paymentdisclosuredb.h"
using namespace libzcash;
extern UniValue sendrawtransaction(const UniValue& params, bool fHelp);
@ -139,11 +138,7 @@ void AsyncRPCOperation_mergetoaddress::main()
bool success = false;
#ifdef ENABLE_MINING
#ifdef ENABLE_WALLET
GenerateBitcoins(false, NULL, 0);
#else
GenerateBitcoins(false, 0);
#endif
GenerateBitcoins(false, 0, Params());
#endif
try {
@ -168,11 +163,7 @@ void AsyncRPCOperation_mergetoaddress::main()
}
#ifdef ENABLE_MINING
#ifdef ENABLE_WALLET
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
#else
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1));
#endif
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params());
#endif
stop_execution_clock();

View File

@ -7,10 +7,10 @@
#include "amount.h"
#include "asyncrpcoperation.h"
#include "paymentdisclosure.h"
#include "primitives/transaction.h"
#include "transaction_builder.h"
#include "wallet.h"
#include "wallet/paymentdisclosure.h"
#include "zcash/Address.hpp"
#include "zcash/JoinSplit.hpp"

View File

@ -24,6 +24,7 @@
#include "zcash/IncrementalMerkleTree.hpp"
#include "sodium.h"
#include "miner.h"
#include "wallet/paymentdisclosuredb.h"
#include <array>
#include <iostream>
@ -31,8 +32,6 @@
#include <thread>
#include <string>
#include "paymentdisclosuredb.h"
using namespace libzcash;
extern UniValue signrawtransaction(const UniValue& params, bool fHelp);
@ -135,11 +134,7 @@ void AsyncRPCOperation_sendmany::main() {
bool success = false;
#ifdef ENABLE_MINING
#ifdef ENABLE_WALLET
GenerateBitcoins(false, NULL, 0);
#else
GenerateBitcoins(false, 0);
#endif
GenerateBitcoins(false, 0, Params());
#endif
try {
@ -164,11 +159,7 @@ void AsyncRPCOperation_sendmany::main() {
}
#ifdef ENABLE_MINING
#ifdef ENABLE_WALLET
GenerateBitcoins(GetBoolArg("-gen",false), pwalletMain, GetArg("-genproclimit", 1));
#else
GenerateBitcoins(GetBoolArg("-gen",false), GetArg("-genproclimit", 1));
#endif
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params());
#endif
stop_execution_clock();

View File

@ -12,7 +12,7 @@
#include "zcash/JoinSplit.hpp"
#include "zcash/Address.hpp"
#include "wallet.h"
#include "paymentdisclosure.h"
#include "wallet/paymentdisclosure.h"
#include <array>
#include <unordered_map>

View File

@ -23,6 +23,7 @@
#include "zcash/IncrementalMerkleTree.hpp"
#include "sodium.h"
#include "miner.h"
#include "wallet/paymentdisclosuredb.h"
#include <array>
#include <iostream>
@ -32,9 +33,6 @@
#include "asyncrpcoperation_shieldcoinbase.h"
#include "paymentdisclosure.h"
#include "paymentdisclosuredb.h"
using namespace libzcash;
static int find_output(UniValue obj, int n) {
@ -110,11 +108,7 @@ void AsyncRPCOperation_shieldcoinbase::main() {
bool success = false;
#ifdef ENABLE_MINING
#ifdef ENABLE_WALLET
GenerateBitcoins(false, NULL, 0);
#else
GenerateBitcoins(false, 0);
#endif
GenerateBitcoins(false, 0, Params());
#endif
try {
@ -139,11 +133,7 @@ void AsyncRPCOperation_shieldcoinbase::main() {
}
#ifdef ENABLE_MINING
#ifdef ENABLE_WALLET
GenerateBitcoins(GetBoolArg("-gen",false), pwalletMain, GetArg("-genproclimit", 1));
#else
GenerateBitcoins(GetBoolArg("-gen",false), GetArg("-genproclimit", 1));
#endif
GenerateBitcoins(GetBoolArg("-gen",false), GetArg("-genproclimit", 1), Params());
#endif
stop_execution_clock();

View File

@ -12,14 +12,13 @@
#include "zcash/JoinSplit.hpp"
#include "zcash/Address.hpp"
#include "wallet.h"
#include "wallet/paymentdisclosure.h"
#include <unordered_map>
#include <tuple>
#include <univalue.h>
#include "paymentdisclosure.h"
// Default transaction fee if caller does not specify one.
#define SHIELD_COINBASE_DEFAULT_MINERS_FEE 10000

View File

@ -17,8 +17,8 @@
#include <iostream>
#include "util.h"
#include "paymentdisclosure.h"
#include "paymentdisclosuredb.h"
#include "wallet/paymentdisclosure.h"
#include "wallet/paymentdisclosuredb.h"
#include "sodium.h"

View File

@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "paymentdisclosure.h"
#include "wallet/paymentdisclosure.h"
#include "key_io.h"
#include "util.h"

View File

@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "paymentdisclosuredb.h"
#include "wallet/paymentdisclosuredb.h"
#include "util.h"
#include "dbwrapper.h"

View File

@ -5,7 +5,7 @@
#ifndef ZCASH_PAYMENTDISCLOSUREDB_H
#define ZCASH_PAYMENTDISCLOSUREDB_H
#include "paymentdisclosure.h"
#include <wallet/paymentdisclosure.h>
#include <cstdint>
#include <string>

View File

@ -12,6 +12,8 @@
#include "util.h"
#include "utiltime.h"
#include "wallet.h"
#include "wallet/paymentdisclosure.h"
#include "wallet/paymentdisclosuredb.h"
#include <fstream>
#include <stdint.h>
@ -21,9 +23,6 @@
#include <univalue.h>
#include "paymentdisclosure.h"
#include "paymentdisclosuredb.h"
#include "zcash/Note.hpp"
#include "zcash/NoteEncryption.hpp"

View File

@ -4039,6 +4039,21 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx)
}
}
void CWallet::GetScriptForMining(boost::shared_ptr<CReserveScript> &script)
{
if (!GetArg("-mineraddress", "").empty()) {
return;
}
boost::shared_ptr<CReserveKey> rKey(new CReserveKey(this));
CPubKey pubkey;
if (!rKey->GetReservedKey(pubkey))
return;
script = rKey;
script->reserveScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
}
void CWallet::LockCoin(COutPoint& output)
{
AssertLockHeld(cs_wallet); // setLockedCoins

View File

@ -35,6 +35,8 @@
#include <utility>
#include <vector>
#include <boost/shared_ptr.hpp>
/**
* Settings
*/
@ -1206,6 +1208,13 @@ public:
}
}
void GetScriptForMining(boost::shared_ptr<CReserveScript> &script);
void ResetRequestCount(const uint256 &hash)
{
LOCK(cs_wallet);
mapRequestCount[hash] = 0;
};
unsigned int GetKeyPoolSize()
{
AssertLockHeld(cs_wallet); // setKeyPool
@ -1301,7 +1310,7 @@ public:
};
/** A key allocated from the key pool. */
class CReserveKey
class CReserveKey : public CReserveScript
{
protected:
CWallet* pwallet;
@ -1322,6 +1331,7 @@ public:
void ReturnKey();
virtual bool GetReservedKey(CPubKey &pubkey);
void KeepKey();
void KeepScript() { KeepKey(); }
};

View File

@ -44,7 +44,7 @@ void pre_wallet_load()
if (pwalletMain)
pwalletMain->Flush(false);
#ifdef ENABLE_MINING
GenerateBitcoins(false, NULL, 0);
GenerateBitcoins(false, 0, Params());
#endif
UnregisterNodeSignals(GetNodeSignals());
if (pwalletMain)
@ -63,7 +63,7 @@ void post_wallet_load(){
#ifdef ENABLE_MINING
// Generate coins in the background
if (pwalletMain || !GetArg("-mineraddress", "").empty())
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params());
#endif
}