package sweep // bucket contains a set of inputs that are not mutually exclusive. type bucket pendingInputs // tryAdd tries to add a new input to this bucket. func (b bucket) tryAdd(input *pendingInput) bool { exclusiveGroup := input.params.ExclusiveGroup if exclusiveGroup != nil { for _, input := range b { existingGroup := input.params.ExclusiveGroup // Don't add an exclusive group input if other inputs // are non-exclusive. The exclusive group input may be // invalid (for example in the case of commitment // anchors) and could thereby block sweeping of the // other inputs. if existingGroup == nil { return false } // Don't combine inputs from the same exclusive group. // Because only one input is valid, this may result in // txes that are always invalid. if *existingGroup == *exclusiveGroup { return false } } } b[*input.OutPoint()] = input return true } // bucketList is a list of buckets that contain non-mutually exclusive inputs. type bucketList struct { buckets []bucket } // add adds a new input. If the input is not accepted by any of the existing // buckets, a new bucket will be created. func (b *bucketList) add(input *pendingInput) { for _, existingBucket := range b.buckets { if existingBucket.tryAdd(input) { return } } // Create a new bucket and add the input. It is not necessary to check // the return value of tryAdd because it will always succeed on an empty // bucket. newBucket := make(bucket) newBucket.tryAdd(input) b.buckets = append(b.buckets, newBucket) }