@@ -120,6 +120,7 @@ type statefulPrecompileOutput struct {
120120func (o statefulPrecompileOutput ) String () string {
121121 var lines []string
122122 out := reflect .ValueOf (o )
123+ FieldLoop:
123124 for i , n := 0 , out .NumField (); i < n ; i ++ {
124125 name := out .Type ().Field (i ).Name
125126 fld := out .Field (i ).Interface ()
@@ -129,7 +130,12 @@ func (o statefulPrecompileOutput) String() string {
129130 case []byte :
130131 verb = "%#x"
131132 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
133139 case vm.CallType :
134140 verb = "%d (%[2]q)"
135141 }
@@ -211,6 +217,13 @@ func TestNewStatefulPrecompile(t *testing.T) {
211217 state .SetBalance (caller , new (uint256.Int ).Not (uint256 .NewInt (0 )))
212218 evm .Origin = eoa
213219
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+
214227 tests := []struct {
215228 name string
216229 call func () ([]byte , uint64 , error )
@@ -227,9 +240,9 @@ func TestNewStatefulPrecompile(t *testing.T) {
227240 return evm .Call (callerContract , precompile , input , gasLimit , transferValue )
228241 },
229242 wantAddresses : & libevm.AddressContext {
230- Origin : eoa ,
231- Caller : caller ,
232- Self : precompile ,
243+ Origin : eoa ,
244+ EVMSemantic : rawAddresses ,
245+ Raw : & rawAddresses ,
233246 },
234247 wantReadOnly : false ,
235248 wantTransferValue : transferValue ,
@@ -242,8 +255,11 @@ func TestNewStatefulPrecompile(t *testing.T) {
242255 },
243256 wantAddresses : & libevm.AddressContext {
244257 Origin : eoa ,
245- Caller : caller ,
246- Self : caller ,
258+ EVMSemantic : libevm.CallerAndSelf {
259+ Caller : caller ,
260+ Self : caller ,
261+ },
262+ Raw : & rawAddresses ,
247263 },
248264 wantReadOnly : false ,
249265 wantTransferValue : transferValue ,
@@ -256,8 +272,11 @@ func TestNewStatefulPrecompile(t *testing.T) {
256272 },
257273 wantAddresses : & libevm.AddressContext {
258274 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 ,
261280 },
262281 wantReadOnly : false ,
263282 wantTransferValue : uint256 .NewInt (0 ),
@@ -269,9 +288,9 @@ func TestNewStatefulPrecompile(t *testing.T) {
269288 return evm .StaticCall (callerContract , precompile , input , gasLimit )
270289 },
271290 wantAddresses : & libevm.AddressContext {
272- Origin : eoa ,
273- Caller : caller ,
274- Self : precompile ,
291+ Origin : eoa ,
292+ EVMSemantic : rawAddresses ,
293+ Raw : & rawAddresses ,
275294 },
276295 wantReadOnly : true ,
277296 wantTransferValue : uint256 .NewInt (0 ),
@@ -527,7 +546,7 @@ func TestCanCreateContract(t *testing.T) {
527546 gasUsage := rng .Uint64n (gasLimit )
528547
529548 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 )
531550 }
532551 hooks := & hookstest.Stub {
533552 CanCreateContractFn : func (cc * libevm.AddressContext , gas uint64 , s libevm.StateReader ) (uint64 , error ) {
@@ -555,14 +574,34 @@ func TestCanCreateContract(t *testing.T) {
555574 create : func (evm * vm.EVM ) ([]byte , common.Address , uint64 , error ) {
556575 return evm .Create (vm .AccountRef (caller ), code , gasLimit , uint256 .NewInt (0 ))
557576 },
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+ ),
559588 },
560589 {
561590 name : "Create2" ,
562591 create : func (evm * vm.EVM ) ([]byte , common.Address , uint64 , error ) {
563592 return evm .Create2 (vm .AccountRef (caller ), code , gasLimit , uint256 .NewInt (0 ), new (uint256.Int ).SetBytes (salt [:]))
564593 },
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+ ),
566605 },
567606 }
568607
@@ -630,7 +669,10 @@ func TestPrecompileMakeCall(t *testing.T) {
630669 if bytes .Equal (input , unsafeCallerProxyOptSentinel ) {
631670 opts = append (opts , vm .WithUNSAFECallerAddressProxying ())
632671 }
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.
634676 return env .Call (dest , precompileCallData , env .Gas (), uint256 .NewInt (0 ), opts ... )
635677 }),
636678 dest : vm .NewStatefulPrecompile (func (env vm.PrecompileEnvironment , input []byte ) (ret []byte , err error ) {
@@ -663,8 +705,10 @@ func TestPrecompileMakeCall(t *testing.T) {
663705 want : statefulPrecompileOutput {
664706 Addresses : & libevm.AddressContext {
665707 Origin : eoa ,
666- Caller : sut ,
667- Self : dest ,
708+ EVMSemantic : libevm.CallerAndSelf {
709+ Caller : sut ,
710+ Self : dest ,
711+ },
668712 },
669713 Input : precompileCallData ,
670714 },
@@ -675,8 +719,10 @@ func TestPrecompileMakeCall(t *testing.T) {
675719 want : statefulPrecompileOutput {
676720 Addresses : & libevm.AddressContext {
677721 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+ },
680726 },
681727 Input : precompileCallData ,
682728 },
@@ -686,8 +732,10 @@ func TestPrecompileMakeCall(t *testing.T) {
686732 want : statefulPrecompileOutput {
687733 Addresses : & libevm.AddressContext {
688734 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+ },
691739 },
692740 Input : precompileCallData ,
693741 },
@@ -698,8 +746,10 @@ func TestPrecompileMakeCall(t *testing.T) {
698746 want : statefulPrecompileOutput {
699747 Addresses : & libevm.AddressContext {
700748 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+ },
703753 },
704754 Input : precompileCallData ,
705755 },
@@ -709,8 +759,10 @@ func TestPrecompileMakeCall(t *testing.T) {
709759 want : statefulPrecompileOutput {
710760 Addresses : & libevm.AddressContext {
711761 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+ },
714766 },
715767 Input : precompileCallData ,
716768 },
@@ -721,8 +773,10 @@ func TestPrecompileMakeCall(t *testing.T) {
721773 want : statefulPrecompileOutput {
722774 Addresses : & libevm.AddressContext {
723775 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+ },
726780 },
727781 Input : precompileCallData ,
728782 },
@@ -732,8 +786,10 @@ func TestPrecompileMakeCall(t *testing.T) {
732786 want : statefulPrecompileOutput {
733787 Addresses : & libevm.AddressContext {
734788 Origin : eoa ,
735- Caller : sut ,
736- Self : dest ,
789+ EVMSemantic : libevm.CallerAndSelf {
790+ Caller : sut ,
791+ Self : dest ,
792+ },
737793 },
738794 Input : precompileCallData ,
739795 // This demonstrates that even though the precompile makes a
@@ -749,8 +805,10 @@ func TestPrecompileMakeCall(t *testing.T) {
749805 want : statefulPrecompileOutput {
750806 Addresses : & libevm.AddressContext {
751807 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+ },
754812 },
755813 Input : precompileCallData ,
756814 ReadOnly : true ,
@@ -760,6 +818,9 @@ func TestPrecompileMakeCall(t *testing.T) {
760818
761819 for _ , tt := range tests {
762820 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+
763824 t .Logf ("calldata = %q" , tt .eoaTxCallData )
764825 state , evm := ethtest .NewZeroEVM (t )
765826 evm .Origin = eoa
@@ -816,26 +877,3 @@ func TestPrecompileCallWithTracer(t *testing.T) {
816877 require .NoErrorf (t , json .Unmarshal (gotJSON , & got ), "json.Unmarshal(%T.GetResult(), %T)" , tracer , & got )
817878 require .Equal (t , value , got [contract ].Storage [zeroHash ], "value loaded with SLOAD" )
818879}
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