Replace CReserveKey with ReserveDestinatoin

Instead of reserving keys, reserve destinations which are backed by keys
This commit is contained in:
Andrew Chow
2019-06-18 15:48:20 -04:00
parent 172213be5b
commit 33d13edd2b
6 changed files with 73 additions and 74 deletions

View File

@@ -2609,9 +2609,9 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
auto locked_chain = chain().lock();
LOCK(cs_wallet);
CReserveKey reservekey(this);
ReserveDestination reservedest(this);
CTransactionRef tx_new;
if (!CreateTransaction(*locked_chain, vecSend, tx_new, reservekey, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) {
if (!CreateTransaction(*locked_chain, vecSend, tx_new, reservedest, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) {
return false;
}
@@ -2619,7 +2619,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
tx.vout.insert(tx.vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]);
// We don't have the normal Create/Commit cycle, and don't want to risk
// reusing change, so just remove the key from the keypool here.
reservekey.KeepKey();
reservedest.KeepDestination();
}
// Copy output sizes from new transaction; they may have had the fee
@@ -2730,7 +2730,7 @@ OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vec
return m_default_address_type;
}
bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CReserveKey& reservekey, CAmount& nFeeRet,
bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, ReserveDestination& reservedest, CAmount& nFeeRet,
int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
{
CAmount nValue = 0;
@@ -2771,7 +2771,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
CoinSelectionParams coin_selection_params; // Parameters for coin selection, init with dummy
// Create change script that will be used if we need change
// TODO: pass in scriptChange instead of reservekey so
// TODO: pass in scriptChange instead of reservedest so
// change transaction isn't always pay-to-bitcoin-address
CScript scriptChange;
@@ -2791,19 +2791,16 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
strFailReason = _("Can't generate a change-address key. No keys in the internal keypool and can't generate any keys.");
return false;
}
CPubKey vchPubKey;
bool ret;
ret = reservekey.GetReservedKey(vchPubKey, true);
CTxDestination dest;
const OutputType change_type = TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type : m_default_change_type, vecSend);
bool ret = reservedest.GetReservedDestination(change_type, dest, true);
if (!ret)
{
strFailReason = _("Keypool ran out, please call keypoolrefill first");
strFailReason = "Keypool ran out, please call keypoolrefill first";
return false;
}
const OutputType change_type = TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type : m_default_change_type, vecSend);
LearnRelatedScripts(vchPubKey, change_type);
scriptChange = GetScriptForDestination(GetDestinationForKey(vchPubKey, change_type));
scriptChange = GetScriptForDestination(dest);
}
CTxOut change_prototype_txout(0, scriptChange);
coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout);
@@ -3024,7 +3021,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
}
}
if (nChangePosInOut == -1) reservekey.ReturnKey(); // Return any reserved key if we don't have change
if (nChangePosInOut == -1) reservedest.ReturnDestination(); // Return any reserved address if we don't have change
// Shuffle selected coins and fill in final vin
txNew.vin.clear();
@@ -3097,7 +3094,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
/**
* Call after CreateTransaction unless you want to abort
*/
bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CReserveKey& reservekey, CValidationState& state)
bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, ReserveDestination& reservedest, CValidationState& state)
{
{
auto locked_chain = chain().lock();
@@ -3112,7 +3109,7 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
WalletLogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString()); /* Continued */
{
// Take key pair from key pool so it won't be used again
reservekey.KeepKey();
reservedest.KeepDestination();
// Add tx to wallet, because if it has change it's also ours,
// otherwise just for transaction history.
@@ -3713,7 +3710,7 @@ std::set<CTxDestination> CWallet::GetLabelAddresses(const std::string& label) co
return result;
}
bool CReserveKey::GetReservedKey(CPubKey& pubkey, bool internal)
bool ReserveDestination::GetReservedDestination(const OutputType type, CTxDestination& dest, bool internal)
{
if (!pwallet->CanGetAddresses(internal)) {
return false;
@@ -3729,25 +3726,29 @@ bool CReserveKey::GetReservedKey(CPubKey& pubkey, bool internal)
fInternal = keypool.fInternal;
}
assert(vchPubKey.IsValid());
pubkey = vchPubKey;
pwallet->LearnRelatedScripts(vchPubKey, type);
address = GetDestinationForKey(vchPubKey, type);
dest = address;
return true;
}
void CReserveKey::KeepKey()
void ReserveDestination::KeepDestination()
{
if (nIndex != -1)
pwallet->KeepKey(nIndex);
nIndex = -1;
vchPubKey = CPubKey();
address = CNoDestination();
}
void CReserveKey::ReturnKey()
void ReserveDestination::ReturnDestination()
{
if (nIndex != -1) {
pwallet->ReturnKey(nIndex, fInternal, vchPubKey);
}
nIndex = -1;
vchPubKey = CPubKey();
address = CNoDestination();
}
void CWallet::MarkReserveKeysAsUsed(int64_t keypool_id)