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
80f7c6c2
Commit
80f7c6c2
authored
Jun 07, 2017
by
Martin Holst Swende
Committed by
Felix Lange
Jun 07, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd/evm: add --prestate, --sender, --json flags for fuzzing (#14476)
parent
bc24b7a9
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
295 additions
and
35 deletions
+295
-35
json_logger.go
cmd/evm/json_logger.go
+60
-0
main.go
cmd/evm/main.go
+15
-0
runner.go
cmd/evm/runner.go
+71
-16
gen_structlog.go
core/vm/gen_structlog.go
+95
-0
logger.go
core/vm/logger.go
+40
-12
runtime.go
core/vm/runtime/runtime.go
+6
-6
runtime_test.go
core/vm/runtime/runtime_test.go
+1
-1
tracer.go
internal/ethapi/tracer.go
+7
-0
No files found.
cmd/evm/json_logger.go
0 → 100644
View file @
80f7c6c2
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
main
import
(
"encoding/json"
"io"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/vm"
)
type
JSONLogger
struct
{
encoder
*
json
.
Encoder
}
func
NewJSONLogger
(
writer
io
.
Writer
)
*
JSONLogger
{
return
&
JSONLogger
{
json
.
NewEncoder
(
writer
)}
}
// CaptureState outputs state information on the logger.
func
(
l
*
JSONLogger
)
CaptureState
(
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
{
return
l
.
encoder
.
Encode
(
vm
.
StructLog
{
Pc
:
pc
,
Op
:
op
,
Gas
:
gas
+
cost
,
GasCost
:
cost
,
Memory
:
memory
.
Data
(),
Stack
:
stack
.
Data
(),
Storage
:
nil
,
Depth
:
depth
,
Err
:
err
,
})
}
// CaptureEnd is triggered at end of execution.
func
(
l
*
JSONLogger
)
CaptureEnd
(
output
[]
byte
,
gasUsed
uint64
,
t
time
.
Duration
)
error
{
type
endLog
struct
{
Output
string
`json:"output"`
GasUsed
math
.
HexOrDecimal64
`json:"gasUsed"`
Time
time
.
Duration
`json:"time"`
}
return
l
.
encoder
.
Encode
(
endLog
{
common
.
Bytes2Hex
(
output
),
math
.
HexOrDecimal64
(
gasUsed
),
t
})
}
cmd/evm/main.go
View file @
80f7c6c2
...
@@ -90,6 +90,18 @@ var (
...
@@ -90,6 +90,18 @@ var (
Name
:
"nogasmetering"
,
Name
:
"nogasmetering"
,
Usage
:
"disable gas metering"
,
Usage
:
"disable gas metering"
,
}
}
GenesisFlag
=
cli
.
StringFlag
{
Name
:
"prestate"
,
Usage
:
"JSON file with prestate (genesis) config"
,
}
MachineFlag
=
cli
.
BoolFlag
{
Name
:
"json"
,
Usage
:
"output trace logs in machine readable format (json)"
,
}
SenderFlag
=
cli
.
StringFlag
{
Name
:
"sender"
,
Usage
:
"The transaction origin"
,
}
)
)
func
init
()
{
func
init
()
{
...
@@ -108,6 +120,9 @@ func init() {
...
@@ -108,6 +120,9 @@ func init() {
MemProfileFlag
,
MemProfileFlag
,
CPUProfileFlag
,
CPUProfileFlag
,
StatDumpFlag
,
StatDumpFlag
,
GenesisFlag
,
MachineFlag
,
SenderFlag
,
}
}
app
.
Commands
=
[]
cli
.
Command
{
app
.
Commands
=
[]
cli
.
Command
{
compileCommand
,
compileCommand
,
...
...
cmd/evm/runner.go
View file @
80f7c6c2
...
@@ -18,6 +18,7 @@ package main
...
@@ -18,6 +18,7 @@ package main
import
(
import
(
"bytes"
"bytes"
"encoding/json"
"fmt"
"fmt"
"io/ioutil"
"io/ioutil"
"os"
"os"
...
@@ -29,11 +30,13 @@ import (
...
@@ -29,11 +30,13 @@ import (
"github.com/ethereum/go-ethereum/cmd/evm/internal/compiler"
"github.com/ethereum/go-ethereum/cmd/evm/internal/compiler"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/core/vm/runtime"
"github.com/ethereum/go-ethereum/core/vm/runtime"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
cli
"gopkg.in/urfave/cli.v1"
cli
"gopkg.in/urfave/cli.v1"
)
)
...
@@ -45,17 +48,59 @@ var runCommand = cli.Command{
...
@@ -45,17 +48,59 @@ var runCommand = cli.Command{
Description
:
`The run command runs arbitrary EVM code.`
,
Description
:
`The run command runs arbitrary EVM code.`
,
}
}
// readGenesis will read the given JSON format genesis file and return
// the initialized Genesis structure
func
readGenesis
(
genesisPath
string
)
*
core
.
Genesis
{
// Make sure we have a valid genesis JSON
//genesisPath := ctx.Args().First()
if
len
(
genesisPath
)
==
0
{
utils
.
Fatalf
(
"Must supply path to genesis JSON file"
)
}
file
,
err
:=
os
.
Open
(
genesisPath
)
if
err
!=
nil
{
utils
.
Fatalf
(
"Failed to read genesis file: %v"
,
err
)
}
defer
file
.
Close
()
genesis
:=
new
(
core
.
Genesis
)
if
err
:=
json
.
NewDecoder
(
file
)
.
Decode
(
genesis
);
err
!=
nil
{
utils
.
Fatalf
(
"invalid genesis file: %v"
,
err
)
}
return
genesis
}
func
runCmd
(
ctx
*
cli
.
Context
)
error
{
func
runCmd
(
ctx
*
cli
.
Context
)
error
{
glogger
:=
log
.
NewGlogHandler
(
log
.
StreamHandler
(
os
.
Stderr
,
log
.
TerminalFormat
(
false
)))
glogger
:=
log
.
NewGlogHandler
(
log
.
StreamHandler
(
os
.
Stderr
,
log
.
TerminalFormat
(
false
)))
glogger
.
Verbosity
(
log
.
Lvl
(
ctx
.
GlobalInt
(
VerbosityFlag
.
Name
)))
glogger
.
Verbosity
(
log
.
Lvl
(
ctx
.
GlobalInt
(
VerbosityFlag
.
Name
)))
log
.
Root
()
.
SetHandler
(
glogger
)
log
.
Root
()
.
SetHandler
(
glogger
)
var
(
var
(
db
,
_
=
ethdb
.
NewMemDatabase
()
tracer
vm
.
Tracer
statedb
,
_
=
state
.
New
(
common
.
Hash
{},
db
)
debugLogger
*
vm
.
StructLogger
sender
=
common
.
StringToAddress
(
"sender"
)
statedb
*
state
.
StateDB
logger
=
vm
.
NewStructLogger
(
nil
)
chainConfig
*
params
.
ChainConfig
sender
=
common
.
StringToAddress
(
"sender"
)
)
)
if
ctx
.
GlobalBool
(
MachineFlag
.
Name
)
{
tracer
=
NewJSONLogger
(
os
.
Stdout
)
}
else
if
ctx
.
GlobalBool
(
DebugFlag
.
Name
)
{
debugLogger
=
vm
.
NewStructLogger
(
nil
)
tracer
=
debugLogger
}
else
{
debugLogger
=
vm
.
NewStructLogger
(
nil
)
}
if
ctx
.
GlobalString
(
GenesisFlag
.
Name
)
!=
""
{
gen
:=
readGenesis
(
ctx
.
GlobalString
(
GenesisFlag
.
Name
))
_
,
statedb
=
gen
.
ToBlock
()
chainConfig
=
gen
.
Config
}
else
{
var
db
,
_
=
ethdb
.
NewMemDatabase
()
statedb
,
_
=
state
.
New
(
common
.
Hash
{},
db
)
}
if
ctx
.
GlobalString
(
SenderFlag
.
Name
)
!=
""
{
sender
=
common
.
HexToAddress
(
ctx
.
GlobalString
(
SenderFlag
.
Name
))
}
statedb
.
CreateAccount
(
sender
)
statedb
.
CreateAccount
(
sender
)
var
(
var
(
...
@@ -95,16 +140,16 @@ func runCmd(ctx *cli.Context) error {
...
@@ -95,16 +140,16 @@ func runCmd(ctx *cli.Context) error {
}
}
code
=
common
.
Hex2Bytes
(
string
(
bytes
.
TrimRight
(
hexcode
,
"
\n
"
)))
code
=
common
.
Hex2Bytes
(
string
(
bytes
.
TrimRight
(
hexcode
,
"
\n
"
)))
}
}
initialGas
:=
ctx
.
GlobalUint64
(
GasFlag
.
Name
)
runtimeConfig
:=
runtime
.
Config
{
runtimeConfig
:=
runtime
.
Config
{
Origin
:
sender
,
Origin
:
sender
,
State
:
statedb
,
State
:
statedb
,
GasLimit
:
ctx
.
GlobalUint64
(
GasFlag
.
Name
)
,
GasLimit
:
initialGas
,
GasPrice
:
utils
.
GlobalBig
(
ctx
,
PriceFlag
.
Name
),
GasPrice
:
utils
.
GlobalBig
(
ctx
,
PriceFlag
.
Name
),
Value
:
utils
.
GlobalBig
(
ctx
,
ValueFlag
.
Name
),
Value
:
utils
.
GlobalBig
(
ctx
,
ValueFlag
.
Name
),
EVMConfig
:
vm
.
Config
{
EVMConfig
:
vm
.
Config
{
Tracer
:
logg
er
,
Tracer
:
trac
er
,
Debug
:
ctx
.
GlobalBool
(
DebugFlag
.
Name
),
Debug
:
ctx
.
GlobalBool
(
DebugFlag
.
Name
)
||
ctx
.
GlobalBool
(
MachineFlag
.
Name
)
,
DisableGasMetering
:
ctx
.
GlobalBool
(
DisableGasMeteringFlag
.
Name
),
DisableGasMetering
:
ctx
.
GlobalBool
(
DisableGasMeteringFlag
.
Name
),
},
},
}
}
...
@@ -122,15 +167,19 @@ func runCmd(ctx *cli.Context) error {
...
@@ -122,15 +167,19 @@ func runCmd(ctx *cli.Context) error {
defer
pprof
.
StopCPUProfile
()
defer
pprof
.
StopCPUProfile
()
}
}
if
chainConfig
!=
nil
{
runtimeConfig
.
ChainConfig
=
chainConfig
}
tstart
:=
time
.
Now
()
tstart
:=
time
.
Now
()
var
leftOverGas
uint64
if
ctx
.
GlobalBool
(
CreateFlag
.
Name
)
{
if
ctx
.
GlobalBool
(
CreateFlag
.
Name
)
{
input
:=
append
(
code
,
common
.
Hex2Bytes
(
ctx
.
GlobalString
(
InputFlag
.
Name
))
...
)
input
:=
append
(
code
,
common
.
Hex2Bytes
(
ctx
.
GlobalString
(
InputFlag
.
Name
))
...
)
ret
,
_
,
err
=
runtime
.
Create
(
input
,
&
runtimeConfig
)
ret
,
_
,
leftOverGas
,
err
=
runtime
.
Create
(
input
,
&
runtimeConfig
)
}
else
{
}
else
{
receiver
:=
common
.
StringToAddress
(
"receiver"
)
receiver
:=
common
.
StringToAddress
(
"receiver"
)
statedb
.
SetCode
(
receiver
,
code
)
statedb
.
SetCode
(
receiver
,
code
)
ret
,
err
=
runtime
.
Call
(
receiver
,
common
.
Hex2Bytes
(
ctx
.
GlobalString
(
InputFlag
.
Name
)),
&
runtimeConfig
)
ret
,
leftOverGas
,
err
=
runtime
.
Call
(
receiver
,
common
.
Hex2Bytes
(
ctx
.
GlobalString
(
InputFlag
.
Name
)),
&
runtimeConfig
)
}
}
execTime
:=
time
.
Since
(
tstart
)
execTime
:=
time
.
Since
(
tstart
)
...
@@ -153,8 +202,10 @@ func runCmd(ctx *cli.Context) error {
...
@@ -153,8 +202,10 @@ func runCmd(ctx *cli.Context) error {
}
}
if
ctx
.
GlobalBool
(
DebugFlag
.
Name
)
{
if
ctx
.
GlobalBool
(
DebugFlag
.
Name
)
{
fmt
.
Fprintln
(
os
.
Stderr
,
"#### TRACE ####"
)
if
debugLogger
!=
nil
{
vm
.
WriteTrace
(
os
.
Stderr
,
logger
.
StructLogs
())
fmt
.
Fprintln
(
os
.
Stderr
,
"#### TRACE ####"
)
vm
.
WriteTrace
(
os
.
Stderr
,
debugLogger
.
StructLogs
())
}
fmt
.
Fprintln
(
os
.
Stderr
,
"#### LOGS ####"
)
fmt
.
Fprintln
(
os
.
Stderr
,
"#### LOGS ####"
)
vm
.
WriteLogs
(
os
.
Stderr
,
statedb
.
Logs
())
vm
.
WriteLogs
(
os
.
Stderr
,
statedb
.
Logs
())
}
}
...
@@ -167,14 +218,18 @@ heap objects: %d
...
@@ -167,14 +218,18 @@ heap objects: %d
allocations: %d
allocations: %d
total allocations: %d
total allocations: %d
GC calls: %d
GC calls: %d
Gas used: %d
`
,
execTime
,
mem
.
HeapObjects
,
mem
.
Alloc
,
mem
.
TotalAlloc
,
mem
.
NumGC
)
`
,
execTime
,
mem
.
HeapObjects
,
mem
.
Alloc
,
mem
.
TotalAlloc
,
mem
.
NumGC
,
initialGas
-
leftOverGas
)
}
if
tracer
!=
nil
{
tracer
.
CaptureEnd
(
ret
,
initialGas
-
leftOverGas
,
execTime
)
}
else
{
fmt
.
Printf
(
"0x%x
\n
"
,
ret
)
}
}
fmt
.
Printf
(
"0x%x"
,
ret
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Printf
(
" error: %v"
,
err
)
fmt
.
Printf
(
" error: %v
\n
"
,
err
)
}
}
fmt
.
Println
()
return
nil
return
nil
}
}
core/vm/gen_structlog.go
0 → 100644
View file @
80f7c6c2
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
package
vm
import
(
"encoding/json"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
)
func
(
s
StructLog
)
MarshalJSON
()
([]
byte
,
error
)
{
type
StructLog
struct
{
Pc
uint64
`json:"pc"`
Op
OpCode
`json:"op"`
Gas
math
.
HexOrDecimal64
`json:"gas"`
GasCost
math
.
HexOrDecimal64
`json:"gasCost"`
Memory
hexutil
.
Bytes
`json:"memory"`
Stack
[]
*
math
.
HexOrDecimal256
`json:"stack"`
Storage
map
[
common
.
Hash
]
common
.
Hash
`json:"-"`
Depth
int
`json:"depth"`
Err
error
`json:"error"`
OpName
string
`json:"opName"`
MemorySize
int
`json:"memSize"`
}
var
enc
StructLog
enc
.
Pc
=
s
.
Pc
enc
.
Op
=
s
.
Op
enc
.
Gas
=
math
.
HexOrDecimal64
(
s
.
Gas
)
enc
.
GasCost
=
math
.
HexOrDecimal64
(
s
.
GasCost
)
enc
.
Memory
=
s
.
Memory
if
s
.
Stack
!=
nil
{
enc
.
Stack
=
make
([]
*
math
.
HexOrDecimal256
,
len
(
s
.
Stack
))
for
k
,
v
:=
range
s
.
Stack
{
enc
.
Stack
[
k
]
=
(
*
math
.
HexOrDecimal256
)(
v
)
}
}
enc
.
Storage
=
s
.
Storage
enc
.
Depth
=
s
.
Depth
enc
.
Err
=
s
.
Err
enc
.
OpName
=
s
.
OpName
()
enc
.
MemorySize
=
s
.
MemorySize
()
return
json
.
Marshal
(
&
enc
)
}
func
(
s
*
StructLog
)
UnmarshalJSON
(
input
[]
byte
)
error
{
type
StructLog
struct
{
Pc
*
uint64
`json:"pc"`
Op
*
OpCode
`json:"op"`
Gas
*
math
.
HexOrDecimal64
`json:"gas"`
GasCost
*
math
.
HexOrDecimal64
`json:"gasCost"`
Memory
hexutil
.
Bytes
`json:"memory"`
Stack
[]
*
math
.
HexOrDecimal256
`json:"stack"`
Storage
map
[
common
.
Hash
]
common
.
Hash
`json:"-"`
Depth
*
int
`json:"depth"`
Err
*
error
`json:"error"`
}
var
dec
StructLog
if
err
:=
json
.
Unmarshal
(
input
,
&
dec
);
err
!=
nil
{
return
err
}
if
dec
.
Pc
!=
nil
{
s
.
Pc
=
*
dec
.
Pc
}
if
dec
.
Op
!=
nil
{
s
.
Op
=
*
dec
.
Op
}
if
dec
.
Gas
!=
nil
{
s
.
Gas
=
uint64
(
*
dec
.
Gas
)
}
if
dec
.
GasCost
!=
nil
{
s
.
GasCost
=
uint64
(
*
dec
.
GasCost
)
}
if
dec
.
Memory
!=
nil
{
s
.
Memory
=
dec
.
Memory
}
if
dec
.
Stack
!=
nil
{
s
.
Stack
=
make
([]
*
big
.
Int
,
len
(
dec
.
Stack
))
for
k
,
v
:=
range
dec
.
Stack
{
s
.
Stack
[
k
]
=
(
*
big
.
Int
)(
v
)
}
}
if
dec
.
Storage
!=
nil
{
s
.
Storage
=
dec
.
Storage
}
if
dec
.
Depth
!=
nil
{
s
.
Depth
=
*
dec
.
Depth
}
if
dec
.
Err
!=
nil
{
s
.
Err
=
*
dec
.
Err
}
return
nil
}
core/vm/logger.go
View file @
80f7c6c2
...
@@ -21,8 +21,10 @@ import (
...
@@ -21,8 +21,10 @@ import (
"fmt"
"fmt"
"io"
"io"
"math/big"
"math/big"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types"
)
)
...
@@ -47,18 +49,38 @@ type LogConfig struct {
...
@@ -47,18 +49,38 @@ type LogConfig struct {
Limit
int
// maximum length of output, but zero means unlimited
Limit
int
// maximum length of output, but zero means unlimited
}
}
//go:generate gencodec -type StructLog -field-override structLogMarshaling -out gen_structlog.go
// StructLog is emitted to the EVM each cycle and lists information about the current internal state
// StructLog is emitted to the EVM each cycle and lists information about the current internal state
// prior to the execution of the statement.
// prior to the execution of the statement.
type
StructLog
struct
{
type
StructLog
struct
{
Pc
uint64
Pc
uint64
`json:"pc"`
Op
OpCode
Op
OpCode
`json:"op"`
Gas
uint64
Gas
uint64
`json:"gas"`
GasCost
uint64
GasCost
uint64
`json:"gasCost"`
Memory
[]
byte
Memory
[]
byte
`json:"memory"`
Stack
[]
*
big
.
Int
Stack
[]
*
big
.
Int
`json:"stack"`
Storage
map
[
common
.
Hash
]
common
.
Hash
Storage
map
[
common
.
Hash
]
common
.
Hash
`json:"-"`
Depth
int
Depth
int
`json:"depth"`
Err
error
Err
error
`json:"error"`
}
// overrides for gencodec
type
structLogMarshaling
struct
{
Stack
[]
*
math
.
HexOrDecimal256
Gas
math
.
HexOrDecimal64
GasCost
math
.
HexOrDecimal64
Memory
hexutil
.
Bytes
OpName
string
`json:"opName"`
MemorySize
int
`json:"memSize"`
}
func
(
s
*
StructLog
)
OpName
()
string
{
return
s
.
Op
.
String
()
}
func
(
s
*
StructLog
)
MemorySize
()
int
{
return
len
(
s
.
Memory
)
}
}
// Tracer is used to collect execution traces from an EVM transaction
// Tracer is used to collect execution traces from an EVM transaction
...
@@ -68,6 +90,7 @@ type StructLog struct {
...
@@ -68,6 +90,7 @@ type StructLog struct {
// if you need to retain them beyond the current call.
// if you need to retain them beyond the current call.
type
Tracer
interface
{
type
Tracer
interface
{
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
CaptureState
(
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
)
error
}
}
// StructLogger is an EVM state logger and implements Tracer.
// StructLogger is an EVM state logger and implements Tracer.
...
@@ -82,7 +105,7 @@ type StructLogger struct {
...
@@ -82,7 +105,7 @@ type StructLogger struct {
changedValues
map
[
common
.
Address
]
Storage
changedValues
map
[
common
.
Address
]
Storage
}
}
// NewLogger returns a new logger
// New
Struct
Logger returns a new logger
func
NewStructLogger
(
cfg
*
LogConfig
)
*
StructLogger
{
func
NewStructLogger
(
cfg
*
LogConfig
)
*
StructLogger
{
logger
:=
&
StructLogger
{
logger
:=
&
StructLogger
{
changedValues
:
make
(
map
[
common
.
Address
]
Storage
),
changedValues
:
make
(
map
[
common
.
Address
]
Storage
),
...
@@ -93,9 +116,9 @@ func NewStructLogger(cfg *LogConfig) *StructLogger {
...
@@ -93,9 +116,9 @@ func NewStructLogger(cfg *LogConfig) *StructLogger {
return
logger
return
logger
}
}
//
c
aptureState logs a new structured log message and pushes it out to the environment
//
C
aptureState logs a new structured log message and pushes it out to the environment
//
//
//
c
aptureState also tracks SSTORE ops to track dirty values.
//
C
aptureState also tracks SSTORE ops to track dirty values.
func
(
l
*
StructLogger
)
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
func
(
l
*
StructLogger
)
CaptureState
(
env
*
EVM
,
pc
uint64
,
op
OpCode
,
gas
,
cost
uint64
,
memory
*
Memory
,
stack
*
Stack
,
contract
*
Contract
,
depth
int
,
err
error
)
error
{
// check if already accumulated the specified number of logs
// check if already accumulated the specified number of logs
if
l
.
cfg
.
Limit
!=
0
&&
l
.
cfg
.
Limit
<=
len
(
l
.
logs
)
{
if
l
.
cfg
.
Limit
!=
0
&&
l
.
cfg
.
Limit
<=
len
(
l
.
logs
)
{
...
@@ -164,6 +187,11 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
...
@@ -164,6 +187,11 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
return
nil
return
nil
}
}
func
(
l
*
StructLogger
)
CaptureEnd
(
output
[]
byte
,
gasUsed
uint64
,
t
time
.
Duration
)
error
{
fmt
.
Printf
(
"0x%x"
,
output
)
return
nil
}
// StructLogs returns a list of captured log entries
// StructLogs returns a list of captured log entries
func
(
l
*
StructLogger
)
StructLogs
()
[]
StructLog
{
func
(
l
*
StructLogger
)
StructLogs
()
[]
StructLog
{
return
l
.
logs
return
l
.
logs
...
...
core/vm/runtime/runtime.go
View file @
80f7c6c2
...
@@ -125,7 +125,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
...
@@ -125,7 +125,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
}
}
// Create executes the code using the EVM create method
// Create executes the code using the EVM create method
func
Create
(
input
[]
byte
,
cfg
*
Config
)
([]
byte
,
common
.
Address
,
error
)
{
func
Create
(
input
[]
byte
,
cfg
*
Config
)
([]
byte
,
common
.
Address
,
uint64
,
error
)
{
if
cfg
==
nil
{
if
cfg
==
nil
{
cfg
=
new
(
Config
)
cfg
=
new
(
Config
)
}
}
...
@@ -141,13 +141,13 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
...
@@ -141,13 +141,13 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
)
)
// Call the code with the given configuration.
// Call the code with the given configuration.
code
,
address
,
_
,
err
:=
vmenv
.
Create
(
code
,
address
,
leftOverGas
,
err
:=
vmenv
.
Create
(
sender
,
sender
,
input
,
input
,
cfg
.
GasLimit
,
cfg
.
GasLimit
,
cfg
.
Value
,
cfg
.
Value
,
)
)
return
code
,
address
,
err
return
code
,
address
,
leftOverGas
,
err
}
}
// Call executes the code given by the contract's address. It will return the
// Call executes the code given by the contract's address. It will return the
...
@@ -155,14 +155,14 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
...
@@ -155,14 +155,14 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
//
//
// Call, unlike Execute, requires a config and also requires the State field to
// Call, unlike Execute, requires a config and also requires the State field to
// be set.
// be set.
func
Call
(
address
common
.
Address
,
input
[]
byte
,
cfg
*
Config
)
([]
byte
,
error
)
{
func
Call
(
address
common
.
Address
,
input
[]
byte
,
cfg
*
Config
)
([]
byte
,
uint64
,
error
)
{
setDefaults
(
cfg
)
setDefaults
(
cfg
)
vmenv
:=
NewEnv
(
cfg
,
cfg
.
State
)
vmenv
:=
NewEnv
(
cfg
,
cfg
.
State
)
sender
:=
cfg
.
State
.
GetOrNewStateObject
(
cfg
.
Origin
)
sender
:=
cfg
.
State
.
GetOrNewStateObject
(
cfg
.
Origin
)
// Call the code with the given configuration.
// Call the code with the given configuration.
ret
,
_
,
err
:=
vmenv
.
Call
(
ret
,
leftOverGas
,
err
:=
vmenv
.
Call
(
sender
,
sender
,
address
,
address
,
input
,
input
,
...
@@ -170,5 +170,5 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, error) {
...
@@ -170,5 +170,5 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, error) {
cfg
.
Value
,
cfg
.
Value
,
)
)
return
ret
,
err
return
ret
,
leftOverGas
,
err
}
}
core/vm/runtime/runtime_test.go
View file @
80f7c6c2
...
@@ -106,7 +106,7 @@ func TestCall(t *testing.T) {
...
@@ -106,7 +106,7 @@ func TestCall(t *testing.T) {
byte
(
vm
.
RETURN
),
byte
(
vm
.
RETURN
),
})
})
ret
,
err
:=
Call
(
address
,
nil
,
&
Config
{
State
:
state
})
ret
,
_
,
err
:=
Call
(
address
,
nil
,
&
Config
{
State
:
state
})
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
"didn't expect error"
,
err
)
t
.
Fatal
(
"didn't expect error"
,
err
)
}
}
...
...
internal/ethapi/tracer.go
View file @
80f7c6c2
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"errors"
"errors"
"fmt"
"fmt"
"math/big"
"math/big"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/hexutil"
...
@@ -344,6 +345,12 @@ func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode,
...
@@ -344,6 +345,12 @@ func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode,
return
nil
return
nil
}
}
// CaptureEnd is called after the call finishes
func
(
jst
*
JavascriptTracer
)
CaptureEnd
(
output
[]
byte
,
gasUsed
uint64
,
t
time
.
Duration
)
error
{
//TODO! @Arachnid please figure out of there's anything we can use this method for
return
nil
}
// GetResult calls the Javascript 'result' function and returns its value, or any accumulated error
// GetResult calls the Javascript 'result' function and returns its value, or any accumulated error
func
(
jst
*
JavascriptTracer
)
GetResult
()
(
result
interface
{},
err
error
)
{
func
(
jst
*
JavascriptTracer
)
GetResult
()
(
result
interface
{},
err
error
)
{
if
jst
.
err
!=
nil
{
if
jst
.
err
!=
nil
{
...
...
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