Last active
August 19, 2020 17:51
-
-
Save Thegaram/13534d482816a051c0d581eaee4ac4a2 to your computer and use it in GitHub Desktop.
evm-tracing-0.1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
build | |
$ cargo build --release --features final | |
run a dev node | |
$ ../target/release/openethereum --chain dev --jsonrpc-cors="*" | |
deploy contract | |
```sol | |
contract Storage { | |
uint256 public number; | |
mapping(address => uint256) public people; | |
... | |
} | |
``` | |
---------------------------------------------------------- | |
0. deploy contract | |
---------------------------------------------------------- | |
```sol | |
constructor() public { | |
// EMPTY | |
} | |
``` | |
<evm-trace> block #24, tx 0x35e34030bd167344a1153af9b9eac3c53e0bf9f50b60e3dba8dd89c920064d2d, accesses = {Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Create }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Create }} | |
explanation: | |
distribute tx fee to miner: | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, | |
charge sender with tx fee: | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, | |
deploy account and code: | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, | |
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read }, | |
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Create }, | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Create }} | |
notes: | |
contract address is 0x83d85eeb38a2dc37eac0239c19b343a7653d8f79 | |
code hash is 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064 | |
it seems storage values or not pre-initialized | |
---------------------------------------------------------- | |
1. read account balance | |
---------------------------------------------------------- | |
```sol | |
function read() public returns (uint256 result) { | |
result = address(this).balance; | |
} | |
``` | |
<evm-trace> block #25, tx 0xc56164a16b664b4cad1bd4e176c77b3e95513597a40b5c48450d15bb8075cc85, accesses = {Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }} | |
explanation: | |
distribute tx fee to miner: | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, | |
charge sender with tx fee: | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, | |
read contract code: | |
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, | |
execute read(): | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, | |
---------------------------------------------------------- | |
2. update account balance | |
---------------------------------------------------------- | |
```sol | |
function update() public payable { | |
// EMPTY | |
} | |
``` | |
<evm-trace> block #26, tx 0x7695d4c1b253678f70d1ac7f010d66b223756914643ea27eda54197f2f6685b7, accesses = {Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }} | |
explanation: | |
distribute tx fee to miner: | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, | |
charge sender with tx fee: | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, | |
read contract code: | |
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, | |
execute update(): | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }, | |
---------------------------------------------------------- | |
3. update simple storage (uint256) | |
---------------------------------------------------------- | |
``` | |
function storage_1() public { | |
number = number + 1; | |
} | |
``` | |
<evm-trace> block #31, tx 0x668aba887b436d2274c980d34e509fb92baa914fd9fcd4d18052276ed07ea115, accesses = {Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Update }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }} | |
explanation: | |
distribute tx fee to miner: | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, | |
charge sender with tx fee: | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, | |
read contract code: | |
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, | |
execute storage_1(): | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, | |
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Update }, | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }} | |
notes: | |
storage update corresponds to the `number = number + 1` assignment | |
account update corresponds to updating the storage root | |
---------------------------------------------------------- | |
4. insert item into mapping | |
---------------------------------------------------------- | |
```sol | |
function storage_2() public { | |
if (number % 2 == 1) { | |
people[msg.sender] = number; // --> this branch | |
} | |
else { | |
delete people[msg.sender]; | |
} | |
} | |
``` | |
<evm-trace> block #32, tx 0x3027cde50a595a984fa1572240abee7d8b62a79c715bbbe8147d854a613bc87f, accesses = {Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Create }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }} | |
explanation: | |
distribute tx fee to miner: | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, | |
charge sender with tx fee: | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, | |
read contract code: | |
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, | |
execute storage_2(): | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, | |
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Read }, | |
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Create }, | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }, | |
notes: | |
first storage read corresponds to getting the value of `number` | |
---------------------------------------------------------- | |
5. delete item from mapping | |
---------------------------------------------------------- | |
```sol | |
function storage_2() public { | |
if (number % 2 == 1) { | |
people[msg.sender] = number; | |
} | |
else { | |
delete people[msg.sender]; // --> this branch | |
} | |
} | |
``` | |
<evm-trace> block #34, tx 0xdd8f1e17a117924bf5cfd3159658814a78f78f4cbf37d9786467759e80ad6f76, accesses = {Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Delete }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }} | |
explanation: | |
distribute tx fee to miner: | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, | |
charge sender with tx fee: | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, | |
read contract code: | |
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, | |
execute storage_2(): | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }} | |
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Read }, | |
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Delete }, | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }, | |
---------------------------------------------------------- | |
6. destroy contract | |
---------------------------------------------------------- | |
```sol | |
function destroy() public { | |
selfdestruct(msg.sender); | |
} | |
``` | |
<evm-trace> block #35, tx 0xa38b9849a5031ad1c662c938752fe1a6cc1d4e269106994f55935a2a48a73156, accesses = {Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Delete }} | |
explanation: | |
distribute tx fee to miner: | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, | |
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, | |
charge sender with tx fee: | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, | |
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, | |
read contract code: | |
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, | |
execute destroy(): | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, | |
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Delete }} | |
notes: | |
code is not destroyed | |
---------------------------------------------------------- | |
7. real chain data | |
---------------------------------------------------------- | |
https://etherscan.io/block/651688 | |
<evm-trace> Start execution of block #651688 | |
<evm-trace> block #651688, tx 0x0874843e04e93341dd5433c34abd9e2b098096e92da0bc733585888eaf325c24, accesses = {Access { target: Account(0xd8bd2c0f1ff677215f8b235db85bd5e7f3fbd59d), mode: Read }, Access { target: Account(0xd8bd2c0f1ff677215f8b235db85bd5e7f3fbd59d), mode: Update }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Read }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Update }, Access { target: Account(0x9d551f41fed6fc27b719777c224dfecce170004d), mode: Read }, Access { target: Code(0xd8bd2c0f1ff677215f8b235db85bd5e7f3fbd59d, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read }, Access { target: Account(0x9d551f41fed6fc27b719777c224dfecce170004d), mode: Update }} | |
<evm-trace> block #651688, tx 0x3458fa8882378c6c0dbc5be2df0d27cb24f93b1a41eb6217a7ebeeeed06e6e42, accesses = {Access { target: Code(0xf9b3fc6160a6629840ed33f08e25b8ed8f70e8c6, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Read }, Access { target: Account(0xf9b3fc6160a6629840ed33f08e25b8ed8f70e8c6), mode: Read }, Access { target: Account(0xf9b3fc6160a6629840ed33f08e25b8ed8f70e8c6), mode: Update }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Update }} | |
<evm-trace> block #651688, tx 0xa245f8b562ee670bfdd5b5b30658b5b1a64f02cf3c22ee41dcec075c544c05dd, accesses = {Access { target: Account(0xa6191639b137cd47600a5242391a592f28a2c5a6), mode: Read }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Read }, Access { target: Account(0xa6191639b137cd47600a5242391a592f28a2c5a6), mode: Update }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Update }, Access { target: Code(0xa6191639b137cd47600a5242391a592f28a2c5a6, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read }} | |
<evm-trace> Finish execution of block #651688. hash = 0x2165d7a4b98e44814a16bd7ed03812b1e9585dc8170a4fd74c4d87eb375ab8db | |
---------------------------------------------------------- | |
---------------------------------------------------------- | |
we need to define our granularity and/or execution model/ | |
for example, if our "parallel evm" updates account.storage_root whenever a transaction commits, | |
then transactions operating on the same storage will conflict, even if they access different entries/ | |
if, on the other hand, we collect commits in memory and update storage root once we've executed all block txs, | |
then these will not conflict. | |
```sol | |
function set(uint256 key) public { | |
my_mapping[key] += 1; | |
} | |
``` | |
tx#0 calls `set(0)`, tx#1 calls `set(1)` | |
---------------------------------------------------------- | |
---------------------------------------------------------- | |
opcode-level tracing | |
Parity seems to have some built-in mechanisms for this | |
this might be a safer approach as this does not need to care about caches | |
need to know what low-level storage access patterns opcodes translate to | |
also reverts might be hard to handle | |
state-level tracing | |
current approach | |
storage-level tracing | |
trace all db get/set ops | |
does not really work unless we disable all higher-level caching |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment