Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dynamic Protocol State] Changing structure of participants in EpochSetup #4726

Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f490707
Updated EpochSetup to contain IdentitySkeletonList instead of Identit…
durkmurder Sep 18, 2023
9e98875
Introduced generic types for identity list, identity skeleton, orderi…
durkmurder Sep 19, 2023
8641897
Updated godoc, cleanup of commented out code
durkmurder Sep 19, 2023
59112b2
Merge branch 'yurii/4719-refactor-protocol-state-entry' of https://gi…
durkmurder Sep 21, 2023
40fdaf5
Merge branch 'feature/dynamic-protocol-state' into yurii/4649-todos-a…
durkmurder Sep 28, 2023
001d6a0
Updated how generic identities are handled in hotstuff committee
durkmurder Sep 28, 2023
c2f1123
Updated state updater and other usages of protocol state
durkmurder Sep 28, 2023
d9e78a6
Updated how static replicas are implemented
durkmurder Sep 28, 2023
e408bc1
Updated how static consensus committee is implemented. Updated identi…
durkmurder Sep 28, 2023
4f68f38
Updated filter adapter
durkmurder Sep 28, 2023
16c1347
Work in progress on fixing mutator tests
durkmurder Sep 28, 2023
1ea0703
Fixed more compilation issues in tests
durkmurder Sep 29, 2023
72349e0
Moved identity list to a separate file
durkmurder Sep 29, 2023
420244f
Added proper encoding for identity and identity skeleton
durkmurder Oct 2, 2023
a9d7587
Fixed compilation issues regarding generic identity in main codebase
durkmurder Oct 3, 2023
23cec18
Fixed more compilation issues regarding generic identity
durkmurder Oct 3, 2023
38ffeee
Fixed compilation and implementation issues with tests
durkmurder Oct 4, 2023
6e65018
Removed outdated tests. Fixed compilation for other tests
durkmurder Oct 4, 2023
ea3ef44
Fixed execution test
durkmurder Oct 4, 2023
8f91562
Fixed last batch of broken tests
durkmurder Oct 4, 2023
092927a
Linted
durkmurder Oct 4, 2023
a5ca17d
Updated godoc
durkmurder Oct 4, 2023
5acf227
Fixed compilation in DKG tests
durkmurder Oct 4, 2023
d4cba51
Fixed compilation in integration tests
durkmurder Oct 4, 2023
9230603
Merge branch 'yurii/4649-todos-and-refactoring-part-1' of https://git…
durkmurder Oct 4, 2023
fe04abc
Fixed test fixtures. Updated implementation of EqualTo
durkmurder Oct 4, 2023
3dd3c4d
Updated identities ordering for some tests. Changed how root QC are v…
durkmurder Oct 4, 2023
d3ee95b
Updated integration test fixtures to work with BootstrapInfo instead …
durkmurder Oct 5, 2023
e4885eb
Linted
durkmurder Oct 5, 2023
7e5d3c9
Fixed leftover compilation issues
durkmurder Oct 6, 2023
6707537
Fixed insecure tests
durkmurder Oct 6, 2023
99aff89
Linted
durkmurder Oct 6, 2023
32dd1d2
Apply suggestions from code review
durkmurder Oct 11, 2023
497bec2
Apply suggestions from PR review
durkmurder Oct 11, 2023
636d3d1
Merge branch 'feature/dynamic-protocol-state' of https://github.com/o…
durkmurder Oct 16, 2023
2a0b64b
removing dapper copyright notice.
Oct 16, 2023
4122b04
fixed typo
Oct 16, 2023
9feb09e
extended documentation of GenericIdentityList[T].Union
Oct 16, 2023
cf2469d
marginal goDoc update
Oct 17, 2023
c99c1ac
• extending documentation around cluster committee
Oct 17, 2023
739cbdf
Merge pull request #4832 from onflow/alex/4649-todos-and-refactoring-…
durkmurder Oct 18, 2023
b2c97b5
Apply suggestions from PR review
durkmurder Oct 19, 2023
244af7b
Simplified bootstrap in cluster switchover test
durkmurder Oct 19, 2023
ad075bc
Apply suggestions from PR review
durkmurder Oct 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ generate-fvm-env-wrappers:
generate-mocks: install-mock-generators
mockery --name '(Connector|PingInfoProvider)' --dir=network/p2p --case=underscore --output="./network/mocknetwork" --outpkg="mocknetwork"
mockgen -destination=storage/mocks/storage.go -package=mocks github.com/onflow/flow-go/storage Blocks,Headers,Payloads,Collections,Commits,Events,ServiceEvents,TransactionResults
mockgen -destination=module/mocks/network.go -package=mocks github.com/onflow/flow-go/module Local,Requester
#mockgen -destination=module/mocks/network.go -package=mocks github.com/onflow/flow-go/module Local,Requester
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mockgen doesn't support generics and it's deprecated I think we should replace it with mockery but not as part of this PR. I've manually updated generated code to compile.

