Skip to content

Commit 415c1f2

Browse files
authored
docs: fix typos (#772)
1 parent 38d8e52 commit 415c1f2

8 files changed

+108
-108
lines changed

Diff for: docs/architecture.md

+15-15
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ subgraph "Consensus Node"
99
engine[Engine API Client]
1010
BAPI[Beacon API]
1111
TICK[Slot processor]
12-
blk_db[Block DB]
13-
BS_db[Beacon State DB]
12+
blk_db[Block DB]
13+
BS_db[Beacon State DB]
1414
brod[Broadway]
15-
FCTree[Fork choice store - Genserver]
15+
FCTree[Fork choice store - Genserver]
1616
BAPI -->|Beacon state queries| BS_db
17-
brod -->|Save blocks| blk_db
18-
brod -->|Blocks and attestations| FCTree
19-
TICK -->|New ticks| FCTree
17+
brod -->|Save blocks| blk_db
18+
brod -->|Blocks and attestations| FCTree
19+
TICK -->|New ticks| FCTree
2020
BAPI --> engine
21-
BAPI --> |head/slot requests| FCTree
22-
brod --> |Save new states|BS_db
21+
BAPI --> |head/slot requests| FCTree
22+
brod --> |Save new states|BS_db
2323
end
2424
GOS[Gossip Protocols]
2525
exec[Execution Client]
@@ -31,20 +31,20 @@ VALIDATOR --> BAPI
3131

3232
## Networking
3333

34-
The main entry for new events is the gossip protocol, which is the way in which our consensus node communicates with other consensus nodes. This includes:
34+
The main entry for new events is the gossip protocol, which is how our consensus node communicates with other consensus nodes. This includes:
3535

3636
1. Discovery: our node has a series of known `bootnodes` hardcoded. We request a list of the nodes they know about and add them to our list. We save them locally and now can use those too to request new nodes.
3737
2. Message propagation. When a proposer sends a new block, or validators attest for a new block, they send those to other known nodes. Those, in turn, propagate the messages sent to other nodes. This process is repeated until, ideally, the whole network receives the messages.
3838

39-
We use the `go-libp2p` library for the networking primitives, which is an implementation of the `libp2p`networking stack.
39+
We use the `go-libp2p` library for the networking primitives, which is an implementation of the `libp2p` networking stack.
4040

41-
We use ports to communicate with a go application and broadway to process notifications.
41+
We use ports to communicate with a go application and Broadway to process notifications.
4242

43-
**TO DO**: We need to document the ports architecture.
43+
**TO DO**: We need to document the port's architecture.
4444

4545
## Gossipsub
4646

47-
One of the main communication protocols is gossipsub. This allows us to tell peers which topics we're interested in and receive events for them. The main external events we react to are blocks and attestations.
47+
One of the main communication protocols is GossipSub. This allows us to tell peers which topics we're interested in and receive events for them. The main external events we react to are blocks and attestations.
4848

4949
### Receiving an attestation
5050

@@ -65,7 +65,7 @@ sequenceDiagram
6565

6666
When receiving an attestation, it's processed by the [on_attestation](https://eth2book.info/capella/annotated-spec/#on_attestation) callback. We just validate it and send it to the fork choice store to update its weights and target checkpoints. The attestation is only processed if this attestation is the latest message by that validator. If there's a newer one, it should be discarded.
6767

68-
The most relevant piece of the spec here is the [get_weight](https://eth2book.info/capella/annotated-spec/#get_weight) function, which is the core of the fork-choice algorithm. In the specs, this function is called on demand, when calling [get_head](https://eth2book.info/capella/annotated-spec/#get_head), works with the store's values and recalculates them each time. In our case, we cache the weights and the head root each time we add a block or attestation, so we don't need to do the same calculations again.
68+
The most relevant piece of the spec here is the [get_weight](https://eth2book.info/capella/annotated-spec/#get_weight) function, which is the core of the fork-choice algorithm. In the specs, this function is called on demand, when calling [get_head](https://eth2book.info/capella/annotated-spec/#get_head), works with the store's values, and recalculates them each time. In our case, we cache the weights and the head root each time we add a block or attestation, so we don't need to do the same calculations again.
6969

7070
**To do**: we should probably save the latest messages in persistent storage as well so that if the node crashes we can recover the tree weights.
7171

@@ -103,7 +103,7 @@ sequenceDiagram
103103
Receiving a block is more complex:
104104

105105
- The block itself needs to be stored.
106-
- The state transition needs to be applied, a new beacon state calculated and stored separately.
106+
- The state transition needs to be applied, a new beacon state calculated, and stored separately.
107107
- A new node needs to be added to the block tree aside from updating weights.
108108
- on_attestation needs to be called for each attestation.
109109

Diff for: docs/bindings_go.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The bindings are used to interact with the *go-libp2p* and *go-ethereum/p2p* lib
66
As we couldn't find a way to communicate the two languages directly, we used some **C** code to communicate the two sides.
77
However, as Go is a garbage-collected language, this brings some issues.
88

9-
<!-- TODO: add explanation about general bindings usage -->
9+
<!-- TODO: add an explanation about general bindings usage -->
1010
<!-- TODO: explain the callback -> message translation -->
1111

1212
## References and handles
@@ -57,7 +57,7 @@ func SumAndConsumeArray(arrayHandle C.uintptr_t) uint {
5757

5858
What we have until now allows us to create long-living references, but we still need to free them manually (otherwise we leak memory).
5959
To fix this, we can treat them as native objects with Erlang's [*Resource objects*](https://www.erlang.org/doc/man/erl_nif.html#functionality).
60-
By treating them as resources with an associated type and destructor, we can let Erlang's garbage-collector manage the reference's lifetime.
60+
By treating them as resources with an associated type and destructor, we can let Erlang's garbage collector manage the reference's lifetime.
6161
It works as follows:
6262

6363
<!-- TODO: add code examples -->

Diff for: docs/bitvectors.md

+13-13
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
## Representing integers
44

5-
Computers use transistors to store data. These electrical components only have two possible states: `clear` or `set`. Numerically, we represent the clear state as a `0` and and the set state as `1`. Using 1s and 0s, we can represent any integer number using the binary system, the same way we use the decimal system in our daily lives.
5+
Computers use transistors to store data. These electrical components only have two possible states: `clear` or `set`. Numerically, we represent the clear state as a `0` and the set state as `1`. Using 1s and 0s, we can represent any integer number using the binary system, the same way we use the decimal system in our daily lives.
66

7-
As an example, let's take the number 259. For its decimal representation, we use the digits 2, 5 and 9, because each digit, or coefficient, represents a power of 10:
7+
As an example, let's take the number 259. For its decimal representation, we use the digits 2, 5, and 9, because each digit, or coefficient, represents a power of 10:
88

99
$$ 259 = 200 + 50 + 9 = 2*10^2 + 5*10^1 + 9*10^0 $$
1010

11-
If we wanted to do the same the binary binary, we would use powers of two, and each individual symbol (or bit) can only be 0 or 1.
11+
If we wanted to do the same in the binary, we would use powers of two, and each symbol (or bit) can only be 0 or 1.
1212

1313
$$ 259 = 256 + 2 + 1 = 1*2^{8} + 1*2^{1} + 1*2^0 $$
1414

@@ -44,7 +44,7 @@ Representing it as a byte array, we get `bytes = [3, 1]`. The lowest index, `byt
4444

4545
### "Little-endian bit order"
4646

47-
Why would we need a third representation? Let's first pose the problem. Imagine we have a fixed amount of validators, equal to 9, and we want to represent whether they attested in a block or not. If the validators 0, 1 and 8 attested, we may represent this with a boolean array, as follows:
47+
Why would we need a third representation? Let's first pose the problem. Imagine we have a fixed amount of validators, equal to 9, and we want to represent whether they attested in a block or not. If the validators 0, 1, and 8 attested, we may represent this with a boolean array, as follows:
4848

4949
```
5050
[true, true, false, false, false, false, false, false, true]
@@ -76,13 +76,13 @@ If we want to convert from each order to each other:
7676

7777
- Little-endian byte order to big-endian: reverse the bytes.
7878
- Little-endian bit order to big-endian: reverse the bits of the whole number.
79-
- Little-endian bit order to little-endian byte order: reverse the bits of each individual byte. This is equivalent to reversing all bits (converting to big-endian) and then reversing the bytes (big-endian to little-endian byte order) but in a single step.
79+
- Little-endian bit order to little-endian byte order: reverse the bits of each byte. This is equivalent to reversing all bits (converting to big-endian) and then reversing the bytes (big-endian to little-endian byte order) but in a single step.
8080

8181
## Bit vectors
8282

8383
### Serialization (SSZ)
8484

85-
`bitvectors` are exactly that: a set of booleans with fixed size. SSZ represents bit vectors as follows:
85+
`bitvectors` are exactly that: a set of booleans with a fixed size. SSZ represents bit vectors as follows:
8686

8787
- Conceptually, a set is represented in little-endian bit ordering, padded with 0s at the end to get full bytes.
8888
- When serializing, we convert from little-endian bit ordering to little-endian byte ordering.
@@ -111,22 +111,22 @@ Moving it to little-endian byte order (we go byte by byte and reverse the bits):
111111
00000011 00000001
112112
```
113113

114-
This is how nodes send `bitvectors` over the network. We know that this array is of size 9 beforehand, so we know what bits are padding and should be ignored. For variable-sized bit arrays we'll use `bitlists`, which we'll talk about later.
114+
This is how nodes send `bitvectors` over the network. We know that this array is of size 9 beforehand, so we know what bits are padding and should be ignored. For variable-sized bit arrays, we'll use `bitlists`, which we'll talk about later.
115115

116116
### Internal representation
117117

118-
There's a trick here: SSZ doesn't specify how to store a `bitvector` in memory after deserializing. We could, theoretically, read the serialized data, transform it from little-endian byte order to little-endian bit order, and use bit addressing (which elixir supports) to get individual values. This would imply, however, going through each byte and reversing the bits, which is a costly operation. If we stuck with little-endian byte order without transforming it, addressing individual bits would be more complicated, and shifting (moving every bit to the left or right) would be tricky.
118+
There's a trick here: SSZ doesn't specify how to store a `bitvector` in memory after deserializing. We could, theoretically, read the serialized data, transform it from little-endian byte order to little-endian bit order, and use bit addressing (which Elixir supports) to get individual values. This would imply, however, going through each byte and reversing the bits, which is a costly operation. If we stuck with little-endian byte order without transforming it, addressing individual bits would be more complicated, and shifting (moving every bit to the left or right) would be tricky.
119119

120120
For this reason, we represent bitvectors in our node as big-endian binaries. That means that we reverse the bytes (a relatively cheap operation) and, for bit addressing, we just use the complementary index. An example:
121121

122-
If we are still representing the number 259 (validators with index 0, 1 and 8 attested) we'll have the two following representations (note, elixir has a `bitstring` type that lets you address bit by bit and store an amount of bits that's not a multiple of 8):
122+
If we are still representing the number 259 (validators with index 0, 1, and 8 attested) we'll have the two following representations (note, elixir has a `bitstring` type that lets you address bit by bit and store several bits that's not a multiple of 8):
123123

124124
```
125125
110000001 -> little-endian bit order
126126
100000011 -> big-endian
127127
```
128128

129-
If we watch closely, we confirm something we said before: these are bit-mirrored representations. That means that if I want to know if the validator i voted, in the little-endian bit order, we address `bitvector[i]`, and in the big-endian order, we just use `bitvector[N-i]`, where `N=9` as it's the size of the vector.
129+
If we watch closely, we confirm something we said before: these are bit-mirrored representations. That means that if I want to know if the validator I voted, in the little-endian bit order, we address `bitvector[i]`, and in the big-endian order, we just use `bitvector[N-i]`, where `N=9` as it's the size of the vector.
130130

131131
This is the code that performs this conversion:
132132

@@ -139,9 +139,9 @@ def new(bitstring, size) when is_bitstring(bitstring) do
139139
end
140140
```
141141

142-
It reads the input as a little-endian number, and then constructs a big-endian binary representation of it.
142+
It reads the input as a little-endian number and then constructs a big-endian binary representation of it.
143143

144-
Instead of using Elixir's bitstrings, a possible optimization (we'd need to benchmark it) would be to represent the array as the number 259 directly, and use bitwise operations to address bits or shift.
144+
Instead of using Elixir's bitstrings, a possible optimization (we'd need to benchmark it) would be to represent the array as the number 259 directly and use bitwise operations to address bits or shift.
145145

146146
## Bitlists
147147

@@ -177,7 +177,7 @@ When deserializing, we'll look closely at the last byte, realize that there are
177177

178178
### Edge case: already a multiple of 8
179179

180-
It might be the case that we already have a multiple of 8 as the number of booleans we're representing. For instance, let's suppose that we have 8 validators and only the first and the second one attested. In little-endian bit order, that is:
180+
It might be the case that we already have a multiple of 8 as the number of booleans we're representing. For instance, let's suppose that we have 8 validators and only the first and the second ones attested. In little-endian bit order, that is:
181181

182182
```
183183
11000000

0 commit comments

Comments
 (0)