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

Commit e2b4628

Browse files
committed
Adjust TipManager to receive a CommitteeInSlot retriever and wire up events to start tracking of validators in TipManager
1 parent f8e0172 commit e2b4628

File tree

5 files changed

+75
-36
lines changed

5 files changed

+75
-36
lines changed

pkg/protocol/engine/tipmanager/tests/testframework.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ import (
77
"github.com/stretchr/testify/require"
88

99
"github.com/iotaledger/hive.go/ds"
10+
"github.com/iotaledger/hive.go/kvstore/mapdb"
1011
"github.com/iotaledger/hive.go/lo"
12+
"github.com/iotaledger/iota-core/pkg/core/account"
1113
"github.com/iotaledger/iota-core/pkg/model"
1214
"github.com/iotaledger/iota-core/pkg/protocol/engine/blocks"
1315
"github.com/iotaledger/iota-core/pkg/protocol/engine/tipmanager"
1416
tipmanagerv1 "github.com/iotaledger/iota-core/pkg/protocol/engine/tipmanager/v1"
17+
"github.com/iotaledger/iota-core/pkg/protocol/sybilprotection/seatmanager/mock"
18+
"github.com/iotaledger/iota-core/pkg/storage/prunable/epochstore"
1519
iotago "github.com/iotaledger/iota.go/v4"
1620
"github.com/iotaledger/iota.go/v4/builder"
1721
"github.com/iotaledger/iota.go/v4/tpkg"
@@ -23,10 +27,11 @@ type TestFramework struct {
2327
blockIDsByAlias map[string]iotago.BlockID
2428
tipMetadataByAlias map[string]tipmanager.TipMetadata
2529
blocksByID map[iotago.BlockID]*blocks.Block
26-
validatorByAlias map[string]iotago.AccountID
2730
test *testing.T
2831
time time.Time
2932

33+
manualPOA mock.ManualPOA
34+
3035
API iotago.API
3136
}
3237

@@ -35,36 +40,42 @@ func NewTestFramework(test *testing.T) *TestFramework {
3540
blockIDsByAlias: make(map[string]iotago.BlockID),
3641
tipMetadataByAlias: make(map[string]tipmanager.TipMetadata),
3742
blocksByID: make(map[iotago.BlockID]*blocks.Block),
38-
validatorByAlias: make(map[string]iotago.AccountID),
3943
test: test,
4044
API: tpkg.ZeroCostTestAPI,
4145
time: time.Now(),
46+
manualPOA: *mock.NewManualPOA(iotago.SingleVersionProvider(tpkg.ZeroCostTestAPI),
47+
epochstore.NewStore[*account.Accounts](
48+
nil,
49+
mapdb.NewMapDB(),
50+
func(index iotago.EpochIndex) iotago.EpochIndex { return index },
51+
(*account.Accounts).Bytes,
52+
account.AccountsFromBytes),
53+
),
4254
}
4355

4456
t.blockIDsByAlias["Genesis"] = iotago.EmptyBlockID
4557

4658
t.Instance = tipmanagerv1.New(func(blockID iotago.BlockID) (block *blocks.Block, exists bool) {
4759
block, exists = t.blocksByID[blockID]
4860
return block, exists
49-
})
61+
}, t.manualPOA.CommitteeInSlot)
5062

5163
return t
5264
}
5365

5466
func (t *TestFramework) Validator(alias string) iotago.AccountID {
55-
validator, validatorExists := t.validatorByAlias[alias]
56-
require.True(t.test, validatorExists)
57-
58-
return validator
67+
return t.manualPOA.AccountID(alias)
5968
}
6069

6170
func (t *TestFramework) AddValidator(alias string) {
62-
accountID := iotago.AccountID(tpkg.Rand32ByteArray())
63-
accountID.RegisterAlias(alias)
71+
t.manualPOA.AddRandomAccount(alias)
6472

65-
t.validatorByAlias[alias] = accountID
73+
seat, exists := t.manualPOA.GetSeat(alias)
74+
if !exists {
75+
panic("seat does not exist")
76+
}
6677

67-
t.Instance.AddValidator(accountID)
78+
t.Instance.AddSeat(seat)
6879
}
6980

