Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIMD-0088: Enable Core BPF Programs #88

Merged
124 changes: 124 additions & 0 deletions proposals/0088-enable-core-bpf-programs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
simd: '0088'
title: Enable Core BPF Programs
authors:
- Joe Caulfield
category: Standard
type: Core
status: Draft
created: 2023-11-07
feature: (fill in with feature tracking issues once accepted)
---

## Summary

This proposal introduces the concept of Core BPF programs: programs which are
essential to network operations. Currently, these exist as built-in programs
known as "native" programs.
ripatel-fd marked this conversation as resolved.
Show resolved Hide resolved

This SIMD details the process by which existing native programs can be
ported to Core BPF, as well as the process for introducing brand-new Core BPF
programs.

## Motivation

BPF programs offer less complexity than native programs for other clients, such
as Firedancer, since developers will no longer have to keep up with program
changes in their runtime implementations. Instead, the program can just be
updated once.

For this reason, it makes sense to introduce the concept of Core BPF programs:
BPF programs the network depends on that should be treated with special care.

## Alternatives Considered

The alternative to Core BPF programs is to keep these essential programs as
native programs. This would mean each validator client implementation would have
to build and maintain these built-in programs with their runtime
implementations, including any future changes to these programs introduced via
SIMDs or other fixes.

## New Terminology

- `Core BPF Program`: A BPF program relied on by any part of the Solana stack,
including (but not limited to) consensus, transaction processing, voting,
staking, and account creation.

## Detailed Design

Core BPF programs in many ways will be designed no differently than any other
BPF program on Solana. However, some programs may require special privileges,
which is beyond the scope of this SIMD.

When an existing native program is being proposed to be migrated to Core BPF,
or when a new Core BPF program is being introduced, at least one SIMD shall be
published outlining at least the following details:

- The interface for the program
- A precise and complete specification of its behavior
- How any required special privileges will be granted to the program in its BPF
buffalojoec marked this conversation as resolved.
Show resolved Hide resolved
form
- Whether or not this program will be an upgradeable or non-upgradeable BPF
program
- How this changes to this program will be managed after it becomes BPF

**Migrating a native program to core BPF** shall consist of deploying a
BPF version of the native program to a new arbitrary address and using a
feature gate to move the BPF program, replacing the existing native program at
its original program address. No program IDs for existing native programs would
be changed by this migration process.

In the context of this design, **target program** refers to an existing native
program, while **source program** refers to the BPF version to be moved into the
existing program account.

The migration process must adhere to the following steps:

1. Verifiably build the source BPF program.
2. Generate a new keypair for the source program.
3. Deploy the program to the source program address.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this method of deployment would work. The regular BPF program loader might not be able to load a program using privileged instructions. (Which could be in the form of syscalls that are disabled for regular programs, thus fail loading, or dynamic imports for sBPFv2)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking it should work if you're just deploying and not invoking the program (right?).

In theory, if the core BPF program at say 11111111111111111111111111111111 has special privileges, then unless the executable lives at 11111111111111111111111111111111 it's not going to be able to use those privileges. So you deploy the BPF version of it to some arbitrary address, and if it was to be invoked at that arbitrary address it would fail to load. However, it shouldn't ever be invoked at that arbitrary address. It's only temporarily living there until the swap is complete.

Additionally, I think if any tweaks are necessary in the future as we figure out how to provide all of these core BPF programs with the necessary privileges, we can issue another proposal to modify the process or introduce a new one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking it should work if you're just deploying and not invoking the program (right?).

Currently, deployment includes the full ELF loading and eBPF verify pass. Deploying is actually even more restrictive than invoking. It's done that way to allow caching of the verification result, so it is unlikely to change soon.

In theory, if the core BPF program at say 11111111111111111111111111111111 has special privileges, then unless the executable lives at 11111111111111111111111111111111 it's not going to be able to use those privileges.

