GRING

package module
v0.0.0-...-eca426a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 9, 2022 License: MIT Imports: 29 Imported by: 4

README

Introduction

This repository contains implementation of G-RING: the resilient decentralized communication protocol and systems designs for distributed services.

Installation

  1. Install Go This repository is valided with, but not limited to, go1.16
wget https://golang.org/dl/go1.16.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.16.linux-amd64.tar.gz

Write your own distributed service example

distributed service applications can be implemented on G-RING.

Please refer to examples in G-RING/cmd

Node Creation

This is a G-RING core data structure that contains management resources such as event handling(e.g., connection management), message handler, overlay network.

node, err = GRING.NewNode(
            GRING.WithNodeBindHost(net.ParseIP(host)),
            GRING.WithNodeBindPort(uint16(port)),
            GRING.WithNodeMaxRecvMessageSize(1<<24),
            )

Register Message Handlers

//Register the chatMessage structure to the node with an associated unmarshal function.
node.RegisterMessage(chatMessage{}, unmarshalChatMessage)

// Register a message handler to the node.
node.Handle(handle)

Register Overlay Network Routing Protocol

// This example uses Dual protocol.
events = dual.Events{
             OnPeerAdmitted: func(id GRING.ID) {
                fmt.Printf("Learned about a new peer %s(%s).\n", id.Address, id.ID.String()[:printedLength])
	     }
             OnPeerEvicted: func(id GRING.ID) {
                fmt.Printf("Forgotten a peer %s(%s).\n", id.Address, id.ID.String()[:printedLength])
             },
        }
