@@ -0,0 +1,425 @@
1++++
2+title = "Layer 2 Overview"
3+weight = 5
4+template = "doc.html"
5++++
6+
7+This document provides technical details on Azimuth's "Layer 2" scaling solution
8+for Azimuth, known more formally as "naive rollups". We focus here primarily on the
9+"Hoon smart contract" located at `/lib/naive.hoon` in your ship's pier, as well
10+as other proximal topics.
11+
12+This is intended for developers that desire a deeper understanding of how this
13+protocol works, how secure it is, and how to extract data from layer 2 to obtain
14+a complete picture of the Arvo network.
15+
16+This is not intended for everyday users who only wish to know how
17+to either transfer their ship to layer 2 or perform layer 2 actions. For that,
18+see ((bridge documentation yet to be written)). For a casual overview of the
19+rationale and functionality of layer 2, please see this [blog
20+post](/blog/rollups). For more information on how Azimuth works more generally,
21+including interactions with Bridge and Ethereum, see the page on [Azimuth data flow](/docs/azimuth/flow).
22+
23+This page is also not where to find instruction on how to run your own "aggregator"/"roller".
24+Documentation for this process is forthcoming. However, this page does contain
25+essential background information for anybody in this category.
26+
27+## Summary
28+
29+Naive rollups were developed in response to rising gas costs for performing
30+Azimuth actions. They also serve the dual purpose of making onboarding easier,
31+as it is now possible to acquire a planet and get on Urbit without any knowledge
32+of Ethereum or cryptocurrency.
33+
34+In this section we give a high-level summary of how naive rollups function and
35+how they affect the end user. Later sections elaborate on this summary.
36+
37+### Layer 1
38+
39+We briefly review how "Layer 1", i.e. the [Azimuth](/docs/glossary/azimuth) smart
40+contract suite, functions. An update to the Azimuth PKI data stored on your urbit
41+occurs with four steps:
42+
43+ 1. A transaction is posted to the Ethereum blockchain.
44+ 2. The [Ethereum Virtual Machine](https://ethereum.org/en/developers/docs/evm/)
45+ calculates the resulting state transition and checks its validity, then
46+ updates the state if it is a valid transition.
47+ 3. Your urbit downloads the new state from an Ethereum node.
48+ 4. Your urbit makes the final decision on whether the new state is valid.
49+
50+By default, step four always succeeds. It has always been possible in theory for
51+your urbit to dispute what it read on Ethereum, but there has never been any
52+reason to do so.
53+
54+### Layer 2 {#layer-2}
55+
56+Layer 1 still functions identically today as it did before naive rollups. Naive
57+rollups work via the following process.
58+
59+ 1. A batch of one or more transactions is posted to the Ethereum blockchain by
60+ an urbit node called a roller or aggregator.
61+ 2. Your urbit downloads the transactions from an Ethereum node.
62+ 3. Your urbit computes the resulting state transitions from the transactions
63+ and checks them for validity.
64+ 4. Your urbit updates its locally stored Azimuth state using state transitions
65+ from the batch that have been deemed valid.
66+
67+ In comparison with Layer 1, the EVM no longer checks the validity or computes
68+ the state transitions for any given transaction. It is now being used solely as
69+ a database of submitted transactions, and the business logic of computing what
70+ these transactions mean has been offloaded to your urbit. Thus we think of
71+ `naive.hoon` as being the first "Hoon smart contract". You could also consider
72+steps 3 and 4 of the Layer 2 process as being a fattening of the trivial step 4
73+ of the layer 1 process.
74+
75+Here we briefly elaborate on the layer 2 steps, but see below for more technical
76+detail.
77+
78+A roller is any urbit node - even a moon, comet, or fakezod will do - to which
79+batches of transactions are submitted. You could use your own ship as a roller
80+if you wanted. The roller collects batches of transactions from whichever
81+parties they choose and submits them to the Ethereum blockchain all at once.
82+We expect this to either happen on a regular interval, or once some minimum
83+threshold of transactions is reached, but the decision on when to submit is
84+ultimately up to the roller.
85+
86+Computing the resulting state transitions obtained from downloaded Ethereum
87+transactions is done using `/lib/naive.hoon`, which is a gate that accepts both layer
88+1 transaction logs and layer 2 batches, and then computes the resulting state
89+transitions and updates the ship's internal Azimuth data held in
90+the Gall agent `/app/azimuth.hoon` accordingly.
91+
92+### Savings in gas costs
93+
94+There are several dimensions by which naive rollups saves on gas over layer 1.
95+They are:
96+
97+ 1. Gas is not spent on instructing the EVM to compute state transitions and
98+ confirm validity.
99+ 2. Layer 2 Azimuth state is not stored on Ethereum, so the only data storage
100+ gas costs is for the transactions themselves.
101+ 3. Layer 2 transactions are written in a highly compressed form. E.g., instead
102+ of calling the spawn action by name, it is simply referred to as action `%1`.
103+ 4. By collecting multiple layer 2 transactions and submitting them as a single
104+ "batch transaction", additional gas savings are achieved by not needing to
105+ duplicate information such as which smart contract the transactions are
106+ intended for.
107+
108+Put together, these create a reduction in gas costs of at least 65x when adding
109+a transaction to a sufficiently large batch (approximately 30 or more
110+transactions). A single transaction submitted as a batch is approximately 5x
111+cheaper, while 10 transaction submitted as a batch is approximately 30x cheaper.
112+Thus using one's own ship to submit a single-transaction batch is still a
113+cost-saving measure.
114+
115+### One way trip
116+
117+Moving to layer 2 is a one-way trip for now. This means that once a ship moves
118+to layer 2, it cannot be moved back to layer 1. We believe it to be technically
119+possible to engineer a return trip, and expect that someday this will be the
120+case, but there are no plans to implement this in the near future.
121+
122+## Interacting with L2
123+
124+Layer 2 ships can perform the same actions on layer 2 that they could on
125+layer 1, but are no longer able to perform any layer 1 actions. Layer 1 ships
126+can also perform a subset of layer 2 actions - namely the ones related to
127+sponsorship.
128+
129+For a complete list of what layer 2 actions each ship rank, layer, and proxy can
130+perform, see [Layer 2 Actions](/docs/azimuth/l2/l2-actions). For an explicit
131+description of the byte format of Layer 2 Ethereum transaction, see [Bytestring format](/docs/azimuth/l2/bytestring).
132+
133+### Sponsorship {#sponsorship}
134+
135+Due to the possibility of sponsors and sponsees existing on different layers,
136+the precise logic of how sponsorship works is complex. However, under common
137+circumstances it is simple.
138+
139+If either the sponsor or sponsee are on layer 2, then sponsorship actions must
140+occur on layer 2. The only exception to this is detaching. A sponsor on layer 1
141+may perform a layer 1 detach action on a layer 2 sponsee, and this will result
142+in the sponsee having no sponsor on layer 1, and layer 2 as well if they were
143+the sponsor on layer 2. This is necessary to simplify the logic, but it also
144+guarantees that there is no hard requirement to ever utilize layer 2. Without
145+this exception, sponsors with sponsees that move to layer 2 would be forced to
146+detach them as a layer 2 action if they wanted to cease sponsorship. This would
147+also have an unacceptable impact on ships owned by [smart contracts](#smart-contracts).
148+
149+If both sponsor and sponsee are on layer 1 then sponsorship actions may occur on
150+either layer. As long as all sponsorship actions betweeen the two parties occur
151+on a single layer, behavior will be as expected.
152+
153+In most cases this is sufficient to understand how sponsorship works. However
154+there are a number of edge cases that make this more complicated that developers
155+may need to concern themselves with in scenarios where layer 1 sponsor and
156+sponsees are mixing layer 1 and layer 2 actions. In the [Sponsorship state
157+transitions](#sponsorship-state-transitions) section below, we give a table that
158+shows how the sponsor and escape status of a ship changes according to which
159+actions are taken.
160+
161+### Smart contracts {#smart-contracts}
162+
163+Smart contracts are unable to own layer 2 ships, and thus cannot sign layer 2
164+transactions. This creates a hard requirement that layer 1 ships be allowed to
165+perform a layer 1 detach operation on a layer 2 ships.
166+
167+## Azimuth state {#state}
168+
169+The introduction of layer 2 presents additional complication in understanding
170+Azimuth state. In order to be precise we define the following terminology:
171+
172+ - _Layer 1 Azimuth state_ refers to the state of Azimuth as reflected on the
173+ Ethereum blockchain. This excludes all layer 2 transactions. Depositing to
174+ layer 2 is considered a layer 1 action, so the layer 1 Azimuth state is aware
175+ of which ships are on layer 2, but is blind to everything that happens to
176+ them afterward.
177+ - _Layer 2 Azimuth state_ refers to the state of Azimuth as stored in
178+ `/app/azimuth.hoon` on your ship. The state here takes into account
179+ transactions that occur on both layers. No distinction between the
180+ layers is made in the state here - e.g. a ship only has one sponsor in Layer 2
181+ Azimuth state, not a layer 1 sponsor and a layer 2 sponsor. This is the state
182+ actually in use by Urbit. Layer 1 Azimuth state is now only an input for
183+ generating Layer 2 Azimuth state, so any time a ship needs to check e.g. the
184+ public key of a ship (regardless of which layer it is on), it will check the
185+ Layer 2 Azimuth state, not the Layer 1 Azimuth state.
186+ - _Layer-2-Only Azimuth state_ refers to the state of Azimuth as reflected
187+ solely by layer 2 transactions. This state is not explicitly stored anywhere,
188+ but is computed as part of the process to create the Layer 2 Azimuth state.
189+ We do not make any further references to this state, but it is important to
190+ keep in mind conceptually.
191+
192+Layer 1 Azimuth state is computed by the Ethereum Virtual Machine. Layer 2
193+Azimuth state is computed by taking in the Layer 1 Azimuth state and modifying
194+it according to layer 2 transactions using `/lib/naive.hoon`. When we are being
195+precise about which state we are referring to we will utilize capitalization as above.
196+
197+Layer 2 Azimuth state is held by the Azimuth Gall app located at
198+`/lib/azimuth.hoon`. Layer 1 and layer 2 state are not held separately - your
199+ship holds only one canonical Azimuth state, generated by parsing both layer 1
200+and layer 2 Ethereum transactions using `/lib/naive.hoon`. It is important to
201+keep in mind that Layer 1 Azimuth state is entirely unaware of Layer 2 Azimuth
202+state. Thus, for instance, the Azimuth PKI on Ethereum (Layer 1 Azimuth state)
203+may claim that the sponsor of `~sampel-palnet` is `~marzod`, while the Azimuth
204+state held on your ship (Layer 2 Azimuth state) claims that the sponsor of
205+`~sampel-palnet` is `~dopzod`. Under this circumstance, this would mean that the
206+sponsor of `~sampel-palnet` was `~marzod` before `~sampel-palnet` was deposited
207+to layer 2, and thus the Azimuth PKI on Ethereum will forever reflect this.
208+
209+For more information on how Azimuth state is handled, including how this
210+integrates with Bridge and Ethereum, see [Azimuth data flow](/docs/azimuth/flow).
211+
212+### Sponsorship state transitions
213+
214+When either a sponsor or sponsee is on layer 2, then all sponsorship actions
215+occur on layer 2 and layer 1 Azimuth state is ignored. The exception to this, as
216+noted [above](#sponsorship), is when a layer 1 sponsor performs a layer 1 detach
217+action on a layer 2 sponsee. Furthermore, any time a ship moves from layer 1 to
218+layer 2, its sponsorship status is automatically maintained in layer 2.
219+
220+The only potentially complicated scenario is when both sponsee and (potential)
221+sponsor exist on layer 1. Then because layer 1 actions can modify layer 2 state,
222+careful consideration is required for interactions that mix the two. If you
223+and your sponsor/sponsee are not mixing layer 1 and layer 2 sponsorship actions
224+between yourselves, then you have nothing to worry about and may safely ignore this
225+section.
226+
227+But, for instance, if both `~sampel-palnet` and `~dopzod` are on layer 1, it is
228+technically possible for `~sampel-palnet` to escape to `~dopzod` on layer 1, and
229+then `~dopzod` can accept the escape on layer 2. This will result in `~dopzod`
230+appearing as the sponsor in the Layer 2 Azimuth state (and thus be
231+`~sampel-palnet`'s "true" sponsor), and the sponsor in the Layer 1 Azimuth state
232+will remain unchanged. While it is difficult to imagine a good reason to do
233+this, developers working with layer 2 need to keep in mind these edge cases and
234+ought to read on.
235+
236+In the following table, columns `E_1` and `S_1` represent the escape status and
237+sponsor of a given ship as reflected by the Layer 1 Azimuth state. Columns `E_2`
238+and `S_2` represent the escape status and sponsor of a given ship as reflected
239+in the Layer 2 Azimuth State. The "true" escape status and sponsor of a ship is
240+always what is listed in the Layer 2 Azimuth state. In other words, at the end
241+of the day, `S_2` is always the sponsor that matters, but layer 1 actions can
242+affect the values of `E_2` and `S_2`.
243+
244+A tar `*` entry represents any value and if an event shows a transition
245+from `*` to `*` that means that value is not altered by the transition. The
246+transitions marked with `!!` are prohibited by the layer 1 Azimuth smart
247+contract and thus never occur. `A1` and `A2` represent two distinct ships.
248+
249+```
250+Event | E_1 | E_2 | S_1 | S_2 | -> | E_1 | E_2 | S_1 | S_2
251+L1-escape A1 | * | * | * | * | -> | A1 | A1 | * | *
252+L1-cancel A1 | ~ | * | * | * | -> !! :: no cancel if not escaping
253+L1-cancel A1 | A1 | * | * | * | -> | ~ | ~ | * | *
254+L1-adopt A1 | A1 | * | * | * | -> | ~ | ~ | A1 | A2
255+L1-adopt A1 | ~ | * | * | * | -> !! :: no adopt if not escaping
256+L1-adopt A1 | A2 | * | * | * | -> !! :: no adopt if not escaping
257+L1-detach A1 | * | * | A1 | A1 | -> | * | * | ~ | ~
258+L1-detach A1 | * | * | A1 | A2 | -> | * | * | ~ | A2
259+L1-detach A1 | * | * | A1 | ~ | -> | * | * | ~ | ~
260+L2-escape A1 | * | * | * | * | -> | * | A1 | * | *
261+L2-cancel A1 | * | * | * | * | -> | * | ~ | * | *
262+L2-adopt A1 | * | A1 | * | * | -> | * | ~ | * | A1
263+L2-adopt A1 | * | A2 | * | * | -> | * | A2 | * | *
264+L2-adopt A1 | * | ~ | * | * | -> | * | ~ | * | *
265+L2-reject A1 | * | A1 | * | * | -> | * | ~ | * | *
266+L2-reject A1 | * | A2 | * | * | -> | * | A2 | * | *
267+L2-reject A1 | * | ~ | * | * | -> | * | ~ | * | *
268+L2-detach A1 | * | * | * | A1 | -> | * | * | * | ~
269+L2-detach A1 | * | * | * | A2 | -> | * | * | * | A2
270+L2-detach A1 | * | * | * | ~ | -> | * | * | * | ~
271+```
272+
273+| **Event** | **E_1** | **E_2** | **S_1** | **S_2** | **->** | **E_1** | **E_2** | **S_1** | **S_2** |
274+|--------------|---------|---------|---------|---------|--------|---------|---------|---------|---------|
275+| L1-escape A1 | * | * | * | * | -> | A1 | A1 | * | * |
276+| L1-cancel A1 | ~ | * | * | * | -> | !! | !! | !! | !! |
277+| L1-cancel A1 | A1 | * | * | * | -> | ~ | ~ | * | * |
278+| L1-adopt A1 | A1 | * | * | * | -> | ~ | ~ | A1 | A2 |
279+| L1-adopt A1 | ~ | * | * | * | -> | !! | !! | !! | !! |
280+| L1-adopt A1 | A2 | * | * | * | -> | !! | !! | !! | !! |
281+| L1-detach A1 | * | * | A1 | A1 | -> | * | * | ~ | ~ |
282+| L1-detach A1 | * | * | A1 | A2 | -> | * | * | ~ | A2 |
283+| L1-detach A1 | * | * | A1 | ~ | -> | * | * | ~ | ~ |
284+| L2-escape A1 | * | * | * | * | -> | * | A1 | * | * |
285+| L2-cancel A1 | * | * | * | * | -> | * | ~ | * | * |
286+| L2-adopt A1 | * | A1 | * | * | -> | * | ~ | * | A1 |
287+| L2-adopt A1 | * | A2 | * | * | -> | * | A2 | * | * |
288+| L2-adopt A1 | * | ~ | * | * | -> | * | ~ | * | * |
289+| L2-reject A1 | * | A1 | * | * | -> | * | ~ | * | * |
290+| L2-reject A1 | * | A2 | * | * | -> | * | A2 | * | * |
291+| L2-reject A1 | * | ~ | * | * | -> | * | ~ | * | * |
292+| L2-detach A1 | * | * | * | A1 | -> | * | * | * | ~ |
293+| L2-detach A1 | * | * | * | A2 | -> | * | * | * | A2 |
294+| L2-detach A1 | * | * | * | ~ | -> | * | * | * | ~ |
295+
296+## Aggregators
297+
298+An "aggregator" or "roller" is any Urbit node that collects signed layer 2
299+transactions (typically via `/app/azimuth-rpc.hoon`), combines them into a
300+"batch", and then submits the batch as an Ethereum transaction. Any urbit can be
301+a roller, including moons, comets, and even fakezods. You can also use your own
302+ship as a roller.
303+
304+Tlon has set up our own roller that is free to use by the community. Using
305+Bridge, a ship may submit X transactions to Tlon's roller per Y period free of
306+charge. Tlon's roller submits on a regular schedule: a submission occurs when a
307+total of A layer 2 transactions have been submitted to it since the the previous
308+submitted Ethereum transaction, or every Z time, whichever occurs first.
309+
310+There are no security risks in utilizing an aggregator. The transactions you
311+submit to it are signed with your private key, and so if an aggregator alters
312+them the signature will no longer match and `naive.hoon` will reject it as an
313+invalid transaction. The worst an aggregator can do is not submit your transaction.
314+
315+## Multi-keyfiles
316+
317+As part of the layer 2 upgrade, Tlon has expanded the role of
318+[keyfiles](/docs/glossary/keyfile). One of our goals with layer 2 was to reduce
319+the amount of friction experienced when getting onto Urbit. The enormous
320+reduction in fees has made a new boot method which allows instantaneous sale of
321+layer 2 planets or stars to be cost effective.
322+
323+The ideal situation would be for the end user to be able to buy or receive a
324+planet and immediately boot it without having to wait for an aggregator to
325+submit a transaction that spawns the planet. In order to bring about this
326+circumstance, "multi-keyfiles" have been introduced.
327+
328+Multi-keyfiles are keyfiles used to boot an urbit for first time that contains
329+more than one set of keys, the purpose of which is to initially utilize one set
330+of keys on a temporary basis, and then the other set of keys soon after. This
331+works as follows. A star owner prespawns a number of layer 2 planets ready to be
332+sold at any time for which they posess the initial key. When a user acquires a
333+planet from a star owner, the star owner immediately hands the initial keys to
334+boot the planet to the buyer. The buyer then queues a transaction at a roller to
335+rotate the keys to a new value only known by the buyer (this step is performed
336+automatically by Bridge). The buyer then downloads a keyfile from Bridge
337+containing both keys and uses that to boot their planet for the first time.
338+After the transaction setting the new keys is submitted by the roller to
339+Ethereum, the purchased planet will automatically switch to them once it reads
340+the corresponding transaction from Ethereum.
341+
342+This process introduces a short period of time in which both the buyer and
343+seller are in possession of the keys of a planet. A malicious seller could
344+theoretically sell a planet to more than one party in this time period. However,
345+they would quickly be found out as two identical ships on the network
346+immediately creates problems, and the seller's reputation would be tarnished.
347+Due to the expense or effort needed to acquire a star, this seems an unlikely
348+scenario as the reward is much less than the cost. Nonetheless, buyers should
349+always make an effort to purchase from a reputable star, as is the case with all
350+transactions in life. If you want to be absolutely sure that you've received the
351+planet, just wait for the batch to be sent and confirmed.
352+
353+Multi-keyfiles were possible before layer 2, but as the cost of configuring keys
354+was comparable to the cost of buying a planet, they were not practical.
355+
356+## Security measures
357+
358+In the process of designing naive rollups, we felt it to be of the utmost
359+importance that there not be any loss in the security of a layer 2 ship over a
360+layer 1 ship. In this section we outline several relevant facets of Urbit as
361+well as particular measures that were taken to ensure that naive rollups were
362+free of bugs and exploits. We think of `naive.hoon` as being the first "Hoon
363+smart contract", and thus its functionality needs to be as rock-solid and
364+guaranteed as the Azimuth Ethereum smart contracts.
365+
366+### Arvo is deterministic
367+
368+Crucial to the functionality of Ethereum smart contracts is that they work the
369+same way every time since the Ethereum Virtual Machine is deterministic.
370+Similarly, as the state of Arvo is evolved via [a single pure
371+function](/docs/arvo/overview#an-operating-function), Arvo is deterministic as
372+well. This property makes it well-suited for cases where side effects are
373+unacceptable such as smart contracts, and thus `naive.hoon` is worthy of the
374+name "Hoon smart contract".
375+
376+### Restricted standard library
377+
378+A standard security practice is to reduce the surface area of attack to be as
379+minimal as possible. One common source of exploits among all programming
380+languages are issues with the standard library of functions, and this is one factor
381+that leads to the existence of multiple implementations of standard library functions for
382+a given programming language. For instance, `glibc` is the most widely used
383+standard library for the C programming language, but sheer size gives a large
384+surface area in which to find exploits. Thus, other standard libraries have been
385+written such as `musl` that are much smaller, and some argue to be more secure
386+at least partially due to fewer lines of code. Hoon is not yet popular enough to have
387+multiple standard library implementations, but `naive.hoon` shucks the usual
388+standard library and so its subject contains only the exact standard library
389+functions needed for it to function. This library is known as `tiny` and is
390+found at `/lib/tiny.hoon`.
391+
392+### Unit tests
393+
394+`naive.hoon` is among the most well-tested software in Urbit. The test suite,
395+which may be run with `-test %/lib/tests/naive ~` from dojo, is larger than any
396+other test suite both in number of lines of code and number of tests. We believe
397+branch coverage to be at or very close to 100%
398+
399+### Nonces
400+
401+In the Layer 2 Azimuth state, each proxy belonging to a given ship (including
402+the ownership "proxy") has a non-negative integer associated to it called a
403+"nonce". Each transaction submitted by a given proxy also have a nonce value. If
404+the current nonce of a proxy in the Layer 2 Azimuth state is `n`, then only a
405+transaction from that proxy with a nonce of `n+1` will be considered valid.
406+Otherwise the transaction is discarded. A valid transaction, by which we
407+mean one in which the nonce and signature are correct, will increment the nonce
408+of the proxy in the Layer 2 Azimuth state by one once processed by `naive.hoon`.
409+Note that "valid transactions" also include ones where the action will fail,
410+such as a planet attempting to `%spawn` another planet. For the purposes of
411+incrementing the nonce, only the nonce and signature matter.
412+
413+The use of nonces prevents "replay attacks", which is when a malicious party collects
414+valid transactions and attempts to resubmit them in order to perform the action
415+again. Since a valid transaction increments the nonce associated to the proxy
416+that submitted it, it is only ever possible for a given transaction to alter the
417+Layer 2 Azimuth state once.
418+
419+The use of nonces also eliminates potential issues caused by submitting a
420+transaction to more than one roller. This might happen if the first roller
421+submitted to is taking too long for your liking, and you want to try again with
422+another. If both rollers end up submitting the transaction, only the first one
423+will succeed, as the second one will be ignored by `naive.hoon` for having the
424+wrong nonce.
425+