Documentation ¶
Overview ¶
Package protocols is an extension to p2p. It offers a user friendly simple way to define devp2p subprotocols by abstracting away code standardly shared by protocols.
* automate assigments of code indexes to messages * automate RLP decoding/encoding based on reflecting * provide the forever loop to read incoming messages * standardise error handling related to communication * standardised handshake negotiation * TODO: automatic generation of wire protocol specification for peers
Index ¶
- Constants
- type Accounting
- type Balance
- type Error
- type Hook
- type Payer
- type Peer
- func (p *Peer) Drop(err error)
- func (p *Peer) Handshake(ctx context.Context, hs interface{}, verify func(interface{}) error) (rhs interface{}, err error)
- func (p *Peer) Run(handler func(ctx context.Context, msg interface{}) error) error
- func (p *Peer) Send(ctx context.Context, msg interface{}) error
- type Price
- type Prices
- type Spec
- type WrappedMsg
Constants ¶
const ( Sender = Payer(true) Receiver = Payer(false) )
const ( ErrMsgTooLong = iota ErrDecode ErrWrite ErrInvalidMsgCode ErrInvalidMsgType ErrHandshake ErrNoHandler ErrHandler )
error codes used by this protocol scheme
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Accounting ¶
type Accounting struct { Balance //interface to accounting logic Prices //interface to prices logic }
Accounting implements the Hook interface It interfaces to the balances through the Balance interface, while interfacing with protocols and its prices through the Prices interface
func NewAccounting ¶
func NewAccounting(balance Balance, po Prices) *Accounting
func (*Accounting) Receive ¶
func (ah *Accounting) Receive(peer *Peer, size uint32, msg interface{}) error
Implement Hook.Receive Receive takes a peer, a size and a msg and - calculates the cost for the local node receiving a msg of size from peer using the Prices interface - credits/debits local node using balance interface
func (*Accounting) Send ¶
func (ah *Accounting) Send(peer *Peer, size uint32, msg interface{}) error
Implement Hook.Send Send takes a peer, a size and a msg and - calculates the cost for the local node sending a msg of size to peer using the Prices interface - credits/debits local node using balance interface
type Balance ¶
type Balance interface { //Adds amount to the local balance with remote node `peer`; //positive amount = credit local node //negative amount = debit local node Add(amount int64, peer *Peer) error }
Balance is the actual accounting instance Balance defines the operations needed for accounting Implementations internally maintain the balance for every peer
type Error ¶
type Error struct { Code int // contains filtered or unexported fields }
Error implements the standard go error interface. Use:
errorf(code, format, params ...interface{})
Prints as:
<description>: <details>
where description is given by code in errorToString and details is fmt.Sprintf(format, params...)
exported field Code can be checked
type Hook ¶
type Hook interface { //A hook for sending messages Send(peer *Peer, size uint32, msg interface{}) error //A hook for receiving messages Receive(peer *Peer, size uint32, msg interface{}) error }
For accounting, the design is to allow the Spec to describe which and how its messages are priced To access this functionality, we provide a Hook interface which will call accounting methods NOTE: there could be more such (horizontal) hooks in the future
type Peer ¶
type Peer struct { *p2p.Peer // the p2p.Peer object representing the remote // contains filtered or unexported fields }
Peer represents a remote peer or protocol instance that is running on a peer connection with a remote peer
func NewPeer ¶
NewPeer constructs a new peer this constructor is called by the p2p.Protocol#Run function the first two arguments are the arguments passed to p2p.Protocol.Run function the third argument is the Spec describing the protocol
func (*Peer) Drop ¶
Drop disconnects a peer. TODO: may need to implement protocol drop only? don't want to kick off the peer if they are useful for other protocols
func (*Peer) Handshake ¶
func (p *Peer) Handshake(ctx context.Context, hs interface{}, verify func(interface{}) error) (rhs interface{}, err error)
Handshake negotiates a handshake on the peer connection * arguments
- context
- the local handshake to be sent to the remote peer
- funcion to be called on the remote handshake (can be nil)
* expects a remote handshake back of the same type * the dialing peer needs to send the handshake first and then waits for remote * the listening peer waits for the remote handshake and then sends it returns the remote handshake and an error
func (*Peer) Run ¶
Run starts the forever loop that handles incoming messages called within the p2p.Protocol#Run function the handler argument is a function which is called for each message received from the remote peer, a returned error causes the loop to exit resulting in disconnection
type Price ¶
type Price struct { Value uint64 // PerByte bool //True if the price is per byte or for unit Payer Payer }
Price represents the costs of a message
func (*Price) For ¶
For gives back the price for a message A protocol provides the message price in absolute value This method then returns the correct signed amount, depending on who pays, which is identified by the `payer` argument: `Send` will pass a `Sender` payer, `Receive` will pass the `Receiver` argument. Thus: If Sending and sender pays, amount positive, otherwise negative If Receiving, and receiver pays, amount positive, otherwise negative
type Prices ¶
type Prices interface { //Return the Price for a message Price(interface{}) *Price }
Prices defines how prices are being passed on to the accounting instance
type Spec ¶
type Spec struct { // Name is the name of the protocol, often a three-letter word Name string // Version is the version number of the protocol Version uint // MaxMsgSize is the maximum accepted length of the message payload MaxMsgSize uint32 // Messages is a list of message data types which this protocol uses, with // each message type being sent with its array index as the code (so // [&foo{}, &bar{}, &baz{}] would send foo, bar and baz with codes // 0, 1 and 2 respectively) // each message must have a single unique data type Messages []interface{} //hook for accounting (could be extended to multiple hooks in the future) Hook Hook // contains filtered or unexported fields }
Spec is a protocol specification including its name and version as well as the types of messages which are exchanged
func (*Spec) GetCode ¶
GetCode returns the message code of a type, and boolean second argument is false if the message type is not found
type WrappedMsg ¶
WrappedMsg is used to propagate marshalled context alongside message payloads