Merge pull request #3111 from filecoin-project/fix/paych-addvchr-chk
paych: check To address is owned by wallet for inbound channels
This commit is contained in:
commit
2f6f978cd5
@ -124,9 +124,7 @@ func (a *PaychAPI) PaychVoucherCheckSpendable(ctx context.Context, ch address.Ad
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *PaychAPI) PaychVoucherAdd(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
func (a *PaychAPI) PaychVoucherAdd(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
||||||
_ = a.PaychMgr.TrackInboundChannel(ctx, ch) // TODO: expose those calls
|
return a.PaychMgr.AddVoucherInbound(ctx, ch, sv, proof, minDelta)
|
||||||
|
|
||||||
return a.PaychMgr.AddVoucher(ctx, ch, sv, proof, minDelta)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaychVoucherCreate creates a new signed voucher on the given payment channel
|
// PaychVoucherCreate creates a new signed voucher on the given payment channel
|
||||||
@ -164,7 +162,7 @@ func (a *PaychAPI) paychVoucherCreate(ctx context.Context, pch address.Address,
|
|||||||
|
|
||||||
sv.Signature = sig
|
sv.Signature = sig
|
||||||
|
|
||||||
if _, err := a.PaychMgr.AddVoucher(ctx, pch, sv, nil, types.NewInt(0)); err != nil {
|
if _, err := a.PaychMgr.AddVoucherOutbound(ctx, pch, sv, nil, types.NewInt(0)); err != nil {
|
||||||
return nil, xerrors.Errorf("failed to persist voucher: %w", err)
|
return nil, xerrors.Errorf("failed to persist voucher: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,8 +45,10 @@ type stateManagerAPI interface {
|
|||||||
|
|
||||||
// paychAPI defines the API methods needed by the payment channel manager
|
// paychAPI defines the API methods needed by the payment channel manager
|
||||||
type paychAPI interface {
|
type paychAPI interface {
|
||||||
|
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||||
StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error)
|
StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error)
|
||||||
MpoolPushMessage(ctx context.Context, msg *types.Message, maxFee *api.MessageSendSpec) (*types.SignedMessage, error)
|
MpoolPushMessage(ctx context.Context, msg *types.Message, maxFee *api.MessageSendSpec) (*types.SignedMessage, error)
|
||||||
|
WalletHas(ctx context.Context, addr address.Address) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// managerAPI defines all methods needed by the manager
|
// managerAPI defines all methods needed by the manager
|
||||||
@ -127,26 +129,6 @@ func (pm *Manager) Stop() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) TrackOutboundChannel(ctx context.Context, ch address.Address) error {
|
|
||||||
return pm.trackChannel(ctx, ch, DirOutbound)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pm *Manager) TrackInboundChannel(ctx context.Context, ch address.Address) error {
|
|
||||||
return pm.trackChannel(ctx, ch, DirInbound)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pm *Manager) trackChannel(ctx context.Context, ch address.Address, dir uint64) error {
|
|
||||||
pm.lk.Lock()
|
|
||||||
defer pm.lk.Unlock()
|
|
||||||
|
|
||||||
ci, err := pm.sa.loadStateChannelInfo(ctx, ch, dir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return pm.store.TrackChannel(ci)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pm *Manager) GetPaych(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, cid.Cid, error) {
|
func (pm *Manager) GetPaych(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, cid.Cid, error) {
|
||||||
chanAccessor, err := pm.accessorByFromTo(from, to)
|
chanAccessor, err := pm.accessorByFromTo(from, to)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -218,7 +200,9 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address
|
|||||||
return ca.checkVoucherSpendable(ctx, ch, sv, secret, proof)
|
return ca.checkVoucherSpendable(ctx, ch, sv, secret, proof)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
// AddVoucherOutbound adds a voucher for an outbound channel.
|
||||||
|
// Returns an error if the channel is not already in the store.
|
||||||
|
func (pm *Manager) AddVoucherOutbound(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
||||||
ca, err := pm.accessorByAddress(ch)
|
ca, err := pm.accessorByAddress(ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.NewInt(0), err
|
return types.NewInt(0), err
|
||||||
@ -226,6 +210,70 @@ func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *paych
|
|||||||
return ca.addVoucher(ctx, ch, sv, proof, minDelta)
|
return ca.addVoucher(ctx, ch, sv, proof, minDelta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddVoucherInbound adds a voucher for an inbound channel.
|
||||||
|
// If the channel is not in the store, fetches the channel from state (and checks that
|
||||||
|
// the channel To address is owned by the wallet).
|
||||||
|
func (pm *Manager) AddVoucherInbound(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
||||||
|
// Make sure channel is in store, or can be fetched from state, and that
|
||||||
|
// the channel To address is owned by the wallet
|
||||||
|
ci, err := pm.trackInboundChannel(ctx, ch)
|
||||||
|
if err != nil {
|
||||||
|
return types.BigInt{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is an inbound channel, so To is the Control address (this node)
|
||||||
|
from := ci.Target
|
||||||
|
to := ci.Control
|
||||||
|
ca, err := pm.accessorByFromTo(from, to)
|
||||||
|
if err != nil {
|
||||||
|
return types.BigInt{}, err
|
||||||
|
}
|
||||||
|
return ca.addVoucher(ctx, ch, sv, proof, minDelta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pm *Manager) trackInboundChannel(ctx context.Context, ch address.Address) (*ChannelInfo, error) {
|
||||||
|
// Need to take an exclusive lock here so that channel operations can't run
|
||||||
|
// in parallel (see channelLock)
|
||||||
|
pm.lk.Lock()
|
||||||
|
defer pm.lk.Unlock()
|
||||||
|
|
||||||
|
// Check if channel is in store
|
||||||
|
ci, err := pm.store.ByAddress(ch)
|
||||||
|
if err == nil {
|
||||||
|
// Channel is in store, so it's already being tracked
|
||||||
|
return ci, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there's an error (besides channel not in store) return err
|
||||||
|
if err != ErrChannelNotTracked {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel is not in store, so get channel from state
|
||||||
|
stateCi, err := pm.sa.loadStateChannelInfo(ctx, ch, DirInbound)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that channel To address is in wallet
|
||||||
|
to := stateCi.Control // Inbound channel so To addr is Control (this node)
|
||||||
|
toKey, err := pm.pchapi.StateAccountKey(ctx, to, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
has, err := pm.pchapi.WalletHas(ctx, toKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !has {
|
||||||
|
msg := "cannot add voucher for channel %s: wallet does not have key for address %s"
|
||||||
|
return nil, xerrors.Errorf(msg, ch, to)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save channel to store
|
||||||
|
return pm.store.TrackChannel(stateCi)
|
||||||
|
}
|
||||||
|
|
||||||
func (pm *Manager) AllocateLane(ch address.Address) (uint64, error) {
|
func (pm *Manager) AllocateLane(ch address.Address) (uint64, error) {
|
||||||
ca, err := pm.accessorByAddress(ch)
|
ca, err := pm.accessorByAddress(ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -111,6 +111,7 @@ type mockPaychAPI struct {
|
|||||||
messages map[cid.Cid]*types.SignedMessage
|
messages map[cid.Cid]*types.SignedMessage
|
||||||
waitingCalls map[cid.Cid]*waitingCall
|
waitingCalls map[cid.Cid]*waitingCall
|
||||||
waitingResponses map[cid.Cid]*waitingResponse
|
waitingResponses map[cid.Cid]*waitingResponse
|
||||||
|
wallet map[address.Address]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMockPaychAPI() *mockPaychAPI {
|
func newMockPaychAPI() *mockPaychAPI {
|
||||||
@ -118,6 +119,7 @@ func newMockPaychAPI() *mockPaychAPI {
|
|||||||
messages: make(map[cid.Cid]*types.SignedMessage),
|
messages: make(map[cid.Cid]*types.SignedMessage),
|
||||||
waitingCalls: make(map[cid.Cid]*waitingCall),
|
waitingCalls: make(map[cid.Cid]*waitingCall),
|
||||||
waitingResponses: make(map[cid.Cid]*waitingResponse),
|
waitingResponses: make(map[cid.Cid]*waitingResponse),
|
||||||
|
wallet: make(map[address.Address]struct{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,3 +201,22 @@ func (pchapi *mockPaychAPI) pushedMessageCount() int {
|
|||||||
|
|
||||||
return len(pchapi.messages)
|
return len(pchapi.messages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pchapi *mockPaychAPI) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||||
|
return addr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pchapi *mockPaychAPI) WalletHas(ctx context.Context, addr address.Address) (bool, error) {
|
||||||
|
pchapi.lk.Lock()
|
||||||
|
defer pchapi.lk.Unlock()
|
||||||
|
|
||||||
|
_, ok := pchapi.wallet[addr]
|
||||||
|
return ok, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pchapi *mockPaychAPI) addWalletAddress(addr address.Address) {
|
||||||
|
pchapi.lk.Lock()
|
||||||
|
defer pchapi.lk.Unlock()
|
||||||
|
|
||||||
|
pchapi.wallet[addr] = struct{}{}
|
||||||
|
}
|
||||||
|
@ -64,11 +64,13 @@ func (ca *channelAccessor) checkVoucherValidUnlocked(ctx context.Context, ch add
|
|||||||
return nil, xerrors.Errorf("voucher ChannelAddr doesn't match channel address, got %s, expected %s", sv.ChannelAddr, ch)
|
return nil, xerrors.Errorf("voucher ChannelAddr doesn't match channel address, got %s, expected %s", sv.ChannelAddr, ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
act, pchState, err := ca.sa.loadPaychState(ctx, ch)
|
// Load payment channel actor state
|
||||||
|
act, pchState, err := ca.sa.loadPaychActorState(ctx, ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load channel "From" account actor state
|
||||||
var actState account.State
|
var actState account.State
|
||||||
_, err = ca.api.LoadActorState(ctx, pchState.From, &actState, nil)
|
_, err = ca.api.LoadActorState(ctx, pchState.From, &actState, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -76,7 +78,7 @@ func (ca *channelAccessor) checkVoucherValidUnlocked(ctx context.Context, ch add
|
|||||||
}
|
}
|
||||||
from := actState.Address
|
from := actState.Address
|
||||||
|
|
||||||
// verify signature
|
// verify voucher signature
|
||||||
vb, err := sv.SigningBytes()
|
vb, err := sv.SigningBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -29,95 +29,16 @@ import (
|
|||||||
ds_sync "github.com/ipfs/go-datastore/sync"
|
ds_sync "github.com/ipfs/go-datastore/sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPaychOutbound(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
|
||||||
|
|
||||||
ch := tutils.NewIDAddr(t, 100)
|
|
||||||
from := tutils.NewIDAddr(t, 101)
|
|
||||||
to := tutils.NewIDAddr(t, 102)
|
|
||||||
fromAcct := tutils.NewIDAddr(t, 201)
|
|
||||||
toAcct := tutils.NewIDAddr(t, 202)
|
|
||||||
|
|
||||||
mock := newMockManagerAPI()
|
|
||||||
arr, err := adt.MakeEmptyArray(mock.store).Root()
|
|
||||||
require.NoError(t, err)
|
|
||||||
mock.setAccountState(fromAcct, account.State{Address: from})
|
|
||||||
mock.setAccountState(toAcct, account.State{Address: to})
|
|
||||||
mock.setPaychState(ch, nil, paych.State{
|
|
||||||
From: fromAcct,
|
|
||||||
To: toAcct,
|
|
||||||
ToSend: big.NewInt(0),
|
|
||||||
SettlingAt: abi.ChainEpoch(0),
|
|
||||||
MinSettleHeight: abi.ChainEpoch(0),
|
|
||||||
LaneStates: arr,
|
|
||||||
})
|
|
||||||
|
|
||||||
mgr, err := newManager(store, mock)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = mgr.TrackOutboundChannel(ctx, ch)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
ci, err := mgr.GetChannelInfo(ch)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, *ci.Channel, ch)
|
|
||||||
require.Equal(t, ci.Control, from)
|
|
||||||
require.Equal(t, ci.Target, to)
|
|
||||||
require.EqualValues(t, ci.Direction, DirOutbound)
|
|
||||||
require.EqualValues(t, ci.NextLane, 0)
|
|
||||||
require.Len(t, ci.Vouchers, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPaychInbound(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
|
||||||
|
|
||||||
ch := tutils.NewIDAddr(t, 100)
|
|
||||||
from := tutils.NewIDAddr(t, 101)
|
|
||||||
to := tutils.NewIDAddr(t, 102)
|
|
||||||
fromAcct := tutils.NewIDAddr(t, 201)
|
|
||||||
toAcct := tutils.NewIDAddr(t, 202)
|
|
||||||
|
|
||||||
mock := newMockManagerAPI()
|
|
||||||
arr, err := adt.MakeEmptyArray(mock.store).Root()
|
|
||||||
require.NoError(t, err)
|
|
||||||
mock.setAccountState(fromAcct, account.State{Address: from})
|
|
||||||
mock.setAccountState(toAcct, account.State{Address: to})
|
|
||||||
mock.setPaychState(ch, nil, paych.State{
|
|
||||||
From: fromAcct,
|
|
||||||
To: toAcct,
|
|
||||||
ToSend: big.NewInt(0),
|
|
||||||
SettlingAt: abi.ChainEpoch(0),
|
|
||||||
MinSettleHeight: abi.ChainEpoch(0),
|
|
||||||
LaneStates: arr,
|
|
||||||
})
|
|
||||||
|
|
||||||
mgr, err := newManager(store, mock)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = mgr.TrackInboundChannel(ctx, ch)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
ci, err := mgr.GetChannelInfo(ch)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, *ci.Channel, ch)
|
|
||||||
require.Equal(t, ci.Control, to)
|
|
||||||
require.Equal(t, ci.Target, from)
|
|
||||||
require.EqualValues(t, ci.Direction, DirInbound)
|
|
||||||
require.EqualValues(t, ci.NextLane, 0)
|
|
||||||
require.Len(t, ci.Vouchers, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckVoucherValid(t *testing.T) {
|
func TestCheckVoucherValid(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
fromKeyPrivate, fromKeyPublic := testGenerateKeyPair(t)
|
fromKeyPrivate, fromKeyPublic := testGenerateKeyPair(t)
|
||||||
|
toKeyPrivate, toKeyPublic := testGenerateKeyPair(t)
|
||||||
randKeyPrivate, _ := testGenerateKeyPair(t)
|
randKeyPrivate, _ := testGenerateKeyPair(t)
|
||||||
|
|
||||||
ch := tutils.NewIDAddr(t, 100)
|
ch := tutils.NewIDAddr(t, 100)
|
||||||
from := tutils.NewSECP256K1Addr(t, string(fromKeyPublic))
|
from := tutils.NewSECP256K1Addr(t, string(fromKeyPublic))
|
||||||
to := tutils.NewSECP256K1Addr(t, "secpTo")
|
to := tutils.NewSECP256K1Addr(t, string(toKeyPublic))
|
||||||
fromAcct := tutils.NewActorAddr(t, "fromAct")
|
fromAcct := tutils.NewActorAddr(t, "fromAct")
|
||||||
toAcct := tutils.NewActorAddr(t, "toAct")
|
toAcct := tutils.NewActorAddr(t, "toAct")
|
||||||
|
|
||||||
@ -155,6 +76,13 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
actorBalance: big.NewInt(10),
|
actorBalance: big.NewInt(10),
|
||||||
toSend: big.NewInt(0),
|
toSend: big.NewInt(0),
|
||||||
voucherAmount: big.NewInt(5),
|
voucherAmount: big.NewInt(5),
|
||||||
|
}, {
|
||||||
|
name: "fails when signed by channel To account (instead of From account)",
|
||||||
|
expectError: true,
|
||||||
|
key: toKeyPrivate,
|
||||||
|
actorBalance: big.NewInt(10),
|
||||||
|
toSend: big.NewInt(0),
|
||||||
|
voucherAmount: big.NewInt(5),
|
||||||
}, {
|
}, {
|
||||||
name: "fails when nonce too low",
|
name: "fails when nonce too low",
|
||||||
expectError: true,
|
expectError: true,
|
||||||
@ -269,6 +197,7 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
t.Run(tcase.name, func(t *testing.T) {
|
t.Run(tcase.name, func(t *testing.T) {
|
||||||
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
||||||
|
|
||||||
|
// Create an actor for the channel with the test case balance
|
||||||
act := &types.Actor{
|
act := &types.Actor{
|
||||||
Code: builtin.AccountActorCodeID,
|
Code: builtin.AccountActorCodeID,
|
||||||
Head: cid.Cid{},
|
Head: cid.Cid{},
|
||||||
@ -276,6 +205,7 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
Balance: tcase.actorBalance,
|
Balance: tcase.actorBalance,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the state of the channel's lanes
|
||||||
laneStates, err := mock.storeLaneStates(tcase.laneStates)
|
laneStates, err := mock.storeLaneStates(tcase.laneStates)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -288,14 +218,24 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
LaneStates: laneStates,
|
LaneStates: laneStates,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Create a manager
|
||||||
mgr, err := newManager(store, mock)
|
mgr, err := newManager(store, mock)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = mgr.TrackInboundChannel(ctx, ch)
|
// Create the channel in the manager's store
|
||||||
|
ci := &ChannelInfo{
|
||||||
|
Channel: &ch,
|
||||||
|
Control: toAcct,
|
||||||
|
Target: fromAcct,
|
||||||
|
Direction: DirInbound,
|
||||||
|
}
|
||||||
|
err = mgr.store.putChannelInfo(ci)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
sv := testCreateVoucher(t, ch, tcase.voucherLane, tcase.voucherNonce, tcase.voucherAmount, tcase.key)
|
// Create a signed voucher
|
||||||
|
sv := createTestVoucher(t, ch, tcase.voucherLane, tcase.voucherNonce, tcase.voucherAmount, tcase.key)
|
||||||
|
|
||||||
|
// Check the voucher's validity
|
||||||
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
||||||
if tcase.expectError {
|
if tcase.expectError {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
@ -358,7 +298,14 @@ func TestCheckVoucherValidCountingAllLanes(t *testing.T) {
|
|||||||
mgr, err := newManager(store, mock)
|
mgr, err := newManager(store, mock)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = mgr.TrackInboundChannel(ctx, ch)
|
// Create the channel in the manager's store
|
||||||
|
ci := &ChannelInfo{
|
||||||
|
Channel: &ch,
|
||||||
|
Control: toAcct,
|
||||||
|
Target: fromAcct,
|
||||||
|
Direction: DirInbound,
|
||||||
|
}
|
||||||
|
err = mgr.store.putChannelInfo(ci)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -380,7 +327,7 @@ func TestCheckVoucherValidCountingAllLanes(t *testing.T) {
|
|||||||
voucherLane := uint64(1)
|
voucherLane := uint64(1)
|
||||||
voucherNonce := uint64(2)
|
voucherNonce := uint64(2)
|
||||||
voucherAmount := big.NewInt(6)
|
voucherAmount := big.NewInt(6)
|
||||||
sv := testCreateVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate)
|
sv := createTestVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate)
|
||||||
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
@ -398,13 +345,13 @@ func TestCheckVoucherValidCountingAllLanes(t *testing.T) {
|
|||||||
// actor balance is 10 so total is ok.
|
// actor balance is 10 so total is ok.
|
||||||
//
|
//
|
||||||
voucherAmount = big.NewInt(4)
|
voucherAmount = big.NewInt(4)
|
||||||
sv = testCreateVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate)
|
sv = createTestVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate)
|
||||||
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Add voucher to lane 1, so Lane 1 effective redeemed
|
// Add voucher to lane 1, so Lane 1 effective redeemed
|
||||||
// (with first voucher) is now 4
|
// (with first voucher) is now 4
|
||||||
_, err = mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
_, err = mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -422,7 +369,7 @@ func TestCheckVoucherValidCountingAllLanes(t *testing.T) {
|
|||||||
//
|
//
|
||||||
voucherNonce++
|
voucherNonce++
|
||||||
voucherAmount = big.NewInt(6)
|
voucherAmount = big.NewInt(6)
|
||||||
sv = testCreateVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate)
|
sv = createTestVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate)
|
||||||
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
@ -440,7 +387,7 @@ func TestCheckVoucherValidCountingAllLanes(t *testing.T) {
|
|||||||
// actor balance is 10 so total is ok.
|
// actor balance is 10 so total is ok.
|
||||||
//
|
//
|
||||||
voucherAmount = big.NewInt(5)
|
voucherAmount = big.NewInt(5)
|
||||||
sv = testCreateVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate)
|
sv = createTestVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate)
|
||||||
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
err = mgr.CheckVoucherValid(ctx, ch, sv)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -457,23 +404,23 @@ func TestAddVoucherDelta(t *testing.T) {
|
|||||||
minDelta := big.NewInt(2)
|
minDelta := big.NewInt(2)
|
||||||
nonce := uint64(1)
|
nonce := uint64(1)
|
||||||
voucherAmount := big.NewInt(1)
|
voucherAmount := big.NewInt(1)
|
||||||
sv := testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
sv := createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
_, err := mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
_, err := mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// Expect success when adding a voucher whose amount is equal to minDelta
|
// Expect success when adding a voucher whose amount is equal to minDelta
|
||||||
nonce++
|
nonce++
|
||||||
voucherAmount = big.NewInt(2)
|
voucherAmount = big.NewInt(2)
|
||||||
sv = testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
sv = createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
delta, err := mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
delta, err := mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, delta.Int64(), 2)
|
require.EqualValues(t, delta.Int64(), 2)
|
||||||
|
|
||||||
// Check that delta is correct when there's an existing voucher
|
// Check that delta is correct when there's an existing voucher
|
||||||
nonce++
|
nonce++
|
||||||
voucherAmount = big.NewInt(5)
|
voucherAmount = big.NewInt(5)
|
||||||
sv = testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
sv = createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
delta, err = mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
delta, err = mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, delta.Int64(), 3)
|
require.EqualValues(t, delta.Int64(), 3)
|
||||||
|
|
||||||
@ -481,8 +428,8 @@ func TestAddVoucherDelta(t *testing.T) {
|
|||||||
nonce = uint64(1)
|
nonce = uint64(1)
|
||||||
voucherAmount = big.NewInt(6)
|
voucherAmount = big.NewInt(6)
|
||||||
voucherLane = uint64(2)
|
voucherLane = uint64(2)
|
||||||
sv = testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
sv = createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
delta, err = mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
delta, err = mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, delta.Int64(), 6)
|
require.EqualValues(t, delta.Int64(), 6)
|
||||||
}
|
}
|
||||||
@ -499,8 +446,8 @@ func TestAddVoucherNextLane(t *testing.T) {
|
|||||||
// Add a voucher in lane 2
|
// Add a voucher in lane 2
|
||||||
nonce := uint64(1)
|
nonce := uint64(1)
|
||||||
voucherLane := uint64(2)
|
voucherLane := uint64(2)
|
||||||
sv := testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
sv := createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
_, err := mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
_, err := mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ci, err := mgr.GetChannelInfo(ch)
|
ci, err := mgr.GetChannelInfo(ch)
|
||||||
@ -518,8 +465,8 @@ func TestAddVoucherNextLane(t *testing.T) {
|
|||||||
|
|
||||||
// Add a voucher in lane 1
|
// Add a voucher in lane 1
|
||||||
voucherLane = uint64(1)
|
voucherLane = uint64(1)
|
||||||
sv = testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
sv = createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
_, err = mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
_, err = mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ci, err = mgr.GetChannelInfo(ch)
|
ci, err = mgr.GetChannelInfo(ch)
|
||||||
@ -528,8 +475,8 @@ func TestAddVoucherNextLane(t *testing.T) {
|
|||||||
|
|
||||||
// Add a voucher in lane 7
|
// Add a voucher in lane 7
|
||||||
voucherLane = uint64(7)
|
voucherLane = uint64(7)
|
||||||
sv = testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
sv = createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
_, err = mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
_, err = mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ci, err = mgr.GetChannelInfo(ch)
|
ci, err = mgr.GetChannelInfo(ch)
|
||||||
@ -557,7 +504,7 @@ func TestAllocateLane(t *testing.T) {
|
|||||||
func TestAllocateLaneWithExistingLaneState(t *testing.T) {
|
func TestAllocateLaneWithExistingLaneState(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
_, fromKeyPublic := testGenerateKeyPair(t)
|
fromKeyPrivate, fromKeyPublic := testGenerateKeyPair(t)
|
||||||
|
|
||||||
ch := tutils.NewIDAddr(t, 100)
|
ch := tutils.NewIDAddr(t, 100)
|
||||||
from := tutils.NewSECP256K1Addr(t, string(fromKeyPublic))
|
from := tutils.NewSECP256K1Addr(t, string(fromKeyPublic))
|
||||||
@ -568,17 +515,13 @@ func TestAllocateLaneWithExistingLaneState(t *testing.T) {
|
|||||||
mock := newMockManagerAPI()
|
mock := newMockManagerAPI()
|
||||||
mock.setAccountState(fromAcct, account.State{Address: from})
|
mock.setAccountState(fromAcct, account.State{Address: from})
|
||||||
mock.setAccountState(toAcct, account.State{Address: to})
|
mock.setAccountState(toAcct, account.State{Address: to})
|
||||||
|
mock.addWalletAddress(to)
|
||||||
|
|
||||||
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
||||||
|
|
||||||
|
// Create a channel that will be retrieved from state
|
||||||
actorBalance := big.NewInt(10)
|
actorBalance := big.NewInt(10)
|
||||||
toSend := big.NewInt(1)
|
toSend := big.NewInt(1)
|
||||||
laneStates := map[uint64]paych.LaneState{
|
|
||||||
2: {
|
|
||||||
Nonce: 1,
|
|
||||||
Redeemed: big.NewInt(4),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
act := &types.Actor{
|
act := &types.Actor{
|
||||||
Code: builtin.AccountActorCodeID,
|
Code: builtin.AccountActorCodeID,
|
||||||
@ -587,7 +530,7 @@ func TestAllocateLaneWithExistingLaneState(t *testing.T) {
|
|||||||
Balance: actorBalance,
|
Balance: actorBalance,
|
||||||
}
|
}
|
||||||
|
|
||||||
lsCid, err := mock.storeLaneStates(laneStates)
|
arr, err := adt.MakeEmptyArray(mock.store).Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
mock.setPaychState(ch, act, paych.State{
|
mock.setPaychState(ch, act, paych.State{
|
||||||
From: fromAcct,
|
From: fromAcct,
|
||||||
@ -595,15 +538,23 @@ func TestAllocateLaneWithExistingLaneState(t *testing.T) {
|
|||||||
ToSend: toSend,
|
ToSend: toSend,
|
||||||
SettlingAt: abi.ChainEpoch(0),
|
SettlingAt: abi.ChainEpoch(0),
|
||||||
MinSettleHeight: abi.ChainEpoch(0),
|
MinSettleHeight: abi.ChainEpoch(0),
|
||||||
LaneStates: lsCid,
|
LaneStates: arr,
|
||||||
})
|
})
|
||||||
|
|
||||||
mgr, err := newManager(store, mock)
|
mgr, err := newManager(store, mock)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = mgr.TrackInboundChannel(ctx, ch)
|
// Create a voucher on lane 2
|
||||||
|
// (also reads the channel from state and puts it in the store)
|
||||||
|
voucherLane := uint64(2)
|
||||||
|
minDelta := big.NewInt(0)
|
||||||
|
nonce := uint64(2)
|
||||||
|
voucherAmount := big.NewInt(5)
|
||||||
|
sv := createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
|
_, err = mgr.AddVoucherInbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Allocate lane should return the next lane (lane 3)
|
||||||
lane, err := mgr.AllocateLane(ch)
|
lane, err := mgr.AllocateLane(ch)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, 3, lane)
|
require.EqualValues(t, 3, lane)
|
||||||
@ -623,8 +574,8 @@ func TestAddVoucherProof(t *testing.T) {
|
|||||||
|
|
||||||
// Add a voucher with no proof
|
// Add a voucher with no proof
|
||||||
var proof []byte
|
var proof []byte
|
||||||
sv := testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
sv := createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
_, err := mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
_, err := mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Expect one voucher with no proof
|
// Expect one voucher with no proof
|
||||||
@ -635,7 +586,7 @@ func TestAddVoucherProof(t *testing.T) {
|
|||||||
|
|
||||||
// Add same voucher with no proof
|
// Add same voucher with no proof
|
||||||
voucherLane = uint64(1)
|
voucherLane = uint64(1)
|
||||||
_, err = mgr.AddVoucher(ctx, ch, sv, proof, minDelta)
|
_, err = mgr.AddVoucherOutbound(ctx, ch, sv, proof, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Expect one voucher with no proof
|
// Expect one voucher with no proof
|
||||||
@ -646,7 +597,7 @@ func TestAddVoucherProof(t *testing.T) {
|
|||||||
|
|
||||||
// Add same voucher with proof
|
// Add same voucher with proof
|
||||||
proof = []byte{1}
|
proof = []byte{1}
|
||||||
_, err = mgr.AddVoucher(ctx, ch, sv, proof, minDelta)
|
_, err = mgr.AddVoucherOutbound(ctx, ch, sv, proof, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Should add proof to existing voucher
|
// Should add proof to existing voucher
|
||||||
@ -656,6 +607,69 @@ func TestAddVoucherProof(t *testing.T) {
|
|||||||
require.Len(t, ci.Vouchers[0].Proof, 1)
|
require.Len(t, ci.Vouchers[0].Proof, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddVoucherInboundWalletKey(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
fromKeyPrivate, fromKeyPublic := testGenerateKeyPair(t)
|
||||||
|
|
||||||
|
ch := tutils.NewIDAddr(t, 100)
|
||||||
|
from := tutils.NewSECP256K1Addr(t, string(fromKeyPublic))
|
||||||
|
to := tutils.NewSECP256K1Addr(t, "secpTo")
|
||||||
|
fromAcct := tutils.NewActorAddr(t, "fromAct")
|
||||||
|
toAcct := tutils.NewActorAddr(t, "toAct")
|
||||||
|
|
||||||
|
// Create an actor for the channel in state
|
||||||
|
act := &types.Actor{
|
||||||
|
Code: builtin.AccountActorCodeID,
|
||||||
|
Head: cid.Cid{},
|
||||||
|
Nonce: 0,
|
||||||
|
Balance: types.NewInt(20),
|
||||||
|
}
|
||||||
|
|
||||||
|
mock := newMockManagerAPI()
|
||||||
|
arr, err := adt.MakeEmptyArray(mock.store).Root()
|
||||||
|
require.NoError(t, err)
|
||||||
|
mock.setAccountState(fromAcct, account.State{Address: from})
|
||||||
|
mock.setAccountState(toAcct, account.State{Address: to})
|
||||||
|
|
||||||
|
mock.setPaychState(ch, act, paych.State{
|
||||||
|
From: fromAcct,
|
||||||
|
To: toAcct,
|
||||||
|
ToSend: types.NewInt(0),
|
||||||
|
SettlingAt: abi.ChainEpoch(0),
|
||||||
|
MinSettleHeight: abi.ChainEpoch(0),
|
||||||
|
LaneStates: arr,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create a manager
|
||||||
|
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
||||||
|
mgr, err := newManager(store, mock)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Add a voucher
|
||||||
|
nonce := uint64(1)
|
||||||
|
voucherLane := uint64(1)
|
||||||
|
minDelta := big.NewInt(0)
|
||||||
|
voucherAmount := big.NewInt(2)
|
||||||
|
sv := createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
|
_, err = mgr.AddVoucherInbound(ctx, ch, sv, nil, minDelta)
|
||||||
|
|
||||||
|
// Should fail because there is no wallet key matching the channel To
|
||||||
|
// address (ie, the channel is not "owned" by this node)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
// Add wallet key for To address
|
||||||
|
mock.addWalletAddress(to)
|
||||||
|
|
||||||
|
// Add voucher again
|
||||||
|
sv = createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, fromKeyPrivate)
|
||||||
|
_, err = mgr.AddVoucherInbound(ctx, ch, sv, nil, minDelta)
|
||||||
|
|
||||||
|
// Should now pass because there is a wallet key matching the channel To
|
||||||
|
// address
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestNextNonceForLane(t *testing.T) {
|
func TestNextNonceForLane(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
@ -674,19 +688,19 @@ func TestNextNonceForLane(t *testing.T) {
|
|||||||
// Add vouchers such that we have
|
// Add vouchers such that we have
|
||||||
// lane 1: nonce 2
|
// lane 1: nonce 2
|
||||||
// lane 1: nonce 4
|
// lane 1: nonce 4
|
||||||
// lane 2: nonce 7
|
|
||||||
voucherLane := uint64(1)
|
voucherLane := uint64(1)
|
||||||
for _, nonce := range []uint64{2, 4} {
|
for _, nonce := range []uint64{2, 4} {
|
||||||
voucherAmount = big.Add(voucherAmount, big.NewInt(1))
|
voucherAmount = big.Add(voucherAmount, big.NewInt(1))
|
||||||
sv := testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, key)
|
sv := createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, key)
|
||||||
_, err := mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
_, err := mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lane 2: nonce 7
|
||||||
voucherLane = uint64(2)
|
voucherLane = uint64(2)
|
||||||
nonce := uint64(7)
|
nonce := uint64(7)
|
||||||
sv := testCreateVoucher(t, ch, voucherLane, nonce, voucherAmount, key)
|
sv := createTestVoucher(t, ch, voucherLane, nonce, voucherAmount, key)
|
||||||
_, err = mgr.AddVoucher(ctx, ch, sv, nil, minDelta)
|
_, err = mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Expect next nonce for lane 1 to be 5
|
// Expect next nonce for lane 1 to be 5
|
||||||
@ -715,6 +729,7 @@ func testSetupMgrWithChannel(ctx context.Context, t *testing.T) (*Manager, addre
|
|||||||
mock.setAccountState(fromAcct, account.State{Address: from})
|
mock.setAccountState(fromAcct, account.State{Address: from})
|
||||||
mock.setAccountState(toAcct, account.State{Address: to})
|
mock.setAccountState(toAcct, account.State{Address: to})
|
||||||
|
|
||||||
|
// Create channel in state
|
||||||
act := &types.Actor{
|
act := &types.Actor{
|
||||||
Code: builtin.AccountActorCodeID,
|
Code: builtin.AccountActorCodeID,
|
||||||
Head: cid.Cid{},
|
Head: cid.Cid{},
|
||||||
@ -734,8 +749,16 @@ func testSetupMgrWithChannel(ctx context.Context, t *testing.T) (*Manager, addre
|
|||||||
mgr, err := newManager(store, mock)
|
mgr, err := newManager(store, mock)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = mgr.TrackInboundChannel(ctx, ch)
|
// Create the channel in the manager's store
|
||||||
|
ci := &ChannelInfo{
|
||||||
|
Channel: &ch,
|
||||||
|
Control: fromAcct,
|
||||||
|
Target: toAcct,
|
||||||
|
Direction: DirOutbound,
|
||||||
|
}
|
||||||
|
err = mgr.store.putChannelInfo(ci)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return mgr, ch, fromKeyPrivate
|
return mgr, ch, fromKeyPrivate
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,7 +770,7 @@ func testGenerateKeyPair(t *testing.T) ([]byte, []byte) {
|
|||||||
return priv, pub
|
return priv, pub
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateVoucher(t *testing.T, ch address.Address, voucherLane uint64, nonce uint64, voucherAmount big.Int, key []byte) *paych.SignedVoucher {
|
func createTestVoucher(t *testing.T, ch address.Address, voucherLane uint64, nonce uint64, voucherAmount big.Int, key []byte) *paych.SignedVoucher {
|
||||||
sv := &paych.SignedVoucher{
|
sv := &paych.SignedVoucher{
|
||||||
ChannelAddr: ch,
|
ChannelAddr: ch,
|
||||||
Lane: voucherLane,
|
Lane: voucherLane,
|
||||||
|
@ -17,7 +17,7 @@ type stateAccessor struct {
|
|||||||
sm stateManagerAPI
|
sm stateManagerAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ca *stateAccessor) loadPaychState(ctx context.Context, ch address.Address) (*types.Actor, *paych.State, error) {
|
func (ca *stateAccessor) loadPaychActorState(ctx context.Context, ch address.Address) (*types.Actor, *paych.State, error) {
|
||||||
var pcast paych.State
|
var pcast paych.State
|
||||||
act, err := ca.sm.LoadActorState(ctx, ch, &pcast, nil)
|
act, err := ca.sm.LoadActorState(ctx, ch, &pcast, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -28,7 +28,7 @@ func (ca *stateAccessor) loadPaychState(ctx context.Context, ch address.Address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ca *stateAccessor) loadStateChannelInfo(ctx context.Context, ch address.Address, dir uint64) (*ChannelInfo, error) {
|
func (ca *stateAccessor) loadStateChannelInfo(ctx context.Context, ch address.Address, dir uint64) (*ChannelInfo, error) {
|
||||||
_, st, err := ca.loadPaychState(ctx, ch)
|
_, st, err := ca.loadPaychActorState(ctx, ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -84,15 +84,20 @@ type ChannelInfo struct {
|
|||||||
|
|
||||||
// TrackChannel stores a channel, returning an error if the channel was already
|
// TrackChannel stores a channel, returning an error if the channel was already
|
||||||
// being tracked
|
// being tracked
|
||||||
func (ps *Store) TrackChannel(ci *ChannelInfo) error {
|
func (ps *Store) TrackChannel(ci *ChannelInfo) (*ChannelInfo, error) {
|
||||||
_, err := ps.ByAddress(*ci.Channel)
|
_, err := ps.ByAddress(*ci.Channel)
|
||||||
switch err {
|
switch err {
|
||||||
default:
|
default:
|
||||||
return err
|
return nil, err
|
||||||
case nil:
|
case nil:
|
||||||
return fmt.Errorf("already tracking channel: %s", ci.Channel)
|
return nil, fmt.Errorf("already tracking channel: %s", ci.Channel)
|
||||||
case ErrChannelNotTracked:
|
case ErrChannelNotTracked:
|
||||||
return ps.putChannelInfo(ci)
|
err = ps.putChannelInfo(ci)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ps.ByAddress(*ci.Channel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,15 +38,15 @@ func TestStore(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Track the channel
|
// Track the channel
|
||||||
err = store.TrackChannel(ci)
|
_, err = store.TrackChannel(ci)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Tracking same channel again should error
|
// Tracking same channel again should error
|
||||||
err = store.TrackChannel(ci)
|
_, err = store.TrackChannel(ci)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// Track another channel
|
// Track another channel
|
||||||
err = store.TrackChannel(ci2)
|
_, err = store.TrackChannel(ci2)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// List channels should include all channels
|
// List channels should include all channels
|
||||||
|
Loading…
Reference in New Issue
Block a user