mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-10-14 00:59:33 +00:00
[NOD-362] Calculate txgen fees by mass instead of size (#431)
* [NOD-362] Calculate txgen fee by mass * formating * [NOD-362] add varint size to calculation * [NOD-362] rename variables * [NOD-362] formating
This commit is contained in:
parent
3ac9fa83c1
commit
3018c18616
@ -302,7 +302,7 @@ func createTx(walletUTXOSet utxoSet, minAmount uint64, feeRate uint64, targetNum
|
|||||||
numOuts = maxNumOuts
|
numOuts = maxNumOuts
|
||||||
}
|
}
|
||||||
|
|
||||||
fee := calcFee(tx, feeRate, numOuts)
|
fee := calcFee(tx, feeRate, numOuts, walletUTXOSet)
|
||||||
funds -= fee
|
funds -= fee
|
||||||
|
|
||||||
for i := uint64(0); i < numOuts; i++ {
|
for i := uint64(0); i < numOuts; i++ {
|
||||||
@ -350,15 +350,15 @@ func fundTx(walletUTXOSet utxoSet, tx *wire.MsgTx, amount uint64, feeRate uint64
|
|||||||
// Add the selected output to the transaction
|
// Add the selected output to the transaction
|
||||||
tx.AddTxIn(wire.NewTxIn(&outpoint, nil))
|
tx.AddTxIn(wire.NewTxIn(&outpoint, nil))
|
||||||
|
|
||||||
// Check if transaction has enought funds. If we don't have enough
|
// Check if transaction has enough funds. If we don't have enough
|
||||||
// coins from he current amount selected to pay the fee, or we have
|
// coins from he current amount selected to pay the fee, or we have
|
||||||
// less inputs then the targeted amount, continue to grab more coins.
|
// less inputs then the targeted amount, continue to grab more coins.
|
||||||
if uint64(len(tx.TxIn)) >= targetNumberOfInputs && isFunded(tx, feeRate, targetNumberOfOutputs, amountSelected, amount) {
|
if uint64(len(tx.TxIn)) >= targetNumberOfInputs && isFunded(tx, feeRate, targetNumberOfOutputs, amountSelected, amount, walletUTXOSet) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isFunded(tx, feeRate, targetNumberOfOutputs, amountSelected, amount) {
|
if !isFunded(tx, feeRate, targetNumberOfOutputs, amountSelected, amount, walletUTXOSet) {
|
||||||
return 0, fmt.Errorf("not enough funds for coin selection")
|
return 0, fmt.Errorf("not enough funds for coin selection")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,20 +367,40 @@ func fundTx(walletUTXOSet utxoSet, tx *wire.MsgTx, amount uint64, feeRate uint64
|
|||||||
|
|
||||||
// Check if the transaction has enough funds to cover the fee
|
// Check if the transaction has enough funds to cover the fee
|
||||||
// required for the txn.
|
// required for the txn.
|
||||||
func isFunded(tx *wire.MsgTx, feeRate uint64, targetNumberOfOutputs uint64, amountSelected uint64, targetAmount uint64) bool {
|
func isFunded(tx *wire.MsgTx, feeRate uint64, targetNumberOfOutputs uint64, amountSelected uint64, targetAmount uint64, walletUTXOSet utxoSet) bool {
|
||||||
reqFee := calcFee(tx, feeRate, targetNumberOfOutputs)
|
reqFee := calcFee(tx, feeRate, targetNumberOfOutputs, walletUTXOSet)
|
||||||
return amountSelected > reqFee && amountSelected-reqFee >= targetAmount
|
return amountSelected > reqFee && amountSelected-reqFee >= targetAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
func calcFee(tx *wire.MsgTx, feeRate uint64, numberOfOutputs uint64) uint64 {
|
func calcFee(msgTx *wire.MsgTx, feeRate uint64, numberOfOutputs uint64, walletUTXOSet utxoSet) uint64 {
|
||||||
txSize := uint64(tx.SerializeSize()) + spendSize*uint64(len(tx.TxIn)) + numberOfOutputs*outputSize + 1
|
txMass := calcTxMass(msgTx, walletUTXOSet)
|
||||||
reqFee := uint64(txSize) * feeRate
|
txMassWithOutputs := txMass + outputsTotalSize(numberOfOutputs)
|
||||||
|
reqFee := txMassWithOutputs * feeRate
|
||||||
if reqFee < minTxFee {
|
if reqFee < minTxFee {
|
||||||
return minTxFee
|
return minTxFee
|
||||||
}
|
}
|
||||||
return reqFee
|
return reqFee
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func outputsTotalSize(numberOfOutputs uint64) uint64 {
|
||||||
|
return numberOfOutputs*outputSize + uint64(wire.VarIntSerializeSize(numberOfOutputs))
|
||||||
|
}
|
||||||
|
|
||||||
|
func calcTxMass(msgTx *wire.MsgTx, walletUTXOSet utxoSet) uint64 {
|
||||||
|
previousScriptPubKeys := getPreviousScriptPubKeys(msgTx, walletUTXOSet)
|
||||||
|
return blockdag.CalcTxMass(util.NewTx(msgTx), previousScriptPubKeys)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPreviousScriptPubKeys(msgTx *wire.MsgTx, walletUTXOSet utxoSet) [][]byte {
|
||||||
|
previousScriptPubKeys := make([][]byte, len(msgTx.TxIn))
|
||||||
|
for i, txIn := range msgTx.TxIn {
|
||||||
|
outpoint := txIn.PreviousOutpoint
|
||||||
|
prevOut := walletUTXOSet[outpoint]
|
||||||
|
previousScriptPubKeys[i] = prevOut.ScriptPubKey
|
||||||
|
}
|
||||||
|
return previousScriptPubKeys
|
||||||
|
}
|
||||||
|
|
||||||
func applyConfirmedTransactionsAndResendNonAccepted(client *txgenClient, walletTxs map[daghash.TxID]*walletTransaction, walletUTXOSet utxoSet,
|
func applyConfirmedTransactionsAndResendNonAccepted(client *txgenClient, walletTxs map[daghash.TxID]*walletTransaction, walletUTXOSet utxoSet,
|
||||||
blockChainHeight uint64, txChan chan *wire.MsgTx) error {
|
blockChainHeight uint64, txChan chan *wire.MsgTx) error {
|
||||||
for txID, walletTx := range walletTxs {
|
for txID, walletTx := range walletTxs {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user