diff --git a/conformance/chaos/actor.go b/conformance/chaos/actor.go index bc68b086f..c56abcb8b 100644 --- a/conformance/chaos/actor.go +++ b/conformance/chaos/actor.go @@ -35,6 +35,8 @@ const ( CallerValidationBranchTwice // CallerValidationBranchIs causes caller validation against CallerValidationArgs.Addrs. CallerValidationBranchIs + // CallerValidationBranchIsReceiver causes validation that the caller was also the receiver. + CallerValidationBranchIsReceiver // CallerValidationBranchType causes caller validation against CallerValidationArgs.Types. CallerValidationBranchType ) @@ -146,6 +148,8 @@ func (a Actor) CallerValidation(rt runtime.Runtime, args *CallerValidationArgs) rt.ValidateImmediateCallerAcceptAny() case CallerValidationBranchIs: rt.ValidateImmediateCallerIs(args.Addrs...) + case CallerValidationBranchIsReceiver: + rt.ValidateImmediateCallerIs(rt.Message().Receiver()) case CallerValidationBranchType: rt.ValidateImmediateCallerType(args.Types...) default: diff --git a/conformance/chaos/actor_test.go b/conformance/chaos/actor_test.go index 2e899980d..c9d804309 100644 --- a/conformance/chaos/actor_test.go +++ b/conformance/chaos/actor_test.go @@ -2,6 +2,9 @@ package chaos import ( "context" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/ipfs/go-cid" "testing" "github.com/filecoin-project/go-state-types/abi" @@ -25,6 +28,108 @@ func TestSingleton(t *testing.T) { rt.Verify() } +func TestCallerValidationNone(t *testing.T) { + receiver := atesting.NewIDAddr(t, 100) + builder := mock.NewBuilder(context.Background(), receiver) + + rt := builder.Build(t) + var a Actor + + rt.Call(a.CallerValidation, &CallerValidationArgs{Branch: CallerValidationBranchNone}) + rt.Verify() +} + +func TestCallerValidationIs(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) + var a Actor + + caddrs := []address.Address{atesting.NewIDAddr(t, 101)} + + rt.ExpectValidateCallerAddr(caddrs...) + // FIXME: https://github.com/filecoin-project/specs-actors/pull/1155 + rt.ExpectAbort(exitcode.ErrForbidden, func() { + rt.Call(a.CallerValidation, &CallerValidationArgs{ + Branch: CallerValidationBranchIs, + Addrs: caddrs, + }) + }) + rt.Verify() + + rt.ExpectValidateCallerAddr(caller) + rt.Call(a.CallerValidation, &CallerValidationArgs{ + Branch: CallerValidationBranchIs, + Addrs: []address.Address{caller}, + }) + rt.Verify() +} + +func TestCallerValidationIsReceiver(t *testing.T) { + caller := atesting.NewIDAddr(t, 100) + receiver := atesting.NewIDAddr(t, 101) + builder := mock.NewBuilder(context.Background(), receiver) + + rt := builder.Build(t) + var a Actor + + rt.SetCaller(caller, builtin.AccountActorCodeID) + rt.ExpectValidateCallerAddr(receiver) + // FIXME: https://github.com/filecoin-project/specs-actors/pull/1155 + rt.ExpectAbort(exitcode.ErrForbidden, func() { + rt.Call(a.CallerValidation, &CallerValidationArgs{Branch: CallerValidationBranchIsReceiver}) + }) + rt.Verify() + + rt.SetCaller(receiver, builtin.AccountActorCodeID) + rt.ExpectValidateCallerAddr(receiver) + rt.Call(a.CallerValidation, &CallerValidationArgs{Branch: CallerValidationBranchIsReceiver}) + rt.Verify() +} + +func TestCallerValidationType(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) + var a Actor + + rt.ExpectValidateCallerType(builtin.CronActorCodeID) + // FIXME: https://github.com/filecoin-project/specs-actors/pull/1155 + rt.ExpectAbort(exitcode.ErrForbidden, func() { + rt.Call(a.CallerValidation, &CallerValidationArgs{ + Branch: CallerValidationBranchType, + Types: []cid.Cid{builtin.CronActorCodeID}, + }) + }) + rt.Verify() + + rt.ExpectValidateCallerType(builtin.AccountActorCodeID) + rt.Call(a.CallerValidation, &CallerValidationArgs{ + Branch: CallerValidationBranchType, + Types: []cid.Cid{builtin.AccountActorCodeID}, + }) + rt.Verify() +} + +func TestCallerValidationInvalidBranch(t *testing.T) { + receiver := atesting.NewIDAddr(t, 100) + builder := mock.NewBuilder(context.Background(), receiver) + + rt := builder.Build(t) + var a Actor + + rt.ExpectAssertionFailure("invalid branch passed to CallerValidation", func() { + rt.Call(a.CallerValidation, &CallerValidationArgs{Branch: -1}) + }) + rt.Verify() +} + func TestDeleteActor(t *testing.T) { receiver := atesting.NewIDAddr(t, 100) beneficiary := atesting.NewIDAddr(t, 101) @@ -118,6 +223,20 @@ func TestMutateStateReadonly(t *testing.T) { rt.Verify() } +func TestMutateStateInvalidBranch(t *testing.T) { + receiver := atesting.NewIDAddr(t, 100) + builder := mock.NewBuilder(context.Background(), receiver) + + rt := builder.Build(t) + var a Actor + + rt.ExpectValidateCallerAny() + rt.ExpectAssertionFailure("unknown mutation type", func() { + rt.Call(a.MutateState, &MutateStateArgs{Branch: -1}) + }) + rt.Verify() +} + func TestAbortWith(t *testing.T) { receiver := atesting.NewIDAddr(t, 100) builder := mock.NewBuilder(context.Background(), receiver)