// register above events handlers to Dual 
overlay = dual.New(dual.WithProtocolEvents(events)

// Bind Dual Overlay to the node.
node.Bind(overlay.Protocol())

Start the node

// Have the node start listening for new peers.
node.Listen()

Setting parameters

G-RING provides below protocols. Please refer to below named directory on the top directory of G-RING

dual

Default routing and messaging protocol for G-RING. It provides three communication protocols and two types of overlays.

Communication protocols
A. P2P Backbone Connection Management Protocol
B. P2P Backbone General Purpose Communication Protocol 
C. P2P Application Communication Protocol
Overlays
A. Backbone overlay
B. Application overlay

kademlia

Vanilla Kademlia

gossip

standard push based gossip protocol

Supported Platforms

Tested environment:

OS : Ubuntu 18.04 Hardware : Ethernet

Status

The code is provided as is, without warranty or support.

Some of codes(e.g., Kademlia, gossip protocol) are from Noise https://github.com/perlin-network/noise

Students Contributions

VGG_face_group FL application on GRING

Federated Learning for face recognition with Kaggle VGG face2 dataset https://www.kaggle.com/greatgamedota/vggface2-test by Prabhy Omkar, Pawar Rohan, Okechukwu Chima, Dumay Alice Jeanne Mi and Sirpurkar Saurab

d3disp

Visualization of overlay network on webbrowser interface by Prabhu Omkar

Documentation

Overview

Package GRING is an opinionated, easy-to-use P2P network stack for decentralized applications, and cryptographic protocols written in Go.

GRING is made to be minimal, robust, developer-friendly, performant, secure, and cross-platform across multitudes of devices by making use of a small amount of well-tested, production-grade dependencies.

Index

Constants

View Source
const (
	// SizePublicKey is the size in bytes of a nodes/peers public key.
	SizePublicKey = ed25519.PublicKeySize

	// SizePrivateKey is the size in bytes of a nodes/peers private key.
	SizePrivateKey = ed25519.PrivateKeySize

	// SizeSignature is the size in bytes of a cryptographic signature.
	SizeSignature = ed25519.SignatureSize
)
View Source
const (
	NO_OP = 0xFF
)

Variables

View Source
var (
	// ZeroPublicKey is the zero-value for a node/peer public key.
	ZeroPublicKey PublicKey

	// ZeroPrivateKey is the zero-value for a node/peer private key.
	ZeroPrivateKey PrivateKey

	// ZeroSignature is the zero-value for a cryptographic signature.
	ZeroSignature Signature
)
View Source
var (
	// ErrMessageTooLarge is reported by a client when it receives a message from a peer that exceeds the max
	// receivable message size limit configured on a node.
	ErrMessageTooLarge = errors.New("msg from peer is too large")
)

Functions

func ECDH

func ECDH(ourPrivateKey PrivateKey, peerPublicKey PublicKey) ([]byte, error)

ECDH transform all Ed25519 points to Curve25519 points and performs a Diffie-Hellman handshake to derive a shared key. It throws an error should the Ed25519 points be invalid.

func GenerateKeys

func GenerateKeys(rand io.Reader) (publicKey PublicKey, privateKey PrivateKey, err error)

GenerateKeys randomly generates a new pair of cryptographic keys. Nil may be passed to rand in order to use crypto/rand by default. It returns an error if rand is invalid.

func ResolveAddress

func ResolveAddress(address string) (string, error)

ResolveAddress resolves an address using net.ResolveTCPAddress("tcp", (*net.Conn).RemoteAddr()) and nullifies the IP if the IP is unspecified or is a loopback address. It then returns the string representation of the address, or an error if the resolution of the address fails.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client represents an pooled inbound/outbound connection under some node. Should a client successfully undergo GRING's protocol handshake, information about the peer representative of this client, such as its ID is available.

A clients connection may be closed through (*Client).Close, through the result of a failed handshake, through exceeding the max inbound/outbound connection count configured on the clients associated node, through a node gracefully being stopped, through a Handler configured on the node returning an error upon recipient of some data, or through receiving unexpected/suspicious data.

The lifecycle of a client may be controlled through (*Client).WaitUntilReady, and (*Client).WaitUntilClosed. It provably has been useful in writing unit tests where a client instance is used under high concurrency scenarios.

A client in total has two goroutines associated to it: a goroutine responsible for handling writing messages, and a goroutine responsible for handling the recipient of messages.

func (*Client) Close

func (c *Client) Close()

Close asynchronously kills the underlying connection and signals all goroutines to stop underlying this client.

Close may be called concurrently.

func (*Client) Error

func (c *Client) Error() error

Error returns the very first error that has caused this clients connection to have dropped.

Error may be called concurrently.

func (*Client) ID

func (c *Client) ID() ID

ID returns an immutable copy of the ID of this client, which is established once the client has successfully completed the handshake protocol configured from this clients associated node.

ID may be called concurrently.

func (*Client) Logger

func (c *Client) Logger() *zap.Logger

Logger returns the underlying logger associated to this client. It may optionally be set via (*Client).SetLogger.

Logger may be called concurrently.

func (*Client) SetLogger

func (c *Client) SetLogger(logger *zap.Logger)

SetLogger updates the logger instance of this client.

SetLogger may be called concurrently.

func (*Client) WaitUntilClosed

func (c *Client) WaitUntilClosed()

WaitUntilClosed pauses the goroutine to which it was called within until all goroutines associated to this client has been closed. The goroutines associated to this client would only close should:

1) handshaking failed/succeeded, 2) the connection was dropped, or 3) (*Client).Close was called.

WaitUntilReady may be called concurrently.

func (*Client) WaitUntilReady

func (c *Client) WaitUntilReady()

WaitUntilReady pauses the goroutine to which it was called within until/unless the client has successfully completed/failed the handshake protocol configured under the node instance to which this peer was derived from.

It pauses the goroutine by reading from a channel that is closed when the client has successfully completed/failed the aforementioned handshake protocol.

WaitUntilReady may be called concurrently.

type Handler

type Handler func(ctx HandlerContext) error

Handler is called whenever a node receives data from either an inbound/outbound peer connection. Multiple handlers may be registered to a node by (*Node).Handle before the node starts listening for new peers.

Returning an error in a handler closes the connection and marks the connection to have closed unexpectedly or due to error. Should you intend to wish to skip a handler from processing some given data, return a nil error.

