Skip to content

Commit

Permalink
Add TX virtual size call / Correct TX weight
Browse files Browse the repository at this point in the history
- The virtual size of a TX can be useful info to have, as it's what is used to calculate the fee when fee/byte is used. Allow users to get the virtual size.
- The current TX weight call is actually the TX virtual size. Correct the call to provide the actual weight.
  • Loading branch information
droark committed Feb 23, 2019
1 parent 7872386 commit 324bb27
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 9 deletions.
4 changes: 2 additions & 2 deletions armoryengine/Transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -3252,8 +3252,8 @@ def getFeeForTx(txHash):
for i in range(tx.getNumTxOut()):
valOut += tx.getTxOutCopy(i).getValue()
fee = valIn - valOut
txWeight = tx.getTxWeight()
fee_byte = fee / float(txWeight)
txVirtSize = tx.getTxVirtSize()
fee_byte = fee / float(txVirtSize)
return fee, fee_byte
except:
LOGERROR('Couldn\'t get tx fee. Ignore this message in Fullnode')
Expand Down
19 changes: 18 additions & 1 deletion cppForSwig/CoinSelection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1035,8 +1035,10 @@ void UtxoSelection::computeSizeAndFee(
throw CoinSelectionException("targetVal > value");

size_ = 10 + txOutSize + txInSize;
if (sw)
if (sw) {
size_ += 2 + witnessSize_ + utxoVec_.size();
}
computeVirtSize(sw);

targetVal = payStruct.spendVal_ + fee_;
changeVal = value_ - targetVal;
Expand Down Expand Up @@ -1072,6 +1074,21 @@ void UtxoSelection::computeSizeAndFee(
}
}

////////////////////////////////////////////////////////////////////////////////
// Function that calculates the selection's virtual size (the size actually used
// to calculate fees).
void UtxoSelection::computeVirtSize(const bool& segwit)
{
size_t numerator{0};
if(segwit) {
numerator = 3*(size_ - witnessSize_) + size_;
}
else {
numerator = 4*size_;
}
virtSize_ = std::ceil(static_cast<float>(numerator) / 4.0f);
}

////////////////////////////////////////////////////////////////////////////////
void UtxoSelection::shuffle()
{
Expand Down
6 changes: 6 additions & 0 deletions cppForSwig/CoinSelection.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ struct PaymentStruct
////////////////////////////////////////////////////////////////////////////////
struct UtxoSelection
{
public:
std::vector<UTXO> utxoVec_;

uint64_t value_ = 0;
Expand All @@ -145,6 +146,7 @@ struct UtxoSelection

size_t size_ = 0;
size_t witnessSize_ = 0;
size_t virtSize_ = 0;
float bumpPct_ = 0.0f;

bool hasChange_ = false;
Expand All @@ -158,6 +160,10 @@ struct UtxoSelection

void computeSizeAndFee(const PaymentStruct&);
void shuffle(void);

private:
void computeVirtSize(const bool& segwit);

};


Expand Down
26 changes: 24 additions & 2 deletions cppForSwig/TxClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,11 @@ bool Tx::isRBF() const
}

/////////////////////////////////////////////////////////////////////////////
size_t Tx::getTxWeight() const
// Get the virtual size of the TX. Used in Bitcoin to determine minimum fees.
size_t Tx::getTxVirtSize() const
{
auto size = getSize();

if (offsetsWitness_.size() > 1)
{
auto witnessSize = *offsetsWitness_.rbegin() - *offsetsWitness_.begin();
Expand All @@ -480,6 +481,27 @@ size_t Tx::getTxWeight() const
return size;
}

// Get the weight of the Tx.
size_t Tx::getTxWeight(void) const
{
return (getTxBaseSize() * 3) + getSize();
}

// Get the base size of the TX. Used for weight & virt size calculations.
size_t Tx::getTxBaseSize() const
{
auto size = getSize();

if (offsetsWitness_.size() > 1)
{
auto witnessSize = *offsetsWitness_.rbegin() - *offsetsWitness_.begin();

size -= witnessSize;
}

return size;
}

/////////////////////////////////////////////////////////////////////////////
void Tx::pprint(ostream & os, int nIndent, bool pBigendian)
{
Expand Down
5 changes: 4 additions & 1 deletion cppForSwig/TxClasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,8 @@ class Tx
void setTxTime(uint32_t txtime) { txTime_ = txtime; }
uint32_t getTxTime(void) const { return txTime_; }

//returns tx weight in bytes
// Get TX virtual size, which is what is used when calculating fee/byte.
size_t getTxVirtSize(void) const;
size_t getTxWeight(void) const;

private:
Expand All @@ -351,6 +352,8 @@ class Tx

bool isRBF_ = false;
bool isChainedZc_ = false;

size_t getTxBaseSize() const;
};

////////////////////////////////////////////////////////////////////////////////
Expand Down
6 changes: 3 additions & 3 deletions qtdialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5136,7 +5136,7 @@ def extractTxInfo(pytx, rcvTime=None):
pytx = ustx.pytxObj.copy()

txHash = pytx.getHash()
txSize, txWeight, sumTxIn, txTime, txBlk, txIdx = [None] * 6
txSize, txVirtSize, sumTxIn, txTime, txBlk, txIdx = [None] * 6

txOutToList = pytx.makeRecipientsList()
sumTxOut = sum([t[1] for t in txOutToList])
Expand All @@ -5146,7 +5146,7 @@ def extractTxInfo(pytx, rcvTime=None):
txcpp = TheBDM.bdv().getTxByHash(txHash)
if txcpp.isInitialized():
hgt = txcpp.getBlockHeight()
txWeight = txcpp.getTxWeight()
txVirtSize = txcpp.getTxVirtSize()
if hgt <= TheBDM.getTopBlockHeight():
headref = TheBDM.bdv().blockchain().getHeaderByHeight(hgt)
txTime = unixTimeToFormatStr(headref.getTimestamp())
Expand Down Expand Up @@ -5234,7 +5234,7 @@ def extractTxInfo(pytx, rcvTime=None):
sumTxIn = None

return [txHash, txOutToList, sumTxOut, txinFromList, sumTxIn, \
txTime, txBlk, txIdx, txSize, txWeight]
txTime, txBlk, txIdx, txSize, txVirtSize]

################################################################################
class DlgDispTxInfo(ArmoryDialog):
Expand Down

0 comments on commit 324bb27

Please sign in to comment.