Use `std::optional` in `CValidationInterface::GetAddressForMining`

The initial value for the provided return value is now `std::nullopt`
instead of the default value of the `MinerAddress` variant. This makes
it easier to distinguish "no miner address was provided" from "invalid
miner address".
This commit is contained in:
Jack Grigg 2022-02-25 16:06:51 +00:00
parent 1732a50957
commit 1c31a1c7d8
6 changed files with 25 additions and 18 deletions

View File

@ -726,7 +726,7 @@ std::optional<MinerAddress> ExtractMinerAddress::operator()(const libzcash::Unif
} }
void GetMinerAddress(MinerAddress &minerAddress) void GetMinerAddress(std::optional<MinerAddress> &minerAddress)
{ {
KeyIO keyIO(Params()); KeyIO keyIO(Params());
@ -804,8 +804,8 @@ void static BitcoinMiner(const CChainParams& chainparams)
// Each thread has its own counter // Each thread has its own counter
unsigned int nExtraNonce = 0; unsigned int nExtraNonce = 0;
MinerAddress minerAddress; std::optional<MinerAddress> maybeMinerAddress;
GetMainSignals().AddressForMining(minerAddress); GetMainSignals().AddressForMining(maybeMinerAddress);
unsigned int n = chainparams.GetConsensus().nEquihashN; unsigned int n = chainparams.GetConsensus().nEquihashN;
unsigned int k = chainparams.GetConsensus().nEquihashK; unsigned int k = chainparams.GetConsensus().nEquihashK;
@ -826,9 +826,10 @@ void static BitcoinMiner(const CChainParams& chainparams)
try { try {
// Throw an error if no address valid for mining was provided. // Throw an error if no address valid for mining was provided.
if (!std::visit(IsValidMinerAddress(), minerAddress)) { if (!(maybeMinerAddress.has_value() && std::visit(IsValidMinerAddress(), maybeMinerAddress.value()))) {
throw std::runtime_error("No miner address available (mining requires a wallet or -mineraddress)"); throw std::runtime_error("No miner address available (mining requires a wallet or -mineraddress)");
} }
auto minerAddress = maybeMinerAddress.value();
while (true) { while (true) {
if (chainparams.MiningRequiresPeers()) { if (chainparams.MiningRequiresPeers()) {

View File

@ -89,7 +89,7 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const MinerAddre
#ifdef ENABLE_MINING #ifdef ENABLE_MINING
/** Get -mineraddress */ /** Get -mineraddress */
void GetMinerAddress(MinerAddress &minerAddress); void GetMinerAddress(std::optional<MinerAddress> &minerAddress);
/** Modify the extranonce in a block */ /** Modify the extranonce in a block */
void IncrementExtraNonce( void IncrementExtraNonce(
CBlockTemplate* pblocktemplate, CBlockTemplate* pblocktemplate,

View File

@ -186,8 +186,14 @@ UniValue generate(const UniValue& params, bool fHelp)
int nHeight = 0; int nHeight = 0;
int nGenerate = params[0].get_int(); int nGenerate = params[0].get_int();
MinerAddress minerAddress; std::optional<MinerAddress> maybeMinerAddress;
GetMainSignals().AddressForMining(minerAddress); GetMainSignals().AddressForMining(maybeMinerAddress);
// Throw an error if no address valid for mining was provided.
if (!(maybeMinerAddress.has_value() && std::visit(IsValidMinerAddress(), maybeMinerAddress.value()))) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "No miner address available (mining requires a wallet or -mineraddress)");
}
auto minerAddress = maybeMinerAddress.value();
// If the keypool is exhausted, no script is returned at all. Catch this. // If the keypool is exhausted, no script is returned at all. Catch this.
auto resv = std::get_if<boost::shared_ptr<CReserveScript>>(&minerAddress); auto resv = std::get_if<boost::shared_ptr<CReserveScript>>(&minerAddress);
@ -195,11 +201,6 @@ UniValue generate(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
} }
// Throw an error if no address valid for mining was provided.
if (!std::visit(IsValidMinerAddress(), minerAddress)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "No miner address available (mining requires a wallet or -mineraddress)");
}
{ // Don't keep cs_main locked { // Don't keep cs_main locked
LOCK(cs_main); LOCK(cs_main);
nHeightStart = chainActive.Height(); nHeightStart = chainActive.Height();
@ -569,9 +570,14 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
if (IsInitialBlockDownload(Params().GetConsensus())) if (IsInitialBlockDownload(Params().GetConsensus()))
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Zcash is downloading blocks..."); throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Zcash is downloading blocks...");
std::optional<MinerAddress> maybeMinerAddress;
GetMainSignals().AddressForMining(maybeMinerAddress);
MinerAddress minerAddress; // Throw an error if no address valid for mining was provided.
GetMainSignals().AddressForMining(minerAddress); if (!(maybeMinerAddress.has_value() && std::visit(IsValidMinerAddress(), maybeMinerAddress.value()))) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "No miner address available (getblocktemplate requires a wallet or -mineraddress)");
}
auto minerAddress = maybeMinerAddress.value();
static unsigned int nTransactionsUpdatedLast; static unsigned int nTransactionsUpdatedLast;
static std::optional<CMutableTransaction> cached_next_cb_mtx; static std::optional<CMutableTransaction> cached_next_cb_mtx;

View File

@ -42,7 +42,7 @@ protected:
virtual void Inventory(const uint256 &hash) {} virtual void Inventory(const uint256 &hash) {}
virtual void ResendWalletTransactions(int64_t nBestBlockTime) {} virtual void ResendWalletTransactions(int64_t nBestBlockTime) {}
virtual void BlockChecked(const CBlock&, const CValidationState&) {} virtual void BlockChecked(const CBlock&, const CValidationState&) {}
virtual void GetAddressForMining(MinerAddress&) {}; virtual void GetAddressForMining(std::optional<MinerAddress>&) {};
virtual void ResetRequestCount(const uint256 &hash) {}; virtual void ResetRequestCount(const uint256 &hash) {};
friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::RegisterValidationInterface(CValidationInterface*);
friend void ::UnregisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*);
@ -67,7 +67,7 @@ struct CMainSignals {
/** Notifies listeners of a block validation result */ /** Notifies listeners of a block validation result */
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked; boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
/** Notifies listeners that an address for mining is required (coinbase) */ /** Notifies listeners that an address for mining is required (coinbase) */
boost::signals2::signal<void (MinerAddress&)> AddressForMining; boost::signals2::signal<void (std::optional<MinerAddress>&)> AddressForMining;
/** Notifies listeners that a block has been successfully mined */ /** Notifies listeners that a block has been successfully mined */
boost::signals2::signal<void (const uint256 &)> BlockFound; boost::signals2::signal<void (const uint256 &)> BlockFound;
}; };

View File

@ -5547,7 +5547,7 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx)
} }
} }
void CWallet::GetAddressForMining(MinerAddress &minerAddress) void CWallet::GetAddressForMining(std::optional<MinerAddress> &minerAddress)
{ {
if (!GetArg("-mineraddress", "").empty()) { if (!GetArg("-mineraddress", "").empty()) {
return; return;

View File

@ -1719,7 +1719,7 @@ public:
} }
} }
void GetAddressForMining(MinerAddress &minerAddress); void GetAddressForMining(std::optional<MinerAddress> &minerAddress);
void ResetRequestCount(const uint256 &hash) void ResetRequestCount(const uint256 &hash)
{ {
LOCK(cs_wallet); LOCK(cs_wallet);