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

Commit e0e827a

Browse files
Merge pull request #640 from iotaledger/feat/activity-window
Activity Window from Protocol Parameters
2 parents 52146a2 + d2653c4 commit e0e827a

File tree

19 files changed

+82
-113
lines changed

19 files changed

+82
-113
lines changed

pkg/core/account/accounts.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ func (a *Accounts) ForEach(callback func(id iotago.AccountID, pool *Pool) bool)
125125
a.accountPools.ForEach(callback)
126126
}
127127

128-
// SelectCommittee creates a new SeatedAccounts instance, that maintains the seats of the given members.
129-
func (a *Accounts) SelectCommittee(members ...iotago.AccountID) *SeatedAccounts {
128+
// SeatedAccounts creates a new SeatedAccounts instance, that maintains the seats of the given members.
129+
func (a *Accounts) SeatedAccounts(members ...iotago.AccountID) *SeatedAccounts {
130130
return NewSeatedAccounts(a, members...)
131131
}
132132

pkg/core/account/accounts_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,11 @@ func TestAccounts(t *testing.T) {
108108
// check "SelectCommittee"
109109

110110
// get 1 issuer
111-
seated := accounts.SelectCommittee(accountIDs[0])
111+
seated := accounts.SeatedAccounts(accountIDs[0])
112112
require.Equal(t, 1, seated.SeatCount())
113113

114114
// get all issuers
115-
seated = accounts.SelectCommittee(accountIDs...)
115+
seated = accounts.SeatedAccounts(accountIDs...)
116116
require.Equal(t, len(accountIDs), seated.SeatCount())
117117

118118
/*

pkg/protocol/engine/attestation/slotattestation/testframework_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func NewTestFramework(test *testing.T) *TestFramework {
6666
members = append(members, issuer.accountID)
6767
return true
6868
})
69-
return accounts.SelectCommittee(members...), true
69+
return accounts.SeatedAccounts(members...), true
7070
}
7171

7272
t.testAPI = iotago.V3API(

pkg/protocol/engine/mempool/spenddag/tests/accounts_framework.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type AccountsTestFramework struct {
2121
func NewAccountsTestFramework(test *testing.T, instance *account.Accounts) *AccountsTestFramework {
2222
return &AccountsTestFramework{
2323
Instance: instance,
24-
Committee: instance.SelectCommittee(),
24+
Committee: instance.SeatedAccounts(),
2525

2626
test: test,
2727
identitiesByAlias: make(map[string]iotago.AccountID),

pkg/protocol/engine/mempool/v1/mempool_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func newTestFramework(t *testing.T) *mempooltests.TestFramework {
141141
workers := workerpool.NewGroup(t.Name())
142142

143143
ledgerState := ledgertests.New(ledgertests.NewMockedState(iotago.EmptyTransactionID, 0))
144-
spendDAG := spenddagv1.New[iotago.TransactionID, mempool.StateID, vote.MockedRank](account.NewAccounts().SelectCommittee().SeatCount)
144+
spendDAG := spenddagv1.New[iotago.TransactionID, mempool.StateID, vote.MockedRank](account.NewAccounts().SeatedAccounts().SeatCount)
145145

146146
mutationsFunc := func(index iotago.SlotIndex) (kvstore.KVStore, error) {
147147
return mapdb.NewMapDB(), nil

pkg/protocol/sybilprotection/activitytracker/activitytrackerv1/activitytracker.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ type ActivityTracker struct {
2222
lastActivityTime time.Time
2323
activityMutex syncutils.RWMutex
2424

25-
activityWindow time.Duration
25+
apiProvider iotago.APIProvider
2626
}
2727

28-
func NewActivityTracker(activityWindow time.Duration) *ActivityTracker {
28+
func NewActivityTracker(apiProvider iotago.APIProvider) *ActivityTracker {
2929
return &ActivityTracker{
3030
Events: activitytracker.NewEvents(),
3131
onlineCommittee: ds.NewSet[account.SeatIndex](),
3232
inactivityQueue: timed.NewPriorityQueue[account.SeatIndex](true),
3333
lastActivities: shrinkingmap.New[account.SeatIndex, time.Time](),
3434

35-
activityWindow: activityWindow,
35+
apiProvider: apiProvider,
3636
}
3737
}
3838

@@ -48,7 +48,10 @@ func (a *ActivityTracker) MarkSeatActive(seat account.SeatIndex, id iotago.Accou
4848
a.activityMutex.Lock()
4949
defer a.activityMutex.Unlock()
5050

51-
if lastActivity, exists := a.lastActivities.Get(seat); (exists && lastActivity.After(seatActivityTime)) || seatActivityTime.Before(a.lastActivityTime.Add(-a.activityWindow)) {
51+
// activity window is given by min committable age in seconds from the protocol parameters
52+
protocolParams := a.apiProvider.APIForTime(seatActivityTime).ProtocolParameters()
53+
activityWindow := time.Duration(protocolParams.MinCommittableAge()*iotago.SlotIndex(protocolParams.SlotDurationInSeconds())) * time.Second
54+
if lastActivity, exists := a.lastActivities.Get(seat); (exists && lastActivity.After(seatActivityTime)) || seatActivityTime.Before(a.lastActivityTime.Add(-activityWindow)) {
5255
return
5356
} else if !exists {
5457
a.onlineCommittee.Add(seat)
@@ -65,7 +68,7 @@ func (a *ActivityTracker) MarkSeatActive(seat account.SeatIndex, id iotago.Accou
6568

6669
a.lastActivityTime = seatActivityTime
6770

68-
activityThreshold := seatActivityTime.Add(-a.activityWindow)
71+
activityThreshold := seatActivityTime.Add(-activityWindow)
6972
for _, inactiveSeat := range a.inactivityQueue.PopUntil(activityThreshold) {
7073
if lastActivityForInactiveSeat, exists := a.lastActivities.Get(inactiveSeat); exists && lastActivityForInactiveSeat.After(activityThreshold) {
7174
continue

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func NewManualPOA(e iotago.APIProvider, committeeStore *epochstore.Store[*accoun
4040
online: ds.NewSet[account.SeatIndex](),
4141
aliases: shrinkingmap.New[string, iotago.AccountID](),
4242
}
43-
m.committee = m.accounts.SelectCommittee()
43+
m.committee = m.accounts.SeatedAccounts()
4444

4545
return m
4646
}
@@ -71,7 +71,7 @@ func (m *ManualPOA) AddRandomAccount(alias string) iotago.AccountID {
7171

7272
m.aliases.Set(alias, id)
7373

74-
m.committee = m.accounts.SelectCommittee(m.accounts.IDs()...)
74+
m.committee = m.accounts.SeatedAccounts(m.accounts.IDs()...)
7575

7676
if err := m.committeeStore.Store(0, m.accounts); err != nil {
7777
panic(err)
@@ -90,7 +90,7 @@ func (m *ManualPOA) AddAccount(id iotago.AccountID, alias string) iotago.Account
9090
}
9191
m.aliases.Set(alias, id)
9292

93-
m.committee = m.accounts.SelectCommittee(m.accounts.IDs()...)
93+
m.committee = m.accounts.SeatedAccounts(m.accounts.IDs()...)
9494

9595
if err := m.committeeStore.Store(0, m.accounts); err != nil {
9696
panic(err)
@@ -152,7 +152,7 @@ func (m *ManualPOA) committeeInEpoch(epoch iotago.EpochIndex) (*account.SeatedAc
152152
return nil, false
153153
}
154154

155-
return c.SelectCommittee(c.IDs()...), true
155+
return c.SeatedAccounts(c.IDs()...), true
156156
}
157157

158158
func (m *ManualPOA) OnlineCommittee() ds.Set[account.SeatIndex] {
@@ -179,7 +179,7 @@ func (m *ManualPOA) RotateCommittee(epoch iotago.EpochIndex, validators accounts
179179
return nil, ierrors.Wrapf(err, "error while setting pool for epoch %d for validator %s", epoch, validatorData.ID.String())
180180
}
181181
}
182-
m.committee = m.accounts.SelectCommittee(m.accounts.IDs()...)
182+
m.committee = m.accounts.SeatedAccounts(m.accounts.IDs()...)
183183
}
184184

185185
if err := m.committeeStore.Store(epoch, m.accounts); err != nil {
@@ -189,10 +189,10 @@ func (m *ManualPOA) RotateCommittee(epoch iotago.EpochIndex, validators accounts
189189
return m.committee, nil
190190
}
191191

192-
func (m *ManualPOA) SetCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error {
192+
func (m *ManualPOA) ReuseCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error {
193193
if m.committee == nil || m.accounts.Size() == 0 {
194194
m.accounts = validators
195-
m.committee = m.accounts.SelectCommittee(validators.IDs()...)
195+
m.committee = m.accounts.SeatedAccounts(validators.IDs()...)
196196
}
197197

198198
if err := m.committeeStore.Store(epoch, validators); err != nil {

pkg/protocol/sybilprotection/seatmanager/poa/options.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
package poa
22

33
import (
4-
"time"
5-
64
"github.com/iotaledger/hive.go/runtime/options"
75
iotago "github.com/iotaledger/iota.go/v4"
86
)
97

10-
// WithActivityWindow sets the duration for which a validator is recognized as active after issuing a block.
11-
func WithActivityWindow(activityWindow time.Duration) options.Option[SeatManager] {
12-
return func(p *SeatManager) {
13-
p.optsActivityWindow = activityWindow
14-
}
15-
}
16-
178
func WithOnlineCommitteeStartup(optsOnlineCommittee ...iotago.AccountID) options.Option[SeatManager] {
189
return func(p *SeatManager) {
1910
p.optsOnlineCommitteeStartup = optsOnlineCommittee

pkg/protocol/sybilprotection/seatmanager/poa/poa.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ type SeatManager struct {
3030

3131
committeeMutex syncutils.RWMutex
3232

33-
optsActivityWindow time.Duration
3433
optsOnlineCommitteeStartup []iotago.AccountID
3534

3635
module.Module
@@ -44,10 +43,8 @@ func NewProvider(opts ...options.Option[SeatManager]) module.Provider[*engine.En
4443
events: seatmanager.NewEvents(),
4544
apiProvider: e,
4645
committeeStore: e.Storage.Committee(),
47-
48-
optsActivityWindow: time.Second * 30,
4946
}, opts, func(s *SeatManager) {
50-
activityTracker := activitytrackerv1.NewActivityTracker(s.optsActivityWindow)
47+
activityTracker := activitytrackerv1.NewActivityTracker(e)
5148
s.activityTracker = activityTracker
5249
s.events.OnlineCommitteeSeatAdded.LinkTo(activityTracker.Events.OnlineCommitteeSeatAdded)
5350
s.events.OnlineCommitteeSeatRemoved.LinkTo(activityTracker.Events.OnlineCommitteeSeatRemoved)
@@ -97,7 +94,7 @@ func (s *SeatManager) RotateCommittee(epoch iotago.EpochIndex, validators accoun
9794
return nil, ierrors.Wrapf(err, "error while setting committee for epoch %d for validator %s", epoch, validatorData.ID.String())
9895
}
9996
}
100-
s.committee = committeeAccounts.SelectCommittee(committeeAccounts.IDs()...)
97+
s.committee = committeeAccounts.SeatedAccounts(committeeAccounts.IDs()...)
10198
}
10299

103100
accounts, err := s.committee.Accounts()
@@ -138,7 +135,7 @@ func (s *SeatManager) committeeInEpoch(epoch iotago.EpochIndex) (*account.Seated
138135
return nil, false
139136
}
140137

141-
return c.SelectCommittee(c.IDs()...), true
138+
return c.SeatedAccounts(c.IDs()...), true
142139
}
143140

144141
// OnlineCommittee returns the set of validators selected to be part of the committee that has been seen recently.
@@ -174,7 +171,7 @@ func (s *SeatManager) InitializeCommittee(epoch iotago.EpochIndex, activityTime
174171
}
175172

176173
committeeAccountsIDs := committeeAccounts.IDs()
177-
s.committee = committeeAccounts.SelectCommittee(committeeAccountsIDs...)
174+
s.committee = committeeAccounts.SeatedAccounts(committeeAccountsIDs...)
178175

179176
// Set validators that are part of the committee as active.
180177
onlineValidators := committeeAccountsIDs
@@ -195,11 +192,11 @@ func (s *SeatManager) InitializeCommittee(epoch iotago.EpochIndex, activityTime
195192
return nil
196193
}
197194

198-
func (s *SeatManager) SetCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error {
195+
func (s *SeatManager) ReuseCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error {
199196
s.committeeMutex.Lock()
200197
defer s.committeeMutex.Unlock()
201198

202-
s.committee = validators.SelectCommittee(validators.IDs()...)
199+
s.committee = validators.SeatedAccounts(validators.IDs()...)
203200

204201
accounts, err := s.committee.Accounts()
205202
if err != nil {

pkg/protocol/sybilprotection/seatmanager/seatmanager.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ type SeatManager interface {
1515
// RotateCommittee rotates the committee evaluating the given set of candidates to produce the new committee.
1616
RotateCommittee(epoch iotago.EpochIndex, candidates accounts.AccountsData) (*account.SeatedAccounts, error)
1717

18-
// SetCommittee sets the committee for a given slot.
19-
// This is used when re-using the same committee for consecutive epochs.
20-
SetCommittee(epoch iotago.EpochIndex, committee *account.Accounts) error
18+
// ReuseCommittee reuses the committee from a previous epoch.
19+
ReuseCommittee(epoch iotago.EpochIndex, committee *account.Accounts) error
2120

2221
// InitializeCommittee initializes the committee for the current slot by marking whole or a subset of the committee as active.
2322
// This is used when initializing committee after node startup (loaded from snapshot or database).

0 commit comments

Comments
 (0)