github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/message/authorization.go (about) 1 package message 2 3 import ( 4 "github.com/onflow/flow-go/model/flow" 5 "github.com/onflow/flow-go/model/libp2p/message" 6 "github.com/onflow/flow-go/model/messages" 7 "github.com/onflow/flow-go/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 ProtocolType) 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{ProtocolTypePubSub}, 70 }, 71 channels.PushBlocks: { 72 AuthorizedRoles: flow.RoleList{flow.RoleConsensus}, 73 AllowedProtocols: Protocols{ProtocolTypePubSub}, 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{ProtocolTypeUnicast}, 86 }, 87 }, 88 } 89 authorizationConfigs[TimeoutObject] = MsgAuthConfig{ 90 Name: TimeoutObject, 91 Type: func() interface{} { 92 return new(messages.TimeoutObject) 93 }, 94 Config: map[channels.Channel]ChannelAuthConfig{ 95 channels.ConsensusCommittee: { 96 AuthorizedRoles: flow.RoleList{flow.RoleConsensus}, 97 AllowedProtocols: Protocols{ProtocolTypePubSub}, 98 }, 99 }, 100 } 101 102 // protocol state sync 103 authorizationConfigs[SyncRequest] = MsgAuthConfig{ 104 Name: SyncRequest, 105 Type: func() interface{} { 106 return new(messages.SyncRequest) 107 }, 108 Config: map[channels.Channel]ChannelAuthConfig{ 109 channels.SyncCommittee: { 110 AuthorizedRoles: flow.Roles(), 111 AllowedProtocols: Protocols{ProtocolTypePubSub}, 112 }, 113 channels.SyncClusterPrefix: { 114 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 115 AllowedProtocols: Protocols{ProtocolTypePubSub}, 116 }, 117 }, 118 } 119 authorizationConfigs[SyncResponse] = MsgAuthConfig{ 120 Name: SyncResponse, 121 Type: func() interface{} { 122 return new(messages.SyncResponse) 123 }, 124 Config: map[channels.Channel]ChannelAuthConfig{ 125 channels.SyncCommittee: { 126 AuthorizedRoles: flow.RoleList{flow.RoleConsensus}, 127 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 128 }, 129 channels.SyncClusterPrefix: { 130 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 131 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 132 }, 133 }, 134 } 135 authorizationConfigs[RangeRequest] = MsgAuthConfig{ 136 Name: RangeRequest, 137 Type: func() interface{} { 138 return new(messages.RangeRequest) 139 }, 140 Config: map[channels.Channel]ChannelAuthConfig{ 141 channels.SyncCommittee: { 142 AuthorizedRoles: flow.Roles(), 143 AllowedProtocols: Protocols{ProtocolTypePubSub}, 144 }, 145 channels.SyncClusterPrefix: { 146 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 147 AllowedProtocols: Protocols{ProtocolTypePubSub}, 148 }, 149 }, 150 } 151 authorizationConfigs[BatchRequest] = MsgAuthConfig{ 152 Name: BatchRequest, 153 Type: func() interface{} { 154 return new(messages.BatchRequest) 155 }, 156 Config: map[channels.Channel]ChannelAuthConfig{ 157 channels.SyncCommittee: { 158 AuthorizedRoles: flow.Roles(), 159 AllowedProtocols: Protocols{ProtocolTypePubSub}, 160 }, 161 channels.SyncClusterPrefix: { 162 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 163 AllowedProtocols: Protocols{ProtocolTypePubSub}, 164 }, 165 }, 166 } 167 authorizationConfigs[BlockResponse] = MsgAuthConfig{ 168 Name: BlockResponse, 169 Type: func() interface{} { 170 return new(messages.BlockResponse) 171 }, 172 Config: map[channels.Channel]ChannelAuthConfig{ 173 channels.SyncCommittee: { 174 AuthorizedRoles: flow.RoleList{flow.RoleConsensus}, 175 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 176 }, 177 }, 178 } 179 180 // cluster consensus 181 authorizationConfigs[ClusterBlockProposal] = MsgAuthConfig{ 182 Name: ClusterBlockProposal, 183 Type: func() interface{} { 184 return new(messages.ClusterBlockProposal) 185 }, 186 Config: map[channels.Channel]ChannelAuthConfig{ 187 channels.ConsensusClusterPrefix: { 188 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 189 AllowedProtocols: Protocols{ProtocolTypePubSub}, 190 }, 191 }, 192 } 193 authorizationConfigs[ClusterBlockVote] = MsgAuthConfig{ 194 Name: ClusterBlockVote, 195 Type: func() interface{} { 196 return new(messages.ClusterBlockVote) 197 }, 198 Config: map[channels.Channel]ChannelAuthConfig{ 199 channels.ConsensusClusterPrefix: { 200 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 201 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 202 }, 203 }, 204 } 205 authorizationConfigs[ClusterTimeoutObject] = MsgAuthConfig{ 206 Name: ClusterTimeoutObject, 207 Type: func() interface{} { 208 return new(messages.ClusterTimeoutObject) 209 }, 210 Config: map[channels.Channel]ChannelAuthConfig{ 211 channels.ConsensusClusterPrefix: { 212 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 213 AllowedProtocols: Protocols{ProtocolTypePubSub}, 214 }, 215 }, 216 } 217 authorizationConfigs[ClusterBlockResponse] = MsgAuthConfig{ 218 Name: ClusterBlockResponse, 219 Type: func() interface{} { 220 return new(messages.ClusterBlockResponse) 221 }, 222 Config: map[channels.Channel]ChannelAuthConfig{ 223 channels.SyncClusterPrefix: { 224 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 225 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 226 }, 227 }, 228 } 229 230 // collections, guarantees & transactions 231 authorizationConfigs[CollectionGuarantee] = MsgAuthConfig{ 232 Name: CollectionGuarantee, 233 Type: func() interface{} { 234 return new(flow.CollectionGuarantee) 235 }, 236 Config: map[channels.Channel]ChannelAuthConfig{ 237 channels.PushGuarantees: { 238 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 239 AllowedProtocols: Protocols{ProtocolTypePubSub}, 240 }, // channel alias ReceiveGuarantees = PushGuarantees 241 }, 242 } 243 authorizationConfigs[TransactionBody] = MsgAuthConfig{ 244 Name: TransactionBody, 245 Type: func() interface{} { 246 return new(flow.TransactionBody) 247 }, 248 Config: map[channels.Channel]ChannelAuthConfig{ 249 channels.PushTransactions: { 250 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 251 AllowedProtocols: Protocols{ProtocolTypePubSub}, 252 }, // channel alias ReceiveTransactions = PushTransactions 253 }, 254 } 255 256 // core messages for execution & verification 257 authorizationConfigs[ExecutionReceipt] = MsgAuthConfig{ 258 Name: ExecutionReceipt, 259 Type: func() interface{} { 260 return new(flow.ExecutionReceipt) 261 }, 262 Config: map[channels.Channel]ChannelAuthConfig{ 263 channels.PushReceipts: { 264 AuthorizedRoles: flow.RoleList{flow.RoleExecution}, 265 AllowedProtocols: Protocols{ProtocolTypePubSub}, 266 }, // channel alias ReceiveReceipts = PushReceipts 267 }, 268 } 269 authorizationConfigs[ResultApproval] = MsgAuthConfig{ 270 Name: ResultApproval, 271 Type: func() interface{} { 272 return new(flow.ResultApproval) 273 }, 274 Config: map[channels.Channel]ChannelAuthConfig{ 275 channels.PushApprovals: { 276 AuthorizedRoles: flow.RoleList{flow.RoleVerification}, 277 AllowedProtocols: Protocols{ProtocolTypePubSub}, 278 }, // channel alias ReceiveApprovals = PushApprovals 279 }, 280 } 281 282 // data exchange for execution of blocks 283 authorizationConfigs[ChunkDataRequest] = MsgAuthConfig{ 284 Name: ChunkDataRequest, 285 Type: func() interface{} { 286 return new(messages.ChunkDataRequest) 287 }, 288 Config: map[channels.Channel]ChannelAuthConfig{ 289 channels.RequestChunks: { 290 AuthorizedRoles: flow.RoleList{flow.RoleVerification}, 291 AllowedProtocols: Protocols{ProtocolTypePubSub}, 292 }, // channel alias RequestChunks = ProvideChunks 293 }, 294 } 295 authorizationConfigs[ChunkDataResponse] = MsgAuthConfig{ 296 Name: ChunkDataResponse, 297 Type: func() interface{} { 298 return new(messages.ChunkDataResponse) 299 }, 300 Config: map[channels.Channel]ChannelAuthConfig{ 301 channels.ProvideChunks: { 302 AuthorizedRoles: flow.RoleList{flow.RoleExecution}, 303 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 304 }, // channel alias RequestChunks = ProvideChunks 305 }, 306 } 307 308 // result approvals 309 authorizationConfigs[ApprovalRequest] = MsgAuthConfig{ 310 Name: ApprovalRequest, 311 Type: func() interface{} { 312 return new(messages.ApprovalRequest) 313 }, 314 Config: map[channels.Channel]ChannelAuthConfig{ 315 channels.RequestApprovalsByChunk: { 316 AuthorizedRoles: flow.RoleList{flow.RoleConsensus}, 317 AllowedProtocols: Protocols{ProtocolTypePubSub}, 318 }, // channel alias ProvideApprovalsByChunk = RequestApprovalsByChunk 319 }, 320 } 321 authorizationConfigs[ApprovalResponse] = MsgAuthConfig{ 322 Name: ApprovalResponse, 323 Type: func() interface{} { 324 return new(messages.ApprovalResponse) 325 }, 326 Config: map[channels.Channel]ChannelAuthConfig{ 327 channels.ProvideApprovalsByChunk: { 328 AuthorizedRoles: flow.RoleList{flow.RoleVerification}, 329 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 330 }, // channel alias ProvideApprovalsByChunk = RequestApprovalsByChunk 331 }, 332 } 333 334 // generic entity exchange engines 335 authorizationConfigs[EntityRequest] = MsgAuthConfig{ 336 Name: EntityRequest, 337 Type: func() interface{} { 338 return new(messages.EntityRequest) 339 }, 340 Config: map[channels.Channel]ChannelAuthConfig{ 341 channels.RequestReceiptsByBlockID: { 342 AuthorizedRoles: flow.RoleList{flow.RoleConsensus}, 343 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 344 }, 345 channels.RequestCollections: { 346 AuthorizedRoles: flow.RoleList{flow.RoleAccess, flow.RoleExecution}, 347 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 348 }, 349 }, 350 } 351 authorizationConfigs[EntityResponse] = MsgAuthConfig{ 352 Name: EntityResponse, 353 Type: func() interface{} { 354 return new(messages.EntityResponse) 355 }, 356 Config: map[channels.Channel]ChannelAuthConfig{ 357 channels.ProvideReceiptsByBlockID: { 358 AuthorizedRoles: flow.RoleList{flow.RoleExecution}, 359 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 360 }, 361 channels.ProvideCollections: { 362 AuthorizedRoles: flow.RoleList{flow.RoleCollection}, 363 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 364 }, 365 }, 366 } 367 368 // testing 369 authorizationConfigs[TestMessage] = MsgAuthConfig{ 370 Name: TestMessage, 371 Type: func() interface{} { 372 return new(message.TestMessage) 373 }, 374 Config: map[channels.Channel]ChannelAuthConfig{ 375 channels.TestNetworkChannel: { 376 AuthorizedRoles: flow.Roles(), 377 AllowedProtocols: Protocols{ProtocolTypePubSub, ProtocolTypeUnicast}, 378 }, 379 channels.TestMetricsChannel: { 380 AuthorizedRoles: flow.Roles(), 381 AllowedProtocols: Protocols{ProtocolTypePubSub, ProtocolTypeUnicast}, 382 }, 383 }, 384 } 385 386 // DKG 387 authorizationConfigs[DKGMessage] = MsgAuthConfig{ 388 Name: DKGMessage, 389 Type: func() interface{} { 390 return new(messages.DKGMessage) 391 }, 392 Config: map[channels.Channel]ChannelAuthConfig{ 393 channels.DKGCommittee: { 394 AuthorizedRoles: flow.RoleList{flow.RoleConsensus}, 395 AllowedProtocols: Protocols{ProtocolTypeUnicast}, 396 }, 397 }, 398 } 399 } 400 401 // GetMessageAuthConfig checks the underlying type and returns the correct 402 // message auth Config. 403 // Expected error returns during normal operations: 404 // - ErrUnknownMsgType : if underlying type of v does not match any of the known message types 405 func GetMessageAuthConfig(v interface{}) (MsgAuthConfig, error) { 406 switch v.(type) { 407 // consensus 408 case *messages.BlockProposal: 409 return authorizationConfigs[BlockProposal], nil 410 case *messages.BlockVote: 411 return authorizationConfigs[BlockVote], nil 412 case *messages.TimeoutObject: 413 return authorizationConfigs[TimeoutObject], nil 414 415 // protocol state sync 416 case *messages.SyncRequest: 417 return authorizationConfigs[SyncRequest], nil 418 case *messages.SyncResponse: 419 return authorizationConfigs[SyncResponse], nil 420 case *messages.RangeRequest: 421 return authorizationConfigs[RangeRequest], nil 422 case *messages.BatchRequest: 423 return authorizationConfigs[BatchRequest], nil 424 case *messages.BlockResponse: 425 return authorizationConfigs[BlockResponse], nil 426 427 // cluster consensus 428 case *messages.ClusterBlockProposal: 429 return authorizationConfigs[ClusterBlockProposal], nil 430 case *messages.ClusterBlockVote: 431 return authorizationConfigs[ClusterBlockVote], nil 432 case *messages.ClusterTimeoutObject: 433 return authorizationConfigs[ClusterTimeoutObject], nil 434 case *messages.ClusterBlockResponse: 435 return authorizationConfigs[ClusterBlockResponse], nil 436 437 // collections, guarantees & transactions 438 case *flow.CollectionGuarantee: 439 return authorizationConfigs[CollectionGuarantee], nil 440 case *flow.TransactionBody: 441 return authorizationConfigs[TransactionBody], nil 442 443 // core messages for execution & verification 444 case *flow.ExecutionReceipt: 445 return authorizationConfigs[ExecutionReceipt], nil 446 case *flow.ResultApproval: 447 return authorizationConfigs[ResultApproval], nil 448 449 // data exchange for execution of blocks 450 case *messages.ChunkDataRequest: 451 return authorizationConfigs[ChunkDataRequest], nil 452 case *messages.ChunkDataResponse: 453 return authorizationConfigs[ChunkDataResponse], nil 454 455 // result approvals 456 case *messages.ApprovalRequest: 457 return authorizationConfigs[ApprovalRequest], nil 458 case *messages.ApprovalResponse: 459 return authorizationConfigs[ApprovalResponse], nil 460 461 // generic entity exchange engines 462 case *messages.EntityRequest: 463 return authorizationConfigs[EntityRequest], nil 464 case *messages.EntityResponse: 465 return authorizationConfigs[EntityResponse], nil 466 467 // testing 468 case *message.TestMessage: 469 return authorizationConfigs[TestMessage], nil 470 471 // dkg 472 case *messages.DKGMessage: 473 return authorizationConfigs[DKGMessage], nil 474 475 default: 476 return MsgAuthConfig{}, NewUnknownMsgTypeErr(v) 477 } 478 } 479 480 // GetAllMessageAuthConfigs returns all the configured message auth configurations. 481 func GetAllMessageAuthConfigs() []MsgAuthConfig { 482 configs := make([]MsgAuthConfig, len(authorizationConfigs)) 483 484 i := 0 485 for _, config := range authorizationConfigs { 486 configs[i] = config 487 i++ 488 } 489 490 return configs 491 }