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

Global Clock (Testing / Mocking / Development Contract) #32

Open
marcoonroad opened this issue Dec 16, 2018 · 0 comments
Open

Global Clock (Testing / Mocking / Development Contract) #32

marcoonroad opened this issue Dec 16, 2018 · 0 comments
Labels
bug Something isn't working enhancement New feature or request

Comments

@marcoonroad
Copy link
Owner

marcoonroad commented Dec 16, 2018

Related to issue #28.

Our current time-dependent logic relies on non-standard Ganache instructions such as evm_increaseTime and evm_mine (see the piece of code below). It doesn't scale to multiple contracts, as is the case for my Hold and Loyalty tests breaking due the sole addition of an Auction contract. Such black magic / workaround doesn't allow to go backwards in time, neither to undo the time travels forward in time.

const jsonrpc = '2.0'
const id = 0
const send = (method, params = []) =>
web3.currentProvider.send({ id, jsonrpc, method, params })
const timeTravel = async seconds => {
await send('evm_increaseTime', [seconds])
await send('evm_mine')
}

A good approach would be to deploy a Global Clock Contract. This contract would be a Singleton (in Ganache, it's possible to interact with the migrated / deployed contract on tests). A flag to describe either the development or production mode would be needed as well. The development mode of this contract allows to one owner to either forward or backward the clock for a given sender / caller (in the case, the contract relying on the current timestamp). So, the implementation carries 2 mappings from addresses to uint256 values. The first mapping is the amount to forward in time over block.timestamp, while the latter is the amount to backward (i.e, subtract) from block.timestamp.

Clients / users can rely and trust all of the contracts of this library whenever the Global Clock is deployed with the production mode. Otherwise, they must not interact with the contracts deployed, 'cause a malicious party could break the rules regarding the contracts (only if he has the authority to change the Global Clock).

To help us to hold such time invariant on the JavaScript / integration test side as well, the good library timekeeper could be used too. The possible sketch for the test support API could be:

await timeTravel(seconds, targetContract.address, async () => {
  // internal logic dealing with the contract <targetContract>
})

Where before the asynchronous block call, we forwards the time for the targetContract by seconds, and after the block call, we backwards the time by seconds for this contract, no matter if the asynchronous block call resolved with a value or rejected with a reason (that backward action could be regarded as a cleanup).

@marcoonroad marcoonroad added bug Something isn't working enhancement New feature or request labels Dec 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant