// (c) 2019-2020, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package networking import ( "github.com/ava-labs/salticidae-go" "github.com/ava-labs/gecko/utils/wrappers" ) // Field that may be packed into a message type Field uint32 // Fields that may be packed. These values are not sent over the wire. const ( VersionStr Field = iota // Used in handshake NetworkID // Used in handshake MyTime // Used in handshake Peers // Used in handshake ChainID // Used for dispatching RequestID // Used for all messages ContainerID // Used for querying ContainerBytes // Used for gossiping ContainerIDs // Used for querying Bytes // Used as arbitrary data TxID // Used for throughput tests Tx // Used for throughput tests Status // Used for throughput tests ) // Packer returns the packer function that can be used to pack this field. func (f Field) Packer() func(*wrappers.Packer, interface{}) { switch f { case VersionStr: return wrappers.TryPackStr case NetworkID: return wrappers.TryPackInt case MyTime: return wrappers.TryPackLong case Peers: return wrappers.TryPackIPList case ChainID: // TODO: This will be shortened to use a modified varint spec return wrappers.TryPackHash case RequestID: return wrappers.TryPackInt case ContainerID: return wrappers.TryPackHash case ContainerBytes: return wrappers.TryPackBytes case ContainerIDs: return wrappers.TryPackHashes case Bytes: return wrappers.TryPackBytes case TxID: return wrappers.TryPackHash case Tx: return wrappers.TryPackBytes case Status: return wrappers.TryPackInt default: return nil } } // Unpacker returns the unpacker function that can be used to unpack this field. func (f Field) Unpacker() func(*wrappers.Packer) interface{} { switch f { case VersionStr: return wrappers.TryUnpackStr case NetworkID: return wrappers.TryUnpackInt case MyTime: return wrappers.TryUnpackLong case Peers: return wrappers.TryUnpackIPList case ChainID: // TODO: This will be shortened to use a modified varint spec return wrappers.TryUnpackHash case RequestID: return wrappers.TryUnpackInt case ContainerID: return wrappers.TryUnpackHash case ContainerBytes: return wrappers.TryUnpackBytes case ContainerIDs: return wrappers.TryUnpackHashes case Bytes: return wrappers.TryUnpackBytes case TxID: return wrappers.TryUnpackHash case Tx: return wrappers.TryUnpackBytes case Status: return wrappers.TryUnpackInt default: return nil } } func (f Field) String() string { switch f { case VersionStr: return "VersionStr" case NetworkID: return "NetworkID" case MyTime: return "MyTime" case Peers: return "Peers" case ChainID: return "ChainID" case ContainerID: return "ContainerID" case ContainerBytes: return "Container Bytes" case ContainerIDs: return "Container IDs" case Bytes: return "Bytes" case TxID: return "TxID" case Tx: return "Tx" case Status: return "Status" default: return "Unknown Field" } } // Public commands that may be sent between stakers const ( // Handshake: GetVersion salticidae.Opcode = iota Version GetPeerList PeerList // Bootstrapping: GetAcceptedFrontier AcceptedFrontier GetAccepted Accepted // Consensus: Get Put PushQuery PullQuery Chits // Pinging: Ping Pong // Arbitrary data message: Data // Throughput test: IssueTx DecidedTx ) // Defines the messages that can be sent/received with this network var ( Messages = map[salticidae.Opcode][]Field{ // Handshake: GetVersion: []Field{}, Version: []Field{NetworkID, MyTime, VersionStr}, GetPeerList: []Field{}, PeerList: []Field{Peers}, // Bootstrapping: GetAcceptedFrontier: []Field{ChainID, RequestID}, AcceptedFrontier: []Field{ChainID, RequestID, ContainerIDs}, GetAccepted: []Field{ChainID, RequestID, ContainerIDs}, Accepted: []Field{ChainID, RequestID, ContainerIDs}, // Consensus: Get: []Field{ChainID, RequestID, ContainerID}, Put: []Field{ChainID, RequestID, ContainerID, ContainerBytes}, PushQuery: []Field{ChainID, RequestID, ContainerID, ContainerBytes}, PullQuery: []Field{ChainID, RequestID, ContainerID}, Chits: []Field{ChainID, RequestID, ContainerIDs}, // Pinging: Ping: []Field{}, Pong: []Field{}, // Arbitrary data message: Data: []Field{Bytes}, // Throughput test: IssueTx: []Field{ChainID, Tx}, DecidedTx: []Field{TxID, Status}, } )