7081
func (t *TestFramework) AddBlock(alias string) tipmanager.TipMetadata {

pkg/protocol/engine/tipmanager/tipmanager.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package tipmanager
22

33
import (
44
"github.com/iotaledger/hive.go/runtime/module"
5+
"github.com/iotaledger/iota-core/pkg/core/account"
56
"github.com/iotaledger/iota-core/pkg/protocol/engine/blocks"
67
iotago "github.com/iotaledger/iota.go/v4"
78
)
@@ -27,11 +28,11 @@ type TipManager interface {
2728
// OnBlockAdded registers a callback that is triggered whenever a new Block was added to the TipManager.
2829
OnBlockAdded(handler func(block TipMetadata)) (unsubscribe func())
2930

30-
// AddValidator adds a validator to the tracking of the TipManager.
31-
AddValidator(accountID iotago.AccountID) (added bool)
31+
// AddSeat adds a validator seat to the tracking of the TipManager.
32+
AddSeat(seat account.SeatIndex)
3233

33-
// RemoveValidator removes a validator from the tracking of the TipManager.
34-
RemoveValidator(accountID iotago.AccountID) (removed bool)
34+
// RemoveSeat removes a validator seat from the tracking of the TipManager.
35+
RemoveSeat(seat account.SeatIndex)
3536

3637
// ValidationTips returns the validation tips of the TipManager (with an optional limit).
3738
ValidationTips(optAmount ...int) []TipMetadata

pkg/protocol/engine/tipmanager/v1/provider.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,29 @@ import (
55
"github.com/iotaledger/hive.go/runtime/event"
66
"github.com/iotaledger/hive.go/runtime/module"
77
"github.com/iotaledger/hive.go/runtime/workerpool"
8+
"github.com/iotaledger/iota-core/pkg/core/account"
89
"github.com/iotaledger/iota-core/pkg/protocol/engine"
910
"github.com/iotaledger/iota-core/pkg/protocol/engine/tipmanager"
11+
iotago "github.com/iotaledger/iota.go/v4"
1012
)
1113

1214
// NewProvider creates a new TipManager provider, that can be used to inject the component into an engine.
1315
func NewProvider() module.Provider[*engine.Engine, tipmanager.TipManager] {
1416
return module.Provide(func(e *engine.Engine) tipmanager.TipManager {
15-
t := New(e.BlockCache.Block)
17+
t := New(e.BlockCache.Block, e.SybilProtection.SeatManager().CommitteeInSlot)
1618

1719
e.Constructed.OnTrigger(func() {
1820
tipWorker := e.Workers.CreatePool("AddTip", workerpool.WithWorkerCount(2))
21+
1922
e.Events.Scheduler.BlockScheduled.Hook(lo.Void(t.AddBlock), event.WithWorkerPool(tipWorker))
2023
e.Events.Scheduler.BlockSkipped.Hook(lo.Void(t.AddBlock), event.WithWorkerPool(tipWorker))
2124
e.BlockCache.Evict.Hook(t.Evict)
2225

26+
e.Events.SeatManager.OnlineCommitteeSeatAdded.Hook(func(index account.SeatIndex, _ iotago.AccountID) {
27+
t.AddSeat(index)
28+
})
29+
e.Events.SeatManager.OnlineCommitteeSeatRemoved.Hook(t.RemoveSeat)
30+
2331
e.Events.TipManager.BlockAdded.LinkTo(t.blockAdded)
2432

2533
t.TriggerInitialized()

pkg/protocol/engine/tipmanager/v1/tipmanager.go

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/iotaledger/hive.go/runtime/event"
1111
"github.com/iotaledger/hive.go/runtime/module"
1212
"github.com/iotaledger/hive.go/runtime/syncutils"
13+
"github.com/iotaledger/iota-core/pkg/core/account"
1314
"github.com/iotaledger/iota-core/pkg/protocol/engine/blocks"
1415
"github.com/iotaledger/iota-core/pkg/protocol/engine/tipmanager"
1516
iotago "github.com/iotaledger/iota.go/v4"
@@ -20,11 +21,14 @@ type TipManager struct {
2021
// retrieveBlock is a function that retrieves a Block from the Tangle.
2122
retrieveBlock func(blockID iotago.BlockID) (block *blocks.Block, exists bool)
2223

24+
// retrieveCommitteeInSlot is a function that retrieves the committee in a given slot.
25+
retrieveCommitteeInSlot func(slot iotago.SlotIndex) (*account.SeatedAccounts, bool)
26+
2327
// tipMetadataStorage contains the TipMetadata of all Blocks that are managed by the TipManager.
2428
tipMetadataStorage *shrinkingmap.ShrinkingMap[iotago.SlotIndex, *shrinkingmap.ShrinkingMap[iotago.BlockID, *TipMetadata]]
2529

2630
// latestValidatorBlocks contains a Variable for each validator that stores the latest validator block.
27-
latestValidatorBlocks *shrinkingmap.ShrinkingMap[iotago.AccountID, reactive.Variable[*TipMetadata]]
31+
latestValidatorBlocks *shrinkingmap.ShrinkingMap[account.SeatIndex, reactive.Variable[*TipMetadata]]
2832

2933
// validatorTipSet contains the subset of blocks from the strong tip set that reference the latest validator block.
3034
validatorTipSet *randommap.RandomMap[iotago.BlockID, *TipMetadata]
@@ -49,15 +53,19 @@ type TipManager struct {
4953
}
5054

5155
// New creates a new TipManager.
52-
func New(blockRetriever func(blockID iotago.BlockID) (block *blocks.Block, exists bool)) *TipManager {
56+
func New(
57+
blockRetriever func(blockID iotago.BlockID) (block *blocks.Block, exists bool),
58+
retrieveCommitteeInSlot func(slot iotago.SlotIndex) (*account.SeatedAccounts, bool),
59+
) *TipManager {
5360
t := &TipManager{
54-
retrieveBlock: blockRetriever,
55-
tipMetadataStorage: shrinkingmap.New[iotago.SlotIndex, *shrinkingmap.ShrinkingMap[iotago.BlockID, *TipMetadata]](),
56-
latestValidatorBlocks: shrinkingmap.New[iotago.AccountID, reactive.Variable[*TipMetadata]](),
57-
validatorTipSet: randommap.New[iotago.BlockID, *TipMetadata](),
58-
strongTipSet: randommap.New[iotago.BlockID, *TipMetadata](),
59-
weakTipSet: randommap.New[iotago.BlockID, *TipMetadata](),
60-
blockAdded: event.New1[tipmanager.TipMetadata](),
61+
retrieveBlock: blockRetriever,
62+
retrieveCommitteeInSlot: retrieveCommitteeInSlot,
63+
tipMetadataStorage: shrinkingmap.New[iotago.SlotIndex, *shrinkingmap.ShrinkingMap[iotago.BlockID, *TipMetadata]](),
64+
latestValidatorBlocks: shrinkingmap.New[account.SeatIndex, reactive.Variable[*TipMetadata]](),
65+
validatorTipSet: randommap.New[iotago.BlockID, *TipMetadata](),
66+
strongTipSet: randommap.New[iotago.BlockID, *TipMetadata](),
67+
weakTipSet: randommap.New[iotago.BlockID, *TipMetadata](),
68+
blockAdded: event.New1[tipmanager.TipMetadata](),
6169
}
6270

6371
t.TriggerConstructed()
@@ -89,23 +97,20 @@ func (t *TipManager) OnBlockAdded(handler func(block tipmanager.TipMetadata)) (u
8997
return t.blockAdded.Hook(handler).Unhook
9098
}
9199

92-
// AddValidator adds a validator to the tracking of the TipManager.
93-
func (t *TipManager) AddValidator(accountID iotago.AccountID) (added bool) {
94-
_, added = t.latestValidatorBlocks.GetOrCreate(accountID, func() reactive.Variable[*TipMetadata] {
100+
// AddSeat adds a validator to the tracking of the TipManager.
101+
func (t *TipManager) AddSeat(seat account.SeatIndex) {
102+
t.latestValidatorBlocks.GetOrCreate(seat, func() reactive.Variable[*TipMetadata] {
95103
return reactive.NewVariable[*TipMetadata]()
96104
})
97-
98-
return added
99105
}
100106

101-
// RemoveValidator removes a validator from the tracking of the TipManager.
102-
func (t *TipManager) RemoveValidator(accountID iotago.AccountID) (removed bool) {
103-
latestValidatorBlock, removed := t.latestValidatorBlocks.DeleteAndReturn(accountID)
107+
// RemoveSeat removes a validator from the tracking of the TipManager.
108+
func (t *TipManager) RemoveSeat(seat account.SeatIndex) {
109+
latestValidatorBlock, removed := t.latestValidatorBlocks.DeleteAndReturn(seat)
104110
if removed {
105111
latestValidatorBlock.Set(nil)
106112
}
107113

108-
return removed
109114
}
110115

111116
func (t *TipManager) ValidationTips(optAmount ...int) []tipmanager.TipMetadata {
@@ -200,8 +205,18 @@ func (t *TipManager) trackLatestValidatorBlock(tipMetadata *TipMetadata) (teardo
200205
return
201206
}
202207

203-
// We only track the validation blocks of validators that are tracked by the TipManager (via AddValidator).
204-
latestValidatorBlock, exists := t.latestValidatorBlocks.Get(tipMetadata.Block().ProtocolBlock().Header.IssuerID)
208+
committee, exists := t.retrieveCommitteeInSlot(tipMetadata.Block().ID().Slot())
209+
if !exists {
210+
return
211+
}
212+
213+
seat, exists := committee.GetSeat(tipMetadata.Block().ProtocolBlock().Header.IssuerID)
214+
if !exists {
215+
return
216+
}
217+
218+
// We only track the validation blocks of validators that are tracked by the TipManager (via AddSeat).
219+
latestValidatorBlock, exists := t.latestValidatorBlocks.Get(seat)
205220
if !exists {
206221
return
207222
}

pkg/protocol/sybilprotection/seatmanager/mock/mockseatmanager.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ func (m *ManualPOA) AccountID(alias string) iotago.AccountID {
108108
return id
109109
}
110110

111+
func (m *ManualPOA) GetSeat(alias string) (account.SeatIndex, bool) {
112+
return m.committee.GetSeat(m.AccountID(alias))
113+
}
114+
111115
func (m *ManualPOA) SetOnline(aliases ...string) {
112116
for _, alias := range aliases {
113117
seat, exists := m.committee.GetSeat(m.AccountID(alias))

0 commit comments

Comments
 (0)