Skip to content

Commit

Permalink
init SIMD
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Oct 26, 2023
1 parent a85a0da commit f6973c9
Showing 1 changed file with 239 additions and 0 deletions.
239 changes: 239 additions & 0 deletions proposals/0077-programify-feature-gate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
---
simd: '0077'
title: Programify Feature Gate Program
authors:
- Joe Caulfield
- Tyera Eulberg
category: Standard
type: Core
status: Draft
created: 2023-10-26
feature: #33547
supercedes: 0072
---

This is SIMD 1/3 required for **Multi-Client Feature Gates**. See
<https://github.com/solana-foundation/solana-improvement-documents/issues/76>

**Goals:**

- Decentralized control over queuing new runtime features
- Automatic feature activation selection based on stake weight with supporting
software
- Decentralized governance of the mechanism itself

**Resulting Architecture:**

1. 👉 **Feature Creation:** Features can be created by anyone. Each is owned by
an upgradeable BPF program at `Feature111111111111111111111111111111111111`
2. **Feature Queuing:** A governance process nominates features that should be
queued for activation
3. **Feature Recognition & Activation:** Features are activated based on stake
support of nodes who recognize the feature in their software version

## Summary

This SIMD outlines a proposal to replace the non-existent system account at
address `Feature111111111111111111111111111111111111`, which is the owner of
all feature accounts, with an upgradeable BPF program.

It defines the program's initial functionality - which consists solely of the
capability to revoke pending feature activations - and an accompanying
governance system for managing upgrades of the program.

Important note: the process by which core contributors *activate* features
would remain completely unchanged by this SIMD.

## Motivation

Sometimes, a feature that has been queued for activation may need to be
revoked. For numerous reasons, a pending feature could suddenly become unsafe
or otherwise non-desirable. The ability to revoke these pending features is
paramount to secure, frictionless engineering processes and protecting the
network’s stability.

The best way to manage such a capability is to ensure all feature accounts are
owned by a program, which has the authority to clear a feature account’s data
and remove its lamports, effectively revoking it from activation.

Such a program surely presents a security risk if the upgrade authority is not
carefully handled, so a proper governance process is required for this program
to exist.

## Alternatives Considered

At this time, core contributors have not considered any viable alternative
solutions for enabling the ability to revoke pending feature activations. An
on-chain program was decided to be the optimally viable solution. Suggestions
are welcome.

## New Terminology

- Feature Gate program: The BPF program that will own all feature accounts.
- “Revoke” or “revoke pending activation”: The act of reallocating a feature
account’s data to zero, assigning it to the system program, and defunding
its lamports balance - effectively removing it from the runtime’s recognized
set of features pending activation.

## Detailed Design

Currently, when a core contributor wishes to add a runtime feature to the
Solana runtime codebase, they are instructed to generate a new key pair, as
described in the instructions linked below.

<https://github.com/solana-labs/solana/blob/f4287d70bb78307f16949509e013fb5e6f15a751/sdk/src/feature_set.rs#L3-L17>

The contributor then places the code required for the runtime to activate the
feature behind a “feature gate” using the public key of the key pair. The
feature gate allows the runtime to check to make sure a specific account exists
at the address provided for the Feature ID before activating the feature with
the contributor’s code.
An example can be found at the link below:

<https://github.com/solana-labs/solana/blob/f4287d70bb78307f16949509e013fb5e6f15a751/runtime/src/bank.rs#L7885-L7889>

When the network reaches 95% of stake running the particular version of the
Solana runtime software containing the feature, and core contributors have
authorized the activation, the feature can be activated using the keypair and
the CLI command `solana feature activate`.

This command will use the keypair to authorize a transaction that will allocate
the necessary data and assign it under owner
`Feature111111111111111111111111111111111111`. This account at
`Feature111111111111111111111111111111111111` does not exist, but is instead
used as a special address that is known to the Solana SDK. After this process
completes, the feature is scheduled for activation and will be activated at the
next epoch boundary.

### Deploying the Program

In order to deploy an upgradeable BPF program to the address at
`Feature111111111111111111111111111111111111`, a runtime change is required.
This change would allow the runtime, upon feature activation, to move an
already deployed upgradeable BPF program in place of the non-existent
`Feature111111111111111111111111111111111111`.

For maximum security, the intial program that will be deployed and then moved
in place of `Feature111111111111111111111111111111111111` will be a no-op
program with an intentionally large allocation (to allow for larger programs
in the future).

Shortly after verifying this program was successfully moved into place, the
program will be upgraded to contain Feature Gate Program v0.1.0 - which will
include the "revoke functionality defined below.

The specific no-op program that will be initially deployed and moved by the
runtime has been verifiably built and deployed to devent, testnet, and
mainnet-beta. It can be found in the repository linked below.

<https://github.com/buffalojoec/noop-programs/tree/main/programs/feature-gate-noop>

The runtime change to perform this account replacement can be found in the pull
request linked below.

<https://github.com/solana-labs/solana/pull/32783>

The feature tracking issue for this change can be found here:

<https://github.com/solana-labs/solana/issues/33547>

### Revoking Pending Features

As mentioned above under “New Terminology”, the act of revoking a pending
feature activation consists of reallocating a feature account’s data to zero,
assigning it to the system program, and defunding its lamports balance. This
causes the feature account to be “revoked” since the runtime will no longer
detect it as an account owned by `Feature11111`.

When a core contributor executes the `solana feature activate` command, a
signature from the feature key pair is required to activate it, since its state
will change. Similarly, we can require the same feature key pair’s signature to
revoke said feature.

Consider the instruction as it would appear in the Feature Gate Program:

```rust
pub enum FeatureGateInstruction {
/// Revoke a pending feature activation.
///
/// A "pending" feature activation is a feature account that has been
/// allocated and assigned, but hasn't yet been updated by the runtime
/// with an `activation_slot`.
///
/// Features that _have_ been activated by the runtime cannot be revoked.
///
/// Accounts expected by this instruction:
///
/// 0. `[w+s]` Feature account
/// 1. `[w]` Destination (for rent lamports)
RevokePendingActivation,
}
```

When this instruction is invoked with the proper signature, the feature account
would be reallocated, defunded, and returned to the System Program, like so:

```rust
/* Checks */

let new_destination_lamports = feature_info
.lamports()
.checked_add(destination_info.lamports())
.ok_or::<ProgramError>(FeatureGateError::Overflow.into())?;

**feature_info.try_borrow_mut_lamports()? = 0;
**destination_info.try_borrow_mut_lamports()? = new_destination_lamports;

feature_info.realloc(0, true)?;
feature_info.assign(&system_program::id());
```

### Governing the Program Upgrades

Upgrading the Feature Gate program will be controlled by a 2-of-3
multi-signature authority, consisting of key-holders distributed across network
participants.

- Solana Labs: 1 key-holder
- Jump: 1 key-holder
- Jito: 1 key-holder

Only when 2 out of 3 key-holders have authorized an upgrade will the Feature
Gate program be upgraded.

**Note:** This includes the upgrade required to upgrade the initial no-op
program to Feature Gate Program v0.1.0.

## Impact

Core contributors are positively impacted by this change, since the ability to
revoke pending feature activations is a significant security advantage.

However, anyone in the community - validators, developers, etc. - who _is not_

Check failure on line 212 in proposals/0077-programify-feature-gate.md

View workflow job for this annotation

GitHub Actions / Markdown Linter

Emphasis style should be consistent [Expected: asterisk; Actual: underscore]

proposals/0077-programify-feature-gate.md:212:71 MD049/emphasis-style Emphasis style should be consistent [Expected: asterisk; Actual: underscore]
satisfied with the governance system outlined in this proposal may be
emotionally impacted and/or feel there is a risk of centralized authority
around a piece of vital runtime functionality.

## Security Considerations

Currently the accounts used for feature-gating are owned by an account that
does not exists. This means that there’s no on-chain authority that can modify
feature accounts once they’ve been created. This allows the runtime to
confidently update their state upon activation.

With this proposal, a live BPF program - which can accept instructions from
anyone and execute code - will be the owner of these accounts. Surely this
provides significant risk if *both* the program’s processor code *and* its
upgrade authority are not properly managed.

With that being said, thoroughly reviewed and safe processor code, as well as
a robust governance system for upgrading the program, will together mitigate
these new risks as much as possible.

## Backwards Compatibility

As mentioned under "Summary", the process by which core contributors *activate*
features would remain completely unchanged by this SIMD.

This SIMD only _adds_ the capability to revoke pending activations, so it's

Check failure on line 238 in proposals/0077-programify-feature-gate.md

View workflow job for this annotation

GitHub Actions / Markdown Linter

Emphasis style should be consistent [Expected: asterisk; Actual: underscore]

proposals/0077-programify-feature-gate.md:238:16 MD049/emphasis-style Emphasis style should be consistent [Expected: asterisk; Actual: underscore]
completely backwards compatible.

0 comments on commit f6973c9

Please sign in to comment.