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 }