@@ -486,19 +486,13 @@ func DistributeCoins(inputs []*proof.Proof, allocations []*Allocation,
486486 // We group the assets by asset ID, since we'll want to create a single
487487 // virtual packet per asset ID (with each virtual packet potentially
488488 // having multiple inputs and outputs).
489- assetIDs := fn .Map (inputs , func (input * proof.Proof ) asset.ID {
490- return input .Asset .ID ()
491- })
492- uniqueAssetIDs := fn .NewSet (assetIDs ... ).ToSlice ()
489+ groupedProofs := GroupProofsByAssetID (inputs )
493490
494491 // Each "piece" keeps track of how many assets of a specific asset ID
495492 // we have already distributed. The pieces are also the main way to
496493 // reference an asset ID's virtual packet.
497- pieces := make ([]* piece , len (uniqueAssetIDs ))
498- for i , assetID := range uniqueAssetIDs {
499- proofsByID := fn .Filter (inputs , func (i * proof.Proof ) bool {
500- return i .Asset .ID () == assetID
501- })
494+ pieces := make ([]* piece , 0 , len (groupedProofs ))
495+ for assetID , proofsByID := range groupedProofs {
502496 sumByID := fn .Reduce (
503497 proofsByID , func (sum uint64 , i * proof.Proof ) uint64 {
504498 return sum + i .Asset .Amount
@@ -512,12 +506,12 @@ func DistributeCoins(inputs []*proof.Proof, allocations []*Allocation,
512506 return nil , err
513507 }
514508
515- pieces [ i ] = & piece {
509+ pieces = append ( pieces , & piece {
516510 assetID : assetID ,
517511 totalAvailable : sumByID ,
518512 proofs : proofsByID ,
519513 packet : pkt ,
520- }
514+ })
521515 }
522516
523517 // Make sure the pieces are in a stable and reproducible order before we
@@ -840,3 +834,22 @@ func setAllocationFieldsFromOutput(alloc *Allocation, vOut *tappsbt.VOutput) {
840834 alloc .AltLeaves = vOut .AltLeaves
841835 alloc .SiblingPreimage = vOut .AnchorOutputTapscriptSibling
842836}
837+
838+ // GroupProofsByAssetID groups the given proofs by their asset ID.
839+ func GroupProofsByAssetID (proofs []* proof.Proof ) map [asset.ID ][]* proof.Proof {
840+ assetIDs := fn .Map (proofs , func (p * proof.Proof ) asset.ID {
841+ return p .Asset .ID ()
842+ })
843+ uniqueAssetIDs := fn .NewSet (assetIDs ... ).ToSlice ()
844+
845+ groupedProofs := make (map [asset.ID ][]* proof.Proof , len (uniqueAssetIDs ))
846+ for _ , assetID := range uniqueAssetIDs {
847+ groupedProofs [assetID ] = fn .Filter (
848+ proofs , func (p * proof.Proof ) bool {
849+ return p .Asset .ID () == assetID
850+ },
851+ )
852+ }
853+
854+ return groupedProofs
855+ }
0 commit comments