channel

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: May 4, 2020 License: MIT Imports: 15 Imported by: 56

Documentation

Overview

Package channel holds the core channel data structures. Those data structures are interpreted by the adjudicator.

Index

Constants

View Source
const IDLen = 32

IDLen the length of a channelID.

View Source
const MaxNumAssets = 1024

MaxNumAssets is an artificial limit on the number of serialized assets in an Allocation to avoid having users run out of memory when a malicious peer pretends to send a large number of assets.

View Source
const MaxNumParts = 1024

MaxNumParts is an artificial limit on the number participant assets in an Allocation to avoid having users run out of memory when a malicious peer pretends to send balances for a large number of participants. Keep in mind that an Allocation contains information about every participant's balance for every asset, i.e., there are num-assets times num-participants balances in an Allocation.

View Source
const MaxNumSubAllocations = 1024

MaxNumSubAllocations is an artificial limit on the number of suballocations in an Allocation to avoid having users run out of memory when a malicious peer pretends to send a large number of suballocations. Keep in mind that an Allocation contains information about every asset for every suballocation, i.e., there are num-assets times num-suballocations items of information in an Allocation.

Variables

This section is empty.

Functions

func IsActionApp

func IsActionApp(app App) bool

IsActionApp returns true if the app is an ActionApp.

func IsActionError

func IsActionError(err error) bool

IsActionError returns true if the error was an ActionError.

func IsAssetFundingError added in v0.2.0

func IsAssetFundingError(err error) bool

IsAssetFundingError checks whether an error is a AssetFundingError.

func IsFundingTimeoutError added in v0.2.0

func IsFundingTimeoutError(err error) bool

IsFundingTimeoutError checks whether an error is a FundingTimeoutError.

func IsPhaseTransitionError

func IsPhaseTransitionError(err error) bool

IsPhaseTransitionError returns true if the error was a PhaseTransitionError.

func IsStateApp

func IsStateApp(app App) bool

IsStateApp returns true if the app is a StateApp.

func IsStateTransitionError

func IsStateTransitionError(err error) bool

IsStateTransitionError returns true if the error was a StateTransitionError.

func NewActionError

func NewActionError(id ID, msg string) error

NewActionError creates a new ActionError.

func NewFundingTimeoutError added in v0.2.0

func NewFundingTimeoutError(fundingErrs []*AssetFundingError) error

NewFundingTimeoutError creates a new FundingTimeoutError.

func NewStateTransitionError

func NewStateTransitionError(id ID, msg string) error

NewStateTransitionError creates a new StateTransitionError.

func SetAppBackend

func SetAppBackend(b AppBackend)

SetAppBackend sets the channel package's app backend. This is more specific than the blockchain backend, so it has to be set separately. The app backend is set to the MockAppBackend by default. Because the MockApp is in package channel, we cannot set it through the usual init.go idiom. The app backend can be changed once by another app (by a SetAppBackend call of the app package's init() function).

func SetBackend

func SetBackend(b Backend)

SetBackend sets the global channel backend. Must not be called directly but through importing the needed backend.

func SetBackendTest

func SetBackendTest(t *testing.T)

SetBackendTest is a generic backend test.

func Sign

func Sign(a wallet.Account, p *Params, s *State) (wallet.Sig, error)

Sign creates a signature from the account a on state s.

func ValidateParameters

func ValidateParameters(challengeDuration uint64, numParts int, appDef wallet.Address, nonce *big.Int) error

ValidateParameters checks that the arguments form valid Params: * non-zero ChallengeDuration * non-nil nonce * at least two and at most MaxNumParts parts * appDef belongs to either a StateApp or ActionApp

func Verify

func Verify(addr wallet.Address, params *Params, state *State, sig wallet.Sig) (bool, error)

Verify verifies that a signature was a valid signature from addr on a state.

Types

type Action

type Action = perunio.Encoder

An Action is applied to a channel state to result in new state. Actions need to be Encoders so they can be sent over the wire. Decoding happens with ActionApp.DecodeAction() since the app context needs to be known at the point of decoding.

type ActionApp

