104 lines
3.5 KiB
Go
104 lines
3.5 KiB
Go
package paychmgr
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
"github.com/filecoin-project/go-state-types/big"
|
|
"github.com/ipfs/go-cid"
|
|
ds "github.com/ipfs/go-datastore"
|
|
ds_sync "github.com/ipfs/go-datastore/sync"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
tutils2 "github.com/filecoin-project/specs-actors/v2/support/testing"
|
|
|
|
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
|
paychmock "github.com/filecoin-project/lotus/chain/actors/builtin/paych/mock"
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
)
|
|
|
|
// TestPaychAddVoucherAfterAddFunds tests adding a voucher to a channel with
|
|
// insufficient funds, then adding funds to the channel, then adding the
|
|
// voucher again
|
|
func TestPaychAddVoucherAfterAddFunds(t *testing.T) {
|
|
ctx := context.Background()
|
|
store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
|
|
|
fromKeyPrivate, fromKeyPublic := testGenerateKeyPair(t)
|
|
ch := tutils2.NewIDAddr(t, 100)
|
|
from := tutils2.NewSECP256K1Addr(t, string(fromKeyPublic))
|
|
to := tutils2.NewSECP256K1Addr(t, "secpTo")
|
|
fromAcct := tutils2.NewActorAddr(t, "fromAct")
|
|
toAcct := tutils2.NewActorAddr(t, "toAct")
|
|
|
|
mock := newMockManagerAPI()
|
|
defer mock.close()
|
|
|
|
// Add the from signing key to the wallet
|
|
mock.setAccountAddress(fromAcct, from)
|
|
mock.setAccountAddress(toAcct, to)
|
|
mock.addSigningKey(fromKeyPrivate)
|
|
|
|
mgr, err := newManager(store, mock)
|
|
require.NoError(t, err)
|
|
|
|
// Send create message for a channel with value 10
|
|
createAmt := big.NewInt(10)
|
|
_, createMsgCid, err := mgr.GetPaych(ctx, from, to, createAmt, onChainReserve)
|
|
require.NoError(t, err)
|
|
|
|
// Send create channel response
|
|
response := testChannelResponse(t, ch)
|
|
mock.receiveMsgResponse(createMsgCid, response)
|
|
|
|
// Create an actor in state for the channel with the initial channel balance
|
|
act := &types.Actor{
|
|
Code: builtin2.AccountActorCodeID,
|
|
Head: cid.Cid{},
|
|
Nonce: 0,
|
|
Balance: createAmt,
|
|
}
|
|
mock.setPaychState(ch, act, paychmock.NewMockPayChState(fromAcct, toAcct, abi.ChainEpoch(0), make(map[uint64]paych.LaneState)))
|
|
|
|
// Wait for create response to be processed by manager
|
|
_, err = mgr.GetPaychWaitReady(ctx, createMsgCid)
|
|
require.NoError(t, err)
|
|
|
|
// Create a voucher with a value equal to the channel balance
|
|
voucher := paych.SignedVoucher{Amount: createAmt, Lane: 1}
|
|
res, err := mgr.CreateVoucher(ctx, ch, voucher)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res.Voucher)
|
|
|
|
// Create a voucher in a different lane with an amount that exceeds the
|
|
// channel balance
|
|
excessAmt := types.NewInt(5)
|
|
voucher = paych.SignedVoucher{Amount: excessAmt, Lane: 2}
|
|
res, err = mgr.CreateVoucher(ctx, ch, voucher)
|
|
require.NoError(t, err)
|
|
require.Nil(t, res.Voucher)
|
|
require.Equal(t, res.Shortfall, excessAmt)
|
|
|
|
// Add funds so as to cover the voucher shortfall
|
|
_, addFundsMsgCid, err := mgr.GetPaych(ctx, from, to, excessAmt, onChainReserve)
|
|
require.NoError(t, err)
|
|
|
|
// Trigger add funds confirmation
|
|
mock.receiveMsgResponse(addFundsMsgCid, types.MessageReceipt{ExitCode: 0})
|
|
|
|
// Update actor test case balance to reflect added funds
|
|
act.Balance = types.BigAdd(createAmt, excessAmt)
|
|
|
|
// Wait for add funds confirmation to be processed by manager
|
|
_, err = mgr.GetPaychWaitReady(ctx, addFundsMsgCid)
|
|
require.NoError(t, err)
|
|
|
|
// Adding same voucher that previously exceeded channel balance
|
|
// should succeed now that the channel balance has been increased
|
|
res, err = mgr.CreateVoucher(ctx, ch, voucher)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res.Voucher)
|
|
}
|