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
0983d02a
Unverified
Commit
0983d02a
authored
Dec 10, 2018
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth, internal/web3ext: tiny polishes in tracers
parent
42a914a8
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
97 additions
and
77 deletions
+97
-77
api_tracer.go
eth/api_tracer.go
+95
-77
web3ext.go
internal/web3ext/web3ext.go
+2
-0
No files found.
eth/api_tracer.go
View file @
0983d02a
...
...
@@ -66,7 +66,7 @@ type TraceConfig struct {
type
StdTraceConfig
struct
{
*
vm
.
LogConfig
Reexec
*
uint64
TxHash
*
common
.
Hash
TxHash
common
.
Hash
}
// txTraceResult is the result of a single transaction trace.
...
...
@@ -375,7 +375,7 @@ func (api *PrivateDebugAPI) TraceBlockByNumber(ctx context.Context, number rpc.B
func
(
api
*
PrivateDebugAPI
)
TraceBlockByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
,
config
*
TraceConfig
)
([]
*
txTraceResult
,
error
)
{
block
:=
api
.
eth
.
blockchain
.
GetBlockByHash
(
hash
)
if
block
==
nil
{
return
nil
,
fmt
.
Errorf
(
"block
#%
x not found"
,
hash
)
return
nil
,
fmt
.
Errorf
(
"block
%#
x not found"
,
hash
)
}
return
api
.
traceBlock
(
ctx
,
block
,
config
)
}
...
...
@@ -400,37 +400,41 @@ func (api *PrivateDebugAPI) TraceBlockFromFile(ctx context.Context, file string,
return
api
.
TraceBlock
(
ctx
,
blob
,
config
)
}
// TraceBadBlockByHash returns the structured logs created during the execution of a block
func
(
api
*
PrivateDebugAPI
)
TraceBadBlock
(
ctx
context
.
Context
,
blockHash
common
.
Hash
,
config
*
TraceConfig
)
([]
*
txTraceResult
,
error
)
{
// TraceBadBlockByHash returns the structured logs created during the execution of
// EVM against a block pulled from the pool of bad ones and returns them as a JSON
// object.
func
(
api
*
PrivateDebugAPI
)
TraceBadBlock
(
ctx
context
.
Context
,
hash
common
.
Hash
,
config
*
TraceConfig
)
([]
*
txTraceResult
,
error
)
{
blocks
:=
api
.
eth
.
blockchain
.
BadBlocks
()
for
_
,
block
:=
range
blocks
{
if
block
.
Hash
()
==
blockH
ash
{
if
block
.
Hash
()
==
h
ash
{
return
api
.
traceBlock
(
ctx
,
block
,
config
)
}
}
return
nil
,
fmt
.
Errorf
(
"
hash not found among bad blocks"
)
return
nil
,
fmt
.
Errorf
(
"
bad block %#x not found"
,
hash
)
}
// StandardTraceBadBlockToFile dumps the standard-json logs to files on the local filesystem,
// and returns a list of files to the caller.
func
(
api
*
PrivateDebugAPI
)
StandardTraceBadBlockToFile
(
ctx
context
.
Context
,
blockHash
common
.
Hash
,
stdConfig
*
StdTraceConfig
)
([]
string
,
error
)
{
blocks
:=
api
.
eth
.
blockchain
.
BadBlocks
()
for
_
,
block
:=
range
blocks
{
if
block
.
Hash
()
==
blockHash
{
return
api
.
standardTraceBlockToFile
(
ctx
,
block
,
stdConfig
)
}
// StandardTraceBlockToFile dumps the structured logs created during the
// execution of EVM to the local file system and returns a list of files
// to the caller.
func
(
api
*
PrivateDebugAPI
)
StandardTraceBlockToFile
(
ctx
context
.
Context
,
hash
common
.
Hash
,
config
*
StdTraceConfig
)
([]
string
,
error
)
{
block
:=
api
.
eth
.
blockchain
.
GetBlockByHash
(
hash
)
if
block
==
nil
{
return
nil
,
fmt
.
Errorf
(
"block %#x not found"
,
hash
)
}
return
nil
,
fmt
.
Errorf
(
"hash not found among bad blocks"
)
return
api
.
standardTraceBlockToFile
(
ctx
,
block
,
config
)
}
// StandardTraceBlockToFile dumps the standard-json logs to files on the local filesystem,
// and returns a list of files to the caller.
func
(
api
*
PrivateDebugAPI
)
StandardTraceBlockToFile
(
ctx
context
.
Context
,
blockHash
common
.
Hash
,
stdConfig
*
StdTraceConfig
)
([]
string
,
error
)
{
block
:=
api
.
eth
.
blockchain
.
GetBlockByHash
(
blockHash
)
if
block
==
nil
{
return
nil
,
fmt
.
Errorf
(
"block #%x not found"
,
blockHash
)
// StandardTraceBadBlockToFile dumps the structured logs created during the
// execution of EVM against a block pulled from the pool of bad ones to the
// local file system and returns a list of files to the caller.
func
(
api
*
PrivateDebugAPI
)
StandardTraceBadBlockToFile
(
ctx
context
.
Context
,
hash
common
.
Hash
,
config
*
StdTraceConfig
)
([]
string
,
error
)
{
blocks
:=
api
.
eth
.
blockchain
.
BadBlocks
()
for
_
,
block
:=
range
blocks
{
if
block
.
Hash
()
==
hash
{
return
api
.
standardTraceBlockToFile
(
ctx
,
block
,
config
)
}
}
return
api
.
standardTraceBlockToFile
(
ctx
,
block
,
stdConfig
)
return
nil
,
fmt
.
Errorf
(
"bad block %#x not found"
,
hash
)
}
// traceBlock configures a new tracer according to the provided configuration, and
...
...
@@ -443,7 +447,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
}
parent
:=
api
.
eth
.
blockchain
.
GetBlock
(
block
.
ParentHash
(),
block
.
NumberU64
()
-
1
)
if
parent
==
nil
{
return
nil
,
fmt
.
Errorf
(
"parent %x not found"
,
block
.
ParentHash
())
return
nil
,
fmt
.
Errorf
(
"parent %
#
x not found"
,
block
.
ParentHash
())
}
reexec
:=
defaultTraceReexec
if
config
!=
nil
&&
config
.
Reexec
!=
nil
{
...
...
@@ -514,90 +518,104 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
return
results
,
nil
}
// standardTraceBlockToFile configures a new tracer which uses standard-json output, and
// traces either a full block or an individual transaction. The return value will be one filename
// per transaction traced.
func
(
api
*
PrivateDebugAPI
)
standardTraceBlockToFile
(
ctx
context
.
Context
,
block
*
types
.
Block
,
stdConfig
*
StdTraceConfig
)
([]
string
,
error
)
{
// standardTraceBlockToFile configures a new tracer which uses standard JSON output,
// and traces either a full block or an individual transaction. The return value will
// be one filename per transaction traced.
func
(
api
*
PrivateDebugAPI
)
standardTraceBlockToFile
(
ctx
context
.
Context
,
block
*
types
.
Block
,
config
*
StdTraceConfig
)
([]
string
,
error
)
{
// If we're tracing a single transaction, make sure it's present
if
config
!=
nil
&&
config
.
TxHash
!=
(
common
.
Hash
{})
{
var
exists
bool
for
_
,
tx
:=
range
block
.
Transactions
()
{
if
exists
=
(
tx
.
Hash
()
==
config
.
TxHash
);
exists
{
break
}
}
if
!
exists
{
return
nil
,
fmt
.
Errorf
(
"transaction %#x not found in block"
,
config
.
TxHash
)
}
}
// Create the parent state database
if
err
:=
api
.
eth
.
engine
.
VerifyHeader
(
api
.
eth
.
blockchain
,
block
.
Header
(),
true
);
err
!=
nil
{
return
nil
,
err
}
parent
:=
api
.
eth
.
blockchain
.
GetBlock
(
block
.
ParentHash
(),
block
.
NumberU64
()
-
1
)
if
parent
==
nil
{
return
nil
,
fmt
.
Errorf
(
"parent %x not found"
,
block
.
ParentHash
())
}
var
(
signer
=
types
.
MakeSigner
(
api
.
config
,
block
.
Number
())
done
=
false
blockPrefix
=
fmt
.
Sprintf
(
"block_0x%x"
,
block
.
Hash
()
.
Bytes
()[
:
4
])
usedLogConfig
=
&
vm
.
LogConfig
{
Debug
:
true
}
files
[]
string
reExec_val
=
defaultTraceReexec
txHash
*
common
.
Hash
)
if
stdConfig
!=
nil
{
if
stdConfig
.
Reexec
!=
nil
{
reExec_val
=
*
stdConfig
.
Reexec
return
nil
,
fmt
.
Errorf
(
"parent %#x not found"
,
block
.
ParentHash
())
}
if
stdConfig
.
LogConfig
!=
nil
{
usedLogConfig
.
DisableMemory
=
stdConfig
.
LogConfig
.
DisableMemory
usedLogConfig
.
DisableStack
=
stdConfig
.
LogConfig
.
DisableStack
usedLogConfig
.
DisableStorage
=
stdConfig
.
LogConfig
.
DisableStorage
usedLogConfig
.
Limit
=
stdConfig
.
LogConfig
.
Limit
}
txHash
=
stdConfig
.
TxHash
reexec
:=
defaultTraceReexec
if
config
!=
nil
&&
config
.
Reexec
!=
nil
{
reexec
=
*
config
.
Reexec
}
statedb
,
err
:=
api
.
computeStateDB
(
parent
,
re
Exec_val
)
statedb
,
err
:=
api
.
computeStateDB
(
parent
,
re
exec
)
if
err
!=
nil
{
return
nil
,
err
}
// Retrieve the tracing configurations, or use default values
var
(
logConfig
vm
.
LogConfig
txHash
common
.
Hash
)
if
config
!=
nil
{
if
config
.
LogConfig
!=
nil
{
logConfig
=
*
config
.
LogConfig
}
txHash
=
config
.
TxHash
}
logConfig
.
Debug
=
true
// Execute transaction, either tracing all or just the requested one
var
(
signer
=
types
.
MakeSigner
(
api
.
config
,
block
.
Number
())
dumps
[]
string
)
for
i
,
tx
:=
range
block
.
Transactions
()
{
// Prepare the trasaction for un-traced execution
var
(
outfile
*
os
.
File
msg
,
_
=
tx
.
AsMessage
(
signer
)
vmctx
=
core
.
NewEVMContext
(
msg
,
block
.
Header
(),
api
.
eth
.
blockchain
,
nil
)
vmConf
vm
.
Config
dump
*
os
.
File
err
error
)
msg
,
_
:=
tx
.
AsMessage
(
signer
)
vmctx
:=
core
.
NewEVMContext
(
msg
,
block
.
Header
(),
api
.
eth
.
blockchain
,
nil
)
vmConf
:=
vm
.
Config
{}
if
txHash
==
nil
||
bytes
.
Equal
(
txHash
.
Bytes
(),
tx
.
Hash
()
.
Bytes
())
{
prefix
:=
fmt
.
Sprintf
(
"%v-%d-0x%x-"
,
blockPrefix
,
i
,
tx
.
Hash
()
.
Bytes
()[
:
4
])
// Open a file to dump trace into
outfile
,
err
=
ioutil
.
TempFile
(
os
.
TempDir
(),
prefix
)
// If the transaction needs tracing, swap out the configs
if
tx
.
Hash
()
==
txHash
||
txHash
==
(
common
.
Hash
{})
{
// Generate a unique temporary file to dump it into
prefix
:=
fmt
.
Sprintf
(
"block_%#x-%d-%#x-"
,
block
.
Hash
()
.
Bytes
()[
:
4
],
i
,
tx
.
Hash
()
.
Bytes
()[
:
4
])
dump
,
err
=
ioutil
.
TempFile
(
os
.
TempDir
(),
prefix
)
if
err
!=
nil
{
return
nil
,
err
}
files
=
append
(
files
,
outfile
.
Name
())
dumps
=
append
(
dumps
,
dump
.
Name
())
// Swap out the noop logger to the standard tracer
vmConf
=
vm
.
Config
{
Debug
:
true
,
Tracer
:
vm
.
NewJSONLogger
(
usedLogConfig
,
bufio
.
NewWriter
(
outfile
)),
Tracer
:
vm
.
NewJSONLogger
(
&
logConfig
,
bufio
.
NewWriter
(
dump
)),
EnablePreimageRecording
:
true
,
}
if
txHash
!=
nil
{
// Only one tx to trace
done
=
true
}
}
// Execute the transaction and flush any traces to disk
vmenv
:=
vm
.
NewEVM
(
vmctx
,
statedb
,
api
.
config
,
vmConf
)
_
,
_
,
_
,
err
=
core
.
ApplyMessage
(
vmenv
,
msg
,
new
(
core
.
GasPool
)
.
AddGas
(
msg
.
Gas
()))
if
outfile
!=
nil
{
outfile
.
Close
()
log
.
Info
(
"Wrote
trace"
,
"file"
,
outfile
.
Name
())
if
dump
!=
nil
{
dump
.
Close
()
log
.
Info
(
"Wrote
standard trace"
,
"file"
,
dump
.
Name
())
}
if
err
!=
nil
{
return
file
s
,
err
return
dump
s
,
err
}
// Finalize the state so any modifications are written to the trie
statedb
.
Finalise
(
true
)
if
done
{
// If we've traced the transaction we were looking for, abort
if
tx
.
Hash
()
==
txHash
{
break
}
}
if
txHash
!=
nil
&&
!
done
{
return
nil
,
fmt
.
Errorf
(
"transaction hash not found in block"
)
}
return
files
,
nil
return
dumps
,
nil
}
// computeStateDB retrieves the state database associated with a certain block.
...
...
@@ -675,7 +693,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Ha
// Retrieve the transaction and assemble its EVM context
tx
,
blockHash
,
_
,
index
:=
rawdb
.
ReadTransaction
(
api
.
eth
.
ChainDb
(),
hash
)
if
tx
==
nil
{
return
nil
,
fmt
.
Errorf
(
"transaction %x not found"
,
hash
)
return
nil
,
fmt
.
Errorf
(
"transaction %
#
x not found"
,
hash
)
}
reexec
:=
defaultTraceReexec
if
config
!=
nil
&&
config
.
Reexec
!=
nil
{
...
...
@@ -755,11 +773,11 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree
// Create the parent state database
block
:=
api
.
eth
.
blockchain
.
GetBlockByHash
(
blockHash
)
if
block
==
nil
{
return
nil
,
vm
.
Context
{},
nil
,
fmt
.
Errorf
(
"block %x not found"
,
blockHash
)
return
nil
,
vm
.
Context
{},
nil
,
fmt
.
Errorf
(
"block %
#
x not found"
,
blockHash
)
}
parent
:=
api
.
eth
.
blockchain
.
GetBlock
(
block
.
ParentHash
(),
block
.
NumberU64
()
-
1
)
if
parent
==
nil
{
return
nil
,
vm
.
Context
{},
nil
,
fmt
.
Errorf
(
"parent %x not found"
,
block
.
ParentHash
())
return
nil
,
vm
.
Context
{},
nil
,
fmt
.
Errorf
(
"parent %
#
x not found"
,
block
.
ParentHash
())
}
statedb
,
err
:=
api
.
computeStateDB
(
parent
,
reexec
)
if
err
!=
nil
{
...
...
@@ -778,10 +796,10 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree
// Not yet the searched for transaction, execute on top of the current state
vmenv
:=
vm
.
NewEVM
(
context
,
statedb
,
api
.
config
,
vm
.
Config
{})
if
_
,
_
,
_
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
new
(
core
.
GasPool
)
.
AddGas
(
tx
.
Gas
()));
err
!=
nil
{
return
nil
,
vm
.
Context
{},
nil
,
fmt
.
Errorf
(
"t
x %
x failed: %v"
,
tx
.
Hash
(),
err
)
return
nil
,
vm
.
Context
{},
nil
,
fmt
.
Errorf
(
"t
ransaction %#
x failed: %v"
,
tx
.
Hash
(),
err
)
}
// Ensure any modifications are committed to the state
statedb
.
Finalise
(
true
)
}
return
nil
,
vm
.
Context
{},
nil
,
fmt
.
Errorf
(
"t
x index %d out of range for block %
x"
,
txIndex
,
blockHash
)
return
nil
,
vm
.
Context
{},
nil
,
fmt
.
Errorf
(
"t
ransaction index %d out of range for block %#
x"
,
txIndex
,
blockHash
)
}
internal/web3ext/web3ext.go
View file @
0983d02a
...
...
@@ -388,11 +388,13 @@ web3._extend({
name: 'standardTraceBadBlockToFile',
call: 'debug_standardTraceBadBlockToFile',
params: 2,
inputFormatter: [null, null]
}),
new web3._extend.Method({
name: 'standardTraceBlockToFile',
call: 'debug_standardTraceBlockToFile',
params: 2,
inputFormatter: [null, null]
}),
new web3._extend.Method({
name: 'traceBlockByNumber',
...
...
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