Skip to content
This repository was archived by the owner on Jan 24, 2025. It is now read-only.

Commit 7444597

Browse files
committed
Fix tip selection to select correct number of tips
1 parent 650d06f commit 7444597

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

Diff for: pkg/protocol/engine/tipselection/v1/tip_selection.go

+23-7
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ func (t *TipSelection) SelectTips(amount int) (references model.ParentReferences
125125

126126
previousLikedInsteadConflicts = updatedLikedInsteadConflicts
127127
}
128+
}, func() int {
129+
return len(references[iotago.StrongParentType])
128130
},
129131
// We select one validation tip as a strong parent. This is a security step to ensure that the tangle maintains
130132
// acceptance by stitching together validation blocks.
@@ -140,6 +142,8 @@ func (t *TipSelection) SelectTips(amount int) (references model.ParentReferences
140142
} else if !shallowLikesParents.Has(tip.ID()) {
141143
references[iotago.WeakParentType] = append(references[iotago.WeakParentType], tip.ID())
142144
}
145+
}, func() int {
146+
return len(references[iotago.WeakParentType])
143147
}, types.NewTuple[func(optAmount ...int) []tipmanager.TipMetadata, int](t.tipManager.WeakTips, t.optMaxWeakReferences))
144148

145149
return nil
@@ -216,17 +220,17 @@ func (t *TipSelection) likedInsteadReferences(likedConflicts ds.Set[iotago.Trans
216220

217221
// collectReferences collects tips from a tip selector (and calls the callback for each tip) until the number of
218222
// references of the given type is reached.
219-
func (t *TipSelection) collectReferences(callback func(tipmanager.TipMetadata), tipSelectorsAmount ...*types.Tuple[func(optAmount ...int) []tipmanager.TipMetadata, int]) {
223+
func (t *TipSelection) collectReferences(callback func(tipmanager.TipMetadata), referencesCountCallback func() int, tipSelectorsAmount ...*types.Tuple[func(optAmount ...int) []tipmanager.TipMetadata, int]) {
220224
seenTips := ds.NewSet[iotago.BlockID]()
221225

222226
// selectUniqueTips selects 'amount' unique tips from the given tip selector.
223-
selectUniqueTips := func(tipSelector func(optAmount ...int) []tipmanager.TipMetadata, amount int) (uniqueTips []tipmanager.TipMetadata) {
224-
if amount > 0 {
225-
for _, tip := range tipSelector(amount + seenTips.Size()) {
227+
selectUniqueTips := func(tipSelector func(optAmount ...int) []tipmanager.TipMetadata, currentReferencesCount int, targetAmount int) (uniqueTips []tipmanager.TipMetadata) {
228+
if targetAmount > 0 {
229+
for _, tip := range tipSelector(targetAmount + seenTips.Size()) {
226230
if seenTips.Add(tip.ID()) {
227231
uniqueTips = append(uniqueTips, tip)
228232

229-
if len(uniqueTips) == amount {
233+
if currentReferencesCount+len(uniqueTips) == targetAmount {
230234
break
231235
}
232236
}
@@ -238,15 +242,27 @@ func (t *TipSelection) collectReferences(callback func(tipmanager.TipMetadata),
238242

239243
accumulatedTipAmount := 0
240244
// We select the desired number of tips from all given tip selectors, respectively.
241-
for _, tipSelectorAmount := range tipSelectorsAmount {
245+
for i, tipSelectorAmount := range tipSelectorsAmount {
242246
// Make sure we select the total number of unique tips and not just the number of tips from the given tip pool,
243247
// because of how selectUniqueTips works.
244248
accumulatedTipAmount += tipSelectorAmount.B
245249

246-
for tipCandidates := selectUniqueTips(tipSelectorAmount.A, accumulatedTipAmount); len(tipCandidates) != 0; tipCandidates = selectUniqueTips(tipSelectorAmount.A, accumulatedTipAmount) {
250+
tipCandidates := selectUniqueTips(tipSelectorAmount.A, referencesCountCallback(), accumulatedTipAmount)
251+
252+
// We exit the loop in two cases:
253+
// 1. When we've seen all the tips and there are no more unique tips to process (len(tipCandidates) != 0).
254+
// 2. When we've successfully selected the desired number of tips and added them to the references (referencesCountCallback() >= accumulatedTipAmount).
255+
for len(tipCandidates) != 0 {
247256
for _, tip := range tipCandidates {
248257
callback(tip)
249258
}
259+
260+
referencesCount := referencesCountCallback()
261+
if referencesCount >= accumulatedTipAmount {
262+
break
263+
}
264+
265+
tipCandidates = selectUniqueTips(tipSelectorAmount.A, referencesCount, accumulatedTipAmount)
250266
}
251267
}
252268
}

0 commit comments

Comments
 (0)