Skip to content

Commit 0c4c147

Browse files
committed
adjust tapscript proof
1 parent 1bd08aa commit 0c4c147

File tree

2 files changed

+54
-11
lines changed

2 files changed

+54
-11
lines changed

x/lending/types/dlc.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,20 @@ func BuildDLCMeta(borrowerPubKey string, borrowerAuthPubKey string, dcmPubKey st
4040

4141
liquidationScript, repaymentScript, timeoutRefundScript, _ := GetVaultScripts(borrowerPubKey, borrowerAuthPubKey, dcmPubKey, finalTimeout)
4242

43-
tapScriptTree := GetTapScriptTree([][]byte{liquidationScript, repaymentScript, timeoutRefundScript})
43+
tapscriptTree := GetTapscriptTree([][]byte{liquidationScript, repaymentScript, timeoutRefundScript})
44+
proofs := GetThreeLeafTapscriptTreeProofs(tapscriptTree)
4445

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

54-
repaymentScriptControlBlock, err := GetControlBlock(internalKey, repaymentScriptProof)
51+
repaymentScriptControlBlock, err := GetControlBlock(internalKey, proofs[1])
5552
if err != nil {
5653
return nil, err
5754
}
5855

59-
timeoutRefundScriptControlBlock, err := GetControlBlock(internalKey, timeoutRefundScriptProof)
56+
timeoutRefundScriptControlBlock, err := GetControlBlock(internalKey, proofs[2])
6057
if err != nil {
6158
return nil, err
6259
}

x/lending/types/taproot.go

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ func CreatePubKeyTimeLockScript(pubKey []byte, lockTime int64) ([]byte, error) {
5757

5858
// CreateTaprootAddress creates the taproot address with the given internal key and scripts
5959
func CreateTaprootAddress(internalKey *secp256k1.PublicKey, scripts [][]byte, params *chaincfg.Params) (string, error) {
60-
tapScriptTree := GetTapScriptTree(scripts)
61-
scriptRoot := tapScriptTree.RootNode.TapHash()
60+
tapscriptTree := GetTapscriptTree(scripts)
61+
scriptRoot := tapscriptTree.RootNode.TapHash()
6262

6363
taprootOutKey := txscript.ComputeTaprootOutputKey(internalKey, scriptRoot[:])
6464

@@ -145,7 +145,7 @@ func GetInternalKey(borrowerPubKey []byte, dcmPubKey []byte) *btcec.PublicKey {
145145
return btcec.NewPublicKey(&P.X, &P.Y)
146146
}
147147

148-
func GetTapScriptTree(scripts [][]byte) *txscript.IndexedTapScriptTree {
148+
func GetTapscriptTree(scripts [][]byte) *txscript.IndexedTapScriptTree {
149149
leaves := []txscript.TapLeaf{}
150150

151151
for _, script := range scripts {
@@ -157,6 +157,29 @@ func GetTapScriptTree(scripts [][]byte) *txscript.IndexedTapScriptTree {
157157
return tree
158158
}
159159

160+
// GetThreeLeafTapscriptTreeProofs gets the tapscript proofs from the given 3-leaf tapscript tree
161+
// This is a workaround because btcsuite.AssembleTaprootScriptTree generates incorrect proofs if there exist same scripts
162+
// NOTE: Assume that this is a tapscript tree with three leaves
163+
// LeafA,LeafB,LeafC:
164+
// LeafA proof: H(LeafB),H(LeafC)
165+
// LeafB proof: H(LeafA),H(LeafC)
166+
// LeafC proof: H(H(LeafA),H(LeafB)) if H(LeafA) <= H(LeafB)
167+
func GetThreeLeafTapscriptTreeProofs(tapscriptTree *txscript.IndexedTapScriptTree) []txscript.TapscriptProof {
168+
leaves := []txscript.TapLeaf{}
169+
170+
for _, p := range tapscriptTree.LeafMerkleProofs {
171+
leaves = append(leaves, p.TapLeaf)
172+
}
173+
174+
rootNode := tapscriptTree.RootNode
175+
176+
return []txscript.TapscriptProof{
177+
newTapscriptProof(leaves[0], rootNode, append(getTapLeafHash(leaves[1]), getTapLeafHash(leaves[2])...)),
178+
newTapscriptProof(leaves[1], rootNode, append(getTapLeafHash(leaves[0]), getTapLeafHash(leaves[2])...)),
179+
newTapscriptProof(leaves[2], rootNode, getBranchNodeHash(leaves[0], leaves[1])),
180+
}
181+
}
182+
160183
func GetControlBlock(pubKey *secp256k1.PublicKey, proof txscript.TapscriptProof) ([]byte, error) {
161184
controlBlock := proof.ToControlBlock(pubKey)
162185

@@ -225,3 +248,26 @@ func GetNUMSPoint() *btcec.PublicKey {
225248

226249
return point
227250
}
251+
252+
// getTapLeafHash gets hash of the given tap leaf
253+
func getTapLeafHash(leaf txscript.TapLeaf) []byte {
254+
hash := leaf.TapHash()
255+
return hash[:]
256+
}
257+
258+
// getBranchNodeHash gets the branch node hash from the given left and right nodes
259+
func getBranchNodeHash(left txscript.TapNode, right txscript.TapNode) []byte {
260+
tapBranch := txscript.NewTapBranch(left, right)
261+
tapBranchHash := tapBranch.TapHash()
262+
263+
return tapBranchHash[:]
264+
}
265+
266+
// newTapscriptProof creates a tapscript proof from the given params
267+
func newTapscriptProof(leaf txscript.TapLeaf, rootNode txscript.TapNode, proof []byte) txscript.TapscriptProof {
268+
return txscript.TapscriptProof{
269+
TapLeaf: leaf,
270+
RootNode: rootNode,
271+
InclusionProof: proof,
272+
}
273+
}

0 commit comments

Comments
 (0)