github.com/MetalBlockchain/metalgo@v1.11.9/message/ops.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package message 5 6 import ( 7 "errors" 8 "fmt" 9 10 "github.com/MetalBlockchain/metalgo/proto/pb/p2p" 11 "github.com/MetalBlockchain/metalgo/utils/set" 12 ) 13 14 // Op is an opcode 15 type Op byte 16 17 // Types of messages that may be sent between nodes 18 // Note: If you add a new parseable Op below, you must also add it to ops 19 // (declared below) 20 const ( 21 // Handshake: 22 PingOp Op = iota 23 PongOp 24 HandshakeOp 25 GetPeerListOp 26 PeerListOp 27 // State sync: 28 GetStateSummaryFrontierOp 29 GetStateSummaryFrontierFailedOp 30 StateSummaryFrontierOp 31 GetAcceptedStateSummaryOp 32 GetAcceptedStateSummaryFailedOp 33 AcceptedStateSummaryOp 34 // Bootstrapping: 35 GetAcceptedFrontierOp 36 GetAcceptedFrontierFailedOp 37 AcceptedFrontierOp 38 GetAcceptedOp 39 GetAcceptedFailedOp 40 AcceptedOp 41 GetAncestorsOp 42 GetAncestorsFailedOp 43 AncestorsOp 44 // Consensus: 45 GetOp 46 GetFailedOp 47 PutOp 48 PushQueryOp 49 PullQueryOp 50 QueryFailedOp 51 ChitsOp 52 // Application: 53 AppRequestOp 54 AppErrorOp 55 AppResponseOp 56 AppGossipOp 57 // Cross chain: 58 CrossChainAppRequestOp 59 CrossChainAppErrorOp 60 CrossChainAppResponseOp 61 // Internal: 62 ConnectedOp 63 ConnectedSubnetOp 64 DisconnectedOp 65 NotifyOp 66 GossipRequestOp 67 TimeoutOp 68 ) 69 70 var ( 71 HandshakeOps = []Op{ 72 PingOp, 73 PongOp, 74 HandshakeOp, 75 GetPeerListOp, 76 PeerListOp, 77 } 78 79 // List of all consensus request message types 80 ConsensusRequestOps = []Op{ 81 GetStateSummaryFrontierOp, 82 GetAcceptedStateSummaryOp, 83 GetAcceptedFrontierOp, 84 GetAcceptedOp, 85 GetAncestorsOp, 86 GetOp, 87 PushQueryOp, 88 PullQueryOp, 89 AppRequestOp, 90 } 91 ConsensusResponseOps = []Op{ 92 StateSummaryFrontierOp, 93 AcceptedStateSummaryOp, 94 AcceptedFrontierOp, 95 AcceptedOp, 96 AncestorsOp, 97 PutOp, 98 ChitsOp, 99 AppResponseOp, 100 AppErrorOp, 101 } 102 // AppGossip is the only message that is sent unrequested without the 103 // expectation of a response 104 ConsensusExternalOps = append( 105 ConsensusRequestOps, 106 append( 107 ConsensusResponseOps, 108 AppGossipOp, 109 )..., 110 ) 111 ConsensusInternalOps = []Op{ 112 GetStateSummaryFrontierFailedOp, 113 GetAcceptedStateSummaryFailedOp, 114 GetAcceptedFrontierFailedOp, 115 GetAcceptedFailedOp, 116 GetAncestorsFailedOp, 117 GetFailedOp, 118 QueryFailedOp, 119 CrossChainAppRequestOp, 120 CrossChainAppErrorOp, 121 CrossChainAppResponseOp, 122 ConnectedOp, 123 ConnectedSubnetOp, 124 DisconnectedOp, 125 NotifyOp, 126 GossipRequestOp, 127 TimeoutOp, 128 } 129 ConsensusOps = append(ConsensusExternalOps, ConsensusInternalOps...) 130 131 ExternalOps = append(ConsensusExternalOps, HandshakeOps...) 132 133 SynchronousOps = []Op{ 134 // State sync 135 GetStateSummaryFrontierOp, 136 GetStateSummaryFrontierFailedOp, 137 StateSummaryFrontierOp, 138 GetAcceptedStateSummaryOp, 139 GetAcceptedStateSummaryFailedOp, 140 AcceptedStateSummaryOp, 141 // Bootstrapping 142 GetAcceptedFrontierOp, 143 GetAcceptedFrontierFailedOp, 144 AcceptedFrontierOp, 145 GetAcceptedOp, 146 GetAcceptedFailedOp, 147 AcceptedOp, 148 GetAncestorsOp, 149 GetAncestorsFailedOp, 150 AncestorsOp, 151 // Consensus 152 GetOp, 153 GetFailedOp, 154 PutOp, 155 PushQueryOp, 156 PullQueryOp, 157 QueryFailedOp, 158 ChitsOp, 159 // Internal 160 ConnectedOp, 161 ConnectedSubnetOp, 162 DisconnectedOp, 163 } 164 165 AsynchronousOps = []Op{ 166 // Application 167 AppRequestOp, 168 AppErrorOp, 169 AppGossipOp, 170 AppResponseOp, 171 // Cross chain 172 CrossChainAppRequestOp, 173 CrossChainAppErrorOp, 174 CrossChainAppResponseOp, 175 } 176 177 FailedToResponseOps = map[Op]Op{ 178 GetStateSummaryFrontierFailedOp: StateSummaryFrontierOp, 179 GetAcceptedStateSummaryFailedOp: AcceptedStateSummaryOp, 180 GetAcceptedFrontierFailedOp: AcceptedFrontierOp, 181 GetAcceptedFailedOp: AcceptedOp, 182 GetAncestorsFailedOp: AncestorsOp, 183 GetFailedOp: PutOp, 184 QueryFailedOp: ChitsOp, 185 AppErrorOp: AppResponseOp, 186 CrossChainAppErrorOp: CrossChainAppResponseOp, 187 } 188 UnrequestedOps = set.Of( 189 GetAcceptedFrontierOp, 190 GetAcceptedOp, 191 GetAncestorsOp, 192 GetOp, 193 PushQueryOp, 194 PullQueryOp, 195 AppRequestOp, 196 AppGossipOp, 197 CrossChainAppRequestOp, 198 GetStateSummaryFrontierOp, 199 GetAcceptedStateSummaryOp, 200 ) 201 202 errUnknownMessageType = errors.New("unknown message type") 203 ) 204 205 func (op Op) String() string { 206 switch op { 207 // Handshake 208 case PingOp: 209 return "ping" 210 case PongOp: 211 return "pong" 212 case HandshakeOp: 213 return "handshake" 214 case GetPeerListOp: 215 return "get_peerlist" 216 case PeerListOp: 217 return "peerlist" 218 // State sync 219 case GetStateSummaryFrontierOp: 220 return "get_state_summary_frontier" 221 case GetStateSummaryFrontierFailedOp: 222 return "get_state_summary_frontier_failed" 223 case StateSummaryFrontierOp: 224 return "state_summary_frontier" 225 case GetAcceptedStateSummaryOp: 226 return "get_accepted_state_summary" 227 case GetAcceptedStateSummaryFailedOp: 228 return "get_accepted_state_summary_failed" 229 case AcceptedStateSummaryOp: 230 return "accepted_state_summary" 231 // Bootstrapping 232 case GetAcceptedFrontierOp: 233 return "get_accepted_frontier" 234 case GetAcceptedFrontierFailedOp: 235 return "get_accepted_frontier_failed" 236 case AcceptedFrontierOp: 237 return "accepted_frontier" 238 case GetAcceptedOp: 239 return "get_accepted" 240 case GetAcceptedFailedOp: 241 return "get_accepted_failed" 242 case AcceptedOp: 243 return "accepted" 244 case GetAncestorsOp: 245 return "get_ancestors" 246 case GetAncestorsFailedOp: 247 return "get_ancestors_failed" 248 case AncestorsOp: 249 return "ancestors" 250 // Consensus 251 case GetOp: 252 return "get" 253 case GetFailedOp: 254 return "get_failed" 255 case PutOp: 256 return "put" 257 case PushQueryOp: 258 return "push_query" 259 case PullQueryOp: 260 return "pull_query" 261 case QueryFailedOp: 262 return "query_failed" 263 case ChitsOp: 264 return "chits" 265 // Application 266 case AppRequestOp: 267 return "app_request" 268 case AppErrorOp: 269 return "app_error" 270 case AppResponseOp: 271 return "app_response" 272 case AppGossipOp: 273 return "app_gossip" 274 // Cross chain 275 case CrossChainAppRequestOp: 276 return "cross_chain_app_request" 277 case CrossChainAppErrorOp: 278 return "cross_chain_app_error" 279 case CrossChainAppResponseOp: 280 return "cross_chain_app_response" 281 // Internal 282 case ConnectedOp: 283 return "connected" 284 case ConnectedSubnetOp: 285 return "connected_subnet" 286 case DisconnectedOp: 287 return "disconnected" 288 case NotifyOp: 289 return "notify" 290 case GossipRequestOp: 291 return "gossip_request" 292 case TimeoutOp: 293 return "timeout" 294 default: 295 return "unknown" 296 } 297 } 298 299 func Unwrap(m *p2p.Message) (fmt.Stringer, error) { 300 switch msg := m.GetMessage().(type) { 301 // Handshake: 302 case *p2p.Message_Ping: 303 return msg.Ping, nil 304 case *p2p.Message_Pong: 305 return msg.Pong, nil 306 case *p2p.Message_Handshake: 307 return msg.Handshake, nil 308 case *p2p.Message_GetPeerList: 309 return msg.GetPeerList, nil 310 case *p2p.Message_PeerList_: 311 return msg.PeerList_, nil 312 // State sync: 313 case *p2p.Message_GetStateSummaryFrontier: 314 return msg.GetStateSummaryFrontier, nil 315 case *p2p.Message_StateSummaryFrontier_: 316 return msg.StateSummaryFrontier_, nil 317 case *p2p.Message_GetAcceptedStateSummary: 318 return msg.GetAcceptedStateSummary, nil 319 case *p2p.Message_AcceptedStateSummary_: 320 return msg.AcceptedStateSummary_, nil 321 // Bootstrapping: 322 case *p2p.Message_GetAcceptedFrontier: 323 return msg.GetAcceptedFrontier, nil 324 case *p2p.Message_AcceptedFrontier_: 325 return msg.AcceptedFrontier_, nil 326 case *p2p.Message_GetAccepted: 327 return msg.GetAccepted, nil 328 case *p2p.Message_Accepted_: 329 return msg.Accepted_, nil 330 case *p2p.Message_GetAncestors: 331 return msg.GetAncestors, nil 332 case *p2p.Message_Ancestors_: 333 return msg.Ancestors_, nil 334 // Consensus: 335 case *p2p.Message_Get: 336 return msg.Get, nil 337 case *p2p.Message_Put: 338 return msg.Put, nil 339 case *p2p.Message_PushQuery: 340 return msg.PushQuery, nil 341 case *p2p.Message_PullQuery: 342 return msg.PullQuery, nil 343 case *p2p.Message_Chits: 344 return msg.Chits, nil 345 // Application: 346 case *p2p.Message_AppRequest: 347 return msg.AppRequest, nil 348 case *p2p.Message_AppResponse: 349 return msg.AppResponse, nil 350 case *p2p.Message_AppError: 351 return msg.AppError, nil 352 case *p2p.Message_AppGossip: 353 return msg.AppGossip, nil 354 default: 355 return nil, fmt.Errorf("%w: %T", errUnknownMessageType, msg) 356 } 357 } 358 359 func ToOp(m *p2p.Message) (Op, error) { 360 switch msg := m.GetMessage().(type) { 361 case *p2p.Message_Ping: 362 return PingOp, nil 363 case *p2p.Message_Pong: 364 return PongOp, nil 365 case *p2p.Message_Handshake: 366 return HandshakeOp, nil 367 case *p2p.Message_GetPeerList: 368 return GetPeerListOp, nil 369 case *p2p.Message_PeerList_: 370 return PeerListOp, nil 371 case *p2p.Message_GetStateSummaryFrontier: 372 return GetStateSummaryFrontierOp, nil 373 case *p2p.Message_StateSummaryFrontier_: 374 return StateSummaryFrontierOp, nil 375 case *p2p.Message_GetAcceptedStateSummary: 376 return GetAcceptedStateSummaryOp, nil 377 case *p2p.Message_AcceptedStateSummary_: 378 return AcceptedStateSummaryOp, nil 379 case *p2p.Message_GetAcceptedFrontier: 380 return GetAcceptedFrontierOp, nil 381 case *p2p.Message_AcceptedFrontier_: 382 return AcceptedFrontierOp, nil 383 case *p2p.Message_GetAccepted: 384 return GetAcceptedOp, nil 385 case *p2p.Message_Accepted_: 386 return AcceptedOp, nil 387 case *p2p.Message_GetAncestors: 388 return GetAncestorsOp, nil 389 case *p2p.Message_Ancestors_: 390 return AncestorsOp, nil 391 case *p2p.Message_Get: 392 return GetOp, nil 393 case *p2p.Message_Put: 394 return PutOp, nil 395 case *p2p.Message_PushQuery: 396 return PushQueryOp, nil 397 case *p2p.Message_PullQuery: 398 return PullQueryOp, nil 399 case *p2p.Message_Chits: 400 return ChitsOp, nil 401 case *p2p.Message_AppRequest: 402 return AppRequestOp, nil 403 case *p2p.Message_AppResponse: 404 return AppResponseOp, nil 405 case *p2p.Message_AppError: 406 return AppErrorOp, nil 407 case *p2p.Message_AppGossip: 408 return AppGossipOp, nil 409 default: 410 return 0, fmt.Errorf("%w: %T", errUnknownMessageType, msg) 411 } 412 }