type HandlerContext

type HandlerContext struct {
	// contains filtered or unexported fields
}

HandlerContext provides contextual information upon the recipient of data from an inbound/outbound connection. It provides the option of responding to a request should the data received be of a request.

func (*HandlerContext) Data

func (ctx *HandlerContext) Data() []byte

Data returns the raw bytes that some peer has sent to you.

Data may be called concurrently.

func (*HandlerContext) DecodeMessage

func (ctx *HandlerContext) DecodeMessage() (Serializable, error)

DecodeMessage decodes the raw bytes that some peer has sent you into a Go type. The Go type must have previously been registered to the node to which the handler this context is under was registered on. An error is thrown otherwise.

It is highly recommended that should you choose to have your application utilize GRING's serialization/ deserialization framework for data over-the-wire, that all handlers use them by default.

DecodeMessage may be called concurrently.

func (*HandlerContext) ID

func (ctx *HandlerContext) ID() ID

ID returns the ID of the inbound/outbound peer that sent you the data that is currently being handled.

func (*HandlerContext) IsRequest

func (ctx *HandlerContext) IsRequest() bool

IsRequest marks whether or not the data received was intended to be of a request.

IsRequest may be called concurrently.

func (*HandlerContext) Logger

func (ctx *HandlerContext) Logger() *zap.Logger

Logger returns the logger instance associated to the inbound/outbound peer being handled.

func (*HandlerContext) Send

func (ctx *HandlerContext) Send(data []byte) error

Send sends data back to the peer that has sent you data. Should the data the peer send you be of a request, Send will send data back as a response. It returns an error if multiple responses attempt to be sent to a single request, or if an error occurred while attempting to send the peer a message.

Send may be called concurrently.

func (*HandlerContext) SendMessage

func (ctx *HandlerContext) SendMessage(msg Serializable) error

SendMessage encodes and serializes a Go type into a byte slice, and sends data back to the peer that has sent you data as either a response or message. Refer to (*HandlerContext).Send for more details. An error is thrown if the Go type passed in has not been registered to the node to which the handler this context is under was registered on.

It is highly recommended that should you choose to have your application utilize GRING's serialization/deserialization framework for data over-the-wire, that all handlers use them by default.

SendMessage may be called concurrently.

type ID

type ID struct {
	// The Ed25519 public key of the bearer of this ID.
	ID PublicKey `json:"public_key"`

	// Public host of the bearer of this ID.
	Host net.IP `json:"address"`

	// Public port of the bearer of this ID.
	Port uint16

	// 'host:port'
	Address string
}

ID represents a peer ID. It comprises of a cryptographic public key, and a public, reachable network address specified by a IPv4/IPv6 host and 16-bit port number. The size of an ID in terms of its byte representation is static, with its contents being deterministic.

func NewID

func NewID(id PublicKey, host net.IP, port uint16) ID

NewID instantiates a new, immutable cryptographic user ID.

func UnmarshalID

func UnmarshalID(buf []byte) (ID, error)

UnmarshalID deserializes buf, representing a slice of bytes, ID instance. It throws io.ErrUnexpectedEOF if the contents of buf is malformed.

func (ID) Marshal

func (e ID) Marshal() []byte

Marshal serializes this ID into its byte representation.

func (ID) Size

func (e ID) Size() int

Size returns the number of bytes this ID comprises of.

func (ID) String

func (e ID) String() string

String returns a JSON representation of this ID.

type Node

type Node struct {
	// contains filtered or unexported fields
}

Node keeps track of a users ID, all of a users outgoing/incoming connections to/from peers as *Client instances under a bounded connection pool whose bounds may be configured, the TCP listener which accepts new incoming peer connections, and all Go types that may be serialized/deserialized at will on-the-wire or through a Handler.

A node at most will only have one goroutine + num configured worker goroutines associated to it which represents the listener looking to accept new incoming peer connections, and workers responsible for handling incoming peer messages. A node once closed or once started (as in, (*Node).Listen was called) should not be reused.

func NewNode

