Skip to content

Commit

Permalink
Merge pull request #345 from anoma/cwgoes/specs-work
Browse files Browse the repository at this point in the history
Specs updates
  • Loading branch information
cwgoes authored May 21, 2024
2 parents b0043bb + fcfaf6a commit 55b9473
Show file tree
Hide file tree
Showing 28 changed files with 286 additions and 45 deletions.
1 change: 1 addition & 0 deletions packages/specs/pages/_meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"index": "Introduction",
"base-ledger": "Base ledger",
"components": "Components",
"modules": "Modules",
"further-reading": "Further reading"
}
3 changes: 2 additions & 1 deletion packages/specs/pages/base-ledger.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ The base ledger of Namada includes:
- a validity-predicate-based [execution model](./base-ledger/execution.mdx) where a "valid state" is defined as that which satisfies a set of boolean conditions;
- a [replay protection system](./base-ledger/replay-protection.mdx) which prevents transactions from being executed multiple times;
- a [block space allocator](./base-ledger/block-space-allocator.mdx) which packs transactions into blocks; and
- a [fee system](./base-ledger/fee-system.mdx) which provides for efficient, DoS-resistant allocation of computational and storage resources within blocks
- a [fee system](./base-ledger/fee-system.mdx) which provides for efficient, DoS-resistant allocation of computational and storage resources within blocks
- a [state system](./base-ledger/state.mdx) which provides for encoding and Merkleization of the state machine state
5 changes: 3 additions & 2 deletions packages/specs/pages/base-ledger/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"execution": "Execution model",
"replay-protection": "Replay protection",
"block-space-allocator": "Block space allocator",
"fee-system": "Fee system"
}
"fee-system": "Fee system",
"state": "State"
}
5 changes: 5 additions & 0 deletions packages/specs/pages/base-ledger/state.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# State

- explain basic interface of state abstraction
- explain Merkleization
- explain lazy storage structures
9 changes: 9 additions & 0 deletions packages/specs/pages/components.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Components

Shared components of Namada include:
- [Address](./components/address.mdx)
- [Decimal](./components/decimal.mdx)
- [Event](./components/event.mdx)
- [Key](./components/key.mdx)
- [PD controller](./components/pd-controller.mdx)
- [Uint](./components/uint.mdx)
3 changes: 3 additions & 0 deletions packages/specs/pages/components/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"pd-controller": "PD controller"
}
Empty file.
Empty file.
Empty file.
Empty file.
1 change: 1 addition & 0 deletions packages/specs/pages/components/pd-controller.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# PD controller
Empty file.
11 changes: 2 additions & 9 deletions packages/specs/pages/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,6 @@ Namada also supports shielded actions, which allow users to hold their assets sh

