Skip to content

Commit

Permalink
[doc] initial progress on dev docs. An overview, some outlines for qu…
Browse files Browse the repository at this point in the history
…ick start and key concepts sections, section on objects.
  • Loading branch information
sblackshear committed Feb 7, 2022
1 parent 6adfe25 commit 1c70d15
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 0 deletions.
58 changes: 58 additions & 0 deletions doc/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Sui Developer Portal

Welcome to Sui, a next generation smart contract platform with high throughput, low latency, and an asset-oriented programming model powered by Move! Here are some suggested starting points:
* To jump right into building smart contract applications on top of Sui, go to [Dev Quick Start](TODO)
* To experiment with a toy Sui wallet, check out [Wallet Quick Start](TODO)
* To understand what's possible by browsing examples of full-fledged applications and games built on top of Sui, have a look at [Demos](TODO)
* To go deep on how Sui works, start at [Key Concepts](TODO)
* To learn what distinguishes Sui from other blockchain systems, see [What Makes Sui Different?](TODO)
* To experience Sui's speed and scalability for yourself, try [Benchmarking](TODO)
* To see the current status of the Sui software/network and preview what's coming next, read through [Roadmap](TODO)

## Dev Quick Start
TODO: installation, defining custom objects, object operations (create/destroy/update/transfer/freeze), publishing, invoking your published code. Then deeper: Sui standard library, design patterns, examples.

## Wallet Quick Start
TODO: installation, querying the chain, client setup, getting test coins, sending transfer transactions, viewing the effects in a block explorer. Then deeper: wallet CLI vs client service vs forwarder architecture, how to integrate your code (wallet, indexer, ...) with the client service or forwarder components.

## Demos

## Key Concepts
- [Overview](overview.md)
- [Authorities](authorities.md)
- [Objects](objects.md)
- [Programmability](programmability.md)
- [Transactions](transactions.md)
- TODO: clients
- TODO: state sync
- TODO: reconfiguration
- TODO governance, incentives, and rewards

## What Makes Sui Different?

EDITORIAL COMMENT: I think this section should lead with high-level selling points, then go into some more nuanced technical comparisons with existing systems, then conclude with honest descriptions limitations + pointers into the roadmap items that show we're already thinking about addressing them

