Merge pull request #3861 from filecoin-project/feat/chaos-inspect-runtime

This commit is contained in:
Raúl Kripalani 2020-09-16 15:50:08 +01:00 committed by GitHub
commit 5a8ee0dd2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 201 additions and 3 deletions

View File

@ -64,6 +64,9 @@ const (
// MethodAbortWith is the identifier for the method that panics optionally with
// a passed exit code.
MethodAbortWith
// MethodInspectRuntime is the identifier for the method that returns the
// current runtime values.
MethodInspectRuntime
)
// Exports defines the methods this actor exposes publicly.
@ -77,6 +80,7 @@ func (a Actor) Exports() []interface{} {
MethodSend: a.Send,
MethodMutateState: a.MutateState,
MethodAbortWith: a.AbortWith,
MethodInspectRuntime: a.InspectRuntime,
}
}
@ -247,3 +251,28 @@ func (a Actor) AbortWith(rt runtime.Runtime, args *AbortWithArgs) *abi.EmptyValu
}
return nil
}
// InspectRuntimeReturn is the return value for the Actor.InspectRuntime method.
type InspectRuntimeReturn struct {
Caller address.Address
Receiver address.Address
ValueReceived abi.TokenAmount
CurrEpoch abi.ChainEpoch
CurrentBalance abi.TokenAmount
State State
}
// InspectRuntime returns a copy of the serializable values available in the Runtime.
func (a Actor) InspectRuntime(rt runtime.Runtime, _ *abi.EmptyValue) *InspectRuntimeReturn {
rt.ValidateImmediateCallerAcceptAny()
var st State
rt.StateReadonly(&st)
return &InspectRuntimeReturn{
Caller: rt.Caller(),
Receiver: rt.Receiver(),
ValueReceived: rt.ValueReceived(),
CurrEpoch: rt.CurrEpoch(),
CurrentBalance: rt.CurrentBalance(),
State: st,
}
}

View File

@ -6,6 +6,7 @@ import (
"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/support/mock"
atesting "github.com/filecoin-project/specs-actors/support/testing"
)
@ -151,3 +152,28 @@ func TestAbortWithUncontrolled(t *testing.T) {
})
rt.Verify()
}
func TestInspectRuntime(t *testing.T) {
caller := atesting.NewIDAddr(t, 100)
receiver := atesting.NewIDAddr(t, 101)
builder := mock.NewBuilder(context.Background(), receiver)
rt := builder.Build(t)
rt.SetCaller(caller, builtin.AccountActorCodeID)
rt.StateCreate(&State{})
var a Actor
rt.ExpectValidateCallerAny()
ret := rt.Call(a.InspectRuntime, abi.Empty)
rtr, ok := ret.(*InspectRuntimeReturn)
if !ok {
t.Fatal("invalid return value")
}
if rtr.Caller != caller {
t.Fatal("unexpected runtime caller")
}
if rtr.Receiver != receiver {
t.Fatal("unexpected runtime receiver")
}
rt.Verify()
}

View File

@ -6,10 +6,10 @@ import (
"fmt"
"io"
abi "github.com/filecoin-project/go-state-types/abi"
exitcode "github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/exitcode"
cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors"
"golang.org/x/xerrors"
)
var _ = xerrors.Errorf
@ -730,3 +730,145 @@ func (t *AbortWithArgs) UnmarshalCBOR(r io.Reader) error {
}
return nil
}
var lengthBufInspectRuntimeReturn = []byte{134}
func (t *InspectRuntimeReturn) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write(lengthBufInspectRuntimeReturn); err != nil {
return err
}
scratch := make([]byte, 9)
// t.Caller (address.Address) (struct)
if err := t.Caller.MarshalCBOR(w); err != nil {
return err
}
// t.Receiver (address.Address) (struct)
if err := t.Receiver.MarshalCBOR(w); err != nil {
return err
}
// t.ValueReceived (big.Int) (struct)
if err := t.ValueReceived.MarshalCBOR(w); err != nil {
return err
}
// t.CurrEpoch (abi.ChainEpoch) (int64)
if t.CurrEpoch >= 0 {
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.CurrEpoch)); err != nil {
return err
}
} else {
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.CurrEpoch-1)); err != nil {
return err
}
}
// t.CurrentBalance (big.Int) (struct)
if err := t.CurrentBalance.MarshalCBOR(w); err != nil {
return err
}
// t.State (chaos.State) (struct)
if err := t.State.MarshalCBOR(w); err != nil {
return err
}
return nil
}
func (t *InspectRuntimeReturn) UnmarshalCBOR(r io.Reader) error {
*t = InspectRuntimeReturn{}
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 != 6 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.Caller (address.Address) (struct)
{
if err := t.Caller.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.Caller: %w", err)
}
}
// t.Receiver (address.Address) (struct)
{
if err := t.Receiver.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.Receiver: %w", err)
}
}
// t.ValueReceived (big.Int) (struct)
{
if err := t.ValueReceived.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.ValueReceived: %w", err)
}
}
// t.CurrEpoch (abi.ChainEpoch) (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.CurrEpoch = abi.ChainEpoch(extraI)
}
// t.CurrentBalance (big.Int) (struct)
{
if err := t.CurrentBalance.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.CurrentBalance: %w", err)
}
}
// t.State (chaos.State) (struct)
{
if err := t.State.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.State: %w", err)
}
}
return nil
}

View File

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