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
893 stars 373 forks source link

gnodev time.Now() values are not preserved on reload #1509

Open jefft0 opened 9 months ago

jefft0 commented 9 months ago

In gnodev, preserve time.Now() values on reload

Description

In gnodev, the reload operation replays all the transactions. In general this lets the realm functions restore the state. But if some realm functions use time.Now() then this returns the (arbitrary) time of reload, not the time of the original transaction. Therefore, reload does not actually restore the state.

Your environment

Steps to reproduce

Expected behaviour

The boards realm uses time.Now() for the displayed post time. Reload should restore the realm state including timestamps from time.Now()

Actual behaviour

The timestamps of all message have the time of reload, erasing important information. This is because to reload gnodev resends the transactions where the block time is the current time of reload. This same timestamp is returned by every call to time.Now() .

(Related, the boards realm in testnet3 was built by replaying transactions, similarly to gnodev reload. The original message timestamps are erased and are set to the same value "2023-08-18 11:44am UTC". https://test3.gno.land/r/demo/boards:testboard .)

Proposed solution

One possible solution: The transaction processing code should have an option to specify the block time. Instead of using a high-level broadcast during replay, gnodev should call the lower-level transaction processing code and supply the correct timestamp of the original transaction. This will be used by time.Now().

Here are the message times before reload: Screenshot 2024-01-10 at 10 15 01

Here is where all timestamps are reset after reload: Screenshot 2024-01-10 at 10 17 17

⚠️ Risks and impact if not fixed

A realm developer can't use gnodev with any realm that relies on time.Now(). For example:

moul commented 9 months ago

Depends on #1511 Related with #1108