Skip to content

Commit e687ac7

Browse files
committed
proof+tapfreighter: export CreateProofSuffix
We'll want to create proof suffixes outside of the chain porter, so we export the function and make it more generic so it can work with any number of related virtual transactions.
1 parent 05b821d commit e687ac7

File tree

2 files changed

+57
-36
lines changed

2 files changed

+57
-36
lines changed

proof/mint.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ func (p *BaseProofParams) HaveExclusionProof(anchorOutputIndex uint32) bool {
152152
return false
153153
}
154154

155+
// HaveInclusionProof returns true if the inclusion proof is for the given
156+
// anchor output index.
157+
func (p *BaseProofParams) HaveInclusionProof(anchorOutputIndex uint32) bool {
158+
return p.OutputIndex == int(anchorOutputIndex)
159+
}
160+
155161
// MintParams holds the set of chain level information needed to make a proof
156162
// file for the set of assets minted in a batch.
157163
type MintParams struct {

tapfreighter/parcel.go

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,9 @@ func (s *sendPackage) prepareForStorage(currentHeight uint32) (*OutboundParcel,
466466
// In any other case we expect an active asset transfer to be
467467
// committed to.
468468
case vOut.Asset != nil:
469-
proofSuffix, err := s.createProofSuffix(idx)
469+
proofSuffix, err := CreateProofSuffix(
470+
s.AnchorTx, s.VirtualPacket, idx, nil,
471+
)
470472
if err != nil {
471473
return nil, fmt.Errorf("unable to create "+
472474
"proof %d: %w", idx, err)
@@ -513,33 +515,51 @@ func (s *sendPackage) prepareForStorage(currentHeight uint32) (*OutboundParcel,
513515
return parcel, nil
514516
}
515517

516-
// createProofSuffix creates the new proof for the given output. This is the
518+
// CreateProofSuffix creates the new proof for the given output. This is the
517519
// final state transition that will be added to the proofs of the receiver. The
518520
// proof returned will have all the Taproot Asset level proof information, but
519521
// contains dummy data for the on-chain part.
520-
func (s *sendPackage) createProofSuffix(outIndex int) (*proof.Proof, error) {
521-
inputPrevID := s.VirtualPacket.Inputs[0].PrevID
522+
func CreateProofSuffix(anchorTx *AnchorTransaction, vPacket *tappsbt.VPacket,
523+
outIndex int, allAnchoredVPackets []*tappsbt.VPacket) (*proof.Proof,
524+
error) {
525+
526+
inputPrevID := vPacket.Inputs[0].PrevID
522527

523-
params, err := proofParams(s.AnchorTx, s.VirtualPacket, outIndex)
528+
params, err := proofParams(
529+
anchorTx, vPacket, outIndex, allAnchoredVPackets,
530+
)
524531
if err != nil {
525532
return nil, err
526533
}
527534

528-
// We also need to account for any P2TR change outputs.
529-
if len(s.AnchorTx.FundedPsbt.Pkt.UnsignedTx.TxOut) > 1 {
530-
isAnchor := func(idx uint32) bool {
531-
for outIdx := range s.VirtualPacket.Outputs {
532-
vOut := s.VirtualPacket.Outputs[outIdx]
533-
if vOut.AnchorOutputIndex == idx {
535+
isAnchor := func(anchorOutputIndex uint32) bool {
536+
// Does the current virtual packet anchor into this output?
537+
for outIdx := range vPacket.Outputs {
538+
vOut := vPacket.Outputs[outIdx]
539+
if vOut.AnchorOutputIndex == anchorOutputIndex {
540+
return true
541+
}
542+
}
543+
544+
// Maybe any of the other anchored virtual packets anchor into
545+
// this output?
546+
for _, vPkt := range allAnchoredVPackets {
547+
for _, vOut := range vPkt.Outputs {
548+
if vOut.AnchorOutputIndex == anchorOutputIndex {
534549
return true
535550
}
536551
}
537-
538-
return false
539552
}
540553

554+
// No virtual packet anchors into this output, it must be a
555+
// pure BTC output.
556+
return false
557+
}
558+
559+
// We also need to account for any P2TR change outputs.
560+
if len(anchorTx.FundedPsbt.Pkt.UnsignedTx.TxOut) > 1 {
541561
err := proof.AddExclusionProofs(
542-
&params.BaseProofParams, s.AnchorTx.FundedPsbt.Pkt,
562+
&params.BaseProofParams, anchorTx.FundedPsbt.Pkt,
543563
isAnchor,
544564
)
545565
if err != nil {
@@ -585,7 +605,8 @@ func newParams(anchorTx *AnchorTransaction, a *asset.Asset, outputIndex int,
585605
// proofParams creates the set of parameters that will be used to create the
586606
// proofs for the sender and receiver.
587607
func proofParams(anchorTx *AnchorTransaction, vPkt *tappsbt.VPacket,
588-
outIndex int) (*proof.TransitionParams, error) {
608+
outIndex int,
609+
allAnchoredVPackets []*tappsbt.VPacket) (*proof.TransitionParams, error) {
589610

590611
outputCommitments := anchorTx.OutputCommitments
591612

@@ -594,6 +615,13 @@ func proofParams(anchorTx *AnchorTransaction, vPkt *tappsbt.VPacket,
594615
return nil, err
595616
}
596617

618+
allVirtualOutputs := append([]*tappsbt.VOutput{}, vPkt.Outputs...)
619+
for _, otherVPkt := range allAnchoredVPackets {
620+
allVirtualOutputs = append(
621+
allVirtualOutputs, otherVPkt.Outputs...,
622+
)
623+
}
624+
597625
// Is this the split root? Then we need exclusion proofs from all the
598626
// split outputs. We can also use this path for interactive full value
599627
// send case, where we also just commit to an asset that has a TX
@@ -612,11 +640,8 @@ func proofParams(anchorTx *AnchorTransaction, vPkt *tappsbt.VPacket,
612640

613641
// Add exclusion proofs for all the other outputs.
614642
err = addOtherOutputExclusionProofs(
615-
vPkt.Outputs, rootOut.Asset, rootParams,
643+
allVirtualOutputs, rootOut.Asset, rootParams,
616644
outputCommitments,
617-
func(i int, _ *tappsbt.VOutput) bool {
618-
return i == outIndex
619-
},
620645
)
621646
if err != nil {
622647
return nil, err
@@ -668,16 +693,8 @@ func proofParams(anchorTx *AnchorTransaction, vPkt *tappsbt.VPacket,
668693

669694
// Add exclusion proofs for all the other outputs.
670695
err = addOtherOutputExclusionProofs(
671-
vPkt.Outputs, splitOut.Asset, splitParams, outputCommitments,
672-
func(i int, vOut *tappsbt.VOutput) bool {
673-
// We don't need exclusion proofs for:
674-
// - The split output itself.
675-
// - The split root output.
676-
// - Any output that is committed to the same
677-
// anchor output as our split output.
678-
return i == outIndex || vOut == splitRootOut ||
679-
vOut.AnchorOutputIndex == splitIndex
680-
},
696+
allVirtualOutputs, splitOut.Asset, splitParams,
697+
outputCommitments,
681698
)
682699
if err != nil {
683700
return nil, err
@@ -691,14 +708,14 @@ func proofParams(anchorTx *AnchorTransaction, vPkt *tappsbt.VPacket,
691708
// return false for not yet processed outputs, otherwise they'll be skipped).
692709
func addOtherOutputExclusionProofs(outputs []*tappsbt.VOutput,
693710
asset *asset.Asset, params *proof.TransitionParams,
694-
outputCommitments map[uint32]*commitment.TapCommitment,
695-
skip func(int, *tappsbt.VOutput) bool) error {
711+
outputCommitments map[uint32]*commitment.TapCommitment) error {
696712

697713
for idx := range outputs {
698714
vOut := outputs[idx]
699715

700-
haveProof := params.HaveExclusionProof(vOut.AnchorOutputIndex)
701-
if skip(idx, vOut) || haveProof {
716+
haveIProof := params.HaveInclusionProof(vOut.AnchorOutputIndex)
717+
haveEProof := params.HaveExclusionProof(vOut.AnchorOutputIndex)
718+
if haveIProof || haveEProof {
702719
continue
703720
}
704721

@@ -772,9 +789,7 @@ func (s *sendPackage) createReAnchorProof(
772789
// BTC level outputs.
773790
err = addOtherOutputExclusionProofs(
774791
s.VirtualPacket.Outputs, passiveOut.Asset, passiveParams,
775-
outputCommitments, func(i int, vOut *tappsbt.VOutput) bool {
776-
return vOut.AnchorOutputIndex == passiveOutputIndex
777-
},
792+
outputCommitments,
778793
)
779794
if err != nil {
780795
return nil, err

0 commit comments

Comments
 (0)