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
bbc77f48
Commit
bbc77f48
authored
Apr 14, 2016
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth: fix single transaction tracing (run prev mutations)
parent
e50e3bea
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
47 additions
and
41 deletions
+47
-41
api.go
eth/api.go
+47
-41
No files found.
eth/api.go
View file @
bbc77f48
...
...
@@ -1772,55 +1772,61 @@ func formatError(err error) string {
// TraceTransaction returns the structured logs created during the execution of EVM
// and returns them as a JSON object.
func
(
s
*
PrivateDebugAPI
)
TraceTransaction
(
txHash
common
.
Hash
,
logger
vm
.
LogConfig
)
(
*
ExecutionResult
,
error
)
{
// Retrieve the tx from the chain
tx
,
_
,
blockIndex
,
_
:=
core
.
GetTransaction
(
s
.
eth
.
ChainDb
(),
txHash
)
// Retrieve the tx from the chain and the containing block
tx
,
blockHash
,
_
,
txIndex
:=
core
.
GetTransaction
(
s
.
eth
.
ChainDb
(),
txHash
)
if
tx
==
nil
{
return
nil
,
fmt
.
Errorf
(
"
Transaction not found"
)
return
nil
,
fmt
.
Errorf
(
"
transaction %x not found"
,
txHash
)
}
block
:=
s
.
eth
.
BlockChain
()
.
GetBlockByNumber
(
blockIndex
-
1
)
block
:=
s
.
eth
.
BlockChain
()
.
GetBlock
(
blockHash
)
if
block
==
nil
{
return
nil
,
fmt
.
Errorf
(
"
Unable to retrieve prior block"
)
return
nil
,
fmt
.
Errorf
(
"
block %x not found"
,
blockHash
)
}
// Create the state database
stateDb
,
err
:=
state
.
New
(
block
.
Root
(),
s
.
eth
.
ChainDb
())
if
err
!=
nil
{
return
nil
,
err
// Create the state database to mutate and eventually trace
parent
:=
s
.
eth
.
BlockChain
()
.
GetBlock
(
block
.
ParentHash
())
if
parent
==
nil
{
return
nil
,
fmt
.
Errorf
(
"block parent %x not found"
,
block
.
ParentHash
())
}
txFrom
,
err
:=
tx
.
FromFrontier
()
stateDb
,
err
:=
state
.
New
(
parent
.
Root
(),
s
.
eth
.
ChainDb
())
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Unable to create transaction sender"
)
}
from
:=
stateDb
.
GetOrNewStateObject
(
txFrom
)
msg
:=
callmsg
{
from
:
from
,
to
:
tx
.
To
(),
gas
:
tx
.
Gas
(),
gasPrice
:
tx
.
GasPrice
(),
value
:
tx
.
Value
(),
data
:
tx
.
Data
(),
return
nil
,
err
}
vmenv
:=
core
.
NewEnv
(
stateDb
,
s
.
config
,
s
.
eth
.
BlockChain
(),
msg
,
block
.
Header
(),
vm
.
Config
{
Debug
:
true
,
Logger
:
logger
,
})
gp
:=
new
(
core
.
GasPool
)
.
AddGas
(
block
.
GasLimit
())
ret
,
gas
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
gp
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Error executing transaction %v"
,
err
)
// Mutate the state and trace the selected transaction
for
idx
,
tx
:=
range
block
.
Transactions
()
{
// Assemble the transaction call message
from
,
err
:=
tx
.
FromFrontier
()
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"sender retrieval failed: %v"
,
err
)
}
msg
:=
callmsg
{
from
:
stateDb
.
GetOrNewStateObject
(
from
),
to
:
tx
.
To
(),
gas
:
tx
.
Gas
(),
gasPrice
:
tx
.
GasPrice
(),
value
:
tx
.
Value
(),
data
:
tx
.
Data
(),
}
// Mutate the state if we haven't reached the tracing transaction yet
if
uint64
(
idx
)
<
txIndex
{
vmenv
:=
core
.
NewEnv
(
stateDb
,
s
.
config
,
s
.
eth
.
BlockChain
(),
msg
,
parent
.
Header
(),
vm
.
Config
{})
_
,
_
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
new
(
core
.
GasPool
)
.
AddGas
(
tx
.
Gas
()))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"mutation failed: %v"
,
err
)
}
continue
}
// Otherwise trace the transaction and return
vmenv
:=
core
.
NewEnv
(
stateDb
,
s
.
config
,
s
.
eth
.
BlockChain
(),
msg
,
parent
.
Header
(),
vm
.
Config
{
Debug
:
true
,
Logger
:
logger
})
ret
,
gas
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
new
(
core
.
GasPool
)
.
AddGas
(
tx
.
Gas
()))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"tracing failed: %v"
,
err
)
}
return
&
ExecutionResult
{
Gas
:
gas
,
ReturnValue
:
fmt
.
Sprintf
(
"%x"
,
ret
),
StructLogs
:
formatLogs
(
vmenv
.
StructLogs
()),
},
nil
}
return
&
ExecutionResult
{
Gas
:
gas
,
ReturnValue
:
fmt
.
Sprintf
(
"%x"
,
ret
),
StructLogs
:
formatLogs
(
vmenv
.
StructLogs
()),
},
nil
return
nil
,
errors
.
New
(
"database inconsistency"
)
}
func
(
s
*
PublicBlockChainAPI
)
TraceCall
(
args
CallArgs
,
blockNr
rpc
.
BlockNumber
)
(
*
ExecutionResult
,
error
)
{
...
...
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