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
0524cede
Unverified
Commit
0524cede
authored
May 11, 2021
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth/tracers: do the JSON serialization via .js to capture C faults
parent
ca980807
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
28 additions
and
10 deletions
+28
-10
tracer.go
eth/tracers/tracer.go
+19
-5
tracer_test.go
eth/tracers/tracer_test.go
+9
-5
No files found.
eth/tracers/tracer.go
View file @
0524cede
...
@@ -505,7 +505,7 @@ func (jst *Tracer) Stop(err error) {
...
@@ -505,7 +505,7 @@ func (jst *Tracer) Stop(err error) {
// call executes a method on a JS object, catching any errors, formatting and
// call executes a method on a JS object, catching any errors, formatting and
// returning them as error objects.
// returning them as error objects.
func
(
jst
*
Tracer
)
call
(
method
string
,
args
...
string
)
(
json
.
RawMessage
,
error
)
{
func
(
jst
*
Tracer
)
call
(
noret
bool
,
method
string
,
args
...
string
)
(
json
.
RawMessage
,
error
)
{
// Execute the JavaScript call and return any error
// Execute the JavaScript call and return any error
jst
.
vm
.
PushString
(
method
)
jst
.
vm
.
PushString
(
method
)
for
_
,
arg
:=
range
args
{
for
_
,
arg
:=
range
args
{
...
@@ -519,7 +519,21 @@ func (jst *Tracer) call(method string, args ...string) (json.RawMessage, error)
...
@@ -519,7 +519,21 @@ func (jst *Tracer) call(method string, args ...string) (json.RawMessage, error)
return
nil
,
errors
.
New
(
err
)
return
nil
,
errors
.
New
(
err
)
}
}
// No error occurred, extract return value and return
// No error occurred, extract return value and return
return
json
.
RawMessage
(
jst
.
vm
.
JsonEncode
(
-
1
)),
nil
if
noret
{
return
nil
,
nil
}
// Push a JSON marshaller onto the stack. We can't marshal from the out-
// side because duktape can crash on large nestings and we can't catch
// C++ exceptions ourselves from Go. TODO(karalabe): Yuck, why wrap?!
jst
.
vm
.
PushString
(
"(JSON.stringify)"
)
jst
.
vm
.
Eval
()
jst
.
vm
.
Swap
(
-
1
,
-
2
)
if
code
=
jst
.
vm
.
Pcall
(
1
);
code
!=
0
{
err
:=
jst
.
vm
.
SafeToString
(
-
1
)
return
nil
,
errors
.
New
(
err
)
}
return
json
.
RawMessage
(
jst
.
vm
.
SafeToString
(
-
1
)),
nil
}
}
func
wrapError
(
context
string
,
err
error
)
error
{
func
wrapError
(
context
string
,
err
error
)
error
{
...
@@ -578,7 +592,7 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
...
@@ -578,7 +592,7 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
*
jst
.
errorValue
=
err
.
Error
()
*
jst
.
errorValue
=
err
.
Error
()
}
}
if
_
,
err
:=
jst
.
call
(
"step"
,
"log"
,
"db"
);
err
!=
nil
{
if
_
,
err
:=
jst
.
call
(
true
,
"step"
,
"log"
,
"db"
);
err
!=
nil
{
jst
.
err
=
wrapError
(
"step"
,
err
)
jst
.
err
=
wrapError
(
"step"
,
err
)
}
}
}
}
...
@@ -592,7 +606,7 @@ func (jst *Tracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
...
@@ -592,7 +606,7 @@ func (jst *Tracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
jst
.
errorValue
=
new
(
string
)
jst
.
errorValue
=
new
(
string
)
*
jst
.
errorValue
=
err
.
Error
()
*
jst
.
errorValue
=
err
.
Error
()
if
_
,
err
:=
jst
.
call
(
"fault"
,
"log"
,
"db"
);
err
!=
nil
{
if
_
,
err
:=
jst
.
call
(
true
,
"fault"
,
"log"
,
"db"
);
err
!=
nil
{
jst
.
err
=
wrapError
(
"fault"
,
err
)
jst
.
err
=
wrapError
(
"fault"
,
err
)
}
}
}
}
...
@@ -640,7 +654,7 @@ func (jst *Tracer) GetResult() (json.RawMessage, error) {
...
@@ -640,7 +654,7 @@ func (jst *Tracer) GetResult() (json.RawMessage, error) {
jst
.
vm
.
PutPropString
(
jst
.
stateObject
,
"ctx"
)
jst
.
vm
.
PutPropString
(
jst
.
stateObject
,
"ctx"
)
// Finalize the trace and return the results
// Finalize the trace and return the results
result
,
err
:=
jst
.
call
(
"result"
,
"ctx"
,
"db"
)
result
,
err
:=
jst
.
call
(
false
,
"result"
,
"ctx"
,
"db"
)
if
err
!=
nil
{
if
err
!=
nil
{
jst
.
err
=
wrapError
(
"result"
,
err
)
jst
.
err
=
wrapError
(
"result"
,
err
)
}
}
...
...
eth/tracers/tracer_test.go
View file @
0524cede
...
@@ -78,7 +78,7 @@ func runTrace(tracer *Tracer, vmctx *vmContext) (json.RawMessage, error) {
...
@@ -78,7 +78,7 @@ func runTrace(tracer *Tracer, vmctx *vmContext) (json.RawMessage, error) {
}
}
func
TestTracer
(
t
*
testing
.
T
)
{
func
TestTracer
(
t
*
testing
.
T
)
{
execTracer
:=
func
(
code
string
)
[]
byte
{
execTracer
:=
func
(
code
string
)
([]
byte
,
string
)
{
t
.
Helper
()
t
.
Helper
()
ctx
:=
&
vmContext
{
blockCtx
:
vm
.
BlockContext
{
BlockNumber
:
big
.
NewInt
(
1
)},
txCtx
:
vm
.
TxContext
{
GasPrice
:
big
.
NewInt
(
100000
)}}
ctx
:=
&
vmContext
{
blockCtx
:
vm
.
BlockContext
{
BlockNumber
:
big
.
NewInt
(
1
)},
txCtx
:
vm
.
TxContext
{
GasPrice
:
big
.
NewInt
(
100000
)}}
tracer
,
err
:=
New
(
code
,
ctx
.
txCtx
)
tracer
,
err
:=
New
(
code
,
ctx
.
txCtx
)
...
@@ -87,13 +87,14 @@ func TestTracer(t *testing.T) {
...
@@ -87,13 +87,14 @@ func TestTracer(t *testing.T) {
}
}
ret
,
err
:=
runTrace
(
tracer
,
ctx
)
ret
,
err
:=
runTrace
(
tracer
,
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
return
nil
,
err
.
Error
()
// Stringify to allow comparison without nil checks
}
}
return
ret
return
ret
,
""
}
}
for
i
,
tt
:=
range
[]
struct
{
for
i
,
tt
:=
range
[]
struct
{
code
string
code
string
want
string
want
string
fail
string
}{
}{
{
// tests that we don't panic on bad arguments to memory access
{
// tests that we don't panic on bad arguments to memory access
code
:
"{depths: [], step: function(log) { this.depths.push(log.memory.slice(-1,-2)); }, fault: function() {}, result: function() { return this.depths; }}"
,
code
:
"{depths: [], step: function(log) { this.depths.push(log.memory.slice(-1,-2)); }, fault: function() {}, result: function() { return this.depths; }}"
,
...
@@ -116,10 +117,13 @@ func TestTracer(t *testing.T) {
...
@@ -116,10 +117,13 @@ func TestTracer(t *testing.T) {
},
{
// tests intrinsic gas
},
{
// tests intrinsic gas
code
:
"{depths: [], step: function() {}, fault: function() {}, result: function(ctx) { return ctx.gasPrice+'.'+ctx.gasUsed+'.'+ctx.intrinsicGas; }}"
,
code
:
"{depths: [], step: function() {}, fault: function() {}, result: function(ctx) { return ctx.gasPrice+'.'+ctx.gasUsed+'.'+ctx.intrinsicGas; }}"
,
want
:
`"100000.6.21000"`
,
want
:
`"100000.6.21000"`
,
},
{
// tests too deep object / serialization crash
code
:
"{step: function() {}, fault: function() {}, result: function() { var o={}; var x=o; for (var i=0; i<1000; i++){ o.foo={}; o=o.foo; } return x; }}"
,
fail
:
"RangeError: json encode recursion limit in server-side tracer function 'result'"
,
},
},
}
{
}
{
if
have
:=
execTracer
(
tt
.
code
);
tt
.
want
!=
string
(
have
)
{
if
have
,
err
:=
execTracer
(
tt
.
code
);
tt
.
want
!=
string
(
have
)
||
tt
.
fail
!=
err
{
t
.
Errorf
(
"testcase %d: expected return value to be
%s got %s
\n\t
code: %v"
,
i
,
tt
.
want
,
string
(
have
)
,
tt
.
code
)
t
.
Errorf
(
"testcase %d: expected return value to be
'%s' got '%s', error to be '%s' got '%s'
\n\t
code: %v"
,
i
,
tt
.
want
,
string
(
have
),
tt
.
fail
,
err
,
tt
.
code
)
}
}
}
}
}
}
...
...
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