@@ -120,6 +120,7 @@ type statefulPrecompileOutput struct {
120
120
func (o statefulPrecompileOutput ) String () string {
121
121
var lines []string
122
122
out := reflect .ValueOf (o )
123
+ FieldLoop:
123
124
for i , n := 0 , out .NumField (); i < n ; i ++ {
124
125
name := out .Type ().Field (i ).Name
125
126
fld := out .Field (i ).Interface ()
@@ -129,7 +130,12 @@ func (o statefulPrecompileOutput) String() string {
129
130
case []byte :
130
131
verb = "%#x"
131
132
case * libevm.AddressContext :
132
- verb = "%+v"
133
+ lines = append (
134
+ lines ,
135
+ fmt .Sprintf ("EVMSemantic addresses: %+v" , o .Addresses .EVMSemantic ),
136
+ fmt .Sprintf ("Raw addresses: %+v" , o .Addresses .Raw ),
137
+ )
138
+ continue FieldLoop
133
139
case vm.CallType :
134
140
verb = "%d (%[2]q)"
135
141
}
@@ -211,6 +217,13 @@ func TestNewStatefulPrecompile(t *testing.T) {
211
217
state .SetBalance (caller , new (uint256.Int ).Not (uint256 .NewInt (0 )))
212
218
evm .Origin = eoa
213
219
220
+ // By definition, the raw caller and self are the same for every test case,
221
+ // regardless of the incoming call type.
222
+ rawAddresses := libevm.CallerAndSelf {
223
+ Caller : caller ,
224
+ Self : precompile ,
225
+ }
226
+
214
227
tests := []struct {
215
228
name string
216
229
call func () ([]byte , uint64 , error )
@@ -227,9 +240,9 @@ func TestNewStatefulPrecompile(t *testing.T) {
227
240
return evm .Call (callerContract , precompile , input , gasLimit , transferValue )
228
241
},
229
242
wantAddresses : & libevm.AddressContext {
230
- Origin : eoa ,
231
- Caller : caller ,
232
- Self : precompile ,
243
+ Origin : eoa ,
244
+ EVMSemantic : rawAddresses ,
245
+ Raw : & rawAddresses ,
233
246
},
234
247
wantReadOnly : false ,
235
248
wantTransferValue : transferValue ,
@@ -242,8 +255,11 @@ func TestNewStatefulPrecompile(t *testing.T) {
242
255
},
243
256
wantAddresses : & libevm.AddressContext {
244
257
Origin : eoa ,
245
- Caller : caller ,
246
- Self : caller ,
258
+ EVMSemantic : libevm.CallerAndSelf {
259
+ Caller : caller ,
260
+ Self : caller ,
261
+ },
262
+ Raw : & rawAddresses ,
247
263
},
248
264
wantReadOnly : false ,
249
265
wantTransferValue : transferValue ,
@@ -256,8 +272,11 @@ func TestNewStatefulPrecompile(t *testing.T) {
256
272
},
257
273
wantAddresses : & libevm.AddressContext {
258
274
Origin : eoa ,
259
- Caller : eoa , // inherited from caller
260
- Self : caller ,
275
+ EVMSemantic : libevm.CallerAndSelf {
276
+ Caller : eoa , // inherited from caller
277
+ Self : caller ,
278
+ },
279
+ Raw : & rawAddresses ,
261
280
},
262
281
wantReadOnly : false ,
263
282
wantTransferValue : uint256 .NewInt (0 ),
@@ -269,9 +288,9 @@ func TestNewStatefulPrecompile(t *testing.T) {
269
288
return evm .StaticCall (callerContract , precompile , input , gasLimit )
270
289
},
271
290
wantAddresses : & libevm.AddressContext {
272
- Origin : eoa ,
273
- Caller : caller ,
274
- Self : precompile ,
291
+ Origin : eoa ,
292
+ EVMSemantic : rawAddresses ,
293
+ Raw : & rawAddresses ,
275
294
},
276
295
wantReadOnly : true ,
277
296
wantTransferValue : uint256 .NewInt (0 ),
@@ -527,7 +546,7 @@ func TestCanCreateContract(t *testing.T) {
527
546
gasUsage := rng .Uint64n (gasLimit )
528
547
529
548
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 )
549
+ return fmt .Errorf ("Origin: %v Caller: %v Contract: %v State: %v" , cc .Origin , cc .EVMSemantic . Caller , cc . EVMSemantic .Self , stateVal )
531
550
}
532
551
hooks := & hookstest.Stub {
533
552
CanCreateContractFn : func (cc * libevm.AddressContext , gas uint64 , s libevm.StateReader ) (uint64 , error ) {
@@ -555,14 +574,34 @@ func TestCanCreateContract(t *testing.T) {
555
574
create : func (evm * vm.EVM ) ([]byte , common.Address , uint64 , error ) {
556
575
return evm .Create (vm .AccountRef (caller ), code , gasLimit , uint256 .NewInt (0 ))
557
576
},
558
- wantErr : makeErr (& libevm.AddressContext {Origin : origin , Caller : caller , Self : create }, value ),
577
+ wantErr : makeErr (
578
+ & libevm.AddressContext {
579
+ Origin : origin ,
580
+ EVMSemantic : libevm.CallerAndSelf {
581
+ Caller : caller ,
582
+ Self : create ,
583
+ },
584
+ // `Raw` is documented as always being nil.
585
+ },
586
+ value ,
587
+ ),
559
588
},
560
589
{
561
590
name : "Create2" ,
562
591
create : func (evm * vm.EVM ) ([]byte , common.Address , uint64 , error ) {
563
592
return evm .Create2 (vm .AccountRef (caller ), code , gasLimit , uint256 .NewInt (0 ), new (uint256.Int ).SetBytes (salt [:]))
564
593
},
565
- wantErr : makeErr (& libevm.AddressContext {Origin : origin , Caller : caller , Self : create2 }, value ),
594
+ wantErr : makeErr (
595
+ & libevm.AddressContext {
596
+ Origin : origin ,
597
+ EVMSemantic : libevm.CallerAndSelf {
598
+ Caller : caller ,
599
+ Self : create2 ,
600
+ },
601
+ // As above re `Raw` always being nil.
602
+ },
603
+ value ,
604
+ ),
566
605
},
567
606
}
568
607
@@ -630,7 +669,10 @@ func TestPrecompileMakeCall(t *testing.T) {
630
669
if bytes .Equal (input , unsafeCallerProxyOptSentinel ) {
631
670
opts = append (opts , vm .WithUNSAFECallerAddressProxying ())
632
671
}
633
- // We are ultimately testing env.Call(), hence why this is the SUT.
672
+ // We are ultimately testing env.Call(), hence why this is the
673
+ // SUT. If this is ever extended to include DELEGATECALL or
674
+ // CALLCODE then the expected [libevm.AddressContext.Raw] values
675
+ // of the tests cases also need to change.
634
676
return env .Call (dest , precompileCallData , env .Gas (), uint256 .NewInt (0 ), opts ... )
635
677
}),
636
678
dest : vm .NewStatefulPrecompile (func (env vm.PrecompileEnvironment , input []byte ) (ret []byte , err error ) {
@@ -663,8 +705,10 @@ func TestPrecompileMakeCall(t *testing.T) {
663
705
want : statefulPrecompileOutput {
664
706
Addresses : & libevm.AddressContext {
665
707
Origin : eoa ,
666
- Caller : sut ,
667
- Self : dest ,
708
+ EVMSemantic : libevm.CallerAndSelf {
709
+ Caller : sut ,
710
+ Self : dest ,
711
+ },
668
712
},
669
713
Input : precompileCallData ,
670
714
},
@@ -675,8 +719,10 @@ func TestPrecompileMakeCall(t *testing.T) {
675
719
want : statefulPrecompileOutput {
676
720
Addresses : & libevm.AddressContext {
677
721
Origin : eoa ,
678
- Caller : caller , // overridden by CallOption
679
- Self : dest ,
722
+ EVMSemantic : libevm.CallerAndSelf {
723
+ Caller : caller , // overridden by CallOption
724
+ Self : dest ,
725
+ },
680
726
},
681
727
Input : precompileCallData ,
682
728
},
@@ -686,8 +732,10 @@ func TestPrecompileMakeCall(t *testing.T) {
686
732
want : statefulPrecompileOutput {
687
733
Addresses : & libevm.AddressContext {
688
734
Origin : eoa ,
689
- Caller : caller , // SUT runs as its own caller because of CALLCODE
690
- Self : dest ,
735
+ EVMSemantic : libevm.CallerAndSelf {
736
+ Caller : caller , // SUT runs as its own caller because of CALLCODE
737
+ Self : dest ,
738
+ },
691
739
},
692
740
Input : precompileCallData ,
693
741
},
@@ -698,8 +746,10 @@ func TestPrecompileMakeCall(t *testing.T) {
698
746
want : statefulPrecompileOutput {
699
747
Addresses : & libevm.AddressContext {
700
748
Origin : eoa ,
701
- Caller : caller , // CallOption is a NOOP
702
- Self : dest ,
749
+ EVMSemantic : libevm.CallerAndSelf {
750
+ Caller : caller , // CallOption is a NOOP
751
+ Self : dest ,
752
+ },
703
753
},
704
754
Input : precompileCallData ,
705
755
},
@@ -709,8 +759,10 @@ func TestPrecompileMakeCall(t *testing.T) {
709
759
want : statefulPrecompileOutput {
710
760
Addresses : & libevm.AddressContext {
711
761
Origin : eoa ,
712
- Caller : caller , // as with CALLCODE
713
- Self : dest ,
762
+ EVMSemantic : libevm.CallerAndSelf {
763
+ Caller : caller , // as with CALLCODE
764
+ Self : dest ,
765
+ },
714
766
},
715
767
Input : precompileCallData ,
716
768
},
@@ -721,8 +773,10 @@ func TestPrecompileMakeCall(t *testing.T) {
721
773
want : statefulPrecompileOutput {
722
774
Addresses : & libevm.AddressContext {
723
775
Origin : eoa ,
724
- Caller : caller , // CallOption is a NOOP
725
- Self : dest ,
776
+ EVMSemantic : libevm.CallerAndSelf {
777
+ Caller : caller , // CallOption is a NOOP
778
+ Self : dest ,
779
+ },
726
780
},
727
781
Input : precompileCallData ,
728
782
},
@@ -732,8 +786,10 @@ func TestPrecompileMakeCall(t *testing.T) {
732
786
want : statefulPrecompileOutput {
733
787
Addresses : & libevm.AddressContext {
734
788
Origin : eoa ,
735
- Caller : sut ,
736
- Self : dest ,
789
+ EVMSemantic : libevm.CallerAndSelf {
790
+ Caller : sut ,
791
+ Self : dest ,
792
+ },
737
793
},
738
794
Input : precompileCallData ,
739
795
// This demonstrates that even though the precompile makes a
@@ -749,8 +805,10 @@ func TestPrecompileMakeCall(t *testing.T) {
749
805
want : statefulPrecompileOutput {
750
806
Addresses : & libevm.AddressContext {
751
807
Origin : eoa ,
752
- Caller : caller , // overridden by CallOption
753
- Self : dest ,
808
+ EVMSemantic : libevm.CallerAndSelf {
809
+ Caller : caller , // overridden by CallOption
810
+ Self : dest ,
811
+ },
754
812
},
755
813
Input : precompileCallData ,
756
814
ReadOnly : true ,
@@ -760,6 +818,9 @@ func TestPrecompileMakeCall(t *testing.T) {
760
818
761
819
for _ , tt := range tests {
762
820
t .Run (tt .incomingCallType .String (), func (t * testing.T ) {
821
+ // From the perspective of `dest` after a CALL from `sut`.
822
+ tt .want .Addresses .Raw = & tt .want .Addresses .EVMSemantic
823
+
763
824
t .Logf ("calldata = %q" , tt .eoaTxCallData )
764
825
state , evm := ethtest .NewZeroEVM (t )
765
826
evm .Origin = eoa
@@ -816,26 +877,3 @@ func TestPrecompileCallWithTracer(t *testing.T) {
816
877
require .NoErrorf (t , json .Unmarshal (gotJSON , & got ), "json.Unmarshal(%T.GetResult(), %T)" , tracer , & got )
817
878
require .Equal (t , value , got [contract ].Storage [zeroHash ], "value loaded with SLOAD" )
818
879
}
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
- }
0 commit comments