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

[Test] Unable to use Test.moveTime #264

Open
austinkline opened this issue Dec 27, 2023 · 4 comments
Open

[Test] Unable to use Test.moveTime #264

austinkline opened this issue Dec 27, 2023 · 4 comments
Labels
Bug The issue represents a bug, malfunction, regression Feedback

Comments

@austinkline
Copy link

Current Behavior

Using Test.moveTime doesn't seem to impact the timestamp of a block

Expected Behavior

Test.moveTime should result in getCurrentBlock().timestamp changing

Steps To Reproduce

pub fun testMoveTime() {
    let before = getCurrentBlock().timestamp
    Test.moveTime(by: 1.0)
    let after = getCurrentBlock().timestamp
    assert(after - before >= 1.0) // this always fails
}

Also fails if you use scripts to obtain the time instead of using the testing framework directly:

pub fun getCurrentTime(): UFix64 {
    return scriptExecutor("util/get_current_time.cdc", [])! as! UFix64
}
pub fun testMoveTime() {
    let before = getCurrentTime()
    Test.moveTime(by: 1.0)
    heartbeat()
    let after = getCurrentTime()

    assert(after - before == 1.0)
}

Script:

pub fun main(): UFix64 {
    return getCurrentBlock().timestamp
}

Environment

- Cadence version: v1.9.2
- Network: Testing Framework
@austinkline austinkline added Bug The issue represents a bug, malfunction, regression Feedback labels Dec 27, 2023
@austinkline
Copy link
Author

Did some further debugging. Seems like this actually works when you grab time directly from the Blockchain itself, you cannot use the testing framework's time. So anyone who uses Test.moveTime needs to ensure they're grabbing time with a helper script like what I had to do.

It seems like the use of log threw some of this off when running directly in the vscode extension, once I removed all logs, things passed as expected so long as I only grabbed timestamps using a script of some kind

#265

@austinkline
Copy link
Author

Final piece I've found is that Test.moveTime seems to only work with whole numbers, but it accepts a UFix64


pub fun testMoveTime() {
    let before = getCurrentTime()
    Test.moveTime(by: 1.5)
    let after = getCurrentTime()

    log(before)
    log(after)
    assert(after - before >= 1.5)
}

Logs out:

9:33AM INF LOG: 1703698412.00000000
9:33AM INF LOG: 1703698413.00000000

@turbolent turbolent changed the title [Testing Framework] Unable to use Test.moveTime [Test] Unable to use Test.moveTime Dec 29, 2023
@m-Peter
Copy link
Contributor

m-Peter commented Jan 3, 2024

Thanks for the report @austinkline 🙇 ,

You are in fact correct in both of your findings. Test.moveTime only affects the Blockchain's time, and the reason behind it is that contracts under testing are deployed on the Blockchain, so they would fetch the current block data from the Blockchain, e.g.:

access(all) contract TimeLocker {
    access(all) let lockPeriod: UFix64
    access(all) let lockedAt: UFix64

    init(lockedAt: UFix64) {
        self.lockedAt = lockedAt
        // Lock period is 30 days, in the form of seconds.
        self.lockPeriod = UFix64(30 * 24 * 60 * 60)
    }

    access(all)
    fun isOpen(): Bool {
        let currentTime = getCurrentBlock().timestamp

        return currentTime > (self.lockedAt + self.lockPeriod)
    }
}

In the above sample contract, isOpen() would check the timestamp from the Blockchain's current block.
The stdlib functions in the script environment that runs test scripts, are not wired to that Blockchain, that's why you would get different results. I am not sure if it is possible to achieve that functionality. I will check it out though.

The reason for accepting UFix64 as the delta. in Test.moveTime is because the timestamp field from getCurrentBlock() is also of UFix64 type. However, we can only advance the system clock in whole seconds. I am not sure if we can have smaller granularity than seconds, I can understand your confusion though 😅

I hope this clarifies things better 🙏

EDIT: We cannot have granularity smaller than seconds, neither in testnet/mainnet.

@turbolent
Copy link
Member

The clock should probably be changed to support sub-second granularity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug The issue represents a bug, malfunction, regression Feedback
Projects
None yet
Development

No branches or pull requests

3 participants