temp fix test-vectors import cycle.
This commit is contained in:
parent
867469e9b3
commit
63cdbef219
231
conformance/chaos/actor.go
Normal file
231
conformance/chaos/actor.go
Normal file
@ -0,0 +1,231 @@
|
||||
package chaos
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
//go:generate go run ./gen
|
||||
|
||||
// Actor is a chaos actor. It implements a variety of illegal behaviours that
|
||||
// trigger violations of VM invariants. These behaviours are not found in
|
||||
// production code, but are important to test that the VM constraints are
|
||||
// properly enforced.
|
||||
//
|
||||
// The chaos actor is being incubated and its behaviour and ABI be standardised
|
||||
// shortly. Its CID is ChaosActorCodeCID, and its singleton address is 98 (Address).
|
||||
// It cannot be instantiated via the init actor, and its constructor panics.
|
||||
//
|
||||
// Test vectors relying on the chaos actor being deployed will carry selector
|
||||
// "chaos_actor:true".
|
||||
type Actor struct{}
|
||||
|
||||
// CallerValidationBranch is an enum used to select a branch in the
|
||||
// CallerValidation method.
|
||||
type CallerValidationBranch int64
|
||||
|
||||
const (
|
||||
CallerValidationBranchNone CallerValidationBranch = iota
|
||||
CallerValidationBranchTwice
|
||||
CallerValidationBranchAddrNilSet
|
||||
CallerValidationBranchTypeNilSet
|
||||
)
|
||||
|
||||
// MutateStateBranch is an enum used to select the type of state mutation to attempt.
|
||||
type MutateStateBranch int64
|
||||
|
||||
const (
|
||||
// MutateInTransaction legally mutates state within a transaction.
|
||||
MutateInTransaction MutateStateBranch = iota
|
||||
// MutateReadonly ILLEGALLY mutates readonly state.
|
||||
MutateReadonly
|
||||
// MutateAfterTransaction ILLEGALLY mutates state after a transaction.
|
||||
MutateAfterTransaction
|
||||
)
|
||||
|
||||
const (
|
||||
_ = 0 // skip zero iota value; first usage of iota gets 1.
|
||||
MethodCallerValidation = builtin.MethodConstructor + iota
|
||||
MethodCreateActor
|
||||
MethodResolveAddress
|
||||
// MethodDeleteActor is the identifier for the method that deletes this actor.
|
||||
MethodDeleteActor
|
||||
// MethodSend is the identifier for the method that sends a message to another actor.
|
||||
MethodSend
|
||||
// MethodMutateState is the identifier for the method that attempts to mutate
|
||||
// a state value in the actor.
|
||||
MethodMutateState
|
||||
)
|
||||
|
||||
// Exports defines the methods this actor exposes publicly.
|
||||
func (a Actor) Exports() []interface{} {
|
||||
return []interface{}{
|
||||
builtin.MethodConstructor: a.Constructor,
|
||||
MethodCallerValidation: a.CallerValidation,
|
||||
MethodCreateActor: a.CreateActor,
|
||||
MethodResolveAddress: a.ResolveAddress,
|
||||
MethodDeleteActor: a.DeleteActor,
|
||||
MethodSend: a.Send,
|
||||
MethodMutateState: a.MutateState,
|
||||
}
|
||||
}
|
||||
|
||||
var _ runtime.Invokee = Actor{}
|
||||
|
||||
// SendArgs are the arguments for the Send method.
|
||||
type SendArgs struct {
|
||||
To address.Address
|
||||
Value abi.TokenAmount
|
||||
Method abi.MethodNum
|
||||
Params []byte
|
||||
}
|
||||
|
||||
// SendReturn is the return values for the Send method.
|
||||
type SendReturn struct {
|
||||
Return runtime.CBORBytes
|
||||
Code exitcode.ExitCode
|
||||
}
|
||||
|
||||
// Send requests for this actor to send a message to an actor with the
|
||||
// passed parameters.
|
||||
func (a Actor) Send(rt runtime.Runtime, args *SendArgs) *SendReturn {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
ret, code := rt.Send(
|
||||
args.To,
|
||||
args.Method,
|
||||
runtime.CBORBytes(args.Params),
|
||||
args.Value,
|
||||
)
|
||||
var out runtime.CBORBytes
|
||||
if ret != nil {
|
||||
if err := ret.Into(&out); err != nil {
|
||||
rt.Abortf(exitcode.ErrIllegalState, "failed to unmarshal send return: %v", err)
|
||||
}
|
||||
}
|
||||
return &SendReturn{
|
||||
Return: out,
|
||||
Code: code,
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor will panic because the Chaos actor is a singleton.
|
||||
func (a Actor) Constructor(_ runtime.Runtime, _ *adt.EmptyValue) *adt.EmptyValue {
|
||||
panic("constructor should not be called; the Chaos actor is a singleton actor")
|
||||
}
|
||||
|
||||
// CallerValidation violates VM call validation constraints.
|
||||
//
|
||||
// CallerValidationBranchNone performs no validation.
|
||||
// CallerValidationBranchTwice validates twice.
|
||||
// CallerValidationBranchAddrNilSet validates against an empty caller
|
||||
// address set.
|
||||
// CallerValidationBranchTypeNilSet validates against an empty caller type set.
|
||||
func (a Actor) CallerValidation(rt runtime.Runtime, branch *typegen.CborInt) *adt.EmptyValue {
|
||||
switch CallerValidationBranch(*branch) {
|
||||
case CallerValidationBranchNone:
|
||||
case CallerValidationBranchTwice:
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
case CallerValidationBranchAddrNilSet:
|
||||
rt.ValidateImmediateCallerIs()
|
||||
case CallerValidationBranchTypeNilSet:
|
||||
rt.ValidateImmediateCallerType()
|
||||
default:
|
||||
panic("invalid branch passed to CallerValidation")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateActorArgs are the arguments to CreateActor.
|
||||
type CreateActorArgs struct {
|
||||
// UndefActorCID instructs us to use cid.Undef; we can't pass cid.Undef
|
||||
// in ActorCID because it doesn't serialize.
|
||||
UndefActorCID bool
|
||||
ActorCID cid.Cid
|
||||
|
||||
// UndefAddress is the same as UndefActorCID but for Address.
|
||||
UndefAddress bool
|
||||
Address address.Address
|
||||
}
|
||||
|
||||
// CreateActor creates an actor with the supplied CID and Address.
|
||||
func (a Actor) CreateActor(rt runtime.Runtime, args *CreateActorArgs) *adt.EmptyValue {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
|
||||
var (
|
||||
acid = args.ActorCID
|
||||
addr = args.Address
|
||||
)
|
||||
|
||||
if args.UndefActorCID {
|
||||
acid = cid.Undef
|
||||
}
|
||||
if args.UndefAddress {
|
||||
addr = address.Undef
|
||||
}
|
||||
|
||||
rt.CreateActor(acid, addr)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResolveAddressResponse holds the response of a call to runtime.ResolveAddress
|
||||
type ResolveAddressResponse struct {
|
||||
Address address.Address
|
||||
Success bool
|
||||
}
|
||||
|
||||
func (a Actor) ResolveAddress(rt runtime.Runtime, args *address.Address) *ResolveAddressResponse {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
|
||||
resolvedAddr, ok := rt.ResolveAddress(*args)
|
||||
if !ok {
|
||||
invalidAddr, _ := address.NewIDAddress(0)
|
||||
resolvedAddr = invalidAddr
|
||||
}
|
||||
return &ResolveAddressResponse{resolvedAddr, ok}
|
||||
}
|
||||
|
||||
// DeleteActor deletes the executing actor from the state tree, transferring any
|
||||
// balance to beneficiary.
|
||||
func (a Actor) DeleteActor(rt runtime.Runtime, beneficiary *address.Address) *adt.EmptyValue {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
rt.DeleteActor(*beneficiary)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MutateStateArgs specify the value to set on the state and the way in which
|
||||
// it should be attempted to be set.
|
||||
type MutateStateArgs struct {
|
||||
Value string
|
||||
Branch MutateStateBranch
|
||||
}
|
||||
|
||||
// MutateState attempts to mutate a state value in the actor.
|
||||
func (a Actor) MutateState(rt runtime.Runtime, args *MutateStateArgs) *adt.EmptyValue {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
var st State
|
||||
switch args.Branch {
|
||||
case MutateInTransaction:
|
||||
rt.State().Transaction(&st, func() {
|
||||
st.Value = args.Value
|
||||
})
|
||||
case MutateReadonly:
|
||||
rt.State().Readonly(&st)
|
||||
st.Value = args.Value
|
||||
case MutateAfterTransaction:
|
||||
rt.State().Transaction(&st, func() {
|
||||
st.Value = args.Value + "-in"
|
||||
})
|
||||
st.Value = args.Value
|
||||
default:
|
||||
panic("unknown mutation type")
|
||||
}
|
||||
return nil
|
||||
}
|
616
conformance/chaos/cbor_gen.go
Normal file
616
conformance/chaos/cbor_gen.go
Normal file
@ -0,0 +1,616 @@
|
||||
// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
|
||||
|
||||
package chaos
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
abi "github.com/filecoin-project/go-state-types/abi"
|
||||
exitcode "github.com/filecoin-project/go-state-types/exitcode"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var _ = xerrors.Errorf
|
||||
|
||||
var lengthBufState = []byte{130}
|
||||
|
||||
func (t *State) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufState); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Value (string) (string)
|
||||
if len(t.Value) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field t.Value was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len(t.Value))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string(t.Value)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Unmarshallable ([]*chaos.UnmarshallableCBOR) (slice)
|
||||
if len(t.Unmarshallable) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Slice value in field t.Unmarshallable was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajArray, uint64(len(t.Unmarshallable))); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range t.Unmarshallable {
|
||||
if err := v.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *State) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = State{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Value (string) (string)
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadStringBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Value = string(sval)
|
||||
}
|
||||
// t.Unmarshallable ([]*chaos.UnmarshallableCBOR) (slice)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.MaxLength {
|
||||
return fmt.Errorf("t.Unmarshallable: array too large (%d)", extra)
|
||||
}
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("expected cbor array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Unmarshallable = make([]*UnmarshallableCBOR, extra)
|
||||
}
|
||||
|
||||
for i := 0; i < int(extra); i++ {
|
||||
|
||||
var v UnmarshallableCBOR
|
||||
if err := v.UnmarshalCBOR(br); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Unmarshallable[i] = &v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufCreateActorArgs = []byte{132}
|
||||
|
||||
func (t *CreateActorArgs) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufCreateActorArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.UndefActorCID (bool) (bool)
|
||||
if err := cbg.WriteBool(w, t.UndefActorCID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.ActorCID (cid.Cid) (struct)
|
||||
|
||||
if err := cbg.WriteCidBuf(scratch, w, t.ActorCID); err != nil {
|
||||
return xerrors.Errorf("failed to write cid field t.ActorCID: %w", err)
|
||||
}
|
||||
|
||||
// t.UndefAddress (bool) (bool)
|
||||
if err := cbg.WriteBool(w, t.UndefAddress); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Address (address.Address) (struct)
|
||||
if err := t.Address.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CreateActorArgs) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = CreateActorArgs{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 4 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.UndefActorCID (bool) (bool)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajOther {
|
||||
return fmt.Errorf("booleans must be major type 7")
|
||||
}
|
||||
switch extra {
|
||||
case 20:
|
||||
t.UndefActorCID = false
|
||||
case 21:
|
||||
t.UndefActorCID = true
|
||||
default:
|
||||
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
|
||||
}
|
||||
// t.ActorCID (cid.Cid) (struct)
|
||||
|
||||
{
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.ActorCID: %w", err)
|
||||
}
|
||||
|
||||
t.ActorCID = c
|
||||
|
||||
}
|
||||
// t.UndefAddress (bool) (bool)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajOther {
|
||||
return fmt.Errorf("booleans must be major type 7")
|
||||
}
|
||||
switch extra {
|
||||
case 20:
|
||||
t.UndefAddress = false
|
||||
case 21:
|
||||
t.UndefAddress = true
|
||||
default:
|
||||
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
|
||||
}
|
||||
// t.Address (address.Address) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Address.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Address: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufResolveAddressResponse = []byte{130}
|
||||
|
||||
func (t *ResolveAddressResponse) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufResolveAddressResponse); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Address (address.Address) (struct)
|
||||
if err := t.Address.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Success (bool) (bool)
|
||||
if err := cbg.WriteBool(w, t.Success); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ResolveAddressResponse) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = ResolveAddressResponse{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Address (address.Address) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Address.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Address: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.Success (bool) (bool)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajOther {
|
||||
return fmt.Errorf("booleans must be major type 7")
|
||||
}
|
||||
switch extra {
|
||||
case 20:
|
||||
t.Success = false
|
||||
case 21:
|
||||
t.Success = true
|
||||
default:
|
||||
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufSendArgs = []byte{132}
|
||||
|
||||
func (t *SendArgs) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufSendArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.To (address.Address) (struct)
|
||||
if err := t.To.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Value (big.Int) (struct)
|
||||
if err := t.Value.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Method (abi.MethodNum) (uint64)
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Method)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Params ([]uint8) (slice)
|
||||
if len(t.Params) > cbg.ByteArrayMaxLen {
|
||||
return xerrors.Errorf("Byte array in field t.Params was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajByteString, uint64(len(t.Params))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := w.Write(t.Params[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *SendArgs) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = SendArgs{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 4 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.To (address.Address) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.To.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.To: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.Value (big.Int) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Value.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Value: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.Method (abi.MethodNum) (uint64)
|
||||
|
||||
{
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.Method = abi.MethodNum(extra)
|
||||
|
||||
}
|
||||
// t.Params ([]uint8) (slice)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.ByteArrayMaxLen {
|
||||
return fmt.Errorf("t.Params: byte array too large (%d)", extra)
|
||||
}
|
||||
if maj != cbg.MajByteString {
|
||||
return fmt.Errorf("expected byte array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Params = make([]uint8, extra)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(br, t.Params[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufSendReturn = []byte{130}
|
||||
|
||||
func (t *SendReturn) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufSendReturn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Return (runtime.CBORBytes) (slice)
|
||||
if len(t.Return) > cbg.ByteArrayMaxLen {
|
||||
return xerrors.Errorf("Byte array in field t.Return was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajByteString, uint64(len(t.Return))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := w.Write(t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Code (exitcode.ExitCode) (int64)
|
||||
if t.Code >= 0 {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Code)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.Code-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *SendReturn) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = SendReturn{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Return (runtime.CBORBytes) (slice)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.ByteArrayMaxLen {
|
||||
return fmt.Errorf("t.Return: byte array too large (%d)", extra)
|
||||
}
|
||||
if maj != cbg.MajByteString {
|
||||
return fmt.Errorf("expected byte array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Return = make([]uint8, extra)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(br, t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
// t.Code (exitcode.ExitCode) (int64)
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.Code = exitcode.ExitCode(extraI)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufMutateStateArgs = []byte{130}
|
||||
|
||||
func (t *MutateStateArgs) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufMutateStateArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Value (string) (string)
|
||||
if len(t.Value) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field t.Value was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len(t.Value))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string(t.Value)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Branch (chaos.MutateStateBranch) (int64)
|
||||
if t.Branch >= 0 {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Branch)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.Branch-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *MutateStateArgs) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = MutateStateArgs{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Value (string) (string)
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadStringBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Value = string(sval)
|
||||
}
|
||||
// t.Branch (chaos.MutateStateBranch) (int64)
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.Branch = MutateStateBranch(extraI)
|
||||
}
|
||||
return nil
|
||||
}
|
20
conformance/chaos/gen/gen.go
Normal file
20
conformance/chaos/gen/gen.go
Normal file
@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/lotus/conformance/chaos"
|
||||
|
||||
gen "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := gen.WriteTupleEncodersToFile("../cbor_gen.go", "chaos",
|
||||
chaos.State{},
|
||||
chaos.CreateActorArgs{},
|
||||
chaos.ResolveAddressResponse{},
|
||||
chaos.SendArgs{},
|
||||
chaos.SendReturn{},
|
||||
chaos.MutateStateArgs{},
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
29
conformance/chaos/ids.go
Normal file
29
conformance/chaos/ids.go
Normal file
@ -0,0 +1,29 @@
|
||||
package chaos
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/multiformats/go-multihash"
|
||||
)
|
||||
|
||||
// ChaosActorCodeCID is the CID by which this kind of actor will be identified.
|
||||
var ChaosActorCodeCID = func() cid.Cid {
|
||||
builder := cid.V1Builder{Codec: cid.Raw, MhType: multihash.IDENTITY}
|
||||
c, err := builder.Sum([]byte("fil/1/chaos"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}()
|
||||
|
||||
// Address is the singleton address of this actor. Its value is 98
|
||||
// (builtin.FirstNonSingletonActorId - 2), as 99 is reserved for the burnt funds
|
||||
// singleton.
|
||||
var Address = func() address.Address {
|
||||
// the address before the burnt funds address (99)
|
||||
addr, err := address.NewIDAddress(98)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return addr
|
||||
}()
|
32
conformance/chaos/state.go
Normal file
32
conformance/chaos/state.go
Normal file
@ -0,0 +1,32 @@
|
||||
package chaos
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// State is the state for the chaos actor used by some methods to invoke
|
||||
// behaviours in the vm or runtime.
|
||||
type State struct {
|
||||
// Value can be updated by chaos actor methods to test illegal state
|
||||
// mutations when the state is in readonly mode for example.
|
||||
Value string
|
||||
// Unmarshallable is a sentinel value. If the slice contains no values, the
|
||||
// State struct will encode as CBOR without issue. If the slice is non-nil,
|
||||
// CBOR encoding will fail.
|
||||
Unmarshallable []*UnmarshallableCBOR
|
||||
}
|
||||
|
||||
// UnmarshallableCBOR is a type that cannot be marshalled or unmarshalled to
|
||||
// CBOR despite implementing the CBORMarshaler and CBORUnmarshaler interface.
|
||||
type UnmarshallableCBOR struct{}
|
||||
|
||||
// UnmarshalCBOR will fail to unmarshal the value from CBOR.
|
||||
func (t *UnmarshallableCBOR) UnmarshalCBOR(io.Reader) error {
|
||||
return fmt.Errorf("failed to unmarshal cbor")
|
||||
}
|
||||
|
||||
// MarshalCBOR will fail to marshal the value to CBOR.
|
||||
func (t *UnmarshallableCBOR) MarshalCBOR(io.Writer) error {
|
||||
return fmt.Errorf("failed to marshal cbor")
|
||||
}
|
@ -9,12 +9,12 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/conformance/chaos"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/test-vectors/chaos"
|
||||
"github.com/filecoin-project/test-vectors/schema"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@ -96,13 +96,16 @@ func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, preroot
|
||||
var (
|
||||
messages []*types.Message
|
||||
results []*vm.ApplyRet
|
||||
|
||||
epoch = abi.ChainEpoch(tipset.Epoch)
|
||||
basefee = abi.NewTokenAmount(tipset.BaseFee.Int64())
|
||||
)
|
||||
|
||||
postcid, receiptsroot, err := sm.ApplyBlocks(context.Background(), parentEpoch, preroot, blocks, tipset.Epoch, vmRand, func(_ cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
|
||||
postcid, receiptsroot, err := sm.ApplyBlocks(context.Background(), parentEpoch, preroot, blocks, epoch, vmRand, func(_ cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
|
||||
messages = append(messages, msg)
|
||||
results = append(results, ret)
|
||||
return nil
|
||||
}, tipset.BaseFee)
|
||||
}, basefee)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -14,6 +14,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/ipfs/go-cid"
|
||||
ds "github.com/ipfs/go-datastore"
|
||||
|
||||
@ -177,7 +179,7 @@ func executeMessageVector(t *testing.T, vector *schema.TestVector) {
|
||||
|
||||
// Execute the message.
|
||||
var ret *vm.ApplyRet
|
||||
ret, root, err = driver.ExecuteMessage(bs, root, epoch, msg)
|
||||
ret, root, err = driver.ExecuteMessage(bs, root, abi.ChainEpoch(epoch), msg)
|
||||
if err != nil {
|
||||
t.Fatalf("fatal failure when executing message: %s", err)
|
||||
}
|
||||
@ -212,7 +214,7 @@ func executeTipsetVector(t *testing.T, vector *schema.TestVector) {
|
||||
var receiptsIdx int
|
||||
for i, ts := range vector.ApplyTipsets {
|
||||
ts := ts // capture
|
||||
ret, err := driver.ExecuteTipset(bs, tmpds, root, prevEpoch, &ts)
|
||||
ret, err := driver.ExecuteTipset(bs, tmpds, root, abi.ChainEpoch(prevEpoch), &ts)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to apply tipset %d message: %s", i, err)
|
||||
}
|
||||
@ -244,7 +246,7 @@ func executeTipsetVector(t *testing.T, vector *schema.TestVector) {
|
||||
func assertMsgResult(t *testing.T, expected *schema.Receipt, actual *vm.ApplyRet, label string) {
|
||||
t.Helper()
|
||||
|
||||
if expected, actual := expected.ExitCode, actual.ExitCode; expected != actual {
|
||||
if expected, actual := exitcode.ExitCode(expected.ExitCode), actual.ExitCode; expected != actual {
|
||||
t.Errorf("exit code of msg %s did not match; expected: %s, got: %s", label, expected, actual)
|
||||
}
|
||||
if expected, actual := expected.GasUsed, actual.GasUsed; expected != actual {
|
||||
|
4
go.mod
4
go.mod
@ -40,7 +40,7 @@ require (
|
||||
github.com/filecoin-project/specs-actors v0.9.7
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796
|
||||
github.com/filecoin-project/statediff v0.0.1
|
||||
github.com/filecoin-project/test-vectors v0.0.0-20200907193218-2c0739eccce6
|
||||
github.com/filecoin-project/test-vectors/schema v0.0.0-00010101000000-000000000000
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||
github.com/go-kit/kit v0.10.0
|
||||
github.com/google/uuid v1.1.1
|
||||
@ -133,5 +133,3 @@ replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v
|
||||
replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi
|
||||
|
||||
replace github.com/dgraph-io/badger/v2 => github.com/dgraph-io/badger/v2 v2.0.1-rc1.0.20200716180832-3ab515320794
|
||||
|
||||
replace github.com/filecoin-project/test-vectors => ./extern/test-vectors
|
||||
|
Loading…
Reference in New Issue
Block a user