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

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

Closed
notJoon opened this issue Jun 13, 2024 · 6 comments
Closed

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

notJoon opened this issue Jun 13, 2024 · 6 comments
Assignees
Labels
🐞 bug Something isn't working

Comments

@notJoon
Copy link
Member

notJoon commented Jun 13, 2024

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.

type ExecContext struct {
ChainID string
Height int64
Timestamp int64 // seconds
TimestampNano int64 // nanoseconds, only used for testing.
Msg sdk.Msg
OrigCaller crypto.Bech32Address
OrigPkgAddr crypto.Bech32Address
OrigSend std.Coins
OrigSendSpent *std.Coins // mutable
Banker BankerInterface
EventLogger *sdk.EventLogger
}

func X_now(m *gno.Machine) (sec int64, nsec int32, mono int64) {
if m == nil || m.Context == nil {
return 0, 0, 0
}
ctx := std.GetContext(m)
return ctx.Timestamp, int32(ctx.TimestampNano), ctx.Timestamp*int64(time.Second) + ctx.TimestampNano
}

@notJoon notJoon changed the title Time.Now() always return 0 Time.Now() always return initial UNIX time Jun 13, 2024
@grepsuzette
Copy link
Contributor

grepsuzette commented Jun 16, 2024

In case of a main() run with gno run your_main.gno it's the second case you mention. So:

gno/gnovm/stdlibs/native.go

Lines 945 to 957 in a1ab6a1

{
"time",
"now",
[]gno.FieldTypeExpr{},
[]gno.FieldTypeExpr{
{Name: gno.N("r0"), Type: gno.X("int64")},
{Name: gno.N("r1"), Type: gno.X("int32")},
{Name: gno.N("r2"), Type: gno.X("int64")},
},
func(m *gno.Machine) {
r0, r1, r2 := libs_time.X_now(
m,
)

calls...

func X_now(m *gno.Machine) (sec int64, nsec int32, mono int64) {
if m == nil || m.Context == nil {
return 0, 0, 0
}
ctx := std.GetContext(m)
return ctx.Timestamp, int32(ctx.TimestampNano), ctx.Timestamp*int64(time.Second) + ctx.TimestampNano
}

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
Copy link
Contributor

leohhhn commented Jun 18, 2024

cc @thehowl

@jefft0
Copy link
Contributor

jefft0 commented Oct 17, 2024

Hello @notJoon . Do you think this could be related to the Time.Now() issue reported in #2960 ?

@notJoon
Copy link
Member Author

notJoon commented Oct 17, 2024

Hello @notJoon . Do you think this could be related to the Time.Now() issue reported in #2960 ?

not sure, but maybe related 🤔🤔🤔🤔🤔

@thehowl
Copy link
Member

thehowl commented Oct 22, 2024

#851 (comment)

@MikaelVallenet is going to take up a larger refactor of time - I think we can also move time.Now() in testing to be at the time of doing the tests. Though I think this should be purely aesthetical; it should not shift in the test as we shouldn't be giving the system time, even during tests (because the time won't ever be changing when you work on-chain).

@thehowl
Copy link
Member

thehowl commented Oct 22, 2024

I'll close this in favour of #851, as I think this issue adds little additional context to that anyway.

@thehowl thehowl closed this as not planned Won't fix, can't repro, duplicate, stale Oct 22, 2024
@github-project-automation github-project-automation bot moved this from Backlog to Done in 🤝🏻 Partner: Onbloc Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 bug Something isn't working
Projects
Status: Done
Development

No branches or pull requests

7 participants