type ActionApp interface {
	App
	// ValidAction checks if the provided Action by the participant at the given
	// index is valid, applied to the provided Params and State.
	// The implementation should return an ActionError describing the invalidity
	// of the action. It should return a normal error (with attached stacktrace
	// from pkg/errors) if there was any other runtime error, not related to the
	// invalidity of the action itself.
	ValidAction(*Params, *State, Index, Action) error

	// ApplyAction applies the given actions to the provided channel state and
	// returns the resulting new state.
	// The version counter should be increased by one.
	// The implementation should return an ActionError describing the invalidity
	// of the action. It should return a normal error (with attached stacktrace
	// from pkg/errors) if there was any other runtime error, not related to the
	// invalidity of the action itself.
	ApplyActions(*Params, *State, []Action) (*State, error)

	// InitState creates the initial state from the given actions. The actual
	// State will be created by the machine and only the initial allocation of
	// funds and app data can be set, as the channel id is specified by the
	// parameters and version must be 0.
	InitState(*Params, []Action) (Allocation, Data, error)

	// DecodeAction decodes actions specific to this application. This has to be
	// defined on an application-level because every app can have completely
	// different actions; during decoding the application needs to be known to
	// know how to decode an action.
	DecodeAction(io.Reader) (Action, error)
}

An ActionApp is advanced by first collecting actions from the participants and then applying those actions to the state. In a sense it is a more fine-grained version of a StateApp and allows for more optimized state channel applications.

type ActionError

type ActionError struct {
	ID ID
}

ActionError happens if an invalid action is applied to a channel state

func (*ActionError) Error

func (e *ActionError) Error() string

type ActionMachine

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

An ActionMachine is the channel pushdown automaton around an ActionApp. It implements the state transitions specific for ActionApps: AddAction, Init and Update.

func NewActionMachine

func NewActionMachine(acc wallet.Account, params Params) (*ActionMachine, error)

NewActionMachine creates a new ActionMachine.

func (ActionMachine) Account

func (m ActionMachine) Account() wallet.Account

Account returns the account this channel is using for signing state updates

func (*ActionMachine) AddAction

func (m *ActionMachine) AddAction(idx Index, a Action) error

AddAction adds the action of participant idx to the staging actions. It is checked that the action of that participant is not already set as it should not happen that an action is overwritten. The validity of the action applied to the current state is also checked as specified by the application. If the index is out of bounds, a panic occurs as this is an invalid usage of the machine.

func (ActionMachine) AddSig

func (m ActionMachine) AddSig(idx Index, sig wallet.Sig) error

AddSig verifies the provided signature of another participant on the staging state and if successful adds it to the staged transaction. It also checks whether the signature has already been set and in that case errors. It should not happen that a signature of the same participant is set twice. It is also checked that the current phase is a signing phase. If the index is out of bounds, a panic occurs as this is an invalid usage of the machine.

func (ActionMachine) AdjudicatorReq added in v0.2.0

func (m ActionMachine) AdjudicatorReq() AdjudicatorReq

