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
287f9908
Commit
287f9908
authored
Jun 12, 2015
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core/vm: Improved error reporting for trace logging
parent
02d629af
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
45 additions
and
46 deletions
+45
-46
environment.go
core/vm/environment.go
+1
-0
errors.go
core/vm/errors.go
+3
-9
logger.go
core/vm/logger.go
+7
-2
vm.go
core/vm/vm.go
+34
-35
No files found.
core/vm/environment.go
View file @
287f9908
...
...
@@ -45,6 +45,7 @@ type StructLog struct {
Memory
[]
byte
Stack
[]
*
big
.
Int
Storage
map
[
common
.
Hash
][]
byte
Err
error
}
type
Account
interface
{
...
...
core/vm/errors.go
View file @
287f9908
...
...
@@ -2,20 +2,14 @@ package vm
import
(
"fmt"
"github.com/ethereum/go-ethereum/params"
"math/big"
)
type
OutOfGasError
struct
{
req
,
has
*
big
.
Int
}
func
OOG
(
req
,
has
*
big
.
Int
)
OutOfGasError
{
return
OutOfGasError
{
req
,
has
}
}
type
OutOfGasError
struct
{}
func
(
self
OutOfGasError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"out of gas! require %v, have %v"
,
self
.
req
,
self
.
has
)
return
"Out Of Gas"
}
func
IsOOGErr
(
err
error
)
bool
{
...
...
core/vm/logger.go
View file @
287f9908
...
...
@@ -9,9 +9,14 @@ import (
)
func
StdErrFormat
(
logs
[]
StructLog
)
{
fmt
.
Fprintf
(
os
.
Stderr
,
"VM S
tats %d op
s
\n
"
,
len
(
logs
))
fmt
.
Fprintf
(
os
.
Stderr
,
"VM S
TAT %d OP
s
\n
"
,
len
(
logs
))
for
_
,
log
:=
range
logs
{
fmt
.
Fprintf
(
os
.
Stderr
,
"PC %08d: %s GAS: %v COST: %v
\n
"
,
log
.
Pc
,
log
.
Op
,
log
.
Gas
,
log
.
GasCost
)
fmt
.
Fprintf
(
os
.
Stderr
,
"PC %08d: %s GAS: %v COST: %v"
,
log
.
Pc
,
log
.
Op
,
log
.
Gas
,
log
.
GasCost
)
if
log
.
Err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
" ERROR: %v"
,
log
.
Err
)
}
fmt
.
Fprintf
(
os
.
Stderr
,
"
\n
"
)
fmt
.
Fprintln
(
os
.
Stderr
,
"STACK ="
,
len
(
log
.
Stack
))
for
i
:=
len
(
log
.
Stack
)
-
1
;
i
>=
0
;
i
--
{
...
...
core/vm/vm.go
View file @
287f9908
...
...
@@ -43,6 +43,31 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
code
=
context
.
Code
value
=
context
.
value
price
=
context
.
Price
op
OpCode
// current opcode
codehash
=
crypto
.
Sha3Hash
(
code
)
// codehash is used when doing jump dest caching
mem
=
NewMemory
()
// bound memory
stack
=
newstack
()
// local stack
statedb
=
self
.
env
.
State
()
// current state
// For optimisation reason we're using uint64 as the program counter.
// It's theoretically possible to go above 2^64. The YP defines the PC to be uint256. Pratically much less so feasible.
pc
=
uint64
(
0
)
// program counter
// jump evaluates and checks whether the given jump destination is a valid one
// if valid move the `pc` otherwise return an error.
jump
=
func
(
from
uint64
,
to
*
big
.
Int
)
error
{
if
!
context
.
jumpdests
.
has
(
codehash
,
code
,
to
)
{
nop
:=
context
.
GetOp
(
to
.
Uint64
())
return
fmt
.
Errorf
(
"invalid jump destination (%v) %v"
,
nop
,
to
)
}
pc
=
to
.
Uint64
()
return
nil
}
newMemSize
*
big
.
Int
cost
*
big
.
Int
)
// User defer pattern to check for an error and, based on the error being nil or not, use all gas and return.
...
...
@@ -52,6 +77,7 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
}
if
err
!=
nil
{
self
.
log
(
pc
,
op
,
context
.
Gas
,
cost
,
mem
,
stack
,
context
,
err
)
// In case of a VM exception (known exceptions) all gas consumed (panics NOT included).
context
.
UseGas
(
context
.
Gas
)
...
...
@@ -71,30 +97,6 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
return
context
.
Return
(
nil
),
nil
}
var
(
op
OpCode
// current opcode
codehash
=
crypto
.
Sha3Hash
(
code
)
// codehash is used when doing jump dest caching
mem
=
NewMemory
()
// bound memory
stack
=
newstack
()
// local stack
statedb
=
self
.
env
.
State
()
// current state
// For optimisation reason we're using uint64 as the program counter.
// It's theoretically possible to go above 2^64. The YP defines the PC to be uint256. Pratically much less so feasible.
pc
=
uint64
(
0
)
// program counter
// jump evaluates and checks whether the given jump destination is a valid one
// if valid move the `pc` otherwise return an error.
jump
=
func
(
from
uint64
,
to
*
big
.
Int
)
error
{
if
!
context
.
jumpdests
.
has
(
codehash
,
code
,
to
)
{
nop
:=
context
.
GetOp
(
to
.
Uint64
())
return
fmt
.
Errorf
(
"invalid jump destination (%v) %v"
,
nop
,
to
)
}
pc
=
to
.
Uint64
()
return
nil
}
)
for
{
// The base for all big integer arithmetic
base
:=
new
(
big
.
Int
)
...
...
@@ -103,24 +105,23 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
op
=
context
.
GetOp
(
pc
)
// calculate the new memory size and gas price for the current executing opcode
newMemSize
,
gas
,
err
:
=
self
.
calculateGasAndSize
(
context
,
caller
,
op
,
statedb
,
mem
,
stack
)
newMemSize
,
cost
,
err
=
self
.
calculateGasAndSize
(
context
,
caller
,
op
,
statedb
,
mem
,
stack
)
if
err
!=
nil
{
return
nil
,
err
}
self
.
log
(
pc
,
op
,
context
.
Gas
,
gas
,
mem
,
stack
,
context
)
// Use the calculated gas. When insufficient gas is present, use all gas and return an
// Out Of Gas error
if
!
context
.
UseGas
(
gas
)
{
tmp
:=
new
(
big
.
Int
)
.
Set
(
context
.
Gas
)
if
!
context
.
UseGas
(
cost
)
{
context
.
UseGas
(
context
.
Gas
)
return
context
.
Return
(
nil
),
O
OG
(
gas
,
tmp
)
return
context
.
Return
(
nil
),
O
utOfGasError
{}
}
// Resize the memory calculated previously
mem
.
Resize
(
newMemSize
.
Uint64
())
// Add a log message
self
.
log
(
pc
,
op
,
context
.
Gas
,
cost
,
mem
,
stack
,
context
,
nil
)
switch
op
{
case
ADD
:
...
...
@@ -783,15 +784,13 @@ func (self *Vm) RunPrecompiled(p *PrecompiledAccount, input []byte, context *Con
return
context
.
Return
(
ret
),
nil
}
else
{
tmp
:=
new
(
big
.
Int
)
.
Set
(
context
.
Gas
)
return
nil
,
OOG
(
gas
,
tmp
)
return
nil
,
OutOfGasError
{}
}
}
// log emits a log event to the environment for each opcode encountered. This is not to be confused with the
// LOG* opcode.
func
(
self
*
Vm
)
log
(
pc
uint64
,
op
OpCode
,
gas
,
cost
*
big
.
Int
,
memory
*
Memory
,
stack
*
stack
,
context
*
Context
)
{
func
(
self
*
Vm
)
log
(
pc
uint64
,
op
OpCode
,
gas
,
cost
*
big
.
Int
,
memory
*
Memory
,
stack
*
stack
,
context
*
Context
,
err
error
)
{
if
Debug
{
mem
:=
make
([]
byte
,
len
(
memory
.
Data
()))
copy
(
mem
,
memory
.
Data
())
...
...
@@ -804,7 +803,7 @@ func (self *Vm) log(pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, st
storage
[
common
.
BytesToHash
(
k
)]
=
v
})
self
.
env
.
AddStructLog
(
StructLog
{
pc
,
op
,
new
(
big
.
Int
)
.
Set
(
gas
),
cost
,
mem
,
stck
,
storage
})
self
.
env
.
AddStructLog
(
StructLog
{
pc
,
op
,
new
(
big
.
Int
)
.
Set
(
gas
),
cost
,
mem
,
stck
,
storage
,
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