Skip to content

Commit c1c38a2

Browse files
mruddysipa
authored andcommitted
segwit: fix gui wallet send transaction size calculation assertion failed
1 parent 059d4d1 commit c1c38a2

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

src/qt/coincontroldialog.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
485485
unsigned int nQuantity = 0;
486486
int nQuantityUncompressed = 0;
487487
bool fAllowFree = false;
488+
bool fWitness = false;
488489

489490
std::vector<COutPoint> vCoinControl;
490491
std::vector<COutput> vOutputs;
@@ -513,7 +514,14 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
513514

514515
// Bytes
515516
CTxDestination address;
516-
if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
517+
int witnessversion = 0;
518+
std::vector<unsigned char> witnessprogram;
519+
if (out.tx->vout[out.i].scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram))
520+
{
521+
nBytesInputs += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
522+
fWitness = true;
523+
}
524+
else if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
517525
{
518526
CPubKey pubkey;
519527
CKeyID *keyid = boost::get<CKeyID>(&address);
@@ -534,6 +542,14 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
534542
{
535543
// Bytes
536544
nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here
545+
if (fWitness)
546+
{
547+
// there is some fudging in these numbers related to the actual virtual transaction size calculation that will keep this estimate from being exact.
548+
// usually, the result will be an overestimate within a couple of satoshis so that the confirmation dialog ends up displaying a slightly smaller fee.
549+
// also, the witness stack size value value is a variable sized integer. usually, the number of stack items will be well under the single byte var int limit.
550+
nBytes += 2; // account for the serialized marker and flag bytes
551+
nBytes += nQuantity; // account for the witness byte that holds the number of stack items for each input.
552+
}
537553

538554
// Priority
539555
double mempoolEstimatePriority = mempool.estimateSmartPriority(nTxConfirmTarget);

src/qt/walletmodeltransaction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "walletmodeltransaction.h"
66

7+
#include "policy/policy.h"
78
#include "wallet/wallet.h"
89

910
WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &recipients) :
@@ -33,7 +34,7 @@ CWalletTx *WalletModelTransaction::getTransaction()
3334

3435
unsigned int WalletModelTransaction::getTransactionSize()
3536
{
36-
return (!walletTransaction ? 0 : (::GetSerializeSize(*(CTransaction*)walletTransaction, SER_NETWORK, PROTOCOL_VERSION)));
37+
return (!walletTransaction ? 0 : ::GetVirtualTransactionSize(*walletTransaction));
3738
}
3839

3940
CAmount WalletModelTransaction::getTransactionFee()

0 commit comments

Comments
 (0)