Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
add: trace tx via the api
Browse files Browse the repository at this point in the history
  • Loading branch information
heikoheiko committed Aug 21, 2014
1 parent 1ddeabf commit fcc9bbe
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
60 changes: 59 additions & 1 deletion pyethereum/apiserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
from pyethereum.chainmanager import chain_manager
from pyethereum.peermanager import peer_manager
import pyethereum.dispatch as dispatch
from pyethereum.blocks import block_structure
from pyethereum.blocks import block_structure, Block
import pyethereum.signals as signals
from pyethereum.transactions import Transaction
import pyethereum.processblock as processblock
import pyethereum.utils as utils
import pyethereum.rlp as rlp

logger = logging.getLogger(__name__)
base_url = '/api/v02a'
Expand Down Expand Up @@ -176,6 +179,61 @@ def get_pending():



# ########### Trace ############

class TraceLogHandler(logging.Handler):
def __init__(self):
logging.Handler.__init__(self)
self.buffer = []

def emit(self, record):
self.buffer.append(record)


@app.get(base_url + '/trace/<txhash>')
def trace(txhash):
"""
/trace/<hexhash> return trace for transaction
"""
logger.debug('GET trace/ %s', txhash)
try: # index
tx, blk = chain_manager.index.get_transaction(txhash.decode('hex'))
except (KeyError, TypeError):
return bottle.abort(404, 'Unknown Transaction %s' % txhash)

# get the state we had before this transaction
test_blk = Block.init_from_parent(blk.get_parent(),
blk.coinbase,
extra_data=blk.extra_data,
timestamp=blk.timestamp,
uncles=blk.uncles)
pre_state = test_blk.state_root
for i in range(blk.transaction_count):
tx_lst_serialized, sr, _ = blk.get_transaction(i)
if utils.sha3(rlp.encode(tx_lst_serialized)) == tx.hash:
break
else:
pre_state = sr
test_blk.state.root_hash = pre_state

# collect debug output
tl = TraceLogHandler()
tl.setLevel(logging.DEBUG)
processblock.logger.addHandler(tl)

# apply tx (thread? we don't want logs from other invocations)
processblock.apply_transaction(test_blk, tx)

# stop collecting debug output
processblock.logger.removeHandler(tl)

# format
formatter = logging.Formatter('%(name)s:%(message)s')
res = '\n'.join(formatter.format(l) for l in tl.buffer)
return dict(trace=res)



# ######## Accounts ############
@app.get(base_url + '/accounts/')
def accounts():
Expand Down
8 changes: 7 additions & 1 deletion pyethereum/ethclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ def gettx(self, id):
def getpending(self):
return self.json_get_request(path='/pending/')

def trace(self, id):
res = self.json_get_request(path='/trace/%s' % id)
if 'trace' in res:
return res['trace']
return res

doc = \
"""ethclient
Expand All @@ -115,7 +120,7 @@ def getpending(self):
pyethclient getblock [options] <blockid_hex_or_num>
pyethclient gettx [options] <txid_hex>
pyethclient getpending [options]
pyethclient trace [options] <txid_hex>
Options:
-h --help Show this screen
Expand Down Expand Up @@ -155,6 +160,7 @@ def main():
getblock=(api.getblock, arguments['<blockid_hex_or_num>']),
gettx=(api.gettx, arguments['<txid_hex>']),
trace=(api.trace, arguments['<txid_hex>']),
getpending=(api.getpending,)
)
for k in cmd_map:
if arguments.get(k):
Expand Down

0 comments on commit fcc9bbe

Please sign in to comment.