@@ -10,7 +10,6 @@ import (
1010 "github.com/btcsuite/btcd/btcutil/psbt"
1111 "github.com/btcsuite/btcd/chaincfg/chainhash"
1212 "github.com/btcsuite/btcd/txscript"
13- "github.com/btcsuite/btcd/wire"
1413
1514 errorsmod "cosmossdk.io/errors"
1615
@@ -21,14 +20,11 @@ import (
2120)
2221
2322const (
24- // liquidation cet sig hash type for borrower
25- BorrowerLiquidationCetSigHashType = txscript .SigHashNone | txscript . SigHashAnyOneCanPay
23+ // default sig hash type
24+ DefaultSigHashType = txscript .SigHashDefault
2625
27- // liquidation cet sig hash type for DCM
28- DCMLiquidationCetSigHashType = txscript .SigHashDefault
29-
30- // default sig hash type used for repayment or redemption
31- DefaultSigHashType = txscript .SigHashDefault | txscript .SigHashAnyOneCanPay
26+ // default fee rate
27+ DefaultFeeRate = 1
3228)
3329
3430const (
@@ -90,33 +86,61 @@ func VerifyCets(dlcMeta *DLCMeta, depositTxs []*psbt.Packet, vaultPkScript []byt
9086 return err
9187 }
9288
93- if err := VerifyLiquidationCet (dlcMeta , depositTxs , vaultPkScript , borrowerAuthPubKey , liquidationCet , liquidationAdaptorSignatures , liquidationAdaptorPoint ); err != nil {
89+ if err := VerifyLiquidationCet (dlcMeta , depositTxs , vaultPkScript , borrowerAuthPubKey , dcmPubKey , liquidationCet , liquidationAdaptorSignatures , liquidationAdaptorPoint ); err != nil {
9490 return errorsmod .Wrapf (ErrInvalidCET , "invalid liquidation cet: %v" , err )
9591 }
9692
97- if err := VerifyLiquidationCet (dlcMeta , depositTxs , vaultPkScript , borrowerAuthPubKey , liquidationCet , defaultLiquidationAdaptorSignatures , defaultLiquidationAdaptorPoint ); err != nil {
93+ if err := VerifyLiquidationCet (dlcMeta , depositTxs , vaultPkScript , borrowerAuthPubKey , dcmPubKey , liquidationCet , defaultLiquidationAdaptorSignatures , defaultLiquidationAdaptorPoint ); err != nil {
9894 return errorsmod .Wrapf (ErrInvalidCET , "invalid default liquidation cet: %v" , err )
9995 }
10096
101- if err := VerifyRepaymentCet (dlcMeta , depositTxs , vaultPkScript , borrowerPubKey , repaymentCet , repaymentSignatures ); err != nil {
97+ if err := VerifyRepaymentCet (dlcMeta , depositTxs , vaultPkScript , borrowerPubKey , dcmPubKey , repaymentCet , repaymentSignatures ); err != nil {
10298 return errorsmod .Wrapf (ErrInvalidCET , "invalid repayment cet: %v" , err )
10399 }
104100
105101 return nil
106102}
107103
108104// VerifyLiquidationCet verifies the given liquidation cet and corresponding adaptor signatures
109- func VerifyLiquidationCet (dlcMeta * DLCMeta , depositTxs []* psbt.Packet , vaultPkScript []byte , borrowerAuthPubKey string , liquidationCET string , adaptorSignatures []string , adaptorPoint []byte ) error {
105+ func VerifyLiquidationCet (dlcMeta * DLCMeta , depositTxs []* psbt.Packet , vaultPkScript []byte , borrowerAuthPubKey string , dcmPubKey string , liquidationCET string , adaptorSignatures []string , adaptorPoint []byte ) error {
110106 p , err := psbt .NewFromRawBytes (bytes .NewReader ([]byte (liquidationCET )), true )
111107 if err != nil {
112108 return errorsmod .Wrap (ErrInvalidCET , "failed to deserialize cet" )
113109 }
114110
115- // no output is allowed; output will be populated later
116- if len (p .UnsignedTx .TxOut ) != 0 {
111+ dcmPkScript , err := GetPkScriptFromPubKey (dcmPubKey )
112+ if err != nil {
113+ return err
114+ }
115+
116+ if len (p .UnsignedTx .TxOut ) != 1 || ! bytes .Equal (p .UnsignedTx .TxOut [0 ].PkScript , dcmPkScript ) {
117117 return errorsmod .Wrap (ErrInvalidCET , "incorrect tx out" )
118118 }
119119
120+ if btcbridgetypes .IsDustOut (p .UnsignedTx .TxOut [0 ]) {
121+ return errorsmod .Wrap (ErrInvalidCET , "dust tx out" )
122+ }
123+
124+ script , controlBlock , err := UnwrapLeafScript (dlcMeta .LiquidationScript )
125+ if err != nil {
126+ return err
127+ }
128+
129+ witnessSize := getCetWitnessSize (CetType_LIQUIDATION , script , controlBlock )
130+
131+ fee , err := p .GetTxFee ()
132+ if err != nil {
133+ return errorsmod .Wrapf (ErrInvalidCET , "failed to get tx fee: %v" , err )
134+ }
135+
136+ if int64 (fee ) < GetTxVirtualSize (p .UnsignedTx , witnessSize ) {
137+ return errorsmod .Wrap (ErrInvalidCET , "too low fee rate" )
138+ }
139+
140+ if err := CheckTransactionWeight (p .UnsignedTx , witnessSize ); err != nil {
141+ return err
142+ }
143+
120144 vaultUtxos , err := GetVaultUtxos (depositTxs , vaultPkScript )
121145 if err != nil {
122146 return err
@@ -157,13 +181,8 @@ func VerifyLiquidationCet(dlcMeta *DLCMeta, depositTxs []*psbt.Packet, vaultPkSc
157181 return errorsmod .Wrap (ErrInvalidPubKey , "failed to decode borrower auth public key" )
158182 }
159183
160- script , _ , err := UnwrapLeafScript (dlcMeta .LiquidationScript )
161- if err != nil {
162- return err
163- }
164-
165184 for i , signature := range adaptorSignatures {
166- sigHash , err := CalcTapscriptSigHash (p , i , BorrowerLiquidationCetSigHashType , script )
185+ sigHash , err := CalcTapscriptSigHash (p , i , DefaultSigHashType , script )
167186 if err != nil {
168187 return errorsmod .Wrapf (err , "failed to calculate sig hash" )
169188 }
@@ -182,7 +201,7 @@ func VerifyLiquidationCet(dlcMeta *DLCMeta, depositTxs []*psbt.Packet, vaultPkSc
182201}
183202
184203// VerifyRepaymentCet verifies the given repayment cet and corresponding signatures
185- func VerifyRepaymentCet (dlcMeta * DLCMeta , depositTxs []* psbt.Packet , vaultPkScript []byte , borrowerPubKey string , repaymentCet string , signatures []string ) error {
204+ func VerifyRepaymentCet (dlcMeta * DLCMeta , depositTxs []* psbt.Packet , vaultPkScript []byte , borrowerPubKey string , dcmPubKey string , repaymentCet string , signatures []string ) error {
186205 p , err := psbt .NewFromRawBytes (bytes .NewReader ([]byte (repaymentCet )), true )
187206 if err != nil {
188207 return errorsmod .Wrap (ErrInvalidCET , "failed to deserialize cet" )
@@ -365,7 +384,7 @@ func CreateTimeoutRefundTransaction(depositTxs []*psbt.Packet, vaultPkScript []b
365384 }
366385
367386 for i := range p .Inputs {
368- p .Inputs [i ].SighashType = txscript . SigHashDefault
387+ p .Inputs [i ].SighashType = DefaultSigHashType
369388 p .Inputs [i ].TaprootInternalKey = internalKeyBytes
370389 p .Inputs [i ].TaprootLeafScript = []* psbt.TaprootTapLeafScript {
371390 {
@@ -453,11 +472,9 @@ func BuildSignedCet(cet string, borrowerPubKey string, borrowerSignatures []stri
453472}
454473
455474// GetCetSigHashTypes gets the cet sig hash types for borrower and DCM by the given cet type
475+ // NOTE: The sig hash type for all cets is SigHashDefault currently
456476func GetCetSigHashTypes (cetType CetType ) (txscript.SigHashType , txscript.SigHashType ) {
457477 switch cetType {
458- case CetType_LIQUIDATION , CetType_DEFAULT_LIQUIDATION :
459- return BorrowerLiquidationCetSigHashType , DCMLiquidationCetSigHashType
460-
461478 default :
462479 return DefaultSigHashType , DefaultSigHashType
463480 }
@@ -485,31 +502,6 @@ func UpdateLiquidationCet(dlcMeta *DLCMeta, cetType CetType, cet LiquidationCet)
485502 }
486503}
487504
488- // UpdateLiquidationCetOutput adds the DCM output to the given cet
489- func AddDCMOutputToLiquidationCet (cet * psbt.Packet , script []byte , controlBlock []byte , dcmPkScript []byte , feeRate int64 ) error {
490- // get total input amount
491- inputAmount := int64 (0 )
492- for _ , input := range cet .Inputs {
493- inputAmount += input .WitnessUtxo .Value
494- }
495-
496- // add dcm output
497- cet .UnsignedTx .TxOut [0 ] = wire .NewTxOut (0 , dcmPkScript )
498-
499- // calculate tx fee
500- witnessSize := getCetWitnessSize (CetType_LIQUIDATION , script , controlBlock )
501- fee := GetTxVirtualSize (cet .UnsignedTx , witnessSize ) * feeRate
502-
503- // update output value
504- cet .UnsignedTx .TxOut [0 ].Value = inputAmount - fee
505-
506- if btcbridgetypes .IsDustOut (cet .UnsignedTx .TxOut [0 ]) {
507- return ErrDustOutput
508- }
509-
510- return CheckTransactionWeight (cet .UnsignedTx , witnessSize )
511- }
512-
513505// GetCetInfo gets the cet info from the given event and script
514506func GetCetInfo (event * dlctypes.DLCEvent , outcomeIndex int , script []byte , controlBlock []byte , sigHashType txscript.SigHashType ) (* CetInfo , error ) {
515507 if event == nil {
@@ -545,7 +537,7 @@ func GetLiquidationCetSigHashes(dlcMeta *DLCMeta) ([]string, error) {
545537 sigHashes := []string {}
546538
547539 for i := range p .Inputs {
548- sigHash , err := CalcTapscriptSigHash (p , i , DCMLiquidationCetSigHashType , script )
540+ sigHash , err := CalcTapscriptSigHash (p , i , DefaultSigHashType , script )
549541 if err != nil {
550542 return nil , err
551543 }
@@ -571,7 +563,7 @@ func GetDefaultLiquidationCetSigHashes(dlcMeta *DLCMeta) ([]string, error) {
571563 sigHashes := []string {}
572564
573565 for i := range p .Inputs {
574- sigHash , err := CalcTapscriptSigHash (p , i , DCMLiquidationCetSigHashType , script )
566+ sigHash , err := CalcTapscriptSigHash (p , i , DefaultSigHashType , script )
575567 if err != nil {
576568 return nil , err
577569 }
@@ -684,14 +676,11 @@ func getVaultUtxosFromDepositTx(depositTx *psbt.Packet, vaultPkScript []byte) ([
684676}
685677
686678// getCetWitnessSize gets the cet witness size according to the given params
679+ // NOTE: The final signature is 64 bytes due to that the sig hash type is SigHashDefault currently.
687680func getCetWitnessSize (cetType CetType , script []byte , controlBlock []byte ) int {
688681 switch cetType {
689- case CetType_LIQUIDATION , CetType_DEFAULT_LIQUIDATION :
690- // dcm signature(64) + borrower signature(65) + len(script) + len(control block)
691- return 64 + 65 + len (script ) + len (controlBlock )
692-
693682 default :
694- // dcm signature(65 ) + borrower signature(65 ) + len(script) + len(control block)
695- return 65 + 65 + len (script ) + len (controlBlock )
683+ // dcm signature(64 ) + borrower signature(64 ) + len(script) + len(control block)
684+ return 64 + 64 + len (script ) + len (controlBlock )
696685 }
697686}
0 commit comments