gnolang / gno

Gno: An interpreted, stack-based Go virtual machine to build succinct and composable apps + Gno.land: a blockchain for timeless code and fair open-source
https://gno.land/
Other
839 stars 342 forks source link

`Time.Now()` always return initial UNIX time #2348

Open notJoon opened 1 week ago

notJoon commented 1 week ago

Description

Found this while checking #2076

When you call time.Now(), it should return the elapsed time since UTC January 1, 1970 00:00:00. However, when you call this function and print the time as shown below, it outputs the value 1970-01-01 00:00:00 +0000 UTC m=+0.000000001. It seems that instead of the elapsed time from that point, it is printing that point in time itself.

package main

import (
    "time"
)

func main() {
    umt := time.Now()
    println(umt)
}

// output:
1970-01-01 00:00:00 +0000 UTC m=+0.000000001

When you run the code below, it prints the current time in the format YYYY-MM-DD HH-MM-SS, and you can see the initial UNIX time is displayed.

import (
    "time"
)

func main() {
    umt := time.Now().UTC().Format("2006-01-02 15:04:05")
    println(umt)
}

// output:
1970-01-01 00:00:00

Currently, there are two version of time.Now(): one that is a ported version of the Go standard library and another that is handled by native binding. I'm not sure which one is actually being called, but I think the latter implmentation will be executed.

The function implemented with native binding calculates the time using the Timestamp and TimestampNano fields of ExecContext. I suspect that these fields might be storing a value of 0, causing all times to be output as the UNIX epoch time.

https://github.com/gnolang/gno/blob/a1ab6a190cbd6082160244a42dd2b257c2254a68/gnovm/stdlibs/std/context.go#L10-L22

https://github.com/gnolang/gno/blob/a1ab6a190cbd6082160244a42dd2b257c2254a68/gnovm/stdlibs/time/time.go#L10-L17

grepsuzette commented 1 week ago

In case of a main() run with gno run your_main.gno it's the second case you mention. So: https://github.com/gnolang/gno/blob/a1ab6a190cbd6082160244a42dd2b257c2254a68/gnovm/stdlibs/native.go#L945-L957

calls... https://github.com/gnolang/gno/blob/a1ab6a190cbd6082160244a42dd2b257c2254a68/gnovm/stdlibs/time/time.go#L10-L17

where the machine is set, but m.Context == nil thus returning 0, 0, 0 (I tested this adding panics and recompiling the code).

Are there counterindications to not want the actual timestamps here?

If we do, we probably want to reduce the precision of the returned timestamps, because of side-channels vulns like meltdown, as divulging precise timing information could be used to create a more effective attack model.

leohhhn commented 1 week ago

cc @thehowl