Skip to content

Commit e931b3c

Browse files
committed
optimize settlement tx
1 parent 6a4f00c commit e931b3c

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

x/liquidation/types/bitcoin.go

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/base64"
66
"errors"
77

8+
"github.com/btcsuite/btcd/blockchain"
89
"github.com/btcsuite/btcd/btcutil"
910
"github.com/btcsuite/btcd/btcutil/psbt"
1011
"github.com/btcsuite/btcd/chaincfg/chainhash"
@@ -27,6 +28,12 @@ const (
2728

2829
// default sig hash type
2930
DefaultSigHashType = txscript.SigHashDefault
31+
32+
// default maximum allowed transaction weight
33+
MaxTransactionWeight = 400000
34+
35+
// default witness size
36+
DefaultWitnessSize = 64
3037
)
3138

3239
// BuildSettlementTransaction builds the settlement tx for the given liquidation and records
@@ -168,7 +175,7 @@ func BuildUnsignedTransaction(utxos []*btcbridgetypes.UTXO, txOuts []*wire.TxOut
168175

169176
tx.AddTxOut(wire.NewTxOut(0, changePkScript))
170177

171-
fee := btcbridgetypes.GetTxVirtualSize(tx, utxos) * feeRate
178+
fee := GetTxVirtualSize(tx, DefaultWitnessSize) * feeRate
172179

173180
changeAmount := inAmount - outAmount - fee
174181
if changeAmount > 0 {
@@ -181,7 +188,7 @@ func BuildUnsignedTransaction(utxos []*btcbridgetypes.UTXO, txOuts []*wire.TxOut
181188
tx.TxOut = tx.TxOut[0 : len(tx.TxOut)-1]
182189

183190
if changeAmount < 0 {
184-
feeWithoutChange := btcbridgetypes.GetTxVirtualSize(tx, utxos) * feeRate
191+
feeWithoutChange := GetTxVirtualSize(tx, DefaultWitnessSize) * feeRate
185192
if inAmount-outAmount-feeWithoutChange < 0 {
186193
return nil, 0, ErrInsufficientUTXOs
187194
}
@@ -190,7 +197,7 @@ func BuildUnsignedTransaction(utxos []*btcbridgetypes.UTXO, txOuts []*wire.TxOut
190197
changeAmount = 0
191198
}
192199

193-
if err := btcbridgetypes.CheckTransactionWeight(tx, utxos); err != nil {
200+
if err := CheckTransactionWeight(tx, DefaultWitnessSize); err != nil {
194201
return nil, 0, err
195202
}
196203

@@ -233,11 +240,11 @@ func BuildUnsignedTransactionWithFee(utxos []*btcbridgetypes.UTXO, txOuts []*wir
233240
changeAmount = 0
234241
}
235242

236-
if fee < btcbridgetypes.GetTxVirtualSize(tx, utxos) {
243+
if fee < GetTxVirtualSize(tx, DefaultWitnessSize) {
237244
return nil, 0, errorsmod.Wrap(ErrFailedToBuildTx, "too low fee rate")
238245
}
239246

240-
if err := btcbridgetypes.CheckTransactionWeight(tx, utxos); err != nil {
247+
if err := CheckTransactionWeight(tx, DefaultWitnessSize); err != nil {
241248
return nil, 0, err
242249
}
243250

@@ -292,3 +299,36 @@ func CalcTaprootSigHash(p *psbt.Packet, idx int, sigHashType txscript.SigHashTyp
292299

293300
return sigHash, nil
294301
}
302+
303+
// GetTxVirtualSize gets the virtual size of the given tx.
304+
func GetTxVirtualSize(tx *wire.MsgTx, witnessSize int) int64 {
305+
newTx := PopulateTxWithDummyWitness(tx, witnessSize)
306+
307+
return mempool.GetTxVirtualSize(btcutil.NewTx(newTx))
308+
}
309+
310+
// CheckTransactionWeight checks if the weight of the given tx exceeds the allowed maximum weight
311+
func CheckTransactionWeight(tx *wire.MsgTx, witnessSize int) error {
312+
newTx := PopulateTxWithDummyWitness(tx, witnessSize)
313+
314+
weight := blockchain.GetTransactionWeight(btcutil.NewTx(newTx))
315+
if weight > MaxTransactionWeight {
316+
return ErrMaxTransactionWeightExceeded
317+
}
318+
319+
return nil
320+
}
321+
322+
// PopulateTxWithDummyWitness populates the given tx with the dummy witness
323+
func PopulateTxWithDummyWitness(tx *wire.MsgTx, witnessSize int) *wire.MsgTx {
324+
newTx := tx.Copy()
325+
326+
for _, txIn := range newTx.TxIn {
327+
if len(txIn.Witness) == 0 {
328+
dummyWitness := make([]byte, witnessSize)
329+
txIn.Witness = wire.TxWitness{dummyWitness}
330+
}
331+
}
332+
333+
return newTx
334+
}

x/liquidation/types/errors.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var (
1515

1616
ErrInvalidParams = errorsmod.Register(ModuleName, 2100, "invalid params")
1717

18-
ErrInsufficientUTXOs = errorsmod.Register(ModuleName, 3100, "insufficient utxos")
19-
ErrFailedToBuildTx = errorsmod.Register(ModuleName, 3101, "failed to build transaction")
18+
ErrInsufficientUTXOs = errorsmod.Register(ModuleName, 3100, "insufficient utxos")
19+
ErrMaxTransactionWeightExceeded = errorsmod.Register(ModuleName, 3101, "maximum transaction weight exceeded")
20+
ErrFailedToBuildTx = errorsmod.Register(ModuleName, 3102, "failed to build transaction")
2021
)

0 commit comments

Comments
 (0)