Fix payment channel for actor changes
Also, allocate the next available lane, instead of max+1. That way, we fill holes. Finally, check some error cases.
This commit is contained in:
parent
335d165db6
commit
cac3d07abb
@ -66,10 +66,11 @@ func (sm *mockStateManager) setPaychState(a address.Address, actor *types.Actor,
|
|||||||
sm.paychState[a] = mockPchState{actor, state}
|
sm.paychState[a] = mockPchState{actor, state}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *mockStateManager) storeLaneStates(laneStates []*paych.LaneState) (cid.Cid, error) {
|
func (sm *mockStateManager) storeLaneStates(laneStates map[uint64]paych.LaneState) (cid.Cid, error) {
|
||||||
arr := adt.MakeEmptyArray(sm.store)
|
arr := adt.MakeEmptyArray(sm.store)
|
||||||
for _, ls := range laneStates {
|
for i, ls := range laneStates {
|
||||||
if err := arr.Set(ls.ID, ls); err != nil {
|
ls := ls
|
||||||
|
if err := arr.Set(i, &ls); err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,11 +331,14 @@ func (ca *channelAccessor) laneState(ctx context.Context, state *paych.State, ch
|
|||||||
// very large index.
|
// very large index.
|
||||||
var ls paych.LaneState
|
var ls paych.LaneState
|
||||||
laneStates := make(map[uint64]*paych.LaneState, lsamt.Length())
|
laneStates := make(map[uint64]*paych.LaneState, lsamt.Length())
|
||||||
lsamt.ForEach(&ls, func(i int64) error {
|
err = lsamt.ForEach(&ls, func(i int64) error {
|
||||||
current := ls
|
current := ls
|
||||||
laneStates[ls.ID] = ¤t
|
laneStates[uint64(i)] = ¤t
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Apply locally stored vouchers
|
// Apply locally stored vouchers
|
||||||
vouchers, err := ca.store.VouchersForPaych(ch)
|
vouchers, err := ca.store.VouchersForPaych(ch)
|
||||||
@ -353,7 +356,6 @@ func (ca *channelAccessor) laneState(ctx context.Context, state *paych.State, ch
|
|||||||
ls, ok := laneStates[v.Voucher.Lane]
|
ls, ok := laneStates[v.Voucher.Lane]
|
||||||
if !ok {
|
if !ok {
|
||||||
ls = &paych.LaneState{
|
ls = &paych.LaneState{
|
||||||
ID: v.Voucher.Lane,
|
|
||||||
Redeemed: types.NewInt(0),
|
Redeemed: types.NewInt(0),
|
||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/lib/sigs"
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
@ -39,6 +40,8 @@ func TestPaychOutbound(t *testing.T) {
|
|||||||
toAcct := tutils.NewIDAddr(t, 202)
|
toAcct := tutils.NewIDAddr(t, 202)
|
||||||
|
|
||||||
mock := newMockManagerAPI()
|
mock := newMockManagerAPI()
|
||||||
|
arr, err := adt.MakeEmptyArray(mock.store).Root()
|
||||||
|
require.NoError(t, err)
|
||||||
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.setPaychState(ch, nil, paych.State{
|
mock.setPaychState(ch, nil, paych.State{
|
||||||
@ -47,6 +50,7 @@ func TestPaychOutbound(t *testing.T) {
|
|||||||
ToSend: big.NewInt(0),
|
ToSend: big.NewInt(0),
|
||||||
SettlingAt: abi.ChainEpoch(0),
|
SettlingAt: abi.ChainEpoch(0),
|
||||||
MinSettleHeight: abi.ChainEpoch(0),
|
MinSettleHeight: abi.ChainEpoch(0),
|
||||||
|
LaneStates: arr,
|
||||||
})
|
})
|
||||||
|
|
||||||
mgr, err := newManager(store, mock)
|
mgr, err := newManager(store, mock)
|
||||||
@ -76,6 +80,8 @@ func TestPaychInbound(t *testing.T) {
|
|||||||
toAcct := tutils.NewIDAddr(t, 202)
|
toAcct := tutils.NewIDAddr(t, 202)
|
||||||
|
|
||||||
mock := newMockManagerAPI()
|
mock := newMockManagerAPI()
|
||||||
|
arr, err := adt.MakeEmptyArray(mock.store).Root()
|
||||||
|
require.NoError(t, err)
|
||||||
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.setPaychState(ch, nil, paych.State{
|
mock.setPaychState(ch, nil, paych.State{
|
||||||
@ -84,6 +90,7 @@ func TestPaychInbound(t *testing.T) {
|
|||||||
ToSend: big.NewInt(0),
|
ToSend: big.NewInt(0),
|
||||||
SettlingAt: abi.ChainEpoch(0),
|
SettlingAt: abi.ChainEpoch(0),
|
||||||
MinSettleHeight: abi.ChainEpoch(0),
|
MinSettleHeight: abi.ChainEpoch(0),
|
||||||
|
LaneStates: arr,
|
||||||
})
|
})
|
||||||
|
|
||||||
mgr, err := newManager(store, mock)
|
mgr, err := newManager(store, mock)
|
||||||
@ -127,7 +134,7 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
voucherAmount big.Int
|
voucherAmount big.Int
|
||||||
voucherLane uint64
|
voucherLane uint64
|
||||||
voucherNonce uint64
|
voucherNonce uint64
|
||||||
laneStates []*paych.LaneState
|
laneStates map[uint64]paych.LaneState
|
||||||
}{{
|
}{{
|
||||||
name: "passes when voucher amount < balance",
|
name: "passes when voucher amount < balance",
|
||||||
key: fromKeyPrivate,
|
key: fromKeyPrivate,
|
||||||
@ -157,11 +164,12 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
voucherAmount: big.NewInt(5),
|
voucherAmount: big.NewInt(5),
|
||||||
voucherLane: 1,
|
voucherLane: 1,
|
||||||
voucherNonce: 2,
|
voucherNonce: 2,
|
||||||
laneStates: []*paych.LaneState{{
|
laneStates: map[uint64]paych.LaneState{
|
||||||
ID: 1,
|
1: {
|
||||||
Redeemed: big.NewInt(2),
|
Redeemed: big.NewInt(2),
|
||||||
Nonce: 3,
|
Nonce: 3,
|
||||||
}},
|
},
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
name: "passes when nonce higher",
|
name: "passes when nonce higher",
|
||||||
key: fromKeyPrivate,
|
key: fromKeyPrivate,
|
||||||
@ -170,11 +178,12 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
voucherAmount: big.NewInt(5),
|
voucherAmount: big.NewInt(5),
|
||||||
voucherLane: 1,
|
voucherLane: 1,
|
||||||
voucherNonce: 3,
|
voucherNonce: 3,
|
||||||
laneStates: []*paych.LaneState{{
|
laneStates: map[uint64]paych.LaneState{
|
||||||
ID: 1,
|
1: {
|
||||||
Redeemed: big.NewInt(2),
|
Redeemed: big.NewInt(2),
|
||||||
Nonce: 2,
|
Nonce: 2,
|
||||||
}},
|
},
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
name: "passes when nonce for different lane",
|
name: "passes when nonce for different lane",
|
||||||
key: fromKeyPrivate,
|
key: fromKeyPrivate,
|
||||||
@ -183,11 +192,12 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
voucherAmount: big.NewInt(5),
|
voucherAmount: big.NewInt(5),
|
||||||
voucherLane: 2,
|
voucherLane: 2,
|
||||||
voucherNonce: 2,
|
voucherNonce: 2,
|
||||||
laneStates: []*paych.LaneState{{
|
laneStates: map[uint64]paych.LaneState{
|
||||||
ID: 1,
|
1: {
|
||||||
Redeemed: big.NewInt(2),
|
Redeemed: big.NewInt(2),
|
||||||
Nonce: 3,
|
Nonce: 3,
|
||||||
}},
|
},
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
name: "fails when voucher has higher nonce but lower value than lane state",
|
name: "fails when voucher has higher nonce but lower value than lane state",
|
||||||
expectError: true,
|
expectError: true,
|
||||||
@ -197,11 +207,12 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
voucherAmount: big.NewInt(5),
|
voucherAmount: big.NewInt(5),
|
||||||
voucherLane: 1,
|
voucherLane: 1,
|
||||||
voucherNonce: 3,
|
voucherNonce: 3,
|
||||||
laneStates: []*paych.LaneState{{
|
laneStates: map[uint64]paych.LaneState{
|
||||||
ID: 1,
|
1: {
|
||||||
Redeemed: big.NewInt(6),
|
Redeemed: big.NewInt(6),
|
||||||
Nonce: 2,
|
Nonce: 2,
|
||||||
}},
|
},
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
name: "fails when voucher + ToSend > balance",
|
name: "fails when voucher + ToSend > balance",
|
||||||
expectError: true,
|
expectError: true,
|
||||||
@ -224,11 +235,13 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
voucherAmount: big.NewInt(6),
|
voucherAmount: big.NewInt(6),
|
||||||
voucherLane: 1,
|
voucherLane: 1,
|
||||||
voucherNonce: 2,
|
voucherNonce: 2,
|
||||||
laneStates: []*paych.LaneState{{
|
laneStates: map[uint64]paych.LaneState{
|
||||||
ID: 1, // Lane 1 (same as voucher lane 1)
|
// Lane 1 (same as voucher lane 1)
|
||||||
Redeemed: big.NewInt(4),
|
1: {
|
||||||
Nonce: 1,
|
Redeemed: big.NewInt(4),
|
||||||
}},
|
Nonce: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
// required balance = toSend + total redeemed
|
// required balance = toSend + total redeemed
|
||||||
// = 1 + 4 (lane 2) + 6 (voucher lane 1)
|
// = 1 + 4 (lane 2) + 6 (voucher lane 1)
|
||||||
@ -242,11 +255,13 @@ func TestCheckVoucherValid(t *testing.T) {
|
|||||||
voucherAmount: big.NewInt(6),
|
voucherAmount: big.NewInt(6),
|
||||||
voucherLane: 1,
|
voucherLane: 1,
|
||||||
voucherNonce: 1,
|
voucherNonce: 1,
|
||||||
laneStates: []*paych.LaneState{{
|
laneStates: map[uint64]paych.LaneState{
|
||||||
ID: 2, // Lane 2 (different from voucher lane 1)
|
// Lane 2 (different from voucher lane 1)
|
||||||
Redeemed: big.NewInt(4),
|
2: {
|
||||||
Nonce: 1,
|
Redeemed: big.NewInt(4),
|
||||||
}},
|
Nonce: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for _, tcase := range tcases {
|
for _, tcase := range tcases {
|
||||||
@ -311,15 +326,16 @@ func TestCheckVoucherValidCountingAllLanes(t *testing.T) {
|
|||||||
|
|
||||||
actorBalance := big.NewInt(10)
|
actorBalance := big.NewInt(10)
|
||||||
toSend := big.NewInt(1)
|
toSend := big.NewInt(1)
|
||||||
laneStates := []*paych.LaneState{{
|
laneStates := map[uint64]paych.LaneState{
|
||||||
ID: 1,
|
1: {
|
||||||
Nonce: 1,
|
Nonce: 1,
|
||||||
Redeemed: big.NewInt(3),
|
Redeemed: big.NewInt(3),
|
||||||
}, {
|
},
|
||||||
ID: 2,
|
2: {
|
||||||
Nonce: 1,
|
Nonce: 1,
|
||||||
Redeemed: big.NewInt(4),
|
Redeemed: big.NewInt(4),
|
||||||
}}
|
},
|
||||||
|
}
|
||||||
|
|
||||||
act := &types.Actor{
|
act := &types.Actor{
|
||||||
Code: builtin.AccountActorCodeID,
|
Code: builtin.AccountActorCodeID,
|
||||||
@ -630,6 +646,8 @@ func testSetupMgrWithChannel(ctx context.Context, t *testing.T) (*Manager, addre
|
|||||||
toAcct := tutils.NewActorAddr(t, "toAct")
|
toAcct := tutils.NewActorAddr(t, "toAct")
|
||||||
|
|
||||||
mock := newMockManagerAPI()
|
mock := newMockManagerAPI()
|
||||||
|
arr, err := adt.MakeEmptyArray(mock.store).Root()
|
||||||
|
require.NoError(t, err)
|
||||||
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})
|
||||||
|
|
||||||
@ -645,6 +663,7 @@ func testSetupMgrWithChannel(ctx context.Context, t *testing.T) (*Manager, addre
|
|||||||
ToSend: big.NewInt(0),
|
ToSend: big.NewInt(0),
|
||||||
SettlingAt: abi.ChainEpoch(0),
|
SettlingAt: abi.ChainEpoch(0),
|
||||||
MinSettleHeight: abi.ChainEpoch(0),
|
MinSettleHeight: abi.ChainEpoch(0),
|
||||||
|
LaneStates: arr,
|
||||||
})
|
})
|
||||||
|
|
||||||
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
||||||
|
@ -2,6 +2,7 @@ package paychmgr
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
@ -77,14 +78,18 @@ func (ca *stateAccessor) nextLaneFromState(ctx context.Context, st *paych.State)
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
maxLane := uint64(0)
|
nextID := int64(0)
|
||||||
var ls paych.LaneState
|
stopErr := errors.New("stop")
|
||||||
laneStates.ForEach(&ls, func(i int64) error {
|
if err := laneStates.ForEach(nil, func(i int64) error {
|
||||||
if ls.ID > maxLane {
|
if nextID < i {
|
||||||
maxLane = ls.ID
|
// We've found a hole. Stop here.
|
||||||
|
return stopErr
|
||||||
}
|
}
|
||||||
|
nextID++
|
||||||
return nil
|
return nil
|
||||||
})
|
}); err != nil && err != stopErr {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
return maxLane + 1, nil
|
return uint64(nextID), nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user