Skip to content

Commit e0f9d58

Browse files
authored
Merge pull request #271 from onflow/measuring-time-and-testing
Edit Measuring Time and Testing articles
2 parents 88e1394 + 79d4f92 commit e0f9d58

2 files changed

Lines changed: 93 additions & 155 deletions

File tree

docs/measuring-time.mdx

Lines changed: 34 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,54 +3,34 @@ title: Measuring Time In Cadence
33
sidebar_label: Measuring Time
44
---
55

6-
## Accessing Time From Cadence
6+
## Accessing time from Cadence
77

8-
Both the [block height and the block timestamp](./language/environment-information.md#block-information) are accessible from within Cadence code.
8+
Both the [block height and the block timestamp] are accessible from within Cadence code.
99

10-
This means that they can be used to calculate dates and durations by smart contracts on Flow
11-
that need to lock resources until a particular point in the future, calculate values between a range of dates,
12-
or otherwise deal with the passage of time.
10+
This means that they can be used to calculate dates and durations by smart contracts on Flow that need to lock resources until a particular point in the future, calculate values between a range of dates, or otherwise deal with the passage of time.
1311

1412
There are two popular strategies that are used to measure time on blockchains:
1513

16-
1. Use the timestamp, and optionally check that the average duration of the last n blocks
17-
is close enough to the block target duration to make an attack unlikely.
18-
2. Use the block height directly. Block height can be treated intuitively
19-
(a hundred blocks, a thousand blocks) or can be related to estimated timestamps
20-
and thereby to time off-chain by the methods described in this article.
21-
22-
## Time On The Flow Blockchain
23-
24-
> Flow currently produces blocks approximately every 0.8 seconds. Note that block height only has a loose correlation with time,
25-
as [the block rate naturally fluctuates](https://developers.flow.com/build/run-and-secure/nodes/faq/operators.mdx#does-the-blockheight-go-up-1-every-second).
26-
27-
In addition to the natural variation described above,
28-
there are several theoretical block production attacks that could skew this relationship even further.
29-
These attacks are unlikely on Flow in the absence of byzantine nodes.
30-
The timestamp cannot be earlier than the timestamp of the previous block,
31-
and cannot be too far into the future ([currently ten seconds](https://github.com/onflow/flow-go/blob/master/module/builder/consensus/builder.go#L60))
32-
33-
Proposed blocks that fail to satisfy these conditions will be rejected by Flow's consensus algorithm.
34-
But the mere possibility of these attacks places an additional limit on the confidence
35-
with which we can use block heights or block timestamps to determine off-chain time from protocol-level data on-chain.
36-
37-
The block timestamp is not the only way to identify a block within the flow of off-chain time.
38-
Each block is numbered successively by its "height", block 70000 is followed by block 70001, 70002,
39-
and so on. Blocks with heights out of sequence are rejected by Flow's consensus algorithm.
40-
In theory the timestamp on a block should be roughly equivalent to the timestamp on the Flow genesis block,
41-
plus the block height multiplied by the target block rate.
42-
But as we have seen both the target and the on-chain average rate of block production may vary over time.
43-
This makes such calculations more difficult.
44-
45-
### Using The Timestamp
46-
47-
Given that [Flow consensus will reject new blocks with a timestamp more than ten seconds into the future from the previous block](https://github.com/onflow/flow-go/blob/1e8a2256171d5fd576f442d0c335c9bcc06e1e09/module/builder/consensus/builder.go#L525-L536),
48-
as long as you do not require an accuracy of less than ten seconds
49-
it is probably safe to use the block timestamp for events lasting a few days - in the absence of a change in block production rate targets.
50-
Or, more intuitively, your timestamp is highly likely to be the correct hour,
51-
very likely to be the correct minute, and may well be within ten seconds of the correct second.
52-
Which of these scales is tolerable for your use case depends on how long the events you need to represent will take.
53-
In an auction lasting several days, you are probably safe with any scale above ten seconds.
14+
1. Use the timestamp, and optionally check that the average duration of the last N blocks is close enough to the block target duration to make an attack unlikely.
15+
2. Use the block height directly. Block height can be treated intuitively (a hundred blocks, a thousand blocks) or can be related to estimated timestamps and thereby to time offchain by the methods described in this article.
16+
17+
## Time on the Flow blockchain
18+
19+
:::note
20+
21+
Flow currently produces blocks approximately every 0.8 seconds. Note that block height only has a loose correlation with time, as the block rate naturally fluctuates.
22+
23+
:::
24+
25+
In addition to the natural variation described above, there are several theoretical block production attacks that could skew this relationship even further. These attacks are unlikely on Flow in the absence of byzantine nodes. The timestamp cannot be earlier than the timestamp of the previous block, and cannot be too far into the future ([currently ten seconds]).
26+
27+
Proposed blocks that fail to satisfy these conditions will be rejected by Flow's consensus algorithm. But the mere possibility of these attacks places an additional limit on the confidence with which we can use block heights or block timestamps to determine offchain time from protocol-level data onchain.
28+
29+
The block timestamp is not the only way to identify a block within the flow of offchain time. Each block is numbered successively by its _height_ — block 70000 is followed by block 70001, 70002, and so on. Blocks with heights out of sequence are rejected by Flow's consensus algorithm. In theory the timestamp on a block should be roughly equivalent to the timestamp on the Flow genesis block, plus the block height multiplied by the target block rate. But as we have seen, both the target and the onchain average rate of block production may vary over time. This makes such calculations more difficult.
30+
31+
### Using the timestamp
32+
33+
Given that [Flow consensus will reject new blocks] with a timestamp more than ten seconds into the future from the previous block, as long as you do not require an accuracy of less than ten seconds it is probably safe to use the block timestamp for events lasting a few days — in the absence of a change in block production rate targets. Or, more intuitively, your timestamp is highly likely to be the correct hour, very likely to be the correct minute, and may well be within ten seconds of the correct second. Which of these scales is tolerable for your use case depends on how long the events you need to represent will take. In an auction lasting several days, you are probably safe with any scale above ten seconds.
5434

5535
```cadence
5636
// To get the timestamp of the block that the code is being executed in
@@ -60,15 +40,9 @@ getCurrentBlock().timestamp
6040
getBlock(at: 70001)?.timestamp
6141
```
6242

63-
### Using The Block Height
43+
### Using the block height
6444

65-
In theory block numbers are more reliable than timestamps,
66-
as the block height is incremented for each block in a fork.
67-
But in practice we must still relate block numbers to off-chain time values,
68-
and to do this requires that we assume that the average block time will hold.
69-
This can vary due to factors other than attacks.
70-
Given that block time targets will vary as Flow development continues,
71-
this will affect any calculations you may make in order to relate block numbers to calendar time.
45+
In theory block numbers are more reliable than timestamps, as the block height is incremented for each block in a fork. But in practice we must still relate block numbers to offchain time values, and to do this requires that we assume that the average block time will hold. This can vary due to factors other than attacks. Given that block time targets will vary as Flow development continues, this will affect any calculations you may make in order to relate block numbers to calendar time.
7246

7347
```cadence
7448
// To get the block number of the block that the code is being executed in
@@ -80,15 +54,14 @@ getBlock(at: 70001)?.height
8054

8155
## Recommendations
8256

83-
If your contract code can tolerate the limitations described above, use block timestamps.
84-
If not, you may need to consider more exotic solutions (time oracles, etc.).
57+
If your contract code can tolerate the limitations described above, use block timestamps. If not, you may need to consider more exotic solutions (e.g., time oracles, and so on).
58+
59+
Whichever method you use, be careful not to hardcode any assumptions about block rates production rates into your code, onchain or off, in a way that cannot be updated later. Block production rates can and will change over time.
60+
61+
Onchain auctions and similar mechanisms should always have an extension mechanism. If someone bids at the last moment (which is easier to do with a block production attack), the end time for the auction extends (if necessary) to N minutes past the last bid (10 minutes, 30 minutes, an hour). As N increases, this becomes more secure: N=5 should be more than enough with the current parameters of the Flow blockchain.
8562

86-
Whichever method you use, be careful not to hardcode any assumptions
87-
about block rates production rates into your code, on-chain or off,
88-
in a way that cannot be updated later. Block production rates can and will change over time.
63+
<!-- Relative links. Will not render on the page -->
8964

90-
On-chain auctions and similar mechanisms should always have an extension mechanism.
91-
If someone bids at the last moment (which is easier to do with a block production attack),
92-
the end time for the auction extends (if necessary) to N minutes past the last bid.
93-
(10 minutes, 30 minutes, an hour). As N increases, this becomes more secure:
94-
N=5 should be more than enough with the current parameters of the Flow blockchain.
65+
[block height and the block timestamp]: ./language/environment-information.md#block-information
66+
[currently ten seconds]: https://github.com/onflow/flow-go/blob/master/module/builder/consensus/builder.go#L60
67+
[Flow consensus will reject new blocks]: https://github.com/onflow/flow-go/blob/1e8a2256171d5fd576f442d0c335c9bcc06e1e09/module/builder/consensus/builder.go#L525-L536

0 commit comments

Comments
 (0)