Skip to content

Commit

Permalink
add x fee section, staking intro + post-etna, token dist init alloc (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
owenwahlgren authored Oct 2, 2024
1 parent e999eaf commit b980045
Show file tree
Hide file tree
Showing 7 changed files with 430 additions and 14 deletions.
20 changes: 18 additions & 2 deletions content/course/l1-tokenomics/04-staking/01-staking-tokens.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
---
title: Introduction
description: Enter description
description: Learn about staking on Avalanche L1s
updated: 2024-09-03
authors: [0xstt]
icon: Book
---

TBD
In many networks, such as Ethereum, the same token is used for both staking and paying for gas. However, in the Avalanche network, staking tokens and gas tokens can be separated, as they fulfill different purposes within the blockchain ecosystem.

### Staking Tokens

Staking tokens are used for securing public, permissionless Avalanche L1s through a proof-of-stake (PoS) consensus mechanism. Holders of staking tokens can:

- Run validators
- Participate in the consensus process by staking a certain amount of tokens as collateral

Validators propose and validate new blocks on your L1 blockchain. Staking tokens play a crucial role in:

- Maintaining network security
- Incentivizing validator participation

### Private Avalanche L1s

Not all Avalanche L1s are public and permissionless. Many enterprises choose a **Proof-of-Authority** setup, where the validators are selected by the enterprise. These blockchains do not require a staking token.
Original file line number Diff line number Diff line change
@@ -1,9 +1,160 @@
---
title: Staking Contract (post Etna Upgrade)
description: Enter description
description: How staking will work post Etna upgrade
updated: 2024-09-03
authors: [0xstt]
icon: Book
---

TBD
## Validator Manager Contract

[`ValidatorManager.sol`](https://github.com/ava-labs/teleporter/blob/staking-contract/contracts/validator-manager/ValidatorManager.sol) defines the abstract staking contract used to manage subnet-only validators, as defined in [ACP-77](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets).

## Usage

The common case for adding or removing a validator from a Subnet's validator set follows these general steps:

1. Initiate the change through the Validator Manager contract. The Validator Manager contract will construct a Warp message attesting to the change in the validator set.
2. Deliver the Warp message containing the validator set change to the P-Chain. The P-Chain will construct a Warp message acknowledging the change to the validator set.
3. Deliver the Warp message containing the P-Chain acknowledgement back to the Validator Manager contract on the Subnet. The Validator Manager contract finalizes the validator set change.

### Initializing a Validator Set

If the Subnet has no validators registered on the P-Chain, then it will not be able to sign a Warp message to add a validator (step 1 above). In this case, Subnet recovery must be performed on the P-Chain, which allows an initial validator set to be specified, along with each validator's expiry. These validators are *not* registered with the Subnet's Validator Manager, and are only used to bootstrap subnet consensus and Warp message signing. The following steps describe how to register validators with the Subnet's Validator Manager, after which the initial validator set specified during Subnet recovery may safely exit the validator set or expire.

### Registering a Validator

Validator registration is initiated with a call to `initializeValidatorRegistration` on the concrete Validator Manager contract. The Validator Manager contract constructs a [`RegisterSubnetValidatorMessage`](#registersubnetvalidatormessage) Warp message to be sent to the P-Chain. Each validator registration request includes all of the information needed to identify the validator and its stake weight, as well as an `expiry` timestamp before which the `RegisterSubnetValidatorMessage` must be delivered to the P-Chain.

The `RegisterSubnetValidatorMessage` is delivered to the P-Chain as the Warp message payload of a [`RegisterSubnetValidatorTx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#registersubnetvalidatortx). Please see the transaction [specification](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#step-2-issue-a-registersubnetvalidatortx-on-the-p-chain) for validity requirements. The successful `RegisterSubnetValidatorTx` results in a [`SubnetValidatorRegistrationMessage`](#subnetvalidatorregistrationmessage) Warp message indicating that the specified validator was successfully registered on the P-Chain.

The `SubnetValidatorRegistrationMessage` is delivered to the Validator Manager contract via a call to `completeValidatorRegistration`. For PoS Validator Managers, staking rewards begin accruing at this time.

#### Handling a Missed Expiry

In the case of a missed expiry, the `RegisterSubnetValidatorTx` will result in a `SubnetValidatorRegistrationMessage` Warp message with `valid=0`. This serves as proof that the corresponding validation has not started and may never start. The `SubnetValidatorRegistrationMessage` can be provided to the Validator Manager contract by calling `completeEndValidation` with `setWeightMessageType=false`.

### Exiting the Validator Set

Validator exit is initiated with a call to `initializeEndValidation` on the Validator Manager contract. For PoS Validator Managers, a [`ValidationUptimeMessage`](#validationuptimemessage) Warp message may optionally be provided in order to calculate the staking rewards; otherwise the validator's uptime will be set to `0`. This proof may be requested directly from the Subnet validators, which will provide it in a `ValidationUptimeMessage` Warp message. Once `initializeEndValidation` is called, staking rewards cease accruing for PoS Validator Managers: the Validator Manager contract constructs a [`SetSubnetValidatorWeightMessage`](#setsubnetvalidatorweightmessage) Warp message, setting the weight to `0`.

The `SetSubnetValidatorWeightMessage` is delivered to the P-Chain as the payload of a [`SetSubnetValidatorWeightTx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#setsubnetvalidatorweighttx). The P-Chain acknowledges validator exit by signing a `SubnetValidatorRegistrationMessage` with `valid=0`, which is delivered to the Validator Manager by calling `completeEndValidation`. The validation is removed from the contract's state, and for PoS Validator Managers, staking rewards are disbursed and stake is returned.

#### Disable a Validator Directly on the P-Chain

ACP-77 also provides a method to disable a validator without interacting with the Subnet directly. The P-Chain transaction [`DisableValidatorTx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#disablevalidatortx) disables the validator on the P-Chain. The disabled validator's weight will still count towards the Subnet's total weight.

Disabled Subnet validators can re-activate at any time by increasing their balance with an `IncreaseBalanceTx`. Anyone can call `IncreaseBalanceTx` for any validator on the P-Chain. A disabled validator can only be totally removed from the validator set by a call to `initializeEndValidation`.

## Warp Message Format Reference

### `RegisterSubnetValidatorMessage`

Description: Issued by the Validator Manager contract in order to register a Subnet validator

Signed by: Subnet
Consumed by: P-Chain

Specification:

```
+--------------+----------+-----------+
| codecID : uint16 | 2 bytes |
+--------------+----------+-----------+
| typeID : uint32 | 4 bytes |
+--------------+----------+-----------+
| subnetID : [32]byte | 32 bytes |
+--------------+----------+-----------+
| nodeID : [32]byte | 32 bytes |
+--------------+----------+-----------+
| weight : uint64 | 8 bytes |
+--------------+----------+-----------+
| blsPublicKey : [48]byte | 48 bytes |
+--------------+----------+-----------+
| expiry : uint64 | 8 bytes |
+--------------+----------+-----------+
| 134 bytes |
+-----------+
```

### `SubnetValidatorRegistrationMessage`

Description: Issued by the P-Chain in order to confirm Subnet validator registration

Signed by: P-Chain
Consumed by: Validator Manager contract

Specification:

```
+--------------+----------+----------+
| codecID : uint16 | 2 bytes |
+--------------+----------+----------+
| typeID : uint32 | 4 bytes |
+--------------+----------+----------+
| validationID : [32]byte | 32 bytes |
+--------------+----------+----------+
| valid : bool | 1 byte |
+--------------+----------+----------+
| 39 bytes |
+----------+
```

### `ValidationUptimeMessage`

Description: Issued by the Subnet in order to provide validator uptime to the Subnet to calculate staking rewards

Signed by: Subnet
Consumed by: Validator Manager contract

Specification:

```
+--------------+----------+----------+
| codecID : uint16 | 2 bytes |
+--------------+----------+----------+
| typeID : uint32 | 4 bytes |
+--------------+----------+----------+
| validationID : [32]byte | 32 bytes |
+--------------+----------+----------+
| uptime : uint64 | 8 bytes |
+--------------+----------+----------+
| 46 bytes |
+----------+
```

### `SetSubnetValidatorWeightMessage`

Description: Used to set a validator's stake weight on another chain

Signed by: Subnet
Consumed by: P-Chain

Specification:

```
+--------------+----------+----------+
| codecID : uint16 | 2 bytes |
+--------------+----------+----------+
| typeID : uint32 | 4 bytes |
+--------------+----------+----------+
| validationID : [32]byte | 32 bytes |
+--------------+----------+----------+
| nonce : uint64 | 8 bytes |
+--------------+----------+----------+
| weight : uint64 | 8 bytes |
+--------------+----------+----------+
| 54 bytes |
+----------+
```

## Types of Validator Managers

### Proof of Authority

The Proof of Authority (PoA) validator manager is ownable, and only allows the owner to modify changes to the validator set of the Subnet. Validators are given a weight by the owner, but do not accrue staking rewards.

### Proof of Stake

The Proof of Stake (PoS) validator manager allows any validator to register and exit the Subnet validator set. Validators are given a weight based on the amount of stake they provide, and accrue staking rewards based on their uptime. The staking rewards can be either native or erc20 tokens.
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
---
title: Introduction
description: Enter description
description: Learn about blockchain transaction fees.
updated: 2024-09-03
authors: [0xstt]
icon: Book
---

TBD
### Background
When creating an Avalanche L1 we cannot only configure our custom native token, but also how the transaction fees (also known as gas fees) are determined. This allows Avalanche L1s to define the desired or maximal throughput of the blockchain differently.

![](/course-images/multi-chain-architecture/subnet-fee-comparison.png)

In the context of the EVM, gas is a unit that measures the computational effort required to execute specific operations. Each operation performed by a contract or transaction on an EVM chain consumes a certain number of gas units based on its complexity. Operations that require more computational resources cost more gas. The EVM calculates the required gas units automatically, and developers are encouraged to optimize their contract code to reduce gas consumption.
```bash
Transaction Cost = Gas Units * Gas Price
```
For EVM based Avalanche L1s, gas payment can be configured to better suit the use case of the L1. This means the L1 can design and decide whether the gas fees are burned, paid to incentivize validators, or used for any other custom behavior.

### Gas Price and Gas Limit
Each transaction specifies the gas price and gas limit:

**Gas Price**: The gas price is the amount of the Avalanche L1's native token that the sender is **willing to spend per unit of gas**, typically denoted in gwei (1 native token = 1,000,000,000 gwei).

**Gas Limit**: The gas limit is the **maximum amount** of gas the sender is willing to use for the transaction. It was introduced to prevent infinite loops in contract execution.

In a Turing-complete language like Solidity (the main programming language in the EVM), it is possible to write a contract with an infinite loop, either accidentally or intentionally. While an infinite loop might be a nuisance in traditional computing, it could cause significant issues in a decentralized blockchain by causing the network to hang as it attempts to process a never-ending transaction. The gas limit prevents this by halting execution once the gas consumed reaches the limit.

If a transaction exceeds the gas limit, it fails, but the fee amounting to the gas limit is still paid by the sender.
Original file line number Diff line number Diff line change
@@ -1,9 +1,74 @@
---
title: Transaction Fee Configuration
description: Enter description
description: Configure the transaction fee for an Avalanche L1
updated: 2024-09-03
authors: [0xstt]
icon: Book
---

TBD
## Configuration Format

The fees are configured in the `chainConfig` in the `feeConfig` field:

```json
{
"config": {
// ...
"feeConfig": { // [!code highlight]
"gasLimit": 15000000,
"minBaseFee": 25000000000,
"targetGas": 15000000,
"baseFeeChangeDenominator": 36,
"minBlockGasCost": 0,
"maxBlockGasCost": 1000000,
"targetBlockRate": 2,
"blockGasCostStep": 200000
},
"allowFeeRecipients": false
},
"alloc": {
// ...
},
// ...

"gasLimit": 0xe4e1c0,
// ...
}
```

## Gas Configuration Parameters

### `gasLimit`

Sets the maximum amount of gas consumed per block. This restriction caps the computational capacity of a single block and thereby limits the maximum gas usage allowed for any single transaction. For reference, the C-Chain value is set to 15,000,000.

You might notice that the `gasLimit` field appears twice. This is because Avalanche introduced its own fee configuration under the `feeConfig` key while maintaining compatibility with the standard EVM configuration. Ensure that both fields have the same decimal and hexadecimal equivalent values.

### `targetBlockRate`

Specifies the target rate of block production in seconds. For instance, a target of 2 aims to produce a block every 2 seconds. If blocks are produced faster than this rate, it signals that more blocks are being issued to the network than anticipated, leading to an increase in base fees. For C-Chain, this value is set to 2.

### `minBaseFee`

Establishes a lower bound on the EIP-1559 base fee for a block. This minimum base fee effectively sets the minimum gas price for any transaction included in that block.

### `targetGas`

Indicates the targeted amount of gas (including block gas cost) to be consumed within a rolling 10-second window. The dynamic fee algorithm adjusts the base fee proportionally based on how actual network activity compares to this target. If network activity exceeds the `targetGas`, the base fee is increased accordingly.

### `baseFeeChangeDenominator`

Determines how much to adjust the base fee based on the difference between actual and target utilization. A larger denominator results in a slower-changing base fee, while a smaller denominator allows for quicker adjustments. For C-Chain, this value is set to 36, meaning the base fee changes by a factor of 1/36 of the parent block's base fee.

### `minBlockGasCost`

Sets the minimum amount of gas charged for the production of a block. In the C-Chain, this value is set to 0.

### `maxBlockGasCost`

Specifies the maximum amount of gas charged for the production of a block.

### `blockGasCostStep`

Defines how much to increase or decrease the block gas cost based on the time elapsed since the previous block. If a block is produced at the target rate, the block gas cost remains the same as the parent block. If the production rate deviates from the target, the block gas cost is adjusted by the `blockGasCostStep` value for each second faster or slower than the target block rate.

Loading

0 comments on commit b980045

Please sign in to comment.