client

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Sep 22, 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 BaseChannelProposal added in v0.4.1

type BaseChannelProposal struct {
	ChallengeDuration uint64              // Dispute challenge duration.
	NonceShare        NonceShare          // Proposer's channel nonce share.
	ParticipantAddr   wallet.Address      // Proposer's address in the channel.
	App               channel.App         // App definition, or nil.
	InitData          channel.Data        // Initial App data, or nil (if App nil).
	InitBals          *channel.Allocation // Initial balances.
	PeerAddrs         []wire.Address      // Participants' wire addresses.
}

BaseChannelProposal 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 (*BaseChannelProposal) Decode added in v0.4.1

func (p *BaseChannelProposal) Decode(r io.Reader) (err error)

Decode decodes a ChannelProposalRequest from an io.Reader.

func (*BaseChannelProposal) Encode added in v0.4.1

func (p *BaseChannelProposal) Encode(w io.Writer) error

Encode encodes the ChannelProposalReq into an io.writer.

func (*BaseChannelProposal) NewChannelProposalAcc added in v0.4.1

func (p *BaseChannelProposal) NewChannelProposalAcc(
	participantAddr wallet.Address,
	nonceShare ProposalOpts,
) *ChannelProposalAcc

NewChannelProposalAcc constructs an accept message that belongs to a proposal message. It should be used instead of manually constructing an accept message.

func (*BaseChannelProposal) Proposal added in v0.4.1

Proposal returns the channel proposal's common values.

func (*BaseChannelProposal) ProposalID added in v0.4.1

func (p *BaseChannelProposal) ProposalID() (propID ProposalID)

ProposalID returns the identifier of this channel proposal request as specified by the Channel Proposal Protocol (CPP).

func (*BaseChannelProposal) Valid added in v0.4.1

func (p *BaseChannelProposal) Valid() error

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

type Channel

type Channel struct {
	perunsync.OnCloser
	log.Embedding
	// 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) OnUpdate added in v0.4.1

func (c *Channel) OnUpdate(cb func(from, to *channel.State))

OnUpdate sets up a callback to state updates for the channel. The subscription cannot be canceled, but it can be replaced. The States that are passed to the callback 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() them first.

func (*Channel) Params

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

Params returns the channel parameters.

func (*Channel) Peers added in v0.4.0

func (c *Channel) Peers() []wire.Address

Peers returns the Perun network addresses of all peers, in the order of the channel participants.

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) SettleSecondary added in v0.4.1

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

SettleSecondary 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.

SettleSecondary is a variant of Settle that can be called when collaboratively settling a channel at the same time as the other channel peers. The initiator of the channel settlement should call Settle, whereas all responders can call SettleSecondary. The blockchain backend might then run an optimized settlement protocol that possibly saves sending unnecessary duplicate transactions in parallel. If the initiator is maliciously not sending the required transactions, the backend guarantees that it will eventually send the required transactions, so it is always safe to call SettleSecondary.

func (*Channel) State

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

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

func (*Channel) Update

func (c *Channel) Update(ctx context.Context, next *channel.State) (err error)

Update proposes the `next` state to all channel participants. `next` should not be modified while this function runs.

Returns nil if all peers accept the update. If any runtime error occurs or any peer rejects the update, an error is returned. nolint: funlen

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.

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 {
	wire.Msg
	ID() channel.ID
}

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

type ChannelProposal

type ChannelProposal interface {
	wire.Msg
	perunio.Decoder

	// Proposal returns the channel proposal's common values.
	Proposal() *BaseChannelProposal
}

ChannelProposal is the interface that describes all channel proposal message types.

type ChannelProposalAcc

type ChannelProposalAcc struct {
	ProposalID      ProposalID     // Proposal session ID we're answering.
	NonceShare      NonceShare     // Responder's channel nonce share.
	ParticipantAddr wallet.Address // Responder's participant address.
}

ChannelProposalAcc contains all data for a response to a channel proposal message. The ProposalID must correspond to the channel proposal request 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() wire.Type

Type returns wire.ChannelProposalAcc.

type ChannelProposalRej

type ChannelProposalRej struct {
	ProposalID ProposalID // The channel proposal to reject.
	Reason     string     // The rejection reason.
}

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() wire.Type

Type returns wire.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 channel.Index
}

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(
	address wire.Address,
	bus wire.Bus,
	funder channel.Funder,
	adjudicator channel.Adjudicator,
	wallet wallet.Wallet,
) (c *Client, err error)

New creates a new State Channel Client.

address is the channel network address of this client. It is the persistend identifier in the network and not necessarily related to any on-chain identity or channel participant address.

bus is the wire protocol bus over which messages to other network clients are sent and received from.

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) Log

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

Log returns the logger used by the client. It is not thread-safe.

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 controller got successfully set up, it is passed to the callback registered with Client.OnNewChannel. Accept returns after this callback has run.

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.

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

