Implement fine-grained control over time #87
Labels
enhancement
New feature or request
prio:shouldhave
For high priority issues that we *should* have because they are major outcomes
TL;DR Summary
To allow more control over time, I propose introducing some flags:
--starting-timestamp
to set the timestamp of the first block(
--starting-timestamp-from-genesis
to take the timestamp from the Genesis file instead)--block-time
to determine how timestamps in blocks increase from one block to the next--block-production-interval
to determine how often CometMock produces blocks automatically--auto-tx
to determine whether CometMock produces a new block when a tx is broadcasted or notGoal
The goal is to enable use cases where time needs to be controlled precisely, i.e.
where we control precisely the block timestamps.
This can be split into separate features:
Feature 1: Decoupling the initial timestamp from the system time
This feature is straightforward: There should be a way to set the initial timestamp completely independently from the system time.
This will be implemented by adding a new CLI flag,
--starting-timestamp
.The default value is time.Now() at startup of CometMock.
Alternatively, one can also opt to use the Genesis time for the first block
with the
--starting-timestamp-from-genesis
flag.Feature 2: Decoupling the time advancement from the system clock
This feature is more complex. I see that we want three modes for timestamps:
Timestamps increase at the same rate as the system clock
With this mode, the exact block timestamps depend on how fast blocks are processed by the app, networking delays, ...
This is the mode that is currently in place, and where the interval for blocks can be set by using
--block-time
, e.g.--block-time 5
makes it so that CometMock sleeps for 5 seconds in between building blocks, and bases the timestamp on the current time (shifted by any time advancements that were made).Timestamps increase at a fixed rate
This is similar to the last mode, but now block timestamps do not depend on how fast blocks are processed by the app, but rather, block timestamps are always advanced by the fixed rate, no matter how much the system clock advances between blocks (but the user may shift timestamps by advancing time).
Timestamps only increase based on user inputs
This is a subcase of Timestamps increasing at a fixed rate, namely the case where the rate is 0.
Timestamps only increase when the user tells them to, and this (together with decoupling the initial time)
gives complete, precise control over the timestamps of blocks.
Feature 3: (Give an option to) Decouple block production from transaction broadcasting
Currently, CometMock immediately produces a new block when a transaction is broadcast.
This does not work well when more precise control over blocks is needed.
In particular, it does not work well with fixed-rate increasing timestamps because when many transactions are submitted (and each produces a new block), the block time would rapidly increase, which could e.g. make ibc connections go out of sync.
Implementation
I propose the addition of three new flags for the cometmock start command, and to change the
block-time
flag:--auto-tx {true | false}
If true, when a tx is set to be broadcasted, a new block is immediately created which contains just this transaction.
If false, all transactions that are broadcasted are kept in a queue, and whenever a new block is created for any reason (either by explicitly calling the advance_blocks endpoint, or with the appropriate flags, by system time passing), all transactions in the queue are included in the block.
(There might be good reason to not include all transactions from the queue, but rather to only include transactions up to a certain byte limit).
Defaults to false.
auto-tx=true is CometMocks current behaviour.
--block-time {time_in_milliseconds}
This flag already exists, but I would propose to change its semantics. Currently,
block-time
governs how long CometMock sleeps before creating a new block, and the block timestamps are taken from local time.I would instead change this as follows: When a new block is created, its timestamp is
where
last_block_timestamp
is the timestamp of the last block created by CometMock,time_advancement_since_last_block
is the sum of time that CometMock was told to advance time by with calls toadvance_time
.This means
block-time
would not govern how often blocks are produced, but only the timestamps of blocks.If
block-time
is below 0, the system clock will be used as a reference for block timestamps, so the above equation would becomewhere
starting_offset
is the offset as calculated from thestarting_timestamp
.Defaults to 1 second.
Current behaviour is block-time=0.
--block-production-interval {time_in_milliseconds}
This flag will take on the previous role of the
block-time
flag.Thus, it governs how often blocks are produced without user intervention. Precisely, it is how long CometMock sleeps after it finished automatically producing one block, before starting to produce the next. This depends on system time.
Setting this to -1 means blocks will not be produced automatically, and will only be produced when
advance_blocks
is called, or (when auto-tx is true) a tx is broadcasted.Defaults to 1 second.
Current behaviour is that this flag can be set, but is currently called
block-time
.User stories
She can run with these settings:
cometmock [...] --block-time -1 --block-production-interval 1000 --auto-tx true
and her test run could look like this:
Bob can run with these settings
cometmock [...] --block-time 1000 --block-production-interval 1000 --auto-tx true --starting-timestamp 0
then Bobs test run could look like this:
He can run with settings like this:
cometmock [...] --block-time 0 --block-production-interval -1 --auto-tx false
--block-production-interval -1 meaning no blocks will be produced automatically.
--block-time 0 meaning timestamps will not increment automatically.
Then his test run can look like this:
The text was updated successfully, but these errors were encountered: