bolt icon indicating copy to clipboard operation
bolt copied to clipboard

:sparkles: Components & Systems Bundle

Open notdanilo opened this issue 2 months ago • 3 comments

Status Type ⚠️ Core Change Issue
Hold Feature Yes #65

Problem

Deployment cost of projects with several components and systems programs might get too high. We want to allow developers to bundle systems and components in a single program to reduce deployment costs.

Solution

Introduce the #[bundle] to allow to ship several #[component]s and #[system]s in a single program.

To implement this, we need to add discriminators for components and systems in the program.

The biggest API change is in the delegation instruction, because now we need to send the seeds as a parameter.

Greptile Overview

Updated On: 2025-10-06 07:08:22 UTC

Summary

This PR introduces a major architectural feature called "bundling" that allows developers to combine multiple `#[component]`s and `#[system]`s into a single Solana program, addressing the high deployment costs of approximately 1.7 SOL per component/system. The solution adds a new `#[bundle]` procedural macro that generates unified programs with discriminator-based routing to distinguish between different components and systems within the same program.

The implementation involves significant changes across the entire codebase:

Core Architecture Changes:

  • Removes standalone bolt-component and bolt-system programs, replacing them with bundle functionality
  • Introduces discriminator-based operation routing using SHA-256 hashes of method names (e.g., "global:initialize", "global:update")
  • Refactors the world program to use manual CPI calls instead of high-level Anchor calls to support discriminator parameters
  • Centralizes attribute processing logic into a shared bolt-attribute crate to enable code reuse between standalone and bundled deployments

Bundle Implementation:

  • The #[bundle] macro processes modules containing mixed component structs and system modules
  • Components within bundles use component names as PDA seed prefixes to ensure unique addressing
  • Systems within bundles get renamed with suffixes to avoid naming collisions
  • Generated programs include wrapper functions that handle discriminator routing to the correct component/system logic

