diff --git a/api/test/paych.go b/api/test/paych.go index 36eb2c256..15ce352bd 100644 --- a/api/test/paych.go +++ b/api/test/paych.go @@ -67,7 +67,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { t.Fatal(err) } - channelAmt := int64(100000) + channelAmt := int64(7000) channelInfo, err := paymentCreator.PaychGet(ctx, createrAddr, receiverAddr, abi.NewTokenAmount(channelAmt)) if err != nil { t.Fatal(err) @@ -169,6 +169,51 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { t.Fatal("Timed out waiting for receiver to submit vouchers") } + // Create a new voucher now that some vouchers have already been submitted + vouchRes, err := paymentCreator.PaychVoucherCreate(ctx, channel, abi.NewTokenAmount(1000), 3) + if err != nil { + t.Fatal(err) + } + if vouchRes.Voucher == nil { + t.Fatal(fmt.Errorf("Not enough funds to create voucher: missing %d", vouchRes.Shortfall)) + } + vdelta, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouchRes.Voucher, nil, abi.NewTokenAmount(1000)) + if err != nil { + t.Fatal(err) + } + if !vdelta.Equals(abi.NewTokenAmount(1000)) { + t.Fatal("voucher didn't have the right amount") + } + + // Create a new voucher whose value would exceed the channel balance + excessAmt := abi.NewTokenAmount(1000) + vouchRes, err = paymentCreator.PaychVoucherCreate(ctx, channel, excessAmt, 4) + if err != nil { + t.Fatal(err) + } + if vouchRes.Voucher != nil { + t.Fatal("Expected not to be able to create voucher whose value would exceed channel balance") + } + if !vouchRes.Shortfall.Equals(excessAmt) { + t.Fatal(fmt.Errorf("Expected voucher shortfall of %d, got %d", excessAmt, vouchRes.Shortfall)) + } + + // Add a voucher whose value would exceed the channel balance + vouch := &paych.SignedVoucher{ChannelAddr: channel, Amount: excessAmt, Lane: 4, Nonce: 1} + vb, err := vouch.SigningBytes() + if err != nil { + t.Fatal(err) + } + sig, err := paymentCreator.WalletSign(ctx, createrAddr, vb) + if err != nil { + t.Fatal(err) + } + vouch.Signature = sig + _, err = paymentReceiver.PaychVoucherAdd(ctx, channel, vouch, nil, abi.NewTokenAmount(1000)) + if err == nil { + t.Fatal(fmt.Errorf("Expected shortfall error of %d", excessAmt)) + } + // wait for the settlement period to pass before collecting waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, paych.SettleDelay) diff --git a/chain/actors/builtin/paych/mock/mock.go b/chain/actors/builtin/paych/mock/mock.go index c4903f3ac..3b82511ff 100644 --- a/chain/actors/builtin/paych/mock/mock.go +++ b/chain/actors/builtin/paych/mock/mock.go @@ -27,10 +27,9 @@ type mockLaneState struct { func NewMockPayChState(from address.Address, to address.Address, settlingAt abi.ChainEpoch, - toSend abi.TokenAmount, lanes map[uint64]paych.LaneState, ) paych.State { - return &mockState{from, to, settlingAt, toSend, lanes} + return &mockState{from: from, to: to, settlingAt: settlingAt, toSend: big.NewInt(0), lanes: lanes} } // NewMockLaneState constructs a state for a payment channel lane with the set fixed values diff --git a/paychmgr/mock_test.go b/paychmgr/mock_test.go index c761221d2..3232e0893 100644 --- a/paychmgr/mock_test.go +++ b/paychmgr/mock_test.go @@ -9,7 +9,6 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" @@ -57,6 +56,7 @@ func (sm *mockStateManager) setAccountAddress(a address.Address, lookup address. func (sm *mockStateManager) setPaychState(a address.Address, actor *types.Actor, state paych.State) { sm.lk.Lock() defer sm.lk.Unlock() + sm.paychState[a] = mockPchState{actor, state} } diff --git a/paychmgr/paych.go b/paychmgr/paych.go index f856b9890..2cf200986 100644 --- a/paychmgr/paych.go +++ b/paychmgr/paych.go @@ -205,7 +205,7 @@ func (ca *channelAccessor) checkVoucherValidUnlocked(ctx context.Context, ch add } // Check the voucher against the highest known voucher nonce / value - laneStates, err := ca.laneState(ctx, pchState, ch) + laneStates, err := ca.laneState(pchState, ch) if err != nil { return nil, err } @@ -253,16 +253,9 @@ func (ca *channelAccessor) checkVoucherValidUnlocked(ctx context.Context, ch add return nil, err } - // Total required balance = total redeemed + toSend - // Must not exceed actor balance - ts, err := pchState.ToSend() - if err != nil { - return nil, err - } - - newTotal := types.BigAdd(totalRedeemed, ts) - if act.Balance.LessThan(newTotal) { - return nil, newErrInsufficientFunds(types.BigSub(newTotal, act.Balance)) + // Total required balance must not exceed actor balance + if act.Balance.LessThan(totalRedeemed) { + return nil, newErrInsufficientFunds(types.BigSub(totalRedeemed, act.Balance)) } if len(sv.Merges) != 0 { @@ -505,7 +498,6 @@ func (ca *channelAccessor) allocateLane(ch address.Address) (uint64, error) { ca.lk.Lock() defer ca.lk.Unlock() - // TODO: should this take into account lane state? return ca.store.AllocateLane(ch) } @@ -520,7 +512,7 @@ func (ca *channelAccessor) listVouchers(ctx context.Context, ch address.Address) // laneState gets the LaneStates from chain, then applies all vouchers in // the data store over the chain state -func (ca *channelAccessor) laneState(ctx context.Context, state paych.State, ch address.Address) (map[uint64]paych.LaneState, error) { +func (ca *channelAccessor) laneState(state paych.State, ch address.Address) (map[uint64]paych.LaneState, error) { // TODO: we probably want to call UpdateChannelState with all vouchers to be fully correct // (but technically dont't need to) @@ -547,14 +539,20 @@ func (ca *channelAccessor) laneState(ctx context.Context, state paych.State, ch return nil, err } + // Note: we use a map instead of an array to store laneStates because the + // client sets the lane ID (the index) and potentially they could use a + // very large index. for _, v := range vouchers { for range v.Voucher.Merges { return nil, xerrors.Errorf("paych merges not handled yet") } - // If there's a voucher for a lane that isn't in chain state just - // create it + // Check if there is an existing laneState in the payment channel + // for this voucher's lane ls, ok := laneStates[v.Voucher.Lane] + + // If the voucher does not have a higher nonce than the existing + // laneState for this lane, ignore it if ok { n, err := ls.Nonce() if err != nil { @@ -565,6 +563,7 @@ func (ca *channelAccessor) laneState(ctx context.Context, state paych.State, ch } } + // Voucher has a higher nonce, so replace laneState with this voucher laneStates[v.Voucher.Lane] = laneState{v.Voucher.Amount, v.Voucher.Nonce} } diff --git a/paychmgr/paych_test.go b/paychmgr/paych_test.go index b27b1e540..71c2bd854 100644 --- a/paychmgr/paych_test.go +++ b/paychmgr/paych_test.go @@ -47,7 +47,6 @@ func TestCheckVoucherValid(t *testing.T) { expectError bool key []byte actorBalance big.Int - toSend big.Int voucherAmount big.Int voucherLane uint64 voucherNonce uint64 @@ -56,35 +55,30 @@ func TestCheckVoucherValid(t *testing.T) { name: "passes when voucher amount < balance", key: fromKeyPrivate, actorBalance: big.NewInt(10), - toSend: big.NewInt(0), voucherAmount: big.NewInt(5), }, { name: "fails when funds too low", expectError: true, key: fromKeyPrivate, actorBalance: big.NewInt(5), - toSend: big.NewInt(0), voucherAmount: big.NewInt(10), }, { name: "fails when invalid signature", expectError: true, key: randKeyPrivate, actorBalance: big.NewInt(10), - toSend: big.NewInt(0), 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", expectError: true, key: fromKeyPrivate, actorBalance: big.NewInt(10), - toSend: big.NewInt(0), voucherAmount: big.NewInt(5), voucherLane: 1, voucherNonce: 2, @@ -95,7 +89,6 @@ func TestCheckVoucherValid(t *testing.T) { name: "passes when nonce higher", key: fromKeyPrivate, actorBalance: big.NewInt(10), - toSend: big.NewInt(0), voucherAmount: big.NewInt(5), voucherLane: 1, voucherNonce: 3, @@ -106,7 +99,6 @@ func TestCheckVoucherValid(t *testing.T) { name: "passes when nonce for different lane", key: fromKeyPrivate, actorBalance: big.NewInt(10), - toSend: big.NewInt(0), voucherAmount: big.NewInt(5), voucherLane: 2, voucherNonce: 2, @@ -118,32 +110,22 @@ func TestCheckVoucherValid(t *testing.T) { expectError: true, key: fromKeyPrivate, actorBalance: big.NewInt(10), - toSend: big.NewInt(0), voucherAmount: big.NewInt(5), voucherLane: 1, voucherNonce: 3, laneStates: map[uint64]paych.LaneState{ 1: paychmock.NewMockLaneState(big.NewInt(6), 2), }, - }, { - name: "fails when voucher + ToSend > balance", - expectError: true, - key: fromKeyPrivate, - actorBalance: big.NewInt(10), - toSend: big.NewInt(9), - voucherAmount: big.NewInt(2), }, { // voucher supersedes lane 1 redeemed so // lane 1 effective redeemed = voucher amount // - // required balance = toSend + total redeemed - // = 1 + 6 (lane1) + // required balance = voucher amt // = 7 // So required balance: 7 < actor balance: 10 - name: "passes when voucher + total redeemed <= balance", + name: "passes when voucher total redeemed <= balance", key: fromKeyPrivate, actorBalance: big.NewInt(10), - toSend: big.NewInt(1), voucherAmount: big.NewInt(6), voucherLane: 1, voucherNonce: 2, @@ -152,29 +134,68 @@ func TestCheckVoucherValid(t *testing.T) { 1: paychmock.NewMockLaneState(big.NewInt(4), 1), }, }, { - // required balance = toSend + total redeemed - // = 1 + 4 (lane 2) + 6 (voucher lane 1) + // required balance = total redeemed + // = 6 (voucher lane 1) + 5 (lane 2) // = 11 // So required balance: 11 > actor balance: 10 - name: "fails when voucher + total redeemed > balance", + name: "fails when voucher total redeemed > balance", expectError: true, key: fromKeyPrivate, actorBalance: big.NewInt(10), - toSend: big.NewInt(1), voucherAmount: big.NewInt(6), voucherLane: 1, voucherNonce: 1, laneStates: map[uint64]paych.LaneState{ // Lane 2 (different from voucher lane 1) - 2: paychmock.NewMockLaneState(big.NewInt(4), 1), + 2: paychmock.NewMockLaneState(big.NewInt(5), 1), + }, + }, { + // voucher supersedes lane 1 redeemed so + // lane 1 effective redeemed = voucher amount + // + // required balance = total redeemed + // = 6 (new voucher lane 1) + 5 (lane 2) + // = 11 + // So required balance: 11 > actor balance: 10 + name: "fails when voucher total redeemed > balance", + expectError: true, + key: fromKeyPrivate, + actorBalance: big.NewInt(10), + voucherAmount: big.NewInt(6), + voucherLane: 1, + voucherNonce: 2, + laneStates: map[uint64]paych.LaneState{ + // Lane 1 (superseded by new voucher in voucher lane 1) + 1: paychmock.NewMockLaneState(big.NewInt(5), 1), + // Lane 2 (different from voucher lane 1) + 2: paychmock.NewMockLaneState(big.NewInt(5), 1), + }, + }, { + // voucher supersedes lane 1 redeemed so + // lane 1 effective redeemed = voucher amount + // + // required balance = total redeemed + // = 5 (new voucher lane 1) + 5 (lane 2) + // = 10 + // So required balance: 10 <= actor balance: 10 + name: "passes when voucher total redeemed <= balance", + expectError: false, + key: fromKeyPrivate, + actorBalance: big.NewInt(10), + voucherAmount: big.NewInt(5), + voucherLane: 1, + voucherNonce: 2, + laneStates: map[uint64]paych.LaneState{ + // Lane 1 (superseded by new voucher in voucher lane 1) + 1: paychmock.NewMockLaneState(big.NewInt(4), 1), + // Lane 2 (different from voucher lane 1) + 2: paychmock.NewMockLaneState(big.NewInt(5), 1), }, }} for _, tcase := range tcases { tcase := tcase t.Run(tcase.name, func(t *testing.T) { - store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore())) - // Create an actor for the channel with the test case balance act := &types.Actor{ Code: builtin.AccountActorCodeID, @@ -184,16 +205,17 @@ func TestCheckVoucherValid(t *testing.T) { } mock.setPaychState(ch, act, paychmock.NewMockPayChState( - fromAcct, toAcct, abi.ChainEpoch(0), tcase.toSend, tcase.laneStates)) + fromAcct, toAcct, abi.ChainEpoch(0), tcase.laneStates)) // Create a manager + store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore())) mgr, err := newManager(store, mock) require.NoError(t, err) // Add channel To address to wallet mock.addWalletAddress(to) - // Create a signed voucher + // Create the test case signed voucher sv := createTestVoucher(t, ch, tcase.voucherLane, tcase.voucherNonce, tcase.voucherAmount, tcase.key) // Check the voucher's validity @@ -207,135 +229,11 @@ func TestCheckVoucherValid(t *testing.T) { } } -func TestCheckVoucherValidCountingAllLanes(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") - minDelta := big.NewInt(0) - - mock := newMockManagerAPI() - mock.setAccountAddress(fromAcct, from) - mock.setAccountAddress(toAcct, to) - - store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore())) - - actorBalance := big.NewInt(10) - toSend := big.NewInt(1) - laneStates := map[uint64]paych.LaneState{ - 1: paychmock.NewMockLaneState(big.NewInt(3), 1), - 2: paychmock.NewMockLaneState(big.NewInt(4), 1), - } - - act := &types.Actor{ - Code: builtin.AccountActorCodeID, - Head: cid.Cid{}, - Nonce: 0, - Balance: actorBalance, - } - - mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), toSend, laneStates)) - - mgr, err := newManager(store, mock) - require.NoError(t, err) - - // Add channel To address to wallet - mock.addWalletAddress(to) - - // - // Should not be possible to add a voucher with a value such that - // + toSend > - // - // lane 1 redeemed: 3 - // voucher amount (lane 1): 6 - // lane 1 redeemed (with voucher): 6 - // - // Lane 1: 6 - // Lane 2: 4 - // toSend: 1 - // -- - // total: 11 - // - // actor balance is 10 so total is too high. - // - voucherLane := uint64(1) - voucherNonce := uint64(2) - voucherAmount := big.NewInt(6) - sv := createTestVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate) - err = mgr.CheckVoucherValid(ctx, ch, sv) - require.Error(t, err) - - // - // lane 1 redeemed: 3 - // voucher amount (lane 1): 4 - // lane 1 redeemed (with voucher): 4 - // - // Lane 1: 4 - // Lane 2: 4 - // toSend: 1 - // -- - // total: 9 - // - // actor balance is 10 so total is ok. - // - voucherAmount = big.NewInt(4) - sv = createTestVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate) - err = mgr.CheckVoucherValid(ctx, ch, sv) - require.NoError(t, err) - - // Add voucher to lane 1, so Lane 1 effective redeemed - // (with first voucher) is now 4 - _, err = mgr.AddVoucherOutbound(ctx, ch, sv, nil, minDelta) - require.NoError(t, err) - - // - // lane 1 redeemed: 4 - // voucher amount (lane 1): 6 - // lane 1 redeemed (with voucher): 6 - // - // Lane 1: 6 - // Lane 2: 4 - // toSend: 1 - // -- - // total: 11 - // - // actor balance is 10 so total is too high. - // - voucherNonce++ - voucherAmount = big.NewInt(6) - sv = createTestVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate) - err = mgr.CheckVoucherValid(ctx, ch, sv) - require.Error(t, err) - - // - // lane 1 redeemed: 4 - // voucher amount (lane 1): 5 - // lane 1 redeemed (with voucher): 5 - // - // Lane 1: 5 - // Lane 2: 4 - // toSend: 1 - // -- - // total: 10 - // - // actor balance is 10 so total is ok. - // - voucherAmount = big.NewInt(5) - sv = createTestVoucher(t, ch, voucherLane, voucherNonce, voucherAmount, fromKeyPrivate) - err = mgr.CheckVoucherValid(ctx, ch, sv) - require.NoError(t, err) -} - func TestCreateVoucher(t *testing.T) { ctx := context.Background() // Set up a manager with a single payment channel - s := testSetupMgrWithChannel(ctx, t) + s := testSetupMgrWithChannel(t) // Create a voucher in lane 1 voucherLane1Amt := big.NewInt(5) @@ -400,7 +298,7 @@ func TestAddVoucherDelta(t *testing.T) { ctx := context.Background() // Set up a manager with a single payment channel - s := testSetupMgrWithChannel(ctx, t) + s := testSetupMgrWithChannel(t) voucherLane := uint64(1) @@ -442,7 +340,7 @@ func TestAddVoucherNextLane(t *testing.T) { ctx := context.Background() // Set up a manager with a single payment channel - s := testSetupMgrWithChannel(ctx, t) + s := testSetupMgrWithChannel(t) minDelta := big.NewInt(0) voucherAmount := big.NewInt(2) @@ -489,10 +387,8 @@ func TestAddVoucherNextLane(t *testing.T) { } func TestAllocateLane(t *testing.T) { - ctx := context.Background() - // Set up a manager with a single payment channel - s := testSetupMgrWithChannel(ctx, t) + s := testSetupMgrWithChannel(t) // First lane should be 0 lane, err := s.mgr.AllocateLane(s.ch) @@ -525,7 +421,6 @@ func TestAllocateLaneWithExistingLaneState(t *testing.T) { // Create a channel that will be retrieved from state actorBalance := big.NewInt(10) - toSend := big.NewInt(1) act := &types.Actor{ Code: builtin.AccountActorCodeID, @@ -534,7 +429,7 @@ func TestAllocateLaneWithExistingLaneState(t *testing.T) { Balance: actorBalance, } - mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), toSend, make(map[uint64]paych.LaneState))) + mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), make(map[uint64]paych.LaneState))) mgr, err := newManager(store, mock) require.NoError(t, err) @@ -559,7 +454,7 @@ func TestAddVoucherProof(t *testing.T) { ctx := context.Background() // Set up a manager with a single payment channel - s := testSetupMgrWithChannel(ctx, t) + s := testSetupMgrWithChannel(t) nonce := uint64(1) voucherAmount := big.NewInt(1) @@ -622,10 +517,11 @@ func TestAddVoucherInboundWalletKey(t *testing.T) { } mock := newMockManagerAPI() + mock.setAccountAddress(fromAcct, from) mock.setAccountAddress(toAcct, to) - mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), types.NewInt(0), make(map[uint64]paych.LaneState))) + mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), make(map[uint64]paych.LaneState))) // Create a manager store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore())) @@ -660,7 +556,7 @@ func TestBestSpendable(t *testing.T) { ctx := context.Background() // Set up a manager with a single payment channel - s := testSetupMgrWithChannel(ctx, t) + s := testSetupMgrWithChannel(t) // Add vouchers to lane 1 with amounts: [1, 2, 3] voucherLane := uint64(1) @@ -740,7 +636,7 @@ func TestCheckSpendable(t *testing.T) { ctx := context.Background() // Set up a manager with a single payment channel - s := testSetupMgrWithChannel(ctx, t) + s := testSetupMgrWithChannel(t) // Create voucher with Extra voucherLane := uint64(1) @@ -821,7 +717,7 @@ func TestSubmitVoucher(t *testing.T) { ctx := context.Background() // Set up a manager with a single payment channel - s := testSetupMgrWithChannel(ctx, t) + s := testSetupMgrWithChannel(t) // Create voucher with Extra voucherLane := uint64(1) @@ -908,7 +804,7 @@ type testScaffold struct { fromKeyPrivate []byte } -func testSetupMgrWithChannel(ctx context.Context, t *testing.T) *testScaffold { +func testSetupMgrWithChannel(t *testing.T) *testScaffold { fromKeyPrivate, fromKeyPublic := testGenerateKeyPair(t) ch := tutils.NewIDAddr(t, 100) @@ -920,6 +816,8 @@ func testSetupMgrWithChannel(ctx context.Context, t *testing.T) *testScaffold { mock := newMockManagerAPI() mock.setAccountAddress(fromAcct, from) mock.setAccountAddress(toAcct, to) + //mock.setAccountState(fromAcct, account.State{Address: from}) + //mock.setAccountState(toAcct, account.State{Address: to}) // Create channel in state balance := big.NewInt(20) @@ -929,7 +827,7 @@ func testSetupMgrWithChannel(ctx context.Context, t *testing.T) *testScaffold { Nonce: 0, Balance: balance, } - mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), big.NewInt(0), make(map[uint64]paych.LaneState))) + mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), make(map[uint64]paych.LaneState))) store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore())) mgr, err := newManager(store, mock) diff --git a/paychmgr/paychget_test.go b/paychmgr/paychget_test.go index 430e66c67..e35ae8371 100644 --- a/paychmgr/paychget_test.go +++ b/paychmgr/paychget_test.go @@ -978,7 +978,7 @@ func TestPaychAvailableFunds(t *testing.T) { Nonce: 0, Balance: createAmt, } - mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), big.NewInt(0), make(map[uint64]paych.LaneState))) + mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), make(map[uint64]paych.LaneState))) // Send create channel response response := testChannelResponse(t, ch) mock.receiveMsgResponse(createMsgCid, response) diff --git a/paychmgr/simple.go b/paychmgr/simple.go index d49ccafe6..ca778829f 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -312,7 +312,7 @@ func (ca *channelAccessor) currentAvailableFunds(channelID string, queuedAmt typ return nil, err } - laneStates, err := ca.laneState(ca.chctx, pchState, ch) + laneStates, err := ca.laneState(pchState, ch) if err != nil { return nil, err }