From 7d118e1b12caac395119ff368ec62fcfdbf9ebb4 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Thu, 6 Aug 2020 18:57:15 +0200 Subject: [PATCH] fix two disabled tests (#207) --- tvx/drivers/dummy_testingt.go | 2 +- tvx/drivers/state_driver.go | 34 +-- tvx/drivers/test_driver.go | 82 +++---- tvx/drivers/tipset_message_producer.go | 14 +- tvx/exec_lotus.go | 7 +- tvx/extract_msg.go | 2 +- tvx/lotus/driver.go | 6 +- tvx/schema.go | 11 +- ...ctor.go => suite_messages_create_actor.go} | 7 +- ... => suite_messages_message_application.go} | 31 ++- tvx/suite_messages_paych.go | 228 ++++++++++++++++++ 11 files changed, 330 insertions(+), 94 deletions(-) rename tvx/{messages_create_actor.go => suite_messages_create_actor.go} (96%) rename tvx/{messages_message_application.go => suite_messages_message_application.go} (90%) create mode 100644 tvx/suite_messages_paych.go diff --git a/tvx/drivers/dummy_testingt.go b/tvx/drivers/dummy_testingt.go index 269dbfe68..c2d542d2b 100644 --- a/tvx/drivers/dummy_testingt.go +++ b/tvx/drivers/dummy_testingt.go @@ -5,7 +5,7 @@ import ( "os" ) -var t dummyTestingT +var T dummyTestingT type dummyTestingT struct{} diff --git a/tvx/drivers/state_driver.go b/tvx/drivers/state_driver.go index 2105eaff3..616c748a0 100644 --- a/tvx/drivers/state_driver.go +++ b/tvx/drivers/state_driver.go @@ -65,19 +65,19 @@ func (d *StateDriver) Randomness() RandomnessSource { func (d *StateDriver) GetState(c cid.Cid, out cbg.CBORUnmarshaler) { err := d.st.StoreGet(c, out) - require.NoError(t, err) + require.NoError(T, err) } func (d *StateDriver) PutState(in cbg.CBORMarshaler) cid.Cid { c, err := d.st.StorePut(in) - require.NoError(t, err) + require.NoError(T, err) return c } func (d *StateDriver) GetActorState(actorAddr address.Address, out cbg.CBORUnmarshaler) { actor, err := d.State().Actor(actorAddr) - require.NoError(t, err) - require.NotNil(t, actor) + require.NoError(T, err) + require.NotNil(T, actor) d.GetState(actor.Head(), out) } @@ -91,22 +91,22 @@ func (d *StateDriver) NewAccountActor(addrType address.Protocol, balanceAttoFil case address.BLS: addr = d.w.NewBLSAccountAddress() default: - require.FailNowf(t, "unsupported address", "protocol for account actor: %v", addrType) + require.FailNowf(T, "unsupported address", "protocol for account actor: %v", addrType) } _, idAddr, err := d.st.CreateActor(builtin_spec.AccountActorCodeID, addr, balanceAttoFil, &account_spec.State{Address: addr}) - require.NoError(t, err) + require.NoError(T, err) d.actorIDMap[idAddr] = addr return addr, idAddr } func (d *StateDriver) ActorPubKey(idAddress address.Address) address.Address { if idAddress.Protocol() != address.ID { - t.Fatalf("ActorPubKey methods expects ID protocol address. actual: %v", idAddress.Protocol()) + T.Fatalf("ActorPubKey methods expects ID protocol address. actual: %v", idAddress.Protocol()) } pubkeyAddr, found := d.actorIDMap[idAddress] if !found { - t.Fatalf("Failed to find pubkey address for: %s", idAddress) + T.Fatalf("Failed to find pubkey address for: %s", idAddress) } return pubkeyAddr } @@ -131,9 +131,9 @@ func (d *StateDriver) newMinerAccountActor(sealProofType abi_spec.RegisteredSeal } ss, err := sealProofType.SectorSize() - require.NoError(t, err) + require.NoError(T, err) ps, err := sealProofType.WindowPoStPartitionSectors() - require.NoError(t, err) + require.NoError(T, err) mi := &miner_spec.MinerInfo{ Owner: minerOwnerID, Worker: minerWorkerID, @@ -145,15 +145,15 @@ func (d *StateDriver) newMinerAccountActor(sealProofType abi_spec.RegisteredSeal WindowPoStPartitionSectors: ps, } mc, err := d.st.StorePut(mi) - require.NoError(t, err) + require.NoError(T, err) // create the miner actor s.t. it exists in the init actors map minerState, err := miner_spec.ConstructState(mc, periodBoundary, EmptyBitfieldCid, EmptyArrayCid, EmptyMapCid, EmptyDeadlinesCid) - require.NoError(t, err) + require.NoError(T, err) _, minerActorIDAddr, err := d.State().CreateActor(builtin_spec.StorageMinerActorCodeID, minerActorAddrs.RobustAddress, big_spec.Zero(), minerState) - require.NoError(t, err) - require.Equal(t, expectedMinerActorIDAddress, minerActorIDAddr) + require.NoError(T, err) + require.Equal(T, expectedMinerActorIDAddress, minerActorIDAddr) // a miner actor has been created, exists in the state tree, and has an entry in the init actor. // next update the storage power actor to track the miner @@ -163,18 +163,18 @@ func (d *StateDriver) newMinerAccountActor(sealProofType abi_spec.RegisteredSeal // set the miners claim hm, err := adt_spec.AsMap(AsStore(d.State()), spa.Claims) - require.NoError(t, err) + require.NoError(T, err) // add claim for the miner err = hm.Put(adt_spec.AddrKey(minerActorIDAddr), &power_spec.Claim{ RawBytePower: abi_spec.NewStoragePower(0), QualityAdjPower: abi_spec.NewTokenAmount(0), }) - require.NoError(t, err) + require.NoError(T, err) // save the claim spa.Claims, err = hm.Root() - require.NoError(t, err) + require.NoError(T, err) // update miner count spa.MinerCount += 1 diff --git a/tvx/drivers/test_driver.go b/tvx/drivers/test_driver.go index a6872eebb..4f3406e87 100644 --- a/tvx/drivers/test_driver.go +++ b/tvx/drivers/test_driver.go @@ -219,11 +219,11 @@ func NewTestDriver() *TestDriver { sd := NewStateDriver(stateWrapper, newKeyManager()) err := initializeStoreWithAdtRoots(AsStore(sd.st)) - require.NoError(t, err) + require.NoError(T, err) for _, acts := range DefaultBuiltinActorsState { _, _, err := sd.State().CreateActor(acts.Code, acts.Addr, acts.Balance, acts.State) - require.NoError(t, err) + require.NoError(T, err) } minerActorIDAddr := sd.newMinerAccountActor(TestSealProofType, abi_spec.ChainEpoch(0)) @@ -297,12 +297,12 @@ func (td *TestDriver) applyMessageExpectCodeAndReturn(msg *types.Message, code e func (td *TestDriver) applyMessage(msg *types.Message) (result vtypes.ApplyMessageResult) { defer func() { if r := recover(); r != nil { - t.Fatalf("message application panicked: %v", r) + T.Fatalf("message application panicked: %v", r) } }() result, err := td.applier.ApplyMessage(td.ExeCtx.Epoch, msg) - require.NoError(t, err) + require.NoError(T, err) return result } @@ -336,75 +336,75 @@ func (td *TestDriver) applyMessageSignedExpectCodeAndReturn(msg *types.Message, func (td *TestDriver) applyMessageSigned(msg *types.Message) (result vtypes.ApplyMessageResult) { defer func() { if r := recover(); r != nil { - t.Fatalf("message application panicked: %v", r) + T.Fatalf("message application panicked: %v", r) } }() serMsg, err := msg.Serialize() - require.NoError(t, err) + require.NoError(T, err) msgSig, err := td.Wallet().Sign(msg.From, serMsg) - require.NoError(t, err) + require.NoError(T, err) smsgs := &types.SignedMessage{ Message: *msg, Signature: msgSig, } result, err = td.applier.ApplySignedMessage(td.ExeCtx.Epoch, smsgs) - require.NoError(t, err) + require.NoError(T, err) return result } func (td *TestDriver) validateResult(result vtypes.ApplyMessageResult, code exitcode.ExitCode, retval []byte) { if td.Config.ValidateExitCode() { - assert.Equal(t, code, result.Receipt.ExitCode, "Expected ExitCode: %s Actual ExitCode: %s", code.Error(), result.Receipt.ExitCode.Error()) + assert.Equal(T, code, result.Receipt.ExitCode, "Expected ExitCode: %s Actual ExitCode: %s", code.Error(), result.Receipt.ExitCode.Error()) } if td.Config.ValidateReturnValue() { - assert.Equal(t, retval, result.Receipt.ReturnValue, "Expected ReturnValue: %v Actual ReturnValue: %v", retval, result.Receipt.ReturnValue) + assert.Equal(T, retval, result.Receipt.ReturnValue, "Expected ReturnValue: %v Actual ReturnValue: %v", retval, result.Receipt.ReturnValue) } } func (td *TestDriver) AssertNoActor(addr address.Address) { _, err := td.State().Actor(addr) - assert.Error(t, err, "expected no such actor %s", addr) + assert.Error(T, err, "expected no such actor %s", addr) } func (td *TestDriver) GetBalance(addr address.Address) abi_spec.TokenAmount { actr, err := td.State().Actor(addr) - require.NoError(t, err) + require.NoError(T, err) return actr.Balance() } func (td *TestDriver) GetHead(addr address.Address) cid.Cid { actr, err := td.State().Actor(addr) - require.NoError(t, err) + require.NoError(T, err) return actr.Head() } // AssertBalance checks an actor has an expected balance. func (td *TestDriver) AssertBalance(addr address.Address, expected abi_spec.TokenAmount) { actr, err := td.State().Actor(addr) - require.NoError(t, err) - assert.Equal(t, expected, actr.Balance(), fmt.Sprintf("expected actor %s balance: %s, actual balance: %s", addr, expected, actr.Balance())) + require.NoError(T, err) + assert.Equal(T, expected, actr.Balance(), fmt.Sprintf("expected actor %s balance: %s, actual balance: %s", addr, expected, actr.Balance())) } // Checks an actor's balance and callSeqNum. func (td *TestDriver) AssertActor(addr address.Address, balance abi_spec.TokenAmount, callSeqNum uint64) { actr, err := td.State().Actor(addr) - require.NoError(t, err) - assert.Equal(t, balance, actr.Balance(), fmt.Sprintf("expected actor %s balance: %s, actual balance: %s", addr, balance, actr.Balance())) - assert.Equal(t, callSeqNum, actr.CallSeqNum(), fmt.Sprintf("expected actor %s callSeqNum: %d, actual : %d", addr, callSeqNum, actr.CallSeqNum())) + require.NoError(T, err) + assert.Equal(T, balance, actr.Balance(), fmt.Sprintf("expected actor %s balance: %s, actual balance: %s", addr, balance, actr.Balance())) + assert.Equal(T, callSeqNum, actr.CallSeqNum(), fmt.Sprintf("expected actor %s callSeqNum: %d, actual : %d", addr, callSeqNum, actr.CallSeqNum())) } func (td *TestDriver) AssertHead(addr address.Address, expected cid.Cid) { head := td.GetHead(addr) - assert.Equal(t, expected, head, "expected actor %s head %s, actual %s", addr, expected, head) + assert.Equal(T, expected, head, "expected actor %s head %s, actual %s", addr, expected, head) } func (td *TestDriver) AssertBalanceCallback(addr address.Address, thing func(actorBalance abi_spec.TokenAmount) bool) { actr, err := td.State().Actor(addr) - require.NoError(t, err) - assert.True(t, thing(actr.Balance())) + require.NoError(T, err) + assert.True(T, thing(actr.Balance())) } func (td *TestDriver) AssertMultisigTransaction(multisigAddr address.Address, txnID multisig_spec.TxnID, txn multisig_spec.Transaction) { @@ -412,14 +412,14 @@ func (td *TestDriver) AssertMultisigTransaction(multisigAddr address.Address, tx td.GetActorState(multisigAddr, &msState) txnMap, err := adt_spec.AsMap(AsStore(td.State()), msState.PendingTxns) - require.NoError(t, err) + require.NoError(T, err) var actualTxn multisig_spec.Transaction found, err := txnMap.Get(txnID, &actualTxn) - require.NoError(t, err) - require.True(t, found) + require.NoError(T, err) + require.True(T, found) - assert.Equal(t, txn, actualTxn) + assert.Equal(T, txn, actualTxn) } func (td *TestDriver) AssertMultisigContainsTransaction(multisigAddr address.Address, txnID multisig_spec.TxnID, contains bool) { @@ -427,28 +427,28 @@ func (td *TestDriver) AssertMultisigContainsTransaction(multisigAddr address.Add td.GetActorState(multisigAddr, &msState) txnMap, err := adt_spec.AsMap(AsStore(td.State()), msState.PendingTxns) - require.NoError(t, err) + require.NoError(T, err) var actualTxn multisig_spec.Transaction found, err := txnMap.Get(txnID, &actualTxn) - require.NoError(t, err) + require.NoError(T, err) - assert.Equal(t, contains, found) + assert.Equal(T, contains, found) } func (td *TestDriver) AssertMultisigState(multisigAddr address.Address, expected multisig_spec.State) { var msState multisig_spec.State td.GetActorState(multisigAddr, &msState) - assert.NotNil(t, msState) - assert.Equal(t, expected.InitialBalance, msState.InitialBalance, fmt.Sprintf("expected InitialBalance: %v, actual InitialBalance: %v", expected.InitialBalance, msState.InitialBalance)) - assert.Equal(t, expected.NextTxnID, msState.NextTxnID, fmt.Sprintf("expected NextTxnID: %v, actual NextTxnID: %v", expected.NextTxnID, msState.NextTxnID)) - assert.Equal(t, expected.NumApprovalsThreshold, msState.NumApprovalsThreshold, fmt.Sprintf("expected NumApprovalsThreshold: %v, actual NumApprovalsThreshold: %v", expected.NumApprovalsThreshold, msState.NumApprovalsThreshold)) - assert.Equal(t, expected.StartEpoch, msState.StartEpoch, fmt.Sprintf("expected StartEpoch: %v, actual StartEpoch: %v", expected.StartEpoch, msState.StartEpoch)) - assert.Equal(t, expected.UnlockDuration, msState.UnlockDuration, fmt.Sprintf("expected UnlockDuration: %v, actual UnlockDuration: %v", expected.UnlockDuration, msState.UnlockDuration)) + assert.NotNil(T, msState) + assert.Equal(T, expected.InitialBalance, msState.InitialBalance, fmt.Sprintf("expected InitialBalance: %v, actual InitialBalance: %v", expected.InitialBalance, msState.InitialBalance)) + assert.Equal(T, expected.NextTxnID, msState.NextTxnID, fmt.Sprintf("expected NextTxnID: %v, actual NextTxnID: %v", expected.NextTxnID, msState.NextTxnID)) + assert.Equal(T, expected.NumApprovalsThreshold, msState.NumApprovalsThreshold, fmt.Sprintf("expected NumApprovalsThreshold: %v, actual NumApprovalsThreshold: %v", expected.NumApprovalsThreshold, msState.NumApprovalsThreshold)) + assert.Equal(T, expected.StartEpoch, msState.StartEpoch, fmt.Sprintf("expected StartEpoch: %v, actual StartEpoch: %v", expected.StartEpoch, msState.StartEpoch)) + assert.Equal(T, expected.UnlockDuration, msState.UnlockDuration, fmt.Sprintf("expected UnlockDuration: %v, actual UnlockDuration: %v", expected.UnlockDuration, msState.UnlockDuration)) for _, e := range expected.Signers { - assert.Contains(t, msState.Signers, e, fmt.Sprintf("expected Signer: %v, actual Signer: %v", e, msState.Signers)) + assert.Contains(T, msState.Signers, e, fmt.Sprintf("expected Signer: %v, actual Signer: %v", e, msState.Signers)) } } @@ -459,15 +459,15 @@ func (td *TestDriver) ComputeInitActorExecReturn(from address.Address, originato func computeInitActorExecReturn(from address.Address, originatorCallSeq uint64, newActorAddressCount uint64, expectedNewAddr address.Address) init_spec.ExecReturn { buf := new(bytes.Buffer) if from.Protocol() == address.ID { - t.Fatal("cannot compute init actor address return from ID address", from) + T.Fatal("cannot compute init actor address return from ID address", from) } - require.NoError(t, from.MarshalCBOR(buf)) - require.NoError(t, binary.Write(buf, binary.BigEndian, originatorCallSeq)) - require.NoError(t, binary.Write(buf, binary.BigEndian, newActorAddressCount)) + require.NoError(T, from.MarshalCBOR(buf)) + require.NoError(T, binary.Write(buf, binary.BigEndian, originatorCallSeq)) + require.NoError(T, binary.Write(buf, binary.BigEndian, newActorAddressCount)) out, err := address.NewActorAddress(buf.Bytes()) - require.NoError(t, err) + require.NoError(T, err) return init_spec.ExecReturn{ IDAddress: expectedNewAddr, @@ -482,7 +482,7 @@ func (td *TestDriver) MustCreateAndVerifyMultisigActor(nonce uint64, value abi_s code, retval) /* Assert the actor state was setup as expected */ pendingTxMapRoot, err := adt_spec.MakeEmptyMap(newMockStore()).Root() - require.NoError(t, err) + require.NoError(T, err) initialBalance := big_spec.Zero() startEpoch := abi_spec.ChainEpoch(0) if params.UnlockDuration > 0 { diff --git a/tvx/drivers/tipset_message_producer.go b/tvx/drivers/tipset_message_producer.go index 1b47bf8c1..bd2e48ce5 100644 --- a/tvx/drivers/tipset_message_producer.go +++ b/tvx/drivers/tipset_message_producer.go @@ -50,7 +50,7 @@ func (tb *TipSetMessageBuilder) apply() vtypes.ApplyTipSetResult { blks = append(blks, b.build()) } result, err := tb.driver.applier.ApplyTipSetMessages(tb.driver.ExeCtx.Epoch, blks, tb.driver.Randomness()) - require.NoError(t, err) + require.NoError(T, err) //t.driver.StateTracker.TrackResult(result) return result @@ -63,16 +63,16 @@ func (tb *TipSetMessageBuilder) validateResult(result vtypes.ApplyTipSetResult) } if len(result.Receipts) > len(expected) { - t.Fatalf("ApplyTipSetMessages returned more result than expected. Expected: %d, Actual: %d", len(expected), len(result.Receipts)) + T.Fatalf("ApplyTipSetMessages returned more result than expected. Expected: %d, Actual: %d", len(expected), len(result.Receipts)) return } for i := range result.Receipts { if tb.driver.Config.ValidateExitCode() { - assert.Equal(t, expected[i].ExitCode, result.Receipts[i].ExitCode, "Message Number: %d Expected ExitCode: %s Actual ExitCode: %s", i, expected[i].ExitCode.Error(), result.Receipts[i].ExitCode.Error()) + assert.Equal(T, expected[i].ExitCode, result.Receipts[i].ExitCode, "Message Number: %d Expected ExitCode: %s Actual ExitCode: %s", i, expected[i].ExitCode.Error(), result.Receipts[i].ExitCode.Error()) } if tb.driver.Config.ValidateReturnValue() { - assert.Equal(t, expected[i].ReturnVal, result.Receipts[i].ReturnValue, "Message Number: %d Expected ReturnValue: %v Actual ReturnValue: %v", i, expected[i].ReturnVal, result.Receipts[i].ReturnValue) + assert.Equal(T, expected[i].ReturnVal, result.Receipts[i].ReturnValue, "Message Number: %d Expected ReturnValue: %v Actual ReturnValue: %v", i, expected[i].ReturnVal, result.Receipts[i].ReturnValue) } } } @@ -177,13 +177,13 @@ func (bb *BlockBuilder) toSignedMessage(m *types.Message) *types.SignedMessage { from = bb.TD.ActorPubKey(from) } if from.Protocol() != address.SECP256K1 { - t.Fatalf("Invalid address for SECP signature, address protocol: %v", from.Protocol()) + T.Fatalf("Invalid address for SECP signature, address protocol: %v", from.Protocol()) } raw, err := m.Serialize() - require.NoError(t, err) + require.NoError(T, err) sig, err := bb.TD.Wallet().Sign(from, raw) - require.NoError(t, err) + require.NoError(T, err) return &types.SignedMessage{ Message: *m, diff --git a/tvx/exec_lotus.go b/tvx/exec_lotus.go index 61486f67e..4d191cf30 100644 --- a/tvx/exec_lotus.go +++ b/tvx/exec_lotus.go @@ -103,11 +103,16 @@ func executeTestVector(tv TestVector) error { for i, m := range tv.ApplyMessages { fmt.Printf("decoding message %v\n", i) - msg, err := types.DecodeMessage(m) + msg, err := types.DecodeMessage(m.Bytes) if err != nil { return err } + // add an epoch if we have set one + if m.Epoch != nil { + epoch = *m.Epoch + } + fmt.Printf("executing message %v\n", i) _, root, err = driver.ExecuteMessage(msg, root, bs, epoch) if err != nil { diff --git a/tvx/extract_msg.go b/tvx/extract_msg.go index eaf67d06a..3bf5f9a3b 100644 --- a/tvx/extract_msg.go +++ b/tvx/extract_msg.go @@ -196,7 +196,7 @@ func runExtractMsg(c *cli.Context) error { RootCID: preroot, }, }, - ApplyMessages: []HexEncodedBytes{msgBytes}, + ApplyMessages: []Message{{Bytes: msgBytes}}, Post: &Postconditions{ StateTree: &StateTree{ RootCID: postroot, diff --git a/tvx/lotus/driver.go b/tvx/lotus/driver.go index b8f09b33b..a97611f37 100644 --- a/tvx/lotus/driver.go +++ b/tvx/lotus/driver.go @@ -32,11 +32,11 @@ func (d *Driver) ExecuteMessage(msg *types.Message, preroot cid.Cid, bs blocksto actor, err := st.GetActor(msg.From) if err != nil { - return nil, cid.Undef, err + fmt.Println("from actor not found: ", msg.From) + } else { + fmt.Println("from actor found: ", actor) } - fmt.Println("from actor found: ", actor) - fmt.Println("creating vm") lvm, err := vm.NewVM(preroot, epoch, &vmRand{}, bs, mkFakedSigSyscalls(vm.Syscalls(ffiwrapper.ProofVerifier)), nil) if err != nil { diff --git a/tvx/schema.go b/tvx/schema.go index d91f38e82..be0a69ccc 100644 --- a/tvx/schema.go +++ b/tvx/schema.go @@ -102,9 +102,14 @@ type TestVector struct { // objects. CAR HexEncodedBytes `json:"car_hex"` - Pre *Preconditions `json:"preconditions"` - ApplyMessages []HexEncodedBytes `json:"apply_messages"` - Post *Postconditions `json:"postconditions"` + Pre *Preconditions `json:"preconditions"` + ApplyMessages []Message `json:"apply_messages"` + Post *Postconditions `json:"postconditions"` +} + +type Message struct { + Bytes HexEncodedBytes `json:"bytes"` + Epoch *abi.ChainEpoch `json:"epoch,omitempty"` } // Validate validates this test vector against the JSON schema, and applies diff --git a/tvx/messages_create_actor.go b/tvx/suite_messages_create_actor.go similarity index 96% rename from tvx/messages_create_actor.go rename to tvx/suite_messages_create_actor.go index c7547d16a..0003200e3 100644 --- a/tvx/messages_create_actor.go +++ b/tvx/suite_messages_create_actor.go @@ -28,6 +28,7 @@ func suiteMessages(c *cli.Context) error { err = multierror.Append(MessageTest_AccountActorCreation()) err = multierror.Append(MessageTest_InitActorSequentialIDAddressCreate()) err = multierror.Append(MessageTest_MessageApplicationEdgecases()) + err = multierror.Append(MessageTest_Paych()) return err.ErrorOrNil() } @@ -100,7 +101,7 @@ func MessageTest_AccountActorCreation() error { if err != nil { return err } - v.ApplyMessages = []HexEncodedBytes{b} + v.ApplyMessages = []Message{{Bytes: b}} result := td.ApplyFailure( msg, tc.expExitCode, @@ -165,7 +166,7 @@ func MessageTest_InitActorSequentialIDAddressCreate() error { if err != nil { return err } - v.ApplyMessages = append(v.ApplyMessages, b1) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: b1}) msg2 := td.MessageProducer.CreatePaymentChannelActor(sender, receiver, chain.Value(toSend), chain.Nonce(1)) td.ApplyExpect( @@ -177,7 +178,7 @@ func MessageTest_InitActorSequentialIDAddressCreate() error { if err != nil { return err } - v.ApplyMessages = append(v.ApplyMessages, b2) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: b2}) postroot := td.GetStateRoot() diff --git a/tvx/messages_message_application.go b/tvx/suite_messages_message_application.go similarity index 90% rename from tvx/messages_message_application.go rename to tvx/suite_messages_message_application.go index 2a5797b33..40ced19e3 100644 --- a/tvx/messages_message_application.go +++ b/tvx/suite_messages_message_application.go @@ -27,7 +27,7 @@ func MessageTest_MessageApplicationEdgecases() error { preroot := td.GetStateRoot() msg := td.MessageProducer.Transfer(alice, alice, chain.Value(transferAmnt), chain.Nonce(0), chain.GasPrice(1), chain.GasLimit(8)) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) td.ApplyFailure( msg, @@ -52,26 +52,25 @@ func MessageTest_MessageApplicationEdgecases() error { } err = func(testname string) error { - //TODO: this test is broken, fix later - return nil td := drivers.NewTestDriver() v := newEmptyMessageVector() - alice, _ := td.NewAccountActor(drivers.SECP, aliceBal) preroot := td.GetStateRoot() msg := td.MessageProducer.Transfer(alice, alice, chain.Value(transferAmnt), chain.Nonce(0), chain.GasPrice(10), chain.GasLimit(1)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) + // Expect Message application to fail due to lack of gas td.ApplyFailure( msg, exitcode_spec.SysErrOutOfGas) - // Expect Message application to fail due to lack of gas when sender is unknown unknown := chain.MustNewIDAddr(10000000) msg = td.MessageProducer.Transfer(unknown, alice, chain.Value(transferAmnt), chain.Nonce(0), chain.GasPrice(10), chain.GasLimit(1)) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) + // Expect Message application to fail due to lack of gas when sender is unknown td.ApplyFailure( msg, exitcode_spec.SysErrOutOfGas) @@ -110,7 +109,7 @@ func MessageTest_MessageApplicationEdgecases() error { newAccountA := chain.MustNewSECP256K1Addr("1") msg := td.MessageProducer.Transfer(alice, newAccountA, chain.Value(transferAmnt), chain.Nonce(aliceNonceF())) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) // get the "true" gas cost of applying the message result := td.ApplyOk(msg) @@ -121,7 +120,7 @@ func MessageTest_MessageApplicationEdgecases() error { newAccountB := chain.MustNewSECP256K1Addr("2") for tryGas := trueGas - gasStep; tryGas > 0; tryGas -= gasStep { msg := td.MessageProducer.Transfer(alice, newAccountB, chain.Value(transferAmnt), chain.Nonce(aliceNonceF()), chain.GasPrice(1), chain.GasLimit(tryGas)) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) td.ApplyFailure( msg, @@ -148,8 +147,6 @@ func MessageTest_MessageApplicationEdgecases() error { } err = func(testname string) error { - //TODO: this test is broken, fix me - return nil td := drivers.NewTestDriver() v := newEmptyMessageVector() @@ -159,7 +156,7 @@ func MessageTest_MessageApplicationEdgecases() error { preroot := td.GetStateRoot() msg := td.MessageProducer.Transfer(alice, alice, chain.Value(transferAmnt), chain.Nonce(1)) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) // Expect Message application to fail due to callseqnum being invalid: 1 instead of 0 td.ApplyFailure( @@ -168,7 +165,7 @@ func MessageTest_MessageApplicationEdgecases() error { unknown := chain.MustNewIDAddr(10000000) msg = td.MessageProducer.Transfer(unknown, alice, chain.Value(transferAmnt), chain.Nonce(1)) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) // Expect message application to fail due to unknow actor when call seq num is also incorrect td.ApplyFailure( @@ -221,7 +218,7 @@ func MessageTest_MessageApplicationEdgecases() error { preroot := td.GetStateRoot() msg := td.MessageProducer.CreatePaymentChannelActor(sender, receiver, chain.Value(toSend), chain.Nonce(0)) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) td.ApplyExpect( msg, @@ -242,7 +239,7 @@ func MessageTest_MessageApplicationEdgecases() error { Signature: pcSig, // construct with invalid signature }, }, chain.Nonce(1), chain.Value(big_spec.Zero())) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) // message application fails due to invalid argument (signature). td.ApplyFailure( @@ -278,7 +275,7 @@ func MessageTest_MessageApplicationEdgecases() error { msg := td.MessageProducer.MarketComputeDataCommitment(alice, alice, nil, chain.Nonce(0)) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) // message application fails because ComputeDataCommitment isn't defined // on the recipient actor @@ -317,7 +314,7 @@ func MessageTest_MessageApplicationEdgecases() error { unknownA := chain.MustNewIDAddr(10000000) msg := td.MessageProducer.Transfer(alice, unknownA, chain.Value(transferAmnt), chain.Nonce(0)) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) td.ApplyFailure( msg, @@ -326,7 +323,7 @@ func MessageTest_MessageApplicationEdgecases() error { // Sending a message to non-existing actor address must produce an error. unknownB := chain.MustNewActorAddr("1234") msg = td.MessageProducer.Transfer(alice, unknownB, chain.Value(transferAmnt), chain.Nonce(1)) - v.ApplyMessages = append(v.ApplyMessages, chain.MustSerialize(msg)) + v.ApplyMessages = append(v.ApplyMessages, Message{Bytes: chain.MustSerialize(msg)}) td.ApplyFailure( msg, diff --git a/tvx/suite_messages_paych.go b/tvx/suite_messages_paych.go new file mode 100644 index 000000000..9d8e3a0e6 --- /dev/null +++ b/tvx/suite_messages_paych.go @@ -0,0 +1,228 @@ +package main + +import ( + "encoding/json" + "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" +) + +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() + + v := newEmptyMessageVector() + + // 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)) + v.ApplyMessages = append(v.ApplyMessages, 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() + + v.CAR = td.MustMarshalGzippedCAR(preroot, postroot) + v.Pre.StateTree.RootCID = preroot + v.Post.StateTree.RootCID = postroot + + // encode and output + enc := json.NewEncoder(os.Stdout) + if err := enc.Encode(&v); err != nil { + return err + } + + return nil + }("happy path constructor") + if err != nil { + return err + } + + err = func(testname string) error { + td := drivers.NewTestDriver() + + v := newEmptyMessageVector() + + //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)) + v.ApplyMessages = append(v.ApplyMessages, 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())) + v.ApplyMessages = append(v.ApplyMessages, 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() + + v.CAR = td.MustMarshalGzippedCAR(preroot, postroot) + v.Pre.StateTree.RootCID = preroot + v.Post.StateTree.RootCID = postroot + + // encode and output + enc := json.NewEncoder(os.Stdout) + if err := enc.Encode(&v); err != nil { + return err + } + + return nil + }("happy path update") + if err != nil { + return err + } + + err = func(testname string) error { + td := drivers.NewTestDriver() + + v := newEmptyMessageVector() + + // 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)) + v.ApplyMessages = append(v.ApplyMessages, 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())) + + v.ApplyMessages = append(v.ApplyMessages, 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)) + v.ApplyMessages = append(v.ApplyMessages, 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())) + v.ApplyMessages = append(v.ApplyMessages, 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() + + v.CAR = td.MustMarshalGzippedCAR(preroot, postroot) + v.Pre.StateTree.RootCID = preroot + v.Post.StateTree.RootCID = postroot + + // encode and output + enc := json.NewEncoder(os.Stdout) + if err := enc.Encode(&v); err != nil { + return err + } + + return nil + }("happy path collect") + if err != nil { + return err + } + + return nil +}