func (*Client) Restore added in v0.4.0

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

Restore restores all channels from persistence. Channels are restored in parallel. Newly restored channels should be acquired through the OnNewChannel callback.

func (*Client) SetLog added in v0.4.0

func (c *Client) SetLog(l log.Logger)

SetLog sets the logger used by the client. It is not thread-safe.

type LedgerChannelProposal added in v0.4.1

type LedgerChannelProposal struct {
	BaseChannelProposal
}

LedgerChannelProposal is a channel proposal for ledger channels and has no additional values beyond a BaseChannelProposal.

func NewLedgerChannelProposal added in v0.4.1

func NewLedgerChannelProposal(
	challengeDuration uint64,
	participantAddr wallet.Address,
	initBals *channel.Allocation,
	peerAddrs []wire.Address,
	opts ...ProposalOpts,
) *LedgerChannelProposal

NewLedgerChannelProposal creates a ledger channel proposal and applies the supplied options. For more information, see ProposalOpts.

func (LedgerChannelProposal) Type added in v0.4.1

Type returns wire.ChannelProposal.

type NonceShare added in v0.4.1

type NonceShare = [32]byte

NonceShare is used to cooperatively calculate a channel's nonce.

type OptAppAndDataDec added in v0.4.1

type OptAppAndDataDec struct {
	App  *channel.App
	Data *channel.Data
}

OptAppAndDataDec makes an optional pair of App definition and Data decodable.

func (OptAppAndDataDec) Decode added in v0.4.1

func (o OptAppAndDataDec) Decode(r io.Reader) (err error)

Decode decodes an optional pair of App definition and Data.

type OptAppAndDataEnc added in v0.4.1

type OptAppAndDataEnc struct {
	channel.App
	channel.Data
}

OptAppAndDataEnc makes an optional pair of App definition and Data encodable.

func (OptAppAndDataEnc) Encode added in v0.4.1

func (o OptAppAndDataEnc) Encode(w io.Writer) error

Encode encodes an optional pair of App definition and Data.

type ProposalHandler

type ProposalHandler interface {
	// HandleProposal is the user callback called by the Client on an incoming channel
	// proposal.
	HandleProposal(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 HandleProposal is called.

func (ProposalHandlerFunc) HandleProposal added in v0.4.0

func (f ProposalHandlerFunc) HandleProposal(p ChannelProposal, r *ProposalResponder)

HandleProposal calls the proposal handler function.

type ProposalID added in v0.4.1

type ProposalID = [32]byte

ProposalID uniquely identifies the channel proposal as specified by the Channel Proposal Protocol (CPP).

type ProposalOpts added in v0.4.1

type ProposalOpts map[string]interface{}

ProposalOpts contains optional configuration instructions for channel proposals and channel proposal acceptance messages. Per default, NoApp and NoData is set, and a random nonce share is generated.

func WithApp added in v0.4.1

func WithApp(app channel.App, initData channel.Data) ProposalOpts

WithApp configures an app and initial data.

func WithNonce added in v0.4.1

func WithNonce(share NonceShare) ProposalOpts

WithNonce configures a fixed nonce share.

func WithNonceFrom added in v0.4.1

func WithNonceFrom(r io.Reader) ProposalOpts

WithNonceFrom reads a nonce share from a reader (should be random stream).

func WithRandomNonce added in v0.4.1

func WithRandomNonce() ProposalOpts

WithRandomNonce creates a nonce from crypto/rand.Reader.

func WithoutApp added in v0.4.1

func WithoutApp() ProposalOpts

WithoutApp configures a NoApp and NoData.

func (ProposalOpts) App added in v0.4.1

func (o ProposalOpts) App() channel.App

App returns the option's configured app.

func (ProposalOpts) AppData added in v0.4.1

func (o ProposalOpts) AppData() channel.Data

AppData returns the option's configured app data.

func (ProposalOpts) SetsApp added in v0.4.1

func (o ProposalOpts) SetsApp() bool

SetsApp returns whether an app and data have been explicitly set.

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

Accept lets the user signal that they want to accept the channel proposal. The ChannelProposalAcc message has to be created using ChannelProposal.Proposal().NewChannelProposalAcc on the proposal that was passed to the handler.

Accept 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 controller got successfully set up, it is passed to the callback registered with Client.OnNewChannel. Accept returns after this callback has run.

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.

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

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 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 {
	// HandleUpdate is the user callback called by the channel controller on an
	// incoming update request.
	HandleUpdate(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 HandleUpdate is called.

func (UpdateHandlerFunc) HandleUpdate added in v0.4.0

func (f UpdateHandlerFunc) HandleUpdate(u ChannelUpdate, r *UpdateResponder)

HandleUpdate 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 testing setup types and functions for package client.
Package test contains testing setup types and functions for package client.

Jump to

Keyboard shortcuts

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