func NewNode(opts ...NodeOption) (*Node, error)

NewNode instantiates a new node instance, and pre-configures the node with provided options. Default values for some non-specified options are instantiated as well, which may yield an error.

func (*Node) Addr

func (n *Node) Addr() string

Addr returns the public address of this node. The public address, should it not be configured through the WithNodeAddress functional option when calling NewNode, is initialized to 'host:port' after a successful call to (*Node).Listen.

Addr may be called concurrently.

func (*Node) Bind

func (n *Node) Bind(protocols ...Protocol)

Bind registers a Protocol to this node, which implements callbacks for all events this node can emit throughout its lifecycle. For more information on how to implement Protocol, refer to the documentation for Protocol. Bind only registers Protocol's should the node not yet be listening for new connections. If the node is already listening for new peers, Bind silently returns and does nothing.

Bind may be called concurrently.

func (*Node) Close

func (n *Node) Close() error

Close gracefully stops all live inbound/outbound peer connections registered on this node, and stops the node from handling/accepting new incoming peer connections. It returns an error if an error occurs closing the nodes listener. Nodes that are closed should not ever be re-used.

Close may be called concurrently.

func (*Node) DecodeMessage

func (n *Node) DecodeMessage(data []byte) (Serializable, error)

DecodeMessage decodes data into its registered Go type T should it be well-formed. It throws an error if the opcode at the head of data has yet to be registered/associated to a Go type via (*Node).RegisterMessage. For more details, refer to (*Node).RegisterMessage.

DecodeMessage may be called concurrently.

func (*Node) EncodeMessage

func (n *Node) EncodeMessage(msg Serializable) ([]byte, error)

EncodeMessage encodes msg which must be a registered Go type T into its wire representation. It throws an error if the Go type of msg has not yet been registered through (*Node).RegisterMessage. For more details, refer to (*Node).RegisterMessage.

EncodeMessage may be called concurrently.

func (*Node) Handle

func (n *Node) Handle(handlers ...Handler)

Handle registers a Handler to this node, which is executed every time this node receives a message from an inbound/outbound connection. For more information on how to write a Handler, refer to the documentation for Handler. Handle only registers Handler's should the node not yet be listening for new connections. If the node is already listening for new peers, Handle silently returns and does nothing.

Handle may be called concurrently.

func (*Node) ID

func (n *Node) ID() ID

ID returns an immutable copy of the ID of this node. The ID of the node is set after a successful call to (*Node).Listen, or otherwise passed through the WithNodeID functional option when calling NewNode.

ID may be called concurrently.

func (*Node) Inbound

func (n *Node) Inbound() []*Client

Inbound returns a cloned slice of all inbound connections to this node as Client instances. It is useful while writing unit tests where you would want to block the current goroutine via (*Client).WaitUntilReady and (*Client).WaitUntilClosed to test scenarios where you want to be sure some inbound client is open/closed.

func (*Node) InboundGet

func (n *Node) InboundGet(addr string) (*Client, bool)

func (*Node) Listen

func (n *Node) Listen() error

Listen has the node start listening for new peers. If an error occurs while starting the listener due to misconfigured options or resource exhaustion, an error is returned. If the node is already listening for new connections, an error is thrown.

Listen must not be called concurrently, and should only ever be called once per node instance.

func (*Node) Logger

func (n *Node) Logger() *zap.Logger

Logger returns the underlying logger associated to this node. The logger, should it not be configured through the WithNodeLogger functional option when calling NewNode, is by default zap.NewNop().

Logger may be called concurrently.

func (*Node) Outbound

func (n *Node) Outbound() []*Client

Outbound returns a cloned slice of all outbound connections to this node as Client instances. It is useful while writing unit tests where you would want to block the current goroutine via (*Client).WaitUntilClosed to test scenarios where you want to be sure some outbound client has resources associated to it completely released.

func (*Node) OutboundGet

func (n *Node) OutboundGet(addr string) (*Client, bool)

func (*Node) Ping

func (n *Node) Ping(ctx context.Context, addr string, opcode ...byte) (*Client, error)

Ping takes an available connection from this nodes connection pool if the peer at addr has never been connected to before, connects to it, handshakes with the peer, and returns a *Client instance should the entire process be successful.

If there already exists a live connection to the peer at addr, no new connection is established and the *Client instance associated to the peer is returned. An error is returned if connecting to the peer should it not have been connected to before fails, or if ctx was canceled/expired, or if handshaking fails.

If there is no available connection from this nodes connection pool, the connection that is at the tail of the pool is closed and evicted and used to ping addr.

It is safe to call Ping concurrently.

func (*Node) RegisterMessage

func (n *Node) RegisterMessage(ser Serializable, de interface{}) uint16

RegisterMessage registers a Go type T that implements the Serializable interface with an associated deserialize function whose signature comprises of func([]byte) (T, error). RegisterMessage should be called in the following manner:

RegisterMessage(T{}, func([]byte) (T, error) { ... })

It returns a 16-bit unsigned integer (opcode) that is associated to the type T on-the-wire. Once a Go type has been registered, it may be used in a Handler, or via (*Node).EncodeMessage, (*Node).DecodeMessage, (*Node).SendMessage, and (*Node).RequestMessage.

The wire format of a type registered comprises of append([]byte{16-bit big-endian integer (opcode)}, ser.Marshal()...).

RegisterMessage may be called concurrently, though is discouraged.

func (*Node) Request

func (n *Node) Request(ctx context.Context, addr string, data []byte, opcode ...byte) ([]byte, error)

Request takes an available connection from this nodes connection pool if the peer at addr has never been connected to before, connects to it, handshakes with the peer, and sends it a request should the entire process be successful.

Once the request has been sent, the current goroutine Request was called in will block until either a response has been received which will be subsequently returned, ctx was canceled/expired, or the connection was dropped.

If there already exists a live connection to the peer at addr, no new connection is established and the request will follow through. An error is returned if connecting to the peer should it not have been connected to before fails, or if handshaking fails.

If there is no available connection from this nodes connection pool, the connection that is at the tail of the pool is closed and evicted and used to send a request to addr.

func (*Node) RequestMessage

func (n *Node) RequestMessage(ctx context.Context, addr string, req Serializable, opcode ...byte) (Serializable, error)

RequestMessage encodes msg which is a Go type registered via (*Node).RegisterMessage, and sends it as a request to addr, and returns a decoded response from the peer at addr. For more details, refer to (*Node).Request and (*Node).RegisterMessage.

func (*Node) Send

func (n *Node) Send(ctx context.Context, addr string, data []byte, opcode ...byte) error

Send takes an available connection from this nodes connection pool if the peer at addr has never been connected to before, connects to it, handshakes with the peer, and sends it data.

If there already exists a live connection to the peer at addr, no new connection is established and data will be sent through. An error is returned if connecting to the peer should it not have been connected to before fails, or if handshaking fails, or if the connection is closed.

If there is no available connection from this nodes connection pool, the connection that is at the tail of the pool is closed and evicted and used to send data to addr.

func (*Node) SendMessage

func (n *Node) SendMessage(ctx context.Context, addr string, msg Serializable, opcode ...byte) error

SendMessage encodes msg which is a Go type registered via (*Node).RegisterMessage, and sends it to addr. For more details, refer to (*Node).Send and (*Node).RegisterMessage.

func (*Node) Sign

func (n *Node) Sign(data []byte) Signature

Sign uses the nodes private key to sign data and return its cryptographic signature as a slice of bytes.

type NodeOption

type NodeOption func(n *Node)

NodeOption represents a functional option that may be passed to NewNode for instantiating a new node instance with configured values.

func WithNodeAddress

func WithNodeAddress(addr string) NodeOption

WithNodeAddress sets the public address of this node which is advertised on the ID sent to peers during a handshake protocol which is performed when interacting with peers this node has had no live connection to beforehand. By default, it is left blank, and initialized to 'binding host:binding port' upon calling (*Node).Listen.

func WithNodeBindHost

func WithNodeBindHost(host net.IP) NodeOption

WithNodeBindHost sets the TCP host IP address which the node binds itself to and listens for new incoming peer connections on. By default, it is unspecified (0.0.0.0).

func WithNodeBindPort

func WithNodeBindPort(port uint16) NodeOption

WithNodeBindPort sets the TCP port which the node binds itself to and listens for new incoming peer connections on. By default, a random port is assigned by the operating system.

func WithNodeID

func WithNodeID(id ID) NodeOption

WithNodeID sets the nodes ID, and public address. By default, the ID is set with an address that is set to the binding host and port upon calling (*Node).Listen should the address not be configured.

func WithNodeIdleTimeout

func WithNodeIdleTimeout(idleTimeout time.Duration) NodeOption

WithNodeIdleTimeout sets the duration in which should there be no subsequent reads/writes on a connection, the connection shall timeout and have resources related to it released. By default, the timeout is set to be 3 seconds. If an idle timeout of 0 is specified, idle timeouts will be disabled.

func WithNodeLogger

func WithNodeLogger(logger *zap.Logger) NodeOption

WithNodeLogger sets the logger implementation that the node shall use. By default, zap.NewNop() is assigned which disables any logs.

func WithNodeMaxDialAttempts

func WithNodeMaxDialAttempts(maxDialAttempts uint) NodeOption

WithNodeMaxDialAttempts sets the max number of attempts a connection is dialed before it is determined to have failed. By default, the max number of attempts a connection is dialed is 3.

func WithNodeMaxInboundConnections

func WithNodeMaxInboundConnections(maxInboundConnections uint) NodeOption

WithNodeMaxInboundConnections sets the max number of inbound connections the connection pool a node maintains allows at any given moment in time. By default, the max number of inbound connections is 128. Exceeding the max number causes the connection pool to release the oldest inbound connection in the pool.

func WithNodeMaxOutboundConnections

func WithNodeMaxOutboundConnections(maxOutboundConnections uint) NodeOption

WithNodeMaxOutboundConnections sets the max number of outbound connections the connection pool a node maintains allows at any given moment in time. By default, the maximum number of outbound connections is 128. Exceeding the max number causes the connection pool to release the oldest outbound connection in the pool.

func WithNodeMaxRecvMessageSize

func WithNodeMaxRecvMessageSize(maxRecvMessageSize uint32) NodeOption

WithNodeMaxRecvMessageSize sets the max number of bytes a node is willing to receive from a peer. If the limit is ever exceeded, the peer is disconnected with an error. Setting this option to zero will disable the limit. By default, the max number of bytes a node is willing to receive from a peer is set to 4MB.

func WithNodeNumWorkers

func WithNodeNumWorkers(numWorkers uint) NodeOption

WithNodeNumWorkers sets the max number of workers a node will spawn to handle incoming peer messages. By default, the max number of workers a node will spawn is the number of CPUs available to the Go runtime specified by runtime.NumCPU(). The minimum number of workers which need to be spawned is 1.

func WithNodePrivateKey

func WithNodePrivateKey(privateKey PrivateKey) NodeOption

WithNodePrivateKey sets the private key of the node. By default, a random private key is generated using GenerateKeys should no private key be configured.

type PrivateKey

type PrivateKey [SizePrivateKey]byte

PrivateKey is the default node/peer private key type.

func LoadKeysFromHex

func LoadKeysFromHex(secretHex string) (PrivateKey, error)

LoadKeysFromHex loads a private key from a hex string. It returns an error if secretHex is not hex-encoded or is an invalid number of bytes. In the case of the latter error, the error is wrapped as io.ErrUnexpectedEOF. Calling this function performs 1 allocation.

func (PrivateKey) MarshalJSON

func (k PrivateKey) MarshalJSON() ([]byte, error)

MarshalJSON returns the hexadecimal representation of this private key in JSON. It should never throw an error.

func (PrivateKey) Public

func (k PrivateKey) Public() PublicKey

Public returns the public key associated to this private key.

func (PrivateKey) Sign

func (k PrivateKey) Sign(data []byte) Signature

Sign uses this private key to sign data and return its cryptographic signature as a slice of bytes.

func (PrivateKey) String

func (k PrivateKey) String() string

String returns the hexadecimal representation of this private key.

type Protocol

type Protocol struct {
	// VersionMajor, VersionMinor, and VersionPatch mark the version of this protocol with respect to semantic
	// versioning.
	VersionMajor, VersionMinor, VersionPatch uint

	// Bind is called when the node has successfully started listening for new peers. Important node information
	// such as the nodes binding host, binding port, public address, and ID are not initialized until after
	// (*Node).Listen has successfully been called. Bind gets called the very moment such information has successfully
	// been initialized.
	//
	// Errors returned from implementations of Bind will propagate back up to (*Node).Listen as a returned error.
	Bind func(node *Node) error

	// OnPeerConnected is called when a node successfully receives an incoming peer/connects to an outgoing peer, and
	// completes GRING's protocol handshake.
	//OnPeerConnected func(client *Client)
	OnPeerConnected func(isInbound bool, client *Client, opcode ...byte)

	// OnPeerDisconnected is called whenever any inbound/outbound connection that has successfully connected to a node
	// has been terminated.
	OnPeerDisconnected func(client *Client)

	OnExistingConnection func(isInbound bool, client *Client, opcode ...byte)

	// OnPingFailed is called whenever any attempt by a node to dial a peer at addr fails.
	OnPingFailed func(addr string, err error)

	// OnMessageSent is called whenever bytes of a message or request or response have been flushed/sent to a peer.
	OnMessageSent func(client *Client, opcode ...byte)

	// OnMessageRecv is called whenever a message or response is received from a peer.
	OnMessageRecv func(client *Client, opcode ...byte)
}

Protocol is an interface that may be implemented by libraries and projects built on top of Noise to hook callbacks onto a series of events that are emitted throughout a nodes lifecycle. They may be registered to a node by (*Node).Bind before the node starts listening for new peers.

type PublicKey

type PublicKey [SizePublicKey]byte

PublicKey is the default node/peer public key type.

func (PublicKey) MarshalJSON

func (k PublicKey) MarshalJSON() ([]byte, error)

MarshalJSON returns the hexadecimal representation of this public key in JSON. It should never throw an error.

func (PublicKey) String

func (k PublicKey) String() string

String returns the hexadecimal representation of this public key.

func (PublicKey) Verify

func (k PublicKey) Verify(data []byte, signature Signature) bool

Verify returns true if the cryptographic signature of data is representative of this public key.

type Serializable

type Serializable interface {
	// Marshal converts this type into it's byte representation as a slice.
	Marshal() []byte
}

Serializable attributes whether or not a type has a byte representation that it may be serialized into.

type Signature

type Signature [SizeSignature]byte

Signature is the default node/peer cryptographic signature type.

func UnmarshalSignature

func UnmarshalSignature(data []byte) Signature

UnmarshalSignature decodes data into a Signature instance. It panics if data is not of expected length by instilling a bound check hint to the compiler. It uses unsafe hackery to zero-alloc convert data into a Signature.

func (Signature) MarshalJSON

func (s Signature) MarshalJSON() ([]byte, error)

MarshalJSON returns the hexadecimal representation of this signature in JSON. It should never throw an error.

func (Signature) String

func (s Signature) String() string

String returns the hexadecimal representation of this signature.

Directories

Path Synopsis
cmd
Package gossip is a simple implementation of a gossip protocol for GRING.
Package gossip is a simple implementation of a gossip protocol for GRING.
Package kademlia is a GRING implementation of the routing and discovery portion of the Kademlia protocol, with minor improvements suggested by the S/Kademlia paper.
Package kademlia is a GRING implementation of the routing and discovery portion of the Kademlia protocol, with minor improvements suggested by the S/Kademlia paper.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL