Skip to content

Commit

Permalink
solana: documentations
Browse files Browse the repository at this point in the history
Signed-off-by: bingyuyap <[email protected]>
  • Loading branch information
bingyuyap committed Oct 1, 2024
1 parent 3004c13 commit a686731
Show file tree
Hide file tree
Showing 12 changed files with 231 additions and 6 deletions.
1 change: 1 addition & 0 deletions .cspell/custom-dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Ruleset
Rulesets
Solana
Pubkey
struct
54 changes: 51 additions & 3 deletions svm/programs/router/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ classDiagram
bump: u8
integrator_id: u64
chain_id: u16
next_transceiver_id: u64
transceiver_bitmap: u64
next_in_transceiver_id: u64
next_out_transceiver_id: u64
in_transceiver_bitmap: Bitmap
out_transceiver_bitmap: Bitmap
}
class RegisteredTransceiver {
Expand All @@ -33,7 +35,53 @@ classDiagram
address: Pubkey
}
class Bitmap {
bitmap: u128
}
Config "1" -- "*" Integrator : tracks
Integrator "1" -- "*" IntegratorChainTransceivers : has
IntegratorChainTransceivers "1" -- "*" RegisteredTransceiver : contains
IntegratorChainTransceivers "1" -- "2" Bitmap : uses
Bitmap "1" -- "*" RegisteredTransceiver : tracks
```

### Key Components

1. **Config**: Stores global configuration for the GMP Router.

- Tracks the program owner, pause state, and integrator ID counter.
- Singleton account created during program initialization.

2. **Integrator**: Represents an entity that can interact with the GMP Router.

- Each integrator has a unique ID and an associated authority.
- Allows for multiple integrators to use the router independently.

3. **IntegratorChainTransceivers**: Manages transceivers for a specific integrator on a particular chain.

- Uses bitmaps for efficient storage and lookup of transceiver statuses.
- Maintains separate counters for incoming and outgoing transceivers.

4. **RegisteredTransceiver**: Represents a registered transceiver in the GMP Router.

- Associated with a specific integrator and chain.
- Has a unique ID within its integrator and chain context.

5. **TransceiverType**: Enum to distinguish between incoming and outgoing transceivers.

- Allows for different handling of inbound and outbound messages.

6. **Bitmap**: Utility struct for efficient storage and manipulation of boolean flags.
- Used to track the status of transceivers (active/inactive).

### Relationships

- The Config account tracks multiple Integrators.
- Each Integrator can have multiple IntegratorChainTransceivers (one per chain).
- IntegratorChainTransceivers use two Bitmaps to efficiently track incoming and outgoing transceiver statuses.
- Each Bitmap tracks multiple RegisteredTransceivers.
- RegisteredTransceivers are associated with a specific Integrator and chain.

This structure allows for efficient management of multiple integrators, chains, and transceivers within the GMP Router system. It provides a scalable and flexible architecture for handling cross-chain message passing.

For detailed documentation on each component and its methods, please refer to the source files and generated API documentation.
3 changes: 3 additions & 0 deletions svm/programs/router/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ use anchor_lang::prelude::*;
pub enum RouterError {
#[msg("The program is paused")]
ProgramPaused,

#[msg("Invalid integrator authority")]
InvalidIntegratorAuthority,

#[msg("Maximum transceivers reached")]
MaxTransceiversReached,

#[msg("Bitmap index is out of bounds")]
BitmapIndexOutOfBounds,
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,29 @@ use crate::{
};
use anchor_lang::prelude::*;

/// Accounts struct for initializing an IntegratorChainTransceivers account
#[derive(Accounts)]
#[instruction(chain_id: u16)]
pub struct InitIntegratorChainTransceivers<'info> {
/// The global configuration account
#[account(
seeds = [Config::SEED_PREFIX],
bump = config.bump,
)]
pub config: Account<'info, Config>,

/// The Integrator account for which the chain transceivers are being initialized
#[account(
seeds = [Integrator::SEED_PREFIX, integrator.id.to_le_bytes().as_ref()],
bump = integrator.bump,
)]
pub integrator: Account<'info, Integrator>,

/// The account paying for the initialization
#[account(mut)]
pub payer: Signer<'info>,

/// The IntegratorChainTransceivers account being initialized
#[account(
init,
payer = payer,
Expand All @@ -35,9 +40,24 @@ pub struct InitIntegratorChainTransceivers<'info> {
)]
pub integrator_chain_transceivers: Account<'info, IntegratorChainTransceivers>,

/// The System Program
pub system_program: Program<'info, System>,
}

/// Initializes an IntegratorChainTransceivers account for a specific integrator and chain
///
/// This function sets up the initial state for managing transceivers on a particular chain
/// for a given integrator. It initializes counters and bitmaps for both incoming and outgoing
/// transceivers.
///
/// # Arguments
///
/// * `ctx` - The context of the instruction, containing the accounts
/// * `chain_id` - The ID of the chain for which the transceivers are being initialized
///
/// # Returns
///
/// Returns `Ok(())` if the initialization is successful
pub fn init_integrator_chain_transceivers(
ctx: Context<InitIntegratorChainTransceivers>,
chain_id: u16,
Expand Down
20 changes: 20 additions & 0 deletions svm/programs/router/src/instructions/initialize.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::state::Config;
use anchor_lang::prelude::*;

/// Accounts struct for initializing the GMP Router
#[derive(Accounts)]
#[instruction(args: InitializeArgs)]
pub struct Initialize<'info> {
/// The account paying for the initialization
#[account(mut)]
pub payer: Signer<'info>,

/// The Config account being initialized
#[account(
init,
space = 8 + Config::INIT_SPACE,
Expand All @@ -16,14 +19,31 @@ pub struct Initialize<'info> {
)]
pub config: Account<'info, Config>,

/// The System Program
pub system_program: Program<'info, System>,
}

/// Arguments for the initialize instruction
#[derive(AnchorSerialize, AnchorDeserialize)]
pub struct InitializeArgs {
/// The public key of the owner of the GMP Router
pub owner: Pubkey,
}

/// Initializes the GMP Router by creating and setting up the Config account
///
/// This function creates the global configuration account for the GMP Router.
/// It sets the owner, initializes the program as unpaused, and sets the initial
/// integrator ID counter.
///
/// # Arguments
///
/// * `ctx` - The context of the instruction, containing the accounts
/// * `args` - The initialization arguments, including the owner's public key
///
/// # Returns
///
/// Returns `Ok(())` if the initialization is successful
pub fn initialize(ctx: Context<Initialize>, args: InitializeArgs) -> Result<()> {
ctx.accounts.config.set_inner(Config {
bump: ctx.bumps.config,
Expand Down
19 changes: 19 additions & 0 deletions svm/programs/router/src/instructions/register_integrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ use crate::error::RouterError;
use crate::state::{Config, Integrator};
use anchor_lang::prelude::*;

/// Accounts struct for registering a new integrator
#[derive(Accounts)]
pub struct RegisterIntegrator<'info> {
/// The global configuration account
#[account(
mut,
seeds = [Config::SEED_PREFIX],
Expand All @@ -12,11 +14,14 @@ pub struct RegisterIntegrator<'info> {
)]
pub config: Account<'info, Config>,

/// The owner of the GMP Router
pub owner: Signer<'info>,

/// The account paying for the registration
#[account(mut)]
pub payer: Signer<'info>,

/// The Integrator account being initialized
#[account(
init,
payer = payer,
Expand All @@ -29,9 +34,23 @@ pub struct RegisterIntegrator<'info> {
)]
pub integrator: Account<'info, Integrator>,

/// The System Program
pub system_program: Program<'info, System>,
}

/// Registers a new integrator in the GMP Router
///
/// This function creates a new Integrator account and assigns it a unique ID.
/// It also updates the global configuration to increment the integrator ID counter.
///
/// # Arguments
///
/// * `ctx` - The context of the instruction, containing the accounts
/// * `authority` - The public key of the authority controlling this integrator
///
/// # Returns
///
/// Returns `Ok(())` if the registration is successful
pub fn register_integrator(ctx: Context<RegisterIntegrator>, authority: Pubkey) -> Result<()> {
let config = &mut ctx.accounts.config;
let integrator_id = config.next_integrator_id;
Expand Down
33 changes: 30 additions & 3 deletions svm/programs/router/src/instructions/register_transceiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@ use crate::error::RouterError;
use crate::state::{Config, Integrator, IntegratorChainTransceivers, RegisteredTransceiver};
use anchor_lang::prelude::*;

/// Enum representing the type of transceiver being registered
#[derive(AnchorSerialize, AnchorDeserialize)]
pub enum TransceiverType {
/// Incoming transceiver
In,
/// Outgoing transceiver
Out,
}

/// Accounts struct for registering a new transceiver
#[derive(Accounts)]
#[instruction(chain_id: u16, transceiver_type: TransceiverType)]
pub struct RegisterTransceiver<'info> {
/// The global configuration account
#[account(
seeds = [Config::SEED_PREFIX],
bump = config.bump,
constraint = !config.paused @ RouterError::ProgramPaused,
)]
pub config: Account<'info, Config>,

/// The Integrator account for which the transceiver is being registered
#[account(
mut,
seeds = [Integrator::SEED_PREFIX, integrator.id.to_le_bytes().as_ref()],
Expand All @@ -26,11 +32,14 @@ pub struct RegisterTransceiver<'info> {
)]
pub integrator: Account<'info, Integrator>,

/// The authority of the Integrator
pub authority: Signer<'info>,

/// The account paying for the registration
#[account(mut)]
pub payer: Signer<'info>,

/// The IntegratorChainTransceivers account for the specific chain
#[account(
mut,
seeds = [
Expand All @@ -42,6 +51,7 @@ pub struct RegisterTransceiver<'info> {
)]
pub integrator_chain_transceivers: Account<'info, IntegratorChainTransceivers>,

/// The RegisteredTransceiver account being initialized
#[account(
init,
payer = payer,
Expand All @@ -56,14 +66,31 @@ pub struct RegisterTransceiver<'info> {
TransceiverType::Out => integrator_chain_transceivers.next_out_transceiver_id,
};
transceiver_id.to_le_bytes().as_ref()
} ],
}
],
bump
)]
pub registered_transceiver: Account<'info, RegisteredTransceiver>,

/// The System Program
pub system_program: Program<'info, System>,
}

/// Registers a new transceiver for a specific integrator and chain
///
/// This function creates a new RegisteredTransceiver account and updates the
/// IntegratorChainTransceivers account to reflect the new transceiver.
///
/// # Arguments
///
/// * `ctx` - The context of the instruction, containing the accounts
/// * `chain_id` - The ID of the chain for which the transceiver is being registered
/// * `transceiver_type` - The type of the transceiver (In or Out)
/// * `transceiver_address` - The public key of the transceiver address
///
/// # Returns
///
/// Returns `Ok(())` if the registration is successful
pub fn register_transceiver(
ctx: Context<RegisterTransceiver>,
chain_id: u16,
Expand All @@ -87,11 +114,11 @@ pub fn register_transceiver(
TransceiverType::In => {
chain_transceivers.set_in_transceiver(transceiver_id as u8, true)?;
chain_transceivers.next_in_transceiver_id += 1;
},
}
TransceiverType::Out => {
chain_transceivers.set_out_transceiver(transceiver_id as u8, true)?;
chain_transceivers.next_out_transceiver_id += 1;
},
}
}

// Initialize the RegisteredTransceiver account
Expand Down
27 changes: 27 additions & 0 deletions svm/programs/router/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,39 @@ use instructions::*;

declare_id!("7qtLhNMdb9dNAWwFvNBMok64EJrS1toY9TQoedVhU1xp");

/// The main program module for the GMP Router
#[program]
pub mod router {
use super::*;

/// Initializes the GMP Router
///
/// # Arguments
///
/// * `ctx` - The context of the instruction
/// * `args` - Initialization arguments
pub fn initialize(ctx: Context<Initialize>, args: InitializeArgs) -> Result<()> {
instructions::initialize::initialize(ctx, args)
}

/// Registers a new integrator
///
/// # Arguments
///
/// * `ctx` - The context of the instruction
/// * `authority` - The public key of the integrator's authority
pub fn register_integrator(ctx: Context<RegisterIntegrator>, authority: Pubkey) -> Result<()> {
instructions::register_integrator::register_integrator(ctx, authority)
}

/// Registers a new transceiver for an integrator
///
/// # Arguments
///
/// * `ctx` - The context of the instruction
/// * `chain_id` - The ID of the chain for which the transceiver is being registered
/// * `transceiver_type` - The type of the transceiver (In or Out)
/// * `transceiver_address` - The public key of the transceiver address
pub fn register_transceiver(
ctx: Context<RegisterTransceiver>,
chain_id: u16,
Expand All @@ -35,6 +56,12 @@ pub mod router {
)
}

/// Initializes the chain transceivers for an integrator
///
/// # Arguments
///
/// * `ctx` - The context of the instruction
/// * `chain_id` - The ID of the chain for which the transceivers are being initialized
pub fn init_integrator_chain_transceivers(
ctx: Context<InitIntegratorChainTransceivers>,
chain_id: u16,
Expand Down
Loading

0 comments on commit a686731

Please sign in to comment.