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

Open
notJoon opened this issue Jun 13, 2024 · 2 comments
Open

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

notJoon opened this issue Jun 13, 2024 · 2 comments
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

@Kouteki Kouteki added the 🐞 bug Something isn't working label Jun 28, 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: Backlog
Development

No branches or pull requests

4 participants