Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
29905d86
G
go-ethereum
项目概览
whqwjb
/
go-ethereum
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go-ethereum
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
29905d86
编写于
6月 24, 2021
作者:
P
Péter Szilágyi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
eth/tracers: expose contextual infos (block hash, tx hash, tx index)
上级
10eb654f
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
49 addition
and
41 deletion
+49
-41
eth/tracers/api.go
eth/tracers/api.go
+16
-23
eth/tracers/tracer.go
eth/tracers/tracer.go
+18
-2
eth/tracers/tracer_test.go
eth/tracers/tracer_test.go
+13
-14
eth/tracers/tracers_test.go
eth/tracers/tracers_test.go
+2
-2
未找到文件。
eth/tracers/api.go
浏览文件 @
29905d86
...
...
@@ -178,13 +178,6 @@ type StdTraceConfig struct {
TxHash
common
.
Hash
}
// txTraceContext is the contextual infos about a transaction before it gets run.
type
txTraceContext
struct
{
index
int
// Index of the transaction within the block
hash
common
.
Hash
// Hash of the transaction
block
common
.
Hash
// Hash of the block containing the transaction
}
// txTraceResult is the result of a single transaction trace.
type
txTraceResult
struct
{
Result
interface
{}
`json:"result,omitempty"`
// Trace results produced by the tracer
...
...
@@ -272,10 +265,10 @@ func (api *API) traceChain(ctx context.Context, start, end *types.Block, config
// Trace all the transactions contained within
for
i
,
tx
:=
range
task
.
block
.
Transactions
()
{
msg
,
_
:=
tx
.
AsMessage
(
signer
,
task
.
block
.
BaseFee
())
txctx
:=
&
txTrace
Context
{
index
:
i
,
hash
:
tx
.
Hash
()
,
block
:
task
.
block
.
Hash
(),
txctx
:=
&
Context
{
BlockHash
:
task
.
block
.
Hash
()
,
TxIndex
:
i
,
TxHash
:
tx
.
Hash
(),
}
res
,
err
:=
api
.
traceTx
(
localctx
,
msg
,
txctx
,
blockCtx
,
task
.
statedb
,
config
)
if
err
!=
nil
{
...
...
@@ -524,10 +517,10 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
// Fetch and execute the next transaction trace tasks
for
task
:=
range
jobs
{
msg
,
_
:=
txs
[
task
.
index
]
.
AsMessage
(
signer
,
block
.
BaseFee
())
txctx
:=
&
txTrace
Context
{
index
:
task
.
index
,
hash
:
txs
[
task
.
index
]
.
Hash
()
,
block
:
blockHash
,
txctx
:=
&
Context
{
BlockHash
:
blockHash
,
TxIndex
:
task
.
index
,
TxHash
:
txs
[
task
.
index
]
.
Hash
()
,
}
res
,
err
:=
api
.
traceTx
(
ctx
,
msg
,
txctx
,
blockCtx
,
task
.
statedb
,
config
)
if
err
!=
nil
{
...
...
@@ -718,10 +711,10 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
if
err
!=
nil
{
return
nil
,
err
}
txctx
:=
&
txTrace
Context
{
index
:
int
(
index
)
,
hash
:
hash
,
block
:
blockH
ash
,
txctx
:=
&
Context
{
BlockHash
:
blockHash
,
TxIndex
:
int
(
index
)
,
TxHash
:
h
ash
,
}
return
api
.
traceTx
(
ctx
,
msg
,
txctx
,
vmctx
,
statedb
,
config
)
}
...
...
@@ -777,13 +770,13 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
Reexec
:
config
.
Reexec
,
}
}
return
api
.
traceTx
(
ctx
,
msg
,
new
(
txTrace
Context
),
vmctx
,
statedb
,
traceConfig
)
return
api
.
traceTx
(
ctx
,
msg
,
new
(
Context
),
vmctx
,
statedb
,
traceConfig
)
}
// traceTx configures a new tracer according to the provided configuration, and
// executes the given message in the provided environment. The return value will
// be tracer dependent.
func
(
api
*
API
)
traceTx
(
ctx
context
.
Context
,
message
core
.
Message
,
txctx
*
txTrace
Context
,
vmctx
vm
.
BlockContext
,
statedb
*
state
.
StateDB
,
config
*
TraceConfig
)
(
interface
{},
error
)
{
func
(
api
*
API
)
traceTx
(
ctx
context
.
Context
,
message
core
.
Message
,
txctx
*
Context
,
vmctx
vm
.
BlockContext
,
statedb
*
state
.
StateDB
,
config
*
TraceConfig
)
(
interface
{},
error
)
{
// Assemble the structured logger or the JavaScript tracer
var
(
tracer
vm
.
Tracer
...
...
@@ -800,7 +793,7 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *txTrac
}
}
// Constuct the JavaScript tracer to execute with
if
tracer
,
err
=
New
(
*
config
.
Tracer
,
tx
Context
);
err
!=
nil
{
if
tracer
,
err
=
New
(
*
config
.
Tracer
,
tx
ctx
);
err
!=
nil
{
return
nil
,
err
}
// Handle timeouts and RPC cancellations
...
...
@@ -823,7 +816,7 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *txTrac
vmenv
:=
vm
.
NewEVM
(
vmctx
,
txContext
,
statedb
,
api
.
backend
.
ChainConfig
(),
vm
.
Config
{
Debug
:
true
,
Tracer
:
tracer
,
NoBaseFee
:
true
})
// Call Prepare to clear out the statedb access list
statedb
.
Prepare
(
txctx
.
hash
,
txctx
.
block
,
txctx
.
i
ndex
)
statedb
.
Prepare
(
txctx
.
TxHash
,
txctx
.
BlockHash
,
txctx
.
TxI
ndex
)
result
,
err
:=
core
.
ApplyMessage
(
vmenv
,
message
,
new
(
core
.
GasPool
)
.
AddGas
(
message
.
Gas
()))
if
err
!=
nil
{
...
...
eth/tracers/tracer.go
浏览文件 @
29905d86
...
...
@@ -312,10 +312,18 @@ type Tracer struct {
reason
error
// Textual reason for the interruption
}
// Context contains some contextual infos for a transaction execution that is not
// available from within the EVM object.
type
Context
struct
{
BlockHash
common
.
Hash
// Hash of the block the tx is contained within (zero if dangling tx or call)
TxIndex
int
// Index of the transaction within a block (zero if dangling tx or call)
TxHash
common
.
Hash
// Hash of the transaction being traced (zero if dangling call)
}
// New instantiates a new tracer instance. code specifies a Javascript snippet,
// which must evaluate to an expression returning an object with 'step', 'fault'
// and 'result' functions.
func
New
(
code
string
,
txCtx
vm
.
Tx
Context
)
(
*
Tracer
,
error
)
{
func
New
(
code
string
,
ctx
*
Context
)
(
*
Tracer
,
error
)
{
// Resolve any tracers by name and assemble the tracer object
if
tracer
,
ok
:=
tracer
(
code
);
ok
{
code
=
tracer
...
...
@@ -334,8 +342,14 @@ func New(code string, txCtx vm.TxContext) (*Tracer, error) {
depthValue
:
new
(
uint
),
refundValue
:
new
(
uint
),
}
tracer
.
ctx
[
"gasPrice"
]
=
txCtx
.
GasPrice
if
ctx
.
BlockHash
!=
(
common
.
Hash
{})
{
tracer
.
ctx
[
"blockHash"
]
=
ctx
.
BlockHash
if
ctx
.
TxHash
!=
(
common
.
Hash
{})
{
tracer
.
ctx
[
"txIndex"
]
=
ctx
.
TxIndex
tracer
.
ctx
[
"txHash"
]
=
ctx
.
TxHash
}
}
// Set up builtins for this environment
tracer
.
vm
.
PushGlobalGoFunction
(
"toHex"
,
func
(
ctx
*
duktape
.
Context
)
int
{
ctx
.
PushString
(
hexutil
.
Encode
(
popSlice
(
ctx
)))
...
...
@@ -550,11 +564,13 @@ func (jst *Tracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
jst
.
ctx
[
"to"
]
=
to
jst
.
ctx
[
"input"
]
=
input
jst
.
ctx
[
"gas"
]
=
gas
jst
.
ctx
[
"gasPrice"
]
=
env
.
TxContext
.
GasPrice
jst
.
ctx
[
"value"
]
=
value
// Initialize the context
jst
.
ctx
[
"block"
]
=
env
.
Context
.
BlockNumber
.
Uint64
()
jst
.
dbWrapper
.
db
=
env
.
StateDB
// Compute intrinsic gas
isHomestead
:=
env
.
ChainConfig
()
.
IsHomestead
(
env
.
Context
.
BlockNumber
)
isIstanbul
:=
env
.
ChainConfig
()
.
IsIstanbul
(
env
.
Context
.
BlockNumber
)
...
...
eth/tracers/tracer_test.go
浏览文件 @
29905d86
...
...
@@ -80,12 +80,14 @@ func runTrace(tracer *Tracer, vmctx *vmContext) (json.RawMessage, error) {
func
TestTracer
(
t
*
testing
.
T
)
{
execTracer
:=
func
(
code
string
)
([]
byte
,
string
)
{
t
.
Helper
()
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
,
new
(
Context
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
ret
,
err
:=
runTrace
(
tracer
,
ctx
)
ret
,
err
:=
runTrace
(
tracer
,
&
vmContext
{
blockCtx
:
vm
.
BlockContext
{
BlockNumber
:
big
.
NewInt
(
1
)},
txCtx
:
vm
.
TxContext
{
GasPrice
:
big
.
NewInt
(
100000
)},
})
if
err
!=
nil
{
return
nil
,
err
.
Error
()
// Stringify to allow comparison without nil checks
}
...
...
@@ -132,25 +134,21 @@ func TestHalt(t *testing.T) {
t
.
Skip
(
"duktape doesn't support abortion"
)
timeout
:=
errors
.
New
(
"stahp"
)
vmctx
:=
testCtx
()
tracer
,
err
:=
New
(
"{step: function() { while(1); }, result: function() { return null; }}"
,
vmctx
.
txCtx
)
tracer
,
err
:=
New
(
"{step: function() { while(1); }, result: function() { return null; }}"
,
new
(
Context
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
go
func
()
{
time
.
Sleep
(
1
*
time
.
Second
)
tracer
.
Stop
(
timeout
)
}()
if
_
,
err
=
runTrace
(
tracer
,
vmctx
);
err
.
Error
()
!=
"stahp in server-side tracer function 'step'"
{
if
_
,
err
=
runTrace
(
tracer
,
testCtx
());
err
.
Error
()
!=
"stahp in server-side tracer function 'step'"
{
t
.
Errorf
(
"Expected timeout error, got %v"
,
err
)
}
}
func
TestHaltBetweenSteps
(
t
*
testing
.
T
)
{
vmctx
:=
testCtx
()
tracer
,
err
:=
New
(
"{step: function() {}, fault: function() {}, result: function() { return null; }}"
,
vmctx
.
txCtx
)
tracer
,
err
:=
New
(
"{step: function() {}, fault: function() {}, result: function() { return null; }}"
,
new
(
Context
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
...
...
@@ -158,7 +156,6 @@ func TestHaltBetweenSteps(t *testing.T) {
scope
:=
&
vm
.
ScopeContext
{
Contract
:
vm
.
NewContract
(
&
account
{},
&
account
{},
big
.
NewInt
(
0
),
0
),
}
tracer
.
CaptureState
(
env
,
0
,
0
,
0
,
0
,
scope
,
nil
,
0
,
nil
)
timeout
:=
errors
.
New
(
"stahp"
)
tracer
.
Stop
(
timeout
)
...
...
@@ -182,12 +179,14 @@ func TestNoStepExec(t *testing.T) {
}
execTracer
:=
func
(
code
string
)
[]
byte
{
t
.
Helper
()
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
,
new
(
Context
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
ret
,
err
:=
runEmptyTrace
(
tracer
,
ctx
)
ret
,
err
:=
runEmptyTrace
(
tracer
,
&
vmContext
{
blockCtx
:
vm
.
BlockContext
{
BlockNumber
:
big
.
NewInt
(
1
)},
txCtx
:
vm
.
TxContext
{
GasPrice
:
big
.
NewInt
(
100000
)},
})
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
...
...
eth/tracers/tracers_test.go
浏览文件 @
29905d86
...
...
@@ -173,7 +173,7 @@ func TestPrestateTracerCreate2(t *testing.T) {
_
,
statedb
:=
tests
.
MakePreState
(
rawdb
.
NewMemoryDatabase
(),
alloc
,
false
)
// Create the tracer, the EVM environment and run it
tracer
,
err
:=
New
(
"prestateTracer"
,
txContext
)
tracer
,
err
:=
New
(
"prestateTracer"
,
new
(
Context
)
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create call tracer: %v"
,
err
)
}
...
...
@@ -248,7 +248,7 @@ func TestCallTracer(t *testing.T) {
_
,
statedb
:=
tests
.
MakePreState
(
rawdb
.
NewMemoryDatabase
(),
test
.
Genesis
.
Alloc
,
false
)
// Create the tracer, the EVM environment and run it
tracer
,
err
:=
New
(
"callTracer"
,
txContext
)
tracer
,
err
:=
New
(
"callTracer"
,
new
(
Context
)
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create call tracer: %v"
,
err
)
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录