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

block.timestamp value varies within block #111

Closed
cgewecke opened this issue May 6, 2018 · 11 comments · Fixed by #443
Closed

block.timestamp value varies within block #111

cgewecke opened this issue May 6, 2018 · 11 comments · Fixed by #443

Comments

@cgewecke
Copy link
Contributor

cgewecke commented May 6, 2018

@vzts reported this behavior in truffle 921 - there's more detail there. In summary it's unclear what the expected behavior is and @benjamincburns suggested we follow the other major clients, favoring static timestamps if there's no agreement.

Have just tested intra-block time values on geth dev and Parity POA over 4 calls at 1 second intervals: both have static timestamps.

Will send a PR fixing this at processCall - just opening here in the meantime in case this change would impact any other timing related issues or there are implementation details to consider.

@mikeseese
Copy link
Contributor

from Chris:

It appears so. I think the problem is that the timestamp is set at createBlock but it should inherit the latest / defaultBlock timestamp for call cases. https://github.com/trufflesuite/ganache-core/blob/develop/lib/blockchain_double.js#L345

@benjamincburns
Copy link
Contributor

Added "needs validation" because we've recently reworked some of the timekeeping logic and this may have had an impact.

@rudolfix
Copy link

Ganache CLI v6.1.8 (ganache-core: 2.2.1)
this problem still persists, I'm logging timestamps via events in quite complex transaction and I'm getting different timestamps. apparently they are taken from the system clock each time

@haltman-at
Copy link
Contributor

Just wanted to note, just encountered this while adding support for globally-available variables to the debugger. If the transaction was run with Ganache (which I assume debugger transactions often will be), the debugger may incorrectly report the value of now due to the inconsistency here.

(Note: I haven't tried upgrading Ganache, but seeing as nobody closed this, I'm assuming this is still live. I'm just commenting because I thought its impact on the debugger was worth noting.)

@d10r
Copy link

d10r commented May 22, 2019

I still see this issue in the ganache bundled with truffle 5.0.18.
That issue seems to make it impossible to write deterministic tests for contracts using block.timestamp in constant methods.
Even when manually writing blocks with evm_mine in order to have deterministic timestamps in blocks, immediately following calls to constant methods may still end up using an incremented timestamp if the internal clock happens to flip second right at that moment.

I've tried for a few hours to work around it, but so far failed.

@d10r
Copy link

d10r commented May 23, 2019

I've found a workaround which for me greatly reduces the probability of spurious test failures:

  • Check how many milliseconds the system clock is away from switching to the next second
  • If the switch is imminent (I've put 200 ms as threshold), blocking wait for that switch
  • Mine a new block and/or set the chain time to the wanted value

Code:

function sleepMs(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function getLastBlockTimestamp() {
    return (await web3.eth.getBlock(await web3.eth.getBlockNumber())).timestamp;
}

async function setChainTimestamp(ts) {
    await web3.currentProvider.send({
        jsonrpc: '2.0',
        method: 'evm_setTimestamp',
        params: [ ts ],
    }, () => {});
    // for unknown reason, omitting the second parameter (callback) fails in my environment
}

async function mineBlockWithTS(ts) {
    await web3.currentProvider.send({
        jsonrpc: '2.0',
        method: 'evm_mine',
        params: [ts],
    }, () => {});

    await setChainTimestamp(ts);
}

async function fastForward(offset) {
    const t0 = await getLastBlockTimestamp();
    await alignToSystemClock();
    await mineBlockWithTS(t0 + offset);
    return t0 + offset;
}

With this code (I'm not sure if all of it is needed, that's what I found working for me), after invoking fastForward, the application has at least ~200 ms of time to call constant methods depending on correct block.timestamp values.
Still no guarantee, but in many cases that's enough - better than nothing :-/

dforsten pushed a commit to lab10-coop/streaming-token-contracts that referenced this issue May 31, 2019
@davidqhr
Copy link

I create a temporary fix.For anyone who are waiting this to be fixed, you can try to use @davidqhr/ganache-cli@6.4.3 for a while.
All changes are at davidqhr@3518200

@haltman-at
Copy link
Contributor

@davidqhr, perhaps you should turn this into an actual PR?

@haltman-at
Copy link
Contributor

Hey, @davidqhr, were you going to PR this? It looks like you basically have this all set up to go. I haven't checked your code or anything, but if you have a fix for this it would certainly be helpful to PR it so it can make its way into the codebase. Thank you!

@davidqhr
Copy link

davidqhr commented Jul 3, 2019

@haltman-at Sure. Will create a PR.

@haltman-at
Copy link
Contributor

Thank you!

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

Successfully merging a pull request may close this issue.

9 participants