Skip to content

Commit 9ca208f

Browse files
authored
Merge pull request #52 from cardano-scaling/push-tmwqxvkqtquo
Principle: Optimise for the worst case
2 parents 5b0e2e0 + b9fddf7 commit 9ca208f

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Summary
22

33
- [Introduction](introduction/README.md)
4+
- [Principles](principles/README.md)
45
- [Network](network/README.md)
56
- [Multiplexing](network/multiplexing.md)
67
- [Mini-protocols](network/mini-protocols.md)

src/principles/README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Principles
2+
3+
This section contains general principles to apply when developing Cardano nodes.
4+
5+
## Optimise only for the worst case
6+
7+
Algorithms often possess different performance characteristics in the best,
8+
average and worst cases. Quick sort has, for example, `O(n*log(n))` time
9+
complexity in the average case, but `O(n^2)` in the worst case.
10+
11+
Often in software we are interested in optimising for the average case, since
12+
over time it tends to result in the highest overall performance. In Cardano,
13+
however, we take a different approach: we want to only optimise the worst case
14+
performance, and indeed, pick algorithms where _worst case is the same as best
15+
(or average) case_.
16+
17+
### Motivation
18+
19+
There are two motivating ideas behind this principle:
20+
21+
1. _Performance will come to be relied upon_. This is an instance of Hyrum's
22+
law in action:
23+
24+
> With a sufficient number of users of an API, it does not matter what you
25+
> promise in the contract: all observable behaviors of your system will be
26+
> depended on by somebody.
27+
28+
If we manage to increase average performance, tools will be developed that
29+
come to expect this behaviour. If blocks can be processed faster, for
30+
example, there may be pressure to use that extra time to allow larger script
31+
execution budgets.
32+
33+
1. Forcing honest nodes to do more work provides an attack opportunity for the
34+
adversary. In the worst case, an adversary could potentially force nodes to
35+
fail to adopt or forge blocks, and hence potentially gain control of the
36+
chain.
37+
38+
### Example: UTxO locality
39+
40+
As an example, there is certain evidence that the UTxO set exhibits a degree of
41+
temporal locality. That is, there are a number of long-lived UTxO entries that
42+
are unlikely to be spent, while recently created entries are quite likely to
43+
come up again.
44+
45+
We could choose to take advantage of this to organise the UTxO along the form
46+
of a LRU (least recently used) cache. This would likely speed up UTxO lookup
47+
in the average case, particularly were the UTxO stored on disk.
48+
49+
However, an attacker could then choose to deliberately craft a number of
50+
transactions containing UTxO that were created a long time ago. A block filled
51+
with such transactions, while being perfectly legitimate, might take
52+
significantly longer to process than a regular block. The attacker could use
53+
this delay to gain an advantage in block forging and thus magnify their
54+
effective stake.
55+
56+
### Considerations
57+
58+
Whilst we have written the above as a general principle, there are of course
59+
various considerations that effect how much we want to follow it:
60+
61+
1. The situation we most want to avoid is where an attacker could control an
62+
input such that they can force the worst-case behaviour. The UTxO locality
63+
example above is one such.
64+
1. Still problematic are cases where an attacker cannot control the performance
65+
but can predict it, or less serious still, observe it. Either way a
66+
prepared attacker could take advantage of the degraded performance to launch
67+
an attack on the chain.
68+
1. Either of these cases are exacerbated if the same behaviour is coordinated
69+
across all nodes, since this allows an attacker to exploit a performance
70+
drop across the entire network.
71+
72+
In situations where the inputs to a function are random or not observable by
73+
an adversary, or where the effects are purely local, it may therefore still be
74+
sensible to optimise for the average case. An example of such might be in
75+
local state query computations, since these are triggered only by a (trusted)
76+
local connection and do not lie on a critical path for block forging or
77+
adoption.
78+
79+
The key point is that, in the Cardano setting, optimisations should be carefully
80+
considered and it is certainly not the case that better average-case performance
81+
is always desirable!

0 commit comments

Comments
 (0)