|
1 | 1 | package keeper |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | "encoding/hex" |
5 | 6 |
|
| 7 | + "github.com/btcsuite/btcd/btcec/v2/schnorr" |
| 8 | + "github.com/btcsuite/btcd/btcutil/psbt" |
| 9 | + "github.com/btcsuite/btcd/txscript" |
| 10 | + |
6 | 11 | errorsmod "cosmossdk.io/errors" |
7 | 12 | sdk "github.com/cosmos/cosmos-sdk/types" |
8 | 13 |
|
@@ -30,26 +35,135 @@ func (k Keeper) GetDLCMeta(ctx sdk.Context, loanId string) *types.DLCMeta { |
30 | 35 | return &dlcMeta |
31 | 36 | } |
32 | 37 |
|
| 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 | + |
33 | 149 | // GetCetInfos gets the related cet infos of the given loan |
34 | 150 | // Assume that the loan exists |
35 | 151 | func (k Keeper) GetCetInfos(ctx sdk.Context, loanId string, collateralAmount sdk.Coin) ([]*types.CetInfo, error) { |
36 | 152 | loan := k.GetLoan(ctx, loanId) |
| 153 | + dlcMeta := k.GetDLCMeta(ctx, loanId) |
37 | 154 | poolConfig := k.GetPool(ctx, loan.PoolId).Config |
38 | 155 |
|
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) |
46 | 159 |
|
47 | | - merkleTree := types.GetTapscriptTree([][]byte{liquidationScript, repaymentScript, timeRefundScript}) |
| 160 | + merkleTree := types.GetTapscriptTree([][]byte{liquidationScript, repaymentScript, timeoutRefundScript}) |
48 | 161 |
|
49 | 162 | liquidationScriptProof := merkleTree.LeafMerkleProofs[0] |
50 | 163 | repaymentScriptProof := merkleTree.LeafMerkleProofs[1] |
51 | 164 |
|
52 | | - internalKey := types.GetInternalKey(borrowerPubKey, dcmPubKey) |
| 165 | + internalKeyBytes, _ := hex.DecodeString(dlcMeta.InternalKey) |
| 166 | + internalKey, _ := schnorr.ParsePubKey(internalKeyBytes) |
53 | 167 |
|
54 | 168 | liquidationScriptControlBlock, err := types.GetControlBlock(internalKey, liquidationScriptProof) |
55 | 169 | if err != nil { |
|
0 commit comments