Skip to content

Commit 36f50fa

Browse files
committed
optimize control block
1 parent 713240a commit 36f50fa

2 files changed

Lines changed: 39 additions & 21 deletions

File tree

x/lending/types/dlc.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,27 @@ const (
3434
// Assume that the given params are valid
3535
func BuildDLCMeta(borrowerPubKey string, borrowerAuthPubKey string, dcmPubKey string, finalTimeout int64) (*DLCMeta, error) {
3636
borrowerPubKeyBytes, _ := hex.DecodeString(borrowerPubKey)
37+
borrowerAuthPubKeyBytes, _ := hex.DecodeString(borrowerAuthPubKey)
3738
dcmPubKeyBytes, _ := hex.DecodeString(dcmPubKey)
3839

3940
internalKey := GetInternalKey(borrowerPubKeyBytes, dcmPubKeyBytes)
4041

41-
liquidationScript, repaymentScript, timeoutRefundScript, _ := GetVaultScripts(borrowerPubKey, borrowerAuthPubKey, dcmPubKey, finalTimeout)
42+
liquidationScript, repaymentScript, timeoutRefundScript, _ := GetVaultScripts(borrowerPubKeyBytes, borrowerAuthPubKeyBytes, dcmPubKeyBytes, finalTimeout)
4243

4344
tapscriptTree := GetTapscriptTree([][]byte{liquidationScript, repaymentScript, timeoutRefundScript})
4445
sanitizeTapscriptTreeProofs(tapscriptTree)
4546

46-
liquidationScriptProof := tapscriptTree.LeafMerkleProofs[0]
47-
repaymentScriptProof := tapscriptTree.LeafMerkleProofs[1]
48-
timeoutRefundScriptProof := tapscriptTree.LeafMerkleProofs[2]
49-
50-
liquidationScriptControlBlock, err := GetControlBlock(internalKey, liquidationScriptProof)
47+
liquidationScriptControlBlock, err := GetControlBlock(tapscriptTree, liquidationScript, internalKey)
5148
if err != nil {
5249
return nil, err
5350
}
5451

55-
repaymentScriptControlBlock, err := GetControlBlock(internalKey, repaymentScriptProof)
52+
repaymentScriptControlBlock, err := GetControlBlock(tapscriptTree, repaymentScript, internalKey)
5653
if err != nil {
5754
return nil, err
5855
}
5956

60-
timeoutRefundScriptControlBlock, err := GetControlBlock(internalKey, timeoutRefundScriptProof)
57+
timeoutRefundScriptControlBlock, err := GetControlBlock(tapscriptTree, timeoutRefundScript, internalKey)
6158
if err != nil {
6259
return nil, err
6360
}

x/lending/types/taproot.go

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/btcsuite/btcd/btcutil"
1111
"github.com/btcsuite/btcd/btcutil/psbt"
1212
"github.com/btcsuite/btcd/chaincfg"
13+
"github.com/btcsuite/btcd/chaincfg/chainhash"
1314
"github.com/btcsuite/btcd/txscript"
1415

1516
"github.com/sideprotocol/side/bitcoin"
@@ -75,11 +76,12 @@ func CreateTaprootAddress(internalKey *secp256k1.PublicKey, scripts [][]byte, pa
7576
// Assume that the given pub keys are valid
7677
func CreateVaultAddress(borrowerPubKey string, borrowerAuthPubKey string, dcmPubKey string, finalTimeout int64) (string, error) {
7778
borrowerPubKeyBytes, _ := hex.DecodeString(borrowerPubKey)
79+
borrowerAuthPubKeyBytes, _ := hex.DecodeString(borrowerAuthPubKey)
7880
dcmPubKeyBytes, _ := hex.DecodeString(dcmPubKey)
7981

8082
internalKey := GetInternalKey(borrowerPubKeyBytes, dcmPubKeyBytes)
8183

82-
liquidationScript, repaymentScript, timeoutRefundScript, err := GetVaultScripts(borrowerPubKey, borrowerAuthPubKey, dcmPubKey, finalTimeout)
84+
liquidationScript, repaymentScript, timeoutRefundScript, err := GetVaultScripts(borrowerPubKeyBytes, borrowerAuthPubKeyBytes, dcmPubKeyBytes, finalTimeout)
8385
if err != nil {
8486
return "", err
8587
}
@@ -95,26 +97,21 @@ func CreateVaultAddress(borrowerPubKey string, borrowerAuthPubKey string, dcmPub
9597
}
9698

9799
// GetVaultScripts gets the scripts associated the underlying vault address from the given params
98-
// Assume that the given pub keys are valid
99-
func GetVaultScripts(borrowerPubKey string, borrowerAuthPubKey string, dcmPubKey string, finalTimeout int64) ([]byte, []byte, []byte, error) {
100-
borrowerPubKeyBytes, _ := hex.DecodeString(borrowerPubKey)
101-
borrowerAuthPubKeyBytes, _ := hex.DecodeString(borrowerAuthPubKey)
102-
dcmPubKeyBytes, _ := hex.DecodeString(dcmPubKey)
103-
100+
func GetVaultScripts(borrowerPubKey []byte, borrowerAuthPubKey []byte, dcmPubKey []byte, finalTimeout int64) ([]byte, []byte, []byte, error) {
104101
// liquidation script
105-
liquidationScript, err := CreateMultisigScript([][]byte{borrowerAuthPubKeyBytes, dcmPubKeyBytes})
102+
liquidationScript, err := CreateMultisigScript([][]byte{borrowerAuthPubKey, dcmPubKey})
106103
if err != nil {
107104
return nil, nil, nil, err
108105
}
109106

110107
// repayment script
111-
repaymentScript, err := CreateMultisigScript([][]byte{borrowerPubKeyBytes, dcmPubKeyBytes})
108+
repaymentScript, err := CreateMultisigScript([][]byte{borrowerPubKey, dcmPubKey})
112109
if err != nil {
113110
return nil, nil, nil, err
114111
}
115112

116113
// refund script
117-
timeoutRefundScript, err := CreatePubKeyTimeLockScript(borrowerPubKeyBytes, finalTimeout)
114+
timeoutRefundScript, err := CreatePubKeyTimeLockScript(borrowerPubKey, finalTimeout)
118115
if err != nil {
119116
return nil, nil, nil, err
120117
}
@@ -145,20 +142,44 @@ func GetInternalKey(borrowerPubKey []byte, dcmPubKey []byte) *btcec.PublicKey {
145142
return btcec.NewPublicKey(&P.X, &P.Y)
146143
}
147144

145+
// GetTapscriptTree gets the tapscript tree built from the given tapscripts
146+
// NOTE: Duplicate scripts are filtered out
148147
func GetTapscriptTree(scripts [][]byte) *txscript.IndexedTapScriptTree {
149148
leaves := []txscript.TapLeaf{}
149+
leafMap := make(map[chainhash.Hash]bool)
150150

151151
for _, script := range scripts {
152-
leaves = append(leaves, txscript.NewBaseTapLeaf(script))
152+
leaf := txscript.NewBaseTapLeaf(script)
153+
hash := leaf.TapHash()
154+
155+
if !leafMap[hash] {
156+
leaves = append(leaves, leaf)
157+
leafMap[hash] = true
158+
}
153159
}
154160

155161
tree := txscript.AssembleTaprootScriptTree(leaves...)
156162

157163
return tree
158164
}
159165

160-
func GetControlBlock(pubKey *secp256k1.PublicKey, proof txscript.TapscriptProof) ([]byte, error) {
161-
controlBlock := proof.ToControlBlock(pubKey)
166+
// GetTapscriptMerkleProof gets the merkle proof of the specified script from the given tapscript tree
167+
func GetTapscriptMerkleProof(tree *txscript.IndexedTapScriptTree, script []byte) txscript.TapscriptProof {
168+
leaf := txscript.NewBaseTapLeaf(script)
169+
170+
index, ok := tree.LeafProofIndex[leaf.TapHash()]
171+
if !ok {
172+
return txscript.TapscriptProof{}
173+
}
174+
175+
return tree.LeafMerkleProofs[index]
176+
}
177+
178+
// GetControlBlock gets the control block for the given tapscript
179+
// Assume that the given script exists in the tapscript tree
180+
func GetControlBlock(tree *txscript.IndexedTapScriptTree, script []byte, internalKey *secp256k1.PublicKey) ([]byte, error) {
181+
proof := GetTapscriptMerkleProof(tree, script)
182+
controlBlock := proof.ToControlBlock(internalKey)
162183

163184
controlBlockBz, err := controlBlock.ToBytes()
164185
if err != nil {

0 commit comments

Comments
 (0)