@Lichtso Has your team thought of ways to privilege core BPF programs? Sounds like @buffalojoec is proposing doing these checks at runtime rather than load time. If we decide to use syscalls, then these syscalls can be invoked by any program but would fail depending on the execution context. I don't think we can use cross program invocations since those are not aware of the caller identity, so I don't see any other mechanism than syscalls without some design changes.

Additionally, I think if any tweaks are necessary in the future as we figure out how to provide all of these core BPF programs with the necessary privileges, we can issue another proposal to modify the process or introduce a new one.

Sounds good to me, I sent my approval already. I just wanted to flag it for future discussion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More discussion is required from VM stakeholders about privileged execution before I can consider approval. I do not want to add more syscalls if they all have to be re-invented in PRv2.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More discussion is required from VM stakeholders about privileged execution before I can consider approval. I do not want to add more syscalls if they all have to be re-invented in PRv2.

Fair point. I guess the question is, does the number of syscalls block us from migration any native program to BPF?

In other words, is it possible we could move this SIMD along to acknowledge that at least some programs will be migrated, and then assess the impact of any necessary syscalls when the SIMDs outlining migration specifications are proposed for a program requiring privileges?

Copy link
Contributor

@ripatel-fd ripatel-fd Jan 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More discussion is required from VM stakeholders about privileged execution before I can consider approval. I do not want to add more syscalls if they all have to be re-invented in PRv2.

@lheeger-jump PRv2 does not require re-inventing any syscalls. It suggests doing so. The benefit of doing that for privileged operations is debatable. This SIMD merely introduces the concept of Core BPF programs and sets the direction towards them long term without specifying a particular way to do privileged operations. We can do that in a follow-up SIMD.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are also a bunch of native programs whose instruction processor is entirely unprivileged. (The privileged parts happen in the slot boundary). Therefore, strongly suggest unblocking this so we can already start porting some programs while we're figuring out the privileges story.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up-voting previous message by @ripatel-fd. If we can move this proposal along to introduce these programs and their migration path, then each program's migration SIMD - outlining the details of its migration to BPF - can tackle privileges.

If we learn that privileged programs will need a different migration path, we can publish another SIMD that adds the necessary changes to the migration process, and block any program migration SIMDs on that new proposal.

buffalojoec marked this conversation as resolved.
Show resolved Hide resolved
4. Generate a new keypair for the feature gate.
5. Create a new feature gate to replace the target program with the source BPF
program.
buffalojoec marked this conversation as resolved.
Show resolved Hide resolved
6. Follow the existing process for activating features.

## Impact

With this change, validator clients would no longer be required to implement
changes to essential programs. Instead these programs could be updated just
once. This reduces some engineering overhead on validator teams.

## Security Considerations

This proposal establishes the concept of relying on BPF programs that are not
built into the runtime for essential cluster operations. Depending on how these
programs are elected to be upgraded, there are some obvious security
considerations around who can upgrade these programs and when. Any new Core BPF
program should follow a fully-fledged SIMD process addressing these concerns.

When it comes to migrating native programs to core BPF, this change introduces a
serious security consideration surrounding the replacement of an essential
program with the contents of another account. This is an extremely sensitive
process that must be handled with maximum caution. If a core program is
reimplemented incorrectly, or somehow erased during migration, it could have
immediate and fatal consequences for the network.

## Backwards Compatibility

This proposal itself does not directly introduce any breaking changes. The code
introduced to migrate native programs to core BPF programs will exist off of the
runtime's "hot path" until it's actually used for a migration.

When a migration is conducted, the BPF version of a native program will be
buffalojoec marked this conversation as resolved.
Show resolved Hide resolved
absolutely backwards compatible *functionally*. Its BPF version must provide the
exact same results as the original native program it aims to replace.

However, since BPF programs cannot precisely match the compute meter and other
resource limits of their original native counterparts, some of these metrics may
be slightly different when a native program becomes BPF, thereby affecting
backwards compatibility in that regard.

Additionally, once a native program has been migrated to core BPF, the process
by which this program is upgraded will not be backwards compatible. Core
contributors must follow the upgrade process outlined in each program's
migration SIMD.
Loading