Skip to content

Instantly share code, notes, and snippets.

@ankitchiplunkar
Last active November 30, 2018 15:04
Show Gist options
  • Save ankitchiplunkar/e298352f95b09e825cfaa3f466d3ba1c to your computer and use it in GitHub Desktop.
Save ankitchiplunkar/e298352f95b09e825cfaa3f466d3ba1c to your computer and use it in GitHub Desktop.
preliminary comparison between netnermind and parity traces

Checked the traces at block 1Million

blocknumber 10**6 = 0xf4240

For parity

curl --data '{"method":"trace_replayBlockTransactions","params":["0xf4240",["stateDiff", "trace"]],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545

For nethermind

curl --data '{"method":"trace_replayBlockTransactions","params":["0xf4240",["stateDiff", "trace"]],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8345

The block 1 million has 2 transactions
Results of nethermind and parity traces

NETHERMIND_TRACE = {"id":1,"jsonrpc":"2.0","result":["{\"trace\":[{\"action\":{\"callType\":\"call\",\"from\":\"0x39fa8c5f2793459d6622857e7d9fbb4bd91766d3\",\"gas\":108244,\"input\":\"0x\",\"to\":\"0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47\",\"value\":\"0x56bc75e2d63100000\"},\"blockHash\":\"0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e\",\"blockNumber\":\"0x0f4240\",\"result\":{\"gasUsed\":29244,\"output\":\"0x0000000000000000000000000000000000000000000000000000000000000000\"},\"subtraces\":1,\"traceAddress\":\"[]\",\"transactionHash\":\"0xea1093d492a1dcb1bef708f771a99a96ff05dcab81ca76c31940300177fcf49f\",\"transactionPosition\":0,\"type\":\"call\"},{\"action\":{\"callType\":\"callCode\",\"from\":\"0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47\",\"gas\":101462,\"input\":\"0x\",\"to\":\"0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47\",\"value\":\"0x56bc75e2d63100000\"},\"blockHash\":\"0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e\",\"blockNumber\":\"0x0f4240\",\"result\":{\"gasUsed\":1444,\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":\"[0]\",\"transactionHash\":\"0xea1093d492a1dcb1bef708f771a99a96ff05dcab81ca76c31940300177fcf49f\",\"transactionPosition\":0,\"type\":\"callCode\"}],\"stateDiff\":{\"0x39fa8c5f2793459d6622857e7d9fbb4bd91766d3\":{\"balance\":{\"*\":{\"from\":\"0x1b26987c0aef361ea8\",\"to\":\"0x15bac8c01b85fe4028\"}},\"code\":\"=\",\"nonce\":{\"*\":{\"from\":\"0x15\",\"to\":\"0x16\"}},\"storage\":\"=\"},\"0x2a65aca4d5fc5b5c859090a6c34d164135398226\":{\"balance\":{\"*\":{\"from\":\"0x0b422f22219345bee6f\",\"to\":\"0x0b422fa7fdb3a83ccef\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":\"=\"},\"0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47\":{\"balance\":{\"*\":{\"from\":\"0x0\",\"to\":\"0x56bc75e2d63100000\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":\"=\"}}}","{\"trace\":[{\"action\":{\"callType\":\"call\",\"from\":\"0x32be343b94f860124dc4fee278fdcbd38c102d88\",\"gas\":29000,\"input\":\"0x\",\"to\":\"0xdf190dc7190dfba737d7777a163445b7fff16133\",\"value\":\"0x6113a84987be800\"},\"blockHash\":\"0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e\",\"blockNumber\":\"0x0f4240\",\"result\":{\"gasUsed\":21000,\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":\"[]\",\"transactionHash\":\"0xe9e91f1ee4b56c0df2e9f06c2b8c27c6076195a88a7b8537ba8313d80e6f124e\",\"transactionPosition\":0,\"type\":\"call\"}],\"stateDiff\":{\"0x32be343b94f860124dc4fee278fdcbd38c102d88\":{\"balance\":{\"*\":{\"from\":\"0x328ee5c75c7470f8f7b4\",\"to\":\"0x328edfb1a7f93c124fb4\"}},\"code\":\"=\",\"nonce\":{\"*\":{\"from\":\"0x43eb\",\"to\":\"0x43ec\"}},\"storage\":\"=\"},\"0x2a65aca4d5fc5b5c859090a6c34d164135398226\":{\"balance\":{\"*\":{\"from\":\"0x0b422fa7fdb3a83ccef\",\"to\":\"0x0b422fef9d1d6ee8cef\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":\"=\"},\"0xdf190dc7190dfba737d7777a163445b7fff16133\":{\"balance\":{\"*\":{\"from\":\"0x287b2c88ddbf3c00\",\"to\":\"0x2e8c670d763b2400\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":\"=\"}}}","{\"trace\":[{\"action\":{\"callType\":\"reward\",\"from\":null,\"gas\":0,\"input\":null,\"to\":null,\"value\":\"0x4563918244f40000\"},\"blockHash\":\"0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e\",\"blockNumber\":\"0x0f4240\",\"result\":{\"gasUsed\":0,\"output\":null},\"subtraces\":0,\"traceAddress\":\"[]\",\"transactionHash\":null,\"transactionPosition\":null,\"type\":\"reward\"}],\"stateDiff\":{\"0x2a65aca4d5fc5b5c859090a6c34d164135398226\":{\"balance\":{\"*\":{\"from\":\"0x0b422fef9d1d6ee8cef\",\"to\":\"0x0b468628b541be28cef\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":\"=\"}}}"]}
PARITY_TRACE = {"jsonrpc":"2.0","result":[{"output":"0x0000000000000000000000000000000000000000000000000000000000000000","stateDiff":{"0x2a65aca4d5fc5b5c859090a6c34d164135398226":{"balance":{"*":{"from":"0xb422f22219345bee6f","to":"0xb422fa7fdb3a83ccef"}},"code":"=","nonce":"=","storage":{}},"0x39fa8c5f2793459d6622857e7d9fbb4bd91766d3":{"balance":{"*":{"from":"0x1b26987c0aef361ea8","to":"0x15bac8c01b85fe4028"}},"code":"=","nonce":{"*":{"from":"0x15","to":"0x16"}},"storage":{}},"0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47":{"balance":{"*":{"from":"0x0","to":"0x56bc75e2d63100000"}},"code":"=","nonce":"=","storage":{}}},"trace":[{"action":{"callType":"call","from":"0x39fa8c5f2793459d6622857e7d9fbb4bd91766d3","gas":"0x1a6d4","input":"0x","to":"0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47","value":"0x56bc75e2d63100000"},"result":{"gasUsed":"0x2034","output":"0x0000000000000000000000000000000000000000000000000000000000000000"},"subtraces":1,"traceAddress":[],"type":"call"},{"action":{"callType":"callcode","from":"0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47","gas":"0x18c56","input":"0x","to":"0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47","value":"0x56bc75e2d63100000"},"result":{"gasUsed":"0x5a4","output":"0x"},"subtraces":0,"traceAddress":[0],"type":"call"}],"vmTrace":"null"},{"output":"0x","stateDiff":{"0x2a65aca4d5fc5b5c859090a6c34d164135398226":{"balance":{"*":{"from":"0xb422fa7fdb3a83ccef","to":"0xb422fef9d1d6ee8cef"}},"code":"=","nonce":"=","storage":{}},"0x32be343b94f860124dc4fee278fdcbd38c102d88":{"balance":{"*":{"from":"0x328ee5c75c7470f8f7b4","to":"0x328edfb1a7f93c124fb4"}},"code":"=","nonce":{"*":{"from":"0x43eb","to":"0x43ec"}},"storage":{}},"0xdf190dc7190dfba737d7777a163445b7fff16133":{"balance":{"*":{"from":"0x287b2c88ddbf3c00","to":"0x2e8c670d763b2400"}},"code":"=","nonce":"=","storage":{}}},"trace":[{"action":{"callType":"call","from":"0x32be343b94f860124dc4fee278fdcbd38c102d88","gas":"0x7148","input":"0x","to":"0xdf190dc7190dfba737d7777a163445b7fff16133","value":"0x6113a84987be800"},"result":{"gasUsed":"0x0","output":"0x"},"subtraces":0,"traceAddress":[],"type":"call"}],"vmTrace":"null"}],"id":1}

Note: Nethermind inserts \ in its traces.

Comparing results

Types of keys for a transaction

Parity = ['output', 'vmTrace', 'trace', 'stateDiff']
Nethermind = ['trace', 'stateDiff']

Parity exposes an extra key called output which is the output of the transaction

Comparing traces

Here I am comparing the traces of the first transaction of block 1M

# Nethermind traces
# I have removed the "\" from the data
[{'blockHash': '0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e', 'transactionHash': '0xea1093d492a1dcb1bef708f771a99a96ff05dcab81ca76c31940300177fcf49f', 'blockNumber':'0x0f4240', 'traceAddress': '[]', 'subtraces': 1, 'action': {'callType': 'call', 'from': '0x39fa8c5f2793459d6622857e7d9fbb4bd91766d3', 'gas': 108244, 'value': '0x56bc75e2d63100000', 'to': '0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47', 'input': '0x'}, 'transactionPosition': 0, 'type': 'call', 'result': {'output': '0x0000000000000000000000000000000000000000000000000000000000000000', 'gasUsed': 29244}}, {'blockHash': '0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e', 'transactionHash': '0xea1093d492a1dcb1bef708f771a99a96ff05dcab81ca76c31940300177fcf49f', 'blockNumber': '0x0f4240', 'traceAddress': '[0]', 'subtraces': 0, 'action': {'callType': 'callCode', 'from': '0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47', 'gas': 101462, 'value': '0x56bc75e2d63100000', 'to': '0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47', 'input': '0x'}, 'transactionPosition': 0, 'type': 'callCode', 'result': {'output': '0x', 'gasUsed': 1444}}]

