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
7834e4a2
Unverified
Commit
7834e4a2
authored
Mar 02, 2021
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core, eth: unship EIP 2315
parent
19d7a37a
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
48 additions
and
205 deletions
+48
-205
contract.go
core/vm/contract.go
+0
-13
eips.go
core/vm/eips.go
+0
-29
gen_structlog.go
core/vm/gen_structlog.go
+0
-13
instructions.go
core/vm/instructions.go
+0
-32
instructions_test.go
core/vm/instructions_test.go
+16
-17
interpreter.go
core/vm/interpreter.go
+6
-10
jump_table.go
core/vm/jump_table.go
+0
-1
logger.go
core/vm/logger.go
+7
-28
logger_json.go
core/vm/logger_json.go
+2
-3
logger_test.go
core/vm/logger_test.go
+1
-2
opcodes.go
core/vm/opcodes.go
+12
-22
stack.go
core/vm/stack.go
+0
-31
tracer.go
eth/tracers/tracer.go
+2
-2
tracer_test.go
eth/tracers/tracer_test.go
+2
-2
No files found.
core/vm/contract.go
View file @
7834e4a2
...
...
@@ -96,19 +96,6 @@ func (c *Contract) validJumpdest(dest *uint256.Int) bool {
return
c
.
isCode
(
udest
)
}
func
(
c
*
Contract
)
validJumpSubdest
(
udest
uint64
)
bool
{
// PC cannot go beyond len(code) and certainly can't be bigger than 63 bits.
// Don't bother checking for BEGINSUB in that case.
if
int64
(
udest
)
<
0
||
udest
>=
uint64
(
len
(
c
.
Code
))
{
return
false
}
// Only BEGINSUBs allowed for destinations
if
OpCode
(
c
.
Code
[
udest
])
!=
BEGINSUB
{
return
false
}
return
c
.
isCode
(
udest
)
}
// isCode returns true if the provided PC location is an actual opcode, as
// opposed to a data-segment following a PUSHN operation.
func
(
c
*
Contract
)
isCode
(
udest
uint64
)
bool
{
...
...
core/vm/eips.go
View file @
7834e4a2
...
...
@@ -29,7 +29,6 @@ var activators = map[int]func(*JumpTable){
2200
:
enable2200
,
1884
:
enable1884
,
1344
:
enable1344
,
2315
:
enable2315
,
}
// EnableEIP enables the given EIP on the config.
...
...
@@ -108,34 +107,6 @@ func enable2200(jt *JumpTable) {
jt
[
SSTORE
]
.
dynamicGas
=
gasSStoreEIP2200
}
// enable2315 applies EIP-2315 (Simple Subroutines)
// - Adds opcodes that jump to and return from subroutines
func
enable2315
(
jt
*
JumpTable
)
{
// New opcode
jt
[
BEGINSUB
]
=
&
operation
{
execute
:
opBeginSub
,
constantGas
:
GasQuickStep
,
minStack
:
minStack
(
0
,
0
),
maxStack
:
maxStack
(
0
,
0
),
}
// New opcode
jt
[
JUMPSUB
]
=
&
operation
{
execute
:
opJumpSub
,
constantGas
:
GasSlowStep
,
minStack
:
minStack
(
1
,
0
),
maxStack
:
maxStack
(
1
,
0
),
jumps
:
true
,
}
// New opcode
jt
[
RETURNSUB
]
=
&
operation
{
execute
:
opReturnSub
,
constantGas
:
GasFastStep
,
minStack
:
minStack
(
0
,
0
),
maxStack
:
maxStack
(
0
,
0
),
jumps
:
true
,
}
}
// enable2929 enables "EIP-2929: Gas cost increases for state access opcodes"
// https://eips.ethereum.org/EIPS/eip-2929
func
enable2929
(
jt
*
JumpTable
)
{
...
...
core/vm/gen_structlog.go
View file @
7834e4a2
...
...
@@ -45,12 +45,6 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
enc
.
Stack
[
k
]
=
(
*
math
.
HexOrDecimal256
)(
v
)
}
}
if
s
.
ReturnStack
!=
nil
{
enc
.
ReturnStack
=
make
([]
math
.
HexOrDecimal64
,
len
(
s
.
ReturnStack
))
for
k
,
v
:=
range
s
.
ReturnStack
{
enc
.
ReturnStack
[
k
]
=
math
.
HexOrDecimal64
(
v
)
}
}
enc
.
ReturnData
=
s
.
ReturnData
enc
.
Storage
=
s
.
Storage
enc
.
Depth
=
s
.
Depth
...
...
@@ -71,7 +65,6 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
Memory
*
hexutil
.
Bytes
`json:"memory"`
MemorySize
*
int
`json:"memSize"`
Stack
[]
*
math
.
HexOrDecimal256
`json:"stack"`
ReturnStack
[]
math
.
HexOrDecimal64
`json:"returnStack"`
ReturnData
*
hexutil
.
Bytes
`json:"returnData"`
Storage
map
[
common
.
Hash
]
common
.
Hash
`json:"-"`
Depth
*
int
`json:"depth"`
...
...
@@ -106,12 +99,6 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
s
.
Stack
[
k
]
=
(
*
big
.
Int
)(
v
)
}
}
if
dec
.
ReturnStack
!=
nil
{
s
.
ReturnStack
=
make
([]
uint32
,
len
(
dec
.
ReturnStack
))
for
k
,
v
:=
range
dec
.
ReturnStack
{
s
.
ReturnStack
[
k
]
=
uint32
(
v
)
}
}
if
dec
.
ReturnData
!=
nil
{
s
.
ReturnData
=
*
dec
.
ReturnData
}
...
...
core/vm/instructions.go
View file @
7834e4a2
...
...
@@ -547,38 +547,6 @@ func opJumpdest(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (
return
nil
,
nil
}
func
opBeginSub
(
pc
*
uint64
,
interpreter
*
EVMInterpreter
,
callContext
*
callCtx
)
([]
byte
,
error
)
{
return
nil
,
ErrInvalidSubroutineEntry
}
func
opJumpSub
(
pc
*
uint64
,
interpreter
*
EVMInterpreter
,
callContext
*
callCtx
)
([]
byte
,
error
)
{
if
len
(
callContext
.
rstack
.
data
)
>=
1023
{
return
nil
,
ErrReturnStackExceeded
}
pos
:=
callContext
.
stack
.
pop
()
if
!
pos
.
IsUint64
()
{
return
nil
,
ErrInvalidJump
}
posU64
:=
pos
.
Uint64
()
if
!
callContext
.
contract
.
validJumpSubdest
(
posU64
)
{
return
nil
,
ErrInvalidJump
}
callContext
.
rstack
.
push
(
uint32
(
*
pc
))
*
pc
=
posU64
+
1
return
nil
,
nil
}
func
opReturnSub
(
pc
*
uint64
,
interpreter
*
EVMInterpreter
,
callContext
*
callCtx
)
([]
byte
,
error
)
{
if
len
(
callContext
.
rstack
.
data
)
==
0
{
return
nil
,
ErrInvalidRetsub
}
// Other than the check that the return stack is not empty, there is no
// need to validate the pc from 'returns', since we only ever push valid
//values onto it via jumpsub.
*
pc
=
uint64
(
callContext
.
rstack
.
pop
())
+
1
return
nil
,
nil
}
func
opPc
(
pc
*
uint64
,
interpreter
*
EVMInterpreter
,
callContext
*
callCtx
)
([]
byte
,
error
)
{
callContext
.
stack
.
push
(
new
(
uint256
.
Int
)
.
SetUint64
(
*
pc
))
return
nil
,
nil
...
...
core/vm/instructions_test.go
View file @
7834e4a2
...
...
@@ -94,7 +94,6 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu
var
(
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
=
newstack
()
rstack
=
newReturnStack
()
pc
=
uint64
(
0
)
evmInterpreter
=
env
.
interpreter
.
(
*
EVMInterpreter
)
)
...
...
@@ -105,7 +104,7 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu
expected
:=
new
(
uint256
.
Int
)
.
SetBytes
(
common
.
Hex2Bytes
(
test
.
Expected
))
stack
.
push
(
x
)
stack
.
push
(
y
)
opFn
(
&
pc
,
evmInterpreter
,
&
callCtx
{
nil
,
stack
,
rstack
,
nil
})
opFn
(
&
pc
,
evmInterpreter
,
&
callCtx
{
nil
,
stack
,
nil
})
if
len
(
stack
.
data
)
!=
1
{
t
.
Errorf
(
"Expected one item on stack after %v, got %d: "
,
name
,
len
(
stack
.
data
))
}
...
...
@@ -220,7 +219,7 @@ func TestAddMod(t *testing.T) {
stack
.
push
(
z
)
stack
.
push
(
y
)
stack
.
push
(
x
)
opAddmod
(
&
pc
,
evmInterpreter
,
&
callCtx
{
nil
,
stack
,
nil
,
nil
})
opAddmod
(
&
pc
,
evmInterpreter
,
&
callCtx
{
nil
,
stack
,
nil
})
actual
:=
stack
.
pop
()
if
actual
.
Cmp
(
expected
)
!=
0
{
t
.
Errorf
(
"Testcase %d, expected %x, got %x"
,
i
,
expected
,
actual
)
...
...
@@ -231,10 +230,10 @@ func TestAddMod(t *testing.T) {
// getResult is a convenience function to generate the expected values
func
getResult
(
args
[]
*
twoOperandParams
,
opFn
executionFunc
)
[]
TwoOperandTestcase
{
var
(
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
,
rstack
=
newstack
(),
newReturnS
tack
()
pc
=
uint64
(
0
)
interpreter
=
env
.
interpreter
.
(
*
EVMInterpreter
)
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
=
news
tack
()
pc
=
uint64
(
0
)
interpreter
=
env
.
interpreter
.
(
*
EVMInterpreter
)
)
result
:=
make
([]
TwoOperandTestcase
,
len
(
args
))
for
i
,
param
:=
range
args
{
...
...
@@ -242,7 +241,7 @@ func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcas
y
:=
new
(
uint256
.
Int
)
.
SetBytes
(
common
.
Hex2Bytes
(
param
.
y
))
stack
.
push
(
x
)
stack
.
push
(
y
)
opFn
(
&
pc
,
interpreter
,
&
callCtx
{
nil
,
stack
,
rstack
,
nil
})
opFn
(
&
pc
,
interpreter
,
&
callCtx
{
nil
,
stack
,
nil
})
actual
:=
stack
.
pop
()
result
[
i
]
=
TwoOperandTestcase
{
param
.
x
,
param
.
y
,
fmt
.
Sprintf
(
"%064x"
,
actual
)}
}
...
...
@@ -282,7 +281,7 @@ func TestJsonTestcases(t *testing.T) {
func
opBenchmark
(
bench
*
testing
.
B
,
op
executionFunc
,
args
...
string
)
{
var
(
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
,
rstack
=
newstack
(),
newReturnS
tack
()
stack
=
news
tack
()
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
vmConfig
)
)
...
...
@@ -300,7 +299,7 @@ func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
a
.
SetBytes
(
arg
)
stack
.
push
(
a
)
}
op
(
&
pc
,
evmInterpreter
,
&
callCtx
{
nil
,
stack
,
rstack
,
nil
})
op
(
&
pc
,
evmInterpreter
,
&
callCtx
{
nil
,
stack
,
nil
})
stack
.
pop
()
}
}
...
...
@@ -516,7 +515,7 @@ func BenchmarkOpIsZero(b *testing.B) {
func
TestOpMstore
(
t
*
testing
.
T
)
{
var
(
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
,
rstack
=
newstack
(),
newReturnS
tack
()
stack
=
news
tack
()
mem
=
NewMemory
()
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
vmConfig
)
)
...
...
@@ -526,12 +525,12 @@ func TestOpMstore(t *testing.T) {
pc
:=
uint64
(
0
)
v
:=
"abcdef00000000000000abba000000000deaf000000c0de00100000000133700"
stack
.
pushN
(
*
new
(
uint256
.
Int
)
.
SetBytes
(
common
.
Hex2Bytes
(
v
)),
*
new
(
uint256
.
Int
))
opMstore
(
&
pc
,
evmInterpreter
,
&
callCtx
{
mem
,
stack
,
rstack
,
nil
})
opMstore
(
&
pc
,
evmInterpreter
,
&
callCtx
{
mem
,
stack
,
nil
})
if
got
:=
common
.
Bytes2Hex
(
mem
.
GetCopy
(
0
,
32
));
got
!=
v
{
t
.
Fatalf
(
"Mstore fail, got %v, expected %v"
,
got
,
v
)
}
stack
.
pushN
(
*
new
(
uint256
.
Int
)
.
SetUint64
(
0x1
),
*
new
(
uint256
.
Int
))
opMstore
(
&
pc
,
evmInterpreter
,
&
callCtx
{
mem
,
stack
,
rstack
,
nil
})
opMstore
(
&
pc
,
evmInterpreter
,
&
callCtx
{
mem
,
stack
,
nil
})
if
common
.
Bytes2Hex
(
mem
.
GetCopy
(
0
,
32
))
!=
"0000000000000000000000000000000000000000000000000000000000000001"
{
t
.
Fatalf
(
"Mstore failed to overwrite previous value"
)
}
...
...
@@ -540,7 +539,7 @@ func TestOpMstore(t *testing.T) {
func
BenchmarkOpMstore
(
bench
*
testing
.
B
)
{
var
(
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
,
rstack
=
newstack
(),
newReturnS
tack
()
stack
=
news
tack
()
mem
=
NewMemory
()
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
vmConfig
)
)
...
...
@@ -554,14 +553,14 @@ func BenchmarkOpMstore(bench *testing.B) {
bench
.
ResetTimer
()
for
i
:=
0
;
i
<
bench
.
N
;
i
++
{
stack
.
pushN
(
*
value
,
*
memStart
)
opMstore
(
&
pc
,
evmInterpreter
,
&
callCtx
{
mem
,
stack
,
rstack
,
nil
})
opMstore
(
&
pc
,
evmInterpreter
,
&
callCtx
{
mem
,
stack
,
nil
})
}
}
func
BenchmarkOpSHA3
(
bench
*
testing
.
B
)
{
var
(
env
=
NewEVM
(
BlockContext
{},
TxContext
{},
nil
,
params
.
TestChainConfig
,
Config
{})
stack
,
rstack
=
newstack
(),
newReturnS
tack
()
stack
=
news
tack
()
mem
=
NewMemory
()
evmInterpreter
=
NewEVMInterpreter
(
env
,
env
.
vmConfig
)
)
...
...
@@ -573,7 +572,7 @@ func BenchmarkOpSHA3(bench *testing.B) {
bench
.
ResetTimer
()
for
i
:=
0
;
i
<
bench
.
N
;
i
++
{
stack
.
pushN
(
*
uint256
.
NewInt
()
.
SetUint64
(
32
),
*
start
)
opSha3
(
&
pc
,
evmInterpreter
,
&
callCtx
{
mem
,
stack
,
rstack
,
nil
})
opSha3
(
&
pc
,
evmInterpreter
,
&
callCtx
{
mem
,
stack
,
nil
})
}
}
...
...
core/vm/interpreter.go
View file @
7834e4a2
...
...
@@ -67,7 +67,6 @@ type Interpreter interface {
type
callCtx
struct
{
memory
*
Memory
stack
*
Stack
rstack
*
ReturnStack
contract
*
Contract
}
...
...
@@ -161,14 +160,12 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
}
var
(
op
OpCode
// current opcode
mem
=
NewMemory
()
// bound memory
stack
=
newstack
()
// local stack
returns
=
newReturnStack
()
// local returns stack
op
OpCode
// current opcode
mem
=
NewMemory
()
// bound memory
stack
=
newstack
()
// local stack
callContext
=
&
callCtx
{
memory
:
mem
,
stack
:
stack
,
rstack
:
returns
,
contract
:
contract
,
}
// For optimisation reason we're using uint64 as the program counter.
...
...
@@ -187,7 +184,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// they are returned to the pools
defer
func
()
{
returnStack
(
stack
)
returnRStack
(
returns
)
}()
contract
.
Input
=
input
...
...
@@ -195,9 +191,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
defer
func
()
{
if
err
!=
nil
{
if
!
logged
{
in
.
cfg
.
Tracer
.
CaptureState
(
in
.
evm
,
pcCopy
,
op
,
gasCopy
,
cost
,
mem
,
stack
,
returns
,
in
.
returnData
,
contract
,
in
.
evm
.
depth
,
err
)
in
.
cfg
.
Tracer
.
CaptureState
(
in
.
evm
,
pcCopy
,
op
,
gasCopy
,
cost
,
mem
,
stack
,
in
.
returnData
,
contract
,
in
.
evm
.
depth
,
err
)
}
else
{
in
.
cfg
.
Tracer
.
CaptureFault
(
in
.
evm
,
pcCopy
,
op
,
gasCopy
,
cost
,
mem
,
stack
,
returns
,
contract
,
in
.
evm
.
depth
,
err
)
in
.
cfg
.
Tracer
.
CaptureFault
(
in
.
evm
,
pcCopy
,
op
,
gasCopy
,
cost
,
mem
,
stack
,
contract
,
in
.
evm
.
depth
,
err
)
}
}
}()
...
...
@@ -279,7 +275,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
}
if
in
.
cfg
.
Debug
{
in
.
cfg
.
Tracer
.
CaptureState
(
in
.
evm
,
pc
,
op
,
gasCopy
,
cost
,
mem
,
stack
,
returns
,
in
.
returnData
,
contract
,
in
.
evm
.
depth
,
err
)
in
.
cfg
.
Tracer
.
CaptureState
(
in
.
evm
,
pc
,
op
,
gasCopy
,
cost
,
mem
,
stack
,
in
.
returnData
,
contract
,
in
.
evm
.
depth
,
err
)
logged
=
true
}
...
...
core/vm/jump_table.go
View file @
7834e4a2
...
...
@@ -66,7 +66,6 @@ type JumpTable [256]*operation
// contantinople, istanbul, petersburg and berlin instructions.
func
newBerlinInstructionSet
()
JumpTable
{
instructionSet
:=
newIstanbulInstructionSet
()
enable2315
(
&
instructionSet
)
// Subroutines - https://eips.ethereum.org/EIPS/eip-2315
enable2929
(
&
instructionSet
)
// Access lists for trie accesses https://eips.ethereum.org/EIPS/eip-2929
return
instructionSet
}
...
...
core/vm/logger.go
View file @
7834e4a2
...
...
@@ -70,7 +70,6 @@ type StructLog struct {
Memory
[]
byte
`json:"memory"`
MemorySize
int
`json:"memSize"`
Stack
[]
*
big
.
Int
`json:"stack"`
ReturnStack
[]
uint32
`json:"returnStack"`
ReturnData
[]
byte
`json:"returnData"`
Storage
map
[
common
.
Hash
]
common
.
Hash
`json:"-"`
Depth
int
`json:"depth"`
...
...
@@ -81,7 +80,6 @@ type StructLog struct {
// overrides for gencodec
type
structLogMarshaling
struct
{
Stack
[]
*
math
.
HexOrDecimal256
ReturnStack
[]
math
.
HexOrDecimal64
Gas
math
.
HexOrDecimal64
GasCost
math
.
HexOrDecimal64
Memory
hexutil
.
Bytes
...
...
@@ -110,8 +108,8 @@ func (s *StructLog) ErrorString() string {
// if you need to retain them beyond the current call.
type
Tracer
interface
{
CaptureStart
(
from
common
.
Address
,
to
common
.
Address
,
create
bool
,
input
[]
byte
,
gas
uint64
,
value
*
big
.
Int
)
error
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
r
Stack
*
ReturnStack
,
r
Data
[]
byte
,
contract
*
Contract
,
depth
int
,
err
error
)
error
CaptureFault
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
rStack
*
ReturnStack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
rData
[]
byte
,
contract
*
Contract
,
depth
int
,
err
error
)
error
CaptureFault
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
CaptureEnd
(
output
[]
byte
,
gasUsed
uint64
,
t
time
.
Duration
,
err
error
)
error
}
...
...
@@ -148,7 +146,7 @@ func (l *StructLogger) CaptureStart(from common.Address, to common.Address, crea
// CaptureState logs a new structured log message and pushes it out to the environment
//
// CaptureState also tracks SLOAD/SSTORE ops to track storage change.
func
(
l
*
StructLogger
)
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
r
Stack
*
ReturnStack
,
r
Data
[]
byte
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
func
(
l
*
StructLogger
)
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
rData
[]
byte
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
// check if already accumulated the specified number of logs
if
l
.
cfg
.
Limit
!=
0
&&
l
.
cfg
.
Limit
<=
len
(
l
.
logs
)
{
return
errTraceLimitReached
...
...
@@ -167,11 +165,6 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
stck
[
i
]
=
new
(
big
.
Int
)
.
Set
(
item
.
ToBig
())
}
}
var
rstack
[]
uint32
if
!
l
.
cfg
.
DisableStack
&&
rStack
!=
nil
{
rstck
:=
make
([]
uint32
,
len
(
rStack
.
data
))
copy
(
rstck
,
rStack
.
data
)
}
// Copy a snapshot of the current storage to a new container
var
storage
Storage
if
!
l
.
cfg
.
DisableStorage
{
...
...
@@ -204,14 +197,14 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
copy
(
rdata
,
rData
)
}
// create a new snapshot of the EVM.
log
:=
StructLog
{
pc
,
op
,
gas
,
cost
,
mem
,
memory
.
Len
(),
stck
,
r
stack
,
r
data
,
storage
,
depth
,
env
.
StateDB
.
GetRefund
(),
err
}
log
:=
StructLog
{
pc
,
op
,
gas
,
cost
,
mem
,
memory
.
Len
(),
stck
,
rdata
,
storage
,
depth
,
env
.
StateDB
.
GetRefund
(),
err
}
l
.
logs
=
append
(
l
.
logs
,
log
)
return
nil
}
// CaptureFault implements the Tracer interface to trace an execution fault
// while running an opcode.
func
(
l
*
StructLogger
)
CaptureFault
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
rStack
*
ReturnStack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
func
(
l
*
StructLogger
)
CaptureFault
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
return
nil
}
...
...
@@ -252,12 +245,6 @@ func WriteTrace(writer io.Writer, logs []StructLog) {
fmt
.
Fprintf
(
writer
,
"%08d %x
\n
"
,
len
(
log
.
Stack
)
-
i
-
1
,
math
.
PaddedBigBytes
(
log
.
Stack
[
i
],
32
))
}
}
if
len
(
log
.
ReturnStack
)
>
0
{
fmt
.
Fprintln
(
writer
,
"ReturnStack:"
)
for
i
:=
len
(
log
.
Stack
)
-
1
;
i
>=
0
;
i
--
{
fmt
.
Fprintf
(
writer
,
"%08d 0x%x (%d)
\n
"
,
len
(
log
.
Stack
)
-
i
-
1
,
log
.
ReturnStack
[
i
],
log
.
ReturnStack
[
i
])
}
}
if
len
(
log
.
Memory
)
>
0
{
fmt
.
Fprintln
(
writer
,
"Memory:"
)
fmt
.
Fprint
(
writer
,
hex
.
Dump
(
log
.
Memory
))
...
...
@@ -323,7 +310,7 @@ func (t *mdLogger) CaptureStart(from common.Address, to common.Address, create b
return
nil
}
func
(
t
*
mdLogger
)
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
r
Stack
*
ReturnStack
,
r
Data
[]
byte
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
func
(
t
*
mdLogger
)
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
rData
[]
byte
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
fmt
.
Fprintf
(
t
.
out
,
"| %4d | %10v | %3d |"
,
pc
,
op
,
cost
)
if
!
t
.
cfg
.
DisableStack
{
...
...
@@ -334,14 +321,6 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64
}
b
:=
fmt
.
Sprintf
(
"[%v]"
,
strings
.
Join
(
a
,
","
))
fmt
.
Fprintf
(
t
.
out
,
"%10v |"
,
b
)
// format return stack
a
=
a
[
:
0
]
for
_
,
elem
:=
range
rStack
.
data
{
a
=
append
(
a
,
fmt
.
Sprintf
(
"%2d"
,
elem
))
}
b
=
fmt
.
Sprintf
(
"[%v]"
,
strings
.
Join
(
a
,
","
))
fmt
.
Fprintf
(
t
.
out
,
"%10v |"
,
b
)
}
fmt
.
Fprintf
(
t
.
out
,
"%10v |"
,
env
.
StateDB
.
GetRefund
())
fmt
.
Fprintln
(
t
.
out
,
""
)
...
...
@@ -351,7 +330,7 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64
return
nil
}
func
(
t
*
mdLogger
)
CaptureFault
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
rStack
*
ReturnStack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
func
(
t
*
mdLogger
)
CaptureFault
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
fmt
.
Fprintf
(
t
.
out
,
"
\n
Error: at pc=%d, op=%v: %v
\n
"
,
pc
,
op
,
err
)
...
...
core/vm/logger_json.go
View file @
7834e4a2
...
...
@@ -46,7 +46,7 @@ func (l *JSONLogger) CaptureStart(from common.Address, to common.Address, create
}
// CaptureState outputs state information on the logger.
func
(
l
*
JSONLogger
)
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
r
Stack
*
ReturnStack
,
r
Data
[]
byte
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
func
(
l
*
JSONLogger
)
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
rData
[]
byte
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
log
:=
StructLog
{
Pc
:
pc
,
Op
:
op
,
...
...
@@ -68,7 +68,6 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
logstack
[
i
]
=
item
.
ToBig
()
}
log
.
Stack
=
logstack
log
.
ReturnStack
=
rStack
.
data
}
if
!
l
.
cfg
.
DisableReturnData
{
log
.
ReturnData
=
rData
...
...
@@ -77,7 +76,7 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
}
// CaptureFault outputs state information on the logger.
func
(
l
*
JSONLogger
)
CaptureFault
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
rStack
*
ReturnStack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
func
(
l
*
JSONLogger
)
CaptureFault
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
return
nil
}
...
...
core/vm/logger_test.go
View file @
7834e4a2
...
...
@@ -55,13 +55,12 @@ func TestStoreCapture(t *testing.T) {
logger
=
NewStructLogger
(
nil
)
mem
=
NewMemory
()
stack
=
newstack
()
rstack
=
newReturnStack
()
contract
=
NewContract
(
&
dummyContractRef
{},
&
dummyContractRef
{},
new
(
big
.
Int
),
0
)
)
stack
.
push
(
uint256
.
NewInt
()
.
SetUint64
(
1
))
stack
.
push
(
uint256
.
NewInt
())
var
index
common
.
Hash
logger
.
CaptureState
(
env
,
0
,
SSTORE
,
0
,
0
,
mem
,
stack
,
rstack
,
nil
,
contract
,
0
,
nil
)
logger
.
CaptureState
(
env
,
0
,
SSTORE
,
0
,
0
,
mem
,
stack
,
nil
,
contract
,
0
,
nil
)
if
len
(
logger
.
storage
[
contract
.
Address
()])
==
0
{
t
.
Fatalf
(
"expected exactly 1 changed value on address %x, got %d"
,
contract
.
Address
(),
len
(
logger
.
storage
[
contract
.
Address
()]))
}
...
...
core/vm/opcodes.go
View file @
7834e4a2
...
...
@@ -107,21 +107,18 @@ const (
// 0x50 range - 'storage' and execution.
const
(
POP
OpCode
=
0x50
MLOAD
OpCode
=
0x51
MSTORE
OpCode
=
0x52
MSTORE8
OpCode
=
0x53
SLOAD
OpCode
=
0x54
SSTORE
OpCode
=
0x55
JUMP
OpCode
=
0x56
JUMPI
OpCode
=
0x57
PC
OpCode
=
0x58
MSIZE
OpCode
=
0x59
GAS
OpCode
=
0x5a
JUMPDEST
OpCode
=
0x5b
BEGINSUB
OpCode
=
0x5c
RETURNSUB
OpCode
=
0x5d
JUMPSUB
OpCode
=
0x5e
POP
OpCode
=
0x50
MLOAD
OpCode
=
0x51
MSTORE
OpCode
=
0x52
MSTORE8
OpCode
=
0x53
SLOAD
OpCode
=
0x54
SSTORE
OpCode
=
0x55
JUMP
OpCode
=
0x56
JUMPI
OpCode
=
0x57
PC
OpCode
=
0x58
MSIZE
OpCode
=
0x59
GAS
OpCode
=
0x5a
JUMPDEST
OpCode
=
0x5b
)
// 0x60 range.
...
...
@@ -300,10 +297,6 @@ var opCodeToString = map[OpCode]string{
GAS
:
"GAS"
,
JUMPDEST
:
"JUMPDEST"
,
BEGINSUB
:
"BEGINSUB"
,
JUMPSUB
:
"JUMPSUB"
,
RETURNSUB
:
"RETURNSUB"
,
// 0x60 range - push.
PUSH1
:
"PUSH1"
,
PUSH2
:
"PUSH2"
,
...
...
@@ -468,9 +461,6 @@ var stringToOp = map[string]OpCode{
"MSIZE"
:
MSIZE
,
"GAS"
:
GAS
,
"JUMPDEST"
:
JUMPDEST
,
"BEGINSUB"
:
BEGINSUB
,
"RETURNSUB"
:
RETURNSUB
,
"JUMPSUB"
:
JUMPSUB
,
"PUSH1"
:
PUSH1
,
"PUSH2"
:
PUSH2
,
"PUSH3"
:
PUSH3
,
...
...
core/vm/stack.go
View file @
7834e4a2
...
...
@@ -98,34 +98,3 @@ func (st *Stack) Print() {
}
fmt
.
Println
(
"#############"
)
}
var
rStackPool
=
sync
.
Pool
{
New
:
func
()
interface
{}
{
return
&
ReturnStack
{
data
:
make
([]
uint32
,
0
,
10
)}
},
}
// ReturnStack is an object for basic return stack operations.
type
ReturnStack
struct
{
data
[]
uint32
}
func
newReturnStack
()
*
ReturnStack
{
return
rStackPool
.
Get
()
.
(
*
ReturnStack
)
}
func
returnRStack
(
rs
*
ReturnStack
)
{
rs
.
data
=
rs
.
data
[
:
0
]
rStackPool
.
Put
(
rs
)
}
func
(
st
*
ReturnStack
)
push
(
d
uint32
)
{
st
.
data
=
append
(
st
.
data
,
d
)
}
// A uint32 is sufficient as for code below 4.2G
func
(
st
*
ReturnStack
)
pop
()
(
ret
uint32
)
{
ret
=
st
.
data
[
len
(
st
.
data
)
-
1
]
st
.
data
=
st
.
data
[
:
len
(
st
.
data
)
-
1
]
return
}
eth/tracers/tracer.go
View file @
7834e4a2
...
...
@@ -544,7 +544,7 @@ func (jst *Tracer) CaptureStart(from common.Address, to common.Address, create b
}
// CaptureState implements the Tracer interface to trace a single step of VM execution.
func
(
jst
*
Tracer
)
CaptureState
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
memory
*
vm
.
Memory
,
stack
*
vm
.
Stack
,
r
Stack
*
vm
.
ReturnStack
,
r
data
[]
byte
,
contract
*
vm
.
Contract
,
depth
int
,
err
error
)
error
{
func
(
jst
*
Tracer
)
CaptureState
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
memory
*
vm
.
Memory
,
stack
*
vm
.
Stack
,
rdata
[]
byte
,
contract
*
vm
.
Contract
,
depth
int
,
err
error
)
error
{
if
jst
.
err
==
nil
{
// Initialize the context if it wasn't done yet
if
!
jst
.
inited
{
...
...
@@ -595,7 +595,7 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
// CaptureFault implements the Tracer interface to trace an execution fault
// while running an opcode.
func
(
jst
*
Tracer
)
CaptureFault
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
memory
*
vm
.
Memory
,
stack
*
vm
.
Stack
,
rStack
*
vm
.
ReturnStack
,
contract
*
vm
.
Contract
,
depth
int
,
err
error
)
error
{
func
(
jst
*
Tracer
)
CaptureFault
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
memory
*
vm
.
Memory
,
stack
*
vm
.
Stack
,
contract
*
vm
.
Contract
,
depth
int
,
err
error
)
error
{
if
jst
.
err
==
nil
{
// Apart from the error, everything matches the previous invocation
jst
.
errorValue
=
new
(
string
)
...
...
eth/tracers/tracer_test.go
View file @
7834e4a2
...
...
@@ -152,10 +152,10 @@ func TestHaltBetweenSteps(t *testing.T) {
env
:=
vm
.
NewEVM
(
vm
.
BlockContext
{
BlockNumber
:
big
.
NewInt
(
1
)},
vm
.
TxContext
{},
&
dummyStatedb
{},
params
.
TestChainConfig
,
vm
.
Config
{
Debug
:
true
,
Tracer
:
tracer
})
contract
:=
vm
.
NewContract
(
&
account
{},
&
account
{},
big
.
NewInt
(
0
),
0
)
tracer
.
CaptureState
(
env
,
0
,
0
,
0
,
0
,
nil
,
nil
,
nil
,
nil
,
contract
,
0
,
nil
)
tracer
.
CaptureState
(
env
,
0
,
0
,
0
,
0
,
nil
,
nil
,
nil
,
contract
,
0
,
nil
)
timeout
:=
errors
.
New
(
"stahp"
)
tracer
.
Stop
(
timeout
)
tracer
.
CaptureState
(
env
,
0
,
0
,
0
,
0
,
nil
,
nil
,
nil
,
nil
,
contract
,
0
,
nil
)
tracer
.
CaptureState
(
env
,
0
,
0
,
0
,
0
,
nil
,
nil
,
nil
,
contract
,
0
,
nil
)
if
_
,
err
:=
tracer
.
GetResult
();
err
.
Error
()
!=
timeout
.
Error
()
{
t
.
Errorf
(
"Expected timeout error, got %v"
,
err
)
...
...
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