mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 11:20:45 +00:00
test: PrecompileEnvironment.Value() under DELEGATECALL (#216)
## Why this should be merged Completeness. ## How this works n/a ## How this was tested Originally the `DELEGATECALL` test asserted that the `CALLVALUE` was zero, but this didn't demonstrate that it was inherited (e.g. `STATICCALL` always receives zero). The value sent to the caller of the precompile is now non-zero, to precisely demonstrate correct behaviour of all call types.
This commit is contained in:
parent
7a59fddf77
commit
414b1f5dff
2 changed files with 25 additions and 24 deletions
|
|
@ -236,7 +236,7 @@ func (args *evmCallArgs) env() *environment {
|
||||||
self = args.addr
|
self = args.addr
|
||||||
|
|
||||||
case DelegateCall:
|
case DelegateCall:
|
||||||
value = nil
|
value = nil // inherited from `args.caller` inside [Contract.AsDelegate]
|
||||||
fallthrough
|
fallthrough
|
||||||
case CallCode:
|
case CallCode:
|
||||||
self = args.caller.Address()
|
self = args.caller.Address()
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ type statefulPrecompileOutput struct {
|
||||||
ChainID *big.Int
|
ChainID *big.Int
|
||||||
Addresses *libevm.AddressContext
|
Addresses *libevm.AddressContext
|
||||||
StateValue common.Hash
|
StateValue common.Hash
|
||||||
ValueReceived *uint256.Int
|
CallValue *uint256.Int
|
||||||
ReadOnly bool
|
ReadOnly bool
|
||||||
BlockNumber, Difficulty *big.Int
|
BlockNumber, Difficulty *big.Int
|
||||||
BlockTime uint64
|
BlockTime uint64
|
||||||
|
|
@ -169,7 +169,7 @@ func TestNewStatefulPrecompile(t *testing.T) {
|
||||||
ChainID: env.ChainConfig().ChainID,
|
ChainID: env.ChainConfig().ChainID,
|
||||||
Addresses: env.Addresses(),
|
Addresses: env.Addresses(),
|
||||||
StateValue: env.ReadOnlyState().GetState(precompile, slot),
|
StateValue: env.ReadOnlyState().GetState(precompile, slot),
|
||||||
ValueReceived: env.Value(),
|
CallValue: env.Value(),
|
||||||
ReadOnly: env.ReadOnly(),
|
ReadOnly: env.ReadOnly(),
|
||||||
BlockNumber: env.BlockNumber(),
|
BlockNumber: env.BlockNumber(),
|
||||||
BlockTime: env.BlockTime(),
|
BlockTime: env.BlockTime(),
|
||||||
|
|
@ -197,12 +197,13 @@ func TestNewStatefulPrecompile(t *testing.T) {
|
||||||
}
|
}
|
||||||
input := rng.Bytes(8)
|
input := rng.Bytes(8)
|
||||||
stateValue := rng.Hash()
|
stateValue := rng.Hash()
|
||||||
transferValue := rng.Uint256()
|
callCallerValue := rng.Uint256()
|
||||||
|
callPrecompileValue := rng.Uint256()
|
||||||
chainID := rng.BigUint64()
|
chainID := rng.BigUint64()
|
||||||
|
|
||||||
caller := common.HexToAddress("CA11E12") // caller of the precompile
|
caller := common.HexToAddress("CA11E12") // caller of the precompile
|
||||||
eoa := common.HexToAddress("E0A") // caller of the precompile-caller
|
eoa := common.HexToAddress("E0A") // caller of the precompile-caller
|
||||||
callerContract := vm.NewContract(vm.AccountRef(eoa), vm.AccountRef(caller), uint256.NewInt(0), 1e6)
|
callerContract := vm.NewContract(vm.AccountRef(eoa), vm.AccountRef(caller), callCallerValue, 1e6)
|
||||||
|
|
||||||
state, evm := ethtest.NewZeroEVM(
|
state, evm := ethtest.NewZeroEVM(
|
||||||
t,
|
t,
|
||||||
|
|
@ -225,10 +226,10 @@ func TestNewStatefulPrecompile(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
call func() ([]byte, uint64, error)
|
call func() ([]byte, uint64, error)
|
||||||
wantAddresses *libevm.AddressContext
|
wantAddresses *libevm.AddressContext
|
||||||
wantTransferValue *uint256.Int
|
wantCallValue *uint256.Int
|
||||||
// Note that this only covers evm.readOnly being true because of the
|
// Note that this only covers evm.readOnly being true because of the
|
||||||
// precompile's call. See TestInheritReadOnly for alternate case.
|
// precompile's call. See TestInheritReadOnly for alternate case.
|
||||||
wantReadOnly bool
|
wantReadOnly bool
|
||||||
|
|
@ -237,21 +238,21 @@ func TestNewStatefulPrecompile(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "EVM.Call()",
|
name: "EVM.Call()",
|
||||||
call: func() ([]byte, uint64, error) {
|
call: func() ([]byte, uint64, error) {
|
||||||
return evm.Call(callerContract, precompile, input, gasLimit, transferValue)
|
return evm.Call(callerContract, precompile, input, gasLimit, callPrecompileValue)
|
||||||
},
|
},
|
||||||
wantAddresses: &libevm.AddressContext{
|
wantAddresses: &libevm.AddressContext{
|
||||||
Origin: eoa,
|
Origin: eoa,
|
||||||
EVMSemantic: rawAddresses,
|
EVMSemantic: rawAddresses,
|
||||||
Raw: &rawAddresses,
|
Raw: &rawAddresses,
|
||||||
},
|
},
|
||||||
wantReadOnly: false,
|
wantReadOnly: false,
|
||||||
wantTransferValue: transferValue,
|
wantCallValue: callPrecompileValue,
|
||||||
wantCallType: vm.Call,
|
wantCallType: vm.Call,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "EVM.CallCode()",
|
name: "EVM.CallCode()",
|
||||||
call: func() ([]byte, uint64, error) {
|
call: func() ([]byte, uint64, error) {
|
||||||
return evm.CallCode(callerContract, precompile, input, gasLimit, transferValue)
|
return evm.CallCode(callerContract, precompile, input, gasLimit, callPrecompileValue)
|
||||||
},
|
},
|
||||||
wantAddresses: &libevm.AddressContext{
|
wantAddresses: &libevm.AddressContext{
|
||||||
Origin: eoa,
|
Origin: eoa,
|
||||||
|
|
@ -261,9 +262,9 @@ func TestNewStatefulPrecompile(t *testing.T) {
|
||||||
},
|
},
|
||||||
Raw: &rawAddresses,
|
Raw: &rawAddresses,
|
||||||
},
|
},
|
||||||
wantReadOnly: false,
|
wantReadOnly: false,
|
||||||
wantTransferValue: transferValue,
|
wantCallValue: callPrecompileValue,
|
||||||
wantCallType: vm.CallCode,
|
wantCallType: vm.CallCode,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "EVM.DelegateCall()",
|
name: "EVM.DelegateCall()",
|
||||||
|
|
@ -278,9 +279,9 @@ func TestNewStatefulPrecompile(t *testing.T) {
|
||||||
},
|
},
|
||||||
Raw: &rawAddresses,
|
Raw: &rawAddresses,
|
||||||
},
|
},
|
||||||
wantReadOnly: false,
|
wantReadOnly: false,
|
||||||
wantTransferValue: uint256.NewInt(0),
|
wantCallValue: callCallerValue, // Important difference from [vm.EVM.Call]
|
||||||
wantCallType: vm.DelegateCall,
|
wantCallType: vm.DelegateCall,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "EVM.StaticCall()",
|
name: "EVM.StaticCall()",
|
||||||
|
|
@ -292,9 +293,9 @@ func TestNewStatefulPrecompile(t *testing.T) {
|
||||||
EVMSemantic: rawAddresses,
|
EVMSemantic: rawAddresses,
|
||||||
Raw: &rawAddresses,
|
Raw: &rawAddresses,
|
||||||
},
|
},
|
||||||
wantReadOnly: true,
|
wantReadOnly: true,
|
||||||
wantTransferValue: uint256.NewInt(0),
|
wantCallValue: uint256.NewInt(0),
|
||||||
wantCallType: vm.StaticCall,
|
wantCallType: vm.StaticCall,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -304,7 +305,7 @@ func TestNewStatefulPrecompile(t *testing.T) {
|
||||||
ChainID: chainID,
|
ChainID: chainID,
|
||||||
Addresses: tt.wantAddresses,
|
Addresses: tt.wantAddresses,
|
||||||
StateValue: stateValue,
|
StateValue: stateValue,
|
||||||
ValueReceived: tt.wantTransferValue,
|
CallValue: tt.wantCallValue,
|
||||||
ReadOnly: tt.wantReadOnly,
|
ReadOnly: tt.wantReadOnly,
|
||||||
BlockNumber: header.Number,
|
BlockNumber: header.Number,
|
||||||
BlockTime: header.Time,
|
BlockTime: header.Time,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue