The PaymentChannel actor allows two parties to establish an off-chain payment channel. This channel is only one directional from the party that sends the funds to the party that receives the funds.
Settle
to begin the PaymentChannel's settling period.Collect
to finalize the PaymentChannel's on-chain state, sending the appropriate amounts to each party and terminating the actor itself.Actor Type:
Exported Methods:
type State struct {
From addr.Address
To addr.Address
ToSend abi.TokenAmount
SettlingAt abi.ChainEpoch
MinSettleHeight abi.ChainEpoch
LaneStates []*LaneState
}
From
: The owner of the channel. Expected to send microtransactions to To
off-chain.
From
is expected to fund the PaymentChannel with a token amount.From
is an ID addressFrom
is an Account actorTo
: The beneficiary who receives payments off-chain in the form of signed vouchers.
To
is expected to validate that the CurrentBalance
of the PaymentChannel actor on-chain meets or exceeds the value of the vouchers being signed off-chain.To
is an ID addressTo
is an Account actorToSend
: The token amount successfully redeemed by the highest-nonce voucher submitted to UpdateChannelState
. Paid to To
on Collect
.
From
.ToSend >= 0
ToSend <= rt.CurrentBalance()
SettlingAt
: The epoch after which a call to Collect
will send ToSend
to To
.
SettlingAt
is set to 0, denoting that the PaymentChannel is not currently settling.SettlingAt
, at which point Collect
can be called.SettlingAt >= 0
MinSettleHeight
: If set, denotes the minimum epoch at which the PaymentChannel can Settle
.
UpdateChannelState
: both parties must agree to this value.MinSettleHeight >= 0
LaneStates
: A collection of "lanes" between the parties. Each lane keeps track of its latest-seen Nonce
and total Redeemed
amount.
len(st.LaneStates) <= LaneLimit
(256)
type LaneState struct {
ID uint64
Redeemed big.Int
Nonce uint64
}
ID
: The lane's ID in st.LaneStates
.
uint64
value may serve as an ID
.sv.Lane
Redeemed
: The token amount successfully redeemed by the highest-nonce voucher associated with this lane.
Redeemed <= rt.CurrentBalance()
Redeemed >= 0
Nonce
: The highest-seen nonce attributed to a voucher redeemed for this lane.
func (pca *Actor) Constructor(rt vmr.Runtime, params *ConstructorParams) *adt.EmptyValue
Initializes actor state with the resolved addresses of params.From
and params.To
as the PaymentChannel's parties.
params.From
may be provided as address protocols SECP, BLS, or ID.
params.To
may be provided as address protocols SECP, BLS, or ID.
params.From
is not an Account actorparams.To
is not an Account actorfunc (a Actor) UpdateChannelState(rt vmr.Runtime, params *UpdateChannelStateParams) *adt.EmptyValue
Allows either party to update the channel's state by providing a voucher signed by their counterparty.
Supports two primary operations:
params.Sv.Lane
does not exist, it will be created.
UpdateChannelState
st.LaneStates
with the following values:
ID
: params.Sv.Lane
Redeemed
: params.Sv.Amount
Nonce
: params.Sv.Nonce
UpdateChannelState
is an implicit "merge" of the voucher's params.Sv.Amount
into the lane's state. A merge updates the lane's Redeemed
and Nonce
fields.
params.Sv.Merges
. For each entry therein, a merge operation will be performed from merge.Lane
into params.Sv.Lane
.Redeemed
total is subtracted from params.Sv.Amount
. The sum of these operations is added to st.ToSend
.
type UpdateChannelStateParams struct {
Sv SignedVoucher
Secret []byte
}
Sv
: A voucher signed by either st.From
or st.To
Secret
: If the SignedVoucher has a SecretPreImage (len(sv.SecretPreimage) > 0
), the hash of Secret
must match it.
len(Secret) <= MaxSecretSize
(256)
type SignedVoucher struct {
ChannelAddr addr.Address
TimeLockMin abi.ChainEpoch
TimeLockMax abi.ChainEpoch
SecretPreimage []byte
Extra *ModVerifyParams
Lane uint64
Nonce uint64
Amount big.Int
MinSettleHeight abi.ChainEpoch
Merges []Merge
Signature *crypto.Signature
}
ChannelAddr
: The address of the PaymentChannel actor this SignedVoucher is valid for
ChannelAddr == rt.Message().Receiver()
TimeLockMin
: Before epoch TimeLockMin
, this voucher may not be redeemed.
rt.CurrEpoch() < TimeLockMin
TimeLockMax
: After epoch TimeLockMax
, this voucher may not be redeemed. If TimeLockMax
is 0, this field is not checked.
TimeLockMin == TimeLockMax
implies a 1-epoch window in which the voucher may be redeemedTimeLockMax == 0 || rt.CurrEpoch() >= TimeLockMax
SecretPreimage
: If provided, params.Secret
must be a valid preimage of SecretPreimage
nil
by default.Extra
: If provided, Extra
defines an arbitrary Send that should succeed when provided some additional Proof
by the Caller.
nil
by default.ModVerifyParams
below for details on individual fields.ExitCode == 0
)Lane
: Specifies which lane the voucher will be redeemed for.
st.LaneStates
, it will be created.
Nonce
: Prevents the redemption of old vouchers. Nonce
is compared to the highest-seen nonce of the lane specified by Lane
. The lane's ls.Nonce
will be set to Nonce
.
ls.Nonce < Nonce
Amount
: The token amount this voucher may be redeemed for. The lane's ls.Redeemed
field will be set to Amount
.
Amount
, the lane's current ls.Redeemed
amount, and any ls.Redeemed
amounts from other lanes specified in Merges
will be added to st.ToSend
.Amount >= 0
MinSettleHeight
: If nonzero, may cause UpdateChannelState
to modify the settling epoch.
st.SettlingAt != 0
) AND MinSettleHeight
specifies a greater epoch, the settling epoch is updated to MinSettleHeight
.MinSettleHeight
specifies a greater epoch than the one currently recorded in st.MinSettleHeight
, this state is updated.MinSettleHeight >= 0
Merges
: If provided, denotes a collection of other lanes that will be merged into the Lane
specified by the voucher.
nil
by default.Merge
below.Signature
: A signature over sv.SigningBytes
, signed by the counterparty to the Caller.
st.From
, the signature must be from st.To
st.To
, the signature must be from st.From
Signature != nil
rt.Syscalls().VerifySignature
type ModVerifyParams struct {
Actor addr.Address
Method abi.MethodNum
Params []byte
}
Actor
: The actor to which a Send will be made, denoting extra verification.
Method
: The MethodNum of the actor to invoke.
Params
: The data provided as parameters to the method invocation.
type Merge struct {
Lane uint64
Nonce uint64
}
Lane
: Which lane will be merged into the lane specified by the voucher (sv.Lane
).
Lane
must exist in st.LaneStates
Lane != sv.Lane
Nonce
: Compared to the highest-seen nonce of the merging lane. The lane's nonce is updated to this value.
Nonce
must be greater than the current nonce of the merging lane.st.From
or st.To
sv.Signature == nil
st.SettlingAt != 0 && rt.CurrEpoch >= st.SettlingAt
len(params.Secret) > MaxSecretSize
(256)SigningBytes
rt.Syscalls().VerifySignature
)rt.Message().Receiver() != sv.ChannelAddr
)rt.CurrEpoch() < sv.TimeLockMin
sv.TimeLockMax != 0 && rt.CurrEpoch() > sv.TimeLockMax
sv.Amount < 0
len(sv.SecretPreimage) != 0
AND hashed params.Secret
does not matchsv.Extra != nil
AND external validation failssv.Lane
specifies a lane that does not exist in st.LaneStates
AND len(st.LaneStates) >= 256
ls.Nonce >= sv.Nonce
merge.Lane == sv.Lane
merge.Lane
does not exist in st.LaneStates
merge.Lane
LaneState is greater than or equal to nonce specified by merge.Nonce
st.ToSend
balance would be negativest.ToSend
balance would be greater than the current balance of the PaymentChannelfunc (pca Actor) Settle(rt vmr.Runtime, _ *adt.EmptyValue) *adt.EmptyValue
Sets st.SettlingAt
, which is the epoch where either party may call Collect
. This may only be called once.
st.SettlingAt
is set to the maximum value between rt.CurrEpoch() + SettleDelay
and st.MinSettleHeight
Once the channel has settled (CurrEpoch == st.SettlingAt
), further updates to the channel are prohibited.
st.From
or st.To
Settle
has already been called (st.SettlingAt != 0
)func (pca Actor) Collect(rt vmr.Runtime, _ *adt.EmptyValue) *adt.EmptyValue
At or after the settling epoch, allows either party to collect the amount redeemed so far.
st.ToSend
is sent to st.To
rt.DeleteActor
, with st.From
supplied as the beneficiary of the remaining funds.st.From
or st.To
st.SettlingAt == 0
, denoting that Settle
has not been called yetrt.CurrEpoch() < st.SettlingAt
, denoting that the settling epoch has not been reachedst.To
failsrt.DeleteActor(st.From)
fails because st.From
does not existSigningBytes()
add additional salt, domain separators, or other information to ensure that signed vouchers are unique in respect to both the payment channel AND the specific permutation of provided values?Syscalls().VerifySignature()
resolve the signer
to a BLS/SECP address?SignedVoucher.ChannelAddr
use the PaymentChannel's ACTOR address for re-org protection?st.From
cause the first Send
to fail in any way outside of the actor being underfunded already?