[wallet] Construct CWalletTx objects in CommitTransaction
Construct CWalletTx objects in CWallet::CommitTransaction, instead of having callers do it. This ensures CWalletTx objects are constructed in a uniform way and all fields are set. This also makes it possible to avoid confusing and wasteful CWalletTx copies in https://github.com/bitcoin/bitcoin/pull/9381 There is no change in behavior.
This commit is contained in:
parent
29fad97c32
commit
a128bdc9e1
8 changed files with 68 additions and 74 deletions
|
@ -275,9 +275,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||||
int nChangePosRet = -1;
|
int nChangePosRet = -1;
|
||||||
std::string strFailReason;
|
std::string strFailReason;
|
||||||
|
|
||||||
CWalletTx *newTx = transaction.getTransaction();
|
CTransactionRef& newTx = transaction.getTransaction();
|
||||||
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
||||||
bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
|
bool fCreated = wallet->CreateTransaction(vecSend, newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
|
||||||
transaction.setTransactionFee(nFeeRequired);
|
transaction.setTransactionFee(nFeeRequired);
|
||||||
if (fSubtractFeeFromAmount && fCreated)
|
if (fSubtractFeeFromAmount && fCreated)
|
||||||
transaction.reassignAmounts(nChangePosRet);
|
transaction.reassignAmounts(nChangePosRet);
|
||||||
|
@ -309,8 +309,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, wallet->cs_wallet);
|
LOCK2(cs_main, wallet->cs_wallet);
|
||||||
CWalletTx *newTx = transaction.getTransaction();
|
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> vOrderForm;
|
||||||
for (const SendCoinsRecipient &rcp : transaction.getRecipients())
|
for (const SendCoinsRecipient &rcp : transaction.getRecipients())
|
||||||
{
|
{
|
||||||
if (rcp.paymentRequest.IsInitialized())
|
if (rcp.paymentRequest.IsInitialized())
|
||||||
|
@ -321,22 +321,22 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store PaymentRequests in wtx.vOrderForm in wallet.
|
// Store PaymentRequests in wtx.vOrderForm in wallet.
|
||||||
std::string key("PaymentRequest");
|
|
||||||
std::string value;
|
std::string value;
|
||||||
rcp.paymentRequest.SerializeToString(&value);
|
rcp.paymentRequest.SerializeToString(&value);
|
||||||
newTx->vOrderForm.push_back(make_pair(key, value));
|
vOrderForm.emplace_back("PaymentRequest", std::move(value));
|
||||||
}
|
}
|
||||||
else if (!rcp.message.isEmpty()) // Message from normal bitcoin:URI (bitcoin:123...?message=example)
|
else if (!rcp.message.isEmpty()) // Message from normal bitcoin:URI (bitcoin:123...?message=example)
|
||||||
newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
|
vOrderForm.emplace_back("Message", rcp.message.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTransactionRef& newTx = transaction.getTransaction();
|
||||||
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if(!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get(), state))
|
if (!wallet->CommitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm), {} /* fromAccount */, *keyChange, g_connman.get(), state))
|
||||||
return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason()));
|
return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason()));
|
||||||
|
|
||||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ssTx << *newTx->tx;
|
ssTx << newTx;
|
||||||
transaction_array.append(&(ssTx[0]), ssTx.size());
|
transaction_array.append(&(ssTx[0]), ssTx.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,6 @@ WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &
|
||||||
walletTransaction(0),
|
walletTransaction(0),
|
||||||
fee(0)
|
fee(0)
|
||||||
{
|
{
|
||||||
walletTransaction = new CWalletTx();
|
|
||||||
}
|
|
||||||
|
|
||||||
WalletModelTransaction::~WalletModelTransaction()
|
|
||||||
{
|
|
||||||
delete walletTransaction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<SendCoinsRecipient> WalletModelTransaction::getRecipients() const
|
QList<SendCoinsRecipient> WalletModelTransaction::getRecipients() const
|
||||||
|
@ -25,14 +19,14 @@ QList<SendCoinsRecipient> WalletModelTransaction::getRecipients() const
|
||||||
return recipients;
|
return recipients;
|
||||||
}
|
}
|
||||||
|
|
||||||
CWalletTx *WalletModelTransaction::getTransaction() const
|
CTransactionRef& WalletModelTransaction::getTransaction()
|
||||||
{
|
{
|
||||||
return walletTransaction;
|
return walletTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int WalletModelTransaction::getTransactionSize()
|
unsigned int WalletModelTransaction::getTransactionSize()
|
||||||
{
|
{
|
||||||
return (!walletTransaction ? 0 : ::GetVirtualTransactionSize(*walletTransaction->tx));
|
return (!walletTransaction ? 0 : ::GetVirtualTransactionSize(*walletTransaction));
|
||||||
}
|
}
|
||||||
|
|
||||||
CAmount WalletModelTransaction::getTransactionFee() const
|
CAmount WalletModelTransaction::getTransactionFee() const
|
||||||
|
@ -62,7 +56,7 @@ void WalletModelTransaction::reassignAmounts(int nChangePosRet)
|
||||||
if (out.amount() <= 0) continue;
|
if (out.amount() <= 0) continue;
|
||||||
if (i == nChangePosRet)
|
if (i == nChangePosRet)
|
||||||
i++;
|
i++;
|
||||||
subtotal += walletTransaction->tx->vout[i].nValue;
|
subtotal += walletTransaction->vout[i].nValue;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
rcp.amount = subtotal;
|
rcp.amount = subtotal;
|
||||||
|
@ -71,7 +65,7 @@ void WalletModelTransaction::reassignAmounts(int nChangePosRet)
|
||||||
{
|
{
|
||||||
if (i == nChangePosRet)
|
if (i == nChangePosRet)
|
||||||
i++;
|
i++;
|
||||||
rcp.amount = walletTransaction->tx->vout[i].nValue;
|
rcp.amount = walletTransaction->vout[i].nValue;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,10 @@ class WalletModelTransaction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit WalletModelTransaction(const QList<SendCoinsRecipient> &recipients);
|
explicit WalletModelTransaction(const QList<SendCoinsRecipient> &recipients);
|
||||||
~WalletModelTransaction();
|
|
||||||
|
|
||||||
QList<SendCoinsRecipient> getRecipients() const;
|
QList<SendCoinsRecipient> getRecipients() const;
|
||||||
|
|
||||||
CWalletTx *getTransaction() const;
|
CTransactionRef& getTransaction();
|
||||||
unsigned int getTransactionSize();
|
unsigned int getTransactionSize();
|
||||||
|
|
||||||
void setTransactionFee(const CAmount& newFee);
|
void setTransactionFee(const CAmount& newFee);
|
||||||
|
@ -39,7 +38,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<SendCoinsRecipient> recipients;
|
QList<SendCoinsRecipient> recipients;
|
||||||
CWalletTx *walletTransaction;
|
CTransactionRef walletTransaction;
|
||||||
std::unique_ptr<CReserveKey> keyChange;
|
std::unique_ptr<CReserveKey> keyChange;
|
||||||
CAmount fee;
|
CAmount fee;
|
||||||
};
|
};
|
||||||
|
|
|
@ -262,23 +262,20 @@ Result CommitTransaction(CWallet* wallet, const uint256& txid, CMutableTransacti
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CWalletTx wtxBumped(wallet, MakeTransactionRef(std::move(mtx)));
|
|
||||||
// commit/broadcast the tx
|
// commit/broadcast the tx
|
||||||
|
CTransactionRef tx = MakeTransactionRef(std::move(mtx));
|
||||||
|
mapValue_t mapValue = oldWtx.mapValue;
|
||||||
|
mapValue["replaces_txid"] = oldWtx.GetHash().ToString();
|
||||||
|
|
||||||
CReserveKey reservekey(wallet);
|
CReserveKey reservekey(wallet);
|
||||||
wtxBumped.mapValue = oldWtx.mapValue;
|
|
||||||
wtxBumped.mapValue["replaces_txid"] = oldWtx.GetHash().ToString();
|
|
||||||
wtxBumped.vOrderForm = oldWtx.vOrderForm;
|
|
||||||
wtxBumped.strFromAccount = oldWtx.strFromAccount;
|
|
||||||
wtxBumped.fTimeReceivedIsTxTime = true;
|
|
||||||
wtxBumped.fFromMe = true;
|
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!wallet->CommitTransaction(wtxBumped, reservekey, g_connman.get(), state)) {
|
if (!wallet->CommitTransaction(tx, std::move(mapValue), oldWtx.vOrderForm, oldWtx.strFromAccount, reservekey, g_connman.get(), state)) {
|
||||||
// NOTE: CommitTransaction never returns false, so this should never happen.
|
// NOTE: CommitTransaction never returns false, so this should never happen.
|
||||||
errors.push_back(strprintf("The transaction was rejected: %s", FormatStateMessage(state)));
|
errors.push_back(strprintf("The transaction was rejected: %s", FormatStateMessage(state)));
|
||||||
return Result::WALLET_ERROR;
|
return Result::WALLET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bumped_txid = wtxBumped.GetHash();
|
bumped_txid = tx->GetHash();
|
||||||
if (state.IsInvalid()) {
|
if (state.IsInvalid()) {
|
||||||
// This can happen if the mempool rejected the transaction. Report
|
// This can happen if the mempool rejected the transaction. Report
|
||||||
// what happened in the "errors" response.
|
// what happened in the "errors" response.
|
||||||
|
@ -286,7 +283,7 @@ Result CommitTransaction(CWallet* wallet, const uint256& txid, CMutableTransacti
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark the original tx as bumped
|
// mark the original tx as bumped
|
||||||
if (!wallet->MarkReplaced(oldWtx.GetHash(), wtxBumped.GetHash())) {
|
if (!wallet->MarkReplaced(oldWtx.GetHash(), bumped_txid)) {
|
||||||
// TODO: see if JSON-RPC has a standard way of returning a response
|
// TODO: see if JSON-RPC has a standard way of returning a response
|
||||||
// along with an exception. It would be good to return information about
|
// along with an exception. It would be good to return information about
|
||||||
// wtxBumped to the caller even if marking the original transaction
|
// wtxBumped to the caller even if marking the original transaction
|
||||||
|
|
|
@ -404,7 +404,7 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control)
|
static CTransactionRef SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, const CCoinControl& coin_control, mapValue_t mapValue, std::string fromAccount)
|
||||||
{
|
{
|
||||||
CAmount curBalance = pwallet->GetBalance();
|
CAmount curBalance = pwallet->GetBalance();
|
||||||
|
|
||||||
|
@ -430,16 +430,18 @@ static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CA
|
||||||
int nChangePosRet = -1;
|
int nChangePosRet = -1;
|
||||||
CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
|
CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
|
||||||
vecSend.push_back(recipient);
|
vecSend.push_back(recipient);
|
||||||
if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError, coin_control)) {
|
CTransactionRef tx;
|
||||||
|
if (!pwallet->CreateTransaction(vecSend, tx, reservekey, nFeeRequired, nChangePosRet, strError, coin_control)) {
|
||||||
if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
|
if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
|
||||||
strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
|
strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
}
|
}
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) {
|
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, std::move(fromAccount), reservekey, g_connman.get(), state)) {
|
||||||
strError = strprintf("Error: The transaction was rejected! Reason given: %s", FormatStateMessage(state));
|
strError = strprintf("Error: The transaction was rejected! Reason given: %s", FormatStateMessage(state));
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
}
|
}
|
||||||
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue sendtoaddress(const JSONRPCRequest& request)
|
UniValue sendtoaddress(const JSONRPCRequest& request)
|
||||||
|
@ -498,11 +500,11 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
|
||||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
|
||||||
|
|
||||||
// Wallet comments
|
// Wallet comments
|
||||||
CWalletTx wtx;
|
mapValue_t mapValue;
|
||||||
if (!request.params[2].isNull() && !request.params[2].get_str().empty())
|
if (!request.params[2].isNull() && !request.params[2].get_str().empty())
|
||||||
wtx.mapValue["comment"] = request.params[2].get_str();
|
mapValue["comment"] = request.params[2].get_str();
|
||||||
if (!request.params[3].isNull() && !request.params[3].get_str().empty())
|
if (!request.params[3].isNull() && !request.params[3].get_str().empty())
|
||||||
wtx.mapValue["to"] = request.params[3].get_str();
|
mapValue["to"] = request.params[3].get_str();
|
||||||
|
|
||||||
bool fSubtractFeeFromAmount = false;
|
bool fSubtractFeeFromAmount = false;
|
||||||
if (!request.params[4].isNull()) {
|
if (!request.params[4].isNull()) {
|
||||||
|
@ -527,9 +529,8 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
|
||||||
|
|
||||||
EnsureWalletIsUnlocked(pwallet);
|
EnsureWalletIsUnlocked(pwallet);
|
||||||
|
|
||||||
SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, wtx, coin_control);
|
CTransactionRef tx = SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, coin_control, std::move(mapValue), {} /* fromAccount */);
|
||||||
|
return tx->GetHash().GetHex();
|
||||||
return wtx.GetHash().GetHex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue listaddressgroupings(const JSONRPCRequest& request)
|
UniValue listaddressgroupings(const JSONRPCRequest& request)
|
||||||
|
@ -995,12 +996,11 @@ UniValue sendfrom(const JSONRPCRequest& request)
|
||||||
if (!request.params[3].isNull())
|
if (!request.params[3].isNull())
|
||||||
nMinDepth = request.params[3].get_int();
|
nMinDepth = request.params[3].get_int();
|
||||||
|
|
||||||
CWalletTx wtx;
|
mapValue_t mapValue;
|
||||||
wtx.strFromAccount = strAccount;
|
|
||||||
if (!request.params[4].isNull() && !request.params[4].get_str().empty())
|
if (!request.params[4].isNull() && !request.params[4].get_str().empty())
|
||||||
wtx.mapValue["comment"] = request.params[4].get_str();
|
mapValue["comment"] = request.params[4].get_str();
|
||||||
if (!request.params[5].isNull() && !request.params[5].get_str().empty())
|
if (!request.params[5].isNull() && !request.params[5].get_str().empty())
|
||||||
wtx.mapValue["to"] = request.params[5].get_str();
|
mapValue["to"] = request.params[5].get_str();
|
||||||
|
|
||||||
EnsureWalletIsUnlocked(pwallet);
|
EnsureWalletIsUnlocked(pwallet);
|
||||||
|
|
||||||
|
@ -1010,9 +1010,8 @@ UniValue sendfrom(const JSONRPCRequest& request)
|
||||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
|
||||||
|
|
||||||
CCoinControl no_coin_control; // This is a deprecated API
|
CCoinControl no_coin_control; // This is a deprecated API
|
||||||
SendMoney(pwallet, dest, nAmount, false, wtx, no_coin_control);
|
CTransactionRef tx = SendMoney(pwallet, dest, nAmount, false, no_coin_control, std::move(mapValue), std::move(strAccount));
|
||||||
|
return tx->GetHash().GetHex();
|
||||||
return wtx.GetHash().GetHex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1083,10 +1082,9 @@ UniValue sendmany(const JSONRPCRequest& request)
|
||||||
if (!request.params[2].isNull())
|
if (!request.params[2].isNull())
|
||||||
nMinDepth = request.params[2].get_int();
|
nMinDepth = request.params[2].get_int();
|
||||||
|
|
||||||
CWalletTx wtx;
|
mapValue_t mapValue;
|
||||||
wtx.strFromAccount = strAccount;
|
|
||||||
if (!request.params[3].isNull() && !request.params[3].get_str().empty())
|
if (!request.params[3].isNull() && !request.params[3].get_str().empty())
|
||||||
wtx.mapValue["comment"] = request.params[3].get_str();
|
mapValue["comment"] = request.params[3].get_str();
|
||||||
|
|
||||||
UniValue subtractFeeFromAmount(UniValue::VARR);
|
UniValue subtractFeeFromAmount(UniValue::VARR);
|
||||||
if (!request.params[4].isNull())
|
if (!request.params[4].isNull())
|
||||||
|
@ -1152,16 +1150,17 @@ UniValue sendmany(const JSONRPCRequest& request)
|
||||||
CAmount nFeeRequired = 0;
|
CAmount nFeeRequired = 0;
|
||||||
int nChangePosRet = -1;
|
int nChangePosRet = -1;
|
||||||
std::string strFailReason;
|
std::string strFailReason;
|
||||||
bool fCreated = pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason, coin_control);
|
CTransactionRef tx;
|
||||||
|
bool fCreated = pwallet->CreateTransaction(vecSend, tx, keyChange, nFeeRequired, nChangePosRet, strFailReason, coin_control);
|
||||||
if (!fCreated)
|
if (!fCreated)
|
||||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) {
|
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, std::move(strAccount), keyChange, g_connman.get(), state)) {
|
||||||
strFailReason = strprintf("Transaction commit failed:: %s", FormatStateMessage(state));
|
strFailReason = strprintf("Transaction commit failed:: %s", FormatStateMessage(state));
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
|
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wtx.GetHash().GetHex();
|
return tx->GetHash().GetHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue addmultisigaddress(const JSONRPCRequest& request)
|
UniValue addmultisigaddress(const JSONRPCRequest& request)
|
||||||
|
|
|
@ -624,23 +624,23 @@ public:
|
||||||
|
|
||||||
CWalletTx& AddTx(CRecipient recipient)
|
CWalletTx& AddTx(CRecipient recipient)
|
||||||
{
|
{
|
||||||
CWalletTx wtx;
|
CTransactionRef tx;
|
||||||
CReserveKey reservekey(wallet.get());
|
CReserveKey reservekey(wallet.get());
|
||||||
CAmount fee;
|
CAmount fee;
|
||||||
int changePos = -1;
|
int changePos = -1;
|
||||||
std::string error;
|
std::string error;
|
||||||
CCoinControl dummy;
|
CCoinControl dummy;
|
||||||
BOOST_CHECK(wallet->CreateTransaction({recipient}, wtx, reservekey, fee, changePos, error, dummy));
|
BOOST_CHECK(wallet->CreateTransaction({recipient}, tx, reservekey, fee, changePos, error, dummy));
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
BOOST_CHECK(wallet->CommitTransaction(wtx, reservekey, nullptr, state));
|
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, {}, reservekey, nullptr, state));
|
||||||
CMutableTransaction blocktx;
|
CMutableTransaction blocktx;
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
blocktx = CMutableTransaction(*wallet->mapWallet.at(wtx.GetHash()).tx);
|
blocktx = CMutableTransaction(*wallet->mapWallet.at(tx->GetHash()).tx);
|
||||||
}
|
}
|
||||||
CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
auto it = wallet->mapWallet.find(wtx.GetHash());
|
auto it = wallet->mapWallet.find(tx->GetHash());
|
||||||
BOOST_CHECK(it != wallet->mapWallet.end());
|
BOOST_CHECK(it != wallet->mapWallet.end());
|
||||||
it->second.SetMerkleBranch(chainActive.Tip(), 1);
|
it->second.SetMerkleBranch(chainActive.Tip(), 1);
|
||||||
return it->second;
|
return it->second;
|
||||||
|
|
|
@ -2631,13 +2631,13 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
|
||||||
LOCK2(cs_main, cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
|
|
||||||
CReserveKey reservekey(this);
|
CReserveKey reservekey(this);
|
||||||
CWalletTx wtx;
|
CTransactionRef tx_new;
|
||||||
if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) {
|
if (!CreateTransaction(vecSend, tx_new, reservekey, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nChangePosInOut != -1) {
|
if (nChangePosInOut != -1) {
|
||||||
tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.tx->vout[nChangePosInOut]);
|
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
|
// 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.
|
// reusing change, so just remove the key from the keypool here.
|
||||||
reservekey.KeepKey();
|
reservekey.KeepKey();
|
||||||
|
@ -2646,11 +2646,11 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
|
||||||
// Copy output sizes from new transaction; they may have had the fee
|
// Copy output sizes from new transaction; they may have had the fee
|
||||||
// subtracted from them.
|
// subtracted from them.
|
||||||
for (unsigned int idx = 0; idx < tx.vout.size(); idx++) {
|
for (unsigned int idx = 0; idx < tx.vout.size(); idx++) {
|
||||||
tx.vout[idx].nValue = wtx.tx->vout[idx].nValue;
|
tx.vout[idx].nValue = tx_new->vout[idx].nValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new txins while keeping original txin scriptSig/order.
|
// Add new txins while keeping original txin scriptSig/order.
|
||||||
for (const CTxIn& txin : wtx.tx->vin) {
|
for (const CTxIn& txin : tx_new->vin) {
|
||||||
if (!coinControl.IsSelected(txin.prevout)) {
|
if (!coinControl.IsSelected(txin.prevout)) {
|
||||||
tx.vin.push_back(txin);
|
tx.vin.push_back(txin);
|
||||||
|
|
||||||
|
@ -2691,7 +2691,7 @@ OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vec
|
||||||
return g_address_type;
|
return g_address_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
|
bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CReserveKey& reservekey, CAmount& nFeeRet,
|
||||||
int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
|
int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
|
||||||
{
|
{
|
||||||
CAmount nValue = 0;
|
CAmount nValue = 0;
|
||||||
|
@ -2715,8 +2715,6 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wtxNew.fTimeReceivedIsTxTime = true;
|
|
||||||
wtxNew.BindWallet(this);
|
|
||||||
CMutableTransaction txNew;
|
CMutableTransaction txNew;
|
||||||
|
|
||||||
// Discourage fee sniping.
|
// Discourage fee sniping.
|
||||||
|
@ -2804,7 +2802,6 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
|
||||||
nChangePosInOut = nChangePosRequest;
|
nChangePosInOut = nChangePosRequest;
|
||||||
txNew.vin.clear();
|
txNew.vin.clear();
|
||||||
txNew.vout.clear();
|
txNew.vout.clear();
|
||||||
wtxNew.fFromMe = true;
|
|
||||||
bool fFirst = true;
|
bool fFirst = true;
|
||||||
|
|
||||||
CAmount nValueToSelect = nValue;
|
CAmount nValueToSelect = nValue;
|
||||||
|
@ -3019,11 +3016,11 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Embed the constructed transaction data in wtxNew.
|
// Return the constructed transaction data.
|
||||||
wtxNew.SetTx(MakeTransactionRef(std::move(txNew)));
|
tx = MakeTransactionRef(std::move(txNew));
|
||||||
|
|
||||||
// Limit size
|
// Limit size
|
||||||
if (GetTransactionWeight(*wtxNew.tx) >= MAX_STANDARD_TX_WEIGHT)
|
if (GetTransactionWeight(*tx) >= MAX_STANDARD_TX_WEIGHT)
|
||||||
{
|
{
|
||||||
strFailReason = _("Transaction too large");
|
strFailReason = _("Transaction too large");
|
||||||
return false;
|
return false;
|
||||||
|
@ -3033,7 +3030,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
|
||||||
if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
||||||
// Lastly, ensure this tx will pass the mempool's chain limits
|
// Lastly, ensure this tx will pass the mempool's chain limits
|
||||||
LockPoints lp;
|
LockPoints lp;
|
||||||
CTxMemPoolEntry entry(wtxNew.tx, 0, 0, 0, false, 0, lp);
|
CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp);
|
||||||
CTxMemPool::setEntries setAncestors;
|
CTxMemPool::setEntries setAncestors;
|
||||||
size_t nLimitAncestors = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
|
size_t nLimitAncestors = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
|
||||||
size_t nLimitAncestorSize = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
|
size_t nLimitAncestorSize = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
|
||||||
|
@ -3060,10 +3057,18 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
|
||||||
/**
|
/**
|
||||||
* Call after CreateTransaction unless you want to abort
|
* Call after CreateTransaction unless you want to abort
|
||||||
*/
|
*/
|
||||||
bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state)
|
bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, std::string fromAccount, CReserveKey& reservekey, CConnman* connman, CValidationState& state)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
|
|
||||||
|
CWalletTx wtxNew(this, std::move(tx));
|
||||||
|
wtxNew.mapValue = std::move(mapValue);
|
||||||
|
wtxNew.vOrderForm = std::move(orderForm);
|
||||||
|
wtxNew.strFromAccount = std::move(fromAccount);
|
||||||
|
wtxNew.fTimeReceivedIsTxTime = true;
|
||||||
|
wtxNew.fFromMe = true;
|
||||||
|
|
||||||
LogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString());
|
LogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString());
|
||||||
{
|
{
|
||||||
// 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
|
||||||
|
|
|
@ -974,9 +974,9 @@ public:
|
||||||
* selected by SelectCoins(); Also create the change output, when needed
|
* selected by SelectCoins(); Also create the change output, when needed
|
||||||
* @note passing nChangePosInOut as -1 will result in setting a random position
|
* @note passing nChangePosInOut as -1 will result in setting a random position
|
||||||
*/
|
*/
|
||||||
bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
|
bool CreateTransaction(const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
|
||||||
std::string& strFailReason, const CCoinControl& coin_control, bool sign = true);
|
std::string& strFailReason, const CCoinControl& coin_control, bool sign = true);
|
||||||
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state);
|
bool CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, std::string fromAccount, CReserveKey& reservekey, CConnman* connman, CValidationState& state);
|
||||||
|
|
||||||
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
|
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
|
||||||
bool AddAccountingEntry(const CAccountingEntry&);
|
bool AddAccountingEntry(const CAccountingEntry&);
|
||||||
|
|
Loading…
Reference in a new issue