@@ -486,19 +486,14 @@ 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 , len (groupedProofs ))
495+ var idx int
496+ for assetID , proofsByID := range groupedProofs {
502497 sumByID := fn .Reduce (
503498 proofsByID , func (sum uint64 , i * proof.Proof ) uint64 {
504499 return sum + i .Asset .Amount
@@ -512,12 +507,13 @@ func DistributeCoins(inputs []*proof.Proof, allocations []*Allocation,
512507 return nil , err
513508 }
514509
515- pieces [i ] = & piece {
510+ pieces [idx ] = & piece {
516511 assetID : assetID ,
517512 totalAvailable : sumByID ,
518513 proofs : proofsByID ,
519514 packet : pkt ,
520515 }
516+ idx ++
521517 }
522518
523519 // Make sure the pieces are in a stable and reproducible order before we
@@ -840,3 +836,22 @@ func setAllocationFieldsFromOutput(alloc *Allocation, vOut *tappsbt.VOutput) {
840836 alloc .AltLeaves = vOut .AltLeaves
841837 alloc .SiblingPreimage = vOut .AnchorOutputTapscriptSibling
842838}
839+
840+ // GroupProofsByAssetID groups the given proofs by their asset ID.
841+ func GroupProofsByAssetID (proofs []* proof.Proof ) map [asset.ID ][]* proof.Proof {
842+ assetIDs := fn .Map (proofs , func (p * proof.Proof ) asset.ID {
843+ return p .Asset .ID ()
844+ })
845+ uniqueAssetIDs := fn .NewSet (assetIDs ... ).ToSlice ()
846+
847+ groupedProofs := make (map [asset.ID ][]* proof.Proof , len (uniqueAssetIDs ))
848+ for _ , assetID := range uniqueAssetIDs {
849+ groupedProofs [assetID ] = fn .Filter (
850+ proofs , func (p * proof.Proof ) bool {
851+ return p .Asset .ID () == assetID
852+ },
853+ )
854+ }
855+
856+ return groupedProofs
857+ }
0 commit comments