github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/builtin/paych/paych_test.go (about)

     1  package paych_test
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"reflect"
     7  	"strings"
     8  	"testing"
     9  
    10  	addr "github.com/filecoin-project/go-address"
    11  	"github.com/filecoin-project/go-state-types/abi"
    12  	"github.com/filecoin-project/go-state-types/big"
    13  	"github.com/filecoin-project/go-state-types/crypto"
    14  	"github.com/filecoin-project/go-state-types/exitcode"
    15  	"github.com/ipfs/go-cid"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  	cbg "github.com/whyrusleeping/cbor-gen"
    19  
    20  	"github.com/filecoin-project/specs-actors/v4/actors/builtin"
    21  	. "github.com/filecoin-project/specs-actors/v4/actors/builtin/paych"
    22  	"github.com/filecoin-project/specs-actors/v4/actors/util/adt"
    23  	"github.com/filecoin-project/specs-actors/v4/support/mock"
    24  	tutil "github.com/filecoin-project/specs-actors/v4/support/testing"
    25  )
    26  
    27  func TestExports(t *testing.T) {
    28  	mock.CheckActorExports(t, Actor{})
    29  }
    30  
    31  func TestPaymentChannelActor_Constructor(t *testing.T) {
    32  	paychAddr := tutil.NewIDAddr(t, 100)
    33  	payerAddr := tutil.NewIDAddr(t, 101)
    34  	payeeAddr := tutil.NewIDAddr(t, 102)
    35  	callerAddr := tutil.NewIDAddr(t, 102)
    36  
    37  	actor := pcActorHarness{Actor{}, t, paychAddr, payerAddr, payeeAddr}
    38  
    39  	t.Run("can create a payment channel actor", func(t *testing.T) {
    40  		builder := mock.NewBuilder(paychAddr).
    41  			WithCaller(callerAddr, builtin.InitActorCodeID).
    42  			WithActorType(payerAddr, builtin.AccountActorCodeID).
    43  			WithActorType(payeeAddr, builtin.AccountActorCodeID)
    44  		rt := builder.Build(t)
    45  		actor.constructAndVerify(t, rt, payerAddr, payeeAddr)
    46  		actor.checkState(rt)
    47  	})
    48  
    49  	t.Run("creates a payment channel actor after resolving non-ID addresses to ID addresses", func(t *testing.T) {
    50  		payerAddr := tutil.NewIDAddr(t, 101)
    51  		payerNonId := tutil.NewBLSAddr(t, 102)
    52  
    53  		payeeAddr := tutil.NewIDAddr(t, 103)
    54  		payeeNonId := tutil.NewBLSAddr(t, 104)
    55  
    56  		builder := mock.NewBuilder(paychAddr).
    57  			WithCaller(callerAddr, builtin.InitActorCodeID).
    58  			WithActorType(payerAddr, builtin.AccountActorCodeID).
    59  			WithActorType(payeeAddr, builtin.AccountActorCodeID)
    60  		rt := builder.Build(t)
    61  		rt.AddIDAddress(payerNonId, payerAddr)
    62  		rt.AddIDAddress(payeeNonId, payeeAddr)
    63  
    64  		actor.constructAndVerify(t, rt, payerNonId, payeeNonId)
    65  		actor.checkState(rt)
    66  	})
    67  
    68  	nonAccountCodeID := builtin.MultisigActorCodeID
    69  	testCases := []struct {
    70  		desc        string
    71  		fromCode    cid.Cid
    72  		fromAddr    addr.Address
    73  		toCode      cid.Cid
    74  		toAddr      addr.Address
    75  		expExitCode exitcode.ExitCode
    76  	}{
    77  		{"fails if target (to) is not account actor",
    78  			builtin.AccountActorCodeID,
    79  			payerAddr,
    80  			nonAccountCodeID,
    81  			payeeAddr,
    82  			exitcode.ErrForbidden,
    83  		}, {"fails if sender (from) is not account actor",
    84  			nonAccountCodeID,
    85  			payerAddr,
    86  			builtin.AccountActorCodeID,
    87  			payeeAddr,
    88  			exitcode.ErrForbidden,
    89  		},
    90  	}
    91  	for _, tc := range testCases {
    92  		t.Run(tc.desc, func(t *testing.T) {
    93  			builder := mock.NewBuilder(paychAddr).
    94  				WithCaller(callerAddr, builtin.InitActorCodeID).
    95  				WithActorType(paychAddr, builtin.PaymentChannelActorCodeID).
    96  				WithActorType(payerAddr, tc.toCode).
    97  				WithActorType(payeeAddr, tc.fromCode)
    98  			rt := builder.Build(t)
    99  			rt.ExpectValidateCallerType(builtin.InitActorCodeID)
   100  			rt.ExpectAbort(tc.expExitCode, func() {
   101  				rt.Call(actor.Constructor, &ConstructorParams{To: tc.toAddr, From: tc.fromAddr})
   102  			})
   103  		})
   104  	}
   105  
   106  	t.Run("fails if sender addr is not resolvable to ID address", func(t *testing.T) {
   107  		to := tutil.NewIDAddr(t, 101)
   108  		nonIdAddr := tutil.NewBLSAddr(t, 501)
   109  
   110  		rt := mock.NewBuilder(paychAddr).
   111  			WithCaller(callerAddr, builtin.InitActorCodeID).
   112  			WithActorType(to, builtin.AccountActorCodeID).Build(t)
   113  
   114  		rt.ExpectSend(nonIdAddr, builtin.MethodSend, nil, abi.NewTokenAmount(0), nil, exitcode.Ok)
   115  		rt.ExpectValidateCallerType(builtin.InitActorCodeID)
   116  		rt.ExpectAbort(exitcode.ErrIllegalState, func() {
   117  			rt.Call(actor.Constructor, &ConstructorParams{From: nonIdAddr, To: to})
   118  		})
   119  		rt.Verify()
   120  	})
   121  
   122  	t.Run("fails if target addr is not resolvable to ID address", func(t *testing.T) {
   123  		from := tutil.NewIDAddr(t, 5555)
   124  		nonIdAddr := tutil.NewBLSAddr(t, 501)
   125  
   126  		rt := mock.NewBuilder(paychAddr).
   127  			WithCaller(callerAddr, builtin.InitActorCodeID).
   128  			WithActorType(from, builtin.AccountActorCodeID).Build(t)
   129  
   130  		rt.ExpectSend(nonIdAddr, builtin.MethodSend, nil, abi.NewTokenAmount(0), nil, exitcode.Ok)
   131  		rt.ExpectValidateCallerType(builtin.InitActorCodeID)
   132  		rt.ExpectAbort(exitcode.ErrIllegalState, func() {
   133  			rt.Call(actor.Constructor, &ConstructorParams{From: from, To: nonIdAddr})
   134  		})
   135  		rt.Verify()
   136  	})
   137  
   138  	t.Run("fails if actor does not exist with: no code for address", func(t *testing.T) {
   139  		builder := mock.NewBuilder(paychAddr).
   140  			WithCaller(callerAddr, builtin.InitActorCodeID).
   141  			WithActorType(payerAddr, builtin.AccountActorCodeID)
   142  		rt := builder.Build(t)
   143  		rt.ExpectValidateCallerType(builtin.InitActorCodeID)
   144  		rt.ExpectAbort(exitcode.ErrIllegalArgument, func() {
   145  			rt.Call(actor.Constructor, &ConstructorParams{To: paychAddr})
   146  		})
   147  	})
   148  }
   149  
   150  func TestPaymentChannelActor_CreateLane(t *testing.T) {
   151  	initActorAddr := tutil.NewIDAddr(t, 100)
   152  	paychNonId := tutil.NewBLSAddr(t, 201)
   153  	paychAddr := tutil.NewIDAddr(t, 101)
   154  	payerAddr := tutil.NewIDAddr(t, 102)
   155  	payeeAddr := tutil.NewIDAddr(t, 103)
   156  	payChBalance := abi.NewTokenAmount(9)
   157  
   158  	actor := pcActorHarness{Actor{}, t, paychAddr, payerAddr, payeeAddr}
   159  	sig := &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("doesn't matter")}
   160  
   161  	testCases := []struct {
   162  		desc       string
   163  		targetCode cid.Cid
   164  
   165  		balance  int64
   166  		received int64
   167  		epoch    int64
   168  
   169  		tlmin int64
   170  		tlmax int64
   171  		lane  uint64
   172  		nonce uint64
   173  		amt   int64
   174  
   175  		paymentChannel addr.Address
   176  
   177  		secretPreimage []byte
   178  		sig            *crypto.Signature
   179  		verifySig      bool
   180  		expExitCode    exitcode.ExitCode
   181  	}{
   182  		{desc: "succeeds", targetCode: builtin.AccountActorCodeID,
   183  			amt: 1, paymentChannel: paychAddr, epoch: 1, tlmin: 1, tlmax: 0,
   184  			sig: sig, verifySig: true,
   185  			expExitCode: exitcode.Ok},
   186  		{desc: "fails if channel address does not match address on the signed voucher", targetCode: builtin.AccountActorCodeID,
   187  			amt: 1, paymentChannel: tutil.NewIDAddr(t, 210), epoch: 1, tlmin: 1, tlmax: 0,
   188  			sig: sig, verifySig: true,
   189  			expExitCode: exitcode.ErrIllegalArgument},
   190  		{desc: "fails if address on the signed voucher cannot be resolved to ID address", targetCode: builtin.AccountActorCodeID,
   191  			amt: 1, paymentChannel: tutil.NewBLSAddr(t, 1), epoch: 1, tlmin: 1, tlmax: 0,
   192  			sig: sig, verifySig: true,
   193  			expExitCode: exitcode.ErrIllegalArgument},
   194  		{desc: "succeeds if address on the signed voucher can be resolved to channel ID address", targetCode: builtin.AccountActorCodeID,
   195  			amt: 1, paymentChannel: paychNonId, epoch: 1, tlmin: 1, tlmax: 0,
   196  			sig: sig, verifySig: true,
   197  			expExitCode: exitcode.Ok},
   198  		{desc: "fails if balance too low", targetCode: builtin.AccountActorCodeID,
   199  			amt: 10, paymentChannel: paychAddr, epoch: 1, tlmin: 1, tlmax: 0,
   200  			sig: sig, verifySig: true,
   201  			expExitCode: exitcode.ErrIllegalArgument},
   202  		{desc: "fails if new send balance is negative", targetCode: builtin.AccountActorCodeID,
   203  			amt: -1, paymentChannel: paychAddr, epoch: 1, tlmin: 1, tlmax: 0,
   204  			sig: sig, verifySig: true,
   205  			expExitCode: exitcode.ErrIllegalArgument},
   206  		{desc: "fails if signature not valid", targetCode: builtin.AccountActorCodeID,
   207  			amt: 1, paymentChannel: paychAddr, epoch: 1, tlmin: 1, tlmax: 0,
   208  			sig: nil, verifySig: true,
   209  			expExitCode: exitcode.ErrIllegalArgument},
   210  		{desc: "fails if too early for voucher", targetCode: builtin.AccountActorCodeID,
   211  			amt: 1, paymentChannel: paychAddr, epoch: 1, tlmin: 10, tlmax: 0,
   212  			sig: sig, verifySig: true,
   213  			expExitCode: exitcode.ErrIllegalArgument},
   214  		{desc: "fails if beyond TimeLockMax", targetCode: builtin.AccountActorCodeID,
   215  			amt: 1, paymentChannel: paychAddr, epoch: 10, tlmin: 1, tlmax: 5,
   216  			sig: sig, verifySig: true,
   217  			expExitCode: exitcode.ErrIllegalArgument},
   218  		{desc: "fails if signature not verified", targetCode: builtin.AccountActorCodeID,
   219  			amt: 1, paymentChannel: paychAddr, epoch: 1, tlmin: 1, tlmax: 0,
   220  			sig: sig, verifySig: false,
   221  			expExitCode: exitcode.ErrIllegalArgument},
   222  		{desc: "fails if SigningBytes fails", targetCode: builtin.AccountActorCodeID,
   223  			amt: 1, paymentChannel: paychAddr, epoch: 1, tlmin: 1, tlmax: 0,
   224  			sig: sig, verifySig: true,
   225  			secretPreimage: make([]byte, 2<<21),
   226  			expExitCode:    exitcode.ErrIllegalArgument},
   227  	}
   228  
   229  	for _, tc := range testCases {
   230  		t.Run(tc.desc, func(t *testing.T) {
   231  			hasher := func(data []byte) [32]byte { return [32]byte{} }
   232  
   233  			builder := mock.NewBuilder(paychAddr).
   234  				WithBalance(payChBalance, abi.NewTokenAmount(tc.received)).
   235  				WithEpoch(abi.ChainEpoch(tc.epoch)).
   236  				WithCaller(initActorAddr, builtin.InitActorCodeID).
   237  				WithActorType(payeeAddr, builtin.AccountActorCodeID).
   238  				WithActorType(payerAddr, builtin.AccountActorCodeID).
   239  				WithHasher(hasher)
   240  
   241  			rt := builder.Build(t)
   242  			rt.AddIDAddress(paychNonId, paychAddr)
   243  			actor.constructAndVerify(t, rt, payerAddr, payeeAddr)
   244  
   245  			sv := SignedVoucher{
   246  				ChannelAddr:    tc.paymentChannel,
   247  				TimeLockMin:    abi.ChainEpoch(tc.tlmin),
   248  				TimeLockMax:    abi.ChainEpoch(tc.tlmax),
   249  				Lane:           tc.lane,
   250  				Nonce:          tc.nonce,
   251  				Amount:         big.NewInt(tc.amt),
   252  				Signature:      tc.sig,
   253  				SecretPreimage: tc.secretPreimage,
   254  			}
   255  			ucp := &UpdateChannelStateParams{Sv: sv}
   256  
   257  			rt.SetCaller(payeeAddr, tc.targetCode)
   258  			rt.ExpectValidateCallerAddr(payerAddr, payeeAddr)
   259  			if tc.sig != nil && tc.secretPreimage == nil {
   260  				var result error
   261  				if !tc.verifySig {
   262  					result = fmt.Errorf("bad signature")
   263  				}
   264  				rt.ExpectVerifySignature(*sv.Signature, payerAddr, voucherBytes(t, &sv), result)
   265  			}
   266  
   267  			if tc.expExitCode == exitcode.Ok {
   268  				rt.Call(actor.UpdateChannelState, ucp)
   269  				var st State
   270  				rt.GetState(&st)
   271  				lstates, err := adt.AsArray(adt.AsStore(rt), st.LaneStates, LaneStatesAmtBitwidth)
   272  				assert.NoError(t, err)
   273  				assert.Equal(t, uint64(1), lstates.Length())
   274  
   275  				var ls LaneState
   276  				found, err := lstates.Get(sv.Lane, &ls)
   277  				assert.True(t, found)
   278  				assert.NoError(t, err)
   279  
   280  				assert.Equal(t, sv.Amount, ls.Redeemed)
   281  				assert.Equal(t, sv.Nonce, ls.Nonce)
   282  				actor.checkState(rt)
   283  			} else {
   284  				rt.ExpectAbort(tc.expExitCode, func() {
   285  					rt.Call(actor.UpdateChannelState, ucp)
   286  				})
   287  				// verify state unchanged; no lane was created
   288  				verifyInitialState(t, rt, payerAddr, payeeAddr)
   289  			}
   290  			rt.Verify()
   291  		})
   292  	}
   293  }
   294  
   295  func assertLaneStatesLength(t *testing.T, rt *mock.Runtime, rcid cid.Cid, l int) {
   296  	t.Helper()
   297  	arr, err := adt.AsArray(adt.AsStore(rt), rcid, LaneStatesAmtBitwidth)
   298  	assert.NoError(t, err)
   299  	assert.Equal(t, arr.Length(), uint64(l))
   300  }
   301  
   302  func constructLaneStateAMT(t *testing.T, rt *mock.Runtime, lss []*LaneState) cid.Cid {
   303  	t.Helper()
   304  	arr, err := adt.MakeEmptyArray(adt.AsStore(rt), LaneStatesAmtBitwidth)
   305  	require.NoError(t, err)
   306  	for i, ls := range lss {
   307  		err := arr.Set(uint64(i), ls)
   308  		assert.NoError(t, err)
   309  	}
   310  
   311  	c, err := arr.Root()
   312  	assert.NoError(t, err)
   313  
   314  	return c
   315  }
   316  
   317  func getLaneState(t *testing.T, rt *mock.Runtime, rcid cid.Cid, lane uint64) *LaneState {
   318  	arr, err := adt.AsArray(adt.AsStore(rt), rcid, LaneStatesAmtBitwidth)
   319  	assert.NoError(t, err)
   320  
   321  	var out LaneState
   322  	found, err := arr.Get(lane, &out)
   323  	assert.NoError(t, err)
   324  	assert.True(t, found)
   325  
   326  	return &out
   327  }
   328  
   329  func TestActor_UpdateChannelStateRedeem(t *testing.T) {
   330  	newVoucherAmt := big.NewInt(9)
   331  
   332  	t.Run("redeeming voucher updates correctly with one lane", func(t *testing.T) {
   333  		rt, actor, sv := requireCreateChannelWithLanes(t, 1)
   334  		var st1 State
   335  		rt.GetState(&st1)
   336  
   337  		expLs := LaneState{
   338  			Redeemed: newVoucherAmt,
   339  			Nonce:    2,
   340  		}
   341  
   342  		ucp := &UpdateChannelStateParams{Sv: *sv}
   343  		ucp.Sv.Amount = newVoucherAmt
   344  
   345  		// Sending to same lane updates the lane with "new" state
   346  		rt.SetCaller(actor.payee, builtin.AccountActorCodeID)
   347  		rt.ExpectValidateCallerAddr(st1.From, st1.To)
   348  		rt.ExpectVerifySignature(*ucp.Sv.Signature, actor.payer, voucherBytes(t, &ucp.Sv), nil)
   349  		ret := rt.Call(actor.UpdateChannelState, ucp)
   350  		require.Nil(t, ret)
   351  		rt.Verify()
   352  
   353  		expState := State{
   354  			From:            st1.From,
   355  			To:              st1.To,
   356  			ToSend:          newVoucherAmt,
   357  			SettlingAt:      st1.SettlingAt,
   358  			MinSettleHeight: st1.MinSettleHeight,
   359  			LaneStates:      constructLaneStateAMT(t, rt, []*LaneState{&expLs}),
   360  		}
   361  		verifyState(t, rt, 1, expState)
   362  		actor.checkState(rt)
   363  	})
   364  
   365  	t.Run("redeems voucher for correct lane", func(t *testing.T) {
   366  		rt, actor, sv := requireCreateChannelWithLanes(t, 3)
   367  		var st1, st2 State
   368  		rt.GetState(&st1)
   369  
   370  		initialAmt := st1.ToSend
   371  
   372  		ucp := &UpdateChannelStateParams{Sv: *sv}
   373  		ucp.Sv.Amount = newVoucherAmt
   374  		ucp.Sv.Lane = 1
   375  
   376  		lsToUpdate := getLaneState(t, rt, st1.LaneStates, ucp.Sv.Lane)
   377  		ucp.Sv.Nonce = lsToUpdate.Nonce + 1
   378  
   379  		// Sending to same lane updates the lane with "new" state
   380  		rt.SetCaller(actor.payee, builtin.AccountActorCodeID)
   381  		rt.ExpectValidateCallerAddr(st1.From, st1.To)
   382  		rt.ExpectVerifySignature(*ucp.Sv.Signature, actor.payer, voucherBytes(t, &ucp.Sv), nil)
   383  		ret := rt.Call(actor.UpdateChannelState, ucp)
   384  		require.Nil(t, ret)
   385  		rt.Verify()
   386  
   387  		rt.GetState(&st2)
   388  		lUpdated := getLaneState(t, rt, st2.LaneStates, ucp.Sv.Lane)
   389  
   390  		bDelta := big.Sub(ucp.Sv.Amount, lsToUpdate.Redeemed)
   391  		expToSend := big.Add(initialAmt, bDelta)
   392  		assert.Equal(t, expToSend, st2.ToSend)
   393  		assert.Equal(t, ucp.Sv.Amount, lUpdated.Redeemed)
   394  		assert.Equal(t, ucp.Sv.Nonce, lUpdated.Nonce)
   395  		actor.checkState(rt)
   396  	})
   397  
   398  	t.Run("redeeming voucher fails on nonce reuse", func(t *testing.T) {
   399  		rt, actor, sv := requireCreateChannelWithLanes(t, 1)
   400  		var st1 State
   401  		rt.GetState(&st1)
   402  
   403  		ucp := &UpdateChannelStateParams{Sv: *sv}
   404  		// requireCreateChannelWithLanes creates a lane with nonce = 1.
   405  		// reusing that should fail
   406  		ucp.Sv.Nonce = 1
   407  		ucp.Sv.Amount = newVoucherAmt
   408  
   409  		rt.SetCaller(actor.payee, builtin.AccountActorCodeID)
   410  		rt.ExpectValidateCallerAddr(st1.From, st1.To)
   411  		rt.ExpectVerifySignature(*ucp.Sv.Signature, actor.payer, voucherBytes(t, &ucp.Sv), nil)
   412  
   413  		rt.ExpectAbort(exitcode.ErrIllegalArgument, func() {
   414  			rt.Call(actor.UpdateChannelState, ucp)
   415  		})
   416  
   417  		rt.Verify()
   418  		actor.checkState(rt)
   419  	})
   420  }
   421  
   422  func TestActor_UpdateChannelStateMergeSuccess(t *testing.T) {
   423  	// Check that a lane merge correctly updates lane states
   424  	numLanes := 3
   425  	rt, actor, sv := requireCreateChannelWithLanes(t, numLanes)
   426  
   427  	var st1 State
   428  	rt.GetState(&st1)
   429  	rt.SetCaller(st1.From, builtin.AccountActorCodeID)
   430  
   431  	mergeToID := uint64(0)
   432  	mergeTo := getLaneState(t, rt, st1.LaneStates, mergeToID)
   433  	mergeFromID := uint64(1)
   434  	mergeFrom := getLaneState(t, rt, st1.LaneStates, mergeFromID)
   435  
   436  	// Note sv.Amount = 3
   437  	sv.Lane = mergeToID
   438  	mergeNonce := mergeTo.Nonce + 10
   439  
   440  	merges := []Merge{{Lane: mergeFromID, Nonce: mergeNonce}}
   441  	sv.Merges = merges
   442  
   443  	ucp := &UpdateChannelStateParams{Sv: *sv}
   444  	rt.ExpectValidateCallerAddr(st1.From, st1.To)
   445  	rt.ExpectVerifySignature(*ucp.Sv.Signature, actor.payee, voucherBytes(t, &ucp.Sv), nil)
   446  	ret := rt.Call(actor.UpdateChannelState, ucp)
   447  	require.Nil(t, ret)
   448  	rt.Verify()
   449  
   450  	expMergeTo := LaneState{Redeemed: sv.Amount, Nonce: sv.Nonce}
   451  	expMergeFrom := LaneState{Redeemed: mergeFrom.Redeemed, Nonce: mergeNonce}
   452  
   453  	// calculate ToSend amount
   454  	redeemed := big.Add(mergeFrom.Redeemed, mergeTo.Redeemed)
   455  	expDelta := big.Sub(sv.Amount, redeemed)
   456  	expSendAmt := big.Add(st1.ToSend, expDelta)
   457  
   458  	// last lane should be unchanged
   459  	expState := st1
   460  	expState.ToSend = expSendAmt
   461  	expState.LaneStates = constructLaneStateAMT(t, rt, []*LaneState{&expMergeTo, &expMergeFrom, getLaneState(t, rt, st1.LaneStates, 2)})
   462  	verifyState(t, rt, numLanes, expState)
   463  	actor.checkState(rt)
   464  }
   465  
   466  func TestActor_UpdateChannelStateMergeFailure(t *testing.T) {
   467  	testCases := []struct {
   468  		name                           string
   469  		balance                        int64
   470  		lane, voucherNonce, mergeNonce uint64
   471  		expExitCode                    exitcode.ExitCode
   472  	}{
   473  		{
   474  			name: "fails: merged lane in voucher has outdated nonce, cannot redeem",
   475  			lane: 1, voucherNonce: 10, mergeNonce: 1,
   476  			expExitCode: exitcode.ErrIllegalArgument,
   477  		},
   478  		{
   479  			name: "fails: voucher has an outdated nonce, cannot redeem",
   480  			lane: 1, voucherNonce: 0, mergeNonce: 10,
   481  			expExitCode: exitcode.ErrIllegalArgument,
   482  		},
   483  		{
   484  			name: "fails: not enough funds in channel to cover voucher",
   485  			lane: 1, balance: 1, voucherNonce: 10, mergeNonce: 10,
   486  			expExitCode: exitcode.ErrIllegalArgument,
   487  		},
   488  		{
   489  			name: "fails: voucher cannot merge lanes into its own lane",
   490  			lane: 0, voucherNonce: 10, mergeNonce: 10,
   491  			expExitCode: exitcode.ErrIllegalArgument,
   492  		},
   493  	}
   494  
   495  	for _, tc := range testCases {
   496  		t.Run(tc.name, func(t *testing.T) {
   497  			rt, actor, sv := requireCreateChannelWithLanes(t, 2)
   498  			if tc.balance > 0 {
   499  				rt.SetBalance(abi.NewTokenAmount(tc.balance))
   500  			}
   501  
   502  			var st1 State
   503  			rt.GetState(&st1)
   504  			mergeToID := uint64(0)
   505  			mergeFromID := uint64(tc.lane)
   506  
   507  			sv.Lane = mergeToID
   508  			sv.Nonce = tc.voucherNonce
   509  			merges := []Merge{{Lane: mergeFromID, Nonce: tc.mergeNonce}}
   510  			sv.Merges = merges
   511  			ucp := &UpdateChannelStateParams{Sv: *sv}
   512  
   513  			rt.SetCaller(st1.From, builtin.AccountActorCodeID)
   514  			rt.ExpectValidateCallerAddr(st1.From, st1.To)
   515  			rt.ExpectVerifySignature(*ucp.Sv.Signature, actor.payee, voucherBytes(t, &ucp.Sv), nil)
   516  			rt.ExpectAbort(tc.expExitCode, func() {
   517  				rt.Call(actor.UpdateChannelState, ucp)
   518  			})
   519  			rt.Verify()
   520  
   521  		})
   522  	}
   523  	t.Run("When lane doesn't exist, fails with: voucher specifies invalid merge lane 999", func(t *testing.T) {
   524  		rt, actor, sv := requireCreateChannelWithLanes(t, 2)
   525  
   526  		var st1 State
   527  		rt.GetState(&st1)
   528  		mergeToID := uint64(0)
   529  		mergeFromID := uint64(999)
   530  
   531  		sv.Lane = mergeToID
   532  		sv.Nonce = 10
   533  		merges := []Merge{{Lane: mergeFromID, Nonce: sv.Nonce}}
   534  		sv.Merges = merges
   535  		ucp := &UpdateChannelStateParams{Sv: *sv}
   536  
   537  		rt.SetCaller(st1.From, builtin.AccountActorCodeID)
   538  		rt.ExpectValidateCallerAddr(st1.From, st1.To)
   539  		rt.ExpectVerifySignature(*ucp.Sv.Signature, actor.payee, voucherBytes(t, &ucp.Sv), nil)
   540  		rt.ExpectAbort(exitcode.ErrIllegalArgument, func() {
   541  			rt.Call(actor.UpdateChannelState, ucp)
   542  		})
   543  		rt.Verify()
   544  	})
   545  
   546  	t.Run("Lane ID over max fails", func(t *testing.T) {
   547  		rt, actor, sv := requireCreateChannelWithLanes(t, 1)
   548  
   549  		var st1 State
   550  		rt.GetState(&st1)
   551  		sv.Lane = MaxLane + 1
   552  		sv.Nonce++
   553  		sv.Amount = abi.NewTokenAmount(100)
   554  		ucp := &UpdateChannelStateParams{Sv: *sv}
   555  		rt.SetCaller(st1.From, builtin.AccountActorCodeID)
   556  		rt.ExpectValidateCallerAddr(st1.From, st1.To)
   557  		rt.ExpectVerifySignature(*ucp.Sv.Signature, actor.payee, voucherBytes(t, &ucp.Sv), nil)
   558  		rt.ExpectAbort(exitcode.ErrIllegalArgument, func() {
   559  			rt.Call(actor.UpdateChannelState, ucp)
   560  		})
   561  		rt.Verify()
   562  	})
   563  }
   564  
   565  func TestActor_UpdateChannelStateExtra(t *testing.T) {
   566  	mnum := builtin.MethodsPaych.UpdateChannelState
   567  	fakeParams := cbg.CborBoolTrue
   568  	expSendParams := &cbg.Deferred{Raw: fakeParams}
   569  	otherAddr := tutil.NewIDAddr(t, 104)
   570  	ex := &ModVerifyParams{
   571  		Actor:  otherAddr,
   572  		Method: mnum,
   573  		Data:   fakeParams,
   574  	}
   575  
   576  	t.Run("Succeeds if extra call succeeds", func(t *testing.T) {
   577  		rt, actor1, sv1 := requireCreateChannelWithLanes(t, 1)
   578  		var st1 State
   579  		rt.GetState(&st1)
   580  		rt.SetCaller(st1.From, builtin.AccountActorCodeID)
   581  
   582  		ucp := &UpdateChannelStateParams{Sv: *sv1}
   583  		ucp.Sv.Extra = ex
   584  
   585  		rt.ExpectValidateCallerAddr(st1.From, st1.To)
   586  		rt.ExpectVerifySignature(*ucp.Sv.Signature, st1.To, voucherBytes(t, &ucp.Sv), nil)
   587  		rt.ExpectSend(otherAddr, mnum, expSendParams, big.Zero(), nil, exitcode.Ok)
   588  		rt.Call(actor1.UpdateChannelState, ucp)
   589  		rt.Verify()
   590  		actor1.checkState(rt)
   591  	})
   592  	t.Run("If Extra call fails, fails with: spend voucher verification failed", func(t *testing.T) {
   593  		rt, actor1, sv1 := requireCreateChannelWithLanes(t, 1)
   594  		var st1 State
   595  		rt.GetState(&st1)
   596  		rt.SetCaller(st1.From, builtin.AccountActorCodeID)
   597  
   598  		ucp := &UpdateChannelStateParams{Sv: *sv1}
   599  		ucp.Sv.Extra = ex
   600  
   601  		rt.ExpectValidateCallerAddr(st1.From, st1.To)
   602  		rt.ExpectSend(otherAddr, mnum, expSendParams, big.Zero(), nil, exitcode.ErrIllegalArgument)
   603  		rt.ExpectVerifySignature(*ucp.Sv.Signature, st1.To, voucherBytes(t, &ucp.Sv), nil)
   604  		rt.ExpectAbort(exitcode.ErrIllegalArgument, func() {
   605  			rt.Call(actor1.UpdateChannelState, ucp)
   606  		})
   607  		rt.Verify()
   608  	})
   609  }
   610  
   611  func TestActor_UpdateChannelStateSettling(t *testing.T) {
   612  	rt, actor, sv := requireCreateChannelWithLanes(t, 1)
   613  
   614  	ep := abi.ChainEpoch(10)
   615  	rt.SetEpoch(ep)
   616  	var st State
   617  	rt.GetState(&st)
   618  
   619  	rt.SetCaller(st.From, builtin.AccountActorCodeID)
   620  	rt.ExpectValidateCallerAddr(st.From, st.To)
   621  	rt.Call(actor.Settle, nil)
   622  
   623  	expSettlingAt := ep + SettleDelay
   624  	rt.GetState(&st)
   625  	require.Equal(t, expSettlingAt, st.SettlingAt)
   626  	require.Equal(t, abi.ChainEpoch(0), st.MinSettleHeight)
   627  
   628  	ucp := &UpdateChannelStateParams{Sv: *sv}
   629  
   630  	testCases := []struct {
   631  		name                                               string
   632  		minSettleHeight, expSettlingAt, expMinSettleHeight abi.ChainEpoch
   633  		//expExitCode                                        exitcode.ExitCode
   634  	}{
   635  		{name: "No change",
   636  			minSettleHeight: 0, expMinSettleHeight: st.MinSettleHeight,
   637  			expSettlingAt: st.SettlingAt},
   638  		{name: "Updates MinSettleHeight only",
   639  			minSettleHeight: abi.ChainEpoch(2), expMinSettleHeight: abi.ChainEpoch(2),
   640  			expSettlingAt: st.SettlingAt},
   641  		{name: "SettlingAt unchanged even after MinSettleHeight is changed because it is greater than MinSettleHeight",
   642  			minSettleHeight: abi.ChainEpoch(12), expMinSettleHeight: abi.ChainEpoch(12),
   643  			expSettlingAt: st.SettlingAt},
   644  		{name: "SettlingAt changes after MinSettleHeight is changed because it is less than MinSettleHeight",
   645  			minSettleHeight: st.SettlingAt + 1, expMinSettleHeight: st.SettlingAt + 1,
   646  			expSettlingAt: st.SettlingAt + 1},
   647  	}
   648  	for _, tc := range testCases {
   649  		t.Run(tc.name, func(t *testing.T) {
   650  			var newSt State
   651  			ucp.Sv.MinSettleHeight = tc.minSettleHeight
   652  			rt.ExpectValidateCallerAddr(st.From, st.To)
   653  			rt.ExpectVerifySignature(*ucp.Sv.Signature, st.To, voucherBytes(t, &ucp.Sv), nil)
   654  			rt.Call(actor.UpdateChannelState, ucp)
   655  			rt.GetState(&newSt)
   656  			assert.Equal(t, tc.expSettlingAt, newSt.SettlingAt)
   657  			assert.Equal(t, tc.expMinSettleHeight, newSt.MinSettleHeight)
   658  			ucp.Sv.Nonce = ucp.Sv.Nonce + 1
   659  			actor.checkState(rt)
   660  		})
   661  	}
   662  }
   663  
   664  func TestActor_UpdateChannelStateSecretPreimage(t *testing.T) {
   665  	t.Run("Succeeds with correct secret", func(t *testing.T) {
   666  		rt, actor, sv := requireCreateChannelWithLanes(t, 1)
   667  		var st State
   668  		rt.GetState(&st)
   669  
   670  		rt.SetHasher(func(data []byte) [32]byte {
   671  			aux := []byte("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
   672  			var res [32]byte
   673  			copy(res[:], aux)
   674  			copy(res[:], data)
   675  			return res
   676  		})
   677  		ucp := &UpdateChannelStateParams{
   678  			Sv:     *sv,
   679  			Secret: []byte("Profesr"),
   680  		}
   681  		ucp.Sv.SecretPreimage = []byte("ProfesrXXXXXXXXXXXXXXXXXXXXXXXXX")
   682  		rt.ExpectValidateCallerAddr(st.From, st.To)
   683  		rt.ExpectVerifySignature(*ucp.Sv.Signature, st.To, voucherBytes(t, &ucp.Sv), nil)
   684  		rt.Call(actor.UpdateChannelState, ucp)
   685  		rt.Verify()
   686  		actor.checkState(rt)
   687  	})
   688  
   689  	t.Run("If bad secret preimage, fails with: incorrect secret!", func(t *testing.T) {
   690  		rt, actor, sv := requireCreateChannelWithLanes(t, 1)
   691  		var st State
   692  		rt.GetState(&st)
   693  		ucp := &UpdateChannelStateParams{
   694  			Sv:     *sv,
   695  			Secret: []byte("Profesr"),
   696  		}
   697  		ucp.Sv.SecretPreimage = append([]byte("Magneto"), make([]byte, 25)...)
   698  		rt.ExpectValidateCallerAddr(st.From, st.To)
   699  		rt.ExpectVerifySignature(*ucp.Sv.Signature, st.To, voucherBytes(t, &ucp.Sv), nil)
   700  		rt.ExpectAbort(exitcode.ErrIllegalArgument, func() {
   701  			rt.Call(actor.UpdateChannelState, ucp)
   702  		})
   703  		rt.Verify()
   704  	})
   705  }
   706  
   707  func TestActor_Settle(t *testing.T) {
   708  	ep := abi.ChainEpoch(10)
   709  
   710  	t.Run("Settle adjusts SettlingAt", func(t *testing.T) {
   711  		rt, actor, _ := requireCreateChannelWithLanes(t, 1)
   712  		rt.SetEpoch(ep)
   713  		var st State
   714  		rt.GetState(&st)
   715  
   716  		rt.SetCaller(st.From, builtin.AccountActorCodeID)
   717  		rt.ExpectValidateCallerAddr(st.From, st.To)
   718  		rt.Call(actor.Settle, nil)
   719  
   720  		expSettlingAt := ep + SettleDelay
   721  		rt.GetState(&st)
   722  		assert.Equal(t, expSettlingAt, st.SettlingAt)
   723  		assert.Equal(t, abi.ChainEpoch(0), st.MinSettleHeight)
   724  		actor.checkState(rt)
   725  	})
   726  
   727  	t.Run("settle fails if called twice: channel already settling", func(t *testing.T) {
   728  		rt, actor, _ := requireCreateChannelWithLanes(t, 1)
   729  		rt.SetEpoch(ep)
   730  		var st State
   731  		rt.GetState(&st)
   732  
   733  		rt.SetCaller(st.From, builtin.AccountActorCodeID)
   734  		rt.ExpectValidateCallerAddr(st.From, st.To)
   735  		rt.Call(actor.Settle, nil)
   736  
   737  		rt.ExpectValidateCallerAddr(st.From, st.To)
   738  		rt.ExpectAbort(exitcode.ErrIllegalState, func() {
   739  			rt.Call(actor.Settle, nil)
   740  		})
   741  	})
   742  
   743  	t.Run("Settle changes SettleHeight again if MinSettleHeight is less", func(t *testing.T) {
   744  		rt, actor, sv := requireCreateChannelWithLanes(t, 1)
   745  		rt.SetEpoch(ep)
   746  		var st State
   747  		rt.GetState(&st)
   748  
   749  		// UpdateChannelState to increase MinSettleHeight only
   750  		ucp := &UpdateChannelStateParams{Sv: *sv}
   751  		ucp.Sv.MinSettleHeight = (ep + SettleDelay) + 1
   752  
   753  		rt.ExpectValidateCallerAddr(st.From, st.To)
   754  		rt.ExpectVerifySignature(*ucp.Sv.Signature, st.To, voucherBytes(t, &ucp.Sv), nil)
   755  		rt.Call(actor.UpdateChannelState, ucp)
   756  
   757  		var newSt State
   758  		rt.GetState(&newSt)
   759  		// SettlingAt should remain the same.
   760  		require.Equal(t, abi.ChainEpoch(0), newSt.SettlingAt)
   761  		require.Equal(t, ucp.Sv.MinSettleHeight, newSt.MinSettleHeight)
   762  
   763  		// Settle.
   764  		rt.SetCaller(st.From, builtin.AccountActorCodeID)
   765  		rt.ExpectValidateCallerAddr(st.From, st.To)
   766  		rt.Call(actor.Settle, nil)
   767  
   768  		// SettlingAt should = MinSettleHeight, not epoch + SettleDelay.
   769  		rt.GetState(&newSt)
   770  		assert.Equal(t, ucp.Sv.MinSettleHeight, newSt.SettlingAt)
   771  		actor.checkState(rt)
   772  	})
   773  
   774  	t.Run("Voucher invalid after settling", func(t *testing.T) {
   775  		rt, actor, sv := requireCreateChannelWithLanes(t, 1)
   776  		rt.SetEpoch(ep)
   777  		var st State
   778  		rt.GetState(&st)
   779  
   780  		rt.SetCaller(st.From, builtin.AccountActorCodeID)
   781  		rt.ExpectValidateCallerAddr(st.From, st.To)
   782  		rt.Call(actor.Settle, nil)
   783  
   784  		rt.GetState(&st)
   785  		rt.SetEpoch(st.SettlingAt + 40)
   786  		ucp := &UpdateChannelStateParams{Sv: *sv}
   787  		rt.ExpectValidateCallerAddr(st.From, st.To)
   788  		rt.ExpectVerifySignature(*ucp.Sv.Signature, actor.payee, voucherBytes(t, &ucp.Sv), nil)
   789  		rt.ExpectAbort(ErrChannelStateUpdateAfterSettled, func() {
   790  			rt.Call(actor.UpdateChannelState, ucp)
   791  		})
   792  
   793  	})
   794  }
   795  
   796  func TestActor_Collect(t *testing.T) {
   797  	t.Run("Happy path", func(t *testing.T) {
   798  		rt, actor, _ := requireCreateChannelWithLanes(t, 1)
   799  		currEpoch := abi.ChainEpoch(10)
   800  		rt.SetEpoch(currEpoch)
   801  		var st State
   802  		rt.GetState(&st)
   803  
   804  		// Settle.
   805  		rt.SetCaller(st.From, builtin.AccountActorCodeID)
   806  		rt.ExpectValidateCallerAddr(st.From, st.To)
   807  		rt.Call(actor.Settle, nil)
   808  
   809  		rt.GetState(&st)
   810  		require.EqualValues(t, SettleDelay+currEpoch, st.SettlingAt)
   811  		rt.ExpectValidateCallerAddr(st.From, st.To)
   812  
   813  		// "wait" for SettlingAt epoch
   814  		rt.SetEpoch(st.SettlingAt + 1)
   815  
   816  		rt.ExpectSend(st.To, builtin.MethodSend, nil, st.ToSend, nil, exitcode.Ok)
   817  
   818  		// Collect.
   819  		rt.SetCaller(st.From, builtin.AccountActorCodeID)
   820  		rt.ExpectValidateCallerAddr(st.From, st.To)
   821  		rt.ExpectDeleteActor(st.From)
   822  		res := rt.Call(actor.Collect, nil)
   823  		assert.Nil(t, res)
   824  		actor.checkState(rt)
   825  	})
   826  
   827  	testCases := []struct {
   828  		name                                           string
   829  		expSendToCode, expSendFromCode, expCollectExit exitcode.ExitCode
   830  		dontSettle                                     bool
   831  	}{
   832  		{name: "fails if not settling with: payment channel not settling or settled", dontSettle: true, expCollectExit: exitcode.ErrForbidden},
   833  		{name: "fails if Failed to send funds to `To`", expSendToCode: exitcode.ErrIllegalArgument, expCollectExit: exitcode.ErrIllegalArgument},
   834  	}
   835  	for _, tc := range testCases {
   836  		t.Run(tc.name, func(t *testing.T) {
   837  			rt, actor, _ := requireCreateChannelWithLanes(t, 1)
   838  			currEpoch := abi.ChainEpoch(10)
   839  			rt.SetEpoch(currEpoch)
   840  			var st State
   841  			rt.GetState(&st)
   842  
   843  			if !tc.dontSettle {
   844  				rt.SetCaller(st.From, builtin.AccountActorCodeID)
   845  				rt.ExpectValidateCallerAddr(st.From, st.To)
   846  				rt.Call(actor.Settle, nil)
   847  				rt.GetState(&st)
   848  				require.Equal(t, SettleDelay+currEpoch, st.SettlingAt)
   849  			}
   850  
   851  			// "wait" for SettlingAt epoch
   852  			rt.SetEpoch(st.SettlingAt + 1)
   853  
   854  			rt.ExpectSend(st.To, builtin.MethodSend, nil, st.ToSend, nil, tc.expSendToCode)
   855  
   856  			// Collect.
   857  			rt.SetCaller(st.From, builtin.AccountActorCodeID)
   858  			rt.ExpectValidateCallerAddr(st.From, st.To)
   859  			rt.ExpectAbort(tc.expCollectExit, func() {
   860  				rt.Call(actor.Collect, nil)
   861  			})
   862  		})
   863  	}
   864  }
   865  
   866  type pcActorHarness struct {
   867  	Actor
   868  	t testing.TB
   869  
   870  	addr  addr.Address
   871  	payer addr.Address
   872  	payee addr.Address
   873  }
   874  
   875  type laneParams struct {
   876  	epochNum    int64
   877  	from, to    addr.Address
   878  	amt         big.Int
   879  	lane, nonce uint64
   880  	merges      []Merge
   881  }
   882  
   883  func requireCreateChannelWithLanes(t *testing.T, numLanes int) (*mock.Runtime, *pcActorHarness, *SignedVoucher) {
   884  	paychAddr := tutil.NewIDAddr(t, 100)
   885  	payerAddr := tutil.NewIDAddr(t, 102)
   886  	payeeAddr := tutil.NewIDAddr(t, 103)
   887  	balance := abi.NewTokenAmount(100000)
   888  	received := abi.NewTokenAmount(0)
   889  
   890  	curEpoch := 2
   891  	hasher := func(data []byte) [32]byte { return [32]byte{} }
   892  
   893  	builder := mock.NewBuilder(paychAddr).
   894  		WithBalance(balance, received).
   895  		WithEpoch(abi.ChainEpoch(curEpoch)).
   896  		WithCaller(builtin.InitActorAddr, builtin.InitActorCodeID).
   897  		WithActorType(payerAddr, builtin.AccountActorCodeID).
   898  		WithActorType(payeeAddr, builtin.AccountActorCodeID).
   899  		WithHasher(hasher)
   900  
   901  	actor := pcActorHarness{Actor{}, t, paychAddr, payerAddr, payeeAddr}
   902  
   903  	rt := builder.Build(t)
   904  	actor.constructAndVerify(t, rt, payerAddr, payeeAddr)
   905  
   906  	var lastSv *SignedVoucher
   907  	for i := 0; i < numLanes; i++ {
   908  		amt := big.NewInt(int64(i + 1))
   909  		lastSv = requireAddNewLane(t, rt, &actor, laneParams{
   910  			epochNum: int64(curEpoch),
   911  			from:     payerAddr,
   912  			to:       payeeAddr,
   913  			amt:      amt,
   914  			lane:     uint64(i),
   915  			nonce:    uint64(i + 1),
   916  		})
   917  	}
   918  	return rt, &actor, lastSv
   919  }
   920  
   921  func requireAddNewLane(t *testing.T, rt *mock.Runtime, actor *pcActorHarness, params laneParams) *SignedVoucher {
   922  	sig := &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte{0, 1, 2, 3, 4, 5, 6, 7}}
   923  	tl := abi.ChainEpoch(params.epochNum)
   924  	sv := SignedVoucher{ChannelAddr: actor.addr, TimeLockMin: tl, TimeLockMax: math.MaxInt64, Lane: params.lane, Nonce: params.nonce, Amount: params.amt, Signature: sig, Merges: params.merges}
   925  	ucp := &UpdateChannelStateParams{Sv: sv}
   926  
   927  	rt.SetCaller(params.from, builtin.AccountActorCodeID)
   928  	rt.ExpectValidateCallerAddr(params.from, params.to)
   929  	rt.ExpectVerifySignature(*sv.Signature, actor.payee, voucherBytes(t, &sv), nil)
   930  	ret := rt.Call(actor.UpdateChannelState, ucp)
   931  	require.Nil(t, ret)
   932  	rt.Verify()
   933  	sv.Nonce = sv.Nonce + 1
   934  	return &sv
   935  }
   936  
   937  func (h *pcActorHarness) constructAndVerify(t *testing.T, rt *mock.Runtime, sender, receiver addr.Address) {
   938  	params := &ConstructorParams{To: receiver, From: sender}
   939  
   940  	rt.ExpectValidateCallerType(builtin.InitActorCodeID)
   941  	ret := rt.Call(h.Actor.Constructor, params)
   942  	assert.Nil(h.t, ret)
   943  	rt.Verify()
   944  
   945  	senderId, ok := rt.GetIdAddr(sender)
   946  	require.True(h.t, ok)
   947  
   948  	receiverId, ok := rt.GetIdAddr(receiver)
   949  	require.True(h.t, ok)
   950  
   951  	verifyInitialState(t, rt, senderId, receiverId)
   952  }
   953  
   954  func (h *pcActorHarness) checkState(rt *mock.Runtime) {
   955  	var st State
   956  	rt.GetState(&st)
   957  	_, msgs := CheckStateInvariants(&st, rt.AdtStore(), rt.Balance())
   958  	assert.True(h.t, msgs.IsEmpty(), strings.Join(msgs.Messages(), "\n"))
   959  }
   960  
   961  func verifyInitialState(t *testing.T, rt *mock.Runtime, sender, receiver addr.Address) {
   962  	var st State
   963  	rt.GetState(&st)
   964  	emptyArray, err := adt.StoreEmptyArray(adt.AsStore(rt), LaneStatesAmtBitwidth)
   965  	require.NoError(t, err)
   966  	expectedState := State{From: sender, To: receiver, ToSend: abi.NewTokenAmount(0), LaneStates: emptyArray}
   967  	verifyState(t, rt, -1, expectedState)
   968  }
   969  
   970  func verifyState(t *testing.T, rt *mock.Runtime, expLanes int, expectedState State) {
   971  	var st State
   972  	rt.GetState(&st)
   973  	assert.Equal(t, expectedState.To, st.To)
   974  	assert.Equal(t, expectedState.From, st.From)
   975  	assert.Equal(t, expectedState.MinSettleHeight, st.MinSettleHeight)
   976  	assert.Equal(t, expectedState.SettlingAt, st.SettlingAt)
   977  	assert.Equal(t, expectedState.ToSend, st.ToSend)
   978  	if expLanes >= 0 {
   979  		assertLaneStatesLength(t, rt, st.LaneStates, expLanes)
   980  		assert.True(t, reflect.DeepEqual(expectedState.LaneStates, st.LaneStates))
   981  	} else {
   982  		emptyArray, err := adt.StoreEmptyArray(adt.AsStore(rt), LaneStatesAmtBitwidth)
   983  		assert.NoError(t, err)
   984  		assert.Equal(t, st.LaneStates, emptyArray)
   985  	}
   986  }
   987  
   988  func voucherBytes(t *testing.T, sv *SignedVoucher) []byte {
   989  	bytes, err := sv.SigningBytes()
   990  	require.NoError(t, err)
   991  	return bytes
   992  }