Skip to content

Commit

Permalink
Merge pull request #58 from crytic/57-export-jsonrpc
Browse files Browse the repository at this point in the history
Export raw RPC calls to a JSON file
  • Loading branch information
ESultanik authored Mar 26, 2019
2 parents 7204e2d + 18c17e2 commit 214591f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
9 changes: 8 additions & 1 deletion etheno/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .echidna import echidna_exists, EchidnaPlugin, install_echidna
from .etheno import app, EthenoView, GETH_DEFAULT_RPC_PORT, ETHENO, VERSION_NAME
from .genesis import Account, make_accounts, make_genesis
from .jsonrpc import JSONRPCExportPlugin
from .synchronization import AddressSynchronizingClient, RawTransactionClient
from .utils import clear_directory, decode_value, find_open_port, format_hex_address, ynprompt
from . import Etheno
Expand Down Expand Up @@ -60,6 +61,7 @@ def main(argv = None):
parser.add_argument('-l', '--log-level', type=str.upper, choices={'CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'}, default='INFO', help='Set Etheno\'s log level (default=INFO)')
parser.add_argument('--log-file', type=str, default=None, help='Path to save all log output to a single file')
parser.add_argument('--log-dir', type=str, default=None, help='Path to a directory in which to save all log output, divided by logging source')
parser.add_argument('-d', '--dump-jsonrpc', type=str, default=None, help='Path to a JSON file in which to dump all raw JSON RPC calls; if `--log-dir` is provided, the raw JSON RPC calls will additionally be dumped to `rpc.json` in the log directory.')
parser.add_argument('-v', '--version', action='store_true', default=False, help='Print version information and exit')
parser.add_argument('client', type=str, nargs='*', help='JSON RPC client URLs to multiplex; if no client is specified for --master, the first client in this list will default to the master (format="http://foo.com:8545/")')
parser.add_argument('-s', '--master', type=str, default=None, help='A JSON RPC client to use as the master (format="http://foo.com:8545/")')
Expand Down Expand Up @@ -103,7 +105,12 @@ def main(argv = None):
if not args.log_file:
# Also create a unified log in the log dir:
ETHENO.logger.save_to_file(os.path.join(args.log_dir, 'Complete.log'))


ETHENO.add_plugin(JSONRPCExportPlugin(os.path.join(args.log_dir, 'rpc.json')))

if args.dump_jsonrpc is not None:
ETHENO.add_plugin(JSONRPCExportPlugin(args.dump_jsonrpc))

# First, see if we need to install Echidna:
if args.echidna:
if not echidna_exists():
Expand Down
32 changes: 32 additions & 0 deletions etheno/jsonrpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import json
from typing import TextIO, Union

from .etheno import EthenoPlugin

class JSONRPCExportPlugin(EthenoPlugin):
def __init__(self, out_stream: Union[str, TextIO]):
self._was_path = isinstance(out_stream, str)
if self._was_path:
self._output = open(out_stream, 'w', encoding='utf8')
else:
self._output = out_stream
self._output.write('[')
self._count = 0

def before_post(self, post_data):
if self._count > 0:
self._output.write(',')
self._count += 1
self._output.write('\n')
json.dump(post_data, self._output)
self._output.flush()

def finalize(self):
if self._count:
self._output.write('\n')
self._output.write(']')
self._output.flush()
if self._was_path:
self._output.close()
if hasattr(self._output, 'name'):
self.logger.info(f'Raw JSON RPC messages dumped to {self._output.name}')

0 comments on commit 214591f

Please sign in to comment.