- High throughput and low latency (enables low cost w/ fixed hardware)
- Horizontal scalability
- Causal order vs total order (enables massively parallel execution)
- Move and object-centric data model (enables composable objects/NFT's)
TODO: more

EDITORIAL COMMENT: feel free to take a hatchet to what follows

### Authorities vs Validators/Miners
An authority plays a role similar to "validators" or "miners" in other blockchain systems. The key distinction between these roles (and the reason we insist on using a separate term) is that validators/miners are *active*, whereas authorities are *passive*. Broadly speaking:
* Miners/validators continuously participate in a global consensus protocol that requires multiple rounds of all-to-all communication between the participants. The goal is typically to agree on a *totally ordered* block of transactions and the result of their execution.
* Authorities do nothing until they recieve a transaction or certificate from a user. Upon receiving a transaction or certificate, an authority need not communicate with other authorities in order to take action and advance its internal state machine. It may wish to communicate with other authorities to share certificates, but need not do so.

## Causal Order vs Total Order
Unlike most existing blockchain systems (and as the reader may have guessed from the description of write requests above), Sui does not impose a total order on the transactions submitted by clients. Instead, transactions are *causally* ordered--if a transaction `T1` produces output objects `O1` that are used as input objects in a transaction `T2`, an authority must execute `T1` before it executes `T2`. Note that `T2` need not use these objects directly for a causal relationship to exist--e.g., `T1` might produce output objects which are then used by `T3`, and `T2` might use `T3`'s output objects. However, transactions with no causal relationship can be processed by Sui authorities in any order.

EDITORIAL NOTE: Feels like this last bit could/should be part of a different

## Benchmarking
TODO: installation, running throughput and latency benchmarks, demonstrating that throughput goes up when you add more cores, adding more authorities leads to linear-ish decrease of latency/throughput.

## Roadmap

TODO
41 changes: 41 additions & 0 deletions doc/authorities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Authorities

The Sui network is operated by a set of independent *authorities*, each running its own instance of the Sui software on a separate machine (or a [sharded](TODO) cluster of machines operated by the same entity). An authority participates in the network by handling [read](TODO) and write requests sent by [clients](TODO). This section focuses on the latter.

Sui uses proof of stake (PoS) to determine which authorities operate the network and their voting power. Authorities are incentivized to participate in good faith via a share of transaction fees, staking rewards, and slashing to punish misbehavior. See [Governance, Incentives, and Rewards](TODO) for more detail.

## Epochs
Operation of the Sui network is temporally partitioned into non-overlapping, fixed duration (e.g. 24 hours) *epochs*. During a particular epoch, the set of authorities participating in the network is fixed. At an epoch boundary, [reconfiguration](TODO) occurs and can change the set of authorities participating in the networ and their voting power. Conceptually, reconfiguration starts a new instance of the Sui protocol with the previous epoch's final state as genesis and the new set of authorities as the operators.

EDITORIAL NOTE: not sure if the fixed duration part matches our plans--let me know

## Committees
A *committee* is a set of authorities whose combined voting power is >2/3 of the total during a particular epoch. For example, in a Sui instance operated by four authorities that all have the same voting power, any group containing 3 authorities is a committee.

The committee size of >2/3 is chosen to ensure *Byzantine fault tolerance*. As we will see, an authority will only commit a transaction (i.e., durably store the transaction and update its internal state with the effects of the transaction) if it is accompanied by cryptographic signatures from a committee. We call the combination of the transaction and the committee signatures on its bytes a *certificate*. The policy of only committing certificates ensures Byzantine fault tolerance: if <2/3 of the authorities faithfully follow the protocol, they are guaranteed to eventually agree on both the set of committed certificates and their effects.

EDITORIAL NOTE: someone with BFT chops please correct/expand on this

## Write Requests
An authority can handle two types of write requests: transactions and certificates. At a high level, a client:
* communicates a transaction to a quorum of authorities to collect the signatures required to form a certificate
* submits a certificate to an authority to commit state changes on that authority.

EDITORIAL NOTE: A diagram would be useful here

### Transactions
When a authority receives a transaction from a client, it will first perform [transaction validity checks](TODO) (e.g., validity of the sender's signature). If the checks pass, the authority will sign the transaction bytes and return the signature to the client. The client repeats this process with multiple authorities until it has collected signatures on its transaction from a committee, thereby forming a certificate.

Note that the process of collecting authority signatures on a transaction into a certificate and the process of submitting certifcates can be performed in parallel. The client can simultaneously broadcast transactions/certificates to an arbitrary number of authorities. Alternatively, a client can outsource either or both of these tasks to a third-party service provider. This provider must be trusted for liveness (e.g., it can refuse to form a certificate), but not for safety (e.g., it cannot change the effects of the transaction).

### Certificates
Once the client forms a certificate, it submits the certificate to an authority, which will perform [certificate validity checks](TODO) (e.g., the signers are authorities in the current epoch and the signatures are cryptographically valid). If the checks pass, the auhority will execute the transaction inside the certificate. Execution of a transaction will either succeed and commit all of its effects to the ledger, or [abort]() (e.g., due to an explicit `abort` instruction, a runtime error like divison by zero, or exceeding the maximum gas budget) and have no effects other than debiting the transaction's gas input. In either case, the transaction will durably store the certificate indexed by the hash of its inner transaction.

As with transactions, we note that the process of sharing a certificate with authorities can be parallelized and (if desired) outsourced to a third-party service provider. A client should broadcast its certificate to >1/3 of the authorities to ensure that (up to BFT assumptions) at least one honest authority has executed and committed the certificate. Other authorities may learn about the certificate via [inter-authority state sync](TODO) or via [client-assisted state sync](TODO).

EDITORIAL NOTE: please check that my advice about how many authorities a client should broadcast certs to looks good

## Further Reading

* Transactions take objects as input and produced objects as output--check out the [objects](objects.md) section to learn more about the structure and attributes of objects.
* Sui supports several different transaction types--see the [transactions](transactions.md) section for full details.
43 changes: 43 additions & 0 deletions doc/objects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Objects

Sui has programmable objects created and managed by [Move](https://github.com/diem/move) packages (aka "smart contracts"). Move packages themselves are also objects. Thus, Sui objects can be partitioned into two categories:
* *Mutable data values*: typed data governed by a particular Move [*module*](https://github.com/diem/move/blob/main/language/documentation/book/src/modules-and-scripts.md). Each object value is a [struct](https://github.com/diem/move/blob/main/language/documentation/book/src/structs-and-resources.md) with fields that can contain primitive types (e.g. integers, addresses), other objects, and non-object structs. Each object value is mutable at the time of its creation, but can subsequently be *frozen* and become permanently immutable.
* *Immutable packages*: a set of Move bytecode modules with distinct name. A package can depend on other pacakge objects that were previously published to the Sui ledger.

## Object Metadata

All Sui objects have the following metadata:
* A 20 byte globally unique ID. An object ID is derived from the digest of the transaction that created the object and a counter encoding the number of ID's generated by the transaction.
* An 8 byte unsigned integer *version* representing the number of transactions that have included this object as an output. Thus, all objects freshly created by a transaction will have version 1.
* A 32 byte *transaction digest* indicating the last transaction that included this object as an output.
* An `is_mutable` flag indicating whether the object can be mutated, destroyed, or transferred in a transaction sent by its owner. Both immutable and immutable objects can be read. Once an object becomes immutable, it remains immutable forever.

In addition to common metadata, objects have a category-specific, variable sized *contents* field. For a data value, this contains the Move type of the object and its BCS-encoded payload. For a package value, this contains the bytecode modules in the package.

## Referring to Objects

There are a few different ways to concisely refer to an object without specifying its full contents and metadata, each with slightly different use-cases:
* ID: the globally unique ID of the object mentioned above. This is a stable identifier for the object across time, and is useful (e.g.) for querying the current state of an object or describing which object was transferred between two addresses.
* Versioned ID: an (ID, version) pair. This describes the state of the object at a particular point in the object's history, and is useful for (e.g.) asking what the value of the object was at some point in the past or determining how fresh some view of an object is.
* Object Reference: an (ID, object digest) pair. The object digest is the hash of the object's contents and metadata. An object reference provides an authenticated view of the object at a particular point in the object's history. Transactions require object inputs to be specified via object references to ensure that the transaction's sender and an authority processing the transaction agree on the contents and metadata of the object.

## The Transaction-Object DAG: Relating Objects and Transactions

Transactions (and thus, certificates) take objects as input, read/write/mutate these inputs, and produce mutated or freshly created objects as output. And as we discussed above, each object knows the (hash of the) last transaction that produced it as an output. Thus, a natural way to represent the relationship between objects and transactions is a DAG where:
* nodes are transactions
* directed edges connect transaction output objects to transaction input objects and are labeled with object references.

To construct this graph, we add a node for each committed transaction and draw a directed edge labeled with object reference `O` from transaction `A` to transaction `B if `A` produced object `O` (i.e., created or mutated `O`) and transaction `B` takes object `O` as an input.

The root of this DAG is a "genesis" transaction that takes no inputs and produces the objects that exist in the initial state of the system. The DAG can be extended by identifying mutable transaction outputs that have not yet been consumed by any committed transaction and sending a new transaction that takes these outputs (and optionally, immutable transaction outputs) as inputs.

The set of objects that are available to be taken as input by a transaction are the *live objects*, and the global state maintained by Sui consists of the totality of such objects. The live objects for a particular Sui address `A` are all objects owned by `A`, along with all immutable objects in the system.

When this DAG contains all committed transactions in the system, it forms a complete (and crytographically auditable) view of the system's state and history. In addition, we can use the scheme above to construct a DAG of the relevant history for a subset of transactions or objects (e.g., the objects owned by a single address).

EDITORIAL NOTE: A diagram would be useful here
EDITORIAL NOTE: Should we describe how to audit this here? In a separate section?

## Further Reading
* Objects are modified and created by transactions--read more about the [transaction types](transactions.md) supported by Sui
* Objects are stored by [authorities](authorities.md)
9 changes: 9 additions & 0 deletions doc/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Overview

FastX is a distributed ledger that stores a collection of programmable *objects*, each with a globally unique ID. Every object is owned by a single *address*, and each address can own an arbitrary number of objects.

The ledger is updated via a *transaction* sent by a particular address. A transaction can create, destroy, and write objects, as well as transfer them to other addresses.

Structurally, a transaction contains a set of input object ID's and a pointer to a Move code object that already exists in the ledger. Executing a transaction produces updates to the input objects and (if applicable) a set of freshly created objects along with their owners.

A transaction whose sender is address *A* can only accept objects owned by *A*, with one exception: a transaction can read from immutable objects regardless of their owner.
Loading

0 comments on commit 1c70d15

Please sign in to comment.