From ffd444272099bb4c730ea3373aeddfcc7ed47c6d Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 21 Dec 2023 18:39:02 +1300 Subject: [PATCH 1/6] remove activity window param WIP --- .../activitytrackerv1/activitytracker.go | 13 ++-- .../seatmanager/poa/options.go | 9 --- .../sybilprotection/seatmanager/poa/poa.go | 5 +- .../seatmanager/topstakers/options.go | 9 --- .../seatmanager/topstakers/topstakers.go | 7 +- .../seatmanager/topstakers/topstakers_test.go | 13 ++-- pkg/tests/committee_rotation_test.go | 6 +- pkg/tests/confirmation_state_test.go | 2 - pkg/tests/protocol_engine_switching_test.go | 68 +++++++++---------- pkg/tests/upgrade_signaling_test.go | 5 +- pkg/testsuite/testsuite_issue_blocks.go | 9 ++- 11 files changed, 59 insertions(+), 87 deletions(-) diff --git a/pkg/protocol/sybilprotection/activitytracker/activitytrackerv1/activitytracker.go b/pkg/protocol/sybilprotection/activitytracker/activitytrackerv1/activitytracker.go index 9a58b6680..5ab909094 100644 --- a/pkg/protocol/sybilprotection/activitytracker/activitytrackerv1/activitytracker.go +++ b/pkg/protocol/sybilprotection/activitytracker/activitytrackerv1/activitytracker.go @@ -22,17 +22,17 @@ type ActivityTracker struct { lastActivityTime time.Time activityMutex syncutils.RWMutex - activityWindow time.Duration + apiProvider iotago.APIProvider } -func NewActivityTracker(activityWindow time.Duration) *ActivityTracker { +func NewActivityTracker(apiProvider iotago.APIProvider) *ActivityTracker { return &ActivityTracker{ Events: activitytracker.NewEvents(), onlineCommittee: ds.NewSet[account.SeatIndex](), inactivityQueue: timed.NewPriorityQueue[account.SeatIndex](true), lastActivities: shrinkingmap.New[account.SeatIndex, time.Time](), - activityWindow: activityWindow, + apiProvider: apiProvider, } } @@ -48,7 +48,10 @@ func (a *ActivityTracker) MarkSeatActive(seat account.SeatIndex, id iotago.Accou a.activityMutex.Lock() defer a.activityMutex.Unlock() - if lastActivity, exists := a.lastActivities.Get(seat); (exists && lastActivity.After(seatActivityTime)) || seatActivityTime.Before(a.lastActivityTime.Add(-a.activityWindow)) { + // activity window is given by min committable age in seconds from the protocol parameters + protocolParams := a.apiProvider.APIForTime(seatActivityTime).ProtocolParameters() + activityWindow := time.Duration(protocolParams.MinCommittableAge()*iotago.SlotIndex(protocolParams.SlotDurationInSeconds())) * time.Second + if lastActivity, exists := a.lastActivities.Get(seat); (exists && lastActivity.After(seatActivityTime)) || seatActivityTime.Before(a.lastActivityTime.Add(-activityWindow)) { return } else if !exists { a.onlineCommittee.Add(seat) @@ -65,7 +68,7 @@ func (a *ActivityTracker) MarkSeatActive(seat account.SeatIndex, id iotago.Accou a.lastActivityTime = seatActivityTime - activityThreshold := seatActivityTime.Add(-a.activityWindow) + activityThreshold := seatActivityTime.Add(-activityWindow) for _, inactiveSeat := range a.inactivityQueue.PopUntil(activityThreshold) { if lastActivityForInactiveSeat, exists := a.lastActivities.Get(inactiveSeat); exists && lastActivityForInactiveSeat.After(activityThreshold) { continue diff --git a/pkg/protocol/sybilprotection/seatmanager/poa/options.go b/pkg/protocol/sybilprotection/seatmanager/poa/options.go index f4df0547f..dcd04712e 100644 --- a/pkg/protocol/sybilprotection/seatmanager/poa/options.go +++ b/pkg/protocol/sybilprotection/seatmanager/poa/options.go @@ -1,19 +1,10 @@ package poa import ( - "time" - "github.com/iotaledger/hive.go/runtime/options" iotago "github.com/iotaledger/iota.go/v4" ) -// WithActivityWindow sets the duration for which a validator is recognized as active after issuing a block. -func WithActivityWindow(activityWindow time.Duration) options.Option[SeatManager] { - return func(p *SeatManager) { - p.optsActivityWindow = activityWindow - } -} - func WithOnlineCommitteeStartup(optsOnlineCommittee ...iotago.AccountID) options.Option[SeatManager] { return func(p *SeatManager) { p.optsOnlineCommitteeStartup = optsOnlineCommittee diff --git a/pkg/protocol/sybilprotection/seatmanager/poa/poa.go b/pkg/protocol/sybilprotection/seatmanager/poa/poa.go index d211750b6..017846e10 100644 --- a/pkg/protocol/sybilprotection/seatmanager/poa/poa.go +++ b/pkg/protocol/sybilprotection/seatmanager/poa/poa.go @@ -30,7 +30,6 @@ type SeatManager struct { committeeMutex syncutils.RWMutex - optsActivityWindow time.Duration optsOnlineCommitteeStartup []iotago.AccountID module.Module @@ -44,10 +43,8 @@ func NewProvider(opts ...options.Option[SeatManager]) module.Provider[*engine.En events: seatmanager.NewEvents(), apiProvider: e, committeeStore: e.Storage.Committee(), - - optsActivityWindow: time.Second * 30, }, opts, func(s *SeatManager) { - activityTracker := activitytrackerv1.NewActivityTracker(s.optsActivityWindow) + activityTracker := activitytrackerv1.NewActivityTracker(e) s.activityTracker = activityTracker s.events.OnlineCommitteeSeatAdded.LinkTo(activityTracker.Events.OnlineCommitteeSeatAdded) s.events.OnlineCommitteeSeatRemoved.LinkTo(activityTracker.Events.OnlineCommitteeSeatRemoved) diff --git a/pkg/protocol/sybilprotection/seatmanager/topstakers/options.go b/pkg/protocol/sybilprotection/seatmanager/topstakers/options.go index b6d6fffe4..259508152 100644 --- a/pkg/protocol/sybilprotection/seatmanager/topstakers/options.go +++ b/pkg/protocol/sybilprotection/seatmanager/topstakers/options.go @@ -1,19 +1,10 @@ package topstakers import ( - "time" - "github.com/iotaledger/hive.go/runtime/options" iotago "github.com/iotaledger/iota.go/v4" ) -// WithActivityWindow sets the duration for which a validator is recognized as active after issuing a block. -func WithActivityWindow(activityWindow time.Duration) options.Option[SeatManager] { - return func(p *SeatManager) { - p.optsActivityWindow = activityWindow - } -} - func WithOnlineCommitteeStartup(optsOnlineCommittee ...iotago.AccountID) options.Option[SeatManager] { return func(p *SeatManager) { p.optsOnlineCommitteeStartup = optsOnlineCommittee diff --git a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go index cc359e617..5bfabcfbf 100644 --- a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go +++ b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go @@ -2,6 +2,7 @@ package topstakers import ( "bytes" + "fmt" "sort" "time" @@ -31,7 +32,6 @@ type SeatManager struct { committeeMutex syncutils.RWMutex activityTracker activitytracker.ActivityTracker - optsActivityWindow time.Duration optsOnlineCommitteeStartup []iotago.AccountID module.Module @@ -45,10 +45,8 @@ func NewProvider(opts ...options.Option[SeatManager]) module.Provider[*engine.En apiProvider: e, events: seatmanager.NewEvents(), committeeStore: e.Storage.Committee(), - - optsActivityWindow: time.Second * 30, }, opts, func(s *SeatManager) { - activityTracker := activitytrackerv1.NewActivityTracker(s.optsActivityWindow) + activityTracker := activitytrackerv1.NewActivityTracker(e) s.activityTracker = activityTracker s.events.OnlineCommitteeSeatAdded.LinkTo(activityTracker.Events.OnlineCommitteeSeatAdded) s.events.OnlineCommitteeSeatRemoved.LinkTo(activityTracker.Events.OnlineCommitteeSeatRemoved) @@ -165,6 +163,7 @@ func (s *SeatManager) Shutdown() { func (s *SeatManager) InitializeCommittee(epoch iotago.EpochIndex, activityTime time.Time) error { s.committeeMutex.Lock() defer s.committeeMutex.Unlock() + fmt.Println("InitializeCommittee") committeeAccounts, err := s.committeeStore.Load(epoch) if err != nil { diff --git a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go index a45851b45..2cd2add5a 100644 --- a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go +++ b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go @@ -27,14 +27,15 @@ func TestTopStakers_InitializeCommittee(t *testing.T) { iotago.WithTargetCommitteeSize(3), ), ) + testAPIProvider := iotago.SingleVersionProvider(testAPI) committeeStore := epochstore.NewStore(kvstore.Realm{}, mapdb.NewMapDB(), 0, (*account.Accounts).Bytes, account.AccountsFromBytes) topStakersSeatManager := &SeatManager{ - apiProvider: iotago.SingleVersionProvider(testAPI), + apiProvider: testAPIProvider, committeeStore: committeeStore, events: seatmanager.NewEvents(), - activityTracker: activitytrackerv1.NewActivityTracker(time.Second * 30), + activityTracker: activitytrackerv1.NewActivityTracker(testAPIProvider), } // Try setting an empty committee. @@ -79,14 +80,15 @@ func TestTopStakers_RotateCommittee(t *testing.T) { iotago.WithTargetCommitteeSize(10), ), ) + testAPIProvider := iotago.SingleVersionProvider(testAPI) committeeStore := epochstore.NewStore(kvstore.Realm{}, mapdb.NewMapDB(), 0, (*account.Accounts).Bytes, account.AccountsFromBytes) s := &SeatManager{ - apiProvider: iotago.SingleVersionProvider(testAPI), + apiProvider: testAPIProvider, committeeStore: committeeStore, events: seatmanager.NewEvents(), - activityTracker: activitytrackerv1.NewActivityTracker(time.Second * 30), + activityTracker: activitytrackerv1.NewActivityTracker(testAPIProvider), } // Committee should not exist because it was never set. @@ -122,13 +124,14 @@ func TestTopStakers_RotateCommittee(t *testing.T) { assertOnlineCommittee(t, s.OnlineCommittee(), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[0]))) s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[1])), committeeInEpoch0IDs[1], testAPI.TimeProvider().SlotStartTime(2)) + fmt.Println(s.activityTracker.OnlineCommittee().Size()) assertOnlineCommittee(t, s.OnlineCommittee(), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[0])), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[1]))) s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2])), committeeInEpoch0IDs[2], testAPI.TimeProvider().SlotStartTime(3)) assertOnlineCommittee(t, s.OnlineCommittee(), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[0])), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[1])), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2]))) // Make sure that after a period of inactivity, the inactive seats are marked as offline. - s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2])), committeeInEpoch0IDs[2], testAPI.TimeProvider().SlotEndTime(7)) + s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2])), committeeInEpoch0IDs[2], testAPI.TimeProvider().SlotEndTime(2+testAPI.ProtocolParameters().MaxCommittableAge())) assertOnlineCommittee(t, s.OnlineCommittee(), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2]))) } diff --git a/pkg/tests/committee_rotation_test.go b/pkg/tests/committee_rotation_test.go index a516c89e3..8317c26d2 100644 --- a/pkg/tests/committee_rotation_test.go +++ b/pkg/tests/committee_rotation_test.go @@ -2,7 +2,6 @@ package tests import ( "testing" - "time" "github.com/iotaledger/hive.go/runtime/options" "github.com/iotaledger/iota-core/pkg/protocol" @@ -51,10 +50,7 @@ func Test_TopStakersRotation(t *testing.T) { protocol.WithSybilProtectionProvider( sybilprotectionv1.NewProvider( sybilprotectionv1.WithSeatManagerProvider( - topstakers.NewProvider( - // We need to make sure that inactive nodes are evicted from the committee to continue acceptance. - topstakers.WithActivityWindow(15 * time.Second), - ), + topstakers.NewProvider(), ), ), ), diff --git a/pkg/tests/confirmation_state_test.go b/pkg/tests/confirmation_state_test.go index 78c6cc293..0323f23f5 100644 --- a/pkg/tests/confirmation_state_test.go +++ b/pkg/tests/confirmation_state_test.go @@ -3,7 +3,6 @@ package tests import ( "fmt" "testing" - "time" "github.com/iotaledger/hive.go/lo" "github.com/iotaledger/hive.go/runtime/options" @@ -59,7 +58,6 @@ func TestConfirmationFlags(t *testing.T) { sybilprotectionv1.WithSeatManagerProvider( topstakers.NewProvider( topstakers.WithOnlineCommitteeStartup(nodeA.Validator.AccountID), - topstakers.WithActivityWindow(2*time.Minute), ), ), ), diff --git a/pkg/tests/protocol_engine_switching_test.go b/pkg/tests/protocol_engine_switching_test.go index 046ffbd99..107386885 100644 --- a/pkg/tests/protocol_engine_switching_test.go +++ b/pkg/tests/protocol_engine_switching_test.go @@ -389,7 +389,7 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { iotago.WithLivenessOptions( 10, 10, - 3, + 2, 5, 10, ), @@ -413,10 +413,7 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { protocol.WithSybilProtectionProvider( sybilprotectionv1.NewProvider( sybilprotectionv1.WithSeatManagerProvider( - topstakers.NewProvider( - // We need to make sure that inactive nodes are evicted from the committee to continue acceptance. - topstakers.WithActivityWindow(10 * time.Second), - ), + topstakers.NewProvider(), ), ), ), @@ -472,13 +469,13 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { ts.IssueBlocksAtSlots("P0:", []iotago.SlotIndex{3, 4, 5, 6, 7, 8}, 4, "P0:node2-candidacy:1", ts.Nodes(), true, true) ts.AssertNodeState(ts.Nodes(), - testsuite.WithLatestFinalizedSlot(4), - testsuite.WithLatestCommitmentSlotIndex(5), - testsuite.WithEqualStoredCommitmentAtIndex(5), - testsuite.WithLatestCommitmentCumulativeWeight(4), // 4 * slot 5 + testsuite.WithLatestFinalizedSlot(5), + testsuite.WithLatestCommitmentSlotIndex(6), + testsuite.WithEqualStoredCommitmentAtIndex(6), + testsuite.WithLatestCommitmentCumulativeWeight(8), // 4 * slot 6 testsuite.WithSybilProtectionOnlineCommittee(ts.SeatOfNodes(5, "node0", "node1", "node2", "node3")...), testsuite.WithSybilProtectionCandidates(0, ts.AccountsOfNodes("node1", "node2")), - testsuite.WithEvictedSlot(5), + testsuite.WithEvictedSlot(6), ) ts.AssertAttestationsForSlot(5, ts.Blocks("P0:5.3-node0", "P0:5.3-node1", "P0:5.3-node2", "P0:5.3-node3"), ts.Nodes()...) @@ -496,15 +493,15 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { // Issue blocks in partition 1. { - ts.IssueBlocksAtSlots("P1:", []iotago.SlotIndex{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, 4, "P0:8.3", nodesP1, true, true) + ts.IssueBlocksAtSlots("P1:", []iotago.SlotIndex{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, 4, "P0:8.3", nodesP1, true, false) ts.AssertNodeState(nodesP1, - testsuite.WithLatestFinalizedSlot(16), - testsuite.WithLatestCommitmentSlotIndex(17), - testsuite.WithEqualStoredCommitmentAtIndex(17), - testsuite.WithLatestCommitmentCumulativeWeight(43), // 4 + see attestation assertions below for how to compute - testsuite.WithSybilProtectionOnlineCommittee(ts.SeatOfNodes(17, "node1", "node2")...), - testsuite.WithEvictedSlot(17), + testsuite.WithLatestFinalizedSlot(17), + testsuite.WithLatestCommitmentSlotIndex(18), + testsuite.WithEqualStoredCommitmentAtIndex(18), + testsuite.WithLatestCommitmentCumulativeWeight(48), // 4 + see attestation assertions below for how to compute + testsuite.WithSybilProtectionOnlineCommittee(ts.SeatOfNodes(18, "node1", "node2")...), + testsuite.WithEvictedSlot(18), ) // Assert committee in epoch 1. @@ -514,18 +511,19 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { // Assert committee in epoch 2. ts.AssertSybilProtectionCandidates(1, iotago.AccountIDs{}, nodesP1...) - ts.AssertAttestationsForSlot(6, ts.Blocks("P0:6.3-node0", "P0:6.3-node1", "P0:6.3-node2", "P0:6.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(7, ts.Blocks("P0:7.3-node0", "P0:7.3-node1", "P0:7.3-node2", "P0:7.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(8, ts.Blocks("P0:8.3-node0", "P0:8.3-node1", "P0:8.3-node2", "P0:8.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(9, ts.Blocks("P1:9.3-node0", "P1:9.3-node1", "P1:9.3-node2", "P0:8.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window - ts.AssertAttestationsForSlot(10, ts.Blocks("P1:10.3-node0", "P1:10.3-node1", "P1:10.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(11, ts.Blocks("P1:11.3-node0", "P1:11.3-node1", "P1:11.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(12, ts.Blocks("P1:12.3-node0", "P1:12.3-node1", "P1:12.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(13, ts.Blocks("P1:13.3-node0", "P1:13.3-node1", "P1:13.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(14, ts.Blocks("P1:14.3-node0", "P1:14.3-node1", "P1:14.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(15, ts.Blocks("P1:15.3-node0", "P1:15.3-node1", "P1:15.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(16, ts.Blocks("P1:15.3-node0", "P1:16.3-node1", "P1:16.3-node2"), nodesP1...) // We're in Epoch 2 (only node1, node2) but we carry attestations of others because of window - ts.AssertAttestationsForSlot(17, ts.Blocks("P1:17.3-node1", "P1:17.3-node2"), nodesP1...) // Committee in epoch 2 is only node1, node2 + ts.AssertAttestationsForSlot(6, ts.Blocks("P0:6.3-node0", "P0:6.3-node1", "P0:6.3-node2", "P0:6.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes + ts.AssertAttestationsForSlot(7, ts.Blocks("P0:7.3-node0", "P0:7.3-node1", "P0:7.3-node2", "P0:7.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes + ts.AssertAttestationsForSlot(8, ts.Blocks("P0:8.3-node0", "P0:8.3-node1", "P0:8.3-node2", "P0:8.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes + ts.AssertAttestationsForSlot(9, ts.Blocks("P1:9.3-node0", "P1:9.3-node1", "P1:9.3-node2", "P0:8.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window + ts.AssertAttestationsForSlot(10, ts.Blocks("P1:10.3-node0", "P1:10.3-node1", "P1:10.3-node2", "P0:8.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(11, ts.Blocks("P1:11.3-node0", "P1:11.3-node1", "P1:11.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(12, ts.Blocks("P1:12.3-node0", "P1:12.3-node1", "P1:12.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(13, ts.Blocks("P1:13.3-node0", "P1:13.3-node1", "P1:13.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(14, ts.Blocks("P1:14.3-node0", "P1:14.3-node1", "P1:14.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(15, ts.Blocks("P1:15.3-node0", "P1:15.3-node1", "P1:15.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(16, ts.Blocks("P1:15.3-node0", "P1:16.3-node1", "P1:16.3-node2"), nodesP1...) // We're in Epoch 2 (only node1, node2) but we carry attestations of others because of window + ts.AssertAttestationsForSlot(17, ts.Blocks("P1:15.3-node0", "P1:17.3-node1", "P1:17.3-node2"), nodesP1...) // Committee in epoch 2 is only node1, node2 + ts.AssertAttestationsForSlot(18, ts.Blocks("P1:15.3-node0", "P1:18.3-node1", "P1:18.3-node2"), nodesP1...) // Committee in epoch 2 is only node1, node2 ts.AssertStrongTips(ts.Blocks("P1:20.3-node0", "P1:20.3-node1", "P1:20.3-node2"), nodesP1...) @@ -535,15 +533,15 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { // Issue blocks in partition 2. { - ts.IssueBlocksAtSlots("P2:", []iotago.SlotIndex{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, 4, "P0:8.3", nodesP2, true, true) + ts.IssueBlocksAtSlots("P2:", []iotago.SlotIndex{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, 4, "P0:8.3", nodesP2, true, false) ts.AssertNodeState(nodesP2, - testsuite.WithLatestFinalizedSlot(4), - testsuite.WithLatestCommitmentSlotIndex(17), - testsuite.WithEqualStoredCommitmentAtIndex(17), + testsuite.WithLatestFinalizedSlot(5), + testsuite.WithLatestCommitmentSlotIndex(18), + testsuite.WithEqualStoredCommitmentAtIndex(18), // testsuite.WithLatestCommitmentCumulativeWeight(43), // 4 + see attestation assertions below for how to compute - testsuite.WithSybilProtectionOnlineCommittee(ts.SeatOfNodes(17, "node3")...), - testsuite.WithEvictedSlot(17), + testsuite.WithSybilProtectionOnlineCommittee(ts.SeatOfNodes(18, "node3")...), + testsuite.WithEvictedSlot(18), ) // Assert committee in epoch 1. diff --git a/pkg/tests/upgrade_signaling_test.go b/pkg/tests/upgrade_signaling_test.go index ce7ae6a3b..edf7d5a04 100644 --- a/pkg/tests/upgrade_signaling_test.go +++ b/pkg/tests/upgrade_signaling_test.go @@ -81,10 +81,7 @@ func Test_Upgrade_Signaling(t *testing.T) { protocol.WithSybilProtectionProvider( sybilprotectionv1.NewProvider( sybilprotectionv1.WithSeatManagerProvider( - topstakers.NewProvider( - // We need to make sure that inactive nodes are evicted from the committee to continue acceptance. - topstakers.WithActivityWindow(15 * time.Second), - ), + topstakers.NewProvider(), ), ), ), diff --git a/pkg/testsuite/testsuite_issue_blocks.go b/pkg/testsuite/testsuite_issue_blocks.go index 866a3252a..46df3b41b 100644 --- a/pkg/testsuite/testsuite_issue_blocks.go +++ b/pkg/testsuite/testsuite_issue_blocks.go @@ -215,11 +215,11 @@ func (t *TestSuite) IssueBlocksAtSlots(prefix string, slots []iotago.SlotIndex, if waitForSlotsCommitted { if slot > t.API.ProtocolParameters().MinCommittableAge() { - commitmentSlot := slot - t.API.ProtocolParameters().MinCommittableAge() - t.AssertCommitmentSlotIndexExists(commitmentSlot, nodes...) - + fmt.Printf("Node: %s, Slot index: %d, Online Committee: %v, Latest Commited Slot: %d\n", nodes[0].Name, slot, nodes[0].Protocol.Engines.Main.Get().SybilProtection.SeatManager().OnlineCommittee(), nodes[0].Protocol.Engines.Main.Get().Storage.Settings().LatestCommitment().Slot()) if useCommitmentAtMinCommittableAge { // Make sure that all nodes create blocks throughout the slot that commit to the same commitment at slot-minCommittableAge-1. + commitmentSlot := slot - t.API.ProtocolParameters().MinCommittableAge() + t.AssertCommitmentSlotIndexExists(commitmentSlot, nodes...) for _, node := range nodes { commitment, err := node.Protocol.Engines.Main.Get().Storage.Commitments().Load(commitmentSlot) require.NoError(t.Testing, err) @@ -229,9 +229,8 @@ func (t *TestSuite) IssueBlocksAtSlots(prefix string, slots []iotago.SlotIndex, } } } - } else { - t.AssertBlocksExist(blocksInSlot, true, nodes...) } + t.AssertBlocksExist(blocksInSlot, true, nodes...) } } From f334e1eab8fc261605fe418e0d0861ee2f998446 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 21 Dec 2023 18:41:49 +1300 Subject: [PATCH 2/6] fix top stakers test --- .../sybilprotection/seatmanager/topstakers/topstakers_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go index 2cd2add5a..6a8de026b 100644 --- a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go +++ b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go @@ -124,14 +124,13 @@ func TestTopStakers_RotateCommittee(t *testing.T) { assertOnlineCommittee(t, s.OnlineCommittee(), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[0]))) s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[1])), committeeInEpoch0IDs[1], testAPI.TimeProvider().SlotStartTime(2)) - fmt.Println(s.activityTracker.OnlineCommittee().Size()) assertOnlineCommittee(t, s.OnlineCommittee(), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[0])), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[1]))) s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2])), committeeInEpoch0IDs[2], testAPI.TimeProvider().SlotStartTime(3)) assertOnlineCommittee(t, s.OnlineCommittee(), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[0])), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[1])), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2]))) // Make sure that after a period of inactivity, the inactive seats are marked as offline. - s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2])), committeeInEpoch0IDs[2], testAPI.TimeProvider().SlotEndTime(2+testAPI.ProtocolParameters().MaxCommittableAge())) + s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2])), committeeInEpoch0IDs[2], testAPI.TimeProvider().SlotEndTime(2+testAPI.ProtocolParameters().MinCommittableAge())) assertOnlineCommittee(t, s.OnlineCommittee(), lo.Return1(committeeInEpoch0.GetSeat(committeeInEpoch0IDs[2]))) } From 4d4a235b866ab019877730741c868305553d10e5 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 21 Dec 2023 19:05:49 +1300 Subject: [PATCH 3/6] fix topstakers test --- .../sybilprotection/seatmanager/topstakers/topstakers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go index 6a8de026b..8dffab6a7 100644 --- a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go +++ b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go @@ -213,7 +213,7 @@ func TestTopStakers_RotateCommittee(t *testing.T) { newCommitteeMemberIDs := committeeInEpoch1Accounts.IDs() // A new committee member appears online and makes the previously active committee seat inactive. - s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(newCommitteeMemberIDs[0])), newCommitteeMemberIDs[0], testAPI.TimeProvider().SlotEndTime(14)) + s.activityTracker.MarkSeatActive(lo.Return1(committeeInEpoch0.GetSeat(newCommitteeMemberIDs[0])), newCommitteeMemberIDs[0], testAPI.TimeProvider().SlotEndTime(2+2*testAPI.ProtocolParameters().MinCommittableAge())) assertOnlineCommittee(t, s.OnlineCommittee(), lo.Return1(committeeInEpoch0.GetSeat(newCommitteeMemberIDs[0]))) // Make sure that the committee retrieved from the committee store matches the expected. From 4f21f84ffef1f4a2ea8e8a59a7752fc10cb21304 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 28 Dec 2023 16:47:42 +1300 Subject: [PATCH 4/6] fix engine switching test --- .../seatmanager/topstakers/topstakers.go | 2 - pkg/tests/protocol_engine_switching_test.go | 60 ++++++++++--------- pkg/testsuite/testsuite_issue_blocks.go | 1 - 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go index 5bfabcfbf..4e3379758 100644 --- a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go +++ b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go @@ -2,7 +2,6 @@ package topstakers import ( "bytes" - "fmt" "sort" "time" @@ -163,7 +162,6 @@ func (s *SeatManager) Shutdown() { func (s *SeatManager) InitializeCommittee(epoch iotago.EpochIndex, activityTime time.Time) error { s.committeeMutex.Lock() defer s.committeeMutex.Unlock() - fmt.Println("InitializeCommittee") committeeAccounts, err := s.committeeStore.Load(epoch) if err != nil { diff --git a/pkg/tests/protocol_engine_switching_test.go b/pkg/tests/protocol_engine_switching_test.go index 107386885..c0d8ce493 100644 --- a/pkg/tests/protocol_engine_switching_test.go +++ b/pkg/tests/protocol_engine_switching_test.go @@ -466,21 +466,21 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { ts.IssueCandidacyAnnouncementInSlot("P0:node2-candidacy:1", 3, "P0:node1-candidacy:1", ts.Wallet("node2")) } - ts.IssueBlocksAtSlots("P0:", []iotago.SlotIndex{3, 4, 5, 6, 7, 8}, 4, "P0:node2-candidacy:1", ts.Nodes(), true, true) + ts.IssueBlocksAtSlots("P0:", []iotago.SlotIndex{3, 4, 5, 6, 7}, 4, "P0:node2-candidacy:1", ts.Nodes(), true, true) ts.AssertNodeState(ts.Nodes(), - testsuite.WithLatestFinalizedSlot(5), - testsuite.WithLatestCommitmentSlotIndex(6), - testsuite.WithEqualStoredCommitmentAtIndex(6), - testsuite.WithLatestCommitmentCumulativeWeight(8), // 4 * slot 6 + testsuite.WithLatestFinalizedSlot(4), + testsuite.WithLatestCommitmentSlotIndex(5), + testsuite.WithEqualStoredCommitmentAtIndex(5), + testsuite.WithLatestCommitmentCumulativeWeight(4), // 4 * slot 6 testsuite.WithSybilProtectionOnlineCommittee(ts.SeatOfNodes(5, "node0", "node1", "node2", "node3")...), testsuite.WithSybilProtectionCandidates(0, ts.AccountsOfNodes("node1", "node2")), - testsuite.WithEvictedSlot(6), + testsuite.WithEvictedSlot(5), ) ts.AssertAttestationsForSlot(5, ts.Blocks("P0:5.3-node0", "P0:5.3-node1", "P0:5.3-node2", "P0:5.3-node3"), ts.Nodes()...) - ts.AssertStrongTips(ts.Blocks("P0:8.3-node0", "P0:8.3-node1", "P0:8.3-node2", "P0:8.3-node3"), ts.Nodes()...) + ts.AssertStrongTips(ts.Blocks("P0:7.3-node0", "P0:7.3-node1", "P0:7.3-node2", "P0:7.3-node3"), ts.Nodes()...) ts.AssertBlocksExist(ts.BlocksWithPrefix("P0"), true, ts.Nodes()...) } @@ -493,13 +493,13 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { // Issue blocks in partition 1. { - ts.IssueBlocksAtSlots("P1:", []iotago.SlotIndex{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, 4, "P0:8.3", nodesP1, true, false) + ts.IssueBlocksAtSlots("P1:", []iotago.SlotIndex{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, 4, "P0:7.3", nodesP1, true, false) ts.AssertNodeState(nodesP1, testsuite.WithLatestFinalizedSlot(17), testsuite.WithLatestCommitmentSlotIndex(18), testsuite.WithEqualStoredCommitmentAtIndex(18), - testsuite.WithLatestCommitmentCumulativeWeight(48), // 4 + see attestation assertions below for how to compute + testsuite.WithLatestCommitmentCumulativeWeight(47), // 4 + see attestation assertions below for how to compute testsuite.WithSybilProtectionOnlineCommittee(ts.SeatOfNodes(18, "node1", "node2")...), testsuite.WithEvictedSlot(18), ) @@ -511,19 +511,19 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { // Assert committee in epoch 2. ts.AssertSybilProtectionCandidates(1, iotago.AccountIDs{}, nodesP1...) - ts.AssertAttestationsForSlot(6, ts.Blocks("P0:6.3-node0", "P0:6.3-node1", "P0:6.3-node2", "P0:6.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(7, ts.Blocks("P0:7.3-node0", "P0:7.3-node1", "P0:7.3-node2", "P0:7.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(8, ts.Blocks("P0:8.3-node0", "P0:8.3-node1", "P0:8.3-node2", "P0:8.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(9, ts.Blocks("P1:9.3-node0", "P1:9.3-node1", "P1:9.3-node2", "P0:8.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window - ts.AssertAttestationsForSlot(10, ts.Blocks("P1:10.3-node0", "P1:10.3-node1", "P1:10.3-node2", "P0:8.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(11, ts.Blocks("P1:11.3-node0", "P1:11.3-node1", "P1:11.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(12, ts.Blocks("P1:12.3-node0", "P1:12.3-node1", "P1:12.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(13, ts.Blocks("P1:13.3-node0", "P1:13.3-node1", "P1:13.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(14, ts.Blocks("P1:14.3-node0", "P1:14.3-node1", "P1:14.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(15, ts.Blocks("P1:15.3-node0", "P1:15.3-node1", "P1:15.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 - ts.AssertAttestationsForSlot(16, ts.Blocks("P1:15.3-node0", "P1:16.3-node1", "P1:16.3-node2"), nodesP1...) // We're in Epoch 2 (only node1, node2) but we carry attestations of others because of window - ts.AssertAttestationsForSlot(17, ts.Blocks("P1:15.3-node0", "P1:17.3-node1", "P1:17.3-node2"), nodesP1...) // Committee in epoch 2 is only node1, node2 - ts.AssertAttestationsForSlot(18, ts.Blocks("P1:15.3-node0", "P1:18.3-node1", "P1:18.3-node2"), nodesP1...) // Committee in epoch 2 is only node1, node2 + ts.AssertAttestationsForSlot(6, ts.Blocks("P0:6.3-node0", "P0:6.3-node1", "P0:6.3-node2", "P0:6.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes + ts.AssertAttestationsForSlot(7, ts.Blocks("P0:7.3-node0", "P0:7.3-node1", "P0:7.3-node2", "P0:7.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes + ts.AssertAttestationsForSlot(8, ts.Blocks("P1:8.3-node0", "P1:8.3-node1", "P1:8.3-node2", "P0:7.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window + ts.AssertAttestationsForSlot(9, ts.Blocks("P1:9.3-node0", "P1:9.3-node1", "P1:9.3-node2", "P0:7.3-node3"), nodesP1...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window + ts.AssertAttestationsForSlot(10, ts.Blocks("P1:10.3-node0", "P1:10.3-node1", "P1:10.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(11, ts.Blocks("P1:11.3-node0", "P1:11.3-node1", "P1:11.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(12, ts.Blocks("P1:12.3-node0", "P1:12.3-node1", "P1:12.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(13, ts.Blocks("P1:13.3-node0", "P1:13.3-node1", "P1:13.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(14, ts.Blocks("P1:14.3-node0", "P1:14.3-node1", "P1:14.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(15, ts.Blocks("P1:15.3-node0", "P1:15.3-node1", "P1:15.3-node2"), nodesP1...) // Committee in epoch 1 is all nodes; node3 is in P2 + ts.AssertAttestationsForSlot(16, ts.Blocks("P1:15.3-node0", "P1:16.3-node1", "P1:16.3-node2"), nodesP1...) // We're in Epoch 2 (only node1, node2) but we carry attestations of others because of window + ts.AssertAttestationsForSlot(17, ts.Blocks("P1:15.3-node0", "P1:17.3-node1", "P1:17.3-node2"), nodesP1...) // Committee in epoch 2 is only node1, node2 + ts.AssertAttestationsForSlot(18, ts.Blocks("P1:15.3-node0", "P1:18.3-node1", "P1:18.3-node2"), nodesP1...) // Committee in epoch 2 is only node1, node2 ts.AssertStrongTips(ts.Blocks("P1:20.3-node0", "P1:20.3-node1", "P1:20.3-node2"), nodesP1...) @@ -533,10 +533,10 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { // Issue blocks in partition 2. { - ts.IssueBlocksAtSlots("P2:", []iotago.SlotIndex{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, 4, "P0:8.3", nodesP2, true, false) + ts.IssueBlocksAtSlots("P2:", []iotago.SlotIndex{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, 4, "P0:7.3", nodesP2, true, false) ts.AssertNodeState(nodesP2, - testsuite.WithLatestFinalizedSlot(5), + testsuite.WithLatestFinalizedSlot(4), testsuite.WithLatestCommitmentSlotIndex(18), testsuite.WithEqualStoredCommitmentAtIndex(18), // testsuite.WithLatestCommitmentCumulativeWeight(43), // 4 + see attestation assertions below for how to compute @@ -553,8 +553,8 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { ts.AssertAttestationsForSlot(6, ts.Blocks("P0:6.3-node0", "P0:6.3-node1", "P0:6.3-node2", "P0:6.3-node3"), nodesP2...) // Committee in epoch 1 is all nodes ts.AssertAttestationsForSlot(7, ts.Blocks("P0:7.3-node0", "P0:7.3-node1", "P0:7.3-node2", "P0:7.3-node3"), nodesP2...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(8, ts.Blocks("P0:8.3-node0", "P0:8.3-node1", "P0:8.3-node2", "P0:8.3-node3"), nodesP2...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(9, ts.Blocks("P0:8.3-node0", "P0:8.3-node1", "P0:8.3-node2", "P2:9.3-node3"), nodesP2...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window + ts.AssertAttestationsForSlot(8, ts.Blocks("P0:7.3-node0", "P0:7.3-node1", "P0:7.3-node2", "P2:8.3-node3"), nodesP2...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window + ts.AssertAttestationsForSlot(9, ts.Blocks("P0:7.3-node0", "P0:7.3-node1", "P0:7.3-node2", "P2:9.3-node3"), nodesP2...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window ts.AssertAttestationsForSlot(10, ts.Blocks("P2:10.3-node3"), nodesP2...) // Committee in epoch 1 is all nodes; only node3 is in P2 ts.AssertAttestationsForSlot(11, ts.Blocks("P2:11.3-node3"), nodesP2...) // Committee in epoch 1 is all nodes; only node3 is in P2 ts.AssertAttestationsForSlot(12, ts.Blocks("P2:12.3-node3"), nodesP2...) // Committee in epoch 1 is all nodes; only node3 is in P2 @@ -628,8 +628,8 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { ts.AssertAttestationsForSlot(6, ts.Blocks("P0:6.3-node0", "P0:6.3-node1", "P0:6.3-node2", "P0:6.3-node3"), ts.Nodes()...) // Committee in epoch 1 is all nodes ts.AssertAttestationsForSlot(7, ts.Blocks("P0:7.3-node0", "P0:7.3-node1", "P0:7.3-node2", "P0:7.3-node3"), ts.Nodes()...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(8, ts.Blocks("P0:8.3-node0", "P0:8.3-node1", "P0:8.3-node2", "P0:8.3-node3"), ts.Nodes()...) // Committee in epoch 1 is all nodes - ts.AssertAttestationsForSlot(9, ts.Blocks("P1:9.3-node0", "P1:9.3-node1", "P1:9.3-node2", "P0:8.3-node3"), ts.Nodes()...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window + ts.AssertAttestationsForSlot(8, ts.Blocks("P1:8.3-node0", "P1:8.3-node1", "P1:8.3-node2", "P0:7.3-node3"), ts.Nodes()...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window + ts.AssertAttestationsForSlot(9, ts.Blocks("P1:9.3-node0", "P1:9.3-node1", "P1:9.3-node2", "P0:7.3-node3"), ts.Nodes()...) // Committee in epoch 1 is all nodes; and we carry attestations of others because of window ts.AssertAttestationsForSlot(10, ts.Blocks("P1:10.3-node0", "P1:10.3-node1", "P1:10.3-node2"), ts.Nodes()...) // Committee in epoch 1 is all nodes; node3 is in P2 ts.AssertAttestationsForSlot(11, ts.Blocks("P1:11.3-node0", "P1:11.3-node1", "P1:11.3-node2"), ts.Nodes()...) // Committee in epoch 1 is all nodes; node3 is in P2 ts.AssertAttestationsForSlot(12, ts.Blocks("P1:12.3-node0", "P1:12.3-node1", "P1:12.3-node2"), ts.Nodes()...) // Committee in epoch 1 is all nodes; node3 is in P2 @@ -637,5 +637,7 @@ func TestProtocol_EngineSwitching_CommitteeRotation(t *testing.T) { ts.AssertAttestationsForSlot(14, ts.Blocks("P1:14.3-node0", "P1:14.3-node1", "P1:14.3-node2"), ts.Nodes()...) // Committee in epoch 1 is all nodes; node3 is in P2 ts.AssertAttestationsForSlot(15, ts.Blocks("P1:15.3-node0", "P1:15.3-node1", "P1:15.3-node2"), ts.Nodes()...) // Committee in epoch 1 is all nodes; node3 is in P2 ts.AssertAttestationsForSlot(16, ts.Blocks("P1:15.3-node0", "P1:16.3-node1", "P1:16.3-node2"), ts.Nodes()...) // We're in Epoch 2 (only node1, node2) but we carry attestations of others because of window - ts.AssertAttestationsForSlot(17, ts.Blocks("P1:17.3-node1", "P1:17.3-node2"), ts.Nodes()...) // Committee in epoch 2 is only node1, node2 + ts.AssertAttestationsForSlot(17, ts.Blocks("P1:15.3-node0", "P1:17.3-node1", "P1:17.3-node2"), ts.Nodes()...) // We're in Epoch 2 (only node1, node2) but we carry attestations of others because of window + ts.AssertAttestationsForSlot(18, ts.Blocks("P1:15.3-node0", "P1:18.3-node1", "P1:18.3-node2"), ts.Nodes()...) // We're in Epoch 2 (only node1, node2) but we carry attestations of others because of window + ts.AssertAttestationsForSlot(19, ts.Blocks("P1:19.3-node1", "P1:19.3-node2"), ts.Nodes()...) // Committee in epoch 2 is only node1, node2 } diff --git a/pkg/testsuite/testsuite_issue_blocks.go b/pkg/testsuite/testsuite_issue_blocks.go index 46df3b41b..3899662bf 100644 --- a/pkg/testsuite/testsuite_issue_blocks.go +++ b/pkg/testsuite/testsuite_issue_blocks.go @@ -215,7 +215,6 @@ func (t *TestSuite) IssueBlocksAtSlots(prefix string, slots []iotago.SlotIndex, if waitForSlotsCommitted { if slot > t.API.ProtocolParameters().MinCommittableAge() { - fmt.Printf("Node: %s, Slot index: %d, Online Committee: %v, Latest Commited Slot: %d\n", nodes[0].Name, slot, nodes[0].Protocol.Engines.Main.Get().SybilProtection.SeatManager().OnlineCommittee(), nodes[0].Protocol.Engines.Main.Get().Storage.Settings().LatestCommitment().Slot()) if useCommitmentAtMinCommittableAge { // Make sure that all nodes create blocks throughout the slot that commit to the same commitment at slot-minCommittableAge-1. commitmentSlot := slot - t.API.ProtocolParameters().MinCommittableAge() From dc3846a297d6983a901d4843eb07f5e6ea17ebe2 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 8 Jan 2024 18:23:50 +1300 Subject: [PATCH 5/6] SelectCommittee() -> SeatedAccounts() and SetCommittee() -> ReuseCommittee() --- pkg/core/account/accounts.go | 4 ++-- pkg/core/account/accounts_test.go | 4 ++-- .../slotattestation/testframework_test.go | 2 +- .../mempool/spenddag/tests/accounts_framework.go | 2 +- pkg/protocol/engine/mempool/v1/mempool_test.go | 2 +- .../seatmanager/mock/mockseatmanager.go | 14 +++++++------- .../sybilprotection/seatmanager/poa/poa.go | 10 +++++----- .../sybilprotection/seatmanager/seatmanager.go | 5 ++--- .../seatmanager/topstakers/topstakers.go | 8 ++++---- .../seatmanager/topstakers/topstakers_test.go | 10 +++++----- .../sybilprotectionv1/sybilprotection.go | 2 +- 11 files changed, 31 insertions(+), 32 deletions(-) diff --git a/pkg/core/account/accounts.go b/pkg/core/account/accounts.go index 7cfdfa3bd..e5237f6da 100644 --- a/pkg/core/account/accounts.go +++ b/pkg/core/account/accounts.go @@ -125,8 +125,8 @@ func (a *Accounts) ForEach(callback func(id iotago.AccountID, pool *Pool) bool) a.accountPools.ForEach(callback) } -// SelectCommittee creates a new SeatedAccounts instance, that maintains the seats of the given members. -func (a *Accounts) SelectCommittee(members ...iotago.AccountID) *SeatedAccounts { +// SeatedAccounts creates a new SeatedAccounts instance, that maintains the seats of the given members. +func (a *Accounts) SeatedAccounts(members ...iotago.AccountID) *SeatedAccounts { return NewSeatedAccounts(a, members...) } diff --git a/pkg/core/account/accounts_test.go b/pkg/core/account/accounts_test.go index 282511d06..ad420a582 100644 --- a/pkg/core/account/accounts_test.go +++ b/pkg/core/account/accounts_test.go @@ -108,11 +108,11 @@ func TestAccounts(t *testing.T) { // check "SelectCommittee" // get 1 issuer - seated := accounts.SelectCommittee(accountIDs[0]) + seated := accounts.SeatedAccounts(accountIDs[0]) require.Equal(t, 1, seated.SeatCount()) // get all issuers - seated = accounts.SelectCommittee(accountIDs...) + seated = accounts.SeatedAccounts(accountIDs...) require.Equal(t, len(accountIDs), seated.SeatCount()) /* diff --git a/pkg/protocol/engine/attestation/slotattestation/testframework_test.go b/pkg/protocol/engine/attestation/slotattestation/testframework_test.go index 67e428c0d..3bd3b1933 100644 --- a/pkg/protocol/engine/attestation/slotattestation/testframework_test.go +++ b/pkg/protocol/engine/attestation/slotattestation/testframework_test.go @@ -66,7 +66,7 @@ func NewTestFramework(test *testing.T) *TestFramework { members = append(members, issuer.accountID) return true }) - return accounts.SelectCommittee(members...), true + return accounts.SeatedAccounts(members...), true } t.testAPI = iotago.V3API( diff --git a/pkg/protocol/engine/mempool/spenddag/tests/accounts_framework.go b/pkg/protocol/engine/mempool/spenddag/tests/accounts_framework.go index 6a32efefb..fe080d6ec 100644 --- a/pkg/protocol/engine/mempool/spenddag/tests/accounts_framework.go +++ b/pkg/protocol/engine/mempool/spenddag/tests/accounts_framework.go @@ -21,7 +21,7 @@ type AccountsTestFramework struct { func NewAccountsTestFramework(test *testing.T, instance *account.Accounts) *AccountsTestFramework { return &AccountsTestFramework{ Instance: instance, - Committee: instance.SelectCommittee(), + Committee: instance.SeatedAccounts(), test: test, identitiesByAlias: make(map[string]iotago.AccountID), diff --git a/pkg/protocol/engine/mempool/v1/mempool_test.go b/pkg/protocol/engine/mempool/v1/mempool_test.go index 606e02efd..957ff0208 100644 --- a/pkg/protocol/engine/mempool/v1/mempool_test.go +++ b/pkg/protocol/engine/mempool/v1/mempool_test.go @@ -141,7 +141,7 @@ func newTestFramework(t *testing.T) *mempooltests.TestFramework { workers := workerpool.NewGroup(t.Name()) ledgerState := ledgertests.New(ledgertests.NewMockedState(iotago.EmptyTransactionID, 0)) - spendDAG := spenddagv1.New[iotago.TransactionID, mempool.StateID, vote.MockedRank](account.NewAccounts().SelectCommittee().SeatCount) + spendDAG := spenddagv1.New[iotago.TransactionID, mempool.StateID, vote.MockedRank](account.NewAccounts().SeatedAccounts().SeatCount) mutationsFunc := func(index iotago.SlotIndex) (kvstore.KVStore, error) { return mapdb.NewMapDB(), nil diff --git a/pkg/protocol/sybilprotection/seatmanager/mock/mockseatmanager.go b/pkg/protocol/sybilprotection/seatmanager/mock/mockseatmanager.go index 4551ead1f..edd0832b2 100644 --- a/pkg/protocol/sybilprotection/seatmanager/mock/mockseatmanager.go +++ b/pkg/protocol/sybilprotection/seatmanager/mock/mockseatmanager.go @@ -40,7 +40,7 @@ func NewManualPOA(e iotago.APIProvider, committeeStore *epochstore.Store[*accoun online: ds.NewSet[account.SeatIndex](), aliases: shrinkingmap.New[string, iotago.AccountID](), } - m.committee = m.accounts.SelectCommittee() + m.committee = m.accounts.SeatedAccounts() return m } @@ -71,7 +71,7 @@ func (m *ManualPOA) AddRandomAccount(alias string) iotago.AccountID { m.aliases.Set(alias, id) - m.committee = m.accounts.SelectCommittee(m.accounts.IDs()...) + m.committee = m.accounts.SeatedAccounts(m.accounts.IDs()...) if err := m.committeeStore.Store(0, m.accounts); err != nil { panic(err) @@ -90,7 +90,7 @@ func (m *ManualPOA) AddAccount(id iotago.AccountID, alias string) iotago.Account } m.aliases.Set(alias, id) - m.committee = m.accounts.SelectCommittee(m.accounts.IDs()...) + m.committee = m.accounts.SeatedAccounts(m.accounts.IDs()...) if err := m.committeeStore.Store(0, m.accounts); err != nil { panic(err) @@ -152,7 +152,7 @@ func (m *ManualPOA) committeeInEpoch(epoch iotago.EpochIndex) (*account.SeatedAc return nil, false } - return c.SelectCommittee(c.IDs()...), true + return c.SeatedAccounts(c.IDs()...), true } func (m *ManualPOA) OnlineCommittee() ds.Set[account.SeatIndex] { @@ -179,7 +179,7 @@ func (m *ManualPOA) RotateCommittee(epoch iotago.EpochIndex, validators accounts return nil, ierrors.Wrapf(err, "error while setting pool for epoch %d for validator %s", epoch, validatorData.ID.String()) } } - m.committee = m.accounts.SelectCommittee(m.accounts.IDs()...) + m.committee = m.accounts.SeatedAccounts(m.accounts.IDs()...) } if err := m.committeeStore.Store(epoch, m.accounts); err != nil { @@ -189,10 +189,10 @@ func (m *ManualPOA) RotateCommittee(epoch iotago.EpochIndex, validators accounts return m.committee, nil } -func (m *ManualPOA) SetCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error { +func (m *ManualPOA) ReuseCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error { if m.committee == nil || m.accounts.Size() == 0 { m.accounts = validators - m.committee = m.accounts.SelectCommittee(validators.IDs()...) + m.committee = m.accounts.SeatedAccounts(validators.IDs()...) } if err := m.committeeStore.Store(epoch, validators); err != nil { diff --git a/pkg/protocol/sybilprotection/seatmanager/poa/poa.go b/pkg/protocol/sybilprotection/seatmanager/poa/poa.go index 017846e10..ba9d1de81 100644 --- a/pkg/protocol/sybilprotection/seatmanager/poa/poa.go +++ b/pkg/protocol/sybilprotection/seatmanager/poa/poa.go @@ -94,7 +94,7 @@ func (s *SeatManager) RotateCommittee(epoch iotago.EpochIndex, validators accoun return nil, ierrors.Wrapf(err, "error while setting committee for epoch %d for validator %s", epoch, validatorData.ID.String()) } } - s.committee = committeeAccounts.SelectCommittee(committeeAccounts.IDs()...) + s.committee = committeeAccounts.SeatedAccounts(committeeAccounts.IDs()...) } accounts, err := s.committee.Accounts() @@ -135,7 +135,7 @@ func (s *SeatManager) committeeInEpoch(epoch iotago.EpochIndex) (*account.Seated return nil, false } - return c.SelectCommittee(c.IDs()...), true + return c.SeatedAccounts(c.IDs()...), true } // OnlineCommittee returns the set of validators selected to be part of the committee that has been seen recently. @@ -171,7 +171,7 @@ func (s *SeatManager) InitializeCommittee(epoch iotago.EpochIndex, activityTime } committeeAccountsIDs := committeeAccounts.IDs() - s.committee = committeeAccounts.SelectCommittee(committeeAccountsIDs...) + s.committee = committeeAccounts.SeatedAccounts(committeeAccountsIDs...) // Set validators that are part of the committee as active. onlineValidators := committeeAccountsIDs @@ -192,11 +192,11 @@ func (s *SeatManager) InitializeCommittee(epoch iotago.EpochIndex, activityTime return nil } -func (s *SeatManager) SetCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error { +func (s *SeatManager) ReuseCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error { s.committeeMutex.Lock() defer s.committeeMutex.Unlock() - s.committee = validators.SelectCommittee(validators.IDs()...) + s.committee = validators.SeatedAccounts(validators.IDs()...) accounts, err := s.committee.Accounts() if err != nil { diff --git a/pkg/protocol/sybilprotection/seatmanager/seatmanager.go b/pkg/protocol/sybilprotection/seatmanager/seatmanager.go index 38c443e17..a78d5f022 100644 --- a/pkg/protocol/sybilprotection/seatmanager/seatmanager.go +++ b/pkg/protocol/sybilprotection/seatmanager/seatmanager.go @@ -15,9 +15,8 @@ type SeatManager interface { // RotateCommittee rotates the committee evaluating the given set of candidates to produce the new committee. RotateCommittee(epoch iotago.EpochIndex, candidates accounts.AccountsData) (*account.SeatedAccounts, error) - // SetCommittee sets the committee for a given slot. - // This is used when re-using the same committee for consecutive epochs. - SetCommittee(epoch iotago.EpochIndex, committee *account.Accounts) error + // ReuseCommittee reuses the committee from a previous epoch epochs. + ReuseCommittee(epoch iotago.EpochIndex, committee *account.Accounts) error // InitializeCommittee initializes the committee for the current slot by marking whole or a subset of the committee as active. // This is used when initializing committee after node startup (loaded from snapshot or database). diff --git a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go index 4e3379758..000bec5f0 100644 --- a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go +++ b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go @@ -129,7 +129,7 @@ func (s *SeatManager) committeeInEpoch(epoch iotago.EpochIndex) (*account.Seated return nil, false } - return c.SelectCommittee(c.IDs()...), true + return c.SeatedAccounts(c.IDs()...), true } // OnlineCommittee returns the set of validators selected to be part of the committee that has been seen recently. @@ -168,7 +168,7 @@ func (s *SeatManager) InitializeCommittee(epoch iotago.EpochIndex, activityTime return ierrors.Wrapf(err, "failed to load PoA committee for epoch %d", epoch) } - committee := committeeAccounts.SelectCommittee(committeeAccounts.IDs()...) + committee := committeeAccounts.SeatedAccounts(committeeAccounts.IDs()...) onlineValidators := committeeAccounts.IDs() if len(s.optsOnlineCommitteeStartup) > 0 { @@ -188,7 +188,7 @@ func (s *SeatManager) InitializeCommittee(epoch iotago.EpochIndex, activityTime return nil } -func (s *SeatManager) SetCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error { +func (s *SeatManager) ReuseCommittee(epoch iotago.EpochIndex, validators *account.Accounts) error { s.committeeMutex.Lock() defer s.committeeMutex.Unlock() @@ -246,7 +246,7 @@ func (s *SeatManager) selectNewCommittee(epoch iotago.EpochIndex, candidates acc return nil, ierrors.Wrapf(err, "error while setting pool for committee candidate %s", candidateData.ID.String()) } } - committee := newCommitteeAccounts.SelectCommittee(newCommitteeAccounts.IDs()...) + committee := newCommitteeAccounts.SeatedAccounts(newCommitteeAccounts.IDs()...) return committee, nil } diff --git a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go index 8dffab6a7..0f825c42e 100644 --- a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go +++ b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers_test.go @@ -39,7 +39,7 @@ func TestTopStakers_InitializeCommittee(t *testing.T) { } // Try setting an empty committee. - err := topStakersSeatManager.SetCommittee(0, account.NewAccounts()) + err := topStakersSeatManager.ReuseCommittee(0, account.NewAccounts()) require.Error(t, err) // Create committee for epoch 0 @@ -55,7 +55,7 @@ func TestTopStakers_InitializeCommittee(t *testing.T) { } // Set committee for epoch 0. - err = topStakersSeatManager.SetCommittee(0, initialCommittee) + err = topStakersSeatManager.ReuseCommittee(0, initialCommittee) require.NoError(t, err) weightedSeats, exists := topStakersSeatManager.CommitteeInEpoch(0) require.True(t, exists) @@ -109,7 +109,7 @@ func TestTopStakers_RotateCommittee(t *testing.T) { addCommitteeMember(t, expectedCommitteeInEpoch0, &account.Pool{PoolStake: 1900, ValidatorStake: 900, FixedCost: 11}) // We should be able to set a committee with only 3 members for epoch 0 (this could be set e.g. via the snapshot). - err := s.SetCommittee(0, expectedCommitteeInEpoch0) + err := s.ReuseCommittee(0, expectedCommitteeInEpoch0) require.NoError(t, err) // Make sure that the online committee is handled correctly. @@ -269,7 +269,7 @@ func TestTopStakers_RotateCommittee(t *testing.T) { // Set reuse of committee manually. expectedCommitteeInEpoch2.SetReused() - err = s.SetCommittee(epoch, expectedCommitteeInEpoch2) + err = s.ReuseCommittee(epoch, expectedCommitteeInEpoch2) require.NoError(t, err) assertCommitteeInEpoch(t, s, testAPI, 3, expectedCommitteeInEpoch2) @@ -282,7 +282,7 @@ func TestTopStakers_RotateCommittee(t *testing.T) { loadedCommittee, err := s.committeeStore.Load(epoch) require.NoError(t, err) require.True(t, loadedCommittee.IsReused()) - assertCommittee(t, expectedCommitteeInEpoch2, loadedCommittee.SelectCommittee(loadedCommittee.IDs()...)) + assertCommittee(t, expectedCommitteeInEpoch2, loadedCommittee.SeatedAccounts(loadedCommittee.IDs()...)) } } diff --git a/pkg/protocol/sybilprotection/sybilprotectionv1/sybilprotection.go b/pkg/protocol/sybilprotection/sybilprotectionv1/sybilprotection.go index 6643c6cb3..acdbdd98a 100644 --- a/pkg/protocol/sybilprotection/sybilprotectionv1/sybilprotection.go +++ b/pkg/protocol/sybilprotection/sybilprotectionv1/sybilprotection.go @@ -392,7 +392,7 @@ func (o *SybilProtection) reuseCommittee(currentEpoch iotago.EpochIndex, targetE } committeeAccounts.SetReused() - if err = o.seatManager.SetCommittee(targetEpoch, committeeAccounts); err != nil { + if err = o.seatManager.ReuseCommittee(targetEpoch, committeeAccounts); err != nil { return nil, ierrors.Wrapf(err, "failed to set committee for epoch %d", targetEpoch) } From d2653c4b14b93f55e0e42f6416009650be0c8466 Mon Sep 17 00:00:00 2001 From: Andrew Cullen <45826600+cyberphysic4l@users.noreply.github.com> Date: Mon, 15 Jan 2024 08:24:56 +1300 Subject: [PATCH 6/6] Piotr suggestion Co-authored-by: Piotr Macek <4007944+piotrm50@users.noreply.github.com> --- pkg/protocol/sybilprotection/seatmanager/seatmanager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/protocol/sybilprotection/seatmanager/seatmanager.go b/pkg/protocol/sybilprotection/seatmanager/seatmanager.go index a78d5f022..656076a8c 100644 --- a/pkg/protocol/sybilprotection/seatmanager/seatmanager.go +++ b/pkg/protocol/sybilprotection/seatmanager/seatmanager.go @@ -15,7 +15,7 @@ type SeatManager interface { // RotateCommittee rotates the committee evaluating the given set of candidates to produce the new committee. RotateCommittee(epoch iotago.EpochIndex, candidates accounts.AccountsData) (*account.SeatedAccounts, error) - // ReuseCommittee reuses the committee from a previous epoch epochs. + // ReuseCommittee reuses the committee from a previous epoch. ReuseCommittee(epoch iotago.EpochIndex, committee *account.Accounts) error // InitializeCommittee initializes the committee for the current slot by marking whole or a subset of the committee as active.