Client Integration:

  • All client libraries (TypeScript, C#) updated to support discriminator parameters in API calls
  • New Component and System classes provide abstractions for working with both standalone and bundled entities
  • GetDiscriminator functions implement Anchor's standard SHA-256-based discriminator generation

Development Workflow:

  • New CLI command bolt bundle <name> creates bundle templates in programs-ecs/bundles/
  • Bundle templates demonstrate combining Position/Velocity components with movement/stop systems
  • Updated workspace configuration to include bundle directories and dependencies

The bundling feature maintains backward compatibility with existing standalone components and systems while providing a cost-effective deployment option for projects with multiple ECS entities. The architecture enables the same component and system logic to work in both contexts through shared instruction modules and unified API interfaces.

Sequence Diagram

sequenceDiagram
    participant User
    participant BoltCLI
    participant BundleTemplate
    participant BundleAttribute
    participant ComponentGen
    participant SystemGen
    participant AnchorProgram
    
    User->>BoltCLI: "bolt bundle example-bundle"
    BoltCLI->>BundleTemplate: "create_bundle_template()"
    BundleTemplate->>BundleTemplate: "generate bundle lib.rs with #[bundle]"
    BundleTemplate-->>BoltCLI: "bundle files created"
    
    User->>AnchorProgram: "anchor build"
    AnchorProgram->>BundleAttribute: "process(#[bundle] mod)"
    BundleAttribute->>BundleAttribute: "parse bundle module content"
    
    loop "for each item in bundle"
        alt "item is #[component] struct"
            BundleAttribute->>ComponentGen: "generate_implementation()"
            ComponentGen->>ComponentGen: "generate initialize/update/destroy functions"
            ComponentGen->>ComponentGen: "add component name as PDA seed suffix"
            ComponentGen-->>BundleAttribute: "component instructions generated"
        else "item is #[system] mod"
            BundleAttribute->>SystemGen: "transform_module_for_bundle()"
            SystemGen->>SystemGen: "rename Components to {name}Components"
            SystemGen->>SystemGen: "generate {name}_bolt_execute wrapper"
            SystemGen-->>BundleAttribute: "system instructions generated"
        end
    end
    
    BundleAttribute->>BundleAttribute: "wrap everything in #[program] module"
    BundleAttribute-->>AnchorProgram: "unified program module"
    
    User->>User: "deploy bundle as single program"
    
    Note over User,AnchorProgram: Bundle allows multiple components/systems<br/>in one program to reduce deployment costs

Summary by CodeRabbit

  • New Features

    • Bundle support to combine components and systems into unified programs
    • New ECS domain objects and APIs: Component and System (C# & TypeScript)
    • CLI command, project template, and example bundle to scaffold bundles
  • Improvements

    • Modernized ApplySystem/transaction flows with discriminator and session variants
    • Client tests updated to exercise bundled components and use standard commitment flow
    • CI/workflows publish keys updated to include example bundle deployment keypair

notdanilo avatar Oct 01 '25 06:10 notdanilo

[!NOTE]

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Consolidates attribute macros into a shared bolt-lang/attribute crate, removes bolt-component and bolt-system crates/manifests, adds bundle primitives and discriminator-based CPI flows in World, introduces Component/System/Identifier domain types in TS/C# clients, adds CLI bundle scaffolding and example-bundle, and updates CI/publish lists.

Changes

Cohort / File(s) Summary
Workspace Manifests & CI
\.github/workflows/publish-bolt-crates.yml, \.github/workflows/publish-bolt-sdk.yml, \.github/workflows/run-tests.yml, Anchor.toml, Cargo.toml, scripts/test-publish.sh
Removed bolt-component/bolt-system from workspace and publish lists; added example-bundle and bundle-related attribute entries; added EXAMPLE_BUNDLE deployment key write steps; updated workspace dependencies and publish targets.
Attribute Macro Consolidation & New Bundle Macro
crates/bolt-lang/attribute/*, crates/bolt-lang/attribute/bundle/*, crates/bolt-lang/attribute/{component,system,delegate,component-deserialize,extra-accounts,...}
Centralized proc-macro logic under bolt-lang/attribute; delegated prior inline implementations to shared processors; added bundle proc-macro and supporting modules (component generation, system transform, delegate injection, common helpers); component discriminator now SHA-256-based.
Removed Legacy Programs
crates/programs/bolt-component/*, crates/programs/bolt-system/*
Deleted bolt-component and bolt-system crates and manifests (sources and Cargo.toml removed).
World Program Refactor & Discriminators
crates/programs/world/src/{lib.rs,utils.rs,Cargo.toml}, crates/programs/world/src/utils.rs
Replaced prior CPI builders with explicit discriminator-based CPI/invoke flows; added const fn discriminator_for and discriminator constants; added apply_with_discriminator/apply_with_session_and_discriminator entry points; removed direct bolt-component/bolt-system deps.
bolt-lang Core API & Instructions
crates/bolt-lang/src/{lib.rs,cpi.rs,errors.rs,instructions/*,initialize.rs,destroy.rs,update.rs}
Added cpi helper and instructions modules (initialize/destroy/update), new error variants, NumberOfComponents trait, metadata helpers, and reworked public re-exports to include bundle and remove delegate/program macros.
Attribute Implementation & Codegen
crates/bolt-lang/attribute/src/{bundle,component,system,delegate,component-deserialize,common,generate,...}
Implemented component codegen pipeline, system transforms for bundles, delegate injection utilities, common program scaffolding, and moved many in-file macro implementations to bolt_attribute processors.
CLI Bundle Scaffolding
crates/bolt-cli/src/{bundle.rs,lib.rs,rust_template.rs}, crates/bolt-cli/src/templates/bundle/*, crates/bolt-cli/src/templates/mod.rs, crates/bolt-cli/src/templates/workspace/workspace.toml.template
Added CLI command and templates to create bundle examples; create_bundle logic and workspace template updated to include programs-ecs/bundles/*.
Examples
examples/bundle/{Cargo.toml,src/lib.rs}
Added example-bundle program with Position/Velocity components and movement/stop systems (bundle-style example).
Clients — TypeScript ECS & Transactions
clients/typescript/src/ecs/{identifier,component,system,index}.ts, clients/typescript/src/index.ts, clients/typescript/src/world/transactions.ts, clients/typescript/test/*, clients/typescript/test/framework.ts
Added Identifier/Component/System domain types and GetDiscriminator; transaction builders accept `PublicKey
Clients — C# ECS & World API
clients/csharp/Solana.Unity.Bolt/ECS/{Identifier,Component,System}.cs, clients/csharp/Solana.Unity.Bolt/WorldProgram/Bolt/*.cs, clients/csharp/Solana.Unity.Bolt/WorldProgram/Generated.cs, clients/csharp/Solana.Unity.Bolt.Test/*, clients/csharp/Solana.Unity.Bolt/WorldProgram/World.cs, clients/csharp/Solana.Unity.Bolt/Test/Framework.cs
Added Identifier/Component/System types, GetDiscriminator, World.ApplySystem overload and component/system-aware initialize/destroy/delegate overloads; updated tests and Framework with bundle program IDs and PDAs.
Runtime libs & Utilities
crates/bolt-lang/utils/src/lib.rs, crates/bolt-lang/attribute/extra-accounts/*, crates/bolt-lang/attribute/component/*, crates/bolt-lang/attribute/system/*
Minor utility adjustments (metadata field ordering), added heck/sha2 dependencies where needed, and various proc-macro helper changes.
Docs & Misc
docs/REPORT.md, scripts/test-publish.sh
Small docs data update; publish script adjusted to reflect crate publish list changes.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant SDK as Client SDK (TS/C#)
    participant World as World Program

    Note over Client,World: Bundle/system apply flow (named vs legacy)

    Client->>SDK: Build Component/System domain objects
    SDK->>SDK: For each (entity, components, seeds): compute component.pda(entity, seed)
    SDK->>SDK: system_discriminator = system.getMethodDiscriminator("bolt_execute")
    Client->>SDK: Bolt.World.ApplySystem(world, system, entities[], args, authority)
    SDK->>World: Instruction (program=World, data = [maybe system_discriminator || legacy opcode] + args, accounts = [entity, component_pdas..., authority, ...])
    alt system has discriminator (named)
        World->>World: apply_with_discriminator(system_discriminator, args)
    else legacy unnamed system
        World->>World: apply(args)
    end
    World-->>SDK: Instruction processed / return data
    SDK-->>Client: Tx submitted / result

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • Proc-macro AST transformations and generated token correctness (crates/bolt-lang/attribute/*).
    • World program CPI/invoke changes and discriminator byte layout (crates/programs/world/src/*).
    • Cross-language client SDK changes that must match on-chain discriminators/PDAs (clients/typescript and clients/csharp).
    • New initialize/destroy/update/update_with_session instruction semantics and error mappings (crates/bolt-lang/src/instructions/*).

Possibly related PRs

  • magicblock-labs/bolt#213 — Overlaps on CPI authentication and instruction-sysvar-based checks; related to World/cpi and client builder changes.
  • magicblock-labs/bolt#212 — CI/workflow edits that touch deployment key handling and test-runner workflow; related to added EXAMPLE_BUNDLE keypair steps.

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "✨ Components & Systems Bundle" is fully related to the main change in the changeset—introducing a #[bundle] procedural macro to allow developers to deploy multiple components and systems in a single program to reduce deployment costs. The core text clearly summarizes the primary objective. However, the emoji (✨) adds unnecessary visual noise and goes against the recommendation to avoid such embellishments in PR titles, preferring clean, readable phrasing instead.
Description Check ✅ Passed The PR description includes the core required sections from the template: a complete status table with all required fields (Status, Type, Core Change, Issue), a clear Problem section explaining the deployment cost issue, and a detailed Solution section describing the #[bundle] macro implementation. While the description is extensive and well-structured overall, it is missing two formal template sections: the "Before & After Screenshots" section (which may not be applicable to this architectural feature) and the formal "Deploy Notes" section with structured "New scripts" and "New dependencies" subsections, although deployment-related information is provided elsewhere in the description. The critical status and content information is present and complete.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment
  • [ ] Commit unit tests in branch feature/bundle

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Oct 11 '25 10:10 coderabbitai[bot]

@coderabbitai review

GabrielePicco avatar Oct 11 '25 10:10 GabrielePicco

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot] avatar Oct 11 '25 10:10 coderabbitai[bot]