Replace boost::optional with std::optional

This commit is contained in:
Jack Grigg 2020-07-17 18:29:04 +12:00
parent 25a225f946
commit aa1567f868
64 changed files with 531 additions and 491 deletions

View File

@ -12,6 +12,7 @@
#include "tinyformat.h" #include "tinyformat.h"
#include "uint256.h" #include "uint256.h"
#include <optional>
#include <vector> #include <vector>
static const int SPROUT_VALUE_VERSION = 1001400; static const int SPROUT_VALUE_VERSION = 1001400;
@ -228,7 +229,7 @@ public:
//! Branch ID corresponding to the consensus rules used to validate this block. //! Branch ID corresponding to the consensus rules used to validate this block.
//! Only cached if block validity is BLOCK_VALID_CONSENSUS. //! Only cached if block validity is BLOCK_VALID_CONSENSUS.
//! Persisted at each activation height, memory-only for intervening blocks. //! Persisted at each activation height, memory-only for intervening blocks.
boost::optional<uint32_t> nCachedBranchId; std::optional<uint32_t> nCachedBranchId;
//! The anchor for the tree state up to the start of this block //! The anchor for the tree state up to the start of this block
uint256 hashSproutAnchor; uint256 hashSproutAnchor;
@ -237,22 +238,22 @@ public:
uint256 hashFinalSproutRoot; uint256 hashFinalSproutRoot;
//! Change in value held by the Sprout circuit over this block. //! Change in value held by the Sprout circuit over this block.
//! Will be boost::none for older blocks on old nodes until a reindex has taken place. //! Will be std::nullopt for older blocks on old nodes until a reindex has taken place.
boost::optional<CAmount> nSproutValue; std::optional<CAmount> nSproutValue;
//! (memory only) Total value held by the Sprout circuit up to and including this block. //! (memory only) Total value held by the Sprout circuit up to and including this block.
//! Will be boost::none for on old nodes until a reindex has taken place. //! Will be std::nullopt for on old nodes until a reindex has taken place.
//! Will be boost::none if nChainTx is zero. //! Will be std::nullopt if nChainTx is zero.
boost::optional<CAmount> nChainSproutValue; std::optional<CAmount> nChainSproutValue;
//! Change in value held by the Sapling circuit over this block. //! Change in value held by the Sapling circuit over this block.
//! Not a boost::optional because this was added before Sapling activated, so we can //! Not a std::optional because this was added before Sapling activated, so we can
//! rely on the invariant that every block before this was added had nSaplingValue = 0. //! rely on the invariant that every block before this was added had nSaplingValue = 0.
CAmount nSaplingValue; CAmount nSaplingValue;
//! (memory only) Total value held by the Sapling circuit up to and including this block. //! (memory only) Total value held by the Sapling circuit up to and including this block.
//! Will be boost::none if nChainTx is zero. //! Will be std::nullopt if nChainTx is zero.
boost::optional<CAmount> nChainSaplingValue; std::optional<CAmount> nChainSaplingValue;
//! Root of the Sapling commitment tree as of the end of this block. //! Root of the Sapling commitment tree as of the end of this block.
//! //!
@ -295,14 +296,14 @@ public:
nTx = 0; nTx = 0;
nChainTx = 0; nChainTx = 0;
nStatus = 0; nStatus = 0;
nCachedBranchId = boost::none; nCachedBranchId = std::nullopt;
hashSproutAnchor = uint256(); hashSproutAnchor = uint256();
hashFinalSproutRoot = uint256(); hashFinalSproutRoot = uint256();
nSequenceId = 0; nSequenceId = 0;
nSproutValue = boost::none; nSproutValue = std::nullopt;
nChainSproutValue = boost::none; nChainSproutValue = std::nullopt;
nSaplingValue = 0; nSaplingValue = 0;
nChainSaplingValue = boost::none; nChainSaplingValue = std::nullopt;
nVersion = 0; nVersion = 0;
hashMerkleRoot = uint256(); hashMerkleRoot = uint256();

View File

@ -13,6 +13,7 @@
#include "utilstrencodings.h" #include "utilstrencodings.h"
#include <assert.h> #include <assert.h>
#include <optional>
#include <variant> #include <variant>
#include <boost/assign/list_of.hpp> #include <boost/assign/list_of.hpp>
@ -104,7 +105,7 @@ public:
consensus.nPowMaxAdjustUp = 16; // 16% adjustment up consensus.nPowMaxAdjustUp = 16; // 16% adjustment up
consensus.nPreBlossomPowTargetSpacing = Consensus::PRE_BLOSSOM_POW_TARGET_SPACING; consensus.nPreBlossomPowTargetSpacing = Consensus::PRE_BLOSSOM_POW_TARGET_SPACING;
consensus.nPostBlossomPowTargetSpacing = Consensus::POST_BLOSSOM_POW_TARGET_SPACING; consensus.nPostBlossomPowTargetSpacing = Consensus::POST_BLOSSOM_POW_TARGET_SPACING;
consensus.nPowAllowMinDifficultyBlocksAfterHeight = boost::none; consensus.nPowAllowMinDifficultyBlocksAfterHeight = std::nullopt;
consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002;
consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight =
Consensus::NetworkUpgrade::ALWAYS_ACTIVE; Consensus::NetworkUpgrade::ALWAYS_ACTIVE;

View File

@ -48,9 +48,9 @@ std::set<FundingStreamElement> GetActiveFundingStreamElements(
// in the definition of vFundingStreams. // in the definition of vFundingStreams.
auto fs = params.vFundingStreams[idx]; auto fs = params.vFundingStreams[idx];
// Funding period is [startHeight, endHeight) // Funding period is [startHeight, endHeight)
if (fs && nHeight >= fs.get().GetStartHeight() && nHeight < fs.get().GetEndHeight()) { if (fs && nHeight >= fs.value().GetStartHeight() && nHeight < fs.value().GetEndHeight()) {
requiredElements.insert(std::make_pair( requiredElements.insert(std::make_pair(
fs.get().RecipientAddress(params, nHeight), fs.value().RecipientAddress(params, nHeight),
FundingStreamInfo[idx].Value(blockSubsidy))); FundingStreamInfo[idx].Value(blockSubsidy)));
} }
} }
@ -64,7 +64,7 @@ std::vector<FSInfo> GetActiveFundingStreams(
std::vector<FSInfo> activeStreams; std::vector<FSInfo> activeStreams;
for (uint32_t idx = Consensus::FIRST_FUNDING_STREAM; idx < Consensus::MAX_FUNDING_STREAMS; idx++) { for (uint32_t idx = Consensus::FIRST_FUNDING_STREAM; idx < Consensus::MAX_FUNDING_STREAMS; idx++) {
auto fs = params.vFundingStreams[idx]; auto fs = params.vFundingStreams[idx];
if (fs && nHeight >= fs.get().GetStartHeight() && nHeight < fs.get().GetEndHeight()) { if (fs && nHeight >= fs.value().GetStartHeight() && nHeight < fs.value().GetEndHeight()) {
activeStreams.push_back(FundingStreamInfo[idx]); activeStreams.push_back(FundingStreamInfo[idx]);
} }
} }

View File

@ -11,10 +11,9 @@
#include "key_constants.h" #include "key_constants.h"
#include <zcash/address/sapling.hpp> #include <zcash/address/sapling.hpp>
#include <optional>
#include <variant> #include <variant>
#include <boost/optional.hpp>
namespace Consensus { namespace Consensus {
// Early declaration to ensure it is accessible. // Early declaration to ensure it is accessible.
@ -80,7 +79,7 @@ struct NetworkUpgrade {
* scrutiny than regular releases. nMinimumChainWork MUST be set to at least the chain * scrutiny than regular releases. nMinimumChainWork MUST be set to at least the chain
* work of this block, otherwise this detection will have false positives. * work of this block, otherwise this detection will have false positives.
*/ */
boost::optional<uint256> hashActivationBlock; std::optional<uint256> hashActivationBlock;
}; };
typedef std::variant<libzcash::SaplingPaymentAddress, CScript> FundingStreamAddress; typedef std::variant<libzcash::SaplingPaymentAddress, CScript> FundingStreamAddress;
@ -211,7 +210,7 @@ struct Params {
NetworkUpgrade vUpgrades[MAX_NETWORK_UPGRADES]; NetworkUpgrade vUpgrades[MAX_NETWORK_UPGRADES];
int nFundingPeriodLength; int nFundingPeriodLength;
boost::optional<FundingStream> vFundingStreams[MAX_FUNDING_STREAMS]; std::optional<FundingStream> vFundingStreams[MAX_FUNDING_STREAMS];
void AddZIP207FundingStream( void AddZIP207FundingStream(
const KeyConstants& keyConstants, const KeyConstants& keyConstants,
FundingStreamIndex idx, FundingStreamIndex idx,
@ -263,7 +262,7 @@ struct Params {
unsigned int nEquihashN = 0; unsigned int nEquihashN = 0;
unsigned int nEquihashK = 0; unsigned int nEquihashK = 0;
uint256 powLimit; uint256 powLimit;
boost::optional<uint32_t> nPowAllowMinDifficultyBlocksAfterHeight; std::optional<uint32_t> nPowAllowMinDifficultyBlocksAfterHeight;
int64_t nPowAveragingWindow; int64_t nPowAveragingWindow;
int64_t nPowMaxAdjustDown; int64_t nPowMaxAdjustDown;
int64_t nPowMaxAdjustUp; int64_t nPowMaxAdjustUp;

View File

@ -140,9 +140,9 @@ bool IsActivationHeightForAnyUpgrade(
return false; return false;
} }
boost::optional<int> NextEpoch(int nHeight, const Consensus::Params& params) { std::optional<int> NextEpoch(int nHeight, const Consensus::Params& params) {
if (nHeight < 0) { if (nHeight < 0) {
return boost::none; return std::nullopt;
} }
// Sprout is never pending // Sprout is never pending
@ -152,16 +152,16 @@ boost::optional<int> NextEpoch(int nHeight, const Consensus::Params& params) {
} }
} }
return boost::none; return std::nullopt;
} }
boost::optional<int> NextActivationHeight( std::optional<int> NextActivationHeight(
int nHeight, int nHeight,
const Consensus::Params& params) const Consensus::Params& params)
{ {
auto idx = NextEpoch(nHeight, params); auto idx = NextEpoch(nHeight, params);
if (idx) { if (idx) {
return params.vUpgrades[idx.get()].nActivationHeight; return params.vUpgrades[idx.value()].nActivationHeight;
} }
return boost::none; return std::nullopt;
} }

View File

@ -7,7 +7,7 @@
#include "consensus/params.h" #include "consensus/params.h"
#include <boost/optional.hpp> #include <optional>
enum UpgradeState { enum UpgradeState {
UPGRADE_DISABLED, UPGRADE_DISABLED,
@ -83,15 +83,15 @@ bool IsActivationHeightForAnyUpgrade(
/** /**
* Returns the index of the next upgrade after the given block height, or * Returns the index of the next upgrade after the given block height, or
* boost::none if there are no more known upgrades. * std::nullopt if there are no more known upgrades.
*/ */
boost::optional<int> NextEpoch(int nHeight, const Consensus::Params& params); std::optional<int> NextEpoch(int nHeight, const Consensus::Params& params);
/** /**
* Returns the activation height for the next upgrade after the given block height, * Returns the activation height for the next upgrade after the given block height,
* or boost::none if there are no more known upgrades. * or std::nullopt if there are no more known upgrades.
*/ */
boost::optional<int> NextActivationHeight( std::optional<int> NextActivationHeight(
int nHeight, int nHeight,
const Consensus::Params& params); const Consensus::Params& params);

View File

@ -24,10 +24,9 @@
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <optional>
#include <stdexcept> #include <stdexcept>
#include <boost/optional.hpp>
static EhSolverCancelledException solver_cancelled; static EhSolverCancelledException solver_cancelled;
eh_HashState::eh_HashState( eh_HashState::eh_HashState(
@ -657,7 +656,7 @@ bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
size_t hashLen; size_t hashLen;
size_t lenIndices; size_t lenIndices;
unsigned char tmpHash[HashOutput]; unsigned char tmpHash[HashOutput];
std::vector<boost::optional<std::vector<FullStepRow<FinalFullWidth>>>> X; std::vector<std::optional<std::vector<FullStepRow<FinalFullWidth>>>> X;
X.reserve(K+1); X.reserve(K+1);
// 3) Repeat steps 1 and 2 for each partial index // 3) Repeat steps 1 and 2 for each partial index
@ -675,7 +674,7 @@ bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
N/8, HashLength, CollisionBitLength, newIndex); N/8, HashLength, CollisionBitLength, newIndex);
if (cancelled(PartialGeneration)) throw solver_cancelled; if (cancelled(PartialGeneration)) throw solver_cancelled;
} }
boost::optional<std::vector<FullStepRow<FinalFullWidth>>> ic = icv; std::optional<std::vector<FullStepRow<FinalFullWidth>>> ic = icv;
// 2a) For each pair of lists: // 2a) For each pair of lists:
hashLen = HashLength; hashLen = HashLength;
@ -700,7 +699,7 @@ bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
if (ic->size() == 0) if (ic->size() == 0)
goto invalidsolution; goto invalidsolution;
X[r] = boost::none; X[r] = std::nullopt;
hashLen -= CollisionByteLength; hashLen -= CollisionByteLength;
lenIndices *= 2; lenIndices *= 2;
rti = lti; rti = lti;

View File

@ -12,7 +12,7 @@ bool fExperimentalPaymentDisclosure = false;
bool fExperimentalInsightExplorer = false; bool fExperimentalInsightExplorer = false;
bool fExperimentalLightWalletd = false; bool fExperimentalLightWalletd = false;
boost::optional<std::string> InitExperimentalMode() std::optional<std::string> InitExperimentalMode()
{ {
auto fExperimentalMode = GetBoolArg("-experimentalfeatures", false); auto fExperimentalMode = GetBoolArg("-experimentalfeatures", false);
fExperimentalDeveloperEncryptWallet = GetBoolArg("-developerencryptwallet", false); fExperimentalDeveloperEncryptWallet = GetBoolArg("-developerencryptwallet", false);
@ -35,7 +35,7 @@ boost::optional<std::string> InitExperimentalMode()
return _("Light Walletd requires -experimentalfeatures."); return _("Light Walletd requires -experimentalfeatures.");
} }
} }
return boost::none; return std::nullopt;
} }
std::vector<std::string> GetExperimentalFeatures() std::vector<std::string> GetExperimentalFeatures()

View File

@ -2,9 +2,9 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php . // file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/optional.hpp>
extern bool fExperimentalDeveloperEncryptWallet; extern bool fExperimentalDeveloperEncryptWallet;
extern bool fExperimentalDeveloperSetPoolSizeZero; extern bool fExperimentalDeveloperSetPoolSizeZero;
@ -12,5 +12,5 @@ extern bool fExperimentalPaymentDisclosure;
extern bool fExperimentalInsightExplorer; extern bool fExperimentalInsightExplorer;
extern bool fExperimentalLightWalletd; extern bool fExperimentalLightWalletd;
boost::optional<std::string> InitExperimentalMode(); std::optional<std::string> InitExperimentalMode();
std::vector<std::string> GetExperimentalFeatures(); std::vector<std::string> GetExperimentalFeatures();

View File

@ -1138,7 +1138,7 @@ TEST(ChecktransactionTests, HeartwoodAcceptsShieldedCoinbase) {
auto output = OutputDescriptionInfo(ovk, note, {{0xF6}}); auto output = OutputDescriptionInfo(ovk, note, {{0xF6}});
auto ctx = librustzcash_sapling_proving_ctx_init(); auto ctx = librustzcash_sapling_proving_ctx_init();
auto odesc = output.Build(ctx).get(); auto odesc = output.Build(ctx).value();
librustzcash_sapling_proving_ctx_free(ctx); librustzcash_sapling_proving_ctx_free(ctx);
CMutableTransaction mtx = GetValidTransaction(); CMutableTransaction mtx = GetValidTransaction();
@ -1244,7 +1244,7 @@ TEST(ChecktransactionTests, HeartwoodEnforcesSaplingRulesOnShieldedCoinbase) {
// Add a Sapling output. // Add a Sapling output.
auto ctx = librustzcash_sapling_proving_ctx_init(); auto ctx = librustzcash_sapling_proving_ctx_init();
auto odesc = output.Build(ctx).get(); auto odesc = output.Build(ctx).value();
librustzcash_sapling_proving_ctx_free(ctx); librustzcash_sapling_proving_ctx_free(ctx);
mtx.vShieldedOutput.push_back(odesc); mtx.vShieldedOutput.push_back(odesc);

View File

@ -105,8 +105,8 @@ void checkNumberOfUniqueAddresses(int nUnique) {
int GetMaxFundingStreamHeight(const Consensus::Params& params) { int GetMaxFundingStreamHeight(const Consensus::Params& params) {
int result = 0; int result = 0;
for (auto fs : params.vFundingStreams) { for (auto fs : params.vFundingStreams) {
if (fs && result < fs.get().GetEndHeight() - 1) { if (fs && result < fs.value().GetEndHeight() - 1) {
result = fs.get().GetEndHeight() - 1; result = fs.value().GetEndHeight() - 1;
} }
} }

View File

@ -94,13 +94,13 @@ TEST(MempoolLimitTests, WeightedTxTreeCheckSizeAfterDropping)
tree.add(WeightedTxInfo(TX_ID2, TxWeight(MIN_TX_COST, MIN_TX_COST))); tree.add(WeightedTxInfo(TX_ID2, TxWeight(MIN_TX_COST, MIN_TX_COST)));
EXPECT_EQ(8000, tree.getTotalWeight().cost); EXPECT_EQ(8000, tree.getTotalWeight().cost);
EXPECT_EQ(8000, tree.getTotalWeight().evictionWeight); EXPECT_EQ(8000, tree.getTotalWeight().evictionWeight);
EXPECT_FALSE(tree.maybeDropRandom().is_initialized()); EXPECT_FALSE(tree.maybeDropRandom().has_value());
tree.add(WeightedTxInfo(TX_ID3, TxWeight(MIN_TX_COST, MIN_TX_COST + LOW_FEE_PENALTY))); tree.add(WeightedTxInfo(TX_ID3, TxWeight(MIN_TX_COST, MIN_TX_COST + LOW_FEE_PENALTY)));
EXPECT_EQ(12000, tree.getTotalWeight().cost); EXPECT_EQ(12000, tree.getTotalWeight().cost);
EXPECT_EQ(12000 + LOW_FEE_PENALTY, tree.getTotalWeight().evictionWeight); EXPECT_EQ(12000 + LOW_FEE_PENALTY, tree.getTotalWeight().evictionWeight);
boost::optional<uint256> drop = tree.maybeDropRandom(); auto drop = tree.maybeDropRandom();
ASSERT_TRUE(drop.is_initialized()); ASSERT_TRUE(drop.has_value());
uint256 txid = drop.get(); uint256 txid = drop.value();
testedDropping.insert(txid); testedDropping.insert(txid);
// Do not continue to test if a particular trial fails // Do not continue to test if a particular trial fails
ASSERT_EQ(8000, tree.getTotalWeight().cost); ASSERT_EQ(8000, tree.getTotalWeight().cost);

View File

@ -2,6 +2,7 @@
#include "sodium.h" #include "sodium.h"
#include <array> #include <array>
#include <optional>
#include <stdexcept> #include <stdexcept>
#include "zcash/Note.hpp" #include "zcash/Note.hpp"
@ -50,7 +51,7 @@ TEST(NoteEncryption, NotePlaintext)
if (!cmu_opt) { if (!cmu_opt) {
FAIL(); FAIL();
} }
uint256 cmu = cmu_opt.get(); uint256 cmu = cmu_opt.value();
SaplingNotePlaintext pt(note, memo); SaplingNotePlaintext pt(note, memo);
auto res = pt.encrypt(addr.pk_d); auto res = pt.encrypt(addr.pk_d);
@ -58,7 +59,7 @@ TEST(NoteEncryption, NotePlaintext)
FAIL(); FAIL();
} }
auto enc = res.get(); auto enc = res.value();
auto ct = enc.first; auto ct = enc.first;
auto encryptor = enc.second; auto encryptor = enc.second;
@ -88,7 +89,7 @@ TEST(NoteEncryption, NotePlaintext)
FAIL(); FAIL();
} }
auto bar = foo.get(); auto bar = foo.value();
ASSERT_TRUE(bar.value() == pt.value()); ASSERT_TRUE(bar.value() == pt.value());
ASSERT_TRUE(bar.memo() == pt.memo()); ASSERT_TRUE(bar.memo() == pt.memo());
@ -101,7 +102,7 @@ TEST(NoteEncryption, NotePlaintext)
FAIL(); FAIL();
} }
auto new_note = foobar.get(); auto new_note = foobar.value();
ASSERT_TRUE(note.value() == new_note.value()); ASSERT_TRUE(note.value() == new_note.value());
ASSERT_TRUE(note.d == new_note.d); ASSERT_TRUE(note.d == new_note.d);
@ -136,7 +137,7 @@ TEST(NoteEncryption, NotePlaintext)
FAIL(); FAIL();
} }
auto decrypted_out_ct_unwrapped = decrypted_out_ct.get(); auto decrypted_out_ct_unwrapped = decrypted_out_ct.value();
ASSERT_TRUE(decrypted_out_ct_unwrapped.pk_d == out_pt.pk_d); ASSERT_TRUE(decrypted_out_ct_unwrapped.pk_d == out_pt.pk_d);
ASSERT_TRUE(decrypted_out_ct_unwrapped.esk == out_pt.esk); ASSERT_TRUE(decrypted_out_ct_unwrapped.esk == out_pt.esk);
@ -169,7 +170,7 @@ TEST(NoteEncryption, NotePlaintext)
FAIL(); FAIL();
} }
bar = foo.get(); bar = foo.value();
ASSERT_TRUE(bar.value() == pt.value()); ASSERT_TRUE(bar.value() == pt.value());
ASSERT_TRUE(bar.memo() == pt.memo()); ASSERT_TRUE(bar.memo() == pt.memo());
@ -210,7 +211,7 @@ TEST(NoteEncryption, RejectsInvalidNoteZip212Enabled)
if (!cmu_opt) { if (!cmu_opt) {
FAIL(); FAIL();
} }
uint256 cmu = cmu_opt.get(); uint256 cmu = cmu_opt.value();
SaplingNotePlaintext pt(note, memo); SaplingNotePlaintext pt(note, memo);
auto res = pt.encrypt(addr.pk_d); auto res = pt.encrypt(addr.pk_d);
@ -218,7 +219,7 @@ TEST(NoteEncryption, RejectsInvalidNoteZip212Enabled)
FAIL(); FAIL();
} }
auto enc = res.get(); auto enc = res.value();
auto ct = enc.first; auto ct = enc.first;
auto encryptor = enc.second; auto encryptor = enc.second;
@ -241,7 +242,7 @@ TEST(NoteEncryption, RejectsInvalidNoteZip212Enabled)
if (!cmu_opt) { if (!cmu_opt) {
FAIL(); FAIL();
} }
uint256 cmu = cmu_opt.get(); uint256 cmu = cmu_opt.value();
SaplingNotePlaintext pt(note, memo); SaplingNotePlaintext pt(note, memo);
auto res = pt.encrypt(addr.pk_d); auto res = pt.encrypt(addr.pk_d);
@ -249,7 +250,7 @@ TEST(NoteEncryption, RejectsInvalidNoteZip212Enabled)
FAIL(); FAIL();
} }
auto enc = res.get(); auto enc = res.value();
auto ct = enc.first; auto ct = enc.first;
auto encryptor = enc.second; auto encryptor = enc.second;
@ -301,7 +302,7 @@ TEST(NoteEncryption, AcceptsValidNoteZip212Enabled)
if (!cmu_opt) { if (!cmu_opt) {
FAIL(); FAIL();
} }
uint256 cmu = cmu_opt.get(); uint256 cmu = cmu_opt.value();
SaplingNotePlaintext pt(note, memo); SaplingNotePlaintext pt(note, memo);
auto res = pt.encrypt(addr.pk_d); auto res = pt.encrypt(addr.pk_d);
@ -309,7 +310,7 @@ TEST(NoteEncryption, AcceptsValidNoteZip212Enabled)
FAIL(); FAIL();
} }
auto enc = res.get(); auto enc = res.value();
auto ct = enc.first; auto ct = enc.first;
auto encryptor = enc.second; auto encryptor = enc.second;
@ -343,7 +344,7 @@ TEST(NoteEncryption, AcceptsValidNoteZip212Enabled)
if (!cmu_opt) { if (!cmu_opt) {
FAIL(); FAIL();
} }
uint256 cmu = cmu_opt.get(); uint256 cmu = cmu_opt.value();
SaplingNotePlaintext pt(note, memo); SaplingNotePlaintext pt(note, memo);
auto res = pt.encrypt(addr.pk_d); auto res = pt.encrypt(addr.pk_d);
@ -351,7 +352,7 @@ TEST(NoteEncryption, AcceptsValidNoteZip212Enabled)
FAIL(); FAIL();
} }
auto enc = res.get(); auto enc = res.value();
auto ct = enc.first; auto ct = enc.first;
auto encryptor = enc.second; auto encryptor = enc.second;
@ -380,7 +381,7 @@ TEST(NoteEncryption, AcceptsValidNoteZip212Enabled)
if (!cmu_opt) { if (!cmu_opt) {
FAIL(); FAIL();
} }
uint256 cmu = cmu_opt.get(); uint256 cmu = cmu_opt.value();
SaplingNotePlaintext pt(note, memo); SaplingNotePlaintext pt(note, memo);
auto res = pt.encrypt(addr.pk_d); auto res = pt.encrypt(addr.pk_d);
@ -388,7 +389,7 @@ TEST(NoteEncryption, AcceptsValidNoteZip212Enabled)
FAIL(); FAIL();
} }
auto enc = res.get(); auto enc = res.value();
auto ct = enc.first; auto ct = enc.first;
auto encryptor = enc.second; auto encryptor = enc.second;
@ -442,7 +443,7 @@ TEST(NoteEncryption, SaplingApi)
librustzcash_sapling_generate_r(esk.begin()); librustzcash_sapling_generate_r(esk.begin());
// Invalid diversifier // Invalid diversifier
ASSERT_EQ(boost::none, SaplingNoteEncryption::FromDiversifier({1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, esk)); ASSERT_EQ(std::nullopt, SaplingNoteEncryption::FromDiversifier({1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, esk));
// Encrypt to pk_1 // Encrypt to pk_1
auto enc = *SaplingNoteEncryption::FromDiversifier(pk_1.d, esk); auto enc = *SaplingNoteEncryption::FromDiversifier(pk_1.d, esk);

View File

@ -93,7 +93,7 @@ TEST(PoW, MinDifficultyRules) {
std::vector<CBlockIndex> blocks(lastBlk+1); std::vector<CBlockIndex> blocks(lastBlk+1);
for (int i = 0; i <= lastBlk; i++) { for (int i = 0; i <= lastBlk; i++) {
blocks[i].pprev = i ? &blocks[i - 1] : nullptr; blocks[i].pprev = i ? &blocks[i - 1] : nullptr;
blocks[i].nHeight = params.nPowAllowMinDifficultyBlocksAfterHeight.get() + i; blocks[i].nHeight = params.nPowAllowMinDifficultyBlocksAfterHeight.value() + i;
blocks[i].nTime = i ? blocks[i - 1].nTime + params.PoWTargetSpacing(i) : 1269211443; blocks[i].nTime = i ? blocks[i - 1].nTime + params.PoWTargetSpacing(i) : 1269211443;
blocks[i].nBits = 0x1e7fffff; /* target 0x007fffff000... */ blocks[i].nBits = 0x1e7fffff; /* target 0x007fffff000... */
blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0); blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0);

View File

@ -45,7 +45,7 @@ TEST(SaplingNote, TestVectors)
// Test commitment // Test commitment
SaplingNote note = SaplingNote(diversifier, pk_d, v, r, Zip212Enabled::BeforeZip212); SaplingNote note = SaplingNote(diversifier, pk_d, v, r, Zip212Enabled::BeforeZip212);
ASSERT_EQ(note.cmu().get(), cm); ASSERT_EQ(note.cmu().value(), cm);
// Test nullifier // Test nullifier
SaplingSpendingKey spendingKey(sk); SaplingSpendingKey spendingKey(sk);

View File

@ -3,7 +3,7 @@
#include "chainparams.h" #include "chainparams.h"
#include "consensus/upgrades.h" #include "consensus/upgrades.h"
#include <boost/optional.hpp> #include <optional>
class UpgradesTest : public ::testing::Test { class UpgradesTest : public ::testing::Test {
protected: protected:
@ -148,28 +148,28 @@ TEST_F(UpgradesTest, NextEpoch) {
const Consensus::Params& params = Params().GetConsensus(); const Consensus::Params& params = Params().GetConsensus();
// Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT // Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT
EXPECT_EQ(NextEpoch(-1, params), boost::none); EXPECT_EQ(NextEpoch(-1, params), std::nullopt);
EXPECT_EQ(NextEpoch(0, params), boost::none); EXPECT_EQ(NextEpoch(0, params), std::nullopt);
EXPECT_EQ(NextEpoch(1, params), boost::none); EXPECT_EQ(NextEpoch(1, params), std::nullopt);
EXPECT_EQ(NextEpoch(1000000, params), boost::none); EXPECT_EQ(NextEpoch(1000000, params), std::nullopt);
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
EXPECT_EQ(NextEpoch(-1, params), boost::none); EXPECT_EQ(NextEpoch(-1, params), std::nullopt);
EXPECT_EQ(NextEpoch(0, params), boost::none); EXPECT_EQ(NextEpoch(0, params), std::nullopt);
EXPECT_EQ(NextEpoch(1, params), boost::none); EXPECT_EQ(NextEpoch(1, params), std::nullopt);
EXPECT_EQ(NextEpoch(1000000, params), boost::none); EXPECT_EQ(NextEpoch(1000000, params), std::nullopt);
int nActivationHeight = 100; int nActivationHeight = 100;
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, nActivationHeight); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, nActivationHeight);
EXPECT_EQ(NextEpoch(-1, params), boost::none); EXPECT_EQ(NextEpoch(-1, params), std::nullopt);
EXPECT_EQ(NextEpoch(0, params), static_cast<int>(Consensus::UPGRADE_TESTDUMMY)); EXPECT_EQ(NextEpoch(0, params), static_cast<int>(Consensus::UPGRADE_TESTDUMMY));
EXPECT_EQ(NextEpoch(1, params), static_cast<int>(Consensus::UPGRADE_TESTDUMMY)); EXPECT_EQ(NextEpoch(1, params), static_cast<int>(Consensus::UPGRADE_TESTDUMMY));
EXPECT_EQ(NextEpoch(nActivationHeight - 1, params), static_cast<int>(Consensus::UPGRADE_TESTDUMMY)); EXPECT_EQ(NextEpoch(nActivationHeight - 1, params), static_cast<int>(Consensus::UPGRADE_TESTDUMMY));
EXPECT_EQ(NextEpoch(nActivationHeight, params), boost::none); EXPECT_EQ(NextEpoch(nActivationHeight, params), std::nullopt);
EXPECT_EQ(NextEpoch(nActivationHeight + 1, params), boost::none); EXPECT_EQ(NextEpoch(nActivationHeight + 1, params), std::nullopt);
EXPECT_EQ(NextEpoch(1000000, params), boost::none); EXPECT_EQ(NextEpoch(1000000, params), std::nullopt);
} }
TEST_F(UpgradesTest, NextActivationHeight) { TEST_F(UpgradesTest, NextActivationHeight) {
@ -177,26 +177,26 @@ TEST_F(UpgradesTest, NextActivationHeight) {
const Consensus::Params& params = Params().GetConsensus(); const Consensus::Params& params = Params().GetConsensus();
// Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT // Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT
EXPECT_EQ(NextActivationHeight(-1, params), boost::none); EXPECT_EQ(NextActivationHeight(-1, params), std::nullopt);
EXPECT_EQ(NextActivationHeight(0, params), boost::none); EXPECT_EQ(NextActivationHeight(0, params), std::nullopt);
EXPECT_EQ(NextActivationHeight(1, params), boost::none); EXPECT_EQ(NextActivationHeight(1, params), std::nullopt);
EXPECT_EQ(NextActivationHeight(1000000, params), boost::none); EXPECT_EQ(NextActivationHeight(1000000, params), std::nullopt);
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
EXPECT_EQ(NextActivationHeight(-1, params), boost::none); EXPECT_EQ(NextActivationHeight(-1, params), std::nullopt);
EXPECT_EQ(NextActivationHeight(0, params), boost::none); EXPECT_EQ(NextActivationHeight(0, params), std::nullopt);
EXPECT_EQ(NextActivationHeight(1, params), boost::none); EXPECT_EQ(NextActivationHeight(1, params), std::nullopt);
EXPECT_EQ(NextActivationHeight(1000000, params), boost::none); EXPECT_EQ(NextActivationHeight(1000000, params), std::nullopt);
int nActivationHeight = 100; int nActivationHeight = 100;
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, nActivationHeight); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, nActivationHeight);
EXPECT_EQ(NextActivationHeight(-1, params), boost::none); EXPECT_EQ(NextActivationHeight(-1, params), std::nullopt);
EXPECT_EQ(NextActivationHeight(0, params), nActivationHeight); EXPECT_EQ(NextActivationHeight(0, params), nActivationHeight);
EXPECT_EQ(NextActivationHeight(1, params), nActivationHeight); EXPECT_EQ(NextActivationHeight(1, params), nActivationHeight);
EXPECT_EQ(NextActivationHeight(nActivationHeight - 1, params), nActivationHeight); EXPECT_EQ(NextActivationHeight(nActivationHeight - 1, params), nActivationHeight);
EXPECT_EQ(NextActivationHeight(nActivationHeight, params), boost::none); EXPECT_EQ(NextActivationHeight(nActivationHeight, params), std::nullopt);
EXPECT_EQ(NextActivationHeight(nActivationHeight + 1, params), boost::none); EXPECT_EQ(NextActivationHeight(nActivationHeight + 1, params), std::nullopt);
EXPECT_EQ(NextActivationHeight(1000000, params), boost::none); EXPECT_EQ(NextActivationHeight(1000000, params), std::nullopt);
} }

View File

@ -7,6 +7,8 @@
#include "transaction_builder.h" #include "transaction_builder.h"
#include "utiltest.h" #include "utiltest.h"
#include <optional>
extern bool ReceivedBlockTransactions( extern bool ReceivedBlockTransactions(
const CBlock &block, const CBlock &block,
CValidationState& state, CValidationState& state,
@ -14,7 +16,7 @@ extern bool ReceivedBlockTransactions(
CBlockIndex *pindexNew, CBlockIndex *pindexNew,
const CDiskBlockPos& pos); const CDiskBlockPos& pos);
void ExpectOptionalAmount(CAmount expected, boost::optional<CAmount> actual) { void ExpectOptionalAmount(CAmount expected, std::optional<CAmount> actual) {
EXPECT_TRUE((bool)actual); EXPECT_TRUE((bool)actual);
if (actual) { if (actual) {
EXPECT_EQ(expected, *actual); EXPECT_EQ(expected, *actual);
@ -24,7 +26,7 @@ void ExpectOptionalAmount(CAmount expected, boost::optional<CAmount> actual) {
// Fake a view that optionally contains a single coin. // Fake a view that optionally contains a single coin.
class ValidationFakeCoinsViewDB : public CCoinsView { class ValidationFakeCoinsViewDB : public CCoinsView {
public: public:
boost::optional<std::pair<std::pair<uint256, uint256>, std::pair<CTxOut, int>>> coin; std::optional<std::pair<std::pair<uint256, uint256>, std::pair<CTxOut, int>>> coin;
ValidationFakeCoinsViewDB() {} ValidationFakeCoinsViewDB() {}
ValidationFakeCoinsViewDB(uint256 blockHash, uint256 txid, CTxOut txOut, int nHeight) : ValidationFakeCoinsViewDB(uint256 blockHash, uint256 txid, CTxOut txOut, int nHeight) :
@ -43,11 +45,11 @@ public:
} }
bool GetCoins(const uint256 &txid, CCoins &coins) const { bool GetCoins(const uint256 &txid, CCoins &coins) const {
if (coin && txid == coin.get().first.second) { if (coin && txid == coin.value().first.second) {
CCoins newCoins; CCoins newCoins;
newCoins.vout.resize(2); newCoins.vout.resize(2);
newCoins.vout[0] = coin.get().second.first; newCoins.vout[0] = coin.value().second.first;
newCoins.nHeight = coin.get().second.second; newCoins.nHeight = coin.value().second.second;
coins.swap(newCoins); coins.swap(newCoins);
return true; return true;
} else { } else {
@ -56,7 +58,7 @@ public:
} }
bool HaveCoins(const uint256 &txid) const { bool HaveCoins(const uint256 &txid) const {
if (coin && txid == coin.get().first.second) { if (coin && txid == coin.value().first.second) {
return true; return true;
} else { } else {
return false; return false;
@ -65,7 +67,7 @@ public:
uint256 GetBestBlock() const { uint256 GetBestBlock() const {
if (coin) { if (coin) {
return coin.get().first.first; return coin.value().first.first;
} else { } else {
uint256 a; uint256 a;
return a; return a;

View File

@ -109,7 +109,7 @@ TEST(ZIP32, TestVectors) {
auto maybe_m_1_2hv_3 = m_1_2hv.Derive(3); auto maybe_m_1_2hv_3 = m_1_2hv.Derive(3);
EXPECT_TRUE(maybe_m_1_2hv_3); EXPECT_TRUE(maybe_m_1_2hv_3);
auto m_1_2hv_3 = maybe_m_1_2hv_3.get(); auto m_1_2hv_3 = maybe_m_1_2hv_3.value();
EXPECT_EQ(m_1_2hv_3.depth, 3); EXPECT_EQ(m_1_2hv_3.depth, 3);
EXPECT_EQ(m_1_2hv_3.parentFVKTag, 0x7583c148); EXPECT_EQ(m_1_2hv_3.parentFVKTag, 0x7583c148);
EXPECT_EQ(m_1_2hv_3.childIndex, 3); EXPECT_EQ(m_1_2hv_3.childIndex, 3);

View File

@ -935,7 +935,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Set this early so that experimental features are correctly enabled/disabled // Set this early so that experimental features are correctly enabled/disabled
auto err = InitExperimentalMode(); auto err = InitExperimentalMode();
if (err) { if (err) {
return InitError(err.get()); return InitError(err.value());
} }
// Make sure enough file descriptors are available // Make sure enough file descriptors are available

View File

@ -87,7 +87,7 @@ uint64_t nPruneTarget = 0;
bool fAlerts = DEFAULT_ALERTS; bool fAlerts = DEFAULT_ALERTS;
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
boost::optional<unsigned int> expiryDeltaArg = boost::none; std::optional<unsigned int> expiryDeltaArg = std::nullopt;
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
@ -1948,7 +1948,7 @@ bool IsInitialBlockDownload(const CChainParams& chainParams)
// If an upgrade is active, we must be past its activation height. // If an upgrade is active, we must be past its activation height.
assert(chainActive[upgrade.nActivationHeight]); assert(chainActive[upgrade.nActivationHeight]);
if (chainActive[upgrade.nActivationHeight]->GetBlockHash() != upgrade.hashActivationBlock.get()) { if (chainActive[upgrade.nActivationHeight]->GetBlockHash() != upgrade.hashActivationBlock.value()) {
AbortNode( AbortNode(
strprintf( strprintf(
"%s: We are on a chain with sufficient work, but the activation block hash for the %s network upgrade is not as expected.\n" "%s: We are on a chain with sufficient work, but the activation block hash for the %s network upgrade is not as expected.\n"
@ -1960,7 +1960,7 @@ bool IsInitialBlockDownload(const CChainParams& chainParams)
chainParams.GetConsensus().nMinimumChainWork.GetHex(), chainParams.GetConsensus().nMinimumChainWork.GetHex(),
chainActive.Height(), chainActive.Height(),
upgrade.nActivationHeight, upgrade.nActivationHeight,
upgrade.hashActivationBlock.get().GetHex(), upgrade.hashActivationBlock.value().GetHex(),
chainActive[upgrade.nActivationHeight]->GetBlockHash().GetHex()), chainActive[upgrade.nActivationHeight]->GetBlockHash().GetHex()),
_("We are on a chain with sufficient work, but the network upgrade checkpoints do not match. Your node may be under attack! Shutting down for safety.")); _("We are on a chain with sufficient work, but the network upgrade checkpoints do not match. Your node may be under attack! Shutting down for safety."));
return true; return true;
@ -2548,7 +2548,7 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s
// This is guaranteed to be filled by LoadBlockIndex. // This is guaranteed to be filled by LoadBlockIndex.
assert(pindex->nCachedBranchId); assert(pindex->nCachedBranchId);
auto consensusBranchId = pindex->nCachedBranchId.get(); auto consensusBranchId = pindex->nCachedBranchId.value();
if (chainparams.GetConsensus().NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_HEARTWOOD)) { if (chainparams.GetConsensus().NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_HEARTWOOD)) {
view.PopHistoryNode(consensusBranchId); view.PopHistoryNode(consensusBranchId);
@ -2749,7 +2749,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// Sapling // Sapling
// //
// If we've reached ConnectBlock, we have all transactions of // If we've reached ConnectBlock, we have all transactions of
// parents and can expect nChainSaplingValue not to be boost::none. // parents and can expect nChainSaplingValue not to be std::nullopt.
// However, the miner and mining RPCs may not have populated this // However, the miner and mining RPCs may not have populated this
// value and will call `TestBlockValidity`. So, we act // value and will call `TestBlockValidity`. So, we act
// conditionally. // conditionally.
@ -3787,7 +3787,7 @@ void FallbackSproutValuePoolBalance(
assert(*pindex->nChainSproutValue == chainparams.SproutValuePoolCheckpointBalance()); assert(*pindex->nChainSproutValue == chainparams.SproutValuePoolCheckpointBalance());
// And we should expect non-none for the delta stored in the block index here, // And we should expect non-none for the delta stored in the block index here,
// or the checkpoint is too early. // or the checkpoint is too early.
assert(pindex->nSproutValue != boost::none); assert(pindex->nSproutValue != std::nullopt);
} }
} else { } else {
LogPrintf( LogPrintf(
@ -3823,9 +3823,9 @@ bool ReceivedBlockTransactions(
} }
} }
pindexNew->nSproutValue = sproutValue; pindexNew->nSproutValue = sproutValue;
pindexNew->nChainSproutValue = boost::none; pindexNew->nChainSproutValue = std::nullopt;
pindexNew->nSaplingValue = saplingValue; pindexNew->nSaplingValue = saplingValue;
pindexNew->nChainSaplingValue = boost::none; pindexNew->nChainSaplingValue = std::nullopt;
pindexNew->nFile = pos.nFile; pindexNew->nFile = pos.nFile;
pindexNew->nDataPos = pos.nPos; pindexNew->nDataPos = pos.nPos;
pindexNew->nUndoPos = 0; pindexNew->nUndoPos = 0;
@ -3847,12 +3847,12 @@ bool ReceivedBlockTransactions(
if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) { if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue; pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
} else { } else {
pindex->nChainSproutValue = boost::none; pindex->nChainSproutValue = std::nullopt;
} }
if (pindex->pprev->nChainSaplingValue) { if (pindex->pprev->nChainSaplingValue) {
pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue; pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
} else { } else {
pindex->nChainSaplingValue = boost::none; pindex->nChainSaplingValue = std::nullopt;
} }
} else { } else {
pindex->nChainSproutValue = pindex->nSproutValue; pindex->nChainSproutValue = pindex->nSproutValue;
@ -4579,17 +4579,17 @@ bool static LoadBlockIndexDB()
if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) { if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue; pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
} else { } else {
pindex->nChainSproutValue = boost::none; pindex->nChainSproutValue = std::nullopt;
} }
if (pindex->pprev->nChainSaplingValue) { if (pindex->pprev->nChainSaplingValue) {
pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue; pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
} else { } else {
pindex->nChainSaplingValue = boost::none; pindex->nChainSaplingValue = std::nullopt;
} }
} else { } else {
pindex->nChainTx = 0; pindex->nChainTx = 0;
pindex->nChainSproutValue = boost::none; pindex->nChainSproutValue = std::nullopt;
pindex->nChainSaplingValue = boost::none; pindex->nChainSaplingValue = std::nullopt;
mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex)); mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
} }
} else { } else {
@ -6893,7 +6893,7 @@ CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Para
bool blossomActive = consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM); bool blossomActive = consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM);
unsigned int defaultExpiryDelta = blossomActive ? DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA : DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA; unsigned int defaultExpiryDelta = blossomActive ? DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA : DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA;
mtx.nExpiryHeight = nHeight + (expiryDeltaArg ? expiryDeltaArg.get() : defaultExpiryDelta); mtx.nExpiryHeight = nHeight + (expiryDeltaArg ? expiryDeltaArg.value() : defaultExpiryDelta);
// mtx.nExpiryHeight == 0 is valid for coinbase transactions // mtx.nExpiryHeight == 0 is valid for coinbase transactions
if (mtx.nExpiryHeight <= 0 || mtx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) { if (mtx.nExpiryHeight <= 0 || mtx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
@ -6905,7 +6905,7 @@ CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Para
// TX_EXPIRING_SOON_THRESHOLD (3) blocks (for DoS mitigation) based on the current height. // TX_EXPIRING_SOON_THRESHOLD (3) blocks (for DoS mitigation) based on the current height.
auto nextActivationHeight = NextActivationHeight(nHeight, consensusParams); auto nextActivationHeight = NextActivationHeight(nHeight, consensusParams);
if (nextActivationHeight) { if (nextActivationHeight) {
mtx.nExpiryHeight = std::min(mtx.nExpiryHeight, static_cast<uint32_t>(nextActivationHeight.get()) - 1); mtx.nExpiryHeight = std::min(mtx.nExpiryHeight, static_cast<uint32_t>(nextActivationHeight.value()) - 1);
} }
} }
return mtx; return mtx;

View File

@ -34,6 +34,7 @@
#include <algorithm> #include <algorithm>
#include <exception> #include <exception>
#include <map> #include <map>
#include <optional>
#include <set> #include <set>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
@ -127,7 +128,7 @@ struct BlockHasher
size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); }
}; };
extern boost::optional<unsigned int> expiryDeltaArg; extern std::optional<unsigned int> expiryDeltaArg;
extern CScript COINBASE_FLAGS; extern CScript COINBASE_FLAGS;
extern CCriticalSection cs_main; extern CCriticalSection cs_main;
extern CTxMemPool mempool; extern CTxMemPool mempool;

View File

@ -118,11 +118,11 @@ void WeightedTxTree::remove(const uint256& txId)
childWeights.pop_back(); childWeights.pop_back();
} }
boost::optional<uint256> WeightedTxTree::maybeDropRandom() std::optional<uint256> WeightedTxTree::maybeDropRandom()
{ {
TxWeight totalTxWeight = getTotalWeight(); TxWeight totalTxWeight = getTotalWeight();
if (totalTxWeight.cost <= capacity) { if (totalTxWeight.cost <= capacity) {
return boost::none; return std::nullopt;
} }
LogPrint("mempool", "Mempool cost limit exceeded (cost=%d, limit=%d)\n", totalTxWeight.cost, capacity); LogPrint("mempool", "Mempool cost limit exceeded (cost=%d, limit=%d)\n", totalTxWeight.cost, capacity);
int randomWeight = GetRand(totalTxWeight.evictionWeight); int randomWeight = GetRand(totalTxWeight.evictionWeight);

View File

@ -7,10 +7,10 @@
#include <deque> #include <deque>
#include <map> #include <map>
#include <optional>
#include <set> #include <set>
#include <vector> #include <vector>
#include "boost/optional.hpp"
#include "primitives/transaction.h" #include "primitives/transaction.h"
#include "uint256.h" #include "uint256.h"
@ -123,7 +123,7 @@ public:
// If the total cost limit is exceeded, pick a random number based on the total cost // If the total cost limit is exceeded, pick a random number based on the total cost
// of the collection and remove the associated transaction. // of the collection and remove the associated transaction.
boost::optional<uint256> maybeDropRandom(); std::optional<uint256> maybeDropRandom();
}; };

View File

@ -256,13 +256,13 @@ std::string DisplaySize(size_t value)
return strprintf(_("%.2f TiB"), value / coef); return strprintf(_("%.2f TiB"), value / coef);
} }
boost::optional<int64_t> SecondsLeftToNextEpoch(const Consensus::Params& params, int currentHeight) std::optional<int64_t> SecondsLeftToNextEpoch(const Consensus::Params& params, int currentHeight)
{ {
auto nextHeight = NextActivationHeight(currentHeight, params); auto nextHeight = NextActivationHeight(currentHeight, params);
if (nextHeight) { if (nextHeight) {
return (nextHeight.get() - currentHeight) * params.PoWTargetSpacing(nextHeight.get() - 1); return (nextHeight.value() - currentHeight) * params.PoWTargetSpacing(nextHeight.value() - 1);
} else { } else {
return boost::none; return std::nullopt;
} }
} }

View File

@ -7,6 +7,7 @@
#include <atomic> #include <atomic>
#include <mutex> #include <mutex>
#include <optional>
#include <string> #include <string>
struct AtomicCounter { struct AtomicCounter {
@ -72,7 +73,7 @@ void TrackMinedBlock(uint256 hash);
void MarkStartTime(); void MarkStartTime();
double GetLocalSolPS(); double GetLocalSolPS();
int EstimateNetHeight(const Consensus::Params& params, int currentBlockHeight, int64_t currentBlockTime); int EstimateNetHeight(const Consensus::Params& params, int currentBlockHeight, int64_t currentBlockTime);
boost::optional<int64_t> SecondsLeftToNextEpoch(const Consensus::Params& params, int currentHeight); std::optional<int64_t> SecondsLeftToNextEpoch(const Consensus::Params& params, int currentHeight);
std::string DisplayDuration(int64_t time, DurationFormat format); std::string DisplayDuration(int64_t time, DurationFormat format);
void TriggerRefresh(); void TriggerRefresh();

View File

@ -111,7 +111,7 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams,
pblock->nTime = nTime; pblock->nTime = nTime;
// Updating time can change work required on testnet: // Updating time can change work required on testnet:
if (consensusParams.nPowAllowMinDifficultyBlocksAfterHeight != boost::none) { if (consensusParams.nPowAllowMinDifficultyBlocksAfterHeight != std::nullopt) {
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
} }
} }
@ -141,7 +141,7 @@ public:
auto odesc = output.Build(ctx); auto odesc = output.Build(ctx);
if (odesc) { if (odesc) {
mtx.vShieldedOutput.push_back(odesc.get()); mtx.vShieldedOutput.push_back(odesc.value());
mtx.valueBalance -= fundingStreamValue; mtx.valueBalance -= fundingStreamValue;
return true; return true;
} else { } else {
@ -258,7 +258,7 @@ public:
librustzcash_sapling_proving_ctx_free(ctx); librustzcash_sapling_proving_ctx_free(ctx);
throw new std::runtime_error("Failed to create shielded output for miner"); throw new std::runtime_error("Failed to create shielded output for miner");
} }
mtx.vShieldedOutput.push_back(odesc.get()); mtx.vShieldedOutput.push_back(odesc.value());
ComputeBindingSig(ctx); ComputeBindingSig(ctx);
@ -916,7 +916,7 @@ void static BitcoinMiner(const CChainParams& chainparams)
// Update nNonce and nTime // Update nNonce and nTime
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
if (chainparams.GetConsensus().nPowAllowMinDifficultyBlocksAfterHeight != boost::none) if (chainparams.GetConsensus().nPowAllowMinDifficultyBlocksAfterHeight != std::nullopt)
{ {
// Changing pblock->nTime can change work required on testnet: // Changing pblock->nTime can change work required on testnet:
hashTarget.SetCompact(pblock->nBits); hashTarget.SetCompact(pblock->nBits);

View File

@ -8,7 +8,6 @@
#include "primitives/block.h" #include "primitives/block.h"
#include <boost/optional.hpp>
#include <stdint.h> #include <stdint.h>
#include <variant> #include <variant>

View File

@ -823,7 +823,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
const Consensus::Params& params = Params().GetConsensus(); const Consensus::Params& params = Params().GetConsensus();
auto nextEpoch = NextEpoch(height, params); auto nextEpoch = NextEpoch(height, params);
if (nextEpoch) { if (nextEpoch) {
auto idx = nextEpoch.get(); auto idx = nextEpoch.value();
int nActivationHeight = params.vUpgrades[idx].nActivationHeight; int nActivationHeight = params.vUpgrades[idx].nActivationHeight;
if (nActivationHeight > 0 && if (nActivationHeight > 0 &&

View File

@ -26,8 +26,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
{ {
// Comparing to pindexLast->nHeight with >= because this function // Comparing to pindexLast->nHeight with >= because this function
// returns the work required for the block after pindexLast. // returns the work required for the block after pindexLast.
if (params.nPowAllowMinDifficultyBlocksAfterHeight != boost::none && if (params.nPowAllowMinDifficultyBlocksAfterHeight != std::nullopt &&
pindexLast->nHeight >= params.nPowAllowMinDifficultyBlocksAfterHeight.get()) pindexLast->nHeight >= params.nPowAllowMinDifficultyBlocksAfterHeight.value())
{ {
// Special difficulty rule for testnet: // Special difficulty rule for testnet:
// If the new block's timestamp is more than 6 * block interval minutes // If the new block's timestamp is more than 6 * block interval minutes

View File

@ -22,6 +22,7 @@
#include <univalue.h> #include <univalue.h>
#include <optional>
#include <regex> #include <regex>
using namespace std; using namespace std;
@ -83,8 +84,8 @@ double GetNetworkDifficulty(const CBlockIndex* blockindex)
static UniValue ValuePoolDesc( static UniValue ValuePoolDesc(
const std::string &name, const std::string &name,
const boost::optional<CAmount> chainValue, const std::optional<CAmount> chainValue,
const boost::optional<CAmount> valueDelta) const std::optional<CAmount> valueDelta)
{ {
UniValue rv(UniValue::VOBJ); UniValue rv(UniValue::VOBJ);
rv.pushKV("id", name); rv.pushKV("id", name);
@ -1058,8 +1059,8 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp)
CBlockIndex* tip = chainActive.Tip(); CBlockIndex* tip = chainActive.Tip();
UniValue valuePools(UniValue::VARR); UniValue valuePools(UniValue::VARR);
valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, boost::none)); valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, std::nullopt));
valuePools.push_back(ValuePoolDesc("sapling", tip->nChainSaplingValue, boost::none)); valuePools.push_back(ValuePoolDesc("sapling", tip->nChainSaplingValue, std::nullopt));
obj.pushKV("valuePools", valuePools); obj.pushKV("valuePools", valuePools);
const Consensus::Params& consensusParams = Params().GetConsensus(); const Consensus::Params& consensusParams = Params().GetConsensus();

View File

@ -16,6 +16,7 @@
#include <list> #include <list>
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional>
#include <set> #include <set>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
@ -23,8 +24,6 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <boost/optional.hpp>
#include "prevector.h" #include "prevector.h"
static const unsigned int MAX_SIZE = 0x02000000; static const unsigned int MAX_SIZE = 0x02000000;
@ -536,8 +535,8 @@ template<typename Stream, typename T, typename A> inline void Unserialize(Stream
/** /**
* optional * optional
*/ */
template<typename Stream, typename T> void Serialize(Stream& os, const boost::optional<T>& item); template<typename Stream, typename T> void Serialize(Stream& os, const std::optional<T>& item);
template<typename Stream, typename T> void Unserialize(Stream& is, boost::optional<T>& item); template<typename Stream, typename T> void Unserialize(Stream& is, std::optional<T>& item);
/** /**
* array * array
@ -764,7 +763,7 @@ inline void Unserialize(Stream& is, std::vector<T, A>& v)
* optional * optional
*/ */
template<typename Stream, typename T> template<typename Stream, typename T>
void Serialize(Stream& os, const boost::optional<T>& item) void Serialize(Stream& os, const std::optional<T>& item)
{ {
// If the value is there, put 0x01 and then serialize the value. // If the value is there, put 0x01 and then serialize the value.
// If it's not, put 0x00. // If it's not, put 0x00.
@ -779,13 +778,13 @@ void Serialize(Stream& os, const boost::optional<T>& item)
} }
template<typename Stream, typename T> template<typename Stream, typename T>
void Unserialize(Stream& is, boost::optional<T>& item) void Unserialize(Stream& is, std::optional<T>& item)
{ {
unsigned char discriminant = 0x00; unsigned char discriminant = 0x00;
Unserialize(is, discriminant); Unserialize(is, discriminant);
if (discriminant == 0x00) { if (discriminant == 0x00) {
item = boost::none; item = std::nullopt;
} else if (discriminant == 0x01) { } else if (discriminant == 0x01) {
T object; T object;
Unserialize(is, object); Unserialize(is, object);

View File

@ -9,10 +9,10 @@
#include "utilstrencodings.h" #include "utilstrencodings.h"
#include <array> #include <array>
#include <optional>
#include <stdint.h> #include <stdint.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/optional.hpp>
using namespace std; using namespace std;
@ -83,15 +83,15 @@ public:
BOOST_AUTO_TEST_CASE(boost_optional) BOOST_AUTO_TEST_CASE(boost_optional)
{ {
check_ser_rep<boost::optional<unsigned char>>(0xff, {0x01, 0xff}); check_ser_rep<std::optional<unsigned char>>(0xff, {0x01, 0xff});
check_ser_rep<boost::optional<unsigned char>>(boost::none, {0x00}); check_ser_rep<std::optional<unsigned char>>(std::nullopt, {0x00});
check_ser_rep<boost::optional<std::string>>(std::string("Test"), {0x01, 0x04, 'T', 'e', 's', 't'}); check_ser_rep<std::optional<std::string>>(std::string("Test"), {0x01, 0x04, 'T', 'e', 's', 't'});
{ {
// Ensure that canonical optional discriminant is used // Ensure that canonical optional discriminant is used
CDataStream ss(SER_DISK, 0); CDataStream ss(SER_DISK, 0);
ss.write("\x02\x04Test", 6); ss.write("\x02\x04Test", 6);
boost::optional<std::string> into; std::optional<std::string> into;
BOOST_CHECK_THROW(ss >> into, std::ios_base::failure); BOOST_CHECK_THROW(ss >> into, std::ios_base::failure);
} }

View File

@ -23,19 +23,19 @@ SpendDescriptionInfo::SpendDescriptionInfo(
librustzcash_sapling_generate_r(alpha.begin()); librustzcash_sapling_generate_r(alpha.begin());
} }
boost::optional<OutputDescription> OutputDescriptionInfo::Build(void* ctx) { std::optional<OutputDescription> OutputDescriptionInfo::Build(void* ctx) {
auto cmu = this->note.cmu(); auto cmu = this->note.cmu();
if (!cmu) { if (!cmu) {
return boost::none; return std::nullopt;
} }
libzcash::SaplingNotePlaintext notePlaintext(this->note, this->memo); libzcash::SaplingNotePlaintext notePlaintext(this->note, this->memo);
auto res = notePlaintext.encrypt(this->note.pk_d); auto res = notePlaintext.encrypt(this->note.pk_d);
if (!res) { if (!res) {
return boost::none; return std::nullopt;
} }
auto enc = res.get(); auto enc = res.value();
auto encryptor = enc.second; auto encryptor = enc.second;
libzcash::SaplingPaymentAddress address(this->note.d, this->note.pk_d); libzcash::SaplingPaymentAddress address(this->note.d, this->note.pk_d);
@ -53,7 +53,7 @@ boost::optional<OutputDescription> OutputDescriptionInfo::Build(void* ctx) {
this->note.value(), this->note.value(),
odesc.cv.begin(), odesc.cv.begin(),
odesc.zkproof.begin())) { odesc.zkproof.begin())) {
return boost::none; return std::nullopt;
} }
odesc.cmu = *cmu; odesc.cmu = *cmu;
@ -125,13 +125,13 @@ TransactionBuilderResult::TransactionBuilderResult(const CTransaction& tx) : may
TransactionBuilderResult::TransactionBuilderResult(const std::string& error) : maybeError(error) {} TransactionBuilderResult::TransactionBuilderResult(const std::string& error) : maybeError(error) {}
bool TransactionBuilderResult::IsTx() { return maybeTx != boost::none; } bool TransactionBuilderResult::IsTx() { return maybeTx != std::nullopt; }
bool TransactionBuilderResult::IsError() { return maybeError != boost::none; } bool TransactionBuilderResult::IsError() { return maybeError != std::nullopt; }
CTransaction TransactionBuilderResult::GetTxOrThrow() { CTransaction TransactionBuilderResult::GetTxOrThrow() {
if (maybeTx) { if (maybeTx) {
return maybeTx.get(); return maybeTx.value();
} else { } else {
throw JSONRPCError(RPC_WALLET_ERROR, "Failed to build transaction: " + GetError()); throw JSONRPCError(RPC_WALLET_ERROR, "Failed to build transaction: " + GetError());
} }
@ -139,7 +139,7 @@ CTransaction TransactionBuilderResult::GetTxOrThrow() {
std::string TransactionBuilderResult::GetError() { std::string TransactionBuilderResult::GetError() {
if (maybeError) { if (maybeError) {
return maybeError.get(); return maybeError.value();
} else { } else {
// This can only happen if isTx() is true in which case we should not call getError() // This can only happen if isTx() is true in which case we should not call getError()
throw std::runtime_error("getError() was called in TransactionBuilderResult, but the result was not initialized as an error."); throw std::runtime_error("getError() was called in TransactionBuilderResult, but the result was not initialized as an error.");
@ -277,15 +277,15 @@ void TransactionBuilder::SetFee(CAmount fee)
void TransactionBuilder::SendChangeTo(libzcash::SaplingPaymentAddress changeAddr, uint256 ovk) void TransactionBuilder::SendChangeTo(libzcash::SaplingPaymentAddress changeAddr, uint256 ovk)
{ {
saplingChangeAddr = std::make_pair(ovk, changeAddr); saplingChangeAddr = std::make_pair(ovk, changeAddr);
sproutChangeAddr = boost::none; sproutChangeAddr = std::nullopt;
tChangeAddr = boost::none; tChangeAddr = std::nullopt;
} }
void TransactionBuilder::SendChangeTo(libzcash::SproutPaymentAddress changeAddr) void TransactionBuilder::SendChangeTo(libzcash::SproutPaymentAddress changeAddr)
{ {
sproutChangeAddr = changeAddr; sproutChangeAddr = changeAddr;
saplingChangeAddr = boost::none; saplingChangeAddr = std::nullopt;
tChangeAddr = boost::none; tChangeAddr = std::nullopt;
} }
void TransactionBuilder::SendChangeTo(CTxDestination& changeAddr) void TransactionBuilder::SendChangeTo(CTxDestination& changeAddr)
@ -295,8 +295,8 @@ void TransactionBuilder::SendChangeTo(CTxDestination& changeAddr)
} }
tChangeAddr = changeAddr; tChangeAddr = changeAddr;
saplingChangeAddr = boost::none; saplingChangeAddr = std::nullopt;
sproutChangeAddr = boost::none; sproutChangeAddr = std::nullopt;
} }
TransactionBuilderResult TransactionBuilder::Build() TransactionBuilderResult TransactionBuilder::Build()
@ -335,7 +335,7 @@ TransactionBuilderResult TransactionBuilder::Build()
if (saplingChangeAddr) { if (saplingChangeAddr) {
AddSaplingOutput(saplingChangeAddr->first, saplingChangeAddr->second, change); AddSaplingOutput(saplingChangeAddr->first, saplingChangeAddr->second, change);
} else if (sproutChangeAddr) { } else if (sproutChangeAddr) {
AddSproutOutput(sproutChangeAddr.get(), change); AddSproutOutput(sproutChangeAddr.value(), change);
} else if (tChangeAddr) { } else if (tChangeAddr) {
// tChangeAddr has already been validated. // tChangeAddr has already been validated.
AddTransparentOutput(tChangeAddr.value(), change); AddTransparentOutput(tChangeAddr.value(), change);
@ -410,7 +410,7 @@ TransactionBuilderResult TransactionBuilder::Build()
return TransactionBuilderResult("Failed to create output description"); return TransactionBuilderResult("Failed to create output description");
} }
mtx.vShieldedOutput.push_back(odesc.get()); mtx.vShieldedOutput.push_back(odesc.value());
} }
// //
@ -616,7 +616,7 @@ void TransactionBuilder::CreateJSDescriptions()
assert(changeOutputIndex != -1); assert(changeOutputIndex != -1);
assert(changeOutputIndex < prevJoinSplit.commitments.size()); assert(changeOutputIndex < prevJoinSplit.commitments.size());
boost::optional<SproutWitness> changeWitness; std::optional<SproutWitness> changeWitness;
int n = 0; int n = 0;
for (const uint256& commitment : prevJoinSplit.commitments) { for (const uint256& commitment : prevJoinSplit.commitments) {
tree.append(commitment); tree.append(commitment);
@ -624,7 +624,7 @@ void TransactionBuilder::CreateJSDescriptions()
if (!changeWitness && changeOutputIndex == n++) { if (!changeWitness && changeOutputIndex == n++) {
changeWitness = tree.witness(); changeWitness = tree.witness();
} else if (changeWitness) { } else if (changeWitness) {
changeWitness.get().append(commitment); changeWitness.value().append(commitment);
} }
} }
assert(changeWitness.has_value()); assert(changeWitness.has_value());
@ -646,7 +646,7 @@ void TransactionBuilder::CreateJSDescriptions()
(unsigned char)changeOutputIndex); (unsigned char)changeOutputIndex);
auto note = plaintext.note(changeAddress); auto note = plaintext.note(changeAddress);
vjsin[0] = libzcash::JSInput(changeWitness.get(), note, changeKey); vjsin[0] = libzcash::JSInput(changeWitness.value(), note, changeKey);
jsInputValue += plaintext.value(); jsInputValue += plaintext.value();

View File

@ -19,7 +19,7 @@
#include "zcash/Note.hpp" #include "zcash/Note.hpp"
#include "zcash/NoteEncryption.hpp" #include "zcash/NoteEncryption.hpp"
#include <boost/optional.hpp> #include <optional>
#define NO_MEMO {{0xF6}} #define NO_MEMO {{0xF6}}
@ -47,7 +47,7 @@ struct OutputDescriptionInfo {
libzcash::SaplingNote note, libzcash::SaplingNote note,
std::array<unsigned char, ZC_MEMO_SIZE> memo) : ovk(ovk), note(note), memo(memo) {} std::array<unsigned char, ZC_MEMO_SIZE> memo) : ovk(ovk), note(note), memo(memo) {}
boost::optional<OutputDescription> Build(void* ctx); std::optional<OutputDescription> Build(void* ctx);
}; };
struct JSDescriptionInfo { struct JSDescriptionInfo {
@ -91,8 +91,8 @@ struct TransparentInputInfo {
class TransactionBuilderResult { class TransactionBuilderResult {
private: private:
boost::optional<CTransaction> maybeTx; std::optional<CTransaction> maybeTx;
boost::optional<std::string> maybeError; std::optional<std::string> maybeError;
public: public:
TransactionBuilderResult() = delete; TransactionBuilderResult() = delete;
TransactionBuilderResult(const CTransaction& tx); TransactionBuilderResult(const CTransaction& tx);
@ -120,9 +120,9 @@ private:
std::vector<libzcash::JSOutput> jsOutputs; std::vector<libzcash::JSOutput> jsOutputs;
std::vector<TransparentInputInfo> tIns; std::vector<TransparentInputInfo> tIns;
boost::optional<std::pair<uint256, libzcash::SaplingPaymentAddress>> saplingChangeAddr; std::optional<std::pair<uint256, libzcash::SaplingPaymentAddress>> saplingChangeAddr;
boost::optional<libzcash::SproutPaymentAddress> sproutChangeAddr; std::optional<libzcash::SproutPaymentAddress> sproutChangeAddr;
boost::optional<CTxDestination> tChangeAddr; std::optional<CTxDestination> tChangeAddr;
public: public:
TransactionBuilder() {} TransactionBuilder() {}

View File

@ -17,6 +17,8 @@
#include "validationinterface.h" #include "validationinterface.h"
#include "version.h" #include "version.h"
#include <optional>
using namespace std; using namespace std;
CTxMemPoolEntry::CTxMemPoolEntry(): CTxMemPoolEntry::CTxMemPoolEntry():
@ -839,9 +841,9 @@ bool CTxMemPool::IsRecentlyEvicted(const uint256& txId) {
void CTxMemPool::EnsureSizeLimit() { void CTxMemPool::EnsureSizeLimit() {
AssertLockHeld(cs); AssertLockHeld(cs);
boost::optional<uint256> maybeDropTxId; std::optional<uint256> maybeDropTxId;
while ((maybeDropTxId = weightedTxTree->maybeDropRandom()).is_initialized()) { while ((maybeDropTxId = weightedTxTree->maybeDropRandom()).has_value()) {
uint256 txId = maybeDropTxId.get(); uint256 txId = maybeDropTxId.value();
recentlyEvicted->add(txId); recentlyEvicted->add(txId);
std::list<CTransaction> removed; std::list<CTransaction> removed;
remove(mapTx.find(txId)->GetTx(), removed, true); remove(mapTx.find(txId)->GetTx(), removed, true);

View File

@ -295,7 +295,7 @@ CKey AddTestCKeyToKeyStore(CBasicKeyStore& keyStore) {
TestSaplingNote GetTestSaplingNote(const libzcash::SaplingPaymentAddress& pa, CAmount value) { TestSaplingNote GetTestSaplingNote(const libzcash::SaplingPaymentAddress& pa, CAmount value) {
// Generate dummy Sapling note // Generate dummy Sapling note
libzcash::SaplingNote note(pa, value, libzcash::Zip212Enabled::BeforeZip212); libzcash::SaplingNote note(pa, value, libzcash::Zip212Enabled::BeforeZip212);
uint256 cm = note.cmu().get(); uint256 cm = note.cmu().value();
SaplingMerkleTree tree; SaplingMerkleTree tree;
tree.append(cm); tree.append(cm);
return { note, tree }; return { note, tree };

View File

@ -190,7 +190,7 @@ void ThreadNotifyWallets(CBlockIndex *pindexLastTip)
SyncWithWallets(tx, NULL, pindexLastTip->nHeight); SyncWithWallets(tx, NULL, pindexLastTip->nHeight);
} }
// Update cached incremental witnesses // Update cached incremental witnesses
GetMainSignals().ChainTip(pindexLastTip, &block, boost::none); GetMainSignals().ChainTip(pindexLastTip, &block, std::nullopt);
// On to the next block! // On to the next block!
pindexLastTip = pindexLastTip->pprev; pindexLastTip = pindexLastTip->pprev;

View File

@ -6,6 +6,8 @@
#ifndef BITCOIN_VALIDATIONINTERFACE_H #ifndef BITCOIN_VALIDATIONINTERFACE_H
#define BITCOIN_VALIDATIONINTERFACE_H #define BITCOIN_VALIDATIONINTERFACE_H
#include <optional>
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
@ -35,7 +37,7 @@ protected:
virtual void UpdatedBlockTip(const CBlockIndex *pindex) {} virtual void UpdatedBlockTip(const CBlockIndex *pindex) {}
virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock, const int nHeight) {} virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock, const int nHeight) {}
virtual void EraseFromWallet(const uint256 &hash) {} virtual void EraseFromWallet(const uint256 &hash) {}
virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, boost::optional<std::pair<SproutMerkleTree, SaplingMerkleTree>> added) {} virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, std::optional<std::pair<SproutMerkleTree, SaplingMerkleTree>> added) {}
virtual void SetBestChain(const CBlockLocator &locator) {} virtual void SetBestChain(const CBlockLocator &locator) {}
virtual void UpdatedTransaction(const uint256 &hash) {} virtual void UpdatedTransaction(const uint256 &hash) {}
virtual void Inventory(const uint256 &hash) {} virtual void Inventory(const uint256 &hash) {}
@ -58,7 +60,7 @@ struct CMainSignals {
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
boost::signals2::signal<void (const uint256 &)> UpdatedTransaction; boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
/** Notifies listeners of a change to the tip of the active block chain. */ /** Notifies listeners of a change to the tip of the active block chain. */
boost::signals2::signal<void (const CBlockIndex *, const CBlock *, boost::optional<std::pair<SproutMerkleTree, SaplingMerkleTree>>)> ChainTip; boost::signals2::signal<void (const CBlockIndex *, const CBlock *, std::optional<std::pair<SproutMerkleTree, SaplingMerkleTree>>)> ChainTip;
/** Notifies listeners of a new active block chain. */ /** Notifies listeners of a new active block chain. */
boost::signals2::signal<void (const CBlockLocator &)> SetBestChain; boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
/** Notifies listeners about an inventory item being seen on the network. */ /** Notifies listeners about an inventory item being seen on the network. */

View File

@ -6,7 +6,11 @@
extern UniValue signrawtransaction(const UniValue& params, bool fHelp); extern UniValue signrawtransaction(const UniValue& params, bool fHelp);
UniValue SendTransaction(CTransaction& tx, boost::optional<CReserveKey&> reservekey, bool testmode) { UniValue SendTransaction(
CTransaction& tx,
std::optional<std::reference_wrapper<CReserveKey>> reservekey,
bool testmode)
{
UniValue o(UniValue::VOBJ); UniValue o(UniValue::VOBJ);
// Send the transaction // Send the transaction
if (!testmode) { if (!testmode) {
@ -25,7 +29,11 @@ UniValue SendTransaction(CTransaction& tx, boost::optional<CReserveKey&> reserve
return o; return o;
} }
std::pair<CTransaction, UniValue> SignSendRawTransaction(UniValue obj, boost::optional<CReserveKey&> reservekey, bool testmode) { std::pair<CTransaction, UniValue> SignSendRawTransaction(
UniValue obj,
std::optional<std::reference_wrapper<CReserveKey>> reservekey,
bool testmode)
{
// Sign the raw transaction // Sign the raw transaction
UniValue rawtxnValue = find_value(obj, "rawtxn"); UniValue rawtxnValue = find_value(obj, "rawtxn");
if (rawtxnValue.isNull()) { if (rawtxnValue.isNull()) {

View File

@ -9,6 +9,9 @@
#include "univalue.h" #include "univalue.h"
#include "wallet.h" #include "wallet.h"
#include <functional>
#include <optional>
/** /**
* Sends a given transaction. * Sends a given transaction.
* *
@ -18,7 +21,10 @@
* If testmode is true, do not commit the transaction, * If testmode is true, do not commit the transaction,
* return {"test": 1, "txid": tx.GetHash().ToString(), "hex": EncodeHexTx(tx)} * return {"test": 1, "txid": tx.GetHash().ToString(), "hex": EncodeHexTx(tx)}
*/ */
UniValue SendTransaction(CTransaction& tx, boost::optional<CReserveKey&> reservekey, bool testmode); UniValue SendTransaction(
CTransaction& tx,
std::optional<std::reference_wrapper<CReserveKey>> reservekey,
bool testmode);
/** /**
* Sign and send a raw transaction. * Sign and send a raw transaction.
@ -26,6 +32,9 @@ UniValue SendTransaction(CTransaction& tx, boost::optional<CReserveKey&> reserve
* *
* Returns a pair of (the parsed transaction, and the result of sending) * Returns a pair of (the parsed transaction, and the result of sending)
*/ */
std::pair<CTransaction, UniValue> SignSendRawTransaction(UniValue obj, boost::optional<CReserveKey&> reservekey, bool testmode); std::pair<CTransaction, UniValue> SignSendRawTransaction(
UniValue obj,
std::optional<std::reference_wrapper<CReserveKey>> reservekey,
bool testmode);
#endif /* ASYNCRPCOPERATION_COMMON_H */ #endif /* ASYNCRPCOPERATION_COMMON_H */

View File

@ -57,7 +57,7 @@ int mta_find_output(UniValue obj, int n)
} }
AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress( AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
boost::optional<TransactionBuilder> builder, std::optional<TransactionBuilder> builder,
CMutableTransaction contextualTx, CMutableTransaction contextualTx,
std::vector<MergeToAddressInputUTXO> utxoInputs, std::vector<MergeToAddressInputUTXO> utxoInputs,
std::vector<MergeToAddressInputSproutNote> sproutNoteInputs, std::vector<MergeToAddressInputSproutNote> sproutNoteInputs,
@ -91,7 +91,7 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
isUsingBuilder_ = false; isUsingBuilder_ = false;
if (builder) { if (builder) {
isUsingBuilder_ = true; isUsingBuilder_ = true;
builder_ = builder.get(); builder_ = builder.value();
} }
KeyIO keyIO(Params()); KeyIO keyIO(Params());
@ -291,7 +291,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
builder_.AddTransparentInput(outPoint, scriptPubKey, amount); builder_.AddTransparentInput(outPoint, scriptPubKey, amount);
} }
boost::optional<uint256> ovk; std::optional<uint256> ovk;
// Select Sapling notes // Select Sapling notes
std::vector<SaplingOutPoint> saplingOPs; std::vector<SaplingOutPoint> saplingOPs;
std::vector<SaplingNote> saplingNotes; std::vector<SaplingNote> saplingNotes;
@ -308,7 +308,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
// Fetch Sapling anchor and witnesses // Fetch Sapling anchor and witnesses
uint256 anchor; uint256 anchor;
std::vector<boost::optional<SaplingWitness>> witnesses; std::vector<std::optional<SaplingWitness>> witnesses;
{ {
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->GetSaplingNoteWitnesses(saplingOPs, witnesses, anchor); pwalletMain->GetSaplingNoteWitnesses(saplingOPs, witnesses, anchor);
@ -319,7 +319,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
if (!witnesses[i]) { if (!witnesses[i]) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing witness for Sapling note"); throw JSONRPCError(RPC_WALLET_ERROR, "Missing witness for Sapling note");
} }
builder_.AddSaplingSpend(expsks[i], saplingNotes[i], anchor, witnesses[i].get()); builder_.AddSaplingSpend(expsks[i], saplingNotes[i], anchor, witnesses[i].value());
} }
if (isToTaddr_) { if (isToTaddr_) {
@ -344,13 +344,13 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
if (!ovk) { if (!ovk) {
throw JSONRPCError(RPC_WALLET_ERROR, "Sending to a Sapling address requires an ovk."); throw JSONRPCError(RPC_WALLET_ERROR, "Sending to a Sapling address requires an ovk.");
} }
builder_.AddSaplingOutput(ovk.get(), *saplingPaymentAddress, sendAmount, hexMemo); builder_.AddSaplingOutput(ovk.value(), *saplingPaymentAddress, sendAmount, hexMemo);
} }
// Build the transaction // Build the transaction
tx_ = builder_.Build().GetTxOrThrow(); tx_ = builder_.Build().GetTxOrThrow();
UniValue sendResult = SendTransaction(tx_, boost::none, testmode); UniValue sendResult = SendTransaction(tx_, std::nullopt, testmode);
set_result(sendResult); set_result(sendResult);
return true; return true;
@ -370,7 +370,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
if (isPureTaddrOnlyTx) { if (isPureTaddrOnlyTx) {
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
obj.pushKV("rawtxn", EncodeHexTx(tx_)); obj.pushKV("rawtxn", EncodeHexTx(tx_));
auto txAndResult = SignSendRawTransaction(obj, boost::none, testmode); auto txAndResult = SignSendRawTransaction(obj, std::nullopt, testmode);
tx_ = txAndResult.first; tx_ = txAndResult.first;
set_result(txAndResult.second); set_result(txAndResult.second);
return true; return true;
@ -408,7 +408,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
info.vjsout.push_back(jso); info.vjsout.push_back(jso);
UniValue obj = perform_joinsplit(info); UniValue obj = perform_joinsplit(info);
auto txAndResult = SignSendRawTransaction(obj, boost::none, testmode); auto txAndResult = SignSendRawTransaction(obj, std::nullopt, testmode);
tx_ = txAndResult.first; tx_ = txAndResult.first;
set_result(txAndResult.second); set_result(txAndResult.second);
return true; return true;
@ -433,7 +433,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
JSOutPoint jso = std::get<0>(t); JSOutPoint jso = std::get<0>(t);
std::vector<JSOutPoint> vOutPoints = {jso}; std::vector<JSOutPoint> vOutPoints = {jso};
uint256 inputAnchor; uint256 inputAnchor;
std::vector<boost::optional<SproutWitness>> vInputWitnesses; std::vector<std::optional<SproutWitness>> vInputWitnesses;
pwalletMain->GetSproutNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor); pwalletMain->GetSproutNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor);
jsopWitnessAnchorMap[jso.ToString()] = MergeToAddressWitnessAnchorData{vInputWitnesses[0], inputAnchor}; jsopWitnessAnchorMap[jso.ToString()] = MergeToAddressWitnessAnchorData{vInputWitnesses[0], inputAnchor};
} }
@ -497,7 +497,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
CAmount jsInputValue = 0; CAmount jsInputValue = 0;
uint256 jsAnchor; uint256 jsAnchor;
std::vector<boost::optional<SproutWitness>> witnesses; std::vector<std::optional<SproutWitness>> witnesses;
JSDescription prevJoinSplit; JSDescription prevJoinSplit;
@ -528,7 +528,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
} }
assert(changeOutputIndex != -1); assert(changeOutputIndex != -1);
boost::optional<SproutWitness> changeWitness; std::optional<SproutWitness> changeWitness;
int n = 0; int n = 0;
for (const uint256& commitment : prevJoinSplit.commitments) { for (const uint256& commitment : prevJoinSplit.commitments) {
tree.append(commitment); tree.append(commitment);
@ -536,7 +536,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
if (!changeWitness && changeOutputIndex == n++) { if (!changeWitness && changeOutputIndex == n++) {
changeWitness = tree.witness(); changeWitness = tree.witness();
} else if (changeWitness) { } else if (changeWitness) {
changeWitness.get().append(commitment); changeWitness.value().append(commitment);
} }
} }
if (changeWitness) { if (changeWitness) {
@ -581,7 +581,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
std::vector<SproutNote> vInputNotes; std::vector<SproutNote> vInputNotes;
std::vector<SproutSpendingKey> vInputZKeys; std::vector<SproutSpendingKey> vInputZKeys;
std::vector<JSOutPoint> vOutPoints; std::vector<JSOutPoint> vOutPoints;
std::vector<boost::optional<SproutWitness>> vInputWitnesses; std::vector<std::optional<SproutWitness>> vInputWitnesses;
uint256 inputAnchor; uint256 inputAnchor;
int numInputsNeeded = (jsChange > 0) ? 1 : 0; int numInputsNeeded = (jsChange > 0) ? 1 : 0;
while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) {
@ -638,7 +638,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
if (!optionalWitness) { if (!optionalWitness) {
throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null"); throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null");
} }
SproutWitness w = *optionalWitness; // could use .get(); SproutWitness w = *optionalWitness; // could use .value();
if (jsChange > 0) { if (jsChange > 0) {
for (const uint256& commitment : previousCommitments) { for (const uint256& commitment : previousCommitments) {
w.append(commitment); w.append(commitment);
@ -712,7 +712,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
assert(zInputsDeque.size() == 0); assert(zInputsDeque.size() == 0);
assert(vpubNewProcessed); assert(vpubNewProcessed);
auto txAndResult = SignSendRawTransaction(obj, boost::none, testmode); auto txAndResult = SignSendRawTransaction(obj, std::nullopt, testmode);
tx_ = txAndResult.first; tx_ = txAndResult.first;
set_result(txAndResult.second); set_result(txAndResult.second);
return true; return true;
@ -721,7 +721,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info) UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info)
{ {
std::vector<boost::optional<SproutWitness>> witnesses; std::vector<std::optional<SproutWitness>> witnesses;
uint256 anchor; uint256 anchor;
{ {
LOCK(cs_main); LOCK(cs_main);
@ -733,7 +733,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInf
UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info, std::vector<JSOutPoint>& outPoints) UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info, std::vector<JSOutPoint>& outPoints)
{ {
std::vector<boost::optional<SproutWitness>> witnesses; std::vector<std::optional<SproutWitness>> witnesses;
uint256 anchor; uint256 anchor;
{ {
LOCK(cs_main); LOCK(cs_main);
@ -744,7 +744,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInf
UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
MergeToAddressJSInfo& info, MergeToAddressJSInfo& info,
std::vector<boost::optional<SproutWitness>> witnesses, std::vector<std::optional<SproutWitness>> witnesses,
uint256 anchor) uint256 anchor)
{ {
if (anchor.IsNull()) { if (anchor.IsNull()) {

View File

@ -15,6 +15,7 @@
#include "zcash/JoinSplit.hpp" #include "zcash/JoinSplit.hpp"
#include <array> #include <array>
#include <optional>
#include <tuple> #include <tuple>
#include <unordered_map> #include <unordered_map>
@ -48,7 +49,7 @@ struct MergeToAddressJSInfo {
// A struct to help us track the witness and anchor for a given JSOutPoint // A struct to help us track the witness and anchor for a given JSOutPoint
struct MergeToAddressWitnessAnchorData { struct MergeToAddressWitnessAnchorData {
boost::optional<SproutWitness> witness; std::optional<SproutWitness> witness;
uint256 anchor; uint256 anchor;
}; };
@ -56,7 +57,7 @@ class AsyncRPCOperation_mergetoaddress : public AsyncRPCOperation
{ {
public: public:
AsyncRPCOperation_mergetoaddress( AsyncRPCOperation_mergetoaddress(
boost::optional<TransactionBuilder> builder, std::optional<TransactionBuilder> builder,
CMutableTransaction contextualTx, CMutableTransaction contextualTx,
std::vector<MergeToAddressInputUTXO> utxoInputs, std::vector<MergeToAddressInputUTXO> utxoInputs,
std::vector<MergeToAddressInputSproutNote> sproutNoteInputs, std::vector<MergeToAddressInputSproutNote> sproutNoteInputs,
@ -120,7 +121,7 @@ private:
// JoinSplit where you have the witnesses and anchor // JoinSplit where you have the witnesses and anchor
UniValue perform_joinsplit( UniValue perform_joinsplit(
MergeToAddressJSInfo& info, MergeToAddressJSInfo& info,
std::vector<boost::optional<SproutWitness>> witnesses, std::vector<std::optional<SproutWitness>> witnesses,
uint256 anchor); uint256 anchor);
void lock_utxos(); void lock_utxos();
@ -178,7 +179,7 @@ public:
UniValue perform_joinsplit( UniValue perform_joinsplit(
MergeToAddressJSInfo& info, MergeToAddressJSInfo& info,
std::vector<boost::optional<SproutWitness>> witnesses, std::vector<std::optional<SproutWitness>> witnesses,
uint256 anchor) uint256 anchor)
{ {
return delegate->perform_joinsplit(info, witnesses, anchor); return delegate->perform_joinsplit(info, witnesses, anchor);

View File

@ -11,6 +11,7 @@
#include "utilmoneystr.h" #include "utilmoneystr.h"
#include "wallet.h" #include "wallet.h"
#include <optional>
#include <variant> #include <variant>
const CAmount FEE = 10000; const CAmount FEE = 10000;
@ -72,7 +73,7 @@ bool AsyncRPCOperation_saplingmigration::main_impl() {
LogPrint("zrpcunsafe", "%s: Beginning AsyncRPCOperation_saplingmigration.\n", getId()); LogPrint("zrpcunsafe", "%s: Beginning AsyncRPCOperation_saplingmigration.\n", getId());
auto consensusParams = Params().GetConsensus(); auto consensusParams = Params().GetConsensus();
auto nextActivationHeight = NextActivationHeight(targetHeight_, consensusParams); auto nextActivationHeight = NextActivationHeight(targetHeight_, consensusParams);
if (nextActivationHeight && targetHeight_ + MIGRATION_EXPIRY_DELTA >= nextActivationHeight.get()) { if (nextActivationHeight && targetHeight_ + MIGRATION_EXPIRY_DELTA >= nextActivationHeight.value()) {
LogPrint("zrpcunsafe", "%s: Migration txs would be created before a NU activation but may expire after. Skipping this round.\n", getId()); LogPrint("zrpcunsafe", "%s: Migration txs would be created before a NU activation but may expire after. Skipping this round.\n", getId());
setMigrationResult(0, 0, std::vector<std::string>()); setMigrationResult(0, 0, std::vector<std::string>());
return true; return true;
@ -139,9 +140,9 @@ bool AsyncRPCOperation_saplingmigration::main_impl() {
// for each Sprout JoinSplit description // for each Sprout JoinSplit description
// TODO: the above functionality (in comment) is not implemented in zcashd // TODO: the above functionality (in comment) is not implemented in zcashd
uint256 inputAnchor; uint256 inputAnchor;
std::vector<boost::optional<SproutWitness>> vInputWitnesses; std::vector<std::optional<SproutWitness>> vInputWitnesses;
pwalletMain->GetSproutNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor); pwalletMain->GetSproutNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor);
builder.AddSproutInput(sproutSk, sproutEntry.note, vInputWitnesses[0].get()); builder.AddSproutInput(sproutSk, sproutEntry.note, vInputWitnesses[0].value());
} }
// The amount chosen *includes* the 0.0001 ZEC fee for this transaction, i.e. // The amount chosen *includes* the 0.0001 ZEC fee for this transaction, i.e.
// the value of the Sapling output will be 0.0001 ZEC less. // the value of the Sapling output will be 0.0001 ZEC less.

View File

@ -58,7 +58,7 @@ int find_output(UniValue obj, int n) {
} }
AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
boost::optional<TransactionBuilder> builder, std::optional<TransactionBuilder> builder,
CMutableTransaction contextualTx, CMutableTransaction contextualTx,
std::string fromAddress, std::string fromAddress,
std::vector<SendManyRecipient> tOutputs, std::vector<SendManyRecipient> tOutputs,
@ -85,7 +85,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
isUsingBuilder_ = false; isUsingBuilder_ = false;
if (builder) { if (builder) {
isUsingBuilder_ = true; isUsingBuilder_ = true;
builder_ = builder.get(); builder_ = builder.value();
} }
KeyIO keyIO(Params()); KeyIO keyIO(Params());
@ -104,7 +104,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
isfromzaddr_ = true; isfromzaddr_ = true;
frompaymentaddress_ = address; frompaymentaddress_ = address;
spendingkey_ = std::visit(GetSpendingKeyForPaymentAddress(pwalletMain), address).get(); spendingkey_ = std::visit(GetSpendingKeyForPaymentAddress(pwalletMain), address).value();
} else { } else {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address");
} }
@ -410,7 +410,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
// Fetch Sapling anchor and witnesses // Fetch Sapling anchor and witnesses
uint256 anchor; uint256 anchor;
std::vector<boost::optional<SaplingWitness>> witnesses; std::vector<std::optional<SaplingWitness>> witnesses;
{ {
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->GetSaplingNoteWitnesses(ops, witnesses, anchor); pwalletMain->GetSaplingNoteWitnesses(ops, witnesses, anchor);
@ -421,7 +421,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
if (!witnesses[i]) { if (!witnesses[i]) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing witness for Sapling note"); throw JSONRPCError(RPC_WALLET_ERROR, "Missing witness for Sapling note");
} }
builder_.AddSaplingSpend(expsk, notes[i], anchor, witnesses[i].get()); builder_.AddSaplingSpend(expsk, notes[i], anchor, witnesses[i].value());
} }
// Add Sapling outputs // Add Sapling outputs
@ -533,7 +533,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
JSOutPoint jso = t.point; JSOutPoint jso = t.point;
std::vector<JSOutPoint> vOutPoints = { jso }; std::vector<JSOutPoint> vOutPoints = { jso };
uint256 inputAnchor; uint256 inputAnchor;
std::vector<boost::optional<SproutWitness>> vInputWitnesses; std::vector<std::optional<SproutWitness>> vInputWitnesses;
pwalletMain->GetSproutNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor); pwalletMain->GetSproutNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor);
jsopWitnessAnchorMap[ jso.ToString() ] = WitnessAnchorData{ vInputWitnesses[0], inputAnchor }; jsopWitnessAnchorMap[ jso.ToString() ] = WitnessAnchorData{ vInputWitnesses[0], inputAnchor };
} }
@ -644,7 +644,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
CAmount jsInputValue = 0; CAmount jsInputValue = 0;
uint256 jsAnchor; uint256 jsAnchor;
std::vector<boost::optional<SproutWitness>> witnesses; std::vector<std::optional<SproutWitness>> witnesses;
JSDescription prevJoinSplit; JSDescription prevJoinSplit;
@ -675,7 +675,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
} }
assert(changeOutputIndex != -1); assert(changeOutputIndex != -1);
boost::optional<SproutWitness> changeWitness; std::optional<SproutWitness> changeWitness;
int n = 0; int n = 0;
for (const uint256& commitment : prevJoinSplit.commitments) { for (const uint256& commitment : prevJoinSplit.commitments) {
tree.append(commitment); tree.append(commitment);
@ -683,7 +683,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
if (!changeWitness && changeOutputIndex == n++) { if (!changeWitness && changeOutputIndex == n++) {
changeWitness = tree.witness(); changeWitness = tree.witness();
} else if (changeWitness) { } else if (changeWitness) {
changeWitness.get().append(commitment); changeWitness.value().append(commitment);
} }
} }
if (changeWitness) { if (changeWitness) {
@ -727,7 +727,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
// //
std::vector<SproutNote> vInputNotes; std::vector<SproutNote> vInputNotes;
std::vector<JSOutPoint> vOutPoints; std::vector<JSOutPoint> vOutPoints;
std::vector<boost::optional<SproutWitness>> vInputWitnesses; std::vector<std::optional<SproutWitness>> vInputWitnesses;
uint256 inputAnchor; uint256 inputAnchor;
int numInputsNeeded = (jsChange>0) ? 1 : 0; int numInputsNeeded = (jsChange>0) ? 1 : 0;
while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) {
@ -784,7 +784,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
if (!optionalWitness) { if (!optionalWitness) {
throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null"); throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null");
} }
SproutWitness w = *optionalWitness; // could use .get(); SproutWitness w = *optionalWitness; // could use .value();
if (jsChange > 0) { if (jsChange > 0) {
for (const uint256& commitment : previousCommitments) { for (const uint256& commitment : previousCommitments) {
w.append(commitment); w.append(commitment);
@ -885,7 +885,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
assert(zOutputsDeque.size() == 0); assert(zOutputsDeque.size() == 0);
assert(vpubNewProcessed); assert(vpubNewProcessed);
auto txAndResult = SignSendRawTransaction(obj, boost::none, testmode); auto txAndResult = SignSendRawTransaction(obj, std::nullopt, testmode);
tx_ = txAndResult.first; tx_ = txAndResult.first;
set_result(txAndResult.second); set_result(txAndResult.second);
return true; return true;
@ -1000,7 +1000,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() {
} }
UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info) { UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info) {
std::vector<boost::optional < SproutWitness>> witnesses; std::vector<std::optional < SproutWitness>> witnesses;
uint256 anchor; uint256 anchor;
{ {
LOCK(cs_main); LOCK(cs_main);
@ -1011,7 +1011,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info
UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info, std::vector<JSOutPoint> & outPoints) { UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info, std::vector<JSOutPoint> & outPoints) {
std::vector<boost::optional < SproutWitness>> witnesses; std::vector<std::optional < SproutWitness>> witnesses;
uint256 anchor; uint256 anchor;
{ {
LOCK(cs_main); LOCK(cs_main);
@ -1022,7 +1022,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info
UniValue AsyncRPCOperation_sendmany::perform_joinsplit( UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
AsyncJoinSplitInfo & info, AsyncJoinSplitInfo & info,
std::vector<boost::optional < SproutWitness>> witnesses, std::vector<std::optional < SproutWitness>> witnesses,
uint256 anchor) uint256 anchor)
{ {
if (anchor.IsNull()) { if (anchor.IsNull()) {

View File

@ -15,6 +15,7 @@
#include "wallet/paymentdisclosure.h" #include "wallet/paymentdisclosure.h"
#include <array> #include <array>
#include <optional>
#include <unordered_map> #include <unordered_map>
#include <tuple> #include <tuple>
@ -68,14 +69,14 @@ struct AsyncJoinSplitInfo
// A struct to help us track the witness and anchor for a given JSOutPoint // A struct to help us track the witness and anchor for a given JSOutPoint
struct WitnessAnchorData { struct WitnessAnchorData {
boost::optional<SproutWitness> witness; std::optional<SproutWitness> witness;
uint256 anchor; uint256 anchor;
}; };
class AsyncRPCOperation_sendmany : public AsyncRPCOperation { class AsyncRPCOperation_sendmany : public AsyncRPCOperation {
public: public:
AsyncRPCOperation_sendmany( AsyncRPCOperation_sendmany(
boost::optional<TransactionBuilder> builder, std::optional<TransactionBuilder> builder,
CMutableTransaction contextualTx, CMutableTransaction contextualTx,
std::string fromAddress, std::string fromAddress,
std::vector<SendManyRecipient> tOutputs, std::vector<SendManyRecipient> tOutputs,
@ -146,7 +147,7 @@ private:
// JoinSplit where you have the witnesses and anchor // JoinSplit where you have the witnesses and anchor
UniValue perform_joinsplit( UniValue perform_joinsplit(
AsyncJoinSplitInfo & info, AsyncJoinSplitInfo & info,
std::vector<boost::optional < SproutWitness>> witnesses, std::vector<std::optional < SproutWitness>> witnesses,
uint256 anchor); uint256 anchor);
// payment disclosure! // payment disclosure!
@ -205,7 +206,7 @@ public:
UniValue perform_joinsplit( UniValue perform_joinsplit(
AsyncJoinSplitInfo & info, AsyncJoinSplitInfo & info,
std::vector<boost::optional < SproutWitness>> witnesses, std::vector<std::optional < SproutWitness>> witnesses,
uint256 anchor) uint256 anchor)
{ {
return delegate->perform_joinsplit(info, witnesses, anchor); return delegate->perform_joinsplit(info, witnesses, anchor);

View File

@ -34,6 +34,7 @@
#include <array> #include <array>
#include <iostream> #include <iostream>
#include <chrono> #include <chrono>
#include <optional>
#include <thread> #include <thread>
#include <string> #include <string>
#include <variant> #include <variant>
@ -223,7 +224,7 @@ bool ShieldToAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) co
info.vjsout.push_back(jso); info.vjsout.push_back(jso);
UniValue obj = m_op->perform_joinsplit(info); UniValue obj = m_op->perform_joinsplit(info);
auto txAndResult = SignSendRawTransaction(obj, boost::none, m_op->testmode); auto txAndResult = SignSendRawTransaction(obj, std::nullopt, m_op->testmode);
m_op->tx_ = txAndResult.first; m_op->tx_ = txAndResult.first;
m_op->set_result(txAndResult.second); m_op->set_result(txAndResult.second);
return true; return true;
@ -251,7 +252,7 @@ bool ShieldToAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) c
// Build the transaction // Build the transaction
m_op->tx_ = m_op->builder_.Build().GetTxOrThrow(); m_op->tx_ = m_op->builder_.Build().GetTxOrThrow();
UniValue sendResult = SendTransaction(m_op->tx_, boost::none, m_op->testmode); UniValue sendResult = SendTransaction(m_op->tx_, std::nullopt, m_op->testmode);
m_op->set_result(sendResult); m_op->set_result(sendResult);
return true; return true;

View File

@ -15,6 +15,8 @@
#include "zcash/Note.hpp" #include "zcash/Note.hpp"
#include "zcash/NoteEncryption.hpp" #include "zcash/NoteEncryption.hpp"
#include <optional>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
using ::testing::Return; using ::testing::Return;
@ -106,8 +108,8 @@ std::pair<JSOutPoint, SaplingOutPoint> CreateValidBlock(TestWallet& wallet,
std::pair<uint256, uint256> GetWitnessesAndAnchors(TestWallet& wallet, std::pair<uint256, uint256> GetWitnessesAndAnchors(TestWallet& wallet,
std::vector<JSOutPoint>& sproutNotes, std::vector<JSOutPoint>& sproutNotes,
std::vector<SaplingOutPoint>& saplingNotes, std::vector<SaplingOutPoint>& saplingNotes,
std::vector<boost::optional<SproutWitness>>& sproutWitnesses, std::vector<std::optional<SproutWitness>>& sproutWitnesses,
std::vector<boost::optional<SaplingWitness>>& saplingWitnesses) { std::vector<std::optional<SaplingWitness>>& saplingWitnesses) {
sproutWitnesses.clear(); sproutWitnesses.clear();
saplingWitnesses.clear(); saplingWitnesses.clear();
uint256 sproutAnchor; uint256 sproutAnchor;
@ -363,7 +365,7 @@ TEST(WalletTests, SetSaplingNoteAddrsInCWalletTx) {
auto pk = sk.DefaultAddress(); auto pk = sk.DefaultAddress();
libzcash::SaplingNote note(pk, 50000, zip_212_enabled[ver]); libzcash::SaplingNote note(pk, 50000, zip_212_enabled[ver]);
auto cm = note.cmu().get(); auto cm = note.cmu().value();
SaplingMerkleTree tree; SaplingMerkleTree tree;
tree.append(cm); tree.append(cm);
auto anchor = tree.root(); auto anchor = tree.root();
@ -371,7 +373,7 @@ TEST(WalletTests, SetSaplingNoteAddrsInCWalletTx) {
auto nf = note.nullifier(fvk, witness.position()); auto nf = note.nullifier(fvk, witness.position());
ASSERT_TRUE(nf); ASSERT_TRUE(nf);
uint256 nullifier = nf.get(); uint256 nullifier = nf.value();
auto builder = TransactionBuilder(consensusParams, 1); auto builder = TransactionBuilder(consensusParams, 1);
builder.AddSaplingSpend(expsk, note, anchor, witness); builder.AddSaplingSpend(expsk, note, anchor, witness);
@ -643,7 +645,7 @@ TEST(WalletTests, GetConflictedSaplingNotes) {
// Generate note A // Generate note A
libzcash::SaplingNote note(pk, 50000, zip_212_enabled[ver]); libzcash::SaplingNote note(pk, 50000, zip_212_enabled[ver]);
auto cm = note.cmu().get(); auto cm = note.cmu().value();
SaplingMerkleTree saplingTree; SaplingMerkleTree saplingTree;
saplingTree.append(cm); saplingTree.append(cm);
auto anchor = saplingTree.root(); auto anchor = saplingTree.root();
@ -693,15 +695,15 @@ TEST(WalletTests, GetConflictedSaplingNotes) {
wtx.vShieldedOutput[0].ephemeralKey, wtx.vShieldedOutput[0].ephemeralKey,
wtx.vShieldedOutput[0].cmu); wtx.vShieldedOutput[0].cmu);
ASSERT_EQ(static_cast<bool>(maybe_pt), true); ASSERT_EQ(static_cast<bool>(maybe_pt), true);
auto maybe_note = maybe_pt.get().note(ivk); auto maybe_note = maybe_pt.value().note(ivk);
ASSERT_EQ(static_cast<bool>(maybe_note), true); ASSERT_EQ(static_cast<bool>(maybe_note), true);
auto note2 = maybe_note.get(); auto note2 = maybe_note.value();
SaplingOutPoint sop0(wtx.GetHash(), 0); SaplingOutPoint sop0(wtx.GetHash(), 0);
auto spend_note_witness = wtx.mapSaplingNoteData[sop0].witnesses.front(); auto spend_note_witness = wtx.mapSaplingNoteData[sop0].witnesses.front();
auto maybe_nf = note2.nullifier(extfvk.fvk, spend_note_witness.position()); auto maybe_nf = note2.nullifier(extfvk.fvk, spend_note_witness.position());
ASSERT_EQ(static_cast<bool>(maybe_nf), true); ASSERT_EQ(static_cast<bool>(maybe_nf), true);
auto nullifier2 = maybe_nf.get(); auto nullifier2 = maybe_nf.value();
anchor = saplingTree.root(); anchor = saplingTree.root();
@ -813,7 +815,7 @@ TEST(WalletTests, SaplingNullifierIsSpent) {
// Manually compute the nullifier based on the known position // Manually compute the nullifier based on the known position
auto nf = testNote.note.nullifier(extfvk.fvk, testNote.tree.witness().position()); auto nf = testNote.note.nullifier(extfvk.fvk, testNote.tree.witness().position());
ASSERT_TRUE(nf); ASSERT_TRUE(nf);
uint256 nullifier = nf.get(); uint256 nullifier = nf.value();
// Verify note has not been spent // Verify note has not been spent
EXPECT_FALSE(wallet.IsSaplingSpent(nullifier)); EXPECT_FALSE(wallet.IsSaplingSpent(nullifier));
@ -898,7 +900,7 @@ TEST(WalletTests, NavigateFromSaplingNullifierToNote) {
// Manually compute the nullifier based on the expected position // Manually compute the nullifier based on the expected position
auto nf = testNote.note.nullifier(extfvk.fvk, testNote.tree.witness().position()); auto nf = testNote.note.nullifier(extfvk.fvk, testNote.tree.witness().position());
ASSERT_TRUE(nf); ASSERT_TRUE(nf);
uint256 nullifier = nf.get(); uint256 nullifier = nf.value();
// Verify dummy note is unspent // Verify dummy note is unspent
EXPECT_FALSE(wallet.IsSaplingSpent(nullifier)); EXPECT_FALSE(wallet.IsSaplingSpent(nullifier));
@ -950,7 +952,7 @@ TEST(WalletTests, NavigateFromSaplingNullifierToNote) {
EXPECT_EQ(hash, op.hash); EXPECT_EQ(hash, op.hash);
EXPECT_EQ(1, nd.witnesses.size()); EXPECT_EQ(1, nd.witnesses.size());
ASSERT_TRUE(nd.nullifier); ASSERT_TRUE(nd.nullifier);
auto nf = nd.nullifier.get(); auto nf = nd.nullifier.value();
EXPECT_EQ(1, wallet.mapSaplingNullifiersToNotes.count(nf)); EXPECT_EQ(1, wallet.mapSaplingNullifiersToNotes.count(nf));
EXPECT_EQ(op.hash, wallet.mapSaplingNullifiersToNotes[nf].hash); EXPECT_EQ(op.hash, wallet.mapSaplingNullifiersToNotes[nf].hash);
EXPECT_EQ(op.n, wallet.mapSaplingNullifiersToNotes[nf].n); EXPECT_EQ(op.n, wallet.mapSaplingNullifiersToNotes[nf].n);
@ -1016,7 +1018,7 @@ TEST(WalletTests, SpentSaplingNoteIsFromMe) {
// Generate Sapling note A // Generate Sapling note A
libzcash::SaplingNote note(pk, 50000, zip_212_enabled[ver]); libzcash::SaplingNote note(pk, 50000, zip_212_enabled[ver]);
auto cm = note.cmu().get(); auto cm = note.cmu().value();
SaplingMerkleTree saplingTree; SaplingMerkleTree saplingTree;
saplingTree.append(cm); saplingTree.append(cm);
auto anchor = saplingTree.root(); auto anchor = saplingTree.root();
@ -1068,7 +1070,7 @@ TEST(WalletTests, SpentSaplingNoteIsFromMe) {
// Manually compute the nullifier and check map entry does not exist // Manually compute the nullifier and check map entry does not exist
auto nf = note.nullifier(extfvk.fvk, witness.position()); auto nf = note.nullifier(extfvk.fvk, witness.position());
ASSERT_TRUE(nf); ASSERT_TRUE(nf);
ASSERT_FALSE(wallet.mapSaplingNullifiersToNotes.count(nf.get())); ASSERT_FALSE(wallet.mapSaplingNullifiersToNotes.count(nf.value()));
// Decrypt note B // Decrypt note B
auto maybe_pt = libzcash::SaplingNotePlaintext::decrypt( auto maybe_pt = libzcash::SaplingNotePlaintext::decrypt(
@ -1079,16 +1081,16 @@ TEST(WalletTests, SpentSaplingNoteIsFromMe) {
wtx.vShieldedOutput[0].ephemeralKey, wtx.vShieldedOutput[0].ephemeralKey,
wtx.vShieldedOutput[0].cmu); wtx.vShieldedOutput[0].cmu);
ASSERT_EQ(static_cast<bool>(maybe_pt), true); ASSERT_EQ(static_cast<bool>(maybe_pt), true);
auto maybe_note = maybe_pt.get().note(ivk); auto maybe_note = maybe_pt.value().note(ivk);
ASSERT_EQ(static_cast<bool>(maybe_note), true); ASSERT_EQ(static_cast<bool>(maybe_note), true);
auto note2 = maybe_note.get(); auto note2 = maybe_note.value();
// Get witness to retrieve position of note B we want to spend // Get witness to retrieve position of note B we want to spend
SaplingOutPoint sop0(wtx.GetHash(), 0); SaplingOutPoint sop0(wtx.GetHash(), 0);
auto spend_note_witness = wtx.mapSaplingNoteData[sop0].witnesses.front(); auto spend_note_witness = wtx.mapSaplingNoteData[sop0].witnesses.front();
auto maybe_nf = note2.nullifier(extfvk.fvk, spend_note_witness.position()); auto maybe_nf = note2.nullifier(extfvk.fvk, spend_note_witness.position());
ASSERT_EQ(static_cast<bool>(maybe_nf), true); ASSERT_EQ(static_cast<bool>(maybe_nf), true);
auto nullifier2 = maybe_nf.get(); auto nullifier2 = maybe_nf.value();
// NOTE: Not updating the anchor results in a core dump. Shouldn't builder just return error? // NOTE: Not updating the anchor results in a core dump. Shouldn't builder just return error?
// *** Error in `./zcash-gtest': double free or corruption (out): 0x00007ffd8755d990 *** // *** Error in `./zcash-gtest': double free or corruption (out): 0x00007ffd8755d990 ***
@ -1168,8 +1170,8 @@ TEST(WalletTests, CachedWitnessesEmptyChain) {
std::vector<JSOutPoint> sproutNotes {jsoutpt, jsoutpt2}; std::vector<JSOutPoint> sproutNotes {jsoutpt, jsoutpt2};
std::vector<SaplingOutPoint> saplingNotes = SetSaplingNoteData(wtx); std::vector<SaplingOutPoint> saplingNotes = SetSaplingNoteData(wtx);
std::vector<boost::optional<SproutWitness>> sproutWitnesses; std::vector<std::optional<SproutWitness>> sproutWitnesses;
std::vector<boost::optional<SaplingWitness>> saplingWitnesses; std::vector<std::optional<SaplingWitness>> saplingWitnesses;
::GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); ::GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses);
@ -1223,8 +1225,8 @@ TEST(WalletTests, CachedWitnessesChainTip) {
// Called to fetch anchor // Called to fetch anchor
std::vector<JSOutPoint> sproutNotes {outpts.first}; std::vector<JSOutPoint> sproutNotes {outpts.first};
std::vector<SaplingOutPoint> saplingNotes {outpts.second}; std::vector<SaplingOutPoint> saplingNotes {outpts.second};
std::vector<boost::optional<SproutWitness>> sproutWitnesses; std::vector<std::optional<SproutWitness>> sproutWitnesses;
std::vector<boost::optional<SaplingWitness>> saplingWitnesses; std::vector<std::optional<SaplingWitness>> saplingWitnesses;
anchors1 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); anchors1 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses);
EXPECT_NE(anchors1.first, anchors1.second); EXPECT_NE(anchors1.first, anchors1.second);
@ -1245,8 +1247,8 @@ TEST(WalletTests, CachedWitnessesChainTip) {
wallet.AddToWallet(wtx, true, NULL); wallet.AddToWallet(wtx, true, NULL);
std::vector<JSOutPoint> sproutNotes {jsoutpt}; std::vector<JSOutPoint> sproutNotes {jsoutpt};
std::vector<boost::optional<SproutWitness>> sproutWitnesses; std::vector<std::optional<SproutWitness>> sproutWitnesses;
std::vector<boost::optional<SaplingWitness>> saplingWitnesses; std::vector<std::optional<SaplingWitness>> saplingWitnesses;
GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses);
@ -1293,8 +1295,8 @@ TEST(WalletTests, CachedWitnessesChainTip) {
// Incrementing with the same block again should not change the cache // Incrementing with the same block again should not change the cache
wallet.IncrementNoteWitnesses(&index2, &block2, sproutTree, saplingTree); wallet.IncrementNoteWitnesses(&index2, &block2, sproutTree, saplingTree);
std::vector<boost::optional<SproutWitness>> sproutWitnesses5; std::vector<std::optional<SproutWitness>> sproutWitnesses5;
std::vector<boost::optional<SaplingWitness>> saplingWitnesses5; std::vector<std::optional<SaplingWitness>> saplingWitnesses5;
auto anchors5 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses5, saplingWitnesses5); auto anchors5 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses5, saplingWitnesses5);
EXPECT_NE(anchors5.first, anchors5.second); EXPECT_NE(anchors5.first, anchors5.second);
@ -1335,8 +1337,8 @@ TEST(WalletTests, CachedWitnessesDecrementFirst) {
// Called to fetch anchor // Called to fetch anchor
std::vector<JSOutPoint> sproutNotes {outpts.first}; std::vector<JSOutPoint> sproutNotes {outpts.first};
std::vector<SaplingOutPoint> saplingNotes {outpts.second}; std::vector<SaplingOutPoint> saplingNotes {outpts.second};
std::vector<boost::optional<SproutWitness>> sproutWitnesses; std::vector<std::optional<SproutWitness>> sproutWitnesses;
std::vector<boost::optional<SaplingWitness>> saplingWitnesses; std::vector<std::optional<SaplingWitness>> saplingWitnesses;
anchors2 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); anchors2 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses);
} }
@ -1355,8 +1357,8 @@ TEST(WalletTests, CachedWitnessesDecrementFirst) {
wallet.AddToWallet(wtx, true, NULL); wallet.AddToWallet(wtx, true, NULL);
std::vector<JSOutPoint> sproutNotes {jsoutpt}; std::vector<JSOutPoint> sproutNotes {jsoutpt};
std::vector<boost::optional<SproutWitness>> sproutWitnesses; std::vector<std::optional<SproutWitness>> sproutWitnesses;
std::vector<boost::optional<SaplingWitness>> saplingWitnesses; std::vector<std::optional<SaplingWitness>> saplingWitnesses;
auto anchors3 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); auto anchors3 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses);
@ -1400,8 +1402,8 @@ TEST(WalletTests, CachedWitnessesCleanIndex) {
SproutMerkleTree sproutRiTree = sproutTree; SproutMerkleTree sproutRiTree = sproutTree;
SaplingMerkleTree saplingTree; SaplingMerkleTree saplingTree;
SaplingMerkleTree saplingRiTree = saplingTree; SaplingMerkleTree saplingRiTree = saplingTree;
std::vector<boost::optional<SproutWitness>> sproutWitnesses; std::vector<std::optional<SproutWitness>> sproutWitnesses;
std::vector<boost::optional<SaplingWitness>> saplingWitnesses; std::vector<std::optional<SaplingWitness>> saplingWitnesses;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSproutSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
@ -1517,8 +1519,8 @@ TEST(WalletTests, ClearNoteWitnessCache) {
saplingNotes.emplace_back(wtx.GetHash(), 1); saplingNotes.emplace_back(wtx.GetHash(), 1);
ASSERT_EQ(saplingNotes.size(), 2); ASSERT_EQ(saplingNotes.size(), 2);
std::vector<boost::optional<SproutWitness>> sproutWitnesses; std::vector<std::optional<SproutWitness>> sproutWitnesses;
std::vector<boost::optional<SaplingWitness>> saplingWitnesses; std::vector<std::optional<SaplingWitness>> saplingWitnesses;
// Before clearing, we should have a witness for one note // Before clearing, we should have a witness for one note
GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses);
@ -2006,9 +2008,9 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) {
// Prepare to spend the note that was just created // Prepare to spend the note that was just created
auto maybe_pt = libzcash::SaplingNotePlaintext::decrypt(consensusParams, fakeIndex.nHeight, tx1.vShieldedOutput[0].encCiphertext, ivk, tx1.vShieldedOutput[0].ephemeralKey, tx1.vShieldedOutput[0].cmu); auto maybe_pt = libzcash::SaplingNotePlaintext::decrypt(consensusParams, fakeIndex.nHeight, tx1.vShieldedOutput[0].encCiphertext, ivk, tx1.vShieldedOutput[0].ephemeralKey, tx1.vShieldedOutput[0].cmu);
ASSERT_EQ(static_cast<bool>(maybe_pt), true); ASSERT_EQ(static_cast<bool>(maybe_pt), true);
auto maybe_note = maybe_pt.get().note(ivk); auto maybe_note = maybe_pt.value().note(ivk);
ASSERT_EQ(static_cast<bool>(maybe_note), true); ASSERT_EQ(static_cast<bool>(maybe_note), true);
auto note = maybe_note.get(); auto note = maybe_note.value();
auto anchor = saplingTree.root(); auto anchor = saplingTree.root();
auto witness = saplingTree.witness(); auto witness = saplingTree.witness();

View File

@ -71,7 +71,7 @@ TEST(WalletZkeysTest, StoreAndLoadSaplingZkeys) {
// If we can't get an early diversified address, we are very unlucky // If we can't get an early diversified address, we are very unlucky
blob88 diversifier; blob88 diversifier;
diversifier.begin()[0] = 10; diversifier.begin()[0] = 10;
auto dpa = sk.ToXFVK().Address(diversifier).get().second; auto dpa = sk.ToXFVK().Address(diversifier).value().second;
// verify wallet only has the default address // verify wallet only has the default address
EXPECT_TRUE(wallet.HaveSaplingIncomingViewingKey(sk.DefaultAddress())); EXPECT_TRUE(wallet.HaveSaplingIncomingViewingKey(sk.DefaultAddress()));
@ -99,7 +99,7 @@ TEST(WalletZkeysTest, StoreAndLoadSaplingZkeys) {
ASSERT_EQ(wallet.mapSaplingZKeyMetadata[ivk2].nCreateTime, now); ASSERT_EQ(wallet.mapSaplingZKeyMetadata[ivk2].nCreateTime, now);
// Load a diversified address for the third key into the wallet // Load a diversified address for the third key into the wallet
auto dpa2 = sk2.ToXFVK().Address(diversifier).get().second; auto dpa2 = sk2.ToXFVK().Address(diversifier).value().second;
EXPECT_TRUE(wallet.HaveSaplingIncomingViewingKey(sk2.DefaultAddress())); EXPECT_TRUE(wallet.HaveSaplingIncomingViewingKey(sk2.DefaultAddress()));
EXPECT_FALSE(wallet.HaveSaplingIncomingViewingKey(dpa2)); EXPECT_FALSE(wallet.HaveSaplingIncomingViewingKey(dpa2));
EXPECT_TRUE(wallet.LoadSaplingPaymentAddress(dpa2, ivk2)); EXPECT_TRUE(wallet.LoadSaplingPaymentAddress(dpa2, ivk2));
@ -451,7 +451,7 @@ TEST(wallet_zkeys_tests, WriteCryptedSaplingZkeyDirectToDb) {
EXPECT_TRUE(wallet.GetSaplingExtendedSpendingKey(address, extsk)); EXPECT_TRUE(wallet.GetSaplingExtendedSpendingKey(address, extsk));
blob88 diversifier; blob88 diversifier;
diversifier.begin()[0] = 10; diversifier.begin()[0] = 10;
auto dpa = extsk.ToXFVK().Address(diversifier).get().second; auto dpa = extsk.ToXFVK().Address(diversifier).value().second;
// Add diversified address to the wallet // Add diversified address to the wallet
auto ivk = extsk.expsk.full_viewing_key().in_viewing_key(); auto ivk = extsk.expsk.full_viewing_key().in_viewing_key();

View File

@ -15,6 +15,7 @@
#include "wallet.h" #include "wallet.h"
#include <fstream> #include <fstream>
#include <optional>
#include <stdint.h> #include <stdint.h>
#include <variant> #include <variant>
@ -397,8 +398,8 @@ UniValue importwallet_impl(const UniValue& params, bool fImportZKeys)
auto spendingkey = keyIO.DecodeSpendingKey(vstr[0]); auto spendingkey = keyIO.DecodeSpendingKey(vstr[0]);
int64_t nTime = DecodeDumpTime(vstr[1]); int64_t nTime = DecodeDumpTime(vstr[1]);
// Only include hdKeypath and seedFpStr if we have both // Only include hdKeypath and seedFpStr if we have both
boost::optional<std::string> hdKeypath = (vstr.size() > 3) ? boost::optional<std::string>(vstr[2]) : boost::none; std::optional<std::string> hdKeypath = (vstr.size() > 3) ? std::optional<std::string>(vstr[2]) : std::nullopt;
boost::optional<std::string> seedFpStr = (vstr.size() > 3) ? boost::optional<std::string>(vstr[3]) : boost::none; std::optional<std::string> seedFpStr = (vstr.size() > 3) ? std::optional<std::string>(vstr[3]) : std::nullopt;
if (IsValidSpendingKey(spendingkey)) { if (IsValidSpendingKey(spendingkey)) {
auto addResult = std::visit( auto addResult = std::visit(
AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus(), nTime, hdKeypath, seedFpStr, true), spendingkey); AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus(), nTime, hdKeypath, seedFpStr, true), spendingkey);
@ -912,7 +913,7 @@ UniValue z_exportkey(const UniValue& params, bool fHelp)
if (!sk) { if (!sk) {
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr"); throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr");
} }
return keyIO.EncodeSpendingKey(sk.get()); return keyIO.EncodeSpendingKey(sk.value());
} }
UniValue z_exportviewingkey(const UniValue& params, bool fHelp) UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
@ -948,7 +949,7 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
auto vk = std::visit(GetViewingKeyForPaymentAddress(pwalletMain), address); auto vk = std::visit(GetViewingKeyForPaymentAddress(pwalletMain), address);
if (vk) { if (vk) {
return keyIO.EncodeViewingKey(vk.get()); return keyIO.EncodeViewingKey(vk.value());
} else { } else {
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr"); throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr");
} }

View File

@ -44,6 +44,7 @@
#include <univalue.h> #include <univalue.h>
#include <numeric> #include <numeric>
#include <optional>
#include <variant> #include <variant>
using namespace std; using namespace std;
@ -2975,7 +2976,7 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp)
SproutNote decrypted_note = npt.note(payment_addr); SproutNote decrypted_note = npt.note(payment_addr);
assert(pwalletMain != NULL); assert(pwalletMain != NULL);
std::vector<boost::optional<SproutWitness>> witnesses; std::vector<std::optional<SproutWitness>> witnesses;
uint256 anchor; uint256 anchor;
uint256 commitment = decrypted_note.cm(); uint256 commitment = decrypted_note.cm();
pwalletMain->WitnessNoteCommitment( pwalletMain->WitnessNoteCommitment(
@ -3084,7 +3085,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
} }
uint256 anchor; uint256 anchor;
std::vector<boost::optional<SproutWitness>> witnesses; std::vector<std::optional<SproutWitness>> witnesses;
pwalletMain->WitnessNoteCommitment(commitments, witnesses, anchor); pwalletMain->WitnessNoteCommitment(commitments, witnesses, anchor);
assert(witnesses.size() == notes.size()); assert(witnesses.size() == notes.size());
@ -3805,7 +3806,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
// We don't need to check the leadbyte here: if wtx exists in // We don't need to check the leadbyte here: if wtx exists in
// the wallet, it must have already passed the leadbyte check // the wallet, it must have already passed the leadbyte check
auto decrypted = wtxPrev.DecryptSaplingNoteWithoutLeadByteCheck(op).get(); auto decrypted = wtxPrev.DecryptSaplingNoteWithoutLeadByteCheck(op).value();
auto notePt = decrypted.first; auto notePt = decrypted.first;
auto pa = decrypted.second; auto pa = decrypted.second;
@ -4257,7 +4258,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
} }
// Builder (used if Sapling addresses are involved) // Builder (used if Sapling addresses are involved)
boost::optional<TransactionBuilder> builder; std::optional<TransactionBuilder> builder;
if (noSproutAddrs) { if (noSproutAddrs) {
builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain); builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain);
} }
@ -5035,7 +5036,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
} }
// Builder (used if Sapling addresses are involved) // Builder (used if Sapling addresses are involved)
boost::optional<TransactionBuilder> builder; std::optional<TransactionBuilder> builder;
if (isToSaplingZaddr || saplingNoteInputs.size() > 0) { if (isToSaplingZaddr || saplingNoteInputs.size() > 0) {
builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain); builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain);
} }

View File

@ -25,6 +25,7 @@
#include <array> #include <array>
#include <chrono> #include <chrono>
#include <optional>
#include <thread> #include <thread>
#include <variant> #include <variant>
@ -1093,26 +1094,26 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
// Test constructor of AsyncRPCOperation_sendmany // Test constructor of AsyncRPCOperation_sendmany
try { try {
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_sendmany(boost::none, mtx, "",{}, {}, -1)); std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_sendmany(std::nullopt, mtx, "",{}, {}, -1));
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "Minconf cannot be negative")); BOOST_CHECK( find_error(objError, "Minconf cannot be negative"));
} }
try { try {
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_sendmany(boost::none, mtx, "",{}, {}, 1)); std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_sendmany(std::nullopt, mtx, "",{}, {}, 1));
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "From address parameter missing")); BOOST_CHECK( find_error(objError, "From address parameter missing"));
} }
try { try {
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, "tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ", {}, {}, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, "tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ", {}, {}, 1) );
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "No recipients")); BOOST_CHECK( find_error(objError, "No recipients"));
} }
try { try {
std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") }; std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, "INVALID", recipients, {}, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, "INVALID", recipients, {}, 1) );
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "Invalid from address")); BOOST_CHECK( find_error(objError, "Invalid from address"));
} }
@ -1120,7 +1121,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
// Testnet payment addresses begin with 'zt'. This test detects an incorrect prefix. // Testnet payment addresses begin with 'zt'. This test detects an incorrect prefix.
try { try {
std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") }; std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, "zcMuhvq8sEkHALuSU2i4NbNQxshSAYrpCExec45ZjtivYPbuiFPwk6WHy4SvsbeZ4siy1WheuRGjtaJmoD1J8bFqNXhsG6U", recipients, {}, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, "zcMuhvq8sEkHALuSU2i4NbNQxshSAYrpCExec45ZjtivYPbuiFPwk6WHy4SvsbeZ4siy1WheuRGjtaJmoD1J8bFqNXhsG6U", recipients, {}, 1) );
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "Invalid from address")); BOOST_CHECK( find_error(objError, "Invalid from address"));
} }
@ -1129,7 +1130,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
// invokes a method on pwalletMain, which is undefined in the google test environment. // invokes a method on pwalletMain, which is undefined in the google test environment.
try { try {
std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") }; std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, "ztjiDe569DPNbyTE6TSdJTaSDhoXEHLGvYoUnBU1wfVNU52TEyT6berYtySkd21njAeEoh8fFJUT42kua9r8EnhBaEKqCpP", recipients, {}, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, "ztjiDe569DPNbyTE6TSdJTaSDhoXEHLGvYoUnBU1wfVNU52TEyT6berYtySkd21njAeEoh8fFJUT42kua9r8EnhBaEKqCpP", recipients, {}, 1) );
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "no spending key found for zaddr")); BOOST_CHECK( find_error(objError, "no spending key found for zaddr"));
} }
@ -1141,7 +1142,7 @@ BOOST_AUTO_TEST_CASE(asyncrpcoperation_sign_send_raw_transaction) {
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
obj.pushKV("rawtxn", raw); obj.pushKV("rawtxn", raw);
// Verify test mode is returning output (since no input taddrs, signed and unsigned are the same). // Verify test mode is returning output (since no input taddrs, signed and unsigned are the same).
std::pair<CTransaction, UniValue> txAndResult = SignSendRawTransaction(obj, boost::none, true); std::pair<CTransaction, UniValue> txAndResult = SignSendRawTransaction(obj, std::nullopt, true);
UniValue resultObj = txAndResult.second.get_obj(); UniValue resultObj = txAndResult.second.get_obj();
std::string hex = find_value(resultObj, "hex").get_str(); std::string hex = find_value(resultObj, "hex").get_str();
BOOST_CHECK_EQUAL(hex, raw); BOOST_CHECK_EQUAL(hex, raw);
@ -1176,7 +1177,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
// there are no utxos to spend // there are no utxos to spend
{ {
std::vector<SendManyRecipient> recipients = { SendManyRecipient(zaddr1,100.0, "DEADBEEF") }; std::vector<SendManyRecipient> recipients = { SendManyRecipient(zaddr1,100.0, "DEADBEEF") };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, taddr1, {}, recipients, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, taddr1, {}, recipients, 1) );
operation->main(); operation->main();
BOOST_CHECK(operation->isFailed()); BOOST_CHECK(operation->isFailed());
std::string msg = operation->getErrorMessage(); std::string msg = operation->getErrorMessage();
@ -1187,7 +1188,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
{ {
try { try {
std::vector<SendManyRecipient> recipients = {SendManyRecipient(taddr1, 100.0, "DEADBEEF")}; std::vector<SendManyRecipient> recipients = {SendManyRecipient(taddr1, 100.0, "DEADBEEF")};
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_sendmany(boost::none, mtx, zaddr1, recipients, {}, 0)); std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_sendmany(std::nullopt, mtx, zaddr1, recipients, {}, 0));
BOOST_CHECK(false); // Fail test if an exception is not thrown BOOST_CHECK(false); // Fail test if an exception is not thrown
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK(find_error(objError, "Minconf cannot be zero when sending from zaddr")); BOOST_CHECK(find_error(objError, "Minconf cannot be zero when sending from zaddr"));
@ -1198,7 +1199,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
// there are no unspent notes to spend // there are no unspent notes to spend
{ {
std::vector<SendManyRecipient> recipients = { SendManyRecipient(taddr1,100.0, "DEADBEEF") }; std::vector<SendManyRecipient> recipients = { SendManyRecipient(taddr1,100.0, "DEADBEEF") };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, zaddr1, recipients, {}, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, zaddr1, recipients, {}, 1) );
operation->main(); operation->main();
BOOST_CHECK(operation->isFailed()); BOOST_CHECK(operation->isFailed());
std::string msg = operation->getErrorMessage(); std::string msg = operation->getErrorMessage();
@ -1208,7 +1209,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
// get_memo_from_hex_string()) // get_memo_from_hex_string())
{ {
std::vector<SendManyRecipient> recipients = { SendManyRecipient(zaddr1,100.0, "DEADBEEF") }; std::vector<SendManyRecipient> recipients = { SendManyRecipient(zaddr1,100.0, "DEADBEEF") };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, zaddr1, recipients, {}, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, zaddr1, recipients, {}, 1) );
std::shared_ptr<AsyncRPCOperation_sendmany> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_sendmany> (operation); std::shared_ptr<AsyncRPCOperation_sendmany> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_sendmany> (operation);
TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr);
@ -1259,7 +1260,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
// add_taddr_change_output_to_tx() will append a vout to a raw transaction // add_taddr_change_output_to_tx() will append a vout to a raw transaction
{ {
std::vector<SendManyRecipient> recipients = { SendManyRecipient(zaddr1,100.0, "DEADBEEF") }; std::vector<SendManyRecipient> recipients = { SendManyRecipient(zaddr1,100.0, "DEADBEEF") };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, zaddr1, recipients, {}, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, zaddr1, recipients, {}, 1) );
std::shared_ptr<AsyncRPCOperation_sendmany> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_sendmany> (operation); std::shared_ptr<AsyncRPCOperation_sendmany> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_sendmany> (operation);
TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr);
@ -1289,7 +1290,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
SendManyRecipient("tmUSbHz3vxnwLvRyNDXbwkZxjVyDodMJEhh",CAmount(4.56), ""), SendManyRecipient("tmUSbHz3vxnwLvRyNDXbwkZxjVyDodMJEhh",CAmount(4.56), ""),
SendManyRecipient("tmYZAXYPCP56Xa5JQWWPZuK7o7bfUQW6kkd",CAmount(7.89), ""), SendManyRecipient("tmYZAXYPCP56Xa5JQWWPZuK7o7bfUQW6kkd",CAmount(7.89), ""),
}; };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, zaddr1, recipients, {}, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, zaddr1, recipients, {}, 1) );
std::shared_ptr<AsyncRPCOperation_sendmany> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_sendmany> (operation); std::shared_ptr<AsyncRPCOperation_sendmany> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_sendmany> (operation);
TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr);
@ -1307,7 +1308,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
// Dummy input so the operation object can be instantiated. // Dummy input so the operation object can be instantiated.
std::vector<SendManyRecipient> recipients = { SendManyRecipient(zaddr1, 0.0005, "ABCD") }; std::vector<SendManyRecipient> recipients = { SendManyRecipient(zaddr1, 0.0005, "ABCD") };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(boost::none, mtx, zaddr1, {}, recipients, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(std::nullopt, mtx, zaddr1, {}, recipients, 1) );
std::shared_ptr<AsyncRPCOperation_sendmany> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_sendmany> (operation); std::shared_ptr<AsyncRPCOperation_sendmany> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_sendmany> (operation);
TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr);
@ -1315,7 +1316,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
static_cast<AsyncRPCOperation_sendmany *>(operation.get())->testmode = true; static_cast<AsyncRPCOperation_sendmany *>(operation.get())->testmode = true;
AsyncJoinSplitInfo info; AsyncJoinSplitInfo info;
std::vector<boost::optional < SproutWitness>> witnesses; std::vector<std::optional<SproutWitness>> witnesses;
uint256 anchor; uint256 anchor;
try { try {
proxy.perform_joinsplit(info, witnesses, anchor); proxy.perform_joinsplit(info, witnesses, anchor);
@ -1854,14 +1855,14 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters)
"mainnet memo"); "mainnet memo");
try { try {
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_mergetoaddress(boost::none, mtx, {}, {}, {}, testnetzaddr, -1 )); std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_mergetoaddress(std::nullopt, mtx, {}, {}, {}, testnetzaddr, -1 ));
BOOST_FAIL("Should have caused an error"); BOOST_FAIL("Should have caused an error");
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "Fee is out of range")); BOOST_CHECK( find_error(objError, "Fee is out of range"));
} }
try { try {
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_mergetoaddress(boost::none, mtx, {}, {}, {}, testnetzaddr, 1)); std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_mergetoaddress(std::nullopt, mtx, {}, {}, {}, testnetzaddr, 1));
BOOST_FAIL("Should have caused an error"); BOOST_FAIL("Should have caused an error");
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "No inputs")); BOOST_CHECK( find_error(objError, "No inputs"));
@ -1871,7 +1872,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters)
try { try {
MergeToAddressRecipient badaddr("", "memo"); MergeToAddressRecipient badaddr("", "memo");
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_mergetoaddress(boost::none, mtx, inputs, {}, {}, badaddr, 1)); std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_mergetoaddress(std::nullopt, mtx, inputs, {}, {}, badaddr, 1));
BOOST_FAIL("Should have caused an error"); BOOST_FAIL("Should have caused an error");
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "Recipient parameter missing")); BOOST_CHECK( find_error(objError, "Recipient parameter missing"));
@ -1884,7 +1885,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters)
// Sprout and Sapling inputs -> throw // Sprout and Sapling inputs -> throw
try { try {
auto operation = new AsyncRPCOperation_mergetoaddress(boost::none, mtx, inputs, sproutNoteInputs, saplingNoteInputs, testnetzaddr, 1); auto operation = new AsyncRPCOperation_mergetoaddress(std::nullopt, mtx, inputs, sproutNoteInputs, saplingNoteInputs, testnetzaddr, 1);
BOOST_FAIL("Should have caused an error"); BOOST_FAIL("Should have caused an error");
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK(find_error(objError, "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress")); BOOST_CHECK(find_error(objError, "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress"));
@ -1900,7 +1901,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters)
// Testnet payment addresses begin with 'zt'. This test detects an incorrect prefix. // Testnet payment addresses begin with 'zt'. This test detects an incorrect prefix.
try { try {
std::vector<MergeToAddressInputUTXO> inputs = { MergeToAddressInputUTXO{ COutPoint{uint256(), 0}, 0, CScript()} }; std::vector<MergeToAddressInputUTXO> inputs = { MergeToAddressInputUTXO{ COutPoint{uint256(), 0}, 0, CScript()} };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_mergetoaddress(boost::none, mtx, inputs, {}, {}, mainnetzaddr, 1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_mergetoaddress(std::nullopt, mtx, inputs, {}, {}, mainnetzaddr, 1) );
BOOST_FAIL("Should have caused an error"); BOOST_FAIL("Should have caused an error");
} catch (const UniValue& objError) { } catch (const UniValue& objError) {
BOOST_CHECK( find_error(objError, "Invalid recipient address")); BOOST_CHECK( find_error(objError, "Invalid recipient address"));
@ -1934,7 +1935,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals)
// Insufficient funds // Insufficient funds
{ {
std::vector<MergeToAddressInputUTXO> inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},0, CScript()} }; std::vector<MergeToAddressInputUTXO> inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},0, CScript()} };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_mergetoaddress(boost::none, mtx, inputs, {}, {}, zaddr1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_mergetoaddress(std::nullopt, mtx, inputs, {}, {}, zaddr1) );
operation->main(); operation->main();
BOOST_CHECK(operation->isFailed()); BOOST_CHECK(operation->isFailed());
std::string msg = operation->getErrorMessage(); std::string msg = operation->getErrorMessage();
@ -1944,7 +1945,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals)
// get_memo_from_hex_string()) // get_memo_from_hex_string())
{ {
std::vector<MergeToAddressInputUTXO> inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},100000, CScript()} }; std::vector<MergeToAddressInputUTXO> inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},100000, CScript()} };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_mergetoaddress(boost::none, mtx, inputs, {}, {}, zaddr1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_mergetoaddress(std::nullopt, mtx, inputs, {}, {}, zaddr1) );
std::shared_ptr<AsyncRPCOperation_mergetoaddress> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_mergetoaddress> (operation); std::shared_ptr<AsyncRPCOperation_mergetoaddress> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_mergetoaddress> (operation);
TEST_FRIEND_AsyncRPCOperation_mergetoaddress proxy(ptr); TEST_FRIEND_AsyncRPCOperation_mergetoaddress proxy(ptr);
@ -1998,7 +1999,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals)
{ {
// Dummy input so the operation object can be instantiated. // Dummy input so the operation object can be instantiated.
std::vector<MergeToAddressInputUTXO> inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},100000, CScript()} }; std::vector<MergeToAddressInputUTXO> inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},100000, CScript()} };
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_mergetoaddress(boost::none, mtx, inputs, {}, {}, zaddr1) ); std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_mergetoaddress(std::nullopt, mtx, inputs, {}, {}, zaddr1) );
std::shared_ptr<AsyncRPCOperation_mergetoaddress> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_mergetoaddress> (operation); std::shared_ptr<AsyncRPCOperation_mergetoaddress> ptr = std::dynamic_pointer_cast<AsyncRPCOperation_mergetoaddress> (operation);
TEST_FRIEND_AsyncRPCOperation_mergetoaddress proxy(ptr); TEST_FRIEND_AsyncRPCOperation_mergetoaddress proxy(ptr);
@ -2006,7 +2007,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals)
static_cast<AsyncRPCOperation_sendmany *>(operation.get())->testmode = true; static_cast<AsyncRPCOperation_sendmany *>(operation.get())->testmode = true;
MergeToAddressJSInfo info; MergeToAddressJSInfo info;
std::vector<boost::optional < SproutWitness>> witnesses; std::vector<std::optional<SproutWitness>> witnesses;
uint256 anchor; uint256 anchor;
try { try {
proxy.perform_joinsplit(info, witnesses, anchor); proxy.perform_joinsplit(info, witnesses, anchor);

View File

@ -605,7 +605,7 @@ void CWallet::ChainTipAdded(const CBlockIndex *pindex,
void CWallet::ChainTip(const CBlockIndex *pindex, void CWallet::ChainTip(const CBlockIndex *pindex,
const CBlock *pblock, const CBlock *pblock,
boost::optional<std::pair<SproutMerkleTree, SaplingMerkleTree>> added) std::optional<std::pair<SproutMerkleTree, SaplingMerkleTree>> added)
{ {
if (added) { if (added) {
ChainTipAdded(pindex, pblock, added->first, added->second); ChainTipAdded(pindex, pblock, added->first, added->second);
@ -656,7 +656,7 @@ void CWallet::RunSaplingMigration(int blockHeight) {
for (const CTransaction& transaction : pendingSaplingMigrationTxs) { for (const CTransaction& transaction : pendingSaplingMigrationTxs) {
// Send the transaction // Send the transaction
CWalletTx wtx(this, transaction); CWalletTx wtx(this, transaction);
CommitTransaction(wtx, boost::none); CommitTransaction(wtx, std::nullopt);
} }
pendingSaplingMigrationTxs.clear(); pendingSaplingMigrationTxs.clear();
} }
@ -695,7 +695,7 @@ std::set<std::pair<libzcash::PaymentAddress, uint256>> CWallet::GetNullifiersFor
auto & nullifier = noteData.nullifier; auto & nullifier = noteData.nullifier;
auto & address = noteData.address; auto & address = noteData.address;
if (nullifier && addresses.count(address)) { if (nullifier && addresses.count(address)) {
nullifierSet.insert(std::make_pair(address, nullifier.get())); nullifierSet.insert(std::make_pair(address, nullifier.value()));
} }
} }
// Sapling // Sapling
@ -705,7 +705,7 @@ std::set<std::pair<libzcash::PaymentAddress, uint256>> CWallet::GetNullifiersFor
auto & ivk = noteData.ivk; auto & ivk = noteData.ivk;
if (nullifier && ivkMap.count(ivk)) { if (nullifier && ivkMap.count(ivk)) {
for (const auto & addr : ivkMap[ivk]) { for (const auto & addr : ivkMap[ivk]) {
nullifierSet.insert(std::make_pair(addr, nullifier.get())); nullifierSet.insert(std::make_pair(addr, nullifier.value()));
} }
} }
} }
@ -1506,9 +1506,9 @@ void CWallet::UpdateSaplingNullifierNoteMapWithTx(CWalletTx& wtx) {
if (nd.witnesses.empty()) { if (nd.witnesses.empty()) {
// If there are no witnesses, erase the nullifier and associated mapping. // If there are no witnesses, erase the nullifier and associated mapping.
if (item.second.nullifier) { if (item.second.nullifier) {
mapSaplingNullifiersToNotes.erase(item.second.nullifier.get()); mapSaplingNullifiersToNotes.erase(item.second.nullifier.value());
} }
item.second.nullifier = boost::none; item.second.nullifier = std::nullopt;
} }
else { else {
uint64_t position = nd.witnesses.front().position(); uint64_t position = nd.witnesses.front().position();
@ -1519,21 +1519,21 @@ void CWallet::UpdateSaplingNullifierNoteMapWithTx(CWalletTx& wtx) {
// The transaction would not have entered the wallet unless // The transaction would not have entered the wallet unless
// its plaintext had been successfully decrypted previously. // its plaintext had been successfully decrypted previously.
assert(optDeserialized != boost::none); assert(optDeserialized != std::nullopt);
auto optPlaintext = SaplingNotePlaintext::plaintext_checks_without_height(*optDeserialized, nd.ivk, output.ephemeralKey, output.cmu); auto optPlaintext = SaplingNotePlaintext::plaintext_checks_without_height(*optDeserialized, nd.ivk, output.ephemeralKey, output.cmu);
// An item in mapSaplingNoteData must have already been successfully decrypted, // An item in mapSaplingNoteData must have already been successfully decrypted,
// otherwise the item would not exist in the first place. // otherwise the item would not exist in the first place.
assert(optPlaintext != boost::none); assert(optPlaintext != std::nullopt);
auto optNote = optPlaintext.get().note(nd.ivk); auto optNote = optPlaintext.value().note(nd.ivk);
assert(optNote != boost::none); assert(optNote != std::nullopt);
auto optNullifier = optNote.get().nullifier(extfvk.fvk, position); auto optNullifier = optNote.value().nullifier(extfvk.fvk, position);
// This should not happen. If it does, maybe the position has been corrupted or miscalculated? // This should not happen. If it does, maybe the position has been corrupted or miscalculated?
assert(optNullifier != boost::none); assert(optNullifier != std::nullopt);
uint256 nullifier = optNullifier.get(); uint256 nullifier = optNullifier.value();
mapSaplingNullifiersToNotes[nullifier] = op; mapSaplingNullifiersToNotes[nullifier] = op;
item.second.nullifier = nullifier; item.second.nullifier = nullifier;
} }
@ -1825,13 +1825,13 @@ void CWallet::EraseFromWallet(const uint256 &hash)
* Returns a nullifier if the SpendingKey is available * Returns a nullifier if the SpendingKey is available
* Throws std::runtime_error if the decryptor doesn't match this note * Throws std::runtime_error if the decryptor doesn't match this note
*/ */
boost::optional<uint256> CWallet::GetSproutNoteNullifier(const JSDescription &jsdesc, std::optional<uint256> CWallet::GetSproutNoteNullifier(const JSDescription &jsdesc,
const libzcash::SproutPaymentAddress &address, const libzcash::SproutPaymentAddress &address,
const ZCNoteDecryption &dec, const ZCNoteDecryption &dec,
const uint256 &hSig, const uint256 &hSig,
uint8_t n) const uint8_t n) const
{ {
boost::optional<uint256> ret; std::optional<uint256> ret;
auto note_pt = libzcash::SproutNotePlaintext::decrypt( auto note_pt = libzcash::SproutNotePlaintext::decrypt(
dec, dec,
jsdesc.ciphertexts[n], jsdesc.ciphertexts[n],
@ -1932,9 +1932,9 @@ std::pair<mapSaplingNoteData_t, SaplingIncomingViewingKeyMap> CWallet::FindMySap
if (!result) { if (!result) {
continue; continue;
} }
auto address = ivk.address(result.get().d); auto address = ivk.address(result.value().d);
if (address && mapSaplingIncomingViewingKeys.count(address.get()) == 0) { if (address && mapSaplingIncomingViewingKeys.count(address.value()) == 0) {
viewingKeysToAdd[address.get()] = ivk; viewingKeysToAdd[address.value()] = ivk;
} }
// We don't cache the nullifier here as computing it requires knowledge of the note position // We don't cache the nullifier here as computing it requires knowledge of the note position
// in the commitment tree, which can only be determined when the transaction has been mined. // in the commitment tree, which can only be determined when the transaction has been mined.
@ -1974,12 +1974,12 @@ bool CWallet::IsSaplingNullifierFromMe(const uint256& nullifier) const
} }
void CWallet::GetSproutNoteWitnesses(std::vector<JSOutPoint> notes, void CWallet::GetSproutNoteWitnesses(std::vector<JSOutPoint> notes,
std::vector<boost::optional<SproutWitness>>& witnesses, std::vector<std::optional<SproutWitness>>& witnesses,
uint256 &final_anchor) uint256 &final_anchor)
{ {
LOCK(cs_wallet); LOCK(cs_wallet);
witnesses.resize(notes.size()); witnesses.resize(notes.size());
boost::optional<uint256> rt; std::optional<uint256> rt;
int i = 0; int i = 0;
for (JSOutPoint note : notes) { for (JSOutPoint note : notes) {
if (mapWallet.count(note.hash) && if (mapWallet.count(note.hash) &&
@ -2001,12 +2001,12 @@ void CWallet::GetSproutNoteWitnesses(std::vector<JSOutPoint> notes,
} }
void CWallet::GetSaplingNoteWitnesses(std::vector<SaplingOutPoint> notes, void CWallet::GetSaplingNoteWitnesses(std::vector<SaplingOutPoint> notes,
std::vector<boost::optional<SaplingWitness>>& witnesses, std::vector<std::optional<SaplingWitness>>& witnesses,
uint256 &final_anchor) uint256 &final_anchor)
{ {
LOCK(cs_wallet); LOCK(cs_wallet);
witnesses.resize(notes.size()); witnesses.resize(notes.size());
boost::optional<uint256> rt; std::optional<uint256> rt;
int i = 0; int i = 0;
for (SaplingOutPoint note : notes) { for (SaplingOutPoint note : notes) {
if (mapWallet.count(note.hash) && if (mapWallet.count(note.hash) &&
@ -2329,13 +2329,13 @@ std::pair<SproutNotePlaintext, SproutPaymentAddress> CWalletTx::DecryptSproutNot
} }
} }
boost::optional<std::pair< std::optional<std::pair<
SaplingNotePlaintext, SaplingNotePlaintext,
SaplingPaymentAddress>> CWalletTx::DecryptSaplingNote(const Consensus::Params& params, int height, SaplingOutPoint op) const SaplingPaymentAddress>> CWalletTx::DecryptSaplingNote(const Consensus::Params& params, int height, SaplingOutPoint op) const
{ {
// Check whether we can decrypt this SaplingOutPoint // Check whether we can decrypt this SaplingOutPoint
if (this->mapSaplingNoteData.count(op) == 0) { if (this->mapSaplingNoteData.count(op) == 0) {
return boost::none; return std::nullopt;
} }
auto output = this->vShieldedOutput[op.n]; auto output = this->vShieldedOutput[op.n];
@ -2348,23 +2348,23 @@ boost::optional<std::pair<
nd.ivk, nd.ivk,
output.ephemeralKey, output.ephemeralKey,
output.cmu); output.cmu);
assert(maybe_pt != boost::none); assert(maybe_pt != std::nullopt);
auto notePt = maybe_pt.get(); auto notePt = maybe_pt.value();
auto maybe_pa = nd.ivk.address(notePt.d); auto maybe_pa = nd.ivk.address(notePt.d);
assert(maybe_pa != boost::none); assert(maybe_pa != std::nullopt);
auto pa = maybe_pa.get(); auto pa = maybe_pa.value();
return std::make_pair(notePt, pa); return std::make_pair(notePt, pa);
} }
boost::optional<std::pair< std::optional<std::pair<
SaplingNotePlaintext, SaplingNotePlaintext,
SaplingPaymentAddress>> CWalletTx::DecryptSaplingNoteWithoutLeadByteCheck(SaplingOutPoint op) const SaplingPaymentAddress>> CWalletTx::DecryptSaplingNoteWithoutLeadByteCheck(SaplingOutPoint op) const
{ {
// Check whether we can decrypt this SaplingOutPoint // Check whether we can decrypt this SaplingOutPoint
if (this->mapSaplingNoteData.count(op) == 0) { if (this->mapSaplingNoteData.count(op) == 0) {
return boost::none; return std::nullopt;
} }
auto output = this->vShieldedOutput[op.n]; auto output = this->vShieldedOutput[op.n];
@ -2374,24 +2374,24 @@ boost::optional<std::pair<
// The transaction would not have entered the wallet unless // The transaction would not have entered the wallet unless
// its plaintext had been successfully decrypted previously. // its plaintext had been successfully decrypted previously.
assert(optDeserialized != boost::none); assert(optDeserialized != std::nullopt);
auto maybe_pt = SaplingNotePlaintext::plaintext_checks_without_height( auto maybe_pt = SaplingNotePlaintext::plaintext_checks_without_height(
*optDeserialized, *optDeserialized,
nd.ivk, nd.ivk,
output.ephemeralKey, output.ephemeralKey,
output.cmu); output.cmu);
assert(maybe_pt != boost::none); assert(maybe_pt != std::nullopt);
auto notePt = maybe_pt.get(); auto notePt = maybe_pt.value();
auto maybe_pa = nd.ivk.address(notePt.d); auto maybe_pa = nd.ivk.address(notePt.d);
assert(static_cast<bool>(maybe_pa)); assert(static_cast<bool>(maybe_pa));
auto pa = maybe_pa.get(); auto pa = maybe_pa.value();
return std::make_pair(notePt, pa); return std::make_pair(notePt, pa);
} }
boost::optional<std::pair< std::optional<std::pair<
SaplingNotePlaintext, SaplingNotePlaintext,
SaplingPaymentAddress>> CWalletTx::RecoverSaplingNote(const Consensus::Params& params, int height, SaplingOutPoint op, std::set<uint256>& ovks) const SaplingPaymentAddress>> CWalletTx::RecoverSaplingNote(const Consensus::Params& params, int height, SaplingOutPoint op, std::set<uint256>& ovks) const
{ {
@ -2418,16 +2418,16 @@ boost::optional<std::pair<
outPt->pk_d, outPt->pk_d,
output.cmu); output.cmu);
assert(static_cast<bool>(maybe_pt)); assert(static_cast<bool>(maybe_pt));
auto notePt = maybe_pt.get(); auto notePt = maybe_pt.value();
return std::make_pair(notePt, SaplingPaymentAddress(notePt.d, outPt->pk_d)); return std::make_pair(notePt, SaplingPaymentAddress(notePt.d, outPt->pk_d));
} }
// Couldn't recover with any of the provided OutgoingViewingKeys // Couldn't recover with any of the provided OutgoingViewingKeys
return boost::none; return std::nullopt;
} }
boost::optional<std::pair< std::optional<std::pair<
SaplingNotePlaintext, SaplingNotePlaintext,
SaplingPaymentAddress>> CWalletTx::RecoverSaplingNoteWithoutLeadByteCheck(SaplingOutPoint op, std::set<uint256>& ovks) const SaplingPaymentAddress>> CWalletTx::RecoverSaplingNoteWithoutLeadByteCheck(SaplingOutPoint op, std::set<uint256>& ovks) const
{ {
@ -2449,7 +2449,7 @@ boost::optional<std::pair<
// The transaction would not have entered the wallet unless // The transaction would not have entered the wallet unless
// its plaintext had been successfully decrypted previously. // its plaintext had been successfully decrypted previously.
assert(optDeserialized != boost::none); assert(optDeserialized != std::nullopt);
auto maybe_pt = SaplingNotePlaintext::plaintext_checks_without_height( auto maybe_pt = SaplingNotePlaintext::plaintext_checks_without_height(
*optDeserialized, *optDeserialized,
@ -2458,13 +2458,13 @@ boost::optional<std::pair<
outPt->pk_d, outPt->pk_d,
output.cmu); output.cmu);
assert(static_cast<bool>(maybe_pt)); assert(static_cast<bool>(maybe_pt));
auto notePt = maybe_pt.get(); auto notePt = maybe_pt.value();
return std::make_pair(notePt, SaplingPaymentAddress(notePt.d, outPt->pk_d)); return std::make_pair(notePt, SaplingPaymentAddress(notePt.d, outPt->pk_d));
} }
// Couldn't recover with any of the provided OutgoingViewingKeys // Couldn't recover with any of the provided OutgoingViewingKeys
return boost::none; return std::nullopt;
} }
int64_t CWalletTx::GetTxTime() const int64_t CWalletTx::GetTxTime() const
@ -2670,7 +2670,7 @@ bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
} }
void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments, void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments,
std::vector<boost::optional<SproutWitness>>& witnesses, std::vector<std::optional<SproutWitness>>& witnesses,
uint256 &final_anchor) uint256 &final_anchor)
{ {
witnesses.resize(commitments.size()); witnesses.resize(commitments.size());
@ -2689,7 +2689,7 @@ void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments,
{ {
tree.append(note_commitment); tree.append(note_commitment);
BOOST_FOREACH(boost::optional<SproutWitness>& wit, witnesses) { BOOST_FOREACH(std::optional<SproutWitness>& wit, witnesses) {
if (wit) { if (wit) {
wit->append(note_commitment); wit->append(note_commitment);
} }
@ -2719,7 +2719,7 @@ void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments,
// TODO: #93; Select a root via some heuristic. // TODO: #93; Select a root via some heuristic.
final_anchor = tree.root(); final_anchor = tree.root();
BOOST_FOREACH(boost::optional<SproutWitness>& wit, witnesses) { BOOST_FOREACH(std::optional<SproutWitness>& wit, witnesses) {
if (wit) { if (wit) {
assert(final_anchor == wit->root()); assert(final_anchor == wit->root());
} }
@ -3834,7 +3834,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
/** /**
* Call after CreateTransaction unless you want to abort * Call after CreateTransaction unless you want to abort
*/ */
bool CWallet::CommitTransaction(CWalletTx& wtxNew, boost::optional<CReserveKey&> reservekey) bool CWallet::CommitTransaction(CWalletTx& wtxNew, std::optional<std::reference_wrapper<CReserveKey>> reservekey)
{ {
{ {
LOCK2(cs_main, cs_wallet); LOCK2(cs_main, cs_wallet);
@ -3847,7 +3847,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, boost::optional<CReserveKey&>
if (reservekey) { if (reservekey) {
// Take key pair from key pool so it won't be used again // Take key pair from key pool so it won't be used again
reservekey.get().KeepKey(); reservekey.value().get().KeepKey();
} }
// Add tx to wallet, because if it has change it's also ours, // Add tx to wallet, because if it has change it's also ours,
@ -5091,12 +5091,12 @@ void CWallet::GetFilteredNotes(
// The transaction would not have entered the wallet unless // The transaction would not have entered the wallet unless
// its plaintext had been successfully decrypted previously. // its plaintext had been successfully decrypted previously.
assert(optDeserialized != boost::none); assert(optDeserialized != std::nullopt);
auto notePt = optDeserialized.get(); auto notePt = optDeserialized.value();
auto maybe_pa = nd.ivk.address(notePt.d); auto maybe_pa = nd.ivk.address(notePt.d);
assert(static_cast<bool>(maybe_pa)); assert(static_cast<bool>(maybe_pa));
auto pa = maybe_pa.get(); auto pa = maybe_pa.value();
// skip notes which belong to a different payment address in the wallet // skip notes which belong to a different payment address in the wallet
if (!(filterAddresses.empty() || filterAddresses.count(pa))) { if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
@ -5117,7 +5117,7 @@ void CWallet::GetFilteredNotes(
continue; continue;
} }
auto note = notePt.note(nd.ivk).get(); auto note = notePt.note(nd.ivk).value();
saplingEntries.push_back(SaplingNoteEntry { saplingEntries.push_back(SaplingNoteEntry {
op, pa, note, notePt.memo(), wtx.GetDepthInMainChain() }); op, pa, note, notePt.memo(), wtx.GetDepthInMainChain() });
} }
@ -5149,21 +5149,21 @@ bool PaymentAddressBelongsToWallet::operator()(const libzcash::InvalidEncoding&
return false; return false;
} }
boost::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()( std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const libzcash::SproutPaymentAddress &zaddr) const const libzcash::SproutPaymentAddress &zaddr) const
{ {
libzcash::SproutViewingKey vk; libzcash::SproutViewingKey vk;
if (!m_wallet->GetSproutViewingKey(zaddr, vk)) { if (!m_wallet->GetSproutViewingKey(zaddr, vk)) {
libzcash::SproutSpendingKey k; libzcash::SproutSpendingKey k;
if (!m_wallet->GetSproutSpendingKey(zaddr, k)) { if (!m_wallet->GetSproutSpendingKey(zaddr, k)) {
return boost::none; return std::nullopt;
} }
vk = k.viewing_key(); vk = k.viewing_key();
} }
return libzcash::ViewingKey(vk); return libzcash::ViewingKey(vk);
} }
boost::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()( std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const const libzcash::SaplingPaymentAddress &zaddr) const
{ {
libzcash::SaplingIncomingViewingKey ivk; libzcash::SaplingIncomingViewingKey ivk;
@ -5174,11 +5174,11 @@ boost::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()
{ {
return libzcash::ViewingKey(extfvk); return libzcash::ViewingKey(extfvk);
} else { } else {
return boost::none; return std::nullopt;
} }
} }
boost::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()( std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const libzcash::InvalidEncoding& no) const const libzcash::InvalidEncoding& no) const
{ {
// Defaults to InvalidEncoding // Defaults to InvalidEncoding
@ -5205,29 +5205,29 @@ bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::InvalidEncodin
return false; return false;
} }
boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()( std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const libzcash::SproutPaymentAddress &zaddr) const const libzcash::SproutPaymentAddress &zaddr) const
{ {
libzcash::SproutSpendingKey k; libzcash::SproutSpendingKey k;
if (m_wallet->GetSproutSpendingKey(zaddr, k)) { if (m_wallet->GetSproutSpendingKey(zaddr, k)) {
return libzcash::SpendingKey(k); return libzcash::SpendingKey(k);
} else { } else {
return boost::none; return std::nullopt;
} }
} }
boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()( std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const const libzcash::SaplingPaymentAddress &zaddr) const
{ {
libzcash::SaplingExtendedSpendingKey extsk; libzcash::SaplingExtendedSpendingKey extsk;
if (m_wallet->GetSaplingExtendedSpendingKey(zaddr, extsk)) { if (m_wallet->GetSaplingExtendedSpendingKey(zaddr, extsk)) {
return libzcash::SpendingKey(extsk); return libzcash::SpendingKey(extsk);
} else { } else {
return boost::none; return std::nullopt;
} }
} }
boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()( std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const libzcash::InvalidEncoding& no) const const libzcash::InvalidEncoding& no) const
{ {
// Defaults to InvalidEncoding // Defaults to InvalidEncoding
@ -5304,11 +5304,11 @@ KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingExtendedS
m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = std::max((int64_t) 154051200, nTime); m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = std::max((int64_t) 154051200, nTime);
} }
if (hdKeypath) { if (hdKeypath) {
m_wallet->mapSaplingZKeyMetadata[ivk].hdKeypath = hdKeypath.get(); m_wallet->mapSaplingZKeyMetadata[ivk].hdKeypath = hdKeypath.value();
} }
if (seedFpStr) { if (seedFpStr) {
uint256 seedFp; uint256 seedFp;
seedFp.SetHex(seedFpStr.get()); seedFp.SetHex(seedFpStr.value());
m_wallet->mapSaplingZKeyMetadata[ivk].seedFp = seedFp; m_wallet->mapSaplingZKeyMetadata[ivk].seedFp = seedFp;
} }
return KeyAdded; return KeyAdded;

View File

@ -28,7 +28,9 @@
#include "base58.h" #include "base58.h"
#include <algorithm> #include <algorithm>
#include <functional>
#include <map> #include <map>
#include <optional>
#include <set> #include <set>
#include <stdexcept> #include <stdexcept>
#include <stdint.h> #include <stdint.h>
@ -228,7 +230,7 @@ public:
* transactions they are spent in. This is the same security semantics as * transactions they are spent in. This is the same security semantics as
* for transparent addresses. * for transparent addresses.
*/ */
boost::optional<uint256> nullifier; std::optional<uint256> nullifier;
/** /**
* Cached incremental witnesses for spendable Notes. * Cached incremental witnesses for spendable Notes.
@ -291,7 +293,7 @@ public:
std::list<SaplingWitness> witnesses; std::list<SaplingWitness> witnesses;
int witnessHeight; int witnessHeight;
libzcash::SaplingIncomingViewingKey ivk; libzcash::SaplingIncomingViewingKey ivk;
boost::optional<uint256> nullifier; std::optional<uint256> nullifier;
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
@ -565,17 +567,17 @@ public:
std::pair<libzcash::SproutNotePlaintext, libzcash::SproutPaymentAddress> DecryptSproutNote( std::pair<libzcash::SproutNotePlaintext, libzcash::SproutPaymentAddress> DecryptSproutNote(
JSOutPoint jsop) const; JSOutPoint jsop) const;
boost::optional<std::pair< std::optional<std::pair<
libzcash::SaplingNotePlaintext, libzcash::SaplingNotePlaintext,
libzcash::SaplingPaymentAddress>> DecryptSaplingNote(const Consensus::Params& params, int height, SaplingOutPoint op) const; libzcash::SaplingPaymentAddress>> DecryptSaplingNote(const Consensus::Params& params, int height, SaplingOutPoint op) const;
boost::optional<std::pair< std::optional<std::pair<
libzcash::SaplingNotePlaintext, libzcash::SaplingNotePlaintext,
libzcash::SaplingPaymentAddress>> DecryptSaplingNoteWithoutLeadByteCheck(SaplingOutPoint op) const; libzcash::SaplingPaymentAddress>> DecryptSaplingNoteWithoutLeadByteCheck(SaplingOutPoint op) const;
boost::optional<std::pair< std::optional<std::pair<
libzcash::SaplingNotePlaintext, libzcash::SaplingNotePlaintext,
libzcash::SaplingPaymentAddress>> RecoverSaplingNote(const Consensus::Params& params, int height, libzcash::SaplingPaymentAddress>> RecoverSaplingNote(const Consensus::Params& params, int height,
SaplingOutPoint op, std::set<uint256>& ovks) const; SaplingOutPoint op, std::set<uint256>& ovks) const;
boost::optional<std::pair< std::optional<std::pair<
libzcash::SaplingNotePlaintext, libzcash::SaplingNotePlaintext,
libzcash::SaplingPaymentAddress>> RecoverSaplingNoteWithoutLeadByteCheck(SaplingOutPoint op, std::set<uint256>& ovks) const; libzcash::SaplingPaymentAddress>> RecoverSaplingNoteWithoutLeadByteCheck(SaplingOutPoint op, std::set<uint256>& ovks) const;
@ -1170,7 +1172,7 @@ public:
void EraseFromWallet(const uint256 &hash); void EraseFromWallet(const uint256 &hash);
void WitnessNoteCommitment( void WitnessNoteCommitment(
std::vector<uint256> commitments, std::vector<uint256> commitments,
std::vector<boost::optional<SproutWitness>>& witnesses, std::vector<std::optional<SproutWitness>>& witnesses,
uint256 &final_anchor); uint256 &final_anchor);
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
void ReacceptWalletTransactions(); void ReacceptWalletTransactions();
@ -1195,7 +1197,7 @@ public:
*/ */
bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet,
std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true); std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true);
bool CommitTransaction(CWalletTx& wtxNew, boost::optional<CReserveKey&> reservekey); bool CommitTransaction(CWalletTx& wtxNew, std::optional<std::reference_wrapper<CReserveKey>> reservekey);
static CFeeRate minTxFee; static CFeeRate minTxFee;
/** /**
@ -1223,7 +1225,7 @@ public:
std::set<CTxDestination> GetAccountAddresses(const std::string& strAccount) const; std::set<CTxDestination> GetAccountAddresses(const std::string& strAccount) const;
boost::optional<uint256> GetSproutNoteNullifier( std::optional<uint256> GetSproutNoteNullifier(
const JSDescription& jsdesc, const JSDescription& jsdesc,
const libzcash::SproutPaymentAddress& address, const libzcash::SproutPaymentAddress& address,
const ZCNoteDecryption& dec, const ZCNoteDecryption& dec,
@ -1236,11 +1238,11 @@ public:
void GetSproutNoteWitnesses( void GetSproutNoteWitnesses(
std::vector<JSOutPoint> notes, std::vector<JSOutPoint> notes,
std::vector<boost::optional<SproutWitness>>& witnesses, std::vector<std::optional<SproutWitness>>& witnesses,
uint256 &final_anchor); uint256 &final_anchor);
void GetSaplingNoteWitnesses( void GetSaplingNoteWitnesses(
std::vector<SaplingOutPoint> notes, std::vector<SaplingOutPoint> notes,
std::vector<boost::optional<SaplingWitness>>& witnesses, std::vector<std::optional<SaplingWitness>>& witnesses,
uint256 &final_anchor); uint256 &final_anchor);
isminetype IsMine(const CTxIn& txin) const; isminetype IsMine(const CTxIn& txin) const;
@ -1258,7 +1260,7 @@ public:
void ChainTip( void ChainTip(
const CBlockIndex *pindex, const CBlockIndex *pindex,
const CBlock *pblock, const CBlock *pblock,
boost::optional<std::pair<SproutMerkleTree, SaplingMerkleTree>> added); std::optional<std::pair<SproutMerkleTree, SaplingMerkleTree>> added);
void RunSaplingMigration(int blockHeight); void RunSaplingMigration(int blockHeight);
void AddPendingSaplingMigrationTx(const CTransaction& tx); void AddPendingSaplingMigrationTx(const CTransaction& tx);
/** Saves witness caches and best block locator to disk. */ /** Saves witness caches and best block locator to disk. */
@ -1478,9 +1480,9 @@ private:
public: public:
GetViewingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} GetViewingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
boost::optional<libzcash::ViewingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const; std::optional<libzcash::ViewingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
boost::optional<libzcash::ViewingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const; std::optional<libzcash::ViewingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
boost::optional<libzcash::ViewingKey> operator()(const libzcash::InvalidEncoding& no) const; std::optional<libzcash::ViewingKey> operator()(const libzcash::InvalidEncoding& no) const;
}; };
class HaveSpendingKeyForPaymentAddress class HaveSpendingKeyForPaymentAddress
@ -1502,9 +1504,9 @@ private:
public: public:
GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
boost::optional<libzcash::SpendingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const; std::optional<libzcash::SpendingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
boost::optional<libzcash::SpendingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const; std::optional<libzcash::SpendingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
boost::optional<libzcash::SpendingKey> operator()(const libzcash::InvalidEncoding& no) const; std::optional<libzcash::SpendingKey> operator()(const libzcash::InvalidEncoding& no) const;
}; };
enum KeyAddResult { enum KeyAddResult {
@ -1532,18 +1534,18 @@ private:
CWallet *m_wallet; CWallet *m_wallet;
const Consensus::Params &params; const Consensus::Params &params;
int64_t nTime; int64_t nTime;
boost::optional<std::string> hdKeypath; // currently sapling only std::optional<std::string> hdKeypath; // currently sapling only
boost::optional<std::string> seedFpStr; // currently sapling only std::optional<std::string> seedFpStr; // currently sapling only
bool log; bool log;
public: public:
AddSpendingKeyToWallet(CWallet *wallet, const Consensus::Params &params) : AddSpendingKeyToWallet(CWallet *wallet, const Consensus::Params &params) :
m_wallet(wallet), params(params), nTime(1), hdKeypath(boost::none), seedFpStr(boost::none), log(false) {} m_wallet(wallet), params(params), nTime(1), hdKeypath(std::nullopt), seedFpStr(std::nullopt), log(false) {}
AddSpendingKeyToWallet( AddSpendingKeyToWallet(
CWallet *wallet, CWallet *wallet,
const Consensus::Params &params, const Consensus::Params &params,
int64_t _nTime, int64_t _nTime,
boost::optional<std::string> _hdKeypath, std::optional<std::string> _hdKeypath,
boost::optional<std::string> _seedFp, std::optional<std::string> _seedFp,
bool _log bool _log
) : m_wallet(wallet), params(params), nTime(_nTime), hdKeypath(_hdKeypath), seedFpStr(_seedFp), log(_log) {} ) : m_wallet(wallet), params(params), nTime(_nTime), hdKeypath(_hdKeypath), seedFpStr(_seedFp), log(_log) {}

View File

@ -930,17 +930,17 @@ void IncrementalMerkleTree<Depth, Hash>::append(Hash obj) {
right = obj; right = obj;
} else { } else {
// Combine the leaves and propagate it up the tree // Combine the leaves and propagate it up the tree
boost::optional<Hash> combined = Hash::combine(*left, *right, 0); std::optional<Hash> combined = Hash::combine(*left, *right, 0);
// Set the "left" leaf to the object and make the "right" leaf none // Set the "left" leaf to the object and make the "right" leaf none
left = obj; left = obj;
right = boost::none; right = std::nullopt;
for (size_t i = 0; i < Depth; i++) { for (size_t i = 0; i < Depth; i++) {
if (i < parents.size()) { if (i < parents.size()) {
if (parents[i]) { if (parents[i]) {
combined = Hash::combine(*parents[i], *combined, i+1); combined = Hash::combine(*parents[i], *combined, i+1);
parents[i] = boost::none; parents[i] = std::nullopt;
} else { } else {
parents[i] = *combined; parents[i] = *combined;
break; break;
@ -966,7 +966,7 @@ bool IncrementalMerkleTree<Depth, Hash>::is_complete(size_t depth) const {
return false; return false;
} }
BOOST_FOREACH(const boost::optional<Hash>& parent, parents) { BOOST_FOREACH(const std::optional<Hash>& parent, parents) {
if (!parent) { if (!parent) {
return false; return false;
} }
@ -997,7 +997,7 @@ size_t IncrementalMerkleTree<Depth, Hash>::next_depth(size_t skip) const {
size_t d = 1; size_t d = 1;
BOOST_FOREACH(const boost::optional<Hash>& parent, parents) { BOOST_FOREACH(const std::optional<Hash>& parent, parents) {
if (!parent) { if (!parent) {
if (skip) { if (skip) {
skip--; skip--;
@ -1025,7 +1025,7 @@ Hash IncrementalMerkleTree<Depth, Hash>::root(size_t depth,
size_t d = 1; size_t d = 1;
BOOST_FOREACH(const boost::optional<Hash>& parent, parents) { BOOST_FOREACH(const std::optional<Hash>& parent, parents) {
if (parent) { if (parent) {
root = Hash::combine(*parent, root, d); root = Hash::combine(*parent, root, d);
} else { } else {
@ -1068,7 +1068,7 @@ MerklePath IncrementalMerkleTree<Depth, Hash>::path(std::deque<Hash> filler_hash
size_t d = 1; size_t d = 1;
BOOST_FOREACH(const boost::optional<Hash>& parent, parents) { BOOST_FOREACH(const std::optional<Hash>& parent, parents) {
if (parent) { if (parent) {
index.push_back(true); index.push_back(true);
path.push_back(*parent); path.push_back(*parent);
@ -1118,7 +1118,7 @@ void IncrementalWitness<Depth, Hash>::append(Hash obj) {
if (cursor->is_complete(cursor_depth)) { if (cursor->is_complete(cursor_depth)) {
filled.push_back(cursor->root(cursor_depth)); filled.push_back(cursor->root(cursor_depth));
cursor = boost::none; cursor = std::nullopt;
} }
} else { } else {
cursor_depth = tree.next_depth(filled.size()); cursor_depth = tree.next_depth(filled.size());

View File

@ -3,7 +3,8 @@
#include <array> #include <array>
#include <deque> #include <deque>
#include <boost/optional.hpp> #include <optional>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include "uint256.h" #include "uint256.h"
@ -126,11 +127,11 @@ public:
private: private:
static EmptyMerkleRoots<Depth, Hash> emptyroots; static EmptyMerkleRoots<Depth, Hash> emptyroots;
boost::optional<Hash> left; std::optional<Hash> left;
boost::optional<Hash> right; std::optional<Hash> right;
// Collapsed "left" subtrees ordered toward the root of the tree. // Collapsed "left" subtrees ordered toward the root of the tree.
std::vector<boost::optional<Hash>> parents; std::vector<std::optional<Hash>> parents;
MerklePath path(std::deque<Hash> filler_hashes = std::deque<Hash>()) const; MerklePath path(std::deque<Hash> filler_hashes = std::deque<Hash>()) const;
Hash root(size_t depth, std::deque<Hash> filler_hashes = std::deque<Hash>()) const; Hash root(size_t depth, std::deque<Hash> filler_hashes = std::deque<Hash>()) const;
bool is_complete(size_t depth = Depth) const; bool is_complete(size_t depth = Depth) const;
@ -193,7 +194,7 @@ public:
private: private:
IncrementalMerkleTree<Depth, Hash> tree; IncrementalMerkleTree<Depth, Hash> tree;
std::vector<Hash> filled; std::vector<Hash> filled;
boost::optional<IncrementalMerkleTree<Depth, Hash>> cursor; std::optional<IncrementalMerkleTree<Depth, Hash>> cursor;
size_t cursor_depth = 0; size_t cursor_depth = 0;
std::deque<Hash> partial_path() const; std::deque<Hash> partial_path() const;
IncrementalWitness(IncrementalMerkleTree<Depth, Hash> tree) : tree(tree) {} IncrementalWitness(IncrementalMerkleTree<Depth, Hash> tree) : tree(tree) {}

View File

@ -59,7 +59,7 @@ SaplingNote::SaplingNote(
} }
// Call librustzcash to compute the commitment // Call librustzcash to compute the commitment
boost::optional<uint256> SaplingNote::cmu() const { std::optional<uint256> SaplingNote::cmu() const {
uint256 result; uint256 result;
uint256 rcm_tmp = rcm(); uint256 rcm_tmp = rcm();
if (!librustzcash_sapling_compute_cm( if (!librustzcash_sapling_compute_cm(
@ -70,14 +70,14 @@ boost::optional<uint256> SaplingNote::cmu() const {
result.begin() result.begin()
)) ))
{ {
return boost::none; return std::nullopt;
} }
return result; return result;
} }
// Call librustzcash to compute the nullifier // Call librustzcash to compute the nullifier
boost::optional<uint256> SaplingNote::nullifier(const SaplingFullViewingKey& vk, const uint64_t position) const std::optional<uint256> SaplingNote::nullifier(const SaplingFullViewingKey& vk, const uint64_t position) const
{ {
auto ak = vk.ak; auto ak = vk.ak;
auto nk = vk.nk; auto nk = vk.nk;
@ -95,7 +95,7 @@ boost::optional<uint256> SaplingNote::nullifier(const SaplingFullViewingKey& vk,
result.begin() result.begin()
)) ))
{ {
return boost::none; return std::nullopt;
} }
return result; return result;
@ -167,7 +167,7 @@ SaplingNotePlaintext::SaplingNotePlaintext(
} }
boost::optional<SaplingNote> SaplingNotePlaintext::note(const SaplingIncomingViewingKey& ivk) const std::optional<SaplingNote> SaplingNotePlaintext::note(const SaplingIncomingViewingKey& ivk) const
{ {
auto addr = ivk.address(d); auto addr = ivk.address(d);
if (addr) { if (addr) {
@ -175,14 +175,14 @@ boost::optional<SaplingNote> SaplingNotePlaintext::note(const SaplingIncomingVie
if (leadbyte != 0x01) { if (leadbyte != 0x01) {
zip_212_enabled = Zip212Enabled::AfterZip212; zip_212_enabled = Zip212Enabled::AfterZip212;
}; };
auto tmp = SaplingNote(d, addr.get().pk_d, value_, rseed, zip_212_enabled); auto tmp = SaplingNote(d, addr.value().pk_d, value_, rseed, zip_212_enabled);
return tmp; return tmp;
} else { } else {
return boost::none; return std::nullopt;
} }
} }
boost::optional<SaplingOutgoingPlaintext> SaplingOutgoingPlaintext::decrypt( std::optional<SaplingOutgoingPlaintext> SaplingOutgoingPlaintext::decrypt(
const SaplingOutCiphertext &ciphertext, const SaplingOutCiphertext &ciphertext,
const uint256& ovk, const uint256& ovk,
const uint256& cv, const uint256& cv,
@ -192,13 +192,13 @@ boost::optional<SaplingOutgoingPlaintext> SaplingOutgoingPlaintext::decrypt(
{ {
auto pt = AttemptSaplingOutDecryption(ciphertext, ovk, cv, cm, epk); auto pt = AttemptSaplingOutDecryption(ciphertext, ovk, cv, cm, epk);
if (!pt) { if (!pt) {
return boost::none; return std::nullopt;
} }
// Deserialize from the plaintext // Deserialize from the plaintext
try { try {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << pt.get(); ss << pt.value();
SaplingOutgoingPlaintext ret; SaplingOutgoingPlaintext ret;
ss >> ret; ss >> ret;
assert(ss.size() == 0); assert(ss.size() == 0);
@ -206,11 +206,11 @@ boost::optional<SaplingOutgoingPlaintext> SaplingOutgoingPlaintext::decrypt(
} catch (const boost::thread_interrupted&) { } catch (const boost::thread_interrupted&) {
throw; throw;
} catch (...) { } catch (...) {
return boost::none; return std::nullopt;
} }
} }
boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt( std::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
const Consensus::Params& params, const Consensus::Params& params,
int height, int height,
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
@ -222,20 +222,20 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
auto ret = attempt_sapling_enc_decryption_deserialization(ciphertext, ivk, epk); auto ret = attempt_sapling_enc_decryption_deserialization(ciphertext, ivk, epk);
if (!ret) { if (!ret) {
return boost::none; return std::nullopt;
} else { } else {
const SaplingNotePlaintext plaintext = *ret; const SaplingNotePlaintext plaintext = *ret;
// Check leadbyte is allowed at block height // Check leadbyte is allowed at block height
if (!plaintext_version_is_valid(params, height, plaintext.get_leadbyte())) { if (!plaintext_version_is_valid(params, height, plaintext.get_leadbyte())) {
return boost::none; return std::nullopt;
} }
return plaintext_checks_without_height(plaintext, ivk, epk, cmu); return plaintext_checks_without_height(plaintext, ivk, epk, cmu);
} }
} }
boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::attempt_sapling_enc_decryption_deserialization( std::optional<SaplingNotePlaintext> SaplingNotePlaintext::attempt_sapling_enc_decryption_deserialization(
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
const uint256 &ivk, const uint256 &ivk,
const uint256 &epk const uint256 &epk
@ -244,25 +244,25 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::attempt_sapling_enc_
auto encPlaintext = AttemptSaplingEncDecryption(ciphertext, ivk, epk); auto encPlaintext = AttemptSaplingEncDecryption(ciphertext, ivk, epk);
if (!encPlaintext) { if (!encPlaintext) {
return boost::none; return std::nullopt;
} }
// Deserialize from the plaintext // Deserialize from the plaintext
SaplingNotePlaintext ret; SaplingNotePlaintext ret;
try { try {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << encPlaintext.get(); ss << encPlaintext.value();
ss >> ret; ss >> ret;
assert(ss.size() == 0); assert(ss.size() == 0);
return ret; return ret;
} catch (const boost::thread_interrupted&) { } catch (const boost::thread_interrupted&) {
throw; throw;
} catch (...) { } catch (...) {
return boost::none; return std::nullopt;
} }
} }
boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_without_height( std::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_without_height(
const SaplingNotePlaintext &plaintext, const SaplingNotePlaintext &plaintext,
const uint256 &ivk, const uint256 &ivk,
const uint256 &epk, const uint256 &epk,
@ -271,7 +271,7 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_wit
{ {
uint256 pk_d; uint256 pk_d;
if (!librustzcash_ivk_to_pkd(ivk.begin(), plaintext.d.data(), pk_d.begin())) { if (!librustzcash_ivk_to_pkd(ivk.begin(), plaintext.d.data(), pk_d.begin())) {
return boost::none; return std::nullopt;
} }
uint256 cmu_expected; uint256 cmu_expected;
@ -284,11 +284,11 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_wit
cmu_expected.begin() cmu_expected.begin()
)) ))
{ {
return boost::none; return std::nullopt;
} }
if (cmu_expected != cmu) { if (cmu_expected != cmu) {
return boost::none; return std::nullopt;
} }
if (plaintext.get_leadbyte() != 0x01) { if (plaintext.get_leadbyte() != 0x01) {
@ -297,17 +297,17 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_wit
uint256 expected_epk; uint256 expected_epk;
uint256 esk = plaintext.generate_or_derive_esk(); uint256 esk = plaintext.generate_or_derive_esk();
if (!librustzcash_sapling_ka_derivepublic(plaintext.d.data(), esk.begin(), expected_epk.begin())) { if (!librustzcash_sapling_ka_derivepublic(plaintext.d.data(), esk.begin(), expected_epk.begin())) {
return boost::none; return std::nullopt;
} }
if (expected_epk != epk) { if (expected_epk != epk) {
return boost::none; return std::nullopt;
} }
} }
return plaintext; return plaintext;
} }
boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt( std::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
const Consensus::Params& params, const Consensus::Params& params,
int height, int height,
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
@ -320,20 +320,20 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
auto ret = attempt_sapling_enc_decryption_deserialization(ciphertext, epk, esk, pk_d); auto ret = attempt_sapling_enc_decryption_deserialization(ciphertext, epk, esk, pk_d);
if (!ret) { if (!ret) {
return boost::none; return std::nullopt;
} else { } else {
SaplingNotePlaintext plaintext = *ret; SaplingNotePlaintext plaintext = *ret;
// Check leadbyte is allowed at block height // Check leadbyte is allowed at block height
if (!plaintext_version_is_valid(params, height, plaintext.get_leadbyte())) { if (!plaintext_version_is_valid(params, height, plaintext.get_leadbyte())) {
return boost::none; return std::nullopt;
} }
return plaintext_checks_without_height(plaintext, epk, esk, pk_d, cmu); return plaintext_checks_without_height(plaintext, epk, esk, pk_d, cmu);
} }
} }
boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::attempt_sapling_enc_decryption_deserialization( std::optional<SaplingNotePlaintext> SaplingNotePlaintext::attempt_sapling_enc_decryption_deserialization(
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
const uint256 &epk, const uint256 &epk,
const uint256 &esk, const uint256 &esk,
@ -343,25 +343,25 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::attempt_sapling_enc_
auto encPlaintext = AttemptSaplingEncDecryption(ciphertext, epk, esk, pk_d); auto encPlaintext = AttemptSaplingEncDecryption(ciphertext, epk, esk, pk_d);
if (!encPlaintext) { if (!encPlaintext) {
return boost::none; return std::nullopt;
}; };
// Deserialize from the plaintext // Deserialize from the plaintext
SaplingNotePlaintext ret; SaplingNotePlaintext ret;
try { try {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << encPlaintext.get(); ss << encPlaintext.value();
ss >> ret; ss >> ret;
assert(ss.size() == 0); assert(ss.size() == 0);
return ret; return ret;
} catch (const boost::thread_interrupted&) { } catch (const boost::thread_interrupted&) {
throw; throw;
} catch (...) { } catch (...) {
return boost::none; return std::nullopt;
} }
} }
boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_without_height( std::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_without_height(
const SaplingNotePlaintext &plaintext, const SaplingNotePlaintext &plaintext,
const uint256 &epk, const uint256 &epk,
const uint256 &esk, const uint256 &esk,
@ -372,10 +372,10 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_wit
// Check that epk is consistent with esk // Check that epk is consistent with esk
uint256 expected_epk; uint256 expected_epk;
if (!librustzcash_sapling_ka_derivepublic(plaintext.d.data(), esk.begin(), expected_epk.begin())) { if (!librustzcash_sapling_ka_derivepublic(plaintext.d.data(), esk.begin(), expected_epk.begin())) {
return boost::none; return std::nullopt;
} }
if (expected_epk != epk) { if (expected_epk != epk) {
return boost::none; return std::nullopt;
} }
uint256 cmu_expected; uint256 cmu_expected;
@ -388,32 +388,32 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_wit
cmu_expected.begin() cmu_expected.begin()
)) ))
{ {
return boost::none; return std::nullopt;
} }
if (cmu_expected != cmu) { if (cmu_expected != cmu) {
return boost::none; return std::nullopt;
} }
if (plaintext.get_leadbyte() != 0x01) { if (plaintext.get_leadbyte() != 0x01) {
// ZIP 212: Additionally check that the esk provided to this function // ZIP 212: Additionally check that the esk provided to this function
// is consistent with the esk we can derive // is consistent with the esk we can derive
if (esk != plaintext.generate_or_derive_esk()) { if (esk != plaintext.generate_or_derive_esk()) {
return boost::none; return std::nullopt;
} }
} }
return plaintext; return plaintext;
} }
boost::optional<SaplingNotePlaintextEncryptionResult> SaplingNotePlaintext::encrypt(const uint256& pk_d) const std::optional<SaplingNotePlaintextEncryptionResult> SaplingNotePlaintext::encrypt(const uint256& pk_d) const
{ {
// Get the encryptor // Get the encryptor
auto sne = SaplingNoteEncryption::FromDiversifier(d, generate_or_derive_esk()); auto sne = SaplingNoteEncryption::FromDiversifier(d, generate_or_derive_esk());
if (!sne) { if (!sne) {
return boost::none; return std::nullopt;
} }
auto enc = sne.get(); auto enc = sne.value();
// Create the plaintext // Create the plaintext
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
@ -425,9 +425,9 @@ boost::optional<SaplingNotePlaintextEncryptionResult> SaplingNotePlaintext::encr
// Encrypt the plaintext // Encrypt the plaintext
auto encciphertext = enc.encrypt_to_recipient(pk_d, pt); auto encciphertext = enc.encrypt_to_recipient(pk_d, pt);
if (!encciphertext) { if (!encciphertext) {
return boost::none; return std::nullopt;
} }
return SaplingNotePlaintextEncryptionResult(encciphertext.get(), enc); return SaplingNotePlaintextEncryptionResult(encciphertext.value(), enc);
} }

View File

@ -9,7 +9,7 @@
#include "consensus/consensus.h" #include "consensus/consensus.h"
#include <array> #include <array>
#include <boost/optional.hpp> #include <optional>
namespace libzcash { namespace libzcash {
@ -82,8 +82,8 @@ public:
virtual ~SaplingNote() {}; virtual ~SaplingNote() {};
boost::optional<uint256> cmu() const; std::optional<uint256> cmu() const;
boost::optional<uint256> nullifier(const SaplingFullViewingKey &vk, const uint64_t position) const; std::optional<uint256> nullifier(const SaplingFullViewingKey &vk, const uint64_t position) const;
uint256 rcm() const; uint256 rcm() const;
Zip212Enabled get_zip_212_enabled() const { Zip212Enabled get_zip_212_enabled() const {
@ -160,7 +160,7 @@ public:
SaplingNotePlaintext(const SaplingNote& note, std::array<unsigned char, ZC_MEMO_SIZE> memo); SaplingNotePlaintext(const SaplingNote& note, std::array<unsigned char, ZC_MEMO_SIZE> memo);
static boost::optional<SaplingNotePlaintext> decrypt( static std::optional<SaplingNotePlaintext> decrypt(
const Consensus::Params& params, const Consensus::Params& params,
int height, int height,
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
@ -169,20 +169,20 @@ public:
const uint256 &cmu const uint256 &cmu
); );
static boost::optional<SaplingNotePlaintext> plaintext_checks_without_height( static std::optional<SaplingNotePlaintext> plaintext_checks_without_height(
const SaplingNotePlaintext &plaintext, const SaplingNotePlaintext &plaintext,
const uint256 &ivk, const uint256 &ivk,
const uint256 &epk, const uint256 &epk,
const uint256 &cmu const uint256 &cmu
); );
static boost::optional<SaplingNotePlaintext> attempt_sapling_enc_decryption_deserialization( static std::optional<SaplingNotePlaintext> attempt_sapling_enc_decryption_deserialization(
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
const uint256 &ivk, const uint256 &ivk,
const uint256 &epk const uint256 &epk
); );
static boost::optional<SaplingNotePlaintext> decrypt( static std::optional<SaplingNotePlaintext> decrypt(
const Consensus::Params& params, const Consensus::Params& params,
int height, int height,
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
@ -192,7 +192,7 @@ public:
const uint256 &cmu const uint256 &cmu
); );
static boost::optional<SaplingNotePlaintext> plaintext_checks_without_height( static std::optional<SaplingNotePlaintext> plaintext_checks_without_height(
const SaplingNotePlaintext &plaintext, const SaplingNotePlaintext &plaintext,
const uint256 &epk, const uint256 &epk,
const uint256 &esk, const uint256 &esk,
@ -200,14 +200,14 @@ public:
const uint256 &cmu const uint256 &cmu
); );
static boost::optional<SaplingNotePlaintext> attempt_sapling_enc_decryption_deserialization( static std::optional<SaplingNotePlaintext> attempt_sapling_enc_decryption_deserialization(
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
const uint256 &epk, const uint256 &epk,
const uint256 &esk, const uint256 &esk,
const uint256 &pk_d const uint256 &pk_d
); );
boost::optional<SaplingNote> note(const SaplingIncomingViewingKey& ivk) const; std::optional<SaplingNote> note(const SaplingIncomingViewingKey& ivk) const;
virtual ~SaplingNotePlaintext() {} virtual ~SaplingNotePlaintext() {}
@ -227,7 +227,7 @@ public:
READWRITE(memo_); // 512 bytes READWRITE(memo_); // 512 bytes
} }
boost::optional<SaplingNotePlaintextEncryptionResult> encrypt(const uint256& pk_d) const; std::optional<SaplingNotePlaintextEncryptionResult> encrypt(const uint256& pk_d) const;
uint256 rcm() const; uint256 rcm() const;
uint256 generate_or_derive_esk() const; uint256 generate_or_derive_esk() const;
@ -254,7 +254,7 @@ public:
READWRITE(esk); // 8 bytes READWRITE(esk); // 8 bytes
} }
static boost::optional<SaplingOutgoingPlaintext> decrypt( static std::optional<SaplingOutgoingPlaintext> decrypt(
const SaplingOutCiphertext &ciphertext, const SaplingOutCiphertext &ciphertext,
const uint256& ovk, const uint256& ovk,
const uint256& cv, const uint256& cv,

View File

@ -91,7 +91,7 @@ void KDF(unsigned char K[NOTEENCRYPTION_CIPHER_KEYSIZE],
namespace libzcash { namespace libzcash {
boost::optional<SaplingNoteEncryption> SaplingNoteEncryption::FromDiversifier( std::optional<SaplingNoteEncryption> SaplingNoteEncryption::FromDiversifier(
diversifier_t d, diversifier_t d,
uint256 esk uint256 esk
) )
@ -100,13 +100,13 @@ boost::optional<SaplingNoteEncryption> SaplingNoteEncryption::FromDiversifier(
// Compute epk given the diversifier // Compute epk given the diversifier
if (!librustzcash_sapling_ka_derivepublic(d.begin(), esk.begin(), epk.begin())) { if (!librustzcash_sapling_ka_derivepublic(d.begin(), esk.begin(), epk.begin())) {
return boost::none; return std::nullopt;
} }
return SaplingNoteEncryption(epk, esk); return SaplingNoteEncryption(epk, esk);
} }
boost::optional<SaplingEncCiphertext> SaplingNoteEncryption::encrypt_to_recipient( std::optional<SaplingEncCiphertext> SaplingNoteEncryption::encrypt_to_recipient(
const uint256 &pk_d, const uint256 &pk_d,
const SaplingEncPlaintext &message const SaplingEncPlaintext &message
) )
@ -118,7 +118,7 @@ boost::optional<SaplingEncCiphertext> SaplingNoteEncryption::encrypt_to_recipien
uint256 dhsecret; uint256 dhsecret;
if (!librustzcash_sapling_ka_agree(pk_d.begin(), esk.begin(), dhsecret.begin())) { if (!librustzcash_sapling_ka_agree(pk_d.begin(), esk.begin(), dhsecret.begin())) {
return boost::none; return std::nullopt;
} }
// Construct the symmetric key // Construct the symmetric key
@ -142,7 +142,7 @@ boost::optional<SaplingEncCiphertext> SaplingNoteEncryption::encrypt_to_recipien
return ciphertext; return ciphertext;
} }
boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption( std::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption(
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
const uint256 &ivk, const uint256 &ivk,
const uint256 &epk const uint256 &epk
@ -151,7 +151,7 @@ boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption(
uint256 dhsecret; uint256 dhsecret;
if (!librustzcash_sapling_ka_agree(epk.begin(), ivk.begin(), dhsecret.begin())) { if (!librustzcash_sapling_ka_agree(epk.begin(), ivk.begin(), dhsecret.begin())) {
return boost::none; return std::nullopt;
} }
// Construct the symmetric key // Construct the symmetric key
@ -171,13 +171,13 @@ boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption(
0, 0,
cipher_nonce, K) != 0) cipher_nonce, K) != 0)
{ {
return boost::none; return std::nullopt;
} }
return plaintext; return plaintext;
} }
boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption ( std::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption (
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
const uint256 &epk, const uint256 &epk,
const uint256 &esk, const uint256 &esk,
@ -187,7 +187,7 @@ boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption (
uint256 dhsecret; uint256 dhsecret;
if (!librustzcash_sapling_ka_agree(pk_d.begin(), esk.begin(), dhsecret.begin())) { if (!librustzcash_sapling_ka_agree(pk_d.begin(), esk.begin(), dhsecret.begin())) {
return boost::none; return std::nullopt;
} }
// Construct the symmetric key // Construct the symmetric key
@ -207,7 +207,7 @@ boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption (
0, 0,
cipher_nonce, K) != 0) cipher_nonce, K) != 0)
{ {
return boost::none; return std::nullopt;
} }
return plaintext; return plaintext;
@ -246,7 +246,7 @@ SaplingOutCiphertext SaplingNoteEncryption::encrypt_to_ourselves(
return ciphertext; return ciphertext;
} }
boost::optional<SaplingOutPlaintext> AttemptSaplingOutDecryption( std::optional<SaplingOutPlaintext> AttemptSaplingOutDecryption(
const SaplingOutCiphertext &ciphertext, const SaplingOutCiphertext &ciphertext,
const uint256 &ovk, const uint256 &ovk,
const uint256 &cv, const uint256 &cv,
@ -271,7 +271,7 @@ boost::optional<SaplingOutPlaintext> AttemptSaplingOutDecryption(
0, 0,
cipher_nonce, K) != 0) cipher_nonce, K) != 0)
{ {
return boost::none; return std::nullopt;
} }
return plaintext; return plaintext;

View File

@ -13,6 +13,7 @@ https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
#include "zcash/Address.hpp" #include "zcash/Address.hpp"
#include <array> #include <array>
#include <optional>
namespace libzcash { namespace libzcash {
@ -42,9 +43,9 @@ protected:
public: public:
static boost::optional<SaplingNoteEncryption> FromDiversifier(diversifier_t d, uint256 esk); static std::optional<SaplingNoteEncryption> FromDiversifier(diversifier_t d, uint256 esk);
boost::optional<SaplingEncCiphertext> encrypt_to_recipient( std::optional<SaplingEncCiphertext> encrypt_to_recipient(
const uint256 &pk_d, const uint256 &pk_d,
const SaplingEncPlaintext &message const SaplingEncPlaintext &message
); );
@ -67,7 +68,7 @@ public:
// Attempts to decrypt a Sapling note. This will not check that the contents // Attempts to decrypt a Sapling note. This will not check that the contents
// of the ciphertext are correct. // of the ciphertext are correct.
boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption( std::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption(
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
const uint256 &ivk, const uint256 &ivk,
const uint256 &epk const uint256 &epk
@ -75,7 +76,7 @@ boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption(
// Attempts to decrypt a Sapling note using outgoing plaintext. // Attempts to decrypt a Sapling note using outgoing plaintext.
// This will not check that the contents of the ciphertext are correct. // This will not check that the contents of the ciphertext are correct.
boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption ( std::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption (
const SaplingEncCiphertext &ciphertext, const SaplingEncCiphertext &ciphertext,
const uint256 &epk, const uint256 &epk,
const uint256 &esk, const uint256 &esk,
@ -84,7 +85,7 @@ boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption (
// Attempts to decrypt a Sapling note. This will not check that the contents // Attempts to decrypt a Sapling note. This will not check that the contents
// of the ciphertext are correct. // of the ciphertext are correct.
boost::optional<SaplingOutPlaintext> AttemptSaplingOutDecryption( std::optional<SaplingOutPlaintext> AttemptSaplingOutDecryption(
const SaplingOutCiphertext &ciphertext, const SaplingOutCiphertext &ciphertext,
const uint256 &ovk, const uint256 &ovk,
const uint256 &cv, const uint256 &cv,

View File

@ -23,13 +23,13 @@ uint256 SaplingPaymentAddress::GetHash() const {
return Hash(ss.begin(), ss.end()); return Hash(ss.begin(), ss.end());
} }
boost::optional<SaplingPaymentAddress> SaplingIncomingViewingKey::address(diversifier_t d) const { std::optional<SaplingPaymentAddress> SaplingIncomingViewingKey::address(diversifier_t d) const {
uint256 pk_d; uint256 pk_d;
if (librustzcash_check_diversifier(d.data())) { if (librustzcash_check_diversifier(d.data())) {
librustzcash_ivk_to_pkd(this->begin(), d.data(), pk_d.begin()); librustzcash_ivk_to_pkd(this->begin(), d.data(), pk_d.begin());
return SaplingPaymentAddress(d, pk_d); return SaplingPaymentAddress(d, pk_d);
} else { } else {
return boost::none; return std::nullopt;
} }
} }
@ -79,7 +79,7 @@ SaplingFullViewingKey SaplingSpendingKey::full_viewing_key() const {
SaplingPaymentAddress SaplingSpendingKey::default_address() const { SaplingPaymentAddress SaplingSpendingKey::default_address() const {
// Iterates within default_diversifier to ensure a valid address is returned // Iterates within default_diversifier to ensure a valid address is returned
auto addrOpt = full_viewing_key().in_viewing_key().address(default_diversifier(*this)); auto addrOpt = full_viewing_key().in_viewing_key().address(default_diversifier(*this));
assert(addrOpt != boost::none); assert(addrOpt != std::nullopt);
return addrOpt.value(); return addrOpt.value();
} }

View File

@ -9,6 +9,8 @@
#include "uint256.h" #include "uint256.h"
#include "zcash/Zcash.h" #include "zcash/Zcash.h"
#include <optional>
namespace libzcash { namespace libzcash {
const size_t SerializedSaplingPaymentAddressSize = 43; const size_t SerializedSaplingPaymentAddressSize = 43;
@ -53,7 +55,7 @@ public:
SaplingIncomingViewingKey(uint256 ivk) : uint256(ivk) { } SaplingIncomingViewingKey(uint256 ivk) : uint256(ivk) { }
// Can pass in diversifier for Sapling addr // Can pass in diversifier for Sapling addr
boost::optional<SaplingPaymentAddress> address(diversifier_t d) const; std::optional<SaplingPaymentAddress> address(diversifier_t d) const;
}; };
class SaplingFullViewingKey { class SaplingFullViewingKey {

View File

@ -54,7 +54,7 @@ uint256 ovkForShieldingFromTaddr(HDSeed& seed) {
namespace libzcash { namespace libzcash {
boost::optional<SaplingExtendedFullViewingKey> SaplingExtendedFullViewingKey::Derive(uint32_t i) const std::optional<SaplingExtendedFullViewingKey> SaplingExtendedFullViewingKey::Derive(uint32_t i) const
{ {
CDataStream ss_p(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss_p(SER_NETWORK, PROTOCOL_VERSION);
ss_p << *this; ss_p << *this;
@ -71,11 +71,11 @@ boost::optional<SaplingExtendedFullViewingKey> SaplingExtendedFullViewingKey::De
ss_i >> xfvk_i; ss_i >> xfvk_i;
return xfvk_i; return xfvk_i;
} else { } else {
return boost::none; return std::nullopt;
} }
} }
boost::optional<std::pair<diversifier_index_t, libzcash::SaplingPaymentAddress>> std::optional<std::pair<diversifier_index_t, libzcash::SaplingPaymentAddress>>
SaplingExtendedFullViewingKey::Address(diversifier_index_t j) const SaplingExtendedFullViewingKey::Address(diversifier_index_t j) const
{ {
CDataStream ss_xfvk(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss_xfvk(SER_NETWORK, PROTOCOL_VERSION);
@ -93,7 +93,7 @@ boost::optional<std::pair<diversifier_index_t, libzcash::SaplingPaymentAddress>>
ss_addr >> addr; ss_addr >> addr;
return std::make_pair(j_ret, addr); return std::make_pair(j_ret, addr);
} else { } else {
return boost::none; return std::nullopt;
} }
} }
@ -105,7 +105,7 @@ libzcash::SaplingPaymentAddress SaplingExtendedFullViewingKey::DefaultAddress()
if (!addr) { if (!addr) {
throw std::runtime_error("SaplingExtendedFullViewingKey::DefaultAddress(): No valid diversifiers out of 2^88!"); throw std::runtime_error("SaplingExtendedFullViewingKey::DefaultAddress(): No valid diversifiers out of 2^88!");
} }
return addr.get().second; return addr.value().second;
} }
SaplingExtendedSpendingKey SaplingExtendedSpendingKey::Master(const HDSeed& seed) SaplingExtendedSpendingKey SaplingExtendedSpendingKey::Master(const HDSeed& seed)

View File

@ -10,7 +10,7 @@
#include "uint256.h" #include "uint256.h"
#include "zcash/address/sapling.hpp" #include "zcash/address/sapling.hpp"
#include <boost/optional.hpp> #include <optional>
const uint32_t ZIP32_HARDENED_KEY_LIMIT = 0x80000000; const uint32_t ZIP32_HARDENED_KEY_LIMIT = 0x80000000;
const size_t ZIP32_XFVK_SIZE = 169; const size_t ZIP32_XFVK_SIZE = 169;
@ -69,12 +69,12 @@ struct SaplingExtendedFullViewingKey {
READWRITE(dk); READWRITE(dk);
} }
boost::optional<SaplingExtendedFullViewingKey> Derive(uint32_t i) const; std::optional<SaplingExtendedFullViewingKey> Derive(uint32_t i) const;
// Returns the first index starting from j that generates a valid // Returns the first index starting from j that generates a valid
// payment address, along with the corresponding address. Returns // payment address, along with the corresponding address. Returns
// an error if the diversifier space is exhausted. // an error if the diversifier space is exhausted.
boost::optional<std::pair<diversifier_index_t, libzcash::SaplingPaymentAddress>> std::optional<std::pair<diversifier_index_t, libzcash::SaplingPaymentAddress>>
Address(diversifier_index_t j) const; Address(diversifier_index_t j) const;
libzcash::SaplingPaymentAddress DefaultAddress() const; libzcash::SaplingPaymentAddress DefaultAddress() const;

View File

@ -374,7 +374,7 @@ CWalletTx CreateSaplingTxWithNoteData(const Consensus::Params& consensusParams,
auto wtx = GetValidSaplingReceive(consensusParams, keyStore, sk, 10); auto wtx = GetValidSaplingReceive(consensusParams, keyStore, sk, 10);
auto testNote = GetTestSaplingNote(sk.DefaultAddress(), 10); auto testNote = GetTestSaplingNote(sk.DefaultAddress(), 10);
auto fvk = sk.expsk.full_viewing_key(); auto fvk = sk.expsk.full_viewing_key();
auto nullifier = testNote.note.nullifier(fvk, testNote.tree.witness().position()).get(); auto nullifier = testNote.note.nullifier(fvk, testNote.tree.witness().position()).value();
mapSaplingNoteData_t noteDataMap; mapSaplingNoteData_t noteDataMap;
SaplingOutPoint outPoint {wtx.GetHash(), 0}; SaplingOutPoint outPoint {wtx.GetHash(), 0};
@ -595,7 +595,7 @@ double benchmark_create_sapling_spend()
SaplingNote note(address, GetRand(MAX_MONEY), libzcash::Zip212Enabled::BeforeZip212); SaplingNote note(address, GetRand(MAX_MONEY), libzcash::Zip212Enabled::BeforeZip212);
SaplingMerkleTree tree; SaplingMerkleTree tree;
auto maybe_cmu = note.cmu(); auto maybe_cmu = note.cmu();
tree.append(maybe_cmu.get()); tree.append(maybe_cmu.value());
auto anchor = tree.root(); auto anchor = tree.root();
auto witness = tree.witness(); auto witness = tree.witness();
auto maybe_nf = note.nullifier(expsk.full_viewing_key(), witness.position()); auto maybe_nf = note.nullifier(expsk.full_viewing_key(), witness.position());
@ -653,7 +653,7 @@ double benchmark_create_sapling_output()
throw JSONRPCError(RPC_INTERNAL_ERROR, "SaplingNotePlaintext::encrypt() failed"); throw JSONRPCError(RPC_INTERNAL_ERROR, "SaplingNotePlaintext::encrypt() failed");
} }
auto enc = res.get(); auto enc = res.value();
auto encryptor = enc.second; auto encryptor = enc.second;
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);