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+ }
0 commit comments