Skip to content

Commit e86c054

Browse files
committed
adjust sig hash type
1 parent ca74734 commit e86c054

2 files changed

Lines changed: 55 additions & 72 deletions

File tree

x/lending/keeper/dlc.go

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ func (k Keeper) UpdateDLCMeta(ctx sdk.Context, loanId string, depositTxs []*psbt
4141
dlcMeta := k.GetDLCMeta(ctx, loanId)
4242

4343
vaultPkScript, _ := types.GetPkScriptFromAddress(loanId)
44-
dcmPkScript, _ := types.GetPkScriptFromPubKey(loan.DCM)
4544

4645
vaultUtxos, err := types.GetVaultUtxos(depositTxs, vaultPkScript)
4746
if err != nil {
@@ -74,17 +73,6 @@ func (k Keeper) UpdateDLCMeta(ctx sdk.Context, loanId string, depositTxs []*psbt
7473
}
7574
}
7675

77-
// get fee rate
78-
feeRate := k.btcbridgeKeeper.GetFeeRate(ctx)
79-
if err := k.btcbridgeKeeper.CheckFeeRate(ctx, feeRate); err != nil {
80-
return err
81-
}
82-
83-
// add DCM output to liquidation cet
84-
if err := types.AddDCMOutputToLiquidationCet(liquidationCetPsbt, liquidationScript, liquidationScriptControlBlock, dcmPkScript, feeRate.Value); err != nil {
85-
return err
86-
}
87-
8876
for i := range repaymentCetPsbt.Inputs {
8977
repaymentCetPsbt.Inputs[i].TaprootInternalKey = internalKey
9078
repaymentCetPsbt.Inputs[i].TaprootLeafScript = []*psbt.TaprootTapLeafScript{
@@ -111,6 +99,12 @@ func (k Keeper) UpdateDLCMeta(ctx sdk.Context, loanId string, depositTxs []*psbt
11199
return err
112100
}
113101

102+
// get fee rate
103+
feeRate := k.btcbridgeKeeper.GetFeeRate(ctx)
104+
if err := k.btcbridgeKeeper.CheckFeeRate(ctx, feeRate); err != nil {
105+
feeRate.Value = types.DefaultFeeRate
106+
}
107+
114108
// timeout refund transaction can be generated offchain as needed
115109
timeoutRefundTx, err := types.CreateTimeoutRefundTransaction(depositTxs, vaultPkScript, borrowerPkScript, internalKey, dlcMeta.TimeoutRefundScript, feeRate.Value)
116110
if err != nil {
@@ -184,8 +178,8 @@ func (k Keeper) GetCetInfos(ctx sdk.Context, loanId string, collateralAmount sdk
184178
k.UpdateDLCEventLiquidatedOutcome(ctx, loan, dlcEvent, liquidationPrice)
185179
}
186180

187-
liquidationCetInfo, _ := types.GetCetInfo(dlcEvent, types.LiquidatedOutcomeIndex, liquidationScript, liquidationScriptControlBlock, types.BorrowerLiquidationCetSigHashType)
188-
defaultLiquidationCetInfo, _ := types.GetCetInfo(dlcEvent, types.DefaultLiquidatedOutcomeIndex, liquidationScript, liquidationScriptControlBlock, types.BorrowerLiquidationCetSigHashType)
181+
liquidationCetInfo, _ := types.GetCetInfo(dlcEvent, types.LiquidatedOutcomeIndex, liquidationScript, liquidationScriptControlBlock, types.DefaultSigHashType)
182+
defaultLiquidationCetInfo, _ := types.GetCetInfo(dlcEvent, types.DefaultLiquidatedOutcomeIndex, liquidationScript, liquidationScriptControlBlock, types.DefaultSigHashType)
189183
repaymentCetInfo, _ := types.GetCetInfo(dlcEvent, types.RepaidOutcomeIndex, repaymentScript, repaymentScriptControlBlock, types.DefaultSigHashType)
190184

191185
return []*types.CetInfo{

x/lending/types/dlc.go

Lines changed: 47 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2322
const (
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

3430
const (
@@ -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
456476
func 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
514506
func 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.
687680
func 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

Comments
 (0)