Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
f68a68a3
Unverified
Commit
f68a68a3
authored
Jun 10, 2021
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core, internal: support various eth_call invocations post 1559
parent
7a00378e
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
62 additions
and
51 deletions
+62
-51
state_transition.go
core/state_transition.go
+21
-19
evm.go
core/vm/evm.go
+19
-19
instructions.go
core/vm/instructions.go
+1
-1
instructions_test.go
core/vm/instructions_test.go
+5
-5
interpreter.go
core/vm/interpreter.go
+1
-0
api.go
internal/ethapi/api.go
+1
-1
transaction_args.go
internal/ethapi/transaction_args.go
+10
-2
bindata.go
internal/jsre/deps/bindata.go
+3
-3
web3.js
internal/jsre/deps/web3.js
+1
-1
No files found.
core/state_transition.go
View file @
f68a68a3
...
...
@@ -221,23 +221,26 @@ func (st *StateTransition) preCheck() error {
}
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
if
st
.
evm
.
ChainConfig
()
.
IsLondon
(
st
.
evm
.
Context
.
BlockNumber
)
{
if
l
:=
st
.
gasFeeCap
.
BitLen
();
l
>
256
{
return
fmt
.
Errorf
(
"%w: address %v, maxFeePerGas bit length: %d"
,
ErrFeeCapVeryHigh
,
st
.
msg
.
From
()
.
Hex
(),
l
)
}
if
l
:=
st
.
gasTipCap
.
BitLen
();
l
>
256
{
return
fmt
.
Errorf
(
"%w: address %v, maxPriorityFeePerGas bit length: %d"
,
ErrTipVeryHigh
,
st
.
msg
.
From
()
.
Hex
(),
l
)
}
if
st
.
gasFeeCap
.
Cmp
(
st
.
gasTipCap
)
<
0
{
return
fmt
.
Errorf
(
"%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s"
,
ErrTipAboveFeeCap
,
st
.
msg
.
From
()
.
Hex
(),
st
.
gasTipCap
,
st
.
gasFeeCap
)
}
// This will panic if baseFee is nil, but basefee presence is verified
// as part of header validation.
if
st
.
gasFeeCap
.
Cmp
(
st
.
evm
.
Context
.
BaseFee
)
<
0
{
return
fmt
.
Errorf
(
"%w: address %v, maxFeePerGas: %s baseFee: %s"
,
ErrFeeCapTooLow
,
st
.
msg
.
From
()
.
Hex
(),
st
.
gasFeeCap
,
st
.
evm
.
Context
.
BaseFee
)
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
if
!
st
.
evm
.
Config
.
NoBaseFee
||
st
.
gasFeeCap
.
BitLen
()
>
0
||
st
.
gasTipCap
.
BitLen
()
>
0
{
if
l
:=
st
.
gasFeeCap
.
BitLen
();
l
>
256
{
return
fmt
.
Errorf
(
"%w: address %v, maxFeePerGas bit length: %d"
,
ErrFeeCapVeryHigh
,
st
.
msg
.
From
()
.
Hex
(),
l
)
}
if
l
:=
st
.
gasTipCap
.
BitLen
();
l
>
256
{
return
fmt
.
Errorf
(
"%w: address %v, maxPriorityFeePerGas bit length: %d"
,
ErrTipVeryHigh
,
st
.
msg
.
From
()
.
Hex
(),
l
)
}
if
st
.
gasFeeCap
.
Cmp
(
st
.
gasTipCap
)
<
0
{
return
fmt
.
Errorf
(
"%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s"
,
ErrTipAboveFeeCap
,
st
.
msg
.
From
()
.
Hex
(),
st
.
gasTipCap
,
st
.
gasFeeCap
)
}
// This will panic if baseFee is nil, but basefee presence is verified
// as part of header validation.
if
st
.
gasFeeCap
.
Cmp
(
st
.
evm
.
Context
.
BaseFee
)
<
0
{
return
fmt
.
Errorf
(
"%w: address %v, maxFeePerGas: %s baseFee: %s"
,
ErrFeeCapTooLow
,
st
.
msg
.
From
()
.
Hex
(),
st
.
gasFeeCap
,
st
.
evm
.
Context
.
BaseFee
)
}
}
}
return
st
.
buyGas
()
...
...
@@ -275,7 +278,6 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
sender
:=
vm
.
AccountRef
(
msg
.
From
())
homestead
:=
st
.
evm
.
ChainConfig
()
.
IsHomestead
(
st
.
evm
.
Context
.
BlockNumber
)
istanbul
:=
st
.
evm
.
ChainConfig
()
.
IsIstanbul
(
st
.
evm
.
Context
.
BlockNumber
)
eip3529
:=
st
.
evm
.
ChainConfig
()
.
IsLondon
(
st
.
evm
.
Context
.
BlockNumber
)
contractCreation
:=
msg
.
To
()
==
nil
// Check clauses 4-5, subtract intrinsic gas if everything is correct
...
...
@@ -308,7 +310,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
st
.
state
.
SetNonce
(
msg
.
From
(),
st
.
state
.
GetNonce
(
sender
.
Address
())
+
1
)
ret
,
st
.
gas
,
vmerr
=
st
.
evm
.
Call
(
sender
,
st
.
to
(),
st
.
data
,
st
.
gas
,
st
.
value
)
}
if
!
eip3529
{
if
!
st
.
evm
.
ChainConfig
()
.
IsLondon
(
st
.
evm
.
Context
.
BlockNumber
)
{
// Before EIP-3529: refunds were capped to gasUsed / 2
st
.
refundGas
(
params
.
RefundQuotient
)
}
else
{
...
...
core/vm/evm.go
View file @
f68a68a3
...
...
@@ -128,7 +128,7 @@ type EVM struct {
chainRules
params
.
Rules
// virtual machine configuration options used to initialise the
// evm.
vm
Config
Config
Config
Config
// global (to this context) ethereum virtual machine
// used throughout the execution of the tx.
interpreters
[]
Interpreter
...
...
@@ -144,12 +144,12 @@ type EVM struct {
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
// only ever be used *once*.
func
NewEVM
(
blockCtx
BlockContext
,
txCtx
TxContext
,
statedb
StateDB
,
chainConfig
*
params
.
ChainConfig
,
vmC
onfig
Config
)
*
EVM
{
func
NewEVM
(
blockCtx
BlockContext
,
txCtx
TxContext
,
statedb
StateDB
,
chainConfig
*
params
.
ChainConfig
,
c
onfig
Config
)
*
EVM
{
evm
:=
&
EVM
{
Context
:
blockCtx
,
TxContext
:
txCtx
,
StateDB
:
statedb
,
vmConfig
:
vmC
onfig
,
Config
:
c
onfig
,
chainConfig
:
chainConfig
,
chainRules
:
chainConfig
.
Rules
(
blockCtx
.
BlockNumber
),
interpreters
:
make
([]
Interpreter
,
0
,
1
),
...
...
@@ -173,7 +173,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
// vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here
// as we always want to have the built-in EVM as the failover option.
evm
.
interpreters
=
append
(
evm
.
interpreters
,
NewEVMInterpreter
(
evm
,
vmC
onfig
))
evm
.
interpreters
=
append
(
evm
.
interpreters
,
NewEVMInterpreter
(
evm
,
c
onfig
))
evm
.
interpreter
=
evm
.
interpreters
[
0
]
return
evm
...
...
@@ -207,7 +207,7 @@ func (evm *EVM) Interpreter() Interpreter {
// the necessary steps to create accounts and reverses the state in case of an
// execution error or failed value transfer.
func
(
evm
*
EVM
)
Call
(
caller
ContractRef
,
addr
common
.
Address
,
input
[]
byte
,
gas
uint64
,
value
*
big
.
Int
)
(
ret
[]
byte
,
leftOverGas
uint64
,
err
error
)
{
if
evm
.
vm
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
if
evm
.
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
return
nil
,
gas
,
nil
}
// Fail if we're trying to execute above the call depth limit
...
...
@@ -224,9 +224,9 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
if
!
evm
.
StateDB
.
Exist
(
addr
)
{
if
!
isPrecompile
&&
evm
.
chainRules
.
IsEIP158
&&
value
.
Sign
()
==
0
{
// Calling a non existing account, don't do anything, but ping the tracer
if
evm
.
vm
Config
.
Debug
&&
evm
.
depth
==
0
{
evm
.
vm
Config
.
Tracer
.
CaptureStart
(
evm
,
caller
.
Address
(),
addr
,
false
,
input
,
gas
,
value
)
evm
.
vm
Config
.
Tracer
.
CaptureEnd
(
ret
,
0
,
0
,
nil
)
if
evm
.
Config
.
Debug
&&
evm
.
depth
==
0
{
evm
.
Config
.
Tracer
.
CaptureStart
(
evm
,
caller
.
Address
(),
addr
,
false
,
input
,
gas
,
value
)
evm
.
Config
.
Tracer
.
CaptureEnd
(
ret
,
0
,
0
,
nil
)
}
return
nil
,
gas
,
nil
}
...
...
@@ -235,10 +235,10 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
evm
.
Context
.
Transfer
(
evm
.
StateDB
,
caller
.
Address
(),
addr
,
value
)
// Capture the tracer start/end events in debug mode
if
evm
.
vm
Config
.
Debug
&&
evm
.
depth
==
0
{
evm
.
vm
Config
.
Tracer
.
CaptureStart
(
evm
,
caller
.
Address
(),
addr
,
false
,
input
,
gas
,
value
)
if
evm
.
Config
.
Debug
&&
evm
.
depth
==
0
{
evm
.
Config
.
Tracer
.
CaptureStart
(
evm
,
caller
.
Address
(),
addr
,
false
,
input
,
gas
,
value
)
defer
func
(
startGas
uint64
,
startTime
time
.
Time
)
{
// Lazy evaluation of the parameters
evm
.
vm
Config
.
Tracer
.
CaptureEnd
(
ret
,
startGas
-
gas
,
time
.
Since
(
startTime
),
err
)
evm
.
Config
.
Tracer
.
CaptureEnd
(
ret
,
startGas
-
gas
,
time
.
Since
(
startTime
),
err
)
}(
gas
,
time
.
Now
())
}
...
...
@@ -283,7 +283,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
// CallCode differs from Call in the sense that it executes the given address'
// code with the caller as context.
func
(
evm
*
EVM
)
CallCode
(
caller
ContractRef
,
addr
common
.
Address
,
input
[]
byte
,
gas
uint64
,
value
*
big
.
Int
)
(
ret
[]
byte
,
leftOverGas
uint64
,
err
error
)
{
if
evm
.
vm
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
if
evm
.
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
return
nil
,
gas
,
nil
}
// Fail if we're trying to execute above the call depth limit
...
...
@@ -326,7 +326,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// DelegateCall differs from CallCode in the sense that it executes the given address'
// code with the caller as context and the caller is set to the caller of the caller.
func
(
evm
*
EVM
)
DelegateCall
(
caller
ContractRef
,
addr
common
.
Address
,
input
[]
byte
,
gas
uint64
)
(
ret
[]
byte
,
leftOverGas
uint64
,
err
error
)
{
if
evm
.
vm
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
if
evm
.
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
return
nil
,
gas
,
nil
}
// Fail if we're trying to execute above the call depth limit
...
...
@@ -360,7 +360,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
// Opcodes that attempt to perform such modifications will result in exceptions
// instead of performing the modifications.
func
(
evm
*
EVM
)
StaticCall
(
caller
ContractRef
,
addr
common
.
Address
,
input
[]
byte
,
gas
uint64
)
(
ret
[]
byte
,
leftOverGas
uint64
,
err
error
)
{
if
evm
.
vm
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
if
evm
.
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
return
nil
,
gas
,
nil
}
// Fail if we're trying to execute above the call depth limit
...
...
@@ -453,12 +453,12 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
contract
:=
NewContract
(
caller
,
AccountRef
(
address
),
value
,
gas
)
contract
.
SetCodeOptionalHash
(
&
address
,
codeAndHash
)
if
evm
.
vm
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
if
evm
.
Config
.
NoRecursion
&&
evm
.
depth
>
0
{
return
nil
,
address
,
gas
,
nil
}
if
evm
.
vm
Config
.
Debug
&&
evm
.
depth
==
0
{
evm
.
vm
Config
.
Tracer
.
CaptureStart
(
evm
,
caller
.
Address
(),
address
,
true
,
codeAndHash
.
code
,
gas
,
value
)
if
evm
.
Config
.
Debug
&&
evm
.
depth
==
0
{
evm
.
Config
.
Tracer
.
CaptureStart
(
evm
,
caller
.
Address
(),
address
,
true
,
codeAndHash
.
code
,
gas
,
value
)
}
start
:=
time
.
Now
()
...
...
@@ -497,8 +497,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
}
}
if
evm
.
vm
Config
.
Debug
&&
evm
.
depth
==
0
{
evm
.
vm
Config
.
Tracer
.
CaptureEnd
(
ret
,
gas
-
contract
.
Gas
,
time
.
Since
(
start
),
err
)
if
evm
.
Config
.
Debug
&&
evm
.
depth
==
0
{
evm
.
Config
.
Tracer
.
CaptureEnd
(
ret
,
gas
-
contract
.
Gas
,
time
.
Since
(
start
),
err
)
}
return
ret
,
address
,
contract
.
Gas
,
err
}
...
...
core/vm/instructions.go
View file @
f68a68a3
...
...
@@ -244,7 +244,7 @@ func opSha3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt
interpreter
.
hasher
.
Read
(
interpreter
.
hasherBuf
[
:
])
evm
:=
interpreter
.
evm
if
evm
.
vm
Config
.
EnablePreimageRecording
{
if
evm
.
Config
.
EnablePreimageRecording
{
evm
.
StateDB
.
AddPreimage
(
interpreter
.
hasherBuf
,
data
)
}
...
...
core/vm/instructions_test.go
View file @
f68a68a3
...
...
@@ -194,7 +194,7 @@ func TestAddMod(t *testing.T) {
var
(
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
=
newstack
()
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
vm
Config
)
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
Config
)
pc
=
uint64
(
0
)
)
tests
:=
[]
struct
{
...
...
@@ -283,7 +283,7 @@ func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
var
(
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
=
newstack
()
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
vm
Config
)
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
Config
)
)
env
.
interpreter
=
evmInterpreter
...
...
@@ -518,7 +518,7 @@ func TestOpMstore(t *testing.T) {
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
=
newstack
()
mem
=
NewMemory
()
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
vm
Config
)
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
Config
)
)
env
.
interpreter
=
evmInterpreter
...
...
@@ -542,7 +542,7 @@ func BenchmarkOpMstore(bench *testing.B) {
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
=
newstack
()
mem
=
NewMemory
()
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
vm
Config
)
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
Config
)
)
env
.
interpreter
=
evmInterpreter
...
...
@@ -563,7 +563,7 @@ func BenchmarkOpSHA3(bench *testing.B) {
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
=
newstack
()
mem
=
NewMemory
()
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
vm
Config
)
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
Config
)
)
env
.
interpreter
=
evmInterpreter
mem
.
Resize
(
32
)
...
...
core/vm/interpreter.go
View file @
f68a68a3
...
...
@@ -30,6 +30,7 @@ type Config struct {
Debug
bool
// Enables debugging
Tracer
Tracer
// Opcode logger
NoRecursion
bool
// Disables call, callcode, delegate call and create
NoBaseFee
bool
// Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
EnablePreimageRecording
bool
// Enables recording of SHA3/keccak preimages
JumpTable
[
256
]
*
operation
// EVM instruction table, automatically populated if unset
...
...
internal/ethapi/api.go
View file @
f68a68a3
...
...
@@ -849,7 +849,7 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash
if
err
!=
nil
{
return
nil
,
err
}
evm
,
vmError
,
err
:=
b
.
GetEVM
(
ctx
,
msg
,
state
,
header
,
nil
)
evm
,
vmError
,
err
:=
b
.
GetEVM
(
ctx
,
msg
,
state
,
header
,
&
vm
.
Config
{
NoBaseFee
:
true
}
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
internal/ethapi/transaction_args.go
View file @
f68a68a3
...
...
@@ -158,7 +158,9 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
return
nil
}
// ToMessage converts TransactionArgs to the Message type used by the core evm
// ToMessage converts th transaction arguments to the Message type used by the
// core evm. This method is used in calls and traces that do not require a real
// live transaction.
func
(
args
*
TransactionArgs
)
ToMessage
(
globalGasCap
uint64
,
baseFee
*
big
.
Int
)
(
types
.
Message
,
error
)
{
// Reject invalid combinations of pre- and post-1559 fee styles
if
args
.
GasPrice
!=
nil
&&
(
args
.
MaxFeePerGas
!=
nil
||
args
.
MaxPriorityFeePerGas
!=
nil
)
{
...
...
@@ -194,9 +196,11 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t
}
else
{
// A basefee is provided, necessitating 1559-type execution
if
args
.
GasPrice
!=
nil
{
// User specified the legacy gas field, convert to 1559 gas typing
gasPrice
=
args
.
GasPrice
.
ToInt
()
gasFeeCap
,
gasTipCap
=
gasPrice
,
gasPrice
}
else
{
// User specified 1559 gas feilds (or none), use those
gasFeeCap
=
new
(
big
.
Int
)
if
args
.
MaxFeePerGas
!=
nil
{
gasFeeCap
=
args
.
MaxFeePerGas
.
ToInt
()
...
...
@@ -205,7 +209,11 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t
if
args
.
MaxPriorityFeePerGas
!=
nil
{
gasTipCap
=
args
.
MaxPriorityFeePerGas
.
ToInt
()
}
gasPrice
=
math
.
BigMin
(
new
(
big
.
Int
)
.
Add
(
gasTipCap
,
baseFee
),
gasFeeCap
)
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
gasPrice
=
new
(
big
.
Int
)
if
gasFeeCap
.
BitLen
()
>
0
||
gasTipCap
.
BitLen
()
>
0
{
gasPrice
=
math
.
BigMin
(
new
(
big
.
Int
)
.
Add
(
gasTipCap
,
baseFee
),
gasFeeCap
)
}
}
}
value
:=
new
(
big
.
Int
)
...
...
internal/jsre/deps/bindata.go
View file @
f68a68a3
This diff is collapsed.
Click to expand it.
internal/jsre/deps/web3.js
View file @
f68a68a3
...
...
@@ -3734,7 +3734,7 @@ var inputCallFormatter = function (options){
options
.
to
=
inputAddressFormatter
(
options
.
to
);
}
[
'gasPrice'
,
'gas'
,
'value'
,
'nonce'
].
filter
(
function
(
key
)
{
[
'
maxFeePerGas'
,
'maxPriorityFeePerGas'
,
'
gasPrice'
,
'gas'
,
'value'
,
'nonce'
].
filter
(
function
(
key
)
{
return
options
[
key
]
!==
undefined
;
}).
forEach
(
function
(
key
){
options
[
key
]
=
utils
.
fromDecimal
(
options
[
key
]);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment