Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why does the estimatedGas not equal the actual used gas #296

Closed
xlz926 opened this issue Feb 26, 2018 · 2 comments
Closed

Why does the estimatedGas not equal the actual used gas #296

xlz926 opened this issue Feb 26, 2018 · 2 comments

Comments

@xlz926
Copy link

xlz926 commented Feb 26, 2018

System information

Geth version: geth 2.0.1
OS & Version: Linux

Contract code

Used this following code as example, but the problem exists for any other contract as well.

pragma solidity ^0.4.0;

contract simplestorage {
  uint  storedData;

  function simplestorage(uint initVal) {
    storedData = initVal;
  }

  function set(uint x) public {
    storedData = x;
  }

  function get() constant returns (uint retVal) {
    return storedData;
  }
}

Get estimatedGas from call simulation, and get the result as 4712388, which is shown as the gas limit of the latest block too.

> eth.estimateGas({"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d","to":"0xfe0602d820f42800e3ef3f89e1c39cd15f78d283","data":"0x60fe47b100000000000000000000000000000000000000000000000000000000000001b2","value":"0x0"})
4712388
> eth.getBlock("latest")
{
  difficulty: 1,
  extraData: "0xd783010702846765746887676f312e372e33856c696e75780000000000000000f9022af893946571d97f340c8495b661a823f2c2145ca47d63c2948157d4437104e3b8df4451a85f7b2438ef6699ff94b131288f355bc27090e542ae0be213c20350b76794b912de287f9b047b4228436e94b5b78e3ee1617194d8dba507e85f116b1f7e231ca8525fc9008a696694e36cbeb565b061217930767886474e3cde903ac594f512a992f3fb749857d758ffda1330e590fa915eb841d5f27426b063fb7d380fa0d3461ddd1c7d77dc459052fb97c8a4301453a1c67f0f30cfe12e7382dd84ff03d07c2fe19e87f0174eb327cfe520dc65a7a7c6079300f9014fb841ea28492e7c26cfb65317845b581772989eb5d2969c569b93281055a955ad47bd595dc23121509b92570c0d3fdb7c172c89fdc11dc3d1a4f7beb2e964c060534301b841cef74344f06fef68bee2cbf7222ee5402572ceb3efb8cd80a62a978643fc30e52abac9c42b978e21349ef5febb7d073720b52c4c7a78ac54538b6eb310f3000200b84118f66a5e8db682167c3f8cde34b4b47a04cea28b18ada8dc95441cbaa4d5b8de2e6cbffc25705e35e81a6b1bf816079f9b6bde26c471164cf01f7737b5e110ca01b841fc323e5cf4ad2559af115fa80c8d831f9b6cb062c9540e4533f489e3c65a0fa953f63c2a8a549aca774e499c9cdbfc523f4f1dd27268fd57a70fc45d04d898e401b8418c09d1edc000ce24c495e9deb6fcc0320879b3aefe893e55bd2c759b8c2012272dc22d6d5ec009411772d6b5af8011230b08141afb64a7b20d2a31f83b077b8300",
  gasLimit: 4712388,
  gasUsed: 0,
  hash: "0x75d2f83f45976b8668f018612f91d51407b6032c3815bfa4d23d679ae947b9e7",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x0000000000000000000000000000000000000000",
  mixHash: "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
  nonce: "0x0000000000000000",
  number: 2057,
  parentHash: "0x067a93f6f482aab99d14224e962a31c6dd12dc3d773bed9689839361146f941f",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 1101,
  stateRoot: "0x0f8103dc5c78e4c9b73ee4af68853a0c37766899e08d329dc49d3e93499d59f2",
  timestamp: 1519637176,
  totalDifficulty: 2058,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

When actually run the transaction, the gas turned out to be 90000.

> eth.sendTransaction({"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d","to":"0xfe0602d820f42800e3ef3f89e1c39cd15f78d283","data":"0x60fe47b100000000000000000000000000000000000000000000000000000000000001b2","value":"0x0"})
"0x807d08223b23d63838f048754a369da3112ce607f0f53c93172f36d4c74198e7"
> eth.getTransaction("0x807d08223b23d63838f048754a369da3112ce607f0f53c93172f36d4c74198e7")
{
  blockHash: "0x27a5ac7e9920334f6b05d17dbcb1181c9efd2f138445b61bb65d5c8640081384",
  blockNumber: 2073,
  from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
  gas: 90000,
  gasPrice: 0,
  hash: "0x807d08223b23d63838f048754a369da3112ce607f0f53c93172f36d4c74198e7",
  input: "0x60fe47b100000000000000000000000000000000000000000000000000000000000001b2",
  nonce: 8,
  r: "0x12d106ff16a3ac9a6a2f60e87992475d183206e2f7df0e43e7d58abefdfa31a0",
  s: "0x4070c742f658ad673293c1cc0135563b3fdf928e538958ccb31cbc7ef60d551",
  to: "0xfe0602d820f42800e3ef3f89e1c39cd15f78d283",
  transactionIndex: 0,
  v: "0x1c",
  value: 0
}

So the question is why the estimatedGas return the gas limit of latest block, instead of the actually running gas?

@kegsay
Copy link

kegsay commented Mar 1, 2018

You posted this on the Quorum slack channel as well. I've encountered this before. From a strictly technical perspective, the EVM has failed to simulate your transaction (it's always returning an error) so the estimateGas function is tending towards the highest valid value which is the block gas limit of the pending block.

So why is it returning an error? If I had a guess, it'd be because this conditional is being hit. The set function will be doing a SSTORE which is a mutating op-code. I'm uncertain what causes the quorumReadOnly flag to be set.

So why does it work when you actually send the transaction? Probably because when you actually send the transaction, quorumReadOnly is no longer true.

It's worth noting that estimateGas is buggy if you use Raft because BlockByNumber was edited to return the latest block instead of the pending block. You generally cannot do this safely due to how the gas limit tends towards the amount of gas actually being used, meaning the returned estimate will be greater than the gas block limit.

You've not given me enough information to say definitively whether this is your problem or not. Try enabling trace logging then try again. In geth:

debug.verbosity(5)

If the cause is down to quorumReadOnly then you should see:

VM in read-only mode. Mutating opcode prohibited

in the logs somewhere.

@fixanoid
Copy link
Contributor

Tracked in #461

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

No branches or pull requests

3 participants