channel

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2020 License: Apache-2.0 Imports: 16 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 MaxNonceLen = 32

MaxNonceLen is the maximum byte count of a nonce.

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

View Source
var MaxBalance = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1))

MaxBalance is the maximum amount of funds per asset that a user can possess. It is set to 2 ^ 256 - 1.

Functions

func AppShouldEqual added in v0.5.0

func AppShouldEqual(expected, actual App) error

AppShouldEqual compares two Apps for equality.

func AssetsAssertEqual added in v0.5.0

func AssetsAssertEqual(a []Asset, b []Asset) error

AssetsAssertEqual returns an error if the given assets are not equal.

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

func IsNoApp(a App) bool

IsNoApp checks whether an app is a NoApp.

func IsNoData added in v0.4.1

func IsNoData(d Data) bool

IsNoData returns whether an app data is NoData.

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 RegisterApp added in v0.5.0

func RegisterApp(app App)

RegisterApp registers a single app for a single address.

func RegisterAppResolver added in v0.5.0

func RegisterAppResolver(pred wallet.AddressPredicate, appRes AppResolver)

RegisterAppResolver appends the given `AddressPredicate` and `AppResolver` to the global `appRegistry`.

func RegisterDefaultApp added in v0.5.0

func RegisterDefaultApp(appRes AppResolver)

RegisterDefaultApp allows to specify a default `AppResolver` which is used by the `AppRegistry` if no predicate matches. It must be set during the initialization of the program, before any app is resolved.

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 SubAllocsAssertEqual added in v0.5.0

func SubAllocsAssertEqual(a []SubAlloc, b []SubAlloc) error

SubAllocsAssertEqual asserts that the two sub-allocations are equal. If they are unequal, an error with additional information is thrown.

func SubAllocsEqual added in v0.5.0

func SubAllocsEqual(a []SubAlloc, b []SubAlloc) bool

SubAllocsEqual returns whether the two sub-allocations are equal.

func ValidateParameters

func ValidateParameters(challengeDuration uint64, numParts int, app App, nonce Nonce) error

ValidateParameters checks that the arguments form valid Params. Checks everything from ValidateProposalParameters, and that the nonce is not nil.

func ValidateProposalParameters added in v0.4.1

func ValidateProposalParameters(challengeDuration uint64, numParts int, app App) error

ValidateProposalParameters validates all parameters that are part of the proposal message in the MPCPP. Checks the following conditions: * non-zero ChallengeDuration * 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

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

The Secondary flag is left as false. Set it manually after creating the request if you want to use optimized sencondary adjudication logic.

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
	Secondary bool
}

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

If the Secondary flag is set to true, it is assumed that this is an on-chain request that is executed by the other channel participants as well and the Adjudicator backend may run an optimized on-chain transaction protocol, possibly saving unnecessary double sending of transactions.

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
	// Locked describes the funds locked in subchannels. There is one entry
	// per subchannel.
	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) AddSubAlloc added in v0.5.0

func (a *Allocation) AddSubAlloc(subAlloc SubAlloc)

AddSubAlloc adds the given sub-allocation.

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) Equal added in v0.3.0

func (a *Allocation) Equal(b *Allocation) error

Equal returns nil if the `Allocation` objects are equal and an error if they are not equal.

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) RemoveSubAlloc added in v0.5.0

func (a *Allocation) RemoveSubAlloc(subAlloc SubAlloc) error

RemoveSubAlloc removes the given sub-allocation.

func (Allocation) SubAlloc added in v0.5.0

func (a Allocation) SubAlloc(subchannel ID) (subAlloc SubAlloc, ok bool)

SubAlloc tries to return the sub-allocation for the given subchannel. The second return value indicates success.

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.
	// Calling this function on a NoApp panics, so ensure that IsNoApp
	// returns false.
	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 NoApp added in v0.4.1

func NoApp() App

NoApp returns an empty app that contains no logic.

func Resolve added in v0.5.0

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

Resolve is a global wrapper call to the global `appRegistry`. This function is intended to resolve app definitions coming in on the wire.

type AppResolver added in v0.5.0

type AppResolver interface {
	// Resolve creates an app from its defining address. It is
	// possible that multiple apps are in use, which is why creation happens
	// over a central Resolve function. This function is intended to resolve
	// app definitions coming in on the wire.
	Resolve(wallet.Address) (App, error)
}

AppResolver provides functionality to create an App from an Address. The AppResolver 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         Index   // 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 Balances added in v0.5.0

type Balances [][]Bal

Balances two dimensional slice of `Bal`. Is a `Summer`.

func (Balances) Add added in v0.5.0

func (b Balances) Add(a Balances) Balances

Add returns the sum b + a. It panics if the dimensions do not match.

func (Balances) AssertEqual added in v0.5.0

func (b Balances) AssertEqual(bals Balances) error

AssertEqual returns an error if the two balances are not equal.

func (Balances) AssertGreaterOrEqual added in v0.5.0

func (b Balances) AssertGreaterOrEqual(bals Balances) error

AssertGreaterOrEqual returns whether each entry of b is greater or equal to the corresponding entry of bals.

func (Balances) Clone added in v0.5.0

func (b Balances) Clone() Balances

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

func (*Balances) Decoder added in v0.5.0

func (b *Balances) Decoder(numAssets, numParts Index) perunio.Decoder

Decoder returns an `io.Decoder` that can be used with our en/decode pattern.

func (Balances) Encode added in v0.5.0

func (b Balances) Encode(w io.Writer) error

Encode encodes these balances into an io.Writer.

func (Balances) Equal added in v0.5.0

func (b Balances) Equal(bals Balances) bool

Equal returns whether the two balances are equal.

func (Balances) Sub added in v0.5.0

func (b Balances) Sub(a Balances) Balances

Sub returns the difference b - a. It panics if the dimensions do not match.

func (Balances) Sum added in v0.5.0

func (b Balances) Sum() []Bal

Sum returns the sum of each asset over all participants.

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.

func NoData added in v0.4.1

func NoData() Data

NoData creates an empty app data value.

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
	State  *State
	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 MockAppResolver added in v0.5.0

type MockAppResolver struct{}

MockAppResolver resolves every given `wallet.Address` to a `mockApp`.

func (*MockAppResolver) Resolve added in v0.5.0

func (m *MockAppResolver) Resolve(addr wallet.Address) (App, error)

Resolve creates an app from its defining 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 Nonce added in v0.4.1

type Nonce = *big.Int

Nonce is the channel parameters' nonce type.

func NonceFromBytes added in v0.4.1

func NonceFromBytes(b []byte) Nonce

NonceFromBytes creates a nonce from a byte slice.

type OptAppDec added in v0.4.1

type OptAppDec struct {
	App *App
}

OptAppDec makes an optional App value decodable.

func (OptAppDec) Decode added in v0.4.1

func (d OptAppDec) Decode(r io.Reader) (err error)

Decode decodes an optional App value.

type OptAppEnc added in v0.4.1

type OptAppEnc struct {
	App
}

OptAppEnc makes an optional App value encodable.

func (OptAppEnc) Encode added in v0.4.1

func (e OptAppEnc) Encode(w io.Writer) error

Encode encodes an optional App value.

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. It is
	// optional, and if nil, signifies that a channel is a payment channel.
	App App `cloneable:"shallow"`
	// Nonce is a random value that makes the channel's ID unique.
	Nonce Nonce
	// 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, app App, nonce Nonce) (*Params, error)

NewParams creates Params from the given data and performs sanity checks. The appDef optional: if it is nil, it describes a payment channel. 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, app App, nonce Nonce) *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) Decode added in v0.3.0

func (p *Params) Decode(r stdio.Reader) error

Decode uses the pkg/io module to deserialize a params instance.

func (*Params) Encode added in v0.3.0

func (p *Params) Encode(w stdio.Writer) error

Encode uses the pkg/io module to serialize a params instance.

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) Decode added in v0.3.0

func (p *Phase) Decode(r stdio.Reader) error

Decode deserializes a Phase.

func (Phase) Encode added in v0.3.0

func (p Phase) Encode(w stdio.Writer) error

Encode serializes a Phase.

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 Source added in v0.3.0

type Source interface {
	ID() ID                 // ID is the channel ID of this source. It is the same as Params().ID().
	Idx() Index             // Idx is the own index in the channel.
	Params() *Params        // Params are the channel parameters.
	StagingTX() Transaction // StagingTX is the staged transaction (State+incomplete list of sigs).
	CurrentTX() Transaction // CurrentTX is the current transaction (State+complete list of sigs).
	Phase() Phase           // Phase is the phase in which the channel is currently in.
}

Source is a source of channel data. It allows access to all information needed for persistence. The ID, Idx and Params only need to be persisted once per channel as they stay constant during a channel's lifetime.

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

func (*State) Equal added in v0.3.0

func (s *State) Equal(t *State) error

Equal returns whether two `State` objects are equal. The App is compared by its definition, and the Apps Data by its encoding.

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 RestoreStateMachine added in v0.3.0

func RestoreStateMachine(acc wallet.Account, source Source) (*StateMachine, error)

RestoreStateMachine restores a state machine to the data given by Source.

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

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

The Secondary flag is left as false. Set it manually after creating the request if you want to use optimized sencondary adjudication logic.

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 NewSubAlloc added in v0.5.0

func NewSubAlloc(id ID, bals []Bal) *SubAlloc

NewSubAlloc creates a new sub-allocation.

func (*SubAlloc) BalancesEqual added in v0.5.0

func (s *SubAlloc) BalancesEqual(b []Bal) bool

BalancesEqual returns whether balances b equal s.Bals.

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) Equal added in v0.3.0

func (s *SubAlloc) Equal(t *SubAlloc) error

Equal returns nil if the `SubAlloc` objects are equal and an error if they are not equal.

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.
keyvalue
Package keyvalue contains an implementation of the channel persister interface using a keyvalue database interface.
Package keyvalue contains an implementation of the channel persister interface using a keyvalue database interface.
test
Package test provides a PersistRestorer implementation for testing purposes as well as a generic PersistRestorer implementation test.
Package test provides a PersistRestorer implementation for testing purposes as well as a generic PersistRestorer implementation test.
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