From a155d466fc4fced5d34d257cb6bc6709a0676520 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 3 Dec 2024 16:42:30 +0100 Subject: [PATCH] txscript: add more detail to invalid tapscript merkle proof error In this commit, we add more detail to the invalid tapscript merkle proof error. Before this commit, the error was blank, making such a case hard to debug. We'll now log the expected witness program, what we derived, and also the passed in tapscript root. --- txscript/taproot.go | 5 ++++- txscript/taproot_test.go | 27 +++++++++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/txscript/taproot.go b/txscript/taproot.go index ee26cae967..b258fbbbf6 100644 --- a/txscript/taproot.go +++ b/txscript/taproot.go @@ -353,7 +353,10 @@ func VerifyTaprootLeafCommitment(controlBlock *ControlBlock, expectedWitnessProgram := schnorr.SerializePubKey(taprootKey) if !bytes.Equal(expectedWitnessProgram, taprootWitnessProgram) { - return scriptError(ErrTaprootMerkleProofInvalid, "") + str := fmt.Sprintf("derived witness program: %x, expected: "+ + "%x, using tapscript_root: %x", expectedWitnessProgram, + taprootWitnessProgram, rootHash) + return scriptError(ErrTaprootMerkleProofInvalid, str) } // Finally, we'll verify that the parity of the y coordinate of the diff --git a/txscript/taproot_test.go b/txscript/taproot_test.go index 9c5bb573a4..def035bae8 100644 --- a/txscript/taproot_test.go +++ b/txscript/taproot_test.go @@ -293,13 +293,15 @@ func TestTapscriptCommitmentVerification(t *testing.T) { // make from 0 to 1 leaf // ensure verifies properly testCases := []struct { + treeMutateFunc func(*IndexedTapScriptTree) + + ctrlBlockMutateFunc func(*ControlBlock) + numLeaves int valid bool - treeMutateFunc func(*IndexedTapScriptTree) - - ctrlBlockMutateFunc func(*ControlBlock) + expectedErr ErrorCode }{ // A valid merkle proof of a single leaf. { @@ -322,11 +324,13 @@ func TestTapscriptCommitmentVerification(t *testing.T) { // An invalid merkle proof, we modify the last byte of one of // the leaves. { - numLeaves: 4, - valid: false, + numLeaves: 4, + valid: false, + expectedErr: ErrTaprootMerkleProofInvalid, treeMutateFunc: func(t *IndexedTapScriptTree) { for _, leafProof := range t.LeafMerkleProofs { - leafProof.InclusionProof[0] ^= 1 + proofLen := len(leafProof.InclusionProof) + leafProof.InclusionProof[proofLen-1] ^= 1 } }, }, @@ -335,8 +339,9 @@ func TestTapscriptCommitmentVerification(t *testing.T) { // An invalid series of proofs, we modify the control // block to not match the parity of the final output // key commitment. - numLeaves: 2, - valid: false, + numLeaves: 2, + valid: false, + expectedErr: ErrTaprootOutputKeyParityMismatch, ctrlBlockMutateFunc: func(c *ControlBlock) { c.OutputKeyYIsOdd = !c.OutputKeyYIsOdd }, @@ -391,6 +396,12 @@ func TestTapscriptCommitmentVerification(t *testing.T) { "valid=%v, got valid=%v", testCase.valid, valid) } + + if !valid { + if !IsErrorCode(err, testCase.expectedErr) { + t.Fatalf("expected error code %v, got %v", testCase.expectedErr, err) + } + } } // TODO(roasbeef): index correctness