@@ -1729,6 +1729,9 @@ func ValidateAnchorOutputs(anchorPacket *psbt.Packet,
17291729 outputSiblings = make (
17301730 map [uint32 ]* commitment.TapscriptPreimage ,
17311731 )
1732+ outputAltLeaves = make (
1733+ map [uint32 ][]asset.AltLeaf [asset.Asset ],
1734+ )
17321735 outputCommitVersions = make (
17331736 map [uint32 ]* commitment.TapCommitmentVersion ,
17341737 )
@@ -1827,6 +1830,10 @@ func ValidateAnchorOutputs(anchorPacket *psbt.Packet,
18271830 vOut .Asset ,
18281831 )
18291832 outputSiblings [vOut .AnchorOutputIndex ] = siblingPreimage
1833+ outputAltLeaves [vOut .AnchorOutputIndex ] = append (
1834+ outputAltLeaves [vOut .AnchorOutputIndex ],
1835+ asset .CopyAltLeaves (vOut .AltLeaves )... ,
1836+ )
18301837
18311838 // Fetch the tap commitment version from the proof of
18321839 // inclusion for the vOutput.
@@ -1889,6 +1896,17 @@ func ValidateAnchorOutputs(anchorPacket *psbt.Packet,
18891896 }
18901897 }
18911898
1899+ // Each output must have a valid set of AltLeaves at this point.
1900+ for anchorIdx , leaves := range outputAltLeaves {
1901+ err := asset .ValidAltLeaves (leaves )
1902+ if err != nil {
1903+ finalErr := fmt .Errorf ("output %d invalid alt " +
1904+ "leaves: %w" , anchorIdx , err )
1905+ log .Tracef (finalErr .Error ())
1906+ return finalErr
1907+ }
1908+ }
1909+
18921910 // We can now go through each anchor output that will carry assets and
18931911 // check that we arrive at the correct script.
18941912 for anchorIdx , assets := range outputAssets {
@@ -1900,6 +1918,14 @@ func ValidateAnchorOutputs(anchorPacket *psbt.Packet,
19001918 "output assets: %w" , err )
19011919 }
19021920
1921+ err = anchorCommitment .MergeAltLeaves (
1922+ outputAltLeaves [anchorIdx ],
1923+ )
1924+ if err != nil {
1925+ return fmt .Errorf ("unable to merge output alt leaves: " +
1926+ "%w" , err )
1927+ }
1928+
19031929 anchorOut := & anchorPacket .Outputs [anchorIdx ]
19041930 anchorTxOut := anchorPacket .UnsignedTx .TxOut [anchorIdx ]
19051931 internalKey , err := schnorr .ParsePubKey (
@@ -1988,6 +2014,9 @@ func ValidateAnchorInputs(anchorPacket *psbt.Packet, packets []*tappsbt.VPacket,
19882014 inputSiblings = make (
19892015 map [wire.OutPoint ]* commitment.TapscriptPreimage ,
19902016 )
2017+ inputAltLeaves = make (
2018+ map [wire.OutPoint ][]asset.AltLeaf [asset.Asset ],
2019+ )
19912020 inputAnchorIndex = make (map [wire.OutPoint ]uint32 )
19922021 )
19932022 for _ , vPkt := range packets {
@@ -2077,6 +2106,10 @@ func ValidateAnchorInputs(anchorPacket *psbt.Packet, packets []*tappsbt.VPacket,
20772106 inputAssets [outpoint ], vIn .Asset (),
20782107 )
20792108 inputSiblings [outpoint ] = sibling
2109+ inputAltLeaves [outpoint ] = append (
2110+ inputAltLeaves [outpoint ],
2111+ asset .CopyAltLeaves (vIn .AltLeaves )... ,
2112+ )
20802113 inputScripts [outpoint ] = anchorIn .WitnessUtxo .PkScript
20812114 inputAnchors [outpoint ] = vIn .Anchor
20822115 }
@@ -2090,6 +2123,15 @@ func ValidateAnchorInputs(anchorPacket *psbt.Packet, packets []*tappsbt.VPacket,
20902123 )
20912124 }
20922125
2126+ // Each input must have a valid set of AltLeaves at this point.
2127+ for outpoint , leaves := range inputAltLeaves {
2128+ err := asset .ValidAltLeaves (leaves )
2129+ if err != nil {
2130+ return fmt .Errorf ("input %v invalid alt leaves: %w" ,
2131+ outpoint .String (), err )
2132+ }
2133+ }
2134+
20932135 // We can now go through each anchor input that contains assets being
20942136 // spent and check that we arrive at the correct script.
20952137 for anchorOutpoint , assets := range inputAssets {
@@ -2101,6 +2143,14 @@ func ValidateAnchorInputs(anchorPacket *psbt.Packet, packets []*tappsbt.VPacket,
21012143 "output assets: %w" , err )
21022144 }
21032145
2146+ err = anchorCommitment .MergeAltLeaves (
2147+ inputAltLeaves [anchorOutpoint ],
2148+ )
2149+ if err != nil {
2150+ return fmt .Errorf ("unable to merge input alt leaves: " +
2151+ "%w" , err )
2152+ }
2153+
21042154 anchorIdx := inputAnchorIndex [anchorOutpoint ]
21052155 anchorIn := inputAnchors [anchorOutpoint ]
21062156 internalKey := anchorIn .InternalKey
0 commit comments