github.com/koko1123/flow-go-1@v0.29.6/network/message/authorization.go (about)

     1  package message
     2  
     3  import (
     4  	"github.com/koko1123/flow-go-1/model/flow"
     5  	"github.com/koko1123/flow-go-1/model/libp2p/message"
     6  	"github.com/koko1123/flow-go-1/model/messages"
     7  	"github.com/koko1123/flow-go-1/network/channels"
     8  )
     9  
    10  type ChannelAuthConfig struct {
    11  	// AuthorizedRoles list of roles authorized to send this message on the channel.
    12  	AuthorizedRoles flow.RoleList
    13  
    14  	// AllowedProtocols list of protocols the message is allowed to be sent on. Currently AllowedProtocols is expected to have
    15  	// exactly one element in the list. This is due to the fact that currently there are no messages that are used with both protocols aside from TestMessage.
    16  	AllowedProtocols Protocols
    17  }
    18  
    19  var authorizationConfigs map[string]MsgAuthConfig
    20  
    21  // MsgAuthConfig contains authorization information for a specific flow message. The authorization
    22  // is represented as a map from network channel -> list of all roles allowed to send the message on
    23  // the channel.
    24  type MsgAuthConfig struct {
    25  	// Name is the string representation of the message type.
    26  	Name string
    27  	// Type is a func that returns a new instance of message type.
    28  	Type func() interface{}
    29  	// Config is the mapping of network channel to list of authorized flow roles.
    30  	Config map[channels.Channel]ChannelAuthConfig
    31  }
    32  
    33  // EnsureAuthorized checks if the specified role is authorized to send the message on the provided channel and
    34  // asserts that the message is authorized to be sent on the channel.
    35  // Expected error returns during normal operations:
    36  //   - ErrUnauthorizedMessageOnChannel: the channel is not included in the message's list of authorized channels
    37  //   - ErrUnauthorizedRole: the role is not included in the message's list of authorized roles for the provided channel
    38  //   - ErrUnauthorizedUnicastOnChannel: the message is not authorized to be sent via unicast protocol.
    39  //   - ErrUnauthorizedPublishOnChannel: the message is not authorized to be sent via publish protocol.
    40  func (m MsgAuthConfig) EnsureAuthorized(role flow.Role, channel channels.Channel, protocol Protocol) error {
    41  	authConfig, ok := m.Config[channel]
    42  	if !ok {
    43  		return ErrUnauthorizedMessageOnChannel
    44  	}
    45  
    46  	if !authConfig.AuthorizedRoles.Contains(role) {
    47  		return ErrUnauthorizedRole
    48  	}
    49  
    50  	if !authConfig.AllowedProtocols.Contains(protocol) {
    51  		return NewUnauthorizedProtocolError(protocol)
    52  	}
    53  
    54  	return nil
    55  }
    56  
    57  func initializeMessageAuthConfigsMap() {
    58  	authorizationConfigs = make(map[string]MsgAuthConfig)
    59  
    60  	// consensus
    61  	authorizationConfigs[BlockProposal] = MsgAuthConfig{
    62  		Name: BlockProposal,
    63  		Type: func() interface{} {
    64  			return new(messages.BlockProposal)
    65  		},
    66  		Config: map[channels.Channel]ChannelAuthConfig{
    67  			channels.ConsensusCommittee: {
    68  				AuthorizedRoles:  flow.RoleList{flow.RoleConsensus},
    69  				AllowedProtocols: Protocols{ProtocolPublish},
    70  			},
    71  			channels.PushBlocks: {
    72  				AuthorizedRoles:  flow.RoleList{flow.RoleConsensus},
    73  				AllowedProtocols: Protocols{ProtocolPublish},
    74  			}, // channel alias ReceiveBlocks = PushBlocks
    75  		},
    76  	}
    77  	authorizationConfigs[BlockVote] = MsgAuthConfig{
    78  		Name: BlockVote,
    79  		Type: func() interface{} {
    80  			return new(messages.BlockVote)
    81  		},
    82  		Config: map[channels.Channel]ChannelAuthConfig{
    83  			channels.ConsensusCommittee: {
    84  				AuthorizedRoles:  flow.RoleList{flow.RoleConsensus},
    85  				AllowedProtocols: Protocols{ProtocolUnicast},
    86  			},
    87  		},
    88  	}
    89  
    90  	// protocol state sync
    91  	authorizationConfigs[SyncRequest] = MsgAuthConfig{
    92  		Name: SyncRequest,
    93  		Type: func() interface{} {
    94  			return new(messages.SyncRequest)
    95  		},
    96  		Config: map[channels.Channel]ChannelAuthConfig{
    97  			channels.SyncCommittee: {
    98  				AuthorizedRoles:  flow.Roles(),
    99  				AllowedProtocols: Protocols{ProtocolPublish},
   100  			},
   101  			channels.SyncClusterPrefix: {
   102  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   103  				AllowedProtocols: Protocols{ProtocolPublish},
   104  			},
   105  		},
   106  	}
   107  	authorizationConfigs[SyncResponse] = MsgAuthConfig{
   108  		Name: SyncResponse,
   109  		Type: func() interface{} {
   110  			return new(messages.SyncResponse)
   111  		},
   112  		Config: map[channels.Channel]ChannelAuthConfig{
   113  			channels.SyncCommittee: {
   114  				AuthorizedRoles:  flow.RoleList{flow.RoleConsensus},
   115  				AllowedProtocols: Protocols{ProtocolUnicast},
   116  			},
   117  			channels.SyncClusterPrefix: {
   118  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   119  				AllowedProtocols: Protocols{ProtocolUnicast},
   120  			},
   121  		},
   122  	}
   123  	authorizationConfigs[RangeRequest] = MsgAuthConfig{
   124  		Name: RangeRequest,
   125  		Type: func() interface{} {
   126  			return new(messages.RangeRequest)
   127  		},
   128  		Config: map[channels.Channel]ChannelAuthConfig{
   129  			channels.SyncCommittee: {
   130  				AuthorizedRoles:  flow.Roles(),
   131  				AllowedProtocols: Protocols{ProtocolPublish},
   132  			},
   133  			channels.SyncClusterPrefix: {
   134  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   135  				AllowedProtocols: Protocols{ProtocolPublish},
   136  			},
   137  		},
   138  	}
   139  	authorizationConfigs[BatchRequest] = MsgAuthConfig{
   140  		Name: BatchRequest,
   141  		Type: func() interface{} {
   142  			return new(messages.BatchRequest)
   143  		},
   144  		Config: map[channels.Channel]ChannelAuthConfig{
   145  			channels.SyncCommittee: {
   146  				AuthorizedRoles:  flow.Roles(),
   147  				AllowedProtocols: Protocols{ProtocolPublish},
   148  			},
   149  			channels.SyncClusterPrefix: {
   150  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   151  				AllowedProtocols: Protocols{ProtocolPublish},
   152  			},
   153  		},
   154  	}
   155  	authorizationConfigs[BlockResponse] = MsgAuthConfig{
   156  		Name: BlockResponse,
   157  		Type: func() interface{} {
   158  			return new(messages.BlockResponse)
   159  		},
   160  		Config: map[channels.Channel]ChannelAuthConfig{
   161  			channels.SyncCommittee: {
   162  				AuthorizedRoles:  flow.RoleList{flow.RoleConsensus},
   163  				AllowedProtocols: Protocols{ProtocolUnicast},
   164  			},
   165  		},
   166  	}
   167  
   168  	// cluster consensus
   169  	authorizationConfigs[ClusterBlockProposal] = MsgAuthConfig{
   170  		Name: ClusterBlockProposal,
   171  		Type: func() interface{} {
   172  			return new(messages.ClusterBlockProposal)
   173  		},
   174  		Config: map[channels.Channel]ChannelAuthConfig{
   175  			channels.ConsensusClusterPrefix: {
   176  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   177  				AllowedProtocols: Protocols{ProtocolPublish},
   178  			},
   179  		},
   180  	}
   181  	authorizationConfigs[ClusterBlockVote] = MsgAuthConfig{
   182  		Name: ClusterBlockVote,
   183  		Type: func() interface{} {
   184  			return new(messages.ClusterBlockVote)
   185  		},
   186  		Config: map[channels.Channel]ChannelAuthConfig{
   187  			channels.ConsensusClusterPrefix: {
   188  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   189  				AllowedProtocols: Protocols{ProtocolUnicast},
   190  			},
   191  		},
   192  	}
   193  	authorizationConfigs[ClusterBlockResponse] = MsgAuthConfig{
   194  		Name: ClusterBlockResponse,
   195  		Type: func() interface{} {
   196  			return new(messages.ClusterBlockResponse)
   197  		},
   198  		Config: map[channels.Channel]ChannelAuthConfig{
   199  			channels.SyncClusterPrefix: {
   200  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   201  				AllowedProtocols: Protocols{ProtocolUnicast},
   202  			},
   203  		},
   204  	}
   205  
   206  	// collections, guarantees & transactions
   207  	authorizationConfigs[CollectionGuarantee] = MsgAuthConfig{
   208  		Name: CollectionGuarantee,
   209  		Type: func() interface{} {
   210  			return new(flow.CollectionGuarantee)
   211  		},
   212  		Config: map[channels.Channel]ChannelAuthConfig{
   213  			channels.PushGuarantees: {
   214  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   215  				AllowedProtocols: Protocols{ProtocolPublish},
   216  			}, // channel alias ReceiveGuarantees = PushGuarantees
   217  		},
   218  	}
   219  	authorizationConfigs[TransactionBody] = MsgAuthConfig{
   220  		Name: TransactionBody,
   221  		Type: func() interface{} {
   222  			return new(flow.TransactionBody)
   223  		},
   224  		Config: map[channels.Channel]ChannelAuthConfig{
   225  			channels.PushTransactions: {
   226  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   227  				AllowedProtocols: Protocols{ProtocolPublish},
   228  			}, // channel alias ReceiveTransactions = PushTransactions
   229  		},
   230  	}
   231  
   232  	// core messages for execution & verification
   233  	authorizationConfigs[ExecutionReceipt] = MsgAuthConfig{
   234  		Name: ExecutionReceipt,
   235  		Type: func() interface{} {
   236  			return new(flow.ExecutionReceipt)
   237  		},
   238  		Config: map[channels.Channel]ChannelAuthConfig{
   239  			channels.PushReceipts: {
   240  				AuthorizedRoles:  flow.RoleList{flow.RoleExecution},
   241  				AllowedProtocols: Protocols{ProtocolPublish},
   242  			}, // channel alias ReceiveReceipts = PushReceipts
   243  		},
   244  	}
   245  	authorizationConfigs[ResultApproval] = MsgAuthConfig{
   246  		Name: ResultApproval,
   247  		Type: func() interface{} {
   248  			return new(flow.ResultApproval)
   249  		},
   250  		Config: map[channels.Channel]ChannelAuthConfig{
   251  			channels.PushApprovals: {
   252  				AuthorizedRoles:  flow.RoleList{flow.RoleVerification},
   253  				AllowedProtocols: Protocols{ProtocolPublish},
   254  			}, // channel alias ReceiveApprovals = PushApprovals
   255  		},
   256  	}
   257  
   258  	// data exchange for execution of blocks
   259  	authorizationConfigs[ChunkDataRequest] = MsgAuthConfig{
   260  		Name: ChunkDataRequest,
   261  		Type: func() interface{} {
   262  			return new(messages.ChunkDataRequest)
   263  		},
   264  		Config: map[channels.Channel]ChannelAuthConfig{
   265  			channels.RequestChunks: {
   266  				AuthorizedRoles:  flow.RoleList{flow.RoleVerification},
   267  				AllowedProtocols: Protocols{ProtocolPublish},
   268  			}, // channel alias RequestChunks = ProvideChunks
   269  		},
   270  	}
   271  	authorizationConfigs[ChunkDataResponse] = MsgAuthConfig{
   272  		Name: ChunkDataResponse,
   273  		Type: func() interface{} {
   274  			return new(messages.ChunkDataResponse)
   275  		},
   276  		Config: map[channels.Channel]ChannelAuthConfig{
   277  			channels.ProvideChunks: {
   278  				AuthorizedRoles:  flow.RoleList{flow.RoleExecution},
   279  				AllowedProtocols: Protocols{ProtocolUnicast},
   280  			}, // channel alias RequestChunks = ProvideChunks
   281  		},
   282  	}
   283  
   284  	// result approvals
   285  	authorizationConfigs[ApprovalRequest] = MsgAuthConfig{
   286  		Name: ApprovalRequest,
   287  		Type: func() interface{} {
   288  			return new(messages.ApprovalRequest)
   289  		},
   290  		Config: map[channels.Channel]ChannelAuthConfig{
   291  			channels.RequestApprovalsByChunk: {
   292  				AuthorizedRoles:  flow.RoleList{flow.RoleConsensus},
   293  				AllowedProtocols: Protocols{ProtocolPublish},
   294  			}, // channel alias ProvideApprovalsByChunk  = RequestApprovalsByChunk
   295  		},
   296  	}
   297  	authorizationConfigs[ApprovalResponse] = MsgAuthConfig{
   298  		Name: ApprovalResponse,
   299  		Type: func() interface{} {
   300  			return new(messages.ApprovalResponse)
   301  		},
   302  		Config: map[channels.Channel]ChannelAuthConfig{
   303  			channels.ProvideApprovalsByChunk: {
   304  				AuthorizedRoles:  flow.RoleList{flow.RoleVerification},
   305  				AllowedProtocols: Protocols{ProtocolUnicast},
   306  			}, // channel alias ProvideApprovalsByChunk  = RequestApprovalsByChunk
   307  		},
   308  	}
   309  
   310  	// generic entity exchange engines
   311  	authorizationConfigs[EntityRequest] = MsgAuthConfig{
   312  		Name: EntityRequest,
   313  		Type: func() interface{} {
   314  			return new(messages.EntityRequest)
   315  		},
   316  		Config: map[channels.Channel]ChannelAuthConfig{
   317  			channels.RequestReceiptsByBlockID: {
   318  				AuthorizedRoles:  flow.RoleList{flow.RoleConsensus},
   319  				AllowedProtocols: Protocols{ProtocolUnicast},
   320  			},
   321  			channels.RequestCollections: {
   322  				AuthorizedRoles:  flow.RoleList{flow.RoleAccess, flow.RoleExecution},
   323  				AllowedProtocols: Protocols{ProtocolUnicast},
   324  			},
   325  		},
   326  	}
   327  	authorizationConfigs[EntityResponse] = MsgAuthConfig{
   328  		Name: EntityResponse,
   329  		Type: func() interface{} {
   330  			return new(messages.EntityResponse)
   331  		},
   332  		Config: map[channels.Channel]ChannelAuthConfig{
   333  			channels.ProvideReceiptsByBlockID: {
   334  				AuthorizedRoles:  flow.RoleList{flow.RoleExecution},
   335  				AllowedProtocols: Protocols{ProtocolUnicast},
   336  			},
   337  			channels.ProvideCollections: {
   338  				AuthorizedRoles:  flow.RoleList{flow.RoleCollection},
   339  				AllowedProtocols: Protocols{ProtocolUnicast},
   340  			},
   341  		},
   342  	}
   343  
   344  	// testing
   345  	authorizationConfigs[TestMessage] = MsgAuthConfig{
   346  		Name: TestMessage,
   347  		Type: func() interface{} {
   348  			return new(message.TestMessage)
   349  		},
   350  		Config: map[channels.Channel]ChannelAuthConfig{
   351  			channels.TestNetworkChannel: {
   352  				AuthorizedRoles:  flow.Roles(),
   353  				AllowedProtocols: Protocols{ProtocolPublish, ProtocolUnicast},
   354  			},
   355  			channels.TestMetricsChannel: {
   356  				AuthorizedRoles:  flow.Roles(),
   357  				AllowedProtocols: Protocols{ProtocolPublish, ProtocolUnicast},
   358  			},
   359  		},
   360  	}
   361  
   362  	// DKG
   363  	authorizationConfigs[DKGMessage] = MsgAuthConfig{
   364  		Name: DKGMessage,
   365  		Type: func() interface{} {
   366  			return new(messages.DKGMessage)
   367  		},
   368  		Config: map[channels.Channel]ChannelAuthConfig{
   369  			channels.DKGCommittee: {
   370  				AuthorizedRoles:  flow.RoleList{flow.RoleConsensus},
   371  				AllowedProtocols: Protocols{ProtocolUnicast},
   372  			},
   373  		},
   374  	}
   375  }
   376  
   377  // GetMessageAuthConfig checks the underlying type and returns the correct
   378  // message auth Config.
   379  // Expected error returns during normal operations:
   380  //   - ErrUnknownMsgType : if underlying type of v does  not match any of the known message types
   381  func GetMessageAuthConfig(v interface{}) (MsgAuthConfig, error) {
   382  	switch v.(type) {
   383  	// consensus
   384  	case *messages.BlockProposal:
   385  		return authorizationConfigs[BlockProposal], nil
   386  	case *messages.BlockVote:
   387  		return authorizationConfigs[BlockVote], nil
   388  
   389  	// protocol state sync
   390  	case *messages.SyncRequest:
   391  		return authorizationConfigs[SyncRequest], nil
   392  	case *messages.SyncResponse:
   393  		return authorizationConfigs[SyncResponse], nil
   394  	case *messages.RangeRequest:
   395  		return authorizationConfigs[RangeRequest], nil
   396  	case *messages.BatchRequest:
   397  		return authorizationConfigs[BatchRequest], nil
   398  	case *messages.BlockResponse:
   399  		return authorizationConfigs[BlockResponse], nil
   400  
   401  	// cluster consensus
   402  	case *messages.ClusterBlockProposal:
   403  		return authorizationConfigs[ClusterBlockProposal], nil
   404  	case *messages.ClusterBlockVote:
   405  		return authorizationConfigs[ClusterBlockVote], nil
   406  	case *messages.ClusterBlockResponse:
   407  		return authorizationConfigs[ClusterBlockResponse], nil
   408  
   409  	// collections, guarantees & transactions
   410  	case *flow.CollectionGuarantee:
   411  		return authorizationConfigs[CollectionGuarantee], nil
   412  	case *flow.TransactionBody:
   413  		return authorizationConfigs[TransactionBody], nil
   414  
   415  	// core messages for execution & verification
   416  	case *flow.ExecutionReceipt:
   417  		return authorizationConfigs[ExecutionReceipt], nil
   418  	case *flow.ResultApproval:
   419  		return authorizationConfigs[ResultApproval], nil
   420  
   421  	// data exchange for execution of blocks
   422  	case *messages.ChunkDataRequest:
   423  		return authorizationConfigs[ChunkDataRequest], nil
   424  	case *messages.ChunkDataResponse:
   425  		return authorizationConfigs[ChunkDataResponse], nil
   426  
   427  	// result approvals
   428  	case *messages.ApprovalRequest:
   429  		return authorizationConfigs[ApprovalRequest], nil
   430  	case *messages.ApprovalResponse:
   431  		return authorizationConfigs[ApprovalResponse], nil
   432  
   433  	// generic entity exchange engines
   434  	case *messages.EntityRequest:
   435  		return authorizationConfigs[EntityRequest], nil
   436  	case *messages.EntityResponse:
   437  		return authorizationConfigs[EntityResponse], nil
   438  
   439  	// testing
   440  	case *message.TestMessage:
   441  		return authorizationConfigs[TestMessage], nil
   442  
   443  	// dkg
   444  	case *messages.DKGMessage:
   445  		return authorizationConfigs[DKGMessage], nil
   446  
   447  	default:
   448  		return MsgAuthConfig{}, NewUnknownMsgTypeErr(v)
   449  	}
   450  }
   451  
   452  // GetAllMessageAuthConfigs returns all the configured message auth configurations.
   453  func GetAllMessageAuthConfigs() []MsgAuthConfig {
   454  	configs := make([]MsgAuthConfig, len(authorizationConfigs))
   455  
   456  	i := 0
   457  	for _, config := range authorizationConfigs {
   458  		configs[i] = config
   459  		i++
   460  	}
   461  
   462  	return configs
   463  }