Skip to content

Commit 3ed65b0

Browse files
committed
refactor: explicit AddressContext.EVMSemantic.{Caller,Self} fields
1 parent e35febe commit 3ed65b0

File tree

5 files changed

+94
-59
lines changed

5 files changed

+94
-59
lines changed

core/vm/contracts.libevm_test.go

Lines changed: 69 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,10 @@ func TestNewStatefulPrecompile(t *testing.T) {
228228
},
229229
wantAddresses: &libevm.AddressContext{
230230
Origin: eoa,
231-
Caller: caller,
232-
Self: precompile,
231+
EVMSemantic: libevm.CallerAndSelf{
232+
Caller: caller,
233+
Self: precompile,
234+
},
233235
},
234236
wantReadOnly: false,
235237
wantTransferValue: transferValue,
@@ -242,8 +244,10 @@ func TestNewStatefulPrecompile(t *testing.T) {
242244
},
243245
wantAddresses: &libevm.AddressContext{
244246
Origin: eoa,
245-
Caller: caller,
246-
Self: caller,
247+
EVMSemantic: libevm.CallerAndSelf{
248+
Caller: caller,
249+
Self: caller,
250+
},
247251
},
248252
wantReadOnly: false,
249253
wantTransferValue: transferValue,
@@ -256,8 +260,10 @@ func TestNewStatefulPrecompile(t *testing.T) {
256260
},
257261
wantAddresses: &libevm.AddressContext{
258262
Origin: eoa,
259-
Caller: eoa, // inherited from caller
260-
Self: caller,
263+
EVMSemantic: libevm.CallerAndSelf{
264+
Caller: eoa, // inherited from caller
265+
Self: caller,
266+
},
261267
},
262268
wantReadOnly: false,
263269
wantTransferValue: uint256.NewInt(0),
@@ -270,8 +276,10 @@ func TestNewStatefulPrecompile(t *testing.T) {
270276
},
271277
wantAddresses: &libevm.AddressContext{
272278
Origin: eoa,
273-
Caller: caller,
274-
Self: precompile,
279+
EVMSemantic: libevm.CallerAndSelf{
280+
Caller: caller,
281+
Self: precompile,
282+
},
275283
},
276284
wantReadOnly: true,
277285
wantTransferValue: uint256.NewInt(0),
@@ -527,7 +535,7 @@ func TestCanCreateContract(t *testing.T) {
527535
gasUsage := rng.Uint64n(gasLimit)
528536

529537
makeErr := func(cc *libevm.AddressContext, stateVal common.Hash) error {
530-
return fmt.Errorf("Origin: %v Caller: %v Contract: %v State: %v", cc.Origin, cc.Caller, cc.Self, stateVal)
538+
return fmt.Errorf("Origin: %v Caller: %v Contract: %v State: %v", cc.Origin, cc.EVMSemantic.Caller, cc.EVMSemantic.Self, stateVal)
531539
}
532540
hooks := &hookstest.Stub{
533541
CanCreateContractFn: func(cc *libevm.AddressContext, gas uint64, s libevm.StateReader) (uint64, error) {
@@ -555,14 +563,32 @@ func TestCanCreateContract(t *testing.T) {
555563
create: func(evm *vm.EVM) ([]byte, common.Address, uint64, error) {
556564
return evm.Create(vm.AccountRef(caller), code, gasLimit, uint256.NewInt(0))
557565
},
558-
wantErr: makeErr(&libevm.AddressContext{Origin: origin, Caller: caller, Self: create}, value),
566+
wantErr: makeErr(
567+
&libevm.AddressContext{
568+
Origin: origin,
569+
EVMSemantic: libevm.CallerAndSelf{
570+
Caller: caller,
571+
Self: create,
572+
},
573+
},
574+
value,
575+
),
559576
},
560577
{
561578
name: "Create2",
562579
create: func(evm *vm.EVM) ([]byte, common.Address, uint64, error) {
563580
return evm.Create2(vm.AccountRef(caller), code, gasLimit, uint256.NewInt(0), new(uint256.Int).SetBytes(salt[:]))
564581
},
565-
wantErr: makeErr(&libevm.AddressContext{Origin: origin, Caller: caller, Self: create2}, value),
582+
wantErr: makeErr(
583+
&libevm.AddressContext{
584+
Origin: origin,
585+
EVMSemantic: libevm.CallerAndSelf{
586+
Caller: caller,
587+
Self: create2,
588+
},
589+
},
590+
value,
591+
),
566592
},
567593
}
568594

@@ -663,8 +689,10 @@ func TestPrecompileMakeCall(t *testing.T) {
663689
want: statefulPrecompileOutput{
664690
Addresses: &libevm.AddressContext{
665691
Origin: eoa,
666-
Caller: sut,
667-
Self: dest,
692+
EVMSemantic: libevm.CallerAndSelf{
693+
Caller: sut,
694+
Self: dest,
695+
},
668696
},
669697
Input: precompileCallData,
670698
},
@@ -675,8 +703,10 @@ func TestPrecompileMakeCall(t *testing.T) {
675703
want: statefulPrecompileOutput{
676704
Addresses: &libevm.AddressContext{
677705
Origin: eoa,
678-
Caller: caller, // overridden by CallOption
679-
Self: dest,
706+
EVMSemantic: libevm.CallerAndSelf{
707+
Caller: caller, // overridden by CallOption
708+
Self: dest,
709+
},
680710
},
681711
Input: precompileCallData,
682712
},
@@ -686,8 +716,10 @@ func TestPrecompileMakeCall(t *testing.T) {
686716
want: statefulPrecompileOutput{
687717
Addresses: &libevm.AddressContext{
688718
Origin: eoa,
689-
Caller: caller, // SUT runs as its own caller because of CALLCODE
690-
Self: dest,
719+
EVMSemantic: libevm.CallerAndSelf{
720+
Caller: caller, // SUT runs as its own caller because of CALLCODE
721+
Self: dest,
722+
},
691723
},
692724
Input: precompileCallData,
693725
},
@@ -698,8 +730,10 @@ func TestPrecompileMakeCall(t *testing.T) {
698730
want: statefulPrecompileOutput{
699731
Addresses: &libevm.AddressContext{
700732
Origin: eoa,
701-
Caller: caller, // CallOption is a NOOP
702-
Self: dest,
733+
EVMSemantic: libevm.CallerAndSelf{
734+
Caller: caller, // CallOption is a NOOP
735+
Self: dest,
736+
},
703737
},
704738
Input: precompileCallData,
705739
},
@@ -709,8 +743,10 @@ func TestPrecompileMakeCall(t *testing.T) {
709743
want: statefulPrecompileOutput{
710744
Addresses: &libevm.AddressContext{
711745
Origin: eoa,
712-
Caller: caller, // as with CALLCODE
713-
Self: dest,
746+
EVMSemantic: libevm.CallerAndSelf{
747+
Caller: caller, // as with CALLCODE
748+
Self: dest,
749+
},
714750
},
715751
Input: precompileCallData,
716752
},
@@ -721,8 +757,10 @@ func TestPrecompileMakeCall(t *testing.T) {
721757
want: statefulPrecompileOutput{
722758
Addresses: &libevm.AddressContext{
723759
Origin: eoa,
724-
Caller: caller, // CallOption is a NOOP
725-
Self: dest,
760+
EVMSemantic: libevm.CallerAndSelf{
761+
Caller: caller, // CallOption is a NOOP
762+
Self: dest,
763+
},
726764
},
727765
Input: precompileCallData,
728766
},
@@ -732,8 +770,10 @@ func TestPrecompileMakeCall(t *testing.T) {
732770
want: statefulPrecompileOutput{
733771
Addresses: &libevm.AddressContext{
734772
Origin: eoa,
735-
Caller: sut,
736-
Self: dest,
773+
EVMSemantic: libevm.CallerAndSelf{
774+
Caller: sut,
775+
Self: dest,
776+
},
737777
},
738778
Input: precompileCallData,
739779
// This demonstrates that even though the precompile makes a
@@ -749,8 +789,10 @@ func TestPrecompileMakeCall(t *testing.T) {
749789
want: statefulPrecompileOutput{
750790
Addresses: &libevm.AddressContext{
751791
Origin: eoa,
752-
Caller: caller, // overridden by CallOption
753-
Self: dest,
792+
EVMSemantic: libevm.CallerAndSelf{
793+
Caller: caller, // overridden by CallOption
794+
Self: dest,
795+
},
754796
},
755797
Input: precompileCallData,
756798
ReadOnly: true,
@@ -816,26 +858,3 @@ func TestPrecompileCallWithTracer(t *testing.T) {
816858
require.NoErrorf(t, json.Unmarshal(gotJSON, &got), "json.Unmarshal(%T.GetResult(), %T)", tracer, &got)
817859
require.Equal(t, value, got[contract].Storage[zeroHash], "value loaded with SLOAD")
818860
}
819-
820-
//nolint:testableexamples // Including output would only make the example more complicated and hide the true intent
821-
func ExamplePrecompileEnvironment() {
822-
// To determine the actual caller of a precompile, as against the effective
823-
// caller (under EVM rules, as exposed by `Addresses().Caller`):
824-
actualCaller := func(env vm.PrecompileEnvironment) common.Address {
825-
if env.IncomingCallType() == vm.DelegateCall {
826-
// DelegateCall acts as if it were its own caller.
827-
return env.Addresses().Self
828-
}
829-
// CallCode could return either `Self` or `Caller` as it acts as its
830-
// caller but doesn't inherit the caller's caller as DelegateCall does.
831-
// Having it handled here is arbitrary from a behavioural perspective
832-
// and is done only to simplify the code.
833-
//
834-
// Call and StaticCall don't affect self/caller semantics in any way.
835-
return env.Addresses().Caller
836-
}
837-
838-
// actualCaller would typically be a top-level function. It's only a
839-
// variable to include it in this example function.
840-
_ = actualCaller
841-
}

core/vm/environment.libevm.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,10 @@ func (e *environment) ReadOnly() bool {
7979
func (e *environment) Addresses() *libevm.AddressContext {
8080
return &libevm.AddressContext{
8181
Origin: e.evm.Origin,
82-
Caller: e.self.CallerAddress,
83-
Self: e.self.Address(),
82+
EVMSemantic: libevm.CallerAndSelf{
83+
Caller: e.self.CallerAddress,
84+
Self: e.self.Address(),
85+
},
8486
}
8587
}
8688

core/vm/evm.libevm.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,15 @@ import (
2525
// canCreateContract is a convenience wrapper for calling the
2626
// [params.RulesHooks.CanCreateContract] hook.
2727
func (evm *EVM) canCreateContract(caller ContractRef, contractToCreate common.Address, gas uint64) (remainingGas uint64, _ error) {
28-
addrs := &libevm.AddressContext{Origin: evm.Origin, Caller: caller.Address(), Self: contractToCreate}
28+
addrs := &libevm.AddressContext{
29+
Origin: evm.Origin,
30+
EVMSemantic: libevm.CallerAndSelf{
31+
Caller: caller.Address(),
32+
Self: contractToCreate,
33+
},
34+
// The "raw" caller isn't guaranteed to be known if the caller is a
35+
// delegate so the `Raw` field is documented as always being nil.
36+
}
2937
gas, err := evm.chainRules.Hooks().CanCreateContract(addrs, gas, evm.StateDB)
3038

3139
// NOTE that this block only performs logging and that all paths propagate
@@ -34,8 +42,8 @@ func (evm *EVM) canCreateContract(caller ContractRef, contractToCreate common.Ad
3442
log.Debug(
3543
"Contract creation blocked by libevm hook",
3644
"origin", addrs.Origin,
37-
"caller", addrs.Caller,
38-
"contract", addrs.Self,
45+
"caller", addrs.EVMSemantic.Caller,
46+
"contract", addrs.EVMSemantic.Self,
3947
"hooks", log.TypeOf(evm.chainRules.Hooks()),
4048
"reason", err,
4149
)

libevm/libevm.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,12 @@ type StateReader interface {
6464
// With respect to contract creation, the Self address MAY be the predicted
6565
// address of the contract about to be deployed, which may not exist yet.
6666
type AddressContext struct {
67-
Origin common.Address // equivalent to vm.ORIGIN op code
68-
Caller common.Address // equivalent to vm.CALLER op code
69-
Self common.Address // equivalent to vm.ADDRESS op code
67+
Origin common.Address // always equivalent to vm.ORIGIN op code
68+
EVMSemantic CallerAndSelf
69+
Raw *CallerAndSelf
70+
}
71+
72+
type CallerAndSelf struct {
73+
Caller common.Address
74+
Self common.Address
7075
}

params/hooks.libevm.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ type RulesHooks interface {
6767
// by returning a nil (allowed) or non-nil (blocked) error.
6868
type RulesAllowlistHooks interface {
6969
// CanCreateContract is called after the deployer's nonce is incremented but
70-
// before all other state-modifying actions.
70+
// before all other state-modifying actions. The [libevm.AddressContext.Raw]
71+
// field will always be nil.
7172
CanCreateContract(_ *libevm.AddressContext, gas uint64, _ libevm.StateReader) (gasRemaining uint64, _ error)
7273
CanExecuteTransaction(from common.Address, to *common.Address, _ libevm.StateReader) error
7374
}

0 commit comments

Comments
 (0)