mockgen -destination=network/mocknetwork/mock_network.go -package=mocknetwork github.com/onflow/flow-go/network EngineRegistry
mockery --name='.*' --dir=integration/benchmark/mocksiface --case=underscore --output="integration/benchmark/mock" --outpkg="mock"
mockery --name=ExecutionDataStore --dir=module/executiondatasync/execution_data --case=underscore --output="./module/executiondatasync/execution_data/mock" --outpkg="mock"
Expand Down
6 changes: 3 additions & 3 deletions cmd/access/node_builder/access_node_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1014,8 +1014,8 @@ func (builder *FlowAccessNodeBuilder) InitIDProviders() {
builder.SyncEngineParticipantsProviderFactory = func() module.IdentifierProvider {
return id.NewIdentityFilterIdentifierProvider(
filter.And(
filter.HasRole(flow.RoleConsensus),
filter.Not(filter.HasNodeID(node.Me.NodeID())),
filter.HasRole[flow.Identity](flow.RoleConsensus),
filter.Not(filter.HasNodeID[flow.Identity](node.Me.NodeID())),
p2pnet.NotEjectedFilter,
),
builder.IdentityProvider,
Expand Down Expand Up @@ -1313,7 +1313,7 @@ func (builder *FlowAccessNodeBuilder) Build() (cmd.Node, error) {
node.Me,
node.State,
channels.RequestCollections,
filter.HasRole(flow.RoleCollection),
filter.HasRole[flow.Identity](flow.RoleCollection),
func() flow.Entity { return &flow.Collection{} },
)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions cmd/bootstrap/cmd/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import (
// of succeeding the assignment by re-running the function without increasing the internal nodes ratio.
func constructClusterAssignment(partnerNodes, internalNodes []model.NodeInfo) (flow.AssignmentList, flow.ClusterList, error) {

partners := model.ToIdentityList(partnerNodes).Filter(filter.HasRole(flow.RoleCollection))
internals := model.ToIdentityList(internalNodes).Filter(filter.HasRole(flow.RoleCollection))
partners := model.ToIdentityList(partnerNodes).Filter(filter.HasRole[flow.Identity](flow.RoleCollection))
internals := model.ToIdentityList(internalNodes).Filter(filter.HasRole[flow.Identity](flow.RoleCollection))
nClusters := int(flagCollectionClusters)
nCollectors := len(partners) + len(internals)

Expand Down Expand Up @@ -73,7 +73,7 @@ func constructClusterAssignment(partnerNodes, internalNodes []model.NodeInfo) (f
assignments := assignment.FromIdentifierLists(identifierLists)

collectors := append(partners, internals...)
clusters, err := factory.NewClusterList(assignments, collectors)
clusters, err := factory.NewClusterList(assignments, collectors.ToSkeleton())
if err != nil {
log.Fatal().Err(err).Msg("could not create cluster list")
}
Expand Down Expand Up @@ -109,7 +109,7 @@ func constructRootQCsForClusters(
// Filters a list of nodes to include only nodes that will sign the QC for the
// given cluster. The resulting list of nodes is only nodes that are in the
// given cluster AND are not partner nodes (ie. we have the private keys).
func filterClusterSigners(cluster flow.IdentityList, nodeInfos []model.NodeInfo) []model.NodeInfo {
func filterClusterSigners(cluster flow.IdentitySkeletonList, nodeInfos []model.NodeInfo) []model.NodeInfo {

var filtered []model.NodeInfo
for _, node := range nodeInfos {
Expand Down
2 changes: 1 addition & 1 deletion cmd/bootstrap/cmd/constraints.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
func ensureUniformNodeWeightsPerRole(allNodes flow.IdentityList) {
// ensure all nodes of the same role have equal weight
for _, role := range flow.Roles() {
withRole := allNodes.Filter(filter.HasRole(role))
withRole := allNodes.Filter(filter.HasRole[flow.Identity](role))
// each role has at least one node so it's safe to access withRole[0]
expectedWeight := withRole[0].Weight
for _, node := range withRole {
Expand Down
4 changes: 2 additions & 2 deletions cmd/bootstrap/cmd/finalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func finalize(cmd *cobra.Command, args []string) {
log.Info().Msg("")

// create flow.IdentityList representation of participant set
participants := model.ToIdentityList(stakingNodes).Sort(order.Canonical)
participants := model.ToIdentityList(stakingNodes).Sort(order.Canonical[flow.Identity])

log.Info().Msg("reading root block data")
block := readRootBlock()
Expand Down Expand Up @@ -491,7 +491,7 @@ func mergeNodeInfos(internalNodes, partnerNodes []model.NodeInfo) []model.NodeIn
}

// sort nodes using the canonical ordering
nodes = model.Sort(nodes, order.Canonical)
nodes = model.Sort(nodes, order.Canonical[flow.Identity])

return nodes
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/bootstrap/cmd/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func genNetworkAndStakingKeys() []model.NodeInfo {
internalNodes = append(internalNodes, nodeInfo)
}

return model.Sort(internalNodes, order.Canonical)
return model.Sort(internalNodes, order.Canonical[flow.Identity])
}

func assembleNodeInfo(nodeConfig model.NodeConfig, networkKey, stakingKey crypto.PrivateKey) model.NodeInfo {
Expand Down
2 changes: 1 addition & 1 deletion cmd/bootstrap/cmd/seal.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func constructRootResultAndSeal(
DKGPhase1FinalView: firstView + flagNumViewsInStakingAuction + flagNumViewsInDKGPhase - 1,
DKGPhase2FinalView: firstView + flagNumViewsInStakingAuction + flagNumViewsInDKGPhase*2 - 1,
DKGPhase3FinalView: firstView + flagNumViewsInStakingAuction + flagNumViewsInDKGPhase*3 - 1,
Participants: participants.Sort(order.Canonical),
Participants: participants.Sort(order.Canonical[flow.Identity]).ToSkeleton(),
Assignments: assignments,
RandomSource: GenerateRandomSeed(flow.EpochSetupRandomSourceLength),
}
Expand Down
20 changes: 17 additions & 3 deletions cmd/bootstrap/run/cluster_qc.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import (
)

// GenerateClusterRootQC creates votes and generates a QC based on participant data
func GenerateClusterRootQC(signers []bootstrap.NodeInfo, allCommitteeMembers flow.IdentityList, clusterBlock *cluster.Block) (*flow.QuorumCertificate, error) {
if !allCommitteeMembers.Sorted(order.Canonical) {
func GenerateClusterRootQC(signers []bootstrap.NodeInfo, allCommitteeMembers flow.IdentitySkeletonList, clusterBlock *cluster.Block) (*flow.QuorumCertificate, error) {
if !allCommitteeMembers.Sorted(order.Canonical[flow.IdentitySkeleton]) {
return nil, fmt.Errorf("can't create root cluster QC: committee members are not sorted in canonical order")
}
clusterRootBlock := model.GenesisBlockFromFlow(clusterBlock.Header)
Expand All @@ -31,8 +31,22 @@ func GenerateClusterRootQC(signers []bootstrap.NodeInfo, allCommitteeMembers flo
return nil, err
}

// STEP 1.5: patch committee to include dynamic identities. This is a temporary measure until bootstrapping is refactored.
// We need to do this since the committee is used to create the QC uses dynamic identities, but clustering for root block contain only
// static identities since there no state transitions haven't happened yet.
durkmurder marked this conversation as resolved.
Show resolved Hide resolved
dynamicCommitteeMembers := make(flow.IdentityList, 0, len(allCommitteeMembers))
for _, participant := range allCommitteeMembers {
dynamicCommitteeMembers = append(dynamicCommitteeMembers, &flow.Identity{
IdentitySkeleton: *participant,
DynamicIdentity: flow.DynamicIdentity{
Weight: participant.InitialWeight,
Ejected: false,
},
})
}

// STEP 2: create VoteProcessor
committee, err := committees.NewStaticCommittee(allCommitteeMembers, flow.Identifier{}, nil, nil)
committee, err := committees.NewStaticCommittee(dynamicCommitteeMembers, flow.Identifier{}, nil, nil)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/bootstrap/run/cluster_qc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestGenerateClusterRootQC(t *testing.T) {
payload := cluster.EmptyPayload(flow.ZeroID)
clusterBlock.SetPayload(payload)

orderedParticipants := model.ToIdentityList(participants).Sort(order.Canonical)
orderedParticipants := model.ToIdentityList(participants).Sort(order.Canonical[flow.Identity]).ToSkeleton()
_, err := GenerateClusterRootQC(participants, orderedParticipants, &clusterBlock)
require.NoError(t, err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/bootstrap/run/qc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func TestGenerateRootQCWithSomeInvalidVotes(t *testing.T) {
}

func createSignerData(t *testing.T, n int) *ParticipantData {
identities := unittest.IdentityListFixture(n).Sort(order.Canonical)
identities := unittest.IdentityListFixture(n).Sort(order.Canonical[flow.Identity])

networkingKeys := unittest.NetworkingKeys(n)
stakingKeys := unittest.StakingKeys(n)
Expand Down
2 changes: 1 addition & 1 deletion cmd/collection/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ func main() {
channels.ProvideCollections,
filter.And(
filter.HasWeight(true),
filter.HasRole(flow.RoleAccess, flow.RoleExecution),
filter.HasRole[flow.Identity](flow.RoleAccess, flow.RoleExecution),
),
retrieve,
)
Expand Down
2 changes: 1 addition & 1 deletion cmd/consensus/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ func main() {
node.Me,
node.State,
channels.RequestReceiptsByBlockID,
filter.HasRole(flow.RoleExecution),
filter.HasRole[flow.Identity](flow.RoleExecution),
func() flow.Entity { return &flow.ExecutionReceipt{} },
requester.WithRetryInitial(2*time.Second),
requester.WithRetryMaximum(30*time.Second),
Expand Down
2 changes: 1 addition & 1 deletion cmd/execution_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ func (exeNode *ExecutionNode) LoadReceiptProviderEngine(
channels.ProvideReceiptsByBlockID,
filter.And(
filter.HasWeight(true),
filter.HasRole(flow.RoleConsensus),
filter.HasRole[flow.Identity](flow.RoleConsensus),
),
retrieve,
)
Expand Down
4 changes: 2 additions & 2 deletions cmd/scaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -1057,8 +1057,8 @@ func (fnb *FlowNodeBuilder) InitIDProviders() {

node.SyncEngineIdentifierProvider = id.NewIdentityFilterIdentifierProvider(
filter.And(
filter.HasRole(flow.RoleConsensus),
filter.Not(filter.HasNodeID(node.Me.NodeID())),
filter.HasRole[flow.Identity](flow.RoleConsensus),
filter.Not(filter.HasNodeID[flow.Identity](node.Me.NodeID())),
p2pnet.NotEjectedFilter,
),
node.IdentityProvider,
Expand Down
4 changes: 2 additions & 2 deletions cmd/util/cmd/common/flow_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func insecureFlowClient(accessAddress string) (*client.Client, error) {
func FlowClientConfigs(accessNodeIDS []flow.Identifier, insecureAccessAPI bool, snapshot protocol.Snapshot) ([]*FlowClientConfig, error) {
flowClientOpts := make([]*FlowClientConfig, 0)

identities, err := snapshot.Identities(filter.HasNodeID(accessNodeIDS...))
identities, err := snapshot.Identities(filter.HasNodeID[flow.Identity](accessNodeIDS...))
if err != nil {
return nil, fmt.Errorf("failed get identities access node identities (ids=%v) from snapshot: %w", accessNodeIDS, err)
}
Expand Down Expand Up @@ -139,7 +139,7 @@ func convertAccessAddrFromState(address string, insecureAccessAPI bool) string {

// DefaultAccessNodeIDS will return all the access node IDS in the protocol state for staked access nodes
func DefaultAccessNodeIDS(snapshot protocol.Snapshot) ([]flow.Identifier, error) {
identities, err := snapshot.Identities(filter.HasRole(flow.RoleAccess))
identities, err := snapshot.Identities(filter.HasRole[flow.Identity](flow.RoleAccess))
if err != nil {
return nil, fmt.Errorf("failed to get staked access node IDs from protocol state %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/util/cmd/epochs/cmd/move_machine_acct.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func moveMachineAcctRun(cmd *cobra.Command, args []string) {
}

// identities with machine accounts
machineAcctIdentities := identities.Filter(filter.HasRole(flow.RoleCollection, flow.RoleConsensus))
machineAcctIdentities := identities.Filter(filter.HasRole[flow.Identity](flow.RoleCollection, flow.RoleConsensus))

machineAcctFiles, err := os.ReadDir(flagMachineAccountsSrcDir)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion consensus/follower_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
mockhotstuff "github.com/onflow/flow-go/consensus/hotstuff/mocks"
"github.com/onflow/flow-go/consensus/hotstuff/model"
"github.com/onflow/flow-go/model/flow"
"github.com/onflow/flow-go/model/flow/order"
"github.com/onflow/flow-go/module/irrecoverable"
"github.com/onflow/flow-go/module/metrics"
mockmodule "github.com/onflow/flow-go/module/mock"
Expand Down Expand Up @@ -75,7 +76,7 @@ type HotStuffFollowerSuite struct {
// SetupTest initializes all the components needed for the Follower.
// The follower itself is instantiated in method BeforeTest
func (s *HotStuffFollowerSuite) SetupTest() {
identities := unittest.IdentityListFixture(4, unittest.WithRole(flow.RoleConsensus))
identities := unittest.IdentityListFixture(4, unittest.WithRole(flow.RoleConsensus)).Sort(order.Canonical[flow.Identity])
s.mockConsensus = &MockConsensus{identities: identities}

// mock storage headers
Expand Down
27 changes: 21 additions & 6 deletions consensus/hotstuff/committees/cluster_committee.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Cluster struct {
// pre-computed leader selection for the full lifecycle of the cluster
selection *leader.LeaderSelection
// a filter that returns all members of the cluster committee allowed to vote
clusterMemberFilter flow.IdentityFilter
clusterMemberFilter flow.IdentityFilter[flow.Identity]
// initial set of cluster members, WITHOUT dynamic weight changes
initialClusterMembers flow.IdentitySkeletonList
initialClusterIdentities flow.IdentityList
Expand All @@ -50,19 +50,34 @@ func NewClusterCommittee(
return nil, fmt.Errorf("could not compute leader selection for cluster: %w", err)
}

totalWeight := cluster.Members().ToSkeleton().TotalWeight()
initialClusterMembers := cluster.Members()
totalWeight := initialClusterMembers.TotalWeight()
initialClusterMembersSelector := initialClusterMembers.Selector()
// the next section is not very nice, but there are no dynamic identities for root block,
// and we need them to specificially handle querying of identities for root block
initialClusterIdentities := make(flow.IdentityList, 0, len(cluster.Members()))
for _, skeleton := range initialClusterMembers {
initialClusterIdentities = append(initialClusterIdentities, &flow.Identity{
IdentitySkeleton: *skeleton,
DynamicIdentity: flow.DynamicIdentity{
Weight: skeleton.InitialWeight,
Ejected: false,
},
})
}
AlexHentschel marked this conversation as resolved.
Show resolved Hide resolved
com := &Cluster{
state: state,
payloads: payloads,
me: me,
selection: selection,
clusterMemberFilter: filter.And(
cluster.Members().Selector(),
clusterMemberFilter: filter.And[flow.Identity](
// adapt the identity filter to the identity skeleton filter
filter.Adapt(initialClusterMembersSelector),
filter.Not(filter.Ejected),
filter.HasWeight(true),
),
initialClusterMembers: cluster.Members().ToSkeleton(),
initialClusterIdentities: cluster.Members(),
initialClusterMembers: initialClusterMembers,
initialClusterIdentities: initialClusterIdentities,
weightThresholdForQC: WeightThresholdToBuildQC(totalWeight),
weightThresholdForTO: WeightThresholdToTimeout(totalWeight),
}
Expand Down
16 changes: 2 additions & 14 deletions consensus/hotstuff/committees/cluster_committee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ func (suite *ClusterSuite) SetupTest() {
suite.members = unittest.IdentityListFixture(5, unittest.WithRole(flow.RoleCollection))
suite.me = suite.members[0]
counter := uint64(1)
suite.root = clusterstate.CanonicalRootBlock(counter, suite.members)
suite.root = clusterstate.CanonicalRootBlock(counter, suite.members.ToSkeleton())

suite.cluster.On("EpochCounter").Return(counter)
suite.cluster.On("Index").Return(uint(1))
suite.cluster.On("Members").Return(suite.members)
suite.cluster.On("Members").Return(suite.members.ToSkeleton())
suite.cluster.On("RootBlock").Return(suite.root)
suite.epoch.On("Counter").Return(counter, nil)
suite.epoch.On("RandomSource").Return(unittest.SeedFixture(prg.RandomSourceLength), nil)
Expand Down Expand Up @@ -146,12 +146,6 @@ func (suite *ClusterSuite) TestInvalidSigner() {
})

suite.Run("should return ErrInvalidSigner for existent but ejected cluster member", func() {
// at the root block, the cluster member is not ejected yet
suite.Run("root block", func() {
actual, err := suite.com.IdentityByBlock(rootBlockID, realEjectedClusterMember.NodeID)
suite.Require().NoError(err)
suite.Assert().Equal(realEjectedClusterMember, actual)
})
jordanschalm marked this conversation as resolved.
Show resolved Hide resolved
suite.Run("non-root block", func() {
_, err := suite.com.IdentityByBlock(nonRootBlockID, realEjectedClusterMember.NodeID)
suite.Assert().True(model.IsInvalidSignerError(err))
Expand All @@ -164,12 +158,6 @@ func (suite *ClusterSuite) TestInvalidSigner() {
})

suite.Run("should return ErrInvalidSigner for existent but zero-weight cluster member", func() {
// at the root block, the cluster member has its initial weight
suite.Run("root block", func() {
actual, err := suite.com.IdentityByBlock(rootBlockID, realNoWeightClusterMember.NodeID)
suite.Require().NoError(err)
suite.Assert().Equal(realNoWeightClusterMember, actual)
})
suite.Run("non-root block", func() {
_, err := suite.com.IdentityByBlock(nonRootBlockID, realNoWeightClusterMember.NodeID)
suite.Assert().True(model.IsInvalidSignerError(err))
Expand Down
2 changes: 1 addition & 1 deletion consensus/hotstuff/committees/consensus_committee.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func newStaticEpochInfo(epoch protocol.Epoch) (*staticEpochInfo, error) {
if err != nil {
return nil, fmt.Errorf("could not initial identities: %w", err)
}
initialCommittee := initialIdentities.Filter(filter.IsVotingConsensusCommitteeMember).ToSkeleton()
initialCommittee := initialIdentities.Filter(filter.IsAllowedConsensusCommitteeMember).ToSkeleton()
dkg, err := epoch.DKG()
if err != nil {
return nil, fmt.Errorf("could not get dkg: %w", err)
Expand Down
10 changes: 3 additions & 7 deletions consensus/hotstuff/committees/consensus_committee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,8 @@ func (suite *ConsensusSuite) TestIdentitiesByEpoch() {
// epoch 1 identities with varying conditions which would disqualify them
// from committee participation
realIdentity := unittest.IdentityFixture(unittest.WithRole(flow.RoleConsensus))
zeroWeightConsensusIdentity := unittest.IdentityFixture(unittest.WithRole(flow.RoleConsensus), unittest.WithWeight(0))
zeroWeightConsensusIdentity := unittest.IdentityFixture(unittest.WithRole(flow.RoleConsensus),
unittest.WithInitialWeight(0))
ejectedConsensusIdentity := unittest.IdentityFixture(unittest.WithRole(flow.RoleConsensus), unittest.WithEjected(true))
validNonConsensusIdentity := unittest.IdentityFixture(unittest.WithRole(flow.RoleVerification))
epoch1Identities := flow.IdentityList{realIdentity, zeroWeightConsensusIdentity, ejectedConsensusIdentity, validNonConsensusIdentity}
Expand Down Expand Up @@ -356,11 +357,6 @@ func (suite *ConsensusSuite) TestIdentitiesByEpoch() {
require.True(t, model.IsInvalidSignerError(err))
})

t.Run("ejected consensus node", func(t *testing.T) {
_, err := suite.committee.IdentityByEpoch(unittest.Uint64InRange(1, 100), ejectedConsensusIdentity.NodeID)
require.True(t, model.IsInvalidSignerError(err))
})

t.Run("otherwise valid non-consensus node", func(t *testing.T) {
_, err := suite.committee.IdentityByEpoch(unittest.Uint64InRange(1, 100), validNonConsensusIdentity.NodeID)
require.True(t, model.IsInvalidSignerError(err))
Expand Down Expand Up @@ -679,7 +675,7 @@ func newMockEpoch(counter uint64, identities flow.IdentityList, firstView uint64

epoch := new(protocolmock.Epoch)
epoch.On("Counter").Return(counter, nil)
epoch.On("InitialIdentities").Return(identities, nil)
epoch.On("InitialIdentities").Return(identities.ToSkeleton(), nil)
epoch.On("FirstView").Return(firstView, nil)
epoch.On("FinalView").Return(finalView, nil)
if committed {
Expand Down
2 changes: 1 addition & 1 deletion consensus/hotstuff/committees/leader/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func SelectionForConsensus(epoch protocol.Epoch) (*LeaderSelection, error) {
firstView,
rng,
int(finalView-firstView+1), // add 1 because both first/final view are inclusive
identities.Filter(filter.IsVotingConsensusCommitteeMember).ToSkeleton(),
identities.Filter(filter.IsAllowedConsensusCommitteeMember),
)
return leaders, err
}
Loading
Loading