You can find an introduction to Namada from a product perspective [here](https://namada.net/blog/introducing-namada-multichain-asset-agnostic-data-protection).

### What is Anoma?

Anoma is an intent-centric architecture for decentralized counterparty discovery, solving, and settlement. You can find the Anoma specs [here](https://specs.anoma.net).

### How does Namada relate to Anoma?

Anoma is a full-stack architecture designed with a long term perspective, while Namada is a specific chain and featureset designed to provide practical data protection now.

### Why Namada?

Data protection should be default and inherent in the systems we use for transacting, yet safe and user-friendly multi-asset data protection doesn't yet exist in the blockchain ecosystem.
Expand All @@ -41,8 +33,9 @@ Users of Namada earn rewards for shielding assets and contributing to shared dat
These documents describe the behavior of the Namada protocol. This description is organized into five sub-sections:

1. [Base Ledger](./base-ledger.mdx): This section describes the core ledger functionality of the Namada protocol. This includes the consensus, execution model, fee system, and environment in which modules operate.
2. [Components](./components.md): This section describes components (specific abstractions) shared by multiple Namada modules. This includes the PD controller.
2. [Modules](./modules.mdx): This section describes the modules that make up the Namada protocol. Each module is a distinct part of the protocol grouping a related set of features that can be understood in isolation from other modules.

This book is written using [NextraJS](https://nextra.site/). The source can be found in the [Namada Docs repository](https://github.com/anoma/namada-docs/tree/master/packages/specs).

Contributions to the contents and the structure of this book should be made via [pull requests](https://github.com/anoma/namada-docs/pulls).
Contributions to the contents and the structure of this book should be made via [pull requests](https://github.com/anoma/namada-docs/pulls).
30 changes: 30 additions & 0 deletions packages/specs/pages/modules/ethereum-bridge/design-rationale.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Callout } from 'nextra-theme-docs'

## Design

The Namada Ethereum bridge system consists of:

* A set of Ethereum smart contracts.
* An Ethereum full node run by each Namada validator, to watch Ethereum events emitted by the bridge's smart contracts.
* A set of validity predicates (VPs) on Namada.
+ A Bridge pool VP, to validate transfers to Ethereum and escrowed NAM.
+ An Ethereum bridge VP, to protect writes to Namada storage key sub-spaces containing Ethereum event tallies.
* Two relayer utilities, to call the Ethereum smart contracts.
+ One for performing validator set updates on the Ethereum smart contracts.
+ Another to aid in submitting batches of transactions to Ethereum.

This basic bridge architecture should provide for almost-Namada consensus
security for the bridge and free Ethereum state reads on Namada, plus
bidirectional message passing with reasonably low gas costs on the
Ethereum side.

### Security

On Namada, the validators are full nodes of Ethereum and their stake is also
accounting for security of the bridge. If they carry out a forking attack
on Namada to steal locked tokens of Ethereum their stake will be slashed on Namada.
On the Ethereum side, there exists a limit to the amount of assets that can be
locked to limit the damage a forking attack on Namada can do. To make an attack
more cumbersome there also exists a limit on how fast wrapped Ethereum assets can
be redeemed from Namada. This does not add more security, but rather makes the
attack more inconvenient, and allows governance time to react.
5 changes: 5 additions & 0 deletions packages/specs/pages/modules/ethereum-bridge/vp-logic.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Callout } from 'nextra-theme-docs'

## VP logic

Placeholder
20 changes: 20 additions & 0 deletions packages/specs/pages/modules/governance/design-rationale.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Callout } from 'nextra-theme-docs'

## Design Rationale

There are two ways to propose a change to the Namada protocol:

1. **On-chain** - A proposal is submitted to the Namada blockchain, and the Namada blockchain handles the voting process.
2. **Off-chain** - A proposal is submitted to a focal point outside of the Namada blockchain, and the voting process occurs off-chain.

## Public Goods Funding

A special type of on-chain proposal is the public goods funding proposal. It is described in more detail under the [Public Goods Funding](./design/public-goods-funding.mdx) section.

## Spam resistance

Namada governance implements a spam resistance mechanism to prevent the network from being spammed with proposals.
This mechanism is based on the fact that a proposal must be submitted with a deposit of `NAM` tokens.
This deposit is returned to the proposer if the proposal is accepted, and burned otherwise.
This is only possible if the proposal is submitted on-chain, as off-chain proposals are not able to submit a deposit.

30 changes: 30 additions & 0 deletions packages/specs/pages/modules/governance/storage-layout.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Callout } from 'nextra-theme-docs'

## Storage keys

### On-chain `Proposals`



### Offline proposals

Offline proposals are represented as JSON objects with the following structure:

```
{
content: Base64<Vec<u8>>,
author: Address,
tallyEpoch: Epoch,
signature: Base64<Vec<u8>>
}
```

The signature is produced over the hash of the concatenation of: `content`, `author`, and `tallyEpoch`.
Proposal types are not supported off-chain.

#### Proposal fields

- `content`: The proposal content (encoded). This is the actual proposal that will be voted on.
- `author`: The address of the proposal author.
- `tallyEpoch`: The epoch in which the proposal will be tallied. This epoch must already exist when tallying occurs. If the chain is halted, this means choosing an epoch in the past (e.g. the most recent epoch).
- `signature`: The signature of the proposal author over the hash of the concatenation of: `content`, `author`, and `tallyEpoch`
114 changes: 114 additions & 0 deletions packages/specs/pages/modules/governance/vp-logic.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { Callout } from 'nextra-theme-docs'

## VP logic

## Governance Address

All on-chain governance mechanisms are handled under a single address, referred to as the `GovernanceAddress`.
The `GovernanceAddress` is created during genesis, and handles the verification of submitted proposals, the tallying of votes, and the execution of proposals.
This address also stores all previous proposals under its address space.

Proposals are submitted through the client, and are verified by the `GovernanceAddress` before being added to the pending proposals list.

The structure of proposals is outlined [here](./proposal.mdx).


The correct logic to handle these different types is hardcoded in protocol.
We'll also rely on type checking to strictly enforce the correctness of a proposal given its type.
These two approaches combined will prevent a user from deviating from the intended logic for a certain proposal type (e.g. providing a wasm code when it's not needed or allowing only validators to vote when also delegators should, etc...).
More details on the specific types supported can be found in the [relative](#supported-proposal-types) section of the [proposals page](./proposal.mdx).


### GovernanceAddress VP

The `GovernanceAddress` validity predicate (VP) task is to check the integrity and correctness of new proposals.

#### Submission validation
A proposal must satisfy the following mandatory storage writes:

- `counter` - The number of proposals submitted so far
- `author` - The address of the author of the proposal
- `type` - The [proposal type](./proposal.mdx#supported-proposal-types)
- `funds` - The amount of funds locked for this proposal
- `voting_start` - The epoch specifying when the voting period starts
- `voting_end`- The epoch specifying when the voting period ends
- `grace_epoch` - The epoch specifying when the proposal becomes active, (and attached WASM code is executed if any), given that the proposal has a positive outcome.

Further, it must check that the proposal satisfies the following constraints:
- The attached `funds` is >= `min_proposal_fund`, a protocol parameter
- The `id` of the proposal is unique
- The attached `ProposalType` is supported by the protocol
- The difference between StartEpoch and EndEpoch is >= `min_proposal_period`
- There is an attached `description` of the proposal with character length < `max_proposal_content_size`
- The difference between the `voting_end` and `voting_start` epoch must be divisible by 3, i.e `(EndEpoch - StartEpoch) % 3 == 0`.
- The difference between `grace_epoch` and `voting_end` is of at least `min_proposal_grace_epochs`, a protocol parameter.
The reason for this constraint is explained below.

#### Voting validation

Once a proposal has been accepted by the protocol as valid, it will be added to the pending proposals list, and delegators and delegates will be able to vote on it.
The VP must also check that voting adheres to the following constraints:

- The voter is a delegator or a delegate (further constraints can be applied depending on the proposal type)
- Given that non-validating accounts can vote, validators may only vote during the initial $\frac{2}{3}$ of the whole proposal duration (`voting_end` - `voting_start`)

Once a proposal has been created, nobody can modify any of its fields.

#### Execution of WASM code

The VP is also responsible for handling the execution of WASM code attached to a `DefaultProposal` proposal type.

Examples of such code execution could be:
- storage writes to change some protocol parameter
- storage writes to restore a slash

This means that corresponding VPs will also be invoked.


## Tallying votes

Proposals are tallied at the start of their `grace_epoch` during the `finalize_block` function.
The tallying is based off of the votes collected at the end of the `voting_end` epoch.
If the threshold specified by the ProposalType is reached, the proposal will be considered successful.

There are two types of thresholds:
- Fraction of total staked `NAM` that voted - This checks whether enough staked `NAM` voted for the proposal at all.
- Fraction of votes in favor of the proposal - This checks whether enough votes (weighted by their staked `NAM`) voted in favor of the proposal, out of the staked `NAM` that did vote.

E.g if the thresholds, respectively, are $\frac{1}{2}$ and $\frac{1}{3}$, then at least 50% of the total staked `NAM` must have voted for the proposal AND out of this NAM, to be accepted.

Tallying is computed with the following rules:

<Steps>

1. Sum all the voting power of delegates that voted `Yay`, call this sum `SumYay`
2. Sum all the voting power of delegates that voted `Nay`, call this sum `SumNay`
3. Sum all the voting power of delegates that voted `Abstain`, call this sum `SumAbstain`
4. Check if the sum `SumYay` + `SumNay` + `SumAbstain` meets the first threshold, if not, the proposal outcome is negative
5. For any delegate that voted `Yay`, subtract the voting power of any delegator that voted other than `Yay` from `SumYay`
6. For any delegate that voted `Nay`, subtract the voting power of any delegator that voted other than `Nay` from `SumNay`
7. For any delegate that voted `Abstain`, subtract the voting power of any delegator that voted other than `Abstain` from `SumAbstain`
8. Add voting power for any delegation that voted `Yay` (whose corresponding delegate didn't vote `Yay`) to `SumYay`
9. Add voting power for any delegation that voted `Nay` (whose corresponding delegate didn't vote `Nay`) to `SumNay`
9. Add voting power for any delegation that voted `Abstain` (whose corresponding delegate didn't vote `Abstain`) to `SumAbstain`
10. Set `SumYeaOrNay` to `SumYay` + `SumNay`
11. Decide whether or not the proposal succeeds based on the proposal-type-specific tally instructions (see [Proposal](./proposal.mdx))

</Steps>

All the computation is done at the start of `grace_epoch` on data collected at the epoch specified in the `voting-end` field of the proposal.

## Tallying votes offline

Offline votes are tallied under the same mechanism as on-chain vote tallying, but instead of reading the data from storage it will require a list of serialized json votes.
The voting power for each delegate/delegator is calculated based on their respective bonded-stake from the latest block in that epoch (in principle it could be any block in the epoch, since voting-power does not change within an epoch).

### Refund and Proposal Execution mechanism

In parallel to tallying, the protocol manages the execution of accepted proposals and refunding in the `finalize_block` function.
If the proposals `grace_epoch` matches with the current epoch, AND the proposal had a positive outcome, the protocol refunds the locked funds from `GovernanceAddress` to the proposal author address (specified in the proposal `author` field).
Moreover, if the proposal had a positive outcome and had attached WASM code, the code is executed immediately.

On the other hand, should the proposal be rejected (negative outcome), any locked funds is burnt (removed from total supply).

The result is then signaled by creating and inserting a [`CometBFT Event`](https://github.com/cometbft/cometbft/blob/main/spec/abci/abci%2B%2B_basic_concepts.md#events).
5 changes: 5 additions & 0 deletions packages/specs/pages/modules/ibc/design-rationale.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Callout } from 'nextra-theme-docs'

## Design Rationale

Placeholder
7 changes: 7 additions & 0 deletions packages/specs/pages/modules/ibc/storage-layout.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Callout } from 'nextra-theme-docs'

## Storage keys

A token balance is stored with a storage key. The token balance key should be `#Multitoken/{token_addr}/balance/{owner_addr}`. These keys can be made with [token functions](https://github.com/anoma/namada/blob/5da82f093f10c0381865accba99f60c557360c51/core/src/types/token.rs).

Namada stores multitoken balances for the same owner by `{token_addr}`, e.g. a token received over IBC is managed in `#Multitoken/{ibc_token}/balance/{receiver_addr}`. It is distinguished from the receiver's original balance in `#Multitoken/{token_addr}/balance/{receiver_addr}` to know which chain the token was transferred from. The `{ibc_token}` is explained in [IBC](../../modules/ibc.mdx).
5 changes: 5 additions & 0 deletions packages/specs/pages/modules/ibc/vp-logic.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Callout } from 'nextra-theme-docs'

## VP logic

Placeholder
6 changes: 6 additions & 0 deletions packages/specs/pages/modules/masp/design-rationale.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Callout } from 'nextra-theme-docs'

## Design Rationale

- [Convert Circuit](./design/convert-circuit.mdx)
- [Burn and mint][./design/burn-and-mint.mdx]
32 changes: 4 additions & 28 deletions packages/specs/pages/modules/proof-of-stake.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,7 @@

This section of the specification describes the proof-of-stake mechanism of Namada, which is largely modeled after [Cosmos bonded proof-of-stake](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/spec/README.md), but makes significant changes to bond storage representation, validator set change handling, reward distribution, and slashing, with the general aims of increased precision in reasoning about security, validator decentralisation, and avoiding unnecessary proof-of-stake-related transactions.

This section is split into three subcomponents: the [bonding mechanism](./proof-of-stake/objects-and-txs.mdx), [reward distribution](./proof-of-stake/reward-distribution.mdx), and [cubic slashing](./proof-of-stake/cubic-slashing.mdx).

## Context

Blockchain systems rely on economic security (directly or indirectly) to
prevent
abuse and
for actors
to behave according to the protocol. The aim is that economic incentives promote
correct long-term operation of the system and economic punishments
discourage diverging from correct protocol execution either by mistake or
with the intent of carrying out attacks. Many PoS blockchains rely on the 1/3 Byzantine rule, where they make the assumption the adversary cannot control more 2/3 of the total stake or 2/3 of the actors.

## Goals of Rewards and Slashing: Liveness and Security

* **Security: Delegation and Slashing**: we want to make sure validators are
backed by enough funds to make misbehavior very expensive. Security is
achieved by punishing (slashing) if they do. *Slashing* locked funds (stake)
intends to disincentivize diverging from correct execution of protocol,
which in this case is voting to finalize valid blocks.
* **Liveness: Paying Rewards**. For continued operation of Namada we want to incentivize participating in consensus and delegation, which helps security.

### Security

In blockchain systems we do not rely on altruistic behavior but rather economic
security. We expect the validators to execute the protocol correctly. They get rewarded for doing so and punished otherwise. Each validator has some self-stake and some stake that is delegated to it by other token holders. The validator and delegators share the reward and risk of slashing impact with each other.

The total stake behind consensus should be taken into account when value is transferred via a transaction. For example, if we have 1 billion tokens, we aim that 300 Million of these tokens is backing validators. This means that users should not transfer more than 200 million of this token within a block.
- [Design overview](proof-of-stake/design-overview.mdx)
- [Types and storage](proof-of-stake/types-and-storage.mdx)
- [Validity conditions](proof-of-stake/validity-conditions.mdx)
- [Transaction actions](proof-of-stake/transaction-actions.mdx)
10 changes: 5 additions & 5 deletions packages/specs/pages/modules/proof-of-stake/_meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"objects-and-txs": "Objects and Txs",
"cubic-slashing": "Cubic slashing",
"reward-distribution": "Reward distribution",
"inflation-system": "Inflation system"
}
"design-overview": "Design overview",
"types-and-storage": "Types and storage",
"validity-conditions": "Validity conditions",
"transaction-actions": "Transaction actions"
}
Loading

0 comments on commit 55b9473

Please sign in to comment.