Skip to content

Commit d739a1b

Browse files
jharveybguggero
authored andcommitted
tapsend: include AltLeaves in output commitments
1 parent 64319ad commit d739a1b

File tree

2 files changed

+162
-30
lines changed

2 files changed

+162
-30
lines changed

tapsend/send.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,9 @@ func CreateOutputCommitments(
10441044
if err := AssertOutputAnchorsEqual(packets); err != nil {
10451045
return nil, err
10461046
}
1047+
if err := AssertOutputAltLeavesValid(packets); err != nil {
1048+
return nil, err
1049+
}
10471050

10481051
// We need to make sure this transaction doesn't lead to collisions in
10491052
// any of the trees (e.g. two asset outputs with the same script key in
@@ -1125,6 +1128,13 @@ func commitPacket(vPkt *tappsbt.VPacket,
11251128
err)
11261129
}
11271130

1131+
// If the vOutput contains any AltLeaves, merge them into the
1132+
// tap commitment.
1133+
err = sendTapCommitment.MergeAltLeaves(vOut.AltLeaves)
1134+
if err != nil {
1135+
return fmt.Errorf("error merging alt leaves: %w", err)
1136+
}
1137+
11281138
// Merge the finished TAP level commitment with the existing
11291139
// one (if any) for the anchor output.
11301140
anchorOutputCommitment, ok := outputCommitments[anchorOutputIdx]
@@ -1570,6 +1580,37 @@ func AssertInputsUnique(packets []*tappsbt.VPacket) error {
15701580
return nil
15711581
}
15721582

1583+
// AssertOutputAltLeavesValid checks that, for each anchor output, the AltLeaves
1584+
// carried by all packets assigned to that output can be used to construct an
1585+
// AltCommitment.
1586+
func AssertOutputAltLeavesValid(vPackets []*tappsbt.VPacket) error {
1587+
anchorLeaves := make(map[uint32]fn.Set[[32]byte])
1588+
1589+
for _, pkt := range vPackets {
1590+
for _, vOut := range pkt.Outputs {
1591+
if len(vOut.AltLeaves) == 0 {
1592+
continue
1593+
}
1594+
1595+
// Build a set of AltLeaf keys for each anchor output.
1596+
outIndex := vOut.AnchorOutputIndex
1597+
if _, ok := anchorLeaves[outIndex]; !ok {
1598+
anchorLeaves[outIndex] = fn.NewSet[[32]byte]()
1599+
}
1600+
1601+
err := asset.AddLeafKeysVerifyUnique(
1602+
anchorLeaves[outIndex], vOut.AltLeaves,
1603+
)
1604+
if err != nil {
1605+
return fmt.Errorf("anchor output %d: %w",
1606+
outIndex, err)
1607+
}
1608+
}
1609+
}
1610+
1611+
return nil
1612+
}
1613+
15731614
// ExtractUnSpendable extracts all tombstones and burns from the active input
15741615
// commitment.
15751616
func ExtractUnSpendable(c *commitment.TapCommitment) []*asset.Asset {

0 commit comments

Comments
 (0)