Merge pull request #3733 from filecoin-project/feat/chaos-abort-2

This commit is contained in:
Raúl Kripalani 2020-09-10 14:20:34 +01:00 committed by GitHub
commit 747a7de168
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 139 additions and 0 deletions

View File

@ -62,6 +62,9 @@ const (
// MethodMutateState is the identifier for the method that attempts to mutate // MethodMutateState is the identifier for the method that attempts to mutate
// a state value in the actor. // a state value in the actor.
MethodMutateState MethodMutateState
// MethodAbortWith is the identifier for the method that panics optionally with
// a passed exit code.
MethodAbortWith
) )
// Exports defines the methods this actor exposes publicly. // Exports defines the methods this actor exposes publicly.
@ -74,6 +77,7 @@ func (a Actor) Exports() []interface{} {
MethodDeleteActor: a.DeleteActor, MethodDeleteActor: a.DeleteActor,
MethodSend: a.Send, MethodSend: a.Send,
MethodMutateState: a.MutateState, MethodMutateState: a.MutateState,
MethodAbortWith: a.AbortWith,
} }
} }
@ -230,3 +234,21 @@ func (a Actor) MutateState(rt runtime.Runtime, args *MutateStateArgs) *adt.Empty
} }
return nil return nil
} }
// AbortWithArgs are the arguments to the Actor.AbortWith method, specifying the
// exit code to (optionally) abort with and the message.
type AbortWithArgs struct {
Code exitcode.ExitCode
Message string
Uncontrolled bool
}
// AbortWith simply causes a panic with the passed exit code.
func (a Actor) AbortWith(rt runtime.Runtime, args *AbortWithArgs) *adt.EmptyValue {
if args.Uncontrolled { // uncontrolled abort: directly panic
panic(args.Message)
} else {
rt.Abortf(args.Code, args.Message)
}
return nil
}

View File

@ -614,3 +614,119 @@ func (t *MutateStateArgs) UnmarshalCBOR(r io.Reader) error {
} }
return nil return nil
} }
var lengthBufAbortWithArgs = []byte{131}
func (t *AbortWithArgs) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write(lengthBufAbortWithArgs); err != nil {
return err
}
scratch := make([]byte, 9)
// 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
}
}
// t.Message (string) (string)
if len(t.Message) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.Message was too long")
}
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len(t.Message))); err != nil {
return err
}
if _, err := io.WriteString(w, string(t.Message)); err != nil {
return err
}
// t.Uncontrolled (bool) (bool)
if err := cbg.WriteBool(w, t.Uncontrolled); err != nil {
return err
}
return nil
}
func (t *AbortWithArgs) UnmarshalCBOR(r io.Reader) error {
*t = AbortWithArgs{}
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 != 3 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// 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)
}
// t.Message (string) (string)
{
sval, err := cbg.ReadStringBuf(br, scratch)
if err != nil {
return err
}
t.Message = string(sval)
}
// t.Uncontrolled (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.Uncontrolled = false
case 21:
t.Uncontrolled = true
default:
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
}
return nil
}

View File

@ -14,6 +14,7 @@ func main() {
chaos.SendArgs{}, chaos.SendArgs{},
chaos.SendReturn{}, chaos.SendReturn{},
chaos.MutateStateArgs{}, chaos.MutateStateArgs{},
chaos.AbortWithArgs{},
); err != nil { ); err != nil {
panic(err) panic(err)
} }