Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Incorrect stateDiff in trace_replaytransaction #6520

Closed
jo-tud opened this issue Sep 15, 2017 · 4 comments · Fixed by #8491
Closed

Incorrect stateDiff in trace_replaytransaction #6520

jo-tud opened this issue Sep 15, 2017 · 4 comments · Fixed by #8491
Labels
F2-bug 🐞 The client fails to follow expected behavior. M4-core ⛓ Core client code / Rust. M6-rpcapi 📣 RPC API. P5-sometimesoon 🌲 Issue is worth doing soon.
Milestone

Comments

@jo-tud
Copy link

jo-tud commented Sep 15, 2017

  • Parity version: v1.8.0-unstable-d520aa2-20170829/x86_64-linux-gnu/rustc1.19.0
  • Operating system: Linux
  • And installed: from source

Problem:

The problem relates to the trace_replaytransaction RPC call.

If A has balance 1000 and B has balance 1000, there are two storage keys with both a value of 1000 in the storage of the contract. In theory, if A sends 500 tokens to B, there should be a stateDiff like this:

          "storage": {
            "0x3122cf52ca415f61f9a275b9b68122794febbe33bf20650f5a17717ee0875719": {
              "*": {
                "from": "0x00000000000000000000000000000000000000000000000000000000000003e8",
                "to": "0x000000000000000000000000000000000000000000000000000000000000014f"
              }
            },
            "0xf54353a2b20ca39c6925309d40b328469cccb296e1e6cc2ee095dd38422a7526": {
              "*": {
                "from": "0x00000000000000000000000000000000000000000000000000000000000003e8",
                "to": "0x00000000000000000000000000000000000000000000000000000000000005dc"
              }

But what I get is this:

       "storage": {
          "0x3122cf52ca415f61f9a275b9b68122794febbe33bf20650f5a17717ee0875719": {
            "*": {
              "from": "0x0000000000000000000000000000000000000000000000000000000000000000",
              "to": "0x000000000000000000000000000000000000000000000000000000000000014f"
            }
          },
          "0xf54353a2b20ca39c6925309d40b328469cccb296e1e6cc2ee095dd38422a7526": {
            "*": {
              "from": "0x0000000000000000000000000000000000000000000000000000000000000000",
              "to": "0x00000000000000000000000000000000000000000000000000000000000005dc"
            }
          }

The from fields are incorrect

Real on chain example (for TX 0xbba6a...):

The above Tx has the following ethon:msgPayload:

Function: transfer(address _to, uint256 _value)

MethodID: 0xa9059cbb
[0]:0000000000000000000000002730826691bb0e970ef1608d5a3b944c29db7ed5
[1]:0000000000000000000000000000000000000000000002ad12e6a90c9c89f800

The token contract is Account 0x5e575279bf9f4acf0a130c186861454247394c06
this means that Account 0x2730826691bb0e970ef1608d5a3b944c29db7ed5 sends 12637381652300000000000 Golem units to Account 0x2730826691bb0e970ef1608d5a3b944c29db7ed5.

As can be seen here (line 32), the token contract that is the ethon:to of the ethon:Tx uses a `mapping (address => uint256) balances;) for storing the golem token

If account 0x5e575279bf9f4acf0a130c186861454247394c06 successfully sends something, its balance cannot be 0 before the transfer. However, in the stateDiff it is:

       "storage": {
          "0x3122cf52ca415f61f9a275b9b68122794febbe33bf20650f5a17717ee0875719": {
            "*": {
              "from": "0x0000000000000000000000000000000000000000000000000000000000000000",
              "to": "0x00000000000000000000000000000000000000000008ed5239ab7f16f7e19df0"
            }
          },
          "0xf54353a2b20ca39c6925309d40b328469cccb296e1e6cc2ee095dd38422a7526": {
            "*": {
              "from": "0x0000000000000000000000000000000000000000000000000000000000000000",
              "to": "0x0000000000000000000000000000000000000000000005314f4a71a02b2bf400"
            }
          }

Here is the full result of curl --data '{"method":"trace_replayTransaction","params":["0xbba6a4ca0ee856f6d0cab991e60fcade2db2b5745b6afee321b899dd37eedd80",["trace","stateDiff"]],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545

https://gist.github.com/jo-tud/8efbe903e81f7271ffc79d8b133ddac2

@jo-tud
Copy link
Author

jo-tud commented Sep 15, 2017

This supports that this is a bug:
Before the token transfer (Block 3000002) - this is displayed incorrectly in the state diff:
curl --data '{"method":"eth_getStorageAt","params":["0xa74476443119a942de498590fe1f2454d7d4ac0d","0x3122cf52ca415f61f9a275b9b68122794febbe33bf20650f5a17717ee0875719","3000002"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545
Result:
{"jsonrpc":"2.0","result":"0x00000000000000000000000000000000000000000008efff4c922823946b95f0","id":1}
After the token transfer (Block 3000003):
curl --data '{"method":"eth_getStorageAt","params":["0xa74476443119a942de498590fe1f2454d7d4ac0d","0x3122cf52ca415f61f9a275b9b68122794febbe33bf20650f5a17717ee0875719","3000003"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545
Result: {"jsonrpc":"2.0","result":"0x00000000000000000000000000000000000000000008ed5239ab7f16f7e19df0","id":1}

@5chdn 5chdn added M4-core ⛓ Core client code / Rust. Z1-question 🙋‍♀️ Issue is a question. Closer should answer. Z0-unconfirmed 🤔 Issue might be valid, but it’s not yet known. labels Sep 17, 2017
@jo-tud
Copy link
Author

jo-tud commented Sep 20, 2017

@5chdn Can I somehow contribute to speed this up?

@5chdn 5chdn added F3-annoyance 💩 The client behaves within expectations, however this “expected behaviour” itself is at issue. M6-rpcapi 📣 RPC API. P5-sometimesoon 🌲 Issue is worth doing soon. F2-bug 🐞 The client fails to follow expected behavior. and removed Z1-question 🙋‍♀️ Issue is a question. Closer should answer. Z0-unconfirmed 🤔 Issue might be valid, but it’s not yet known. F3-annoyance 💩 The client behaves within expectations, however this “expected behaviour” itself is at issue. labels Sep 20, 2017
@ngotchac
Copy link
Contributor

To simplify this a bit :

pragma solidity ^0.4.16;

contract TestContract {
    uint value = 10;
    
    function set (uint nextValue) {
        value = nextValue;
    }
}
  1. Deploy this contract
  2. Call api.eth.getStorageAt('0xdead...', '0x0') : should be 10
  3. Call the set method on the contract with 100
  4. Call api.eth.getStorageAt('0xdead...', '0x0') : should be 100
  5. Call api.trace.replayTransaction('0xdead...', ['stateDiff']) : the only storage diff is for key 0x0 (that's right), and goes from 0x0 to 0x64 (should be from 0xa)

@5chdn 5chdn added this to the 1.9 milestone Oct 5, 2017
@5chdn 5chdn modified the milestones: 1.9, 1.10 Jan 23, 2018
@jo-tud
Copy link
Author

jo-tud commented Feb 22, 2018

Might this be related to #7934 @debris ?

@5chdn 5chdn modified the milestones: 1.10, 1.11 Mar 1, 2018
@5chdn 5chdn modified the milestones: 1.11, 1.12 Apr 24, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
F2-bug 🐞 The client fails to follow expected behavior. M4-core ⛓ Core client code / Rust. M6-rpcapi 📣 RPC API. P5-sometimesoon 🌲 Issue is worth doing soon.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants