Skip to content

Commit 7660f38

Browse files
committed
optimize dlc meta logic
1 parent 7040b68 commit 7660f38

File tree

5 files changed

+219
-181
lines changed

5 files changed

+219
-181
lines changed

x/lending/keeper/dlc.go

Lines changed: 123 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package keeper
22

33
import (
4+
"bytes"
45
"encoding/hex"
56

7+
"github.com/btcsuite/btcd/btcec/v2/schnorr"
8+
"github.com/btcsuite/btcd/btcutil/psbt"
9+
"github.com/btcsuite/btcd/txscript"
10+
611
errorsmod "cosmossdk.io/errors"
712
sdk "github.com/cosmos/cosmos-sdk/types"
813

@@ -30,26 +35,135 @@ func (k Keeper) GetDLCMeta(ctx sdk.Context, loanId string) *types.DLCMeta {
3035
return &dlcMeta
3136
}
3237

38+
// UpdateDLCMeta updates the dlc meta of the given loan with the given params
39+
func (k Keeper) UpdateDLCMeta(ctx sdk.Context, loanId string, depositTxs []*psbt.Packet, liquidationCet string, liquidationAdaptorSignatures []string, defaultLiquidationAdaptorSignatures []string, repaymentCet string, repaymentSignatures []string) error {
40+
loan := k.GetLoan(ctx, loanId)
41+
dlcMeta := k.GetDLCMeta(ctx, loanId)
42+
43+
vaultPkScript, _ := types.GetPkScriptFromAddress(loanId)
44+
45+
vaultUtxos, err := types.GetVaultUtxos(depositTxs, vaultPkScript)
46+
if err != nil {
47+
return err
48+
}
49+
50+
liquidationCetPsbt, err := psbt.NewFromRawBytes(bytes.NewReader([]byte(liquidationCet)), true)
51+
if err != nil {
52+
return err
53+
}
54+
55+
repaymentCetPsbt, err := psbt.NewFromRawBytes(bytes.NewReader([]byte(repaymentCet)), true)
56+
if err != nil {
57+
return err
58+
}
59+
60+
liquidationScript, _ := hex.DecodeString(dlcMeta.LiquidationScript)
61+
repaymentScript, _ := hex.DecodeString(dlcMeta.RepaymentScript)
62+
timeoutRefundScript, _ := hex.DecodeString(dlcMeta.TimeoutRefundScript)
63+
64+
merkleTree := types.GetTapscriptTree([][]byte{
65+
liquidationScript, repaymentScript, timeoutRefundScript,
66+
})
67+
68+
liquidationScriptProof := merkleTree.LeafMerkleProofs[0]
69+
repaymentScriptProof := merkleTree.LeafMerkleProofs[1]
70+
71+
internalKeyBytes, _ := hex.DecodeString(dlcMeta.InternalKey)
72+
internalKey, _ := schnorr.ParsePubKey(internalKeyBytes)
73+
74+
liquidationScriptControlBlock, err := types.GetControlBlock(internalKey, liquidationScriptProof)
75+
if err != nil {
76+
return err
77+
}
78+
79+
repaymentScriptControlBlock, err := types.GetControlBlock(internalKey, repaymentScriptProof)
80+
if err != nil {
81+
return err
82+
}
83+
84+
for i := range liquidationCetPsbt.Inputs {
85+
liquidationCetPsbt.Inputs[i].SighashType = txscript.SigHashDefault
86+
liquidationCetPsbt.Inputs[i].TaprootInternalKey = internalKeyBytes
87+
liquidationCetPsbt.Inputs[i].TaprootLeafScript = []*psbt.TaprootTapLeafScript{
88+
{
89+
ControlBlock: liquidationScriptControlBlock,
90+
Script: liquidationScript,
91+
LeafVersion: txscript.BaseLeafVersion,
92+
},
93+
}
94+
}
95+
96+
for i := range repaymentCetPsbt.Inputs {
97+
repaymentCetPsbt.Inputs[i].SighashType = txscript.SigHashDefault
98+
repaymentCetPsbt.Inputs[i].TaprootInternalKey = internalKeyBytes
99+
repaymentCetPsbt.Inputs[i].TaprootLeafScript = []*psbt.TaprootTapLeafScript{
100+
{
101+
ControlBlock: repaymentScriptControlBlock,
102+
Script: repaymentScript,
103+
LeafVersion: txscript.BaseLeafVersion,
104+
},
105+
}
106+
}
107+
108+
liquidationCet, err = liquidationCetPsbt.B64Encode()
109+
if err != nil {
110+
return err
111+
}
112+
113+
repaymentCet, err = repaymentCetPsbt.B64Encode()
114+
if err != nil {
115+
return err
116+
}
117+
118+
borrowerPkScript, err := types.GetPkScriptFromPubKey(loan.BorrowerPubKey)
119+
if err != nil {
120+
return err
121+
}
122+
123+
timeoutRefundTx, err := types.CreateTimeoutRefundTransaction(depositTxs, vaultPkScript, borrowerPkScript, internalKeyBytes, [][]byte{liquidationScript, repaymentScript, timeoutRefundScript}, 1)
124+
if err != nil {
125+
return err
126+
}
127+
128+
// update dlc meta
129+
dlcMeta.LiquidationCet = types.LiquidationCet{
130+
Tx: liquidationCet,
131+
BorrowerAdaptorSignatures: liquidationAdaptorSignatures,
132+
}
133+
dlcMeta.DefaultLiquidationCet = types.LiquidationCet{
134+
Tx: liquidationCet,
135+
BorrowerAdaptorSignatures: defaultLiquidationAdaptorSignatures,
136+
}
137+
dlcMeta.RepaymentCet = types.RepaymentCet{
138+
Tx: repaymentCet,
139+
BorrowerSignatures: repaymentSignatures,
140+
}
141+
dlcMeta.TimeoutRefundTx = timeoutRefundTx
142+
dlcMeta.VaultUtxos = vaultUtxos
143+
144+
k.SetDLCMeta(ctx, loanId, dlcMeta)
145+
146+
return nil
147+
}
148+
33149
// GetCetInfos gets the related cet infos of the given loan
34150
// Assume that the loan exists
35151
func (k Keeper) GetCetInfos(ctx sdk.Context, loanId string, collateralAmount sdk.Coin) ([]*types.CetInfo, error) {
36152
loan := k.GetLoan(ctx, loanId)
153+
dlcMeta := k.GetDLCMeta(ctx, loanId)
37154
poolConfig := k.GetPool(ctx, loan.PoolId).Config
38155

39-
borrowerPubKey, _ := hex.DecodeString(loan.BorrowerPubKey)
40-
borrowerAuthPubKey, _ := hex.DecodeString(loan.BorrowerAuthPubKey)
41-
dcmPubKey, _ := hex.DecodeString(loan.DCM)
42-
43-
liquidationScript, _ := types.CreateMultisigScript([][]byte{borrowerAuthPubKey, dcmPubKey})
44-
repaymentScript, _ := types.CreateMultisigScript([][]byte{borrowerPubKey, dcmPubKey})
45-
timeRefundScript, _ := types.CreatePubKeyTimeLockScript(borrowerPubKey, loan.FinalTimeout)
156+
liquidationScript, _ := hex.DecodeString(dlcMeta.LiquidationScript)
157+
repaymentScript, _ := hex.DecodeString(dlcMeta.RepaymentScript)
158+
timeoutRefundScript, _ := hex.DecodeString(dlcMeta.TimeoutRefundScript)
46159

47-
merkleTree := types.GetTapscriptTree([][]byte{liquidationScript, repaymentScript, timeRefundScript})
160+
merkleTree := types.GetTapscriptTree([][]byte{liquidationScript, repaymentScript, timeoutRefundScript})
48161

49162
liquidationScriptProof := merkleTree.LeafMerkleProofs[0]
50163
repaymentScriptProof := merkleTree.LeafMerkleProofs[1]
51164

52-
internalKey := types.GetInternalKey(borrowerPubKey, dcmPubKey)
165+
internalKeyBytes, _ := hex.DecodeString(dlcMeta.InternalKey)
166+
internalKey, _ := schnorr.ParsePubKey(internalKeyBytes)
53167

54168
liquidationScriptControlBlock, err := types.GetControlBlock(internalKey, liquidationScriptProof)
55169
if err != nil {

x/lending/keeper/msg_server_loan.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ func (m msgServer) Apply(goCtx context.Context, msg *types.MsgApply) (*types.Msg
127127
m.SetLoan(ctx, loan)
128128
m.SetLoanByAddress(ctx, loan)
129129

130+
// set dlc meta
131+
m.SetDLCMeta(ctx, vault, types.NewDLCMeta(loan.BorrowerPubKey, loan.BorrowerAuthPubKey, loan.DCM, loan.FinalTimeout))
132+
130133
ctx.EventManager().EmitEvent(
131134
sdk.NewEvent(types.EventTypeApply,
132135
sdk.NewAttribute(types.AttributeKeyVault, loan.VaultAddress),
@@ -189,9 +192,8 @@ func (m msgServer) SubmitCets(goCtx context.Context, msg *types.MsgSubmitCets) (
189192
return nil, errorsmod.Wrap(types.ErrInsufficientCollateral, "collateral amount can not be zero")
190193
}
191194

192-
// build DLC metadata
193-
dlcMeta, err := types.BuildDLCMeta(depositTxs, vaultPkScript, msg.LiquidationCet, msg.LiquidationAdaptorSignatures, msg.DefaultLiquidationAdaptorSignatures, msg.RepaymentCet, msg.RepaymentSignatures, loan.BorrowerPubKey, loan.BorrowerAuthPubKey, loan.DCM, loan.MaturityTime, loan.FinalTimeout)
194-
if err != nil {
195+
// update dlc meta
196+
if err := m.UpdateDLCMeta(ctx, msg.LoanId, depositTxs, msg.LiquidationCet, msg.LiquidationAdaptorSignatures, msg.DefaultLiquidationAdaptorSignatures, msg.RepaymentCet, msg.RepaymentSignatures); err != nil {
195197
return nil, err
196198
}
197199

@@ -211,8 +213,6 @@ func (m msgServer) SubmitCets(goCtx context.Context, msg *types.MsgSubmitCets) (
211213
}
212214
}
213215

214-
m.SetDLCMeta(ctx, loan.VaultAddress, dlcMeta)
215-
216216
loan.CollateralAmount = collateralAmount
217217
loan.Authorizations = append(loan.Authorizations, *authorization)
218218

@@ -347,7 +347,11 @@ func (m msgServer) Redeem(goCtx context.Context, msg *types.MsgRedeem) (*types.M
347347
borrowerPubKey, _ := hex.DecodeString(loan.BorrowerPubKey)
348348

349349
internalKey, _ := hex.DecodeString(m.GetDLCMeta(ctx, msg.LoanId).InternalKey)
350-
script, controlBlock := m.GetRedemptionScript(ctx, msg.LoanId)
350+
351+
script, controlBlock, err := m.GetRedemptionScript(ctx, msg.LoanId)
352+
if err != nil {
353+
return nil, err
354+
}
351355

352356
sigHashes := []string{}
353357

x/lending/keeper/redemption.go

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

8+
"github.com/btcsuite/btcd/btcec/v2/schnorr"
89
"github.com/btcsuite/btcd/btcutil/psbt"
910
"github.com/btcsuite/btcd/txscript"
1011

@@ -87,13 +88,33 @@ func (k Keeper) HandleRedemptionSignatures(ctx sdk.Context, id uint64, signature
8788
}
8889

8990
// GetRedemptionScript gets the script along with the corresponding control block for redemption
90-
func (k Keeper) GetRedemptionScript(ctx sdk.Context, loanId string) ([]byte, []byte) {
91-
repaymentCet, _ := psbt.NewFromRawBytes(bytes.NewReader([]byte(k.GetDLCMeta(ctx, loanId).RepaymentCet.Tx)), true)
91+
func (k Keeper) GetRedemptionScript(ctx sdk.Context, loanId string) ([]byte, []byte, error) {
92+
dlcMeta := k.GetDLCMeta(ctx, loanId)
93+
if len(dlcMeta.RepaymentCet.Tx) > 0 {
94+
repaymentCet, _ := psbt.NewFromRawBytes(bytes.NewReader([]byte(dlcMeta.RepaymentCet.Tx)), true)
9295

93-
script := repaymentCet.Inputs[0].TaprootLeafScript[0].Script
94-
controlBlock := repaymentCet.Inputs[0].TaprootLeafScript[0].ControlBlock
96+
script := repaymentCet.Inputs[0].TaprootLeafScript[0].Script
97+
controlBlock := repaymentCet.Inputs[0].TaprootLeafScript[0].ControlBlock
9598

96-
return script, controlBlock
99+
return script, controlBlock, nil
100+
}
101+
102+
liquidationScript, _ := hex.DecodeString(dlcMeta.LiquidationScript)
103+
repaymentScript, _ := hex.DecodeString(dlcMeta.RepaymentScript)
104+
timeoutRefundScript, _ := hex.DecodeString(dlcMeta.TimeoutRefundScript)
105+
106+
merkleTree := types.GetTapscriptTree([][]byte{liquidationScript, repaymentScript, timeoutRefundScript})
107+
repaymentScriptProof := merkleTree.LeafMerkleProofs[1]
108+
109+
internalKeyBytes, _ := hex.DecodeString(dlcMeta.InternalKey)
110+
internalKey, _ := schnorr.ParsePubKey(internalKeyBytes)
111+
112+
repaymentScriptControlBlock, err := types.GetControlBlock(internalKey, repaymentScriptProof)
113+
if err != nil {
114+
return nil, nil, err
115+
}
116+
117+
return repaymentScript, repaymentScriptControlBlock, nil
97118
}
98119

99120
// GetRedemptionId gets the current redemption id

0 commit comments

Comments
 (0)