SettleReq returns the settlement request for the current channel transaction (the current state together with all participants' signatures on it).

func (*ActionMachine) Clone added in v0.2.1

func (m *ActionMachine) Clone() *ActionMachine

Clone returns a deep copy of ActionMachine

func (ActionMachine) CurrentTX added in v0.2.1

func (m ActionMachine) CurrentTX() Transaction

CurrentTX returns the current current transaction.

func (ActionMachine) DiscardUpdate

func (m ActionMachine) DiscardUpdate() error

DiscardUpdate discards the current staging transaction and sets the machine's phase back to Acting. This method is useful in the case where a valid update request is rejected.

func (ActionMachine) EnableFinal

func (m ActionMachine) EnableFinal() error

EnableFinal promotes the final staging state to the final current state. A valid phase transition and the existence of all signatures is checked.

func (ActionMachine) EnableInit

func (m ActionMachine) EnableInit() error

EnableInit promotes the initial staging state to the current funding state. A valid phase transition and the existence of all signatures is checked.

func (ActionMachine) EnableUpdate

func (m ActionMachine) EnableUpdate() error

EnableUpdate promotes the current staging state to the current state. A valid phase transition and the existence of all signatures is checked.

func (ActionMachine) ID

func (m ActionMachine) ID() ID

ID returns the channel id

func (ActionMachine) Idx

func (m ActionMachine) Idx() Index

Idx returns our index in the channel participants list.

func (*ActionMachine) Init

func (m *ActionMachine) Init() error

Init creates the initial state as the combination of all initial actions.

func (ActionMachine) N

func (m ActionMachine) N() Index

N returns the number of participants of the channel parameters of this machine.

func (ActionMachine) Params

func (m ActionMachine) Params() *Params

Params returns the channel parameters

func (ActionMachine) Phase

func (m ActionMachine) Phase() Phase

Phase returns the current phase

func (ActionMachine) Registered added in v0.2.0

func (m ActionMachine) Registered() *RegisteredEvent

Registered returns the currently registered event (timeout and version), if any, or nil.

func (ActionMachine) SetFunded

func (m ActionMachine) SetFunded() error

SetFunded tells the state machine that the channel got funded and progresses to the Acting phase.

func (ActionMachine) SetRegistered added in v0.2.0

func (m ActionMachine) SetRegistered(reg *RegisteredEvent) error

SetRegistered moves the machine into the Registered phase. The passed event gets stored in the machine to record the timeout and registered version. This phase can be reached after the initial phases are done, i.e., when there's at least one state with signatures.

func (ActionMachine) SetRegistering added in v0.2.0

func (m ActionMachine) SetRegistering() error

SetRegistering tells the state machine that the current channel state is being registered on the adjudicator. This phase can be reached after the initial phases are done, i.e., when there's at least one state with signatures.

func (ActionMachine) SetWithdrawing added in v0.2.0

func (m ActionMachine) SetWithdrawing() error

SetWithdrawing sets the state machine to the Withdrawing phase. The current state was registered on-chain and funds withdrawal is in progress. This phase can only be reached from the Registered or Withdrawing phase.

func (ActionMachine) SetWithdrawn added in v0.2.0

func (m ActionMachine) SetWithdrawn() error

SetWithdrawn sets the state machine to the final phase Withdrawn. The current state was registered on-chain and funds withdrawal was successful. This phase can only be reached from the Withdrawing phase.

func (ActionMachine) Sig

func (m ActionMachine) Sig() (sig wallet.Sig, err error)

Sig returns the own signature on the currently staged state. The signature is calculated and saved to the staging TX's signature slice if it was not calculated before. A call to Sig only makes sense in a signing phase.

func (ActionMachine) StagingState

func (m ActionMachine) StagingState() *State

StagingState returns the staging state. It should usually be called after entering a signing phase to get the new staging state, which might have been created during Init() or Update() (for ActionApps). Clone the state first if you need to modify it.

func (ActionMachine) StagingTX added in v0.2.1

func (m ActionMachine) StagingTX() Transaction

StagingTX returns the current staging transaction.

func (ActionMachine) State

func (m ActionMachine) State() *State

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

func (*ActionMachine) Update

func (m *ActionMachine) Update() error

Update applies all staged actions to the current state to create the new staging state for signing.

type Adjudicator added in v0.2.0

type Adjudicator interface {
	// Register should register the given channel state on-chain. It must be
	// taken into account that a peer might already have registered the same or
	// even an old state for the same channel. If registration was successful,
	// it should return the timeout when withdrawal can be initiated with
	// Withdraw.
	Register(context.Context, AdjudicatorReq) (*RegisteredEvent, error)

	// Withdraw should conclude and withdraw the registered state, so that the
	// final outcome is set on the asset holders and funds are withdrawn
	// (dependent on the architecture of the contracts). It must be taken into
	// account that a peer might already have concluded the same channel.
	Withdraw(context.Context, AdjudicatorReq) error

	// SubscribeRegistered returns a RegisteredEvent subscription. The
	// subscription should be a subscription of the newest past as well as
	// future events. The subscription should only be valid within the given
	// context: If the context is canceled, its Next method should return nil
	// and Err should return the context's error.
	SubscribeRegistered(context.Context, *Params) (RegisteredSubscription, error)
}

An Adjudicator represents an adjudicator contract on the blockchain. It has methods for state registration and withdrawal of channel funds. A channel state needs to be registered before the concluded state can be withdrawn after a possible timeout.

Furthermore, it has a method for subscribing to RegisteredEvents. Those events might be triggered by a Register call on the adjudicator from any channel participant.

type AdjudicatorReq added in v0.2.0

type AdjudicatorReq struct {
	Params *Params
	Acc    wallet.Account
	Tx     Transaction
	Idx    Index
}

An AdjudicatorReq collects all necessary information to make calls to the adjudicator.

type Allocation

type Allocation struct {
	// Assets are the asset types held in this channel
	Assets []Asset
	// Balances is the allocation of assets to the Params.Parts
	Balances [][]Bal
	// Locked is the locked allocation to sub-app-channels. It is allowed to be
	// nil, in which case there's nothing locked.
	Locked []SubAlloc
}

Allocation is the distribution of assets, were the channel to be finalized.

Assets identify the assets held in the channel, like an address to the deposit holder contract for this asset.

Balances holds the balance allocations to the participants. Its outer dimension must match the size of Assets. Its inner dimension must match the size of the Params.parts slice. All asset distributions could have been saved as a single []SubAlloc, but this would have saved the participants slice twice, wasting space.

Locked holds the locked allocations to sub-app-channels.

func (Allocation) Clone

func (a Allocation) Clone() (clone Allocation)

Clone returns a deep copy of the Allocation object. If it is nil, it returns nil.

func (*Allocation) Decode

func (a *Allocation) Decode(r io.Reader) error

Decode decodes an allocation from an io.Reader.

func (Allocation) Encode

func (a Allocation) Encode(w io.Writer) error

Encode encodes this allocation into an io.Writer.

func (*Allocation) NumParts added in v0.2.1

func (a *Allocation) NumParts() int

NumParts returns the number of participants of this Allocation. It returns -1 if there are no Balances, i.e., if the Allocation is invalid.

func (Allocation) Sum

func (a Allocation) Sum() []Bal

Sum returns the sum of each asset over all participants and locked allocations.

func (Allocation) Valid

func (a Allocation) Valid() error

Valid checks that the asset-dimensions match and slices are not nil. Assets and Balances cannot be of zero length.

type App

type App interface {
	// Def is an identifier of the channel application. It is usually the
	// (counterfactual) on-chain address of the stateless contract that defines
	// what valid actions or transitions are.
	Def() wallet.Address

	// DecodeData decodes data specific to this application. This has to be
	// defined on an application-level because every app can have completely
	// different data; during decoding the application needs to be known to
	// know how to decode the data.
	DecodeData(io.Reader) (Data, error)
}

An App is an abstract interface for an app definition. Either a StateApp or ActionApp should be implemented.

func AppFromDefinition

func AppFromDefinition(def wallet.Address) (App, error)

AppFromDefinition is a global wrapper call to the app backend function.

type AppBackend

type AppBackend interface {
	// AppFromDefinition creates an app from its defining address. It is
	// possible that multiple apps are in use, which is why creation happens
	// over a central AppFromDefinition function.  One possible implementation
	// is that the app is just read from an app registry, mapping addresses to
	// apps.
	AppFromDefinition(wallet.Address) (App, error)
}

AppBackend provides functionality to create an App from an Address. The AppBackend needs to be implemented for every state channel application.

type Asset

type Asset = perunio.Encoder

Asset identifies an asset. E.g., it may be the address of the multi-sig where all participants' assets are deposited. The same Asset should be shareable by multiple Allocation instances. Decoding happens with AppBackend.DecodeAsset.

func DecodeAsset

func DecodeAsset(r io.Reader) (Asset, error)

DecodeAsset decodes an Asset from an io.Reader.

type AssetFundingError added in v0.2.0

type AssetFundingError struct {
	Asset         int     // The asset for which the timeouts occurred
	TimedOutPeers []Index // Indices of the peers who failed to fund in time
}

An AssetFundingError indicates the peers who timed-out funding a specific asset.

func (AssetFundingError) Error added in v0.2.0

func (e AssetFundingError) Error() string

type Backend

type Backend interface {
	// CalcID infers the channel id of a channel from its parameters. Usually,
	// this should be a hash digest of some or all fields of the parameters.
	// In order to guarantee non-malleability of States, any parameters omitted
	// from the CalcID digest need to be signed together with the State in
	// Sign().
	CalcID(*Params) ID

	// Sign signs a channel's State with the given Account.
	// Returns the signature or an error.
	// The framework guarantees to not pass nil Account, *Params or *State, that
	// the IDs of them match and that Params.ID = ChannelID(Params).
	Sign(wallet.Account, *Params, *State) (wallet.Sig, error)

	// Verify verifies that the provided signature on the state belongs to the
	// provided address.
	// The framework guarantees to not pass nil Address, *Params or *State, that
	// the IDs of them match and that Params.ID = ChannelID(Params).
	Verify(addr wallet.Address, params *Params, state *State, sig wallet.Sig) (bool, error)

	// DecodeAsset decodes an asset from a stream.
	DecodeAsset(io.Reader) (Asset, error)
}

Backend is an interface that needs to be implemented for every blockchain. It provides basic functionalities to the framework.

type Bal

type Bal = *big.Int

Bal is a single asset's balance

func CloneBals

func CloneBals(orig []Bal) []Bal

CloneBals creates a deep copy of a balance array.

type Data

type Data interface {
	perunio.Encoder
	// Clone should return a deep copy of the Data object.
	// It should return nil if the Data object is nil.
	Clone() Data
}

Data is the data of the application running in this app channel. Decoding happens with App.DecodeData.

type ElapsedTimeout added in v0.2.0

type ElapsedTimeout struct{}

ElapsedTimeout is a Timeout that is always elapsed.

func (*ElapsedTimeout) IsElapsed added in v0.2.0

func (t *ElapsedTimeout) IsElapsed(context.Context) bool

IsElapsed returns true.

func (*ElapsedTimeout) String added in v0.2.0

func (t *ElapsedTimeout) String() string

String says that this is an always elapsed timeout.

func (*ElapsedTimeout) Wait added in v0.2.0

Wait immediately return nil.

type Funder

type Funder interface {
	// Fund should fund the channel in FundingReq on the blockchain.
	// It should return an error if own funding did not succeed, possibly
	// because the peer did not fund the channel in time.
	// Depending on the funding protocol, if we fund first and then the peer does
	// not fund in time, a dispute process needs to be initiated to get back the
	// funds from the partially funded channel. In this case, the user should
	// return a PeerTimedOutFundingError containing the index of the peer who
	// did not fund in time. The framework will then initiate the dispute
	// process.
	Fund(context.Context, FundingReq) error
}

The Funder interface needs to be implemented by every blockchain backend. It provides functionality to fund a new channel on-chain.

type FundingReq

type FundingReq struct {
	Params     *Params
	Allocation *Allocation
	Idx        Index // our index
}

A FundingReq bundles all data needed to fund a channel.

type FundingTimeoutError added in v0.2.0

type FundingTimeoutError struct {
	Errors []*AssetFundingError
}

A FundingTimeoutError indicates that some peers failed funding some assets in time.

func (FundingTimeoutError) Error added in v0.2.0

func (e FundingTimeoutError) Error() string

type ID

type ID = [IDLen]byte

ID represents a channelID.

var Zero ID = ID{}

Zero is the default channelID.

func CalcID added in v0.2.0

func CalcID(p *Params) ID

CalcID calculates the CalcID.

type Index

type Index = uint16

Index is the type for the number of participants, assets, sub-allocations, actions and alike.

type MockApp

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

MockApp a mocked App whose behaviour is determined by the MockOp passed to it either as State.Data or Action. It is a StateApp and ActionApp at the same time.

func NewMockApp

func NewMockApp(definition wallet.Address) *MockApp

NewMockApp create an App with the given definition.

func (MockApp) ApplyActions

func (a MockApp) ApplyActions(params *Params, state *State, acts []Action) (*State, error)

ApplyActions applies the actions unto a copy of state and returns the result or an error.

func (MockApp) DecodeAction

func (a MockApp) DecodeAction(r io.Reader) (Action, error)

DecodeAction returns a decoded MockOp or an error.

func (MockApp) DecodeData

func (a MockApp) DecodeData(r io.Reader) (Data, error)

DecodeData returns a decoded MockOp or an error.

func (MockApp) Def

func (a MockApp) Def() wallet.Address

Def returns the definition on the MockApp.

func (MockApp) InitState

func (a MockApp) InitState(params *Params, rawActs []Action) (Allocation, Data, error)

InitState Checks for the validity of the passed arguments as initial state.

func (MockApp) ValidAction

func (a MockApp) ValidAction(params *Params, state *State, part Index, act Action) error

ValidAction checks the action for validity.

func (MockApp) ValidInit

func (a MockApp) ValidInit(params *Params, state *State) error

ValidInit checks the initial state for validity.

func (MockApp) ValidTransition

func (a MockApp) ValidTransition(params *Params, from, to *State, actor Index) error

ValidTransition checks the transition for validity.

type MockAppBackend

type MockAppBackend struct{}

MockAppBackend is the backend for a mock app.

func (MockAppBackend) AppFromDefinition

func (MockAppBackend) AppFromDefinition(addr wallet.Address) (App, error)

AppFromDefinition creates a new MockApp with the provided address.

type MockOp

type MockOp uint64

MockOp serves as Action and State.Data for MockApp.

const (
	// OpValid function call should succeed.
	OpValid MockOp = iota
	// OpErr function call should return an error.
	OpErr
	// OpTransitionErr function call should return a TransisionError.
	OpTransitionErr
	// OpActionErr function call should return an ActionError.
	OpActionErr
	// OpPanic function call should panic.
	OpPanic
)

func NewMockOp

func NewMockOp(op MockOp) *MockOp

NewMockOp returns a pointer to a MockOp with the given value this is needed, since &MockOp{OpValid} does not work.

func (MockOp) Clone

func (o MockOp) Clone() Data

Clone returns a deep copy of a MockOp.

func (*MockOp) Decode

func (o *MockOp) Decode(r io.Reader) error

Decode decodes a MockOp from an io.Reader.

func (MockOp) Encode

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

Encode encodes a MockOp into an io.Writer.

type Params

type Params struct {

	// ChallengeDuration in seconds during disputes
	ChallengeDuration uint64
	// Parts are the channel participants
	Parts []wallet.Address
	// App identifies the application that this channel is running.
	App App `cloneable:"shallow"`
	// Nonce is a randomness to make the channel id unique
	Nonce *big.Int
	// contains filtered or unexported fields
}

Params are a channel's immutable parameters. A channel's id is the hash of (some of) its parameter, as determined by the backend. All fields should be treated as constant. It should only be created through NewParams()

func NewParams

func NewParams(challengeDuration uint64, parts []wallet.Address, appDef wallet.Address, nonce *big.Int) (*Params, error)

NewParams creates Params from the given data and performs sanity checks. The channel id is also calculated here and persisted because it probably is an expensive hash operation.

func NewParamsUnsafe

func NewParamsUnsafe(challengeDuration uint64, parts []wallet.Address, appDef wallet.Address, nonce *big.Int) *Params

NewParamsUnsafe creates Params from the given data and does NOT perform sanity checks. The channel id is also calculated here and persisted because it probably is an expensive hash operation.

func (*Params) Clone added in v0.2.1

func (p *Params) Clone() *Params

Clone returns a deep copy of Params

func (*Params) ID

func (p *Params) ID() ID

ID returns the channelID of this channel.

type Phase

type Phase uint8

Phase is a phase of the channel pushdown automaton

const (
	InitActing Phase = iota
	InitSigning
	Funding
	Acting
	Signing
	Final
	Registering
	Registered
	Withdrawing
	Withdrawn
)

Phases known to the channel machine.

func (Phase) String

func (p Phase) String() string

type PhaseTransition

type PhaseTransition struct {
	From, To Phase
}

PhaseTransition represents a transition between two phases

func (PhaseTransition) String

func (t PhaseTransition) String() string

type PhaseTransitionError

type PhaseTransitionError struct {
	ID ID

	PhaseTransition
	// contains filtered or unexported fields
}

PhaseTransitionError happens in case of an invalid channel machine phase transition

func (*PhaseTransitionError) Error

func (e *PhaseTransitionError) Error() string

type RegisteredEvent added in v0.2.0

type RegisteredEvent struct {
	ID      ID      // Channel ID
	Version uint64  // Registered version.
	Timeout Timeout // Timeout when the event can be concluded or progressed
}

RegisteredEvent is the abstract event that signals a successful state registration on the blockchain.

type RegisteredSubscription added in v0.2.0

type RegisteredSubscription interface {
	// Next returns the newest past or next future event. If the subscription is
	// closed or any other error occurs, it should return nil.
	Next() *RegisteredEvent

	// Err returns the error status of the subscription. After Next returns nil,
	// Err should be checked for an error.
	Err() error

	// Close closes the subscription. Any call to Next should immediately return
	// nil.
	Close() error
}

A RegisteredSubscription is a subscription to RegisteredEvents for a specific channel. The subscription should also return the newest past RegisteredEvent, if there is any.

The usage of the subscription should be similar to that of an iterator. Next calls should block until a new event is generated (or the first past event has been found). If the channel is closed or an error is produced, Next should return nil and Err should tell the possible error.

type State

type State struct {
	// id is the immutable id of the channel this state belongs to
	ID ID
	// version counter
	Version uint64
	// App identifies the application that this channel is running.
	// We do not want a deep copy here, since the Apps are just an immutable reference.
	// They are only included in the State to support serialization of the `Data` field.
	App App `cloneable:"shallow"`
	// Allocation is the current allocation of channel assets to
	// the channel participants and apps running inside this channel.
	Allocation
	// Data is the app-specific data.
	Data Data
	// IsFinal indicates that the channel is in its final state. Such a state
	// can immediately be settled on the blockchain or a funding channel, in
	// case of sub- or virtual channels.
	// A final state cannot be further progressed.
	IsFinal bool
}

State is the full state of a state channel (app). It does not include the channel parameters. However, the included channel ID should be a commitment to the channel parameters by hash-digesting them. The state is the piece of data that is signed and sent to the adjudicator during disputes.

func (*State) Clone

func (s *State) Clone() *State

Clone makes a deep copy of the State object. If it is nil, it returns nil. App implementations should use this method when creating the next state from an old one.

func (*State) Decode

func (s *State) Decode(r io.Reader) error

Decode decodes a state from an `io.Reader` or returns an `error`

func (State) Encode

func (s State) Encode(w io.Writer) error

Encode encodes a state into an `io.Writer` or returns an `error`

type StateApp

type StateApp interface {
	App

	// ValidTransition should check that the app-specific rules of the given
	// transition from `from` to `to` are fulfilled.
	// `actor` is the index of the acting party whose action resulted in the new state.
	// The implementation should return a StateTransitionError describing the
	// invalidity of the transition, if it is not valid. It should return a normal
	// error (with attached stacktrace from pkg/errors) if there was any other
	// runtime error, not related to the invalidity of the transition itself.
	ValidTransition(parameters *Params, from, to *State, actor Index) error

	// ValidInit should perform app-specific checks for a valid initial state.
	// The framework guarantees to only pass initial states with version == 0,
	// correct channel ID and valid initial allocation.
	ValidInit(*Params, *State) error
}

A StateApp is advanced by full state updates. The validity of state transitions is checked with method ValidTransition.

type StateMachine

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

A StateMachine is the channel pushdown automaton around a StateApp. It implements the state transitions specific for StateApps: Init and Update.

func NewStateMachine

func NewStateMachine(acc wallet.Account, params Params) (*StateMachine, error)

NewStateMachine creates a new StateMachine.

func (StateMachine) Account

func (m StateMachine) Account() wallet.Account

Account returns the account this channel is using for signing state updates

func (StateMachine) AddSig

func (m StateMachine) AddSig(idx Index, sig wallet.Sig) error

AddSig verifies the provided signature of another participant on the staging state and if successful adds it to the staged transaction. It also checks whether the signature has already been set and in that case errors. It should not happen that a signature of the same participant is set twice. It is also checked that the current phase is a signing phase. If the index is out of bounds, a panic occurs as this is an invalid usage of the machine.

func (StateMachine) AdjudicatorReq added in v0.2.0

func (m StateMachine) AdjudicatorReq() AdjudicatorReq

SettleReq returns the settlement request for the current channel transaction (the current state together with all participants' signatures on it).

func (*StateMachine) CheckUpdate

func (m *StateMachine) CheckUpdate(
	state *State, actor Index,
	sig wallet.Sig, sigIdx Index,
) error

CheckUpdate checks if the given state is a valid transition from the current state and if the given signature is valid. It is a read-only operation that does not advance the state machine.

func (*StateMachine) Clone added in v0.2.1

func (m *StateMachine) Clone() *StateMachine

Clone returns a deep copy of StateMachine

func (StateMachine) CurrentTX added in v0.2.1

func (m StateMachine) CurrentTX() Transaction

CurrentTX returns the current current transaction.

func (StateMachine) DiscardUpdate

func (m StateMachine) DiscardUpdate() error

DiscardUpdate discards the current staging transaction and sets the machine's phase back to Acting. This method is useful in the case where a valid update request is rejected.

func (StateMachine) EnableFinal

func (m StateMachine) EnableFinal() error

EnableFinal promotes the final staging state to the final current state. A valid phase transition and the existence of all signatures is checked.

func (StateMachine) EnableInit

func (m StateMachine) EnableInit() error

EnableInit promotes the initial staging state to the current funding state. A valid phase transition and the existence of all signatures is checked.

func (StateMachine) EnableUpdate

func (m StateMachine) EnableUpdate() error

EnableUpdate promotes the current staging state to the current state. A valid phase transition and the existence of all signatures is checked.

func (StateMachine) ID

func (m StateMachine) ID() ID

ID returns the channel id

func (StateMachine) Idx

func (m StateMachine) Idx() Index

Idx returns our index in the channel participants list.

func (*StateMachine) Init

func (m *StateMachine) Init(initBals Allocation, initData Data) error

Init sets the initial staging state to the given balance and data. It returns the initial state and own signature on it.

func (StateMachine) N

func (m StateMachine) N() Index

N returns the number of participants of the channel parameters of this machine.

func (StateMachine) Params

func (m StateMachine) Params() *Params

Params returns the channel parameters

func (StateMachine) Phase

func (m StateMachine) Phase() Phase

Phase returns the current phase

func (StateMachine) Registered added in v0.2.0

func (m StateMachine) Registered() *RegisteredEvent

Registered returns the currently registered event (timeout and version), if any, or nil.

func (StateMachine) SetFunded

func (m StateMachine) SetFunded() error

SetFunded tells the state machine that the channel got funded and progresses to the Acting phase.

func (StateMachine) SetRegistered added in v0.2.0

func (m StateMachine) SetRegistered(reg *RegisteredEvent) error

SetRegistered moves the machine into the Registered phase. The passed event gets stored in the machine to record the timeout and registered version. This phase can be reached after the initial phases are done, i.e., when there's at least one state with signatures.

func (StateMachine) SetRegistering added in v0.2.0

func (m StateMachine) SetRegistering() error

SetRegistering tells the state machine that the current channel state is being registered on the adjudicator. This phase can be reached after the initial phases are done, i.e., when there's at least one state with signatures.

func (StateMachine) SetWithdrawing added in v0.2.0

func (m StateMachine) SetWithdrawing() error

SetWithdrawing sets the state machine to the Withdrawing phase. The current state was registered on-chain and funds withdrawal is in progress. This phase can only be reached from the Registered or Withdrawing phase.

func (StateMachine) SetWithdrawn added in v0.2.0

func (m StateMachine) SetWithdrawn() error

SetWithdrawn sets the state machine to the final phase Withdrawn. The current state was registered on-chain and funds withdrawal was successful. This phase can only be reached from the Withdrawing phase.

func (StateMachine) Sig

func (m StateMachine) Sig() (sig wallet.Sig, err error)

Sig returns the own signature on the currently staged state. The signature is calculated and saved to the staging TX's signature slice if it was not calculated before. A call to Sig only makes sense in a signing phase.

func (StateMachine) StagingState

func (m StateMachine) StagingState() *State

StagingState returns the staging state. It should usually be called after entering a signing phase to get the new staging state, which might have been created during Init() or Update() (for ActionApps). Clone the state first if you need to modify it.

func (StateMachine) StagingTX added in v0.2.1

func (m StateMachine) StagingTX() Transaction

StagingTX returns the current staging transaction.

func (StateMachine) State

func (m StateMachine) State() *State

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

func (*StateMachine) Update

func (m *StateMachine) Update(stagingState *State, actor Index) error

Update makes the provided state the staging state. It is checked whether this is a valid state transition.

type StateTransitionError

type StateTransitionError struct {
	ID ID
}

StateTransitionError happens in case of an invalid channel state transition

func (*StateTransitionError) Error

func (e *StateTransitionError) Error() string

type SubAlloc

type SubAlloc struct {
	ID   ID
	Bals []Bal
}

SubAlloc is the allocation of assets to a single receiver channel ID. The size of the balances slice must be of the same size as the assets slice of the channel Params.

func (*SubAlloc) Decode

func (s *SubAlloc) Decode(r io.Reader) error

Decode decodes the SubAlloc s encoded in r and returns an error if it failed.

func (SubAlloc) Encode

func (s SubAlloc) Encode(w io.Writer) error

Encode encodes the SubAlloc s into w and returns an error if it failed.

func (SubAlloc) Valid

func (s SubAlloc) Valid() error

Valid checks if this suballocation is valid.

type TimeTimeout added in v0.2.0

type TimeTimeout struct{ time.Time }

TimeTimeout is a Timeout that elapses after a fixed time.Time.

func (*TimeTimeout) IsElapsed added in v0.2.0

func (t *TimeTimeout) IsElapsed(context.Context) bool

IsElapsed returns whether the current time is after the fixed timeout.

func (*TimeTimeout) String added in v0.2.0

func (t *TimeTimeout) String() string

String returns the timeout's date and time string.

func (*TimeTimeout) Wait added in v0.2.0

func (t *TimeTimeout) Wait(ctx context.Context) error

Wait waits until the timeout has elapsed or the context is cancelled.

type Timeout added in v0.2.0

type Timeout interface {
	// IsElapsed should return whether the timeout has elapsed at the time of
	// the call of this method.
	IsElapsed(context.Context) bool

	// Wait waits for the timeout to elapse. If the context is canceled, Wait
	// should return immediately with the context's error.
	Wait(context.Context) error
}

A Timeout is an abstract timeout of a channel dispute. A timeout can be elapsed and it can be waited on it to elapse.

type Transaction

type Transaction struct {
	*State
	Sigs []wallet.Sig
}

Transaction is a channel state together with valid signatures from the channel participants.

func (Transaction) Clone added in v0.2.1

func (t Transaction) Clone() Transaction

Clone returns a deep copy of Transaction

func (*Transaction) Decode added in v0.2.1

func (t *Transaction) Decode(r io.Reader) error

Decode decodes a transaction from an `io.Reader` or returns an `error`

func (Transaction) Encode added in v0.2.1

func (t Transaction) Encode(w io.Writer) error

Encode encodes a transaction into an `io.Writer` or returns an `error`

Directories

Path Synopsis
Package persistence specifies how the framework interacts with a persistence backend.
Package persistence specifies how the framework interacts with a persistence backend.
test
Package test provides a Persister implementation for testing purposes.
Package test provides a Persister implementation for testing purposes.
Package test contains generic tests for channel backend implementations and random generators of Params, States etc.
Package test contains generic tests for channel backend implementations and random generators of Params, States etc.

Jump to

Keyboard shortcuts

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