# Parity traces
[{'action': {'callType': 'call', 'from': '0x39fa8c5f2793459d6622857e7d9fbb4bd91766d3', 'gas': '0x1a6d4', 'value': '0x56bc75e2d63100000', 'to': '0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47','input': '0x'}, 'traceAddress': [], 'type': 'call', 'result': {'output': '0x0000000000000000000000000000000000000000000000000000000000000000', 'gasUsed': '0x2034'}, 'subtraces': 1}, {'action': {'callType': 'callcode', 'from': '0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47', 'gas': '0x18c56', 'value': '0x56bc75e2d63100000', 'to': '0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47', 'input': '0x'}, 'traceAddress': [0], 'type': 'call', 'result': {'output': '0x', 'gasUsed': '0x5a4'}, 'subtraces': 0}]
  1. The values match
  2. Nethermind attached blockhash, blocknumber and transactionhash with a trace (openethereum/parity-ethereum#8725)
  3. Nethermind converts the gas used into Integers whereas parity returns Hexes for gas used

Comparing state diffs

The state diff's match each other only variation being some formatting differences

# Nethermind stateDiff
{'0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47': {'code': '=', 'nonce': '=', 'balance': {'*': {'to': '0x56bc75e2d63100000', 'from': '0x0'}}, 'storage': '='}, '0x2a65aca4d5fc5b5c859090a6c34d164135398226': {'code': '=', 'nonce': '=', 'balance': {'*': {'to': '0x0b422fa7fdb3a83ccef', 'from': '0x0b422f22219345bee6f'}}, 'storage': '='}, '0x39fa8c5f2793459d6622857e7d9fbb4bd91766d3': {'code': '=', 'nonce': {'*': {'to': '0x16', 'from': '0x15'}}, 'balance': {'*': {'to': '0x15bac8c01b85fe4028', 'from': '0x1b26987c0aef361ea8'}}, 'storage': '='}}

# Parity stateDiff
{'0xc083e9947cf02b8ffc7d3090ae9aea72df98fd47': {'code': '=', 'nonce': '=', 'balance': {'*': {'to': '0x56bc75e2d63100000', 'from': '0x0'}}, 'storage': {}}, '0x2a65aca4d5fc5b5c859090a6c34d164135398226': {'code': '=', 'nonce': '=', 'balance': {'*': {'to': '0xb422fa7fdb3a83ccef', 'from': '0xb422f22219345bee6f'}}, 'storage': {}}, '0x39fa8c5f2793459d6622857e7d9fbb4bd91766d3': {'code': '=', 'nonce': {'*': {'to': '0x16', 'from': '0x15'}}, 'balance': {'*': {'to': '0x15bac8c01b85fe4028', 'from': '0x1b26987c0aef361ea8'}}, 'storage': {}}}

Inserting block rewards

One feature that I really like about the nethermind state diff is that they also attach the block reward in their state diff's. I had opened an issue in parity for a similar feature (~6 months ago) and it had not been included in parity. openethereum/parity-ethereum#8747

'{"trace":[{"action":{"callType":"reward","from":null,"gas":0,"input":null,"to":null,"value":"0x4563918244f40000"},"blockHash":"0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e","blockNumber":"0x0f4240","result":{"gasUsed":0,"output":null},"subtraces":0,"traceAddress":"[]","transactionHash":null,"transactionPosition":null,"type":"reward"}],"stateDiff":{"0x2a65aca4d5fc5b5c859090a6c34d164135398226":{"balance":{"*":{"from":"0x0b422fef9d1d6ee8cef","to":"0x0b468628b541be28cef"}},"code":"=","nonce":"=","storage":"="}}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment