client

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: May 29, 2020 License: Apache-2.0 Imports: 17 Imported by: 14

Documentation

Overview

Package client contains the Perun State Channel network protocol implementation. It provides a Client that exposes the central API to communicate with a channel network. The Client provides Channel controllers to interact with individual channels.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Channel

type Channel struct {
	perunsync.OnCloser
	// contains filtered or unexported fields
}

Channel is the channel controller, progressing the channel state machine and executing the channel update and dispute protocols.

Currently, only the two-party protocol is fully implemented.

func (*Channel) Close

func (c *Channel) Close() error

Close closes the channel and all associated peer subscriptions.

func (*Channel) Ctx added in v0.3.0

func (c *Channel) Ctx() context.Context

Ctx returns a context that is active for the channel's lifetime.

func (*Channel) ID

func (c *Channel) ID() channel.ID

ID returns the channel ID.

func (*Channel) Idx

func (c *Channel) Idx() channel.Index

Idx returns our index in the channel.

func (*Channel) IsClosed added in v0.3.0

func (c *Channel) IsClosed() bool

IsClosed returns whether the channel is closed.

func (*Channel) Params

func (c *Channel) Params() *channel.Params

Params returns the channel parameters.

func (*Channel) Phase

func (c *Channel) Phase() channel.Phase

Phase returns the current phase of the channel state machine.

func (*Channel) Settle

func (c *Channel) Settle(ctx context.Context) error

Settle settles the channel: it is made sure that the current state is registered and the final balance withdrawn. This call blocks until the channel has been successfully withdrawn.

func (*Channel) State

func (c *Channel) State() *channel.State

State returns the current state. Clone it if you want to modify it.

func (*Channel) SubUpdates

func (c *Channel) SubUpdates(updateSub chan<- *channel.State)

SubUpdates sets up a subscription to state updates on the provided go channel. The subscription cannot be canceled, but it can be replaced. The provided go channel is not closed if the Channel is closed. It must not be closed while the Channel is not closed. The States that are sent on the channel are not clones but pointers to the State in the channel machine, so they must not be modified. If you need to modify the State, .Clone() it first.

func (*Channel) Update

func (c *Channel) Update(ctx context.Context, up ChannelUpdate) (err error)

Update proposes the given channel update to all channel participants.

It returns nil if all peers accept the update. If any runtime error occurs or any peer rejects the update, an error is returned.

func (*Channel) UpdateBy added in v0.3.0

func (c *Channel) UpdateBy(ctx context.Context, update func(*channel.State)) (err error)

UpdateBy updates the channel state using the update function and proposes the new state to all other channel participants.

It returns nil if all peers accept the update. If any runtime error occurs or any peer rejects the update, an error is returned.

func (*Channel) Watch added in v0.2.0

func (c *Channel) Watch() error

Watch starts the channel watcher routine. It subscribes to RegisteredEvents on the adjudicator. If an event is registered, it is handled by making sure the latest state is registered and then all funds withdrawn to the receiver specified in the adjudicator that was passed to the channel.

If handling failed, the watcher routine returns the respective error. It is the user's job to restart the watcher after the cause of the error got fixed.

type ChannelMsg

type ChannelMsg interface {
	msg.Msg
	ID() channel.ID
}

ChannelMsg are all messages that can be routed to a particular channel controller.

type ChannelProposal

type ChannelProposal struct {
	ChallengeDuration uint64
	Nonce             *big.Int
	ParticipantAddr   wallet.Address
	AppDef            wallet.Address
	InitData          channel.Data
	InitBals          *channel.Allocation
	PeerAddrs         []peer.Address
}

ChannelProposal contains all data necessary to propose a new channel to a given set of peers. It is also sent over the wire.

ChannelProposal implements the channel proposal messages from the Multi-Party Channel Proposal Protocol (MPCPP).

func (*ChannelProposal) Decode added in v0.2.1

func (c *ChannelProposal) Decode(r io.Reader) (err error)

Decode decodes a ChannelProposalRequest from an io.Reader.

func (ChannelProposal) Encode added in v0.2.1

func (c ChannelProposal) Encode(w io.Writer) error

Encode encodes the ChannelProposalReq into an io.writer.

func (ChannelProposal) SessID added in v0.2.1

func (c ChannelProposal) SessID() (sid SessionID)

SessID calculates the SessionID of a ChannelProposalReq.

func (ChannelProposal) Type added in v0.2.1

func (ChannelProposal) Type() msg.Type

Type returns msg.ChannelProposal.

func (ChannelProposal) Valid added in v0.2.1

func (c ChannelProposal) Valid() error

Valid checks that the channel proposal is valid: * ParticipantAddr, InitBals must not be nil * ValidateParameters returns nil * InitBals are valid * No locked sub-allocations * InitBals match the dimension of Parts * non-zero ChallengeDuration

type ChannelProposalAcc

type ChannelProposalAcc struct {
	SessID          SessionID
	ParticipantAddr wallet.Address
}

ChannelProposalAcc contains all data for a response to a channel proposal message. The SessID must be computed from the channel proposal messages one wishes to respond to. ParticipantAddr should be a participant address just for this channel instantiation.

The type implements the channel proposal response messages from the Multi-Party Channel Proposal Protocol (MPCPP).

func (*ChannelProposalAcc) Decode

func (acc *ChannelProposalAcc) Decode(r io.Reader) (err error)

Decode decodes a ChannelProposalAcc from an io.Reader.

func (ChannelProposalAcc) Encode

func (acc ChannelProposalAcc) Encode(w io.Writer) error

Encode encodes the ChannelProposalAcc into an io.Writer.

func (ChannelProposalAcc) Type

func (ChannelProposalAcc) Type() msg.Type

Type returns msg.ChannelProposalAcc.

type ChannelProposalRej

type ChannelProposalRej struct {
	SessID SessionID
	Reason string
}

ChannelProposalRej is used to reject a ChannelProposalReq. An optional reason for the rejection can be set.

The message is one of two possible responses in the Multi-Party Channel Proposal Protocol (MPCPP).

func (*ChannelProposalRej) Decode

func (rej *ChannelProposalRej) Decode(r io.Reader) error

Decode decodes a ChannelProposalRej from an io.Reader.

func (ChannelProposalRej) Encode

func (rej ChannelProposalRej) Encode(w io.Writer) error

Encode encodes a ChannelProposalRej into an io.Writer.

func (ChannelProposalRej) Type

func (ChannelProposalRej) Type() msg.Type

Type returns msg.ChannelProposalRej.

type ChannelUpdate

type ChannelUpdate struct {
	// State is the proposed new state.
	State *channel.State
	// ActorIdx is the actor causing the new state.  It does not need to
	// coincide with the sender of the request.
	ActorIdx uint16
}

ChannelUpdate is a channel update proposal.

type Client

type Client struct {
	sync.Closer
	// contains filtered or unexported fields
}

Client is a state channel client. It is the central controller to interact with a state channel network. It can be used to propose channels to other channel network peers.

Currently, only the two-party protocol is fully implemented.

func New

func New(
	id peer.Identity,
	dialer peer.Dialer,
	funder channel.Funder,
	adjudicator channel.Adjudicator,
	wallet wallet.Wallet,
) *Client

New creates a new State Channel Client.

id is the channel network identity. It is the persistend identifier in the network and not necessarily related to any on-chain identity or channel identity.

The dialer is used to dial new peers when a peer connection is not yet established, e.g. when proposing a channel.

The funder and adjudicator are used to fund and dispute or settle a ledger channel, respectively.

The wallet is used to resolve addresses to accounts when creating or restoring channels.

If any argument is nil, New panics.

func (*Client) Channel added in v0.2.0

func (c *Client) Channel(id channel.ID) (*Channel, error)

Channel queries a channel by its ID.

func (*Client) Close

func (c *Client) Close() error

Close closes this state channel client. It also closes the peer registry.

func (*Client) EnablePersistence added in v0.3.0

func (c *Client) EnablePersistence(pr persistence.PersistRestorer)

EnablePersistence sets the PersistRestorer that the client is going to use for channel persistence. This methods is expected to be called once during the setup of the client and is hence not thread-safe.

The PersistRestorer is not closed when the Client is closed.

func (*Client) Handle added in v0.3.0

func (c *Client) Handle(ph ProposalHandler, uh UpdateHandler)

Handle is the incoming request handler routine. It handles channel proposals and channel update requests. It must be started exactly once by the user, during the setup of the Client. Incoming requests are handled by the passed respecive handlers.

func (*Client) Listen

func (c *Client) Listen(listener peer.Listener)

Listen starts listening for incoming connections on the provided listener and currently just automatically accepts them after successful authentication. This function does not start go routines but instead should be started by the user as `go client.Listen()`. The client takes ownership of the listener and will close it when the client is closed.

func (*Client) Log

func (c *Client) Log() log.Logger

Log is the getter for the client's field logger.

func (*Client) OnNewChannel added in v0.3.0

func (c *Client) OnNewChannel(handler func(*Channel))

OnNewChannel sets a callback to be called whenever a new channel is created or restored. Only one such handler can be set at a time, and repeated calls to this function will overwrite the currently existing handler. This function may be safely called at any time.

func (*Client) ProposeChannel

func (c *Client) ProposeChannel(ctx context.Context, req *ChannelProposal) (*Channel, error)

ProposeChannel attempts to open a channel with the parameters and peers from ChannelProposal prop: - the proposal is sent to the peers and if all peers accept, - the channel is funded. If successful, - the channel controller is returned.

After the channel got successfully created, the user is required to start the update handler with Channel.ListenUpdates(UpdateHandler) and to start the channel watcher with Channel.Watch(context.Context) on the returned channel controller.

It is important that the passed context does not cancel before twice the ChallengeDuration has passed (at least for real blockchain backends with wall time), or the channel cannot be settled if a peer times out funding.

func (*Client) Reconnect added in v0.3.0

func (c *Client) Reconnect(ctx context.Context) error

Reconnect attempts to reconnect to all known peers from persistence. This will restore all channels for all peers to which a connection could successfully be established. Newly restored channels should be acquired through the OnNewChannel callback.

Note that connections are currently established serially, so allow for enough time in the passed context.

type ProposalAcc

type ProposalAcc struct {
	Participant wallet.Address
}

ProposalAcc is the proposal acceptance struct that the user passes to ProposalResponder.Accept() when they want to accept an incoming channel proposal.

type ProposalHandler

type ProposalHandler interface {
	// Handle is the user callback called by the Client on an incoming channel
	// proposal.
	Handle(*ChannelProposal, *ProposalResponder)
}

A ProposalHandler decides how to handle incoming channel proposals from other channel network peers.

type ProposalHandlerFunc added in v0.3.0

type ProposalHandlerFunc func(*ChannelProposal, *ProposalResponder)

ProposalHandlerFunc is an adapter type to allow the use of functions as proposal handlers. ProposalHandlerFunc(f) is a ProposalHandler that calls f when Handle is called.

func (ProposalHandlerFunc) Handle added in v0.3.0

Handle calls the proposal handler function.

type ProposalResponder

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

ProposalResponder lets the user respond to a channel proposal. If the user wants to accept the proposal, they should call Accept(), otherwise Reject(). Only a single function must be called and every further call causes a panic.

func (*ProposalResponder) Accept

func (r *ProposalResponder) Accept(ctx context.Context, acc ProposalAcc) (*Channel, error)

Accept lets the user signal that they want to accept the channel proposal. Returns the newly created channel controller if the channel was successfully created and funded. Panics if the proposal was already accepted or rejected.

After the channel got successfully created, the user is required to start the update handler with Channel.ListenUpdates(UpdateHandler) and to start the channel watcher with Channel.Watch() on the returned channel controller.

It is important that the passed context does not cancel before twice the ChallengeDuration has passed (at least for real blockchain backends with wall time), or the channel cannot be settled if a peer times out funding.

func (*ProposalResponder) Reject

func (r *ProposalResponder) Reject(ctx context.Context, reason string) error

Reject lets the user signal that they reject the channel proposal. Returns whether the rejection message was successfully sent. Panics if the proposal was already accepted or rejected.

type SessionID

type SessionID = [32]byte

SessionID is a unique identifier generated for every instantiantiation of a channel.

type TestChannel added in v0.2.0

type TestChannel struct {
	*Channel
}

TestChannel grants access to the `AdjudicatorRequest` which is otherwise hidden by `Channel`. Behaves like a `Channel` in all other cases.

Only used for testing.

func NewTestChannel added in v0.2.0

func NewTestChannel(c *Channel) *TestChannel

NewTestChannel creates a new `TestChannel` from a `Channel`.

func (*TestChannel) AdjudicatorReq added in v0.2.0

func (c *TestChannel) AdjudicatorReq() channel.AdjudicatorReq

AdjudicatorReq returns the `AdjudicatorReq` of the underlying machine.

type UpdateHandler

type UpdateHandler interface {
	// Handle is the user callback called by the channel controller on an
	// incoming update request.
	Handle(ChannelUpdate, *UpdateResponder)
}

An UpdateHandler decides how to handle incoming channel update requests from other channel participants.

type UpdateHandlerFunc added in v0.3.0

type UpdateHandlerFunc func(ChannelUpdate, *UpdateResponder)

UpdateHandlerFunc is an adapter type to allow the use of functions as update handlers. UpdateHandlerFunc(f) is an UpdateHandler that calls f when Handle is called.

func (UpdateHandlerFunc) Handle added in v0.3.0

Handle calls the update handler function.

type UpdateResponder

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

The UpdateResponder allows the user to react to the incoming channel update request. If the user wants to accept the update, Accept() should be called, otherwise Reject(), possibly giving a reason for the rejection. Only a single function must be called and every further call causes a panic.

func (*UpdateResponder) Accept

func (r *UpdateResponder) Accept(ctx context.Context) error

Accept lets the user signal that they want to accept the channel update.

func (*UpdateResponder) Reject

func (r *UpdateResponder) Reject(ctx context.Context, reason string) error

Reject lets the user signal that they reject the channel update.

Directories

Path Synopsis
Package test contains helpers for testing the client
Package test contains helpers for testing the client

Jump to

Keyboard shortcuts

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