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 AccountingApi
- func (self *AccountingApi) Balance() (int64, error)
- func (self *AccountingApi) BalanceCredit() (int64, error)
- func (self *AccountingApi) BalanceDebit() (int64, error)
- func (self *AccountingApi) BytesCredit() (int64, error)
- func (self *AccountingApi) BytesDebit() (int64, error)
- func (self *AccountingApi) MsgCredit() (int64, error)
- func (self *AccountingApi) MsgDebit() (int64, error)
- func (self *AccountingApi) PeerDrops() (int64, error)
- func (self *AccountingApi) SelfDrops() (int64, error)
- type AccountingMetrics
- 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
const AccountingVersion = "1.0"
Textual version number of accounting API
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
type AccountingApi ¶
type AccountingApi struct {
// contains filtered or unexported fields
}
AccountingApi provides an API to access account related information
func NewAccountingApi ¶
func NewAccountingApi(m *AccountingMetrics) *AccountingApi
NewAccountingApi creates a new AccountingApi m will be used to check if accounting metrics are enabled
func (*AccountingApi) Balance ¶
func (self *AccountingApi) Balance() (int64, error)
Balance returns local node balance (units credited - units debited)
func (*AccountingApi) BalanceCredit ¶
func (self *AccountingApi) BalanceCredit() (int64, error)
BalanceCredit returns total amount of units credited by local node
func (*AccountingApi) BalanceDebit ¶
func (self *AccountingApi) BalanceDebit() (int64, error)
BalanceCredit returns total amount of units debited by local node
func (*AccountingApi) BytesCredit ¶
func (self *AccountingApi) BytesCredit() (int64, error)
BytesCredit returns total amount of bytes credited by local node
func (*AccountingApi) BytesDebit ¶
func (self *AccountingApi) BytesDebit() (int64, error)
BalanceCredit returns total amount of bytes debited by local node
func (*AccountingApi) MsgCredit ¶
func (self *AccountingApi) MsgCredit() (int64, error)
MsgCredit returns total amount of messages credited by local node
func (*AccountingApi) MsgDebit ¶
func (self *AccountingApi) MsgDebit() (int64, error)
MsgDebit returns total amount of messages debited by local node
func (*AccountingApi) PeerDrops ¶
func (self *AccountingApi) PeerDrops() (int64, error)
PeerDrops returns number of times when local node had to drop remote peers
func (*AccountingApi) SelfDrops ¶
func (self *AccountingApi) SelfDrops() (int64, error)
SelfDrops returns number of times when local node was overdrafted and dropped
type AccountingMetrics ¶
type AccountingMetrics struct {
// contains filtered or unexported fields
}
AccountMetrics abstracts away the metrics DB and the reporter to persist metrics
func NewAccountingMetrics ¶
NewMetricsDB creates a new LevelDB instance used to persist metrics defined inside p2p/protocols/accounting.go
func SetupAccountingMetrics ¶
func SetupAccountingMetrics(reportInterval time.Duration, path string) *AccountingMetrics
SetupAccountingMetrics uses a separate registry for p2p accounting metrics; this registry should be independent of any other metrics as it persists at different endpoints. It also starts the persisting go-routine which at the passed interval writes the metrics to a LevelDB
func (*AccountingMetrics) Close ¶
func (am *AccountingMetrics) Close()
Close will be called when the node is being shutdown for a graceful cleanup
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