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

sov-sequencer-registry module docs #674

Merged
merged 3 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
# `sov-sequencer-registry` module

The `sov-sequencer-registry` module is responsible for sequencer registration, slashing, and rewards. At the moment, only a centralized sequencer is supported. The sequencer's address and bond are registered during the rollup deployment.

### The `sov-sequencer-registry` module offers the following functionality:

Hooks:

The `sov-sequencer-registry` module does not expose any call messages, and rollup users cannot directly modify the state of the sequencer. Instead, the module implements `ApplyBlobHooks` trait.
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,29 @@ use sov_modules_api::macros::CliWalletArg;
use sov_modules_api::CallResponse;
use sov_state::WorkingSet;

use crate::SequencerRegistry;
use crate::{DaAddress, SequencerRegistry};

/// This enumeration represents the available call messages for interacting with the sov-sequencer-registry.
/// This enumeration represents the available call messages for interacting with
/// the `sov-sequencer-registry` module.
#[cfg_attr(
feature = "native",
derive(serde::Serialize),
derive(serde::Deserialize),
derive(CliWalletArg),
derive(schemars::JsonSchema)
derive(schemars::JsonSchema),
derive(CliWalletArg)
)]
#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, PartialEq, Clone)]
// TODO: Replace with DA address generic, when AddressTrait is split
pub enum CallMessage {
Register { da_address: Vec<u8> },
Exit { da_address: Vec<u8> },
/// Add a new sequencer to the sequencer registry.
Register {
/// The DA address of the sequencer you're registering.
da_address: DaAddress,
},
/// Remove a sequencer from the sequencer registry.
Exit {
/// The DA address of the sequencer you're removing.
da_address: DaAddress,
},
}

impl<C: sov_modules_api::Context> SequencerRegistry<C> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
//! The `sov-sequencer-registry` module is responsible for sequencer
//! registration, slashing, and rewards. At the moment, only a centralized
//! sequencer is supported. The sequencer's address and bond are registered
//! during the rollup deployment.
//!
//! The module implements the [`sov_modules_api::hooks::ApplyBlobHooks`] trait.

#![deny(missing_docs)]

mod call;
mod genesis;
mod hooks;
Expand All @@ -10,51 +19,87 @@ pub use query::{SequencerAddressResponse, SequencerRegistryRpcImpl, SequencerReg
use sov_modules_api::{CallResponse, Error, ModuleInfo, Spec};
use sov_state::{StateMap, StateValue, WorkingSet};

/// Initial configuration for the sov_sequencer_registry module.
/// TODO: Should we allow multiple sequencers in genesis?
/// A type alias for DA addresses.
///
/// TODO: All usages of this type ought to be replaced with a DA address generic,
/// once <https://github.com/Sovereign-Labs/sovereign-sdk/issues/493> is fixed.
type DaAddress = Vec<u8>;

/// Genesis configuration for the [`SequencerRegistry`] module.
///
/// This `struct` must be passed as an argument to
/// [`Module::genesis`](sov_modules_api::Module::genesis).
///
// TODO: Should we allow multiple sequencers in genesis?
pub struct SequencerConfig<C: sov_modules_api::Context> {
/// The rollup address of the sequencer.
pub seq_rollup_address: C::Address,
// TODO: Replace with DA address generic, when AddressTrait is split
pub seq_da_address: Vec<u8>,
/// The Data Availability (DA) address of the sequencer.
pub seq_da_address: DaAddress,
/// Coins that will be slashed if the sequencer is malicious.
///
/// The coins will be transferred from
/// [`SequencerConfig::seq_rollup_address`] to this module's address
/// ([`ModuleInfo::address`]) and locked away until the sequencer
/// decides to exit (unregister).
///
/// Only sequencers in the [`SequencerRegistry::allowed_sequencers`] list are
/// allowed to exit.
pub coins_to_lock: sov_bank::Coins<C>,
/// Determines whether this sequencer is *regular* or *preferred*.
///
/// Batches from the preferred sequencer are always processed first in
/// block, which means the preferred sequencer can guarantee soft
/// confirmation time for transactions.
pub is_preferred_sequencer: bool,
}

/// The `sov-sequencer-registry` module `struct`.
#[cfg_attr(feature = "native", derive(sov_modules_api::ModuleCallJsonSchema))]
#[derive(Clone, ModuleInfo)]
pub struct SequencerRegistry<C: sov_modules_api::Context> {
/// The address of the sov_sequencer_registry module
/// Note: this is address is generated by the module framework and the corresponding private key is unknown.
/// The address of the `sov_sequencer_registry` module.
/// Note: this is address is generated by the module framework and the
/// corresponding private key is unknown.
#[address]
pub(crate) address: C::Address,

/// Reference to the Bank module.
#[module]
pub(crate) bank: sov_bank::Bank<C>,

/// Only batches from sequencers from this list are going to be processed
///
/// Only batches from sequencers from this list are going to be processed.
#[state]
pub(crate) allowed_sequencers: StateMap<Vec<u8>, C::Address>,
pub(crate) allowed_sequencers: StateMap<DaAddress, C::Address>,

/// Optional preferred sequencer
/// Optional preferred sequencer.
/// If set, batches from this sequencer will be processed first in block,
/// So this sequencer can guarantee soft confirmation time for transactions
#[state]
pub(crate) preferred_sequencer: StateValue<Vec<u8>>,
pub(crate) preferred_sequencer: StateValue<DaAddress>,

/// Coin's that will be slashed if the sequencer is malicious.
/// The coins will be transferred from `self.seq_rollup_address` to `self.address`
/// and locked forever, until sequencer decides to exit
/// Only sequencers in `allowed_sequencers` list are allowed to exit.
/// The coins will be transferred from
/// [`SequencerConfig::seq_rollup_address`] to
/// [`SequencerRegistry::address`] and locked forever, until sequencer
/// decides to exit (unregister).
///
/// Only sequencers in the [`SequencerRegistry::allowed_sequencers`] list are
/// allowed to exit.
#[state]
pub(crate) coins_to_lock: StateValue<sov_bank::Coins<C>>,
}

/// Result of applying blob, from sequencer point of view.
/// Result of applying a blob, from sequencer's point of view.
pub enum SequencerOutcome {
/// The blob was applied successfully and the operation is concluded.
Completed,
Slashed { sequencer: Vec<u8> },
/// The blob was *not* applied successfully. The sequencer has been slashed
/// as a result of the invalid blob.
Slashed {
/// The address of the sequencer that was slashed.
sequencer: DaAddress,
},
}

impl<C: sov_modules_api::Context> sov_modules_api::Module for SequencerRegistry<C> {
Expand Down Expand Up @@ -88,17 +133,17 @@ impl<C: sov_modules_api::Context> sov_modules_api::Module for SequencerRegistry<
}

impl<C: sov_modules_api::Context> SequencerRegistry<C> {
/// Returns the configured amount of [`Coins`](sov_bank::Coins) to lock.
pub fn get_coins_to_lock(
&self,
working_set: &mut WorkingSet<C::Storage>,
) -> Option<sov_bank::Coins<C>> {
self.coins_to_lock.get(working_set)
}

// TODO: Replace with DA address generic, when AddressTrait is split
pub(crate) fn register_sequencer(
&self,
da_address: Vec<u8>,
da_address: DaAddress,
rollup_address: &C::Address,
working_set: &mut WorkingSet<C::Storage>,
) -> anyhow::Result<()> {
Expand All @@ -120,16 +165,18 @@ impl<C: sov_modules_api::Context> SequencerRegistry<C> {
Ok(())
}

/// Return preferred sequencer if it was set
/// TODO: Replace with DA address generic, when AddressTrait is split
/// Returns the preferred sequencer, or [`None`] it wasn't set.
///
/// Read about [`SequencerConfig::is_preferred_sequencer`] to learn about
/// preferred sequencers.
pub fn get_preferred_sequencer(
&self,
working_set: &mut WorkingSet<C::Storage>,
) -> Option<Vec<u8>> {
) -> Option<DaAddress> {
self.preferred_sequencer.get(working_set)
}

/// Set preferred sequencer
/// Checks whether `sender` is a registered sequencer.
pub fn is_sender_allowed<T: sov_modules_api::AddressTrait>(
&self,
sender: &T,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
#![allow(missing_docs)]

use jsonrpsee::core::RpcResult;
use sov_modules_api::macros::rpc_gen;
use sov_modules_api::Context;
use sov_state::WorkingSet;

use crate::SequencerRegistry;
use crate::{DaAddress, SequencerRegistry};

/// The response type to the `getSequencerDddress` RPC method.
#[cfg_attr(
feature = "native",
derive(serde::Deserialize, serde::Serialize, Clone)
)]
#[derive(Debug, Eq, PartialEq)]
pub struct SequencerAddressResponse<C: Context> {
/// The rollup address of the requested sequencer.
pub address: Option<C::Address>,
}

#[rpc_gen(client, server, namespace = "sequencer")]
impl<C: Context> SequencerRegistry<C> {
/// Returns sequencer rollup address for given DA address
/// Contains any data only if sequencer is allowed to produce batches
/// Returns the rollup address of the sequencer with the given DA address.
///
/// The response only contains data if the sequencer is registered.
#[rpc_method(name = "getSequencerAddress")]
pub fn sequencer_address(
&self,
da_address: Vec<u8>,
da_address: DaAddress,
working_set: &mut WorkingSet<C::Storage>,
) -> RpcResult<SequencerAddressResponse<C>> {
Ok(SequencerAddressResponse {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "CallMessage",
"description": "This enumeration represents the available call messages for interacting with the sov-sequencer-registry.",
"description": "This enumeration represents the available call messages for interacting with the `sov-sequencer-registry` module.",
"oneOf": [
{
"description": "Add a new sequencer to the sequencer registry.",
"type": "object",
"required": [
"Register"
Expand All @@ -16,6 +17,7 @@
],
"properties": {
"da_address": {
"description": "The DA address of the sequencer you're registering.",
"type": "array",
"items": {
"type": "integer",
Expand All @@ -29,6 +31,7 @@
"additionalProperties": false
},
{
"description": "Remove a sequencer from the sequencer registry.",
"type": "object",
"required": [
"Exit"
Expand All @@ -41,6 +44,7 @@
],
"properties": {
"da_address": {
"description": "The DA address of the sequencer you're removing.",
"type": "array",
"items": {
"type": "integer",
Expand Down
Loading