25 txBuilder(consensusParams, _wallet)
27 assert (
wallet !=
nullptr);
60 return errorOut(
"Spending key not in the wallet");
71 if (t.IsTransparent()) {
83 bool isFromtAddress =
false;
84 bool isFromShielded =
false;
88 std::vector<OutPointWrapper> coins;
92 for (
const auto& coin : coins) {
93 if (coin.outPoint.isTransparent) {
94 isFromtAddress =
true;
96 isFromShielded =
true;
104 if (!isFromtAddress && !isFromShielded) {
111 if (!isFromtAddress && !isFromShielded) {
112 return errorOut(
"From address parameter missing");
116 if (isFromtAddress && isFromShielded) {
117 return errorOut(
"From address type cannot be shielded and transparent");
124 if (isFromShielded &&
mindepth == 0) {
125 return errorOut(
"Minconf cannot be zero when sending from shielded address");
129 unsigned int nSubtractFeeFromAmount = 0;
131 if (rec.IsSubtractFee()) nSubtractFeeFromAmount++;
141 if (isFromShielded) {
156 CAmount amount = t.getAmount();
158 if (t.IsSubtractFee()) {
160 amount -= nFeeRet / nSubtractFeeFromAmount;
164 amount -= nFeeRet % nSubtractFeeFromAmount;
168 if (t.IsTransparent()) {
171 const auto& address = t.getSapPaymentAddr();
173 std::array<unsigned char, ZC_MEMO_SIZE> vMemo = {};
183 if (isFromtAddress && !(result =
loadUtxos(txValues))) {
187 const auto& retCalc =
checkTxValues(txValues, isFromtAddress, isFromShielded);
188 if (!retCalc)
return retCalc;
195 }
else if (isFromtAddress) {
206 return errorOut(
"Could not generate a taddr to use as a change address");
216 auto opTx = txResult.
GetTx();
224 bool isShielded = opTx->IsShieldedTx();
227 if (nFeeNeeded <= nFeeRet) {
229 CAmount nMaxFee = nFeeNeeded * (isShielded ? 100 : 10000);
230 if (nFeeRet > nMaxFee) {
242 if (
fee > 0 && nFeeNeeded >
fee) {
248 return errorOut(
"Unable to compute optimal fee. Set manually.");
253 nFeeRet = nFeeNeeded;
261 auto opTx = txResult.
GetTx();
266 finalTx = MakeTransactionRef(*opTx);
277 retTxHash =
finalTx->GetHash().ToString();
284 return (res) ?
send(retTxHash) : res;
310 std::vector<OutPointWrapper> vCoins;
313 std::vector<COutput> selectedUTXOInputs;
315 for (
const auto& outpoint : vCoins) {
318 nSelectedValue += tx->
tx->vout[outpoint.outPoint.n].nValue;
319 selectedUTXOInputs.emplace_back(tx, outpoint.outPoint.n, 0,
true,
true,
true);
321 return loadUtxos(txValues, selectedUTXOInputs, nSelectedValue);
325 std::set<CTxDestination> destinations;
334 return errorOut(
"Insufficient funds, no available UTXO to spend");
339 return i.Value() > j.Value();
348 CAmount selectedUTXOAmount = 0;
349 std::vector<COutput> selectedTInputs;
351 const auto& outPoint = t.tx->tx->vout[t.i];
352 selectedUTXOAmount += outPoint.nValue;
353 selectedTInputs.emplace_back(t);
354 if (selectedUTXOAmount >= txValues.
target) {
356 dustChange = selectedUTXOAmount - txValues.
target;
357 if (dustChange == 0 || dustChange >= dustThreshold) {
364 if (selectedUTXOAmount < txValues.
target) {
370 if (dustChange < dustThreshold && dustChange != 0) {
371 return errorOut(
strprintf(
"Insufficient transparent funds, have %s, need %s more to avoid creating invalid change output %s (dust threshold is %s)",
375 return loadUtxos(txValues, selectedTInputs, selectedUTXOAmount);
385 const auto& outPoint = t.tx->tx->vout[t.i];
409 LogPrintf(
"WARNING: nullifier not cached for note %s. Updating...\n", noteStr);
411 const auto& witness = nd.
witnesses.front();
415 LogPrintf(
"ERROR: Unable to recover nullifier for note %s.\n", noteStr);
420 if (sspkm->IsSaplingSpent(*(nd.
nullifier))) {
421 LogPrintf(
"Removed note %s as it appears to be already spent.\n", noteStr);
437 if (hasCoinControl) {
438 std::vector<OutPointWrapper> vCoins;
442 std::vector<SaplingOutPoint> vSaplingOutpoints;
443 vSaplingOutpoints.reserve(vCoins.size());
444 for (
const auto& outpoint : vCoins) {
445 vSaplingOutpoints.emplace_back(outpoint.outPoint.hash, outpoint.outPoint.n);
451 return errorOut(
"Insufficient funds, no available notes to spend");
458 std::vector<SaplingNoteEntry> _shieldedInputs;
460 return errorOut(_shieldedInputs.empty() ?
461 "Insufficient funds, no available notes to spend" :
462 "Insufficient funds, shielded PIV need at least 5 confirmations");
469 return i.note.value() > j.note.value();
473 std::vector<SaplingOutPoint> ops;
474 std::vector<libzcash::SaplingNote> notes;
475 std::vector<libzcash::SaplingExpandedSpendingKey> spendingKeys;
484 if (!resLoadKeys)
return resLoadKeys;
491 LogPrintf(
"ERROR: Witness/Nullifier invalid for note %s. Restart with --zapwallettxes\n", t.
op.
ToString());
492 return errorOut(
"Note cache corrupt. Try \"Recover transactions\" (Settings-->Debug-->\"wallet repair\")");
504 spendingKeys.emplace_back(expsk);
505 ops.emplace_back(t.
op);
506 notes.emplace_back(t.
note);
512 if (dustChange == 0 || dustChange >= dustThreshold) {
526 std::vector<Optional<SaplingWitness>> witnesses;
530 for (
size_t i = 0; i < notes.size(); i++) {
532 return errorOut(
"Missing witness for Sapling note");
549 std::vector<unsigned char> rawMemo(s.begin(), s.end());
550 const size_t sizeMemo = rawMemo.size();
555 for (
unsigned int i = 0; i < sizeMemo; i++) {
556 memoRet[i] = rawMemo[i];
565 unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
569 size_t nTransparentOuts = 0;
570 for (
const auto& t : recipients) {
571 if (t.IsTransparent()) {
576 mtx.
sapData->vShieldedOutput.emplace_back();
588 if (txsize > max_tx_size) {
589 return errorOut(
strprintf(
"Too many outputs, size of raw transaction would be larger than limit of %d bytes", max_tx_size));
bool IsValidPaymentAddress(const libzcash::PaymentAddress &zaddr)
Check whether a PaymentAddress is not an InvalidEncoding.
int64_t CAmount
Amount in PIV (Can be negative)
bool GetSaplingExtendedSpendingKey(const libzcash::SaplingPaymentAddress &addr, libzcash::SaplingExtendedSpendingKey &extskOut) const
void ListSelected(std::vector< OutPointWrapper > &vOutpoints) const
CTxDestination destChange
Optional< libzcash::SaplingPaymentAddress > destShieldChange
CAmount GetFeePerK() const
An outpoint - a combination of a transaction hash and an index n into its vout.
An encapsulated public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
A key allocated from the key pool.
The basic transaction that is broadcasted on the network and contained in blocks.
unsigned int GetTotalSize() const
An output of a transaction.
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,...
std::map< uint256, CWalletTx > mapWallet
boost::signals2::signal< void(CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged
Wallet transaction added, removed or updated.
SaplingScriptPubKeyMan * GetSaplingScriptPubKeyMan() const
WalletDatabase & GetDBHandle() const
A transaction with a bunch of additional info that only the owner cares about.
mapSaplingNoteData_t mapSaplingNoteData
void MarkDirty()
make sure balances are recalculated
bool isFromTAddress() const
bool isFromSapAddress() const
Optional< libzcash::SaplingPaymentAddress > fromSapAddr
Optional< uint256 > nullifier
Cached note nullifier.
std::list< SaplingWitness > witnesses
std::vector< SaplingNoteEntry > shieldedInputs
const CCoinControl * coinControl
SaplingOperation(const Consensus::Params &consensusParams, CWallet *_wallet)
TransactionBuilder txBuilder
OperationResult loadUnspentNotes(TxValues &txValues, uint256 &ovk)
OperationResult loadUtxos(TxValues &values)
OperationResult checkTxValues(TxValues &txValues, bool isFromtAddress, bool isFromShielded)
void setFromAddress(const CTxDestination &)
std::vector< COutput > transInputs
OperationResult send(std::string &retTxHash)
std::vector< SendManyRecipient > recipients
OperationResult buildAndSend(std::string &retTxHash)
SaplingOperation * setSelectTransparentCoins(const bool select, const bool _fIncludeDelegated=false)
std::string ToString() const
void GetSaplingNoteWitnesses(const std::vector< SaplingOutPoint > ¬es, std::vector< Optional< SaplingWitness >> &witnesses, uint256 &final_anchor) const
Return all of the witnesses for the input notes.
void AddTransparentOutput(const CTxOut &out)
void SetFee(CAmount _fee)
void AddSaplingSpend(const libzcash::SaplingExpandedSpendingKey &expsk, const libzcash::SaplingNote ¬e, const uint256 &anchor, const SaplingWitness &witness)
TransactionBuilderResult Build(bool fDummySig=false)
void ClearProofsAndSignatures()
void AddSaplingOutput(const uint256 &ovk, const libzcash::SaplingPaymentAddress &to, CAmount value, const std::array< unsigned char, ZC_MEMO_SIZE > &memo)
TransactionBuilderResult ProveAndSign()
void AddTransparentInput(const COutPoint &utxo, const CScript &scriptPubKey, CAmount value)
void SendChangeTo(const libzcash::SaplingPaymentAddress &changeAddr, const uint256 &ovk)
Optional< CTransaction > GetTx()
Access to the wallet database.
bool WriteTx(const CWalletTx &wtx)
SaplingFullViewingKey full_viewing_key() const
Optional< uint256 > nullifier(const SaplingFullViewingKey &vk, const uint64_t position) const
CWallet::CommitResult CommitTransaction(CTransactionRef tx, CReserveKey &opReservekey, CConnman *connman)
bool AvailableCoins(std::vector< COutput > *pCoins, const CCoinControl *coinControl=nullptr, AvailableCoinsFilter coinsFilter=AvailableCoinsFilter()) const
populate vCoins with vector of available COutputs.
bool GetReservedKey(CPubKey &pubkey, bool internal=false)
std::string ToString() const
const CWalletTx * GetWalletTx(const uint256 &hash) const
std::unique_ptr< CConnman > g_connman
#define LogPrint(category,...)
std::string EncodePaymentAddress(const libzcash::PaymentAddress &zaddr)
bool IsValidDestination(const CWDestination &address)
OperationResult errorOut(const std::string &errorStr)
boost::optional< T > Optional
Substitute for C++17 std::optional.
CAmount GetDustThreshold(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
CAmount GetShieldedDustThreshold(const CFeeRate &dustRelayFeeIn)
OperationResult loadKeysFromShieldedFrom(const CWallet *pwallet, const libzcash::SaplingPaymentAddress &addr, libzcash::SaplingExpandedSpendingKey &expskOut, uint256 &ovkOut)
TxValues calculateTarget(const std::vector< SendManyRecipient > &recipients, const CAmount &fee)
OperationResult GetMemoFromString(const std::string &s, std::array< unsigned char, ZC_MEMO_SIZE > &memoRet)
OperationResult CheckTransactionSize(std::vector< SendManyRecipient > &recipients, bool fromTaddr)
#define CTXIN_SPEND_DUST_SIZE
#define CTXOUT_REGULAR_SIZE
boost::variant< CNoDestination, CKeyID, CScriptID, CExchangeKeyID > CTxDestination
A txout script template with a specific destination.
A mutable version of CTransaction.
Optional< SaplingTxData > sapData
CWallet::CommitStatus status
Parameters that influence chain consensus.
Sapling note, its location in a transaction, and number of confirmations.
libzcash::SaplingPaymentAddress address
libzcash::SaplingNote note
libzcash::SaplingExpandedSpendingKey expsk
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::string FormatMoney(const CAmount &n, bool fPlus)
Money parsing/formatting utilities.
CAmount GetShieldedTxMinFee(const CTransaction &tx)
Return the minimum fee for a shielded tx.
CFeeRate minRelayTxFee
Fees smaller than this (in upiv) are considered zero fee (for relaying, mining and transaction creati...
CAmount GetMinRelayFee(const CTransaction &tx, const CTxMemPool &pool, unsigned int nBytes)