lotus/tvx/suite_messages_paych.go
Alan Shaw 52cf367a92
feat: add MustMarshalJSON for more DRY outputting (#211)
Small change to make encoding and printing the test vector output a bit more succinct.
2020-08-07 14:09:10 +01:00

215 lines
7.3 KiB
Go

package main
import (
"fmt"
"os"
abi_spec "github.com/filecoin-project/specs-actors/actors/abi"
big_spec "github.com/filecoin-project/specs-actors/actors/abi/big"
paych_spec "github.com/filecoin-project/specs-actors/actors/builtin/paych"
crypto_spec "github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/stretchr/testify/assert"
"github.com/filecoin-project/oni/tvx/chain"
"github.com/filecoin-project/oni/tvx/drivers"
"github.com/filecoin-project/oni/tvx/schema"
)
func MessageTest_Paych() error {
var initialBal = abi_spec.NewTokenAmount(200_000_000_000)
var toSend = abi_spec.NewTokenAmount(10_000)
err := func(testname string) error {
td := drivers.NewTestDriver()
// will create and send on payment channel
sender, senderID := td.NewAccountActor(drivers.SECP, initialBal)
// will be receiver on paych
receiver, receiverID := td.NewAccountActor(drivers.SECP, initialBal)
preroot := td.GetStateRoot()
// the _expected_ address of the payment channel
paychAddr := chain.MustNewIDAddr(chain.MustIDFromAddress(receiverID) + 1)
createRet := td.ComputeInitActorExecReturn(sender, 0, 0, paychAddr)
msg := td.MessageProducer.CreatePaymentChannelActor(sender, receiver, chain.Value(toSend), chain.Nonce(0))
td.Vector.ApplyMessages = append(td.Vector.ApplyMessages, schema.Message{Bytes: chain.MustSerialize(msg)})
// init actor creates the payment channel
td.ApplyExpect(
msg,
chain.MustSerialize(&createRet))
var pcState paych_spec.State
td.GetActorState(paychAddr, &pcState)
assert.Equal(drivers.T, senderID, pcState.From)
assert.Equal(drivers.T, receiverID, pcState.To)
td.AssertBalance(paychAddr, toSend)
postroot := td.GetStateRoot()
td.Vector.CAR = td.MustMarshalGzippedCAR(preroot, postroot)
td.Vector.Pre.StateTree.RootCID = preroot
td.Vector.Post.StateTree.RootCID = postroot
// encode and output
fmt.Fprintln(os.Stdout, string(td.Vector.MustMarshalJSON()))
return nil
}("happy path constructor")
if err != nil {
return err
}
err = func(testname string) error {
td := drivers.NewTestDriver()
//const pcTimeLock = abi_spec.ChainEpoch(1)
const pcTimeLock = abi_spec.ChainEpoch(0)
const pcLane = uint64(123)
const pcNonce = uint64(1)
var pcAmount = big_spec.NewInt(10)
var pcSig = &crypto_spec.Signature{
Type: crypto_spec.SigTypeBLS,
Data: []byte("signature goes here"), // TODO may need to generate an actual signature
}
// will create and send on payment channel
sender, _ := td.NewAccountActor(drivers.SECP, initialBal)
// will be receiver on paych
receiver, receiverID := td.NewAccountActor(drivers.SECP, initialBal)
preroot := td.GetStateRoot()
// the _expected_ address of the payment channel
paychAddr := chain.MustNewIDAddr(chain.MustIDFromAddress(receiverID) + 1)
createRet := td.ComputeInitActorExecReturn(sender, 0, 0, paychAddr)
msg := td.MessageProducer.CreatePaymentChannelActor(sender, receiver, chain.Value(toSend), chain.Nonce(0))
td.Vector.ApplyMessages = append(td.Vector.ApplyMessages, schema.Message{Bytes: chain.MustSerialize(msg)})
td.ApplyExpect(
msg,
chain.MustSerialize(&createRet))
msg = td.MessageProducer.PaychUpdateChannelState(sender, paychAddr, &paych_spec.UpdateChannelStateParams{
Sv: paych_spec.SignedVoucher{
ChannelAddr: paychAddr,
TimeLockMin: pcTimeLock,
TimeLockMax: 0, // TimeLockMax set to 0 means no timeout
SecretPreimage: nil,
Extra: nil,
Lane: pcLane,
Nonce: pcNonce,
Amount: pcAmount,
MinSettleHeight: 0,
Merges: nil,
Signature: pcSig,
},
}, chain.Nonce(1), chain.Value(big_spec.Zero()))
td.Vector.ApplyMessages = append(td.Vector.ApplyMessages, schema.Message{Bytes: chain.MustSerialize(msg)})
td.ApplyOk(msg)
var pcState paych_spec.State
td.GetActorState(paychAddr, &pcState)
assert.Equal(drivers.T, 1, len(pcState.LaneStates))
ls := pcState.LaneStates[0]
assert.Equal(drivers.T, pcAmount, ls.Redeemed)
assert.Equal(drivers.T, pcNonce, ls.Nonce)
assert.Equal(drivers.T, pcLane, ls.ID)
postroot := td.GetStateRoot()
td.Vector.CAR = td.MustMarshalGzippedCAR(preroot, postroot)
td.Vector.Pre.StateTree.RootCID = preroot
td.Vector.Post.StateTree.RootCID = postroot
// encode and output
fmt.Fprintln(os.Stdout, string(td.Vector.MustMarshalJSON()))
return nil
}("happy path update")
if err != nil {
return err
}
err = func(testname string) error {
td := drivers.NewTestDriver()
// create the payment channel
sender, _ := td.NewAccountActor(drivers.SECP, initialBal)
receiver, receiverID := td.NewAccountActor(drivers.SECP, initialBal)
paychAddr := chain.MustNewIDAddr(chain.MustIDFromAddress(receiverID) + 1)
initRet := td.ComputeInitActorExecReturn(sender, 0, 0, paychAddr)
preroot := td.GetStateRoot()
msg := td.MessageProducer.CreatePaymentChannelActor(sender, receiver, chain.Value(toSend), chain.Nonce(0))
td.Vector.ApplyMessages = append(td.Vector.ApplyMessages, schema.Message{Bytes: chain.MustSerialize(msg)})
td.ApplyExpect(
msg,
chain.MustSerialize(&initRet))
td.AssertBalance(paychAddr, toSend)
msg = td.MessageProducer.PaychUpdateChannelState(sender, paychAddr, &paych_spec.UpdateChannelStateParams{
Sv: paych_spec.SignedVoucher{
ChannelAddr: paychAddr,
TimeLockMin: abi_spec.ChainEpoch(0),
TimeLockMax: 0, // TimeLockMax set to 0 means no timeout
SecretPreimage: nil,
Extra: nil,
Lane: 1,
Nonce: 1,
Amount: toSend, // the amount that can be redeemed by receiver,
MinSettleHeight: 0,
Merges: nil,
Signature: &crypto_spec.Signature{
Type: crypto_spec.SigTypeBLS,
Data: []byte("signature goes here"),
},
},
}, chain.Nonce(1), chain.Value(big_spec.Zero()))
td.Vector.ApplyMessages = append(td.Vector.ApplyMessages, schema.Message{Bytes: chain.MustSerialize(msg)})
td.ApplyOk(msg)
// settle the payment channel so it may be collected
msg = td.MessageProducer.PaychSettle(receiver, paychAddr, nil, chain.Value(big_spec.Zero()), chain.Nonce(0))
td.Vector.ApplyMessages = append(td.Vector.ApplyMessages, schema.Message{Bytes: chain.MustSerialize(msg)})
settleResult := td.ApplyOk(msg)
// advance the epoch so the funds may be redeemed.
td.ExeCtx.Epoch += paych_spec.SettleDelay
msg = td.MessageProducer.PaychCollect(receiver, paychAddr, nil, chain.Nonce(1), chain.Value(big_spec.Zero()))
td.Vector.ApplyMessages = append(td.Vector.ApplyMessages, schema.Message{Epoch: &td.ExeCtx.Epoch, Bytes: chain.MustSerialize(msg)})
collectResult := td.ApplyOk(msg)
// receiver_balance = initial_balance + paych_send - settle_paych_msg_gas - collect_paych_msg_gas
td.AssertBalance(receiver, big_spec.Sub(big_spec.Sub(big_spec.Add(toSend, initialBal), settleResult.Receipt.GasUsed.Big()), collectResult.Receipt.GasUsed.Big()))
// the paych actor should have been deleted after the collect
td.AssertNoActor(paychAddr)
postroot := td.GetStateRoot()
td.Vector.CAR = td.MustMarshalGzippedCAR(preroot, postroot)
td.Vector.Pre.StateTree.RootCID = preroot
td.Vector.Post.StateTree.RootCID = postroot
// encode and output
fmt.Fprintln(os.Stdout, string(td.Vector.MustMarshalJSON()))
return nil
}("happy path collect")
if err != nil {
return err
}
return nil
}