Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

BUG: not possible to delete or set storage on forked chain #436

Closed
elenadimitrova opened this issue Jun 18, 2019 · 6 comments
Closed

BUG: not possible to delete or set storage on forked chain #436

elenadimitrova opened this issue Jun 18, 2019 · 6 comments

Comments

@elenadimitrova
Copy link

elenadimitrova commented Jun 18, 2019

SSTORE operations fail to have effect although transactions are reported successful. This is only present on a forked chain.

Expected Behavior

SSTORE(X, Y) should set storage slot X to value Y on a forked chain.

Current Behavior

SSTORE(X, Y) has no effect on storage, irrespective of whether this is setting a slot from zero to non-zero value, or the other way around. Found when testing a possibly related issue #653

Steps to Reproduce (for bugs)

Use the following contract for testing

pragma solidity 0.5.8;
contract ContractEditing {
  function setStorageSlot(uint256 _slot, bytes32 _value) public {
    uint x = _slot;
    bytes32 y = _value;
    assembly {
      sstore(x, y)
    }
  }
}
  1. Start local ganache instance in debug mode yarn run ganache-cli --debug (will run on http://localhost:8545)

  2. Start the truffle console against the local development instance above yarn run truffle console

  3. In the console, create a new instance of ContractEditing via const contractEditing = await ContractEditing.new()

  4. In the console, for the test contract instance, set storage slot 1 to value 0x02
    await contractEditing.setStorageSlot(1, "0x02")

  5. Ensure the value is set
    await web3.eth.getStorageAt(contractEditing.address, 1)
    you should get back 0x0200000000000000000000000000000000000000000000000000000000000000

  6. Now fork the above chain in a new instance running on a different port, e.g. 8900
    yarn run ganache-cli --fork http://localhost:8545 --port 8900

  7. Add truffle config for a new local network running on the above port

testFork: {
      host: "localhost",
      port: 8900,
      network_id: "*"
    },
  1. Start the truffle console against the forked development chain
    yarn run truffle console --network testFork

  2. Initialise the ContractEditing instance from the original dev chain (you'll need the address of the contract off development chain, e.g. 0x4D6f43bbA56AE29BD5a69C0FE08f034Bb318BeaE)
    const contractEditing = await ContractEditing.at("0x4D6f43bbA56AE29BD5a69C0FE08f034Bb318BeaE")

  3. Ensure the storage slot is what we set it to in step 4 via rerunning
    await web3.eth.getStorageAt(contractEditing.address, 1)
    you should still get back 0x0200000000000000000000000000000000000000000000000000000000000000

  4. Now try changing that storage slot in the forked chain
    await contractEditing.setStorageSlot(1, "0x03")

  5. Ensure the storage slot has changed:
    await web3.eth.getStorageAt(contractEditing.address, 1)
    you should get back the new value 0x03 but we still get back 0x0200000000000000000000000000000000000000000000000000000000000000

You can try different combinations of the storage slot changes. I haven't been able to get anything to stick on the forked chain.

Context

This was found during testing of #652 which might be one of the symptoms of this issue.
The above tests also fail with the dirty hack proposed here #653 (comment)

Your Environment

@niklasb
Copy link
Contributor

niklasb commented Jun 21, 2019

I think this could be an unrelated bug in the eth_getStorageAt implementation: The SSTORE does a PUT on key <Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01> (Buffer) of the storage trie, but then the forked eth_getStorageAt actually looks up the key "0x1" (string). This is different from the unforked implementation, where eth_getStorageAt will cause a lookup of the correct Buffer key.

The storage seems to be set correctly though, for example it can be retrieved later via SLOAD.

@niklasb
Copy link
Contributor

niklasb commented Jun 21, 2019

It's also pretty obvious where this bug is: If you compare https://github.com/trufflesuite/ganache-core/blob/develop/lib/blockchain_double.js#L1103 and https://github.com/trufflesuite/ganache-core/blob/develop/lib/utils/forkedblockchain.js#L276 you can see the disparity.

Opened a very small PR for this #438

@elenadimitrova
Copy link
Author

I did test your suggested fix back here #652 (comment) is this merged fix something else I should try?

@niklasb
Copy link
Contributor

niklasb commented Jul 8, 2019 via email

@elenadimitrova
Copy link
Author

elenadimitrova commented Jul 11, 2019

I tested the fix works as of Ganache CLI v6.4.6-beta.0 (ganache-core: 2.5.8-beta.0) 🎉

EDIT: I tested #652 as well but that issue still persists.

@nicholasjpaterno
Copy link
Contributor

Closing as @elenadimitrova can confirm this issue has been fixed in the latest beta! Thanks @elenadimitrova!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants