Skip to content
This repository has been archived by the owner on Aug 22, 2023. It is now read-only.

test: actor abort #118

Merged
merged 7 commits into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions gen/builders/builder_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (b *MessageVectorBuilder) CommitApplies() {

for _, am := range b.Messages.All() {
// apply all messages that are pending application.
if am.Result == nil {
if !am.Applied {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this is a lot more explicit.

b.StateTracker.ApplyMessage(am)
}

Expand All @@ -112,19 +112,24 @@ func (b *MessageVectorBuilder) CommitApplies() {
Bytes: MustSerialize(am.Message),
Epoch: &epoch,
})
b.vector.Post.Receipts = append(b.vector.Post.Receipts, &schema.Receipt{
ExitCode: int64(am.Result.ExitCode),
ReturnValue: am.Result.Return,
GasUsed: am.Result.GasUsed,
})

// am.Result may still be nil if the message failed to be applied
if am.Result != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a more idiomatic way of doing this would be:

var receipt *schema.Receipt
if am.Result != nil {
    receipt = &schema.Receipt{
        ExitCode:    int64(am.Result.ExitCode),
        ReturnValue: am.Result.Return,
        GasUsed:     am.Result.GasUsed,
    }
}
b.vector.Post.Receipts = append(b.vector.Post.Receipts, receipt)

b.vector.Post.Receipts = append(b.vector.Post.Receipts, &schema.Receipt{
ExitCode: int64(am.Result.ExitCode),
ReturnValue: am.Result.Return,
GasUsed: am.Result.GasUsed,
})
} else {
b.vector.Post.Receipts = append(b.vector.Post.Receipts, nil)
}
}

// update the internal state.
b.PostRoot = b.StateTracker.CurrRoot
b.vector.Post.StateTree = &schema.StateTree{RootCID: b.PostRoot}
b.Stage = StageChecks
b.Assert.enterStage(StageChecks)

}

// Finish signals to the builder that the checks stage is complete and that the
Expand All @@ -146,8 +151,10 @@ func (b *MessageVectorBuilder) Finish(w io.Writer) {

msgs := b.Messages.All()
traces := make([]types.ExecutionTrace, 0, len(msgs))
for _, msgs := range msgs {
traces = append(traces, msgs.Result.ExecutionTrace)
for _, msg := range msgs {
if msg.Result != nil {
traces = append(traces, msg.Result.ExecutionTrace)
}
Comment on lines 153 to +157
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we want to make the traces a slice of pointers []*types.ExecutionTrace, and leave a nil element for each message that doesn't have a result?

}
b.vector.Diagnostics = EncodeTraces(traces)

Expand Down
4 changes: 4 additions & 0 deletions gen/builders/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ type ApplicableMessage struct {
Epoch abi.ChainEpoch
Message *types.Message
Result *vm.ApplyRet
// Applied is true if this message has already been applied. Note it's
// not safe to rely on non-nil Result as indication of application
// since applied messages may fail without a result.
Applied bool
}

func (m *Messages) Sugar() *sugarMsg {
Expand Down
10 changes: 10 additions & 0 deletions gen/builders/predicates.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ func MessageReturns(expect cbg.CBORMarshaler) ApplyRetPredicate {
}
}

// Nil returns an ApplyRetPredicate that passes if the message receipt is nil.
func Nil() ApplyRetPredicate {
return func(ret *vm.ApplyRet) error {
if ret != nil {
return fmt.Errorf("message receipt was not nil: %+v", ret)
}
return nil
}
}

// BalanceUpdated returns a ActorPredicate that checks whether the balance
// of the actor has been deducted the gas cost and the outgoing value transfers,
// and has been increased by the offset (or decreased, if the argument is negative).
Expand Down
10 changes: 8 additions & 2 deletions gen/builders/state_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,16 @@ func (st *StateTracker) Flush() cid.Cid {
// root, refreshes the state tree, and updates the underlying vector with the
// message and its receipt.
func (st *StateTracker) ApplyMessage(am *ApplicableMessage) {
var postRoot cid.Cid
var err error
am.Result, st.CurrRoot, err = st.Driver.ExecuteMessage(st.Stores.Blockstore, st.CurrRoot, am.Epoch, am.Message)
st.bc.Assert.NoError(err)

am.Applied = true
am.Result, postRoot, err = st.Driver.ExecuteMessage(st.Stores.Blockstore, st.CurrRoot, am.Epoch, am.Message)
if err != nil {
return
}

st.CurrRoot = postRoot
// replace the state tree.
st.StateTree, err = state.LoadStateTree(st.Stores.CBORStore, st.CurrRoot)
st.bc.Assert.NoError(err)
Expand Down
53 changes: 53 additions & 0 deletions gen/suites/vm_violations/actor_abort.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package main

import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/lotus/conformance/chaos"

. "github.com/filecoin-project/test-vectors/gen/builders"
)

func actorAbort(abortCode exitcode.ExitCode, msg string, expectedCode exitcode.ExitCode) func(*MessageVectorBuilder) {
return func(v *MessageVectorBuilder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))

sender := v.Actors.Account(address.SECP256K1, abi.NewTokenAmount(1_000_000_000_000))
v.CommitPreconditions()

v.Messages.Raw(
sender.ID,
chaos.Address,
chaos.MethodAbort,
MustSerialize(&chaos.AbortArgs{Code: abortCode, Message: msg}),
Value(big.Zero()),
Nonce(0),
)
v.CommitApplies()

v.Assert.LastMessageResultSatisfies(ExitCode(expectedCode))
}
}

func actorPanic(msg string) func(*MessageVectorBuilder) {
return func(v *MessageVectorBuilder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))

sender := v.Actors.Account(address.SECP256K1, abi.NewTokenAmount(1_000_000_000_000))
v.CommitPreconditions()

v.Messages.Raw(
sender.ID,
chaos.Address,
chaos.MethodAbort,
MustSerialize(&chaos.AbortArgs{NoCode: true, Message: msg}),
Value(big.Zero()),
Nonce(0),
)
v.CommitApplies()

v.Assert.LastMessageResultSatisfies(Nil())
}
}
69 changes: 69 additions & 0 deletions gen/suites/vm_violations/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/specs-actors/actors/builtin"
Expand Down Expand Up @@ -228,4 +229,72 @@ func main() {
MessageFunc: mutateState(valPfx+"after-transaction", chaos.MutateAfterTransaction, exitcode.SysErrorIllegalActor),
},
)

actorAbortVectors := []*VectorDef{
{
Metadata: &Metadata{
ID: "custom-exit-code",
Version: "v1",
Desc: "actors can abort with custom exit codes",
},
Selector: map[string]string{"chaos_actor": "true"},
MessageFunc: actorAbort(exitcode.FirstActorSpecificExitCode, "custom exit code abort", exitcode.FirstActorSpecificExitCode),
},
{
Metadata: &Metadata{
ID: "negative-exit-code",
Version: "v1",
Desc: "actors should not abort with negative exit codes",
},
Selector: map[string]string{"chaos_actor": "true"},
Mode: ModeLenientAssertions,
Hints: []string{schema.HintIncorrect, schema.HintNegate},
MessageFunc: actorAbort(-1, "negative exit code abort", exitcode.SysErrorIllegalActor),
},
{
Metadata: &Metadata{
ID: "no-exit-code",
Version: "v1",
Desc: "actor failure, a panic with no associated exit code",
},
Selector: map[string]string{"chaos_actor": "true"},
Mode: ModeLenientAssertions,
Hints: []string{schema.HintIncorrect, schema.HintNegate},
MessageFunc: actorPanic("no exit code abort"),
},
}

sysExitCodes := []exitcode.ExitCode{
exitcode.SysErrSenderInvalid,
exitcode.SysErrSenderStateInvalid,
exitcode.SysErrInvalidMethod,
exitcode.SysErrReserved1,
exitcode.SysErrInvalidReceiver,
exitcode.SysErrInsufficientFunds,
exitcode.SysErrOutOfGas,
exitcode.SysErrForbidden,
exitcode.SysErrorIllegalActor,
exitcode.SysErrorIllegalArgument,
exitcode.SysErrReserved2,
exitcode.SysErrReserved3,
exitcode.SysErrReserved4,
exitcode.SysErrReserved5,
exitcode.SysErrReserved6,
}

for _, xc := range sysExitCodes {
actorAbortVectors = append(actorAbortVectors, &VectorDef{
Metadata: &Metadata{
ID: fmt.Sprintf("system-exit-code-%d", xc),
Version: "v1",
Desc: fmt.Sprintf("actors should not abort with %s", xc),
},
Selector: map[string]string{"chaos_actor": "true"},
Mode: ModeLenientAssertions,
Hints: []string{schema.HintIncorrect, schema.HintNegate},
MessageFunc: actorAbort(xc, fmt.Sprintf("%s abort", xc), exitcode.SysErrorIllegalActor),
})
}

g.Group("actor_abort", actorAbortVectors...)
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ require (
github.com/filecoin-project/go-bitfield v0.2.0
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03
github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df
github.com/filecoin-project/lotus v0.6.2-0.20200908205025-63cdbef2197c
github.com/filecoin-project/lotus v0.6.2-0.20200909104030-159be5b543fd
github.com/filecoin-project/specs-actors v0.9.7
github.com/filecoin-project/test-vectors/schema v0.0.0-00010101000000-000000000000
github.com/filecoin-project/test-vectors/schema v0.0.1
github.com/ipfs/go-block-format v0.0.2
github.com/ipfs/go-blockservice v0.1.4-0.20200624145336-a978cec6e834
github.com/ipfs/go-cid v0.0.7
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ github.com/filecoin-project/lotus v0.4.3-0.20200819133134-a21234cd54d5/go.mod h1
github.com/filecoin-project/lotus v0.4.3-0.20200820203717-d1718369a182/go.mod h1:biFZPQ/YyQGfkHUmHMiaNf2hnD6zm1+OAXPQYQ61Zkg=
github.com/filecoin-project/lotus v0.6.2-0.20200908205025-63cdbef2197c h1:S5wcQLt8tFbh5q/ajPCawRgFPQm3CJ9LAy9/dwlNxtk=
github.com/filecoin-project/lotus v0.6.2-0.20200908205025-63cdbef2197c/go.mod h1:zK3h9oTAN5QSfcKq8JYmGPq7oIYGfwMQ9UKD5/yp5GU=
github.com/filecoin-project/lotus v0.6.2-0.20200909104030-159be5b543fd h1:6Reoqcam6sUmoeyUauwTHgnhYlzf7QAhXciIE1p//3s=
github.com/filecoin-project/lotus v0.6.2-0.20200909104030-159be5b543fd/go.mod h1:8SUeiDq172ZpVm4bLYfaulKLsYlYkl9ZI/IDxacP8M8=
github.com/filecoin-project/sector-storage v0.0.0-20200712023225-1d67dcfa3c15/go.mod h1:salgVdX7qeXFo/xaiEQE29J4pPkjn71T0kt0n+VDBzo=
github.com/filecoin-project/sector-storage v0.0.0-20200730050024-3ee28c3b6d9a/go.mod h1:oOawOl9Yk+qeytLzzIryjI8iRbqo+qzS6EEeElP4PWA=
github.com/filecoin-project/sector-storage v0.0.0-20200810171746-eac70842d8e0/go.mod h1:oOawOl9Yk+qeytLzzIryjI8iRbqo+qzS6EEeElP4PWA=
Expand Down
9 changes: 8 additions & 1 deletion schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,14 @@
"type": "array",
"additionalItems": false,
"items": {
"$ref": "#/definitions/receipt"
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/receipt"
}
]
}
},
"receipts_roots": {
Expand Down