Skip to content

feat: committor service #366

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

Open
wants to merge 59 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
45bdf72
test: add realloc ix to flexi counter
thlorenz Mar 10, 2025
2e61882
chore: resort workspace depencencies
thlorenz May 7, 2025
6806acf
chore: retire old remote scheduled commits processor and add new one
thlorenz May 7, 2025
8cdc141
feat: initial impl of commits processor based on committor service
thlorenz May 7, 2025
c0d08a4
feat: initializing committor service at startup
thlorenz May 7, 2025
9eed608
test: logging signature of failed init_committees tx
thlorenz May 8, 2025
dae8ea8
test: adapt to expect two signatures when finalizing
thlorenz May 9, 2025
80e6777
feat: ensure ephemeral validator is funded on chain
thlorenz May 9, 2025
3078a1c
test: add single account commit test
thlorenz May 9, 2025
8391124
test: warn when we have issues fetching a transaction
thlorenz May 9, 2025
e5aa347
fix: adding change for validator fund check
thlorenz May 9, 2025
be98740
feat: fully integrating committor service
thlorenz May 9, 2025
5ce7a20
chore: update ix tests cargo
thlorenz May 12, 2025
b54cd3b
chore: comment with requirements for schedule commit tests
thlorenz May 12, 2025
dc2da58
chore: improve test logs
thlorenz May 13, 2025
560fd6b
chore: include compute unit price when initializing committor
thlorenz May 13, 2025
b3445c1
fix: mark accounts to be undelegated
thlorenz May 13, 2025
24bb27a
chore: properly handle some unwraps
thlorenz May 14, 2025
cc389e7
test: general improvements + fixes
thlorenz May 14, 2025
f7304cf
chore: use trait for committor service and create stub to use in tests
thlorenz May 14, 2025
04b0116
chore: update ensure accounts tests to use stub
thlorenz May 14, 2025
d770b95
chore: re-enable account cloner and ensure accounts tests
thlorenz May 14, 2025
88dd40b
chore: move committor repo crates into magicblock monorepo
thlorenz May 14, 2025
e6f1edd
chore: move committor service integration tests
thlorenz May 14, 2025
1c4dd78
chore: noting escrow/fee payer related test requirements
thlorenz May 14, 2025
8c620fe
chore: minor cleanup in test runner
thlorenz May 15, 2025
f3e17d1
ix: load committor program for schedule commits
thlorenz May 15, 2025
6d109f9
ix: allow configuring loaded accounts
thlorenz May 15, 2025
0dceb8b
ix: match ephem validator keypair to the one we use on chain
thlorenz May 15, 2025
7fdc795
ix: ensure we always pass same loaded chain accounts to chain + ephen…
thlorenz May 15, 2025
47ccee4
ix: update dlp binary
thlorenz May 15, 2025
c85b529
ix: add committor tests to run_tests
thlorenz May 15, 2025
cf609d4
ix: move table mania tests to integration
thlorenz May 15, 2025
b968ea5
ix: run table mania as part of test suite
thlorenz May 15, 2025
d3bacca
Merge branch 'master' into thlorenz/committor
thlorenz May 15, 2025
7bde596
chore: fmt
thlorenz May 15, 2025
52fd831
chore: update delegation program reference
thlorenz May 15, 2025
714dd68
chore: opt out of doctests for added crates
thlorenz May 15, 2025
0f94802
ix: add rule to make committor program
thlorenz May 15, 2025
c8ddb16
fix: error misspelling
thlorenz May 15, 2025
b246170
chore: address some greptiles
thlorenz May 15, 2025
d3892d1
ix: check in missing config
thlorenz May 15, 2025
ca5e9f4
chore: more greptiles
thlorenz May 15, 2025
bc48d58
ix: move table mania/committor tests last since they are the slowest
thlorenz May 15, 2025
9fb082a
chore: rollback delegation program version
thlorenz May 15, 2025
ee396da
chore: cleanup stray log
thlorenz May 15, 2025
8635738
ix: give more compile time before expecting validator to listen
thlorenz May 15, 2025
7f3e0eb
chore: greptiles
thlorenz May 15, 2025
28504c1
chore: improved error handling in table mania manager
thlorenz May 16, 2025
bc1324d
fix: greptiles
thlorenz May 16, 2025
644ad1c
chore: demote some no longer urgent TODOs
thlorenz May 16, 2025
4f8ecc8
feat: committor service persists into ledger path
thlorenz May 16, 2025
3cf473d
chore: remove duplicate code in magic validator
thlorenz May 16, 2025
a7b4aa5
feat: limiting stale reallocs until we bail
thlorenz May 16, 2025
776bbf1
tmp: disabling ledger restore tests to isolate issues
thlorenz May 16, 2025
aeeb5ae
tmp: disable all workflows but integration tests while isolating issues
thlorenz May 16, 2025
aedf9a2
fix: ordering of worker startups
thlorenz May 16, 2025
1e9921d
Revert "tmp: disabling ledger restore tests to isolate issues"
thlorenz May 16, 2025
0e0ef0f
Revert "tmp: disable all workflows but integration tests while isolat…
thlorenz May 16, 2025
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
323 changes: 322 additions & 1 deletion Cargo.lock

Large diffs are not rendered by default.

63 changes: 41 additions & 22 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ members = [
"magicblock-accounts-db",
"magicblock-api",
"magicblock-bank",
"magicblock-committor-program",
"magicblock-committor-service",
"magicblock-config",
"magicblock-core",
"magicblock-geyser-plugin",
Expand All @@ -25,6 +27,8 @@ members = [
"magicblock-processor",
"magicblock-pubsub",
"magicblock-rpc",
"magicblock-rpc-client",
"magicblock-table-mania",
"magicblock-tokens",
"magicblock-transaction-status",
"magicblock-version",
Expand Down Expand Up @@ -55,18 +59,18 @@ assert_matches = "1.5.0"
async-trait = "0.1.77"
base64 = "0.21.7"
bincode = "1.3.3"
borsh = { version = "1.5.1", features = ["derive", "unstable__schema"] }
borsh-derive = "1.5.1"
bs58 = "0.4.0"
byteorder = "1.5.0"
cargo-lock = "10.0.0"
expiring-hashmap = { path = "./utils/expiring-hashmap" }
conjunto-transwise = { git = "https://github.com/magicblock-labs/conjunto.git", rev = "bf82b45" }
console-subscriber = "0.2.0"
isocountry = "0.3.2"
crossbeam-channel = "0.5.11"
ed25519-dalek = "1.0.1"
enum-iterator = "1.5.0"
env_logger = "0.11.2"
magic-domain-program = { git = "https://github.com/magicblock-labs/magic-domain-program.git", rev = "eba7644", default-features = false}
magicblock-delegation-program = { git = "https://github.com/magicblock-labs/delegation-program.git", rev = "4af7f1c" }
expiring-hashmap = { path = "./utils/expiring-hashmap" }
fd-lock = "4.0.2"
fs_extra = "1.3.0"
futures-util = "0.3.30"
Expand All @@ -76,6 +80,7 @@ hostname = "0.4.0"
http-body-util = "0.1.2"
hyper = "1.4.1"
hyper-util = "0.1.9"
isocountry = "0.3.2"
itertools = "0.14"
jsonrpc-core = "18.0.0"
jsonrpc-core-client = "18.0.0"
Expand All @@ -87,21 +92,7 @@ lazy_static = "1.4.0"
libc = "0.2.153"
libloading = "0.7.4"
log = "0.4.20"
num_cpus = "1.16.0"
num-derive = "0.4"
num-format = "0.4.4"
num-traits = "0.2"
paste = "1.0"
prometheus = "0.13.4"
# Needs to match https://crates.io/crates/solana-storage-bigtable/2.1.13/dependencies
prost = "0.11.9"
rand = "0.8.5"
rayon = "1.10.0"
rustc_version = "0.4"
semver = "1.0.22"
serde = "1.0.217"
serde_derive = "1.0"
serde_json = "1.0"
magic-domain-program = { git = "https://github.com/magicblock-labs/magic-domain-program.git", rev = "eba7644", default-features = false }
magicblock-account-cloner = { path = "./magicblock-account-cloner" }
magicblock-account-dumper = { path = "./magicblock-account-dumper" }
magicblock-account-fetcher = { path = "./magicblock-account-fetcher" }
Expand All @@ -111,8 +102,13 @@ magicblock-accounts-api = { path = "./magicblock-accounts-api" }
magicblock-accounts-db = { path = "./magicblock-accounts-db" }
magicblock-api = { path = "./magicblock-api" }
magicblock-bank = { path = "./magicblock-bank" }
magicblock-committor-program = { path = "./magicblock-committor-program", features = [
"no-entrypoint",
] }
magicblock-committor-service = { path = "./magicblock-committor-service" }
magicblock-config = { path = "./magicblock-config" }
magicblock-core = { path = "./magicblock-core" }
magicblock-delegation-program = { git = "https://github.com/magicblock-labs/delegation-program.git", rev = "4af7f1c" }
magicblock-geyser-plugin = { path = "./magicblock-geyser-plugin" }
magicblock-ledger = { path = "./magicblock-ledger" }
magicblock-metrics = { path = "./magicblock-metrics" }
Expand All @@ -122,10 +118,29 @@ magicblock-processor = { path = "./magicblock-processor" }
magicblock-program = { path = "./programs/magicblock" }
magicblock-pubsub = { path = "./magicblock-pubsub" }
magicblock-rpc = { path = "./magicblock-rpc" }
magicblock-rpc-client = { path = "./magicblock-rpc-client" }
magicblock-table-mania = { path = "./magicblock-table-mania" }
magicblock-tokens = { path = "./magicblock-tokens" }
magicblock-transaction-status = { path = "./magicblock-transaction-status" }
magicblock-version = { path = "./magicblock-version" }
num-derive = "0.4"
num-format = "0.4.4"
num-traits = "0.2"
num_cpus = "1.16.0"
paste = "1.0"
prometheus = "0.13.4"
# Needs to match https://crates.io/crates/solana-storage-bigtable/2.1.13/dependencies
prost = "0.11.9"
protobuf-src = "1.1"
rand = "0.8.5"
rayon = "1.10.0"
rustc_version = "0.4"
rusqlite = { version = "0.34.0", features = ["bundled"] } # bundled sqlite 3.44
semver = "1.0.22"
serde = "1.0.217"
serde_derive = "1.0"
serde_json = "1.0"
sha3 = "0.10.8"
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "7bdfefc" }
solana-accounts-db = { version = "2.2" }
solana-account-decoder = { version = "2.2" }
Expand All @@ -142,33 +157,37 @@ solana-log-collector = { version = "2.2" }
solana-measure = { version = "2.2" }
solana-metrics = { version = "2.2" }
solana-perf = { version = "2.2" }
solana-program = "2.2"
solana-program-runtime = { version = "2.2" }
solana-program-test = "2.2"
solana-pubkey = { version = "2.2" }
solana-rayon-threadlimit = { version = "2.2" }
solana-pubsub-client = { version = "2.2" }
solana-rpc = "2.2"
solana-rpc-client = { version = "2.2" }
solana-rpc-client-api = { version = "2.2" }
solana-sdk = { version = "2.2" }
solana-svm = { version = "2.2", features = [ "dev-context-only-utils" ] }
solana-svm = { version = "2.2", features = ["dev-context-only-utils"] }
solana-svm-transaction = { version = "2.2" }
solana-storage-proto = { path = "storage-proto" }
solana-system-program = { version = "2.2" }
solana-timings = "2.2"
solana-transaction-status = { version = "2.2" }
solana-transaction-status-client-types = "2.2"
spl-token = "=7.0"
spl-token-2022 = "=6.0"
static_assertions = "1.1.0"
strum = "0.24"
strum_macros = "0.24"
tempfile = "3.10.1"
test-tools = { path = "./test-tools" }
test-tools-core = { path = "./test-tools-core" }
thiserror = "1.0.57"
toml = "0.8.13"
# Update solana-tokio patch below when updating this version
tokio = "1.0"
tokio-stream = "0.1.15"
tokio-util = "0.7.10"
toml = "0.8.13"
# Tonic version 11 conflicts with lower level deps of solana and 0.9.x is the last
# version that allows prost 0.11.x to be used
tonic = "0.9.2"
Expand All @@ -181,5 +200,5 @@ vergen = "8.3.1"
# some solana dependencies have solana-storage-proto as dependency
# we need to patch them with our version, because they use protobuf-src v1.1.0
# and we use protobuf-src v2.1.1. Otherwise compilation fails
solana-storage-proto = { path = "./storage-proto" }
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "7bdfefc" }
solana-storage-proto = { path = "./storage-proto" }
4 changes: 4 additions & 0 deletions magicblock-account-cloner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ magicblock-account-updates = { workspace = true }
magicblock-account-dumper = { workspace = true }
magicblock-accounts-api = { workspace = true }
magicblock-core = { workspace = true }
magicblock-committor-service = { workspace = true }
magicblock-metrics = { workspace = true }
magicblock-mutator = { workspace = true }
solana-sdk = { workspace = true }
Expand All @@ -25,3 +26,6 @@ thiserror = { workspace = true }
lru = "0.14"

[dev-dependencies]
magicblock-committor-service = { workspace = true, features = [
"dev-context-only-utils",
] }
20 changes: 19 additions & 1 deletion magicblock-account-cloner/src/account_cloner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ use futures_util::future::BoxFuture;
use magicblock_account_dumper::AccountDumperError;
use magicblock_account_fetcher::AccountFetcherError;
use magicblock_account_updates::AccountUpdatesError;
use magicblock_committor_service::error::CommittorServiceResult;
use magicblock_core::magic_program;
use solana_sdk::{clock::Slot, pubkey::Pubkey, signature::Signature};
use thiserror::Error;
use tokio::sync::oneshot::Sender;
use tokio::sync::oneshot::{self, Sender};

#[derive(Debug, Clone, Error)]
pub enum AccountClonerError {
Expand All @@ -30,6 +31,9 @@ pub enum AccountClonerError {
#[error(transparent)]
AccountDumperError(#[from] AccountDumperError),

#[error("CommittorSerivceError {0}")]
CommittorSerivceError(String),

#[error("ProgramDataDoesNotExist")]
ProgramDataDoesNotExist,

Expand Down Expand Up @@ -66,6 +70,20 @@ pub enum AccountClonerUnclonableReason {
DelegatedAccountsNotClonedWhileHydrating,
}

pub async fn map_committor_request_result<T>(
res: oneshot::Receiver<CommittorServiceResult<T>>,
) -> AccountClonerResult<T> {
res.await
.map_err(|err| {
// Send request error
AccountClonerError::CommittorSerivceError(format!("{:?}", err))
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
AccountClonerError::CommittorSerivceError(format!("{:?}", err))
AccountClonerError::CommittorSerivceError(format!("error sending request {err:?}"))

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
AccountClonerError::CommittorSerivceError(format!("{:?}", err))
AccountClonerError::CommittorSerivceError(format!("error sending request {err:?}"))
```suggestion
AccountClonerError::CommittorSerivceError(format!("{:?}", err))

})?
.map_err(|err| {
// Commit error
AccountClonerError::CommittorSerivceError(format!("{:?}", err))
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
AccountClonerError::CommittorSerivceError(format!("{:?}", err))
AccountClonerError::CommittorSerivceError(format!("error during commit {err:?}"))

})
}

#[derive(Debug, Clone)]
pub struct AccountClonerPermissions {
pub allow_cloning_refresh: bool,
Expand Down
6 changes: 4 additions & 2 deletions magicblock-account-cloner/src/remote_account_cloner_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use magicblock_account_dumper::AccountDumper;
use magicblock_account_fetcher::AccountFetcher;
use magicblock_account_updates::AccountUpdates;
use magicblock_accounts_api::InternalAccountProvider;
use magicblock_committor_service::ChangesetCommittor;
use solana_sdk::pubkey::Pubkey;
use tokio::sync::{mpsc::UnboundedSender, oneshot::channel};

Expand All @@ -25,14 +26,15 @@ pub struct RemoteAccountClonerClient {
}

impl RemoteAccountClonerClient {
pub fn new<IAP, AFE, AUP, ADU>(
worker: &RemoteAccountClonerWorker<IAP, AFE, AUP, ADU>,
pub fn new<IAP, AFE, AUP, ADU, CC>(
worker: &RemoteAccountClonerWorker<IAP, AFE, AUP, ADU, CC>,
) -> Self
where
IAP: InternalAccountProvider,
AFE: AccountFetcher,
AUP: AccountUpdates,
ADU: AccountDumper,
CC: ChangesetCommittor,
{
Self {
clone_request_sender: worker.get_clone_request_sender(),
Expand Down
39 changes: 28 additions & 11 deletions magicblock-account-cloner/src/remote_account_cloner_worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use magicblock_account_dumper::AccountDumper;
use magicblock_account_fetcher::AccountFetcher;
use magicblock_account_updates::{AccountUpdates, AccountUpdatesResult};
use magicblock_accounts_api::InternalAccountProvider;
use magicblock_committor_service::ChangesetCommittor;
use magicblock_metrics::metrics;
use magicblock_mutator::idl::{get_pubkey_anchor_idl, get_pubkey_shank_idl};
use solana_sdk::{
Expand All @@ -36,8 +37,8 @@ use tokio::{
use tokio_util::sync::CancellationToken;

use crate::{
AccountClonerError, AccountClonerListeners, AccountClonerOutput,
AccountClonerPermissions, AccountClonerResult,
map_committor_request_result, AccountClonerError, AccountClonerListeners,
AccountClonerOutput, AccountClonerPermissions, AccountClonerResult,
AccountClonerUnclonableReason, CloneOutputMap,
};

Expand Down Expand Up @@ -96,11 +97,12 @@ impl ValidatorStage {
}
}

pub struct RemoteAccountClonerWorker<IAP, AFE, AUP, ADU> {
pub struct RemoteAccountClonerWorker<IAP, AFE, AUP, ADU, CC> {
internal_account_provider: IAP,
account_fetcher: AFE,
account_updates: AUP,
account_dumper: ADU,
changeset_committor: Arc<CC>,
allowed_program_ids: Option<HashSet<Pubkey>>,
blacklisted_accounts: HashSet<Pubkey>,
payer_init_lamports: Option<u64>,
Expand All @@ -118,31 +120,33 @@ pub struct RemoteAccountClonerWorker<IAP, AFE, AUP, ADU> {
// SAFETY:
// we never keep references to monitored_accounts around,
// especially across await points, so this type is Send
unsafe impl<IAP, AFE, AUP, ADU> Send
for RemoteAccountClonerWorker<IAP, AFE, AUP, ADU>
unsafe impl<IAP, AFE, AUP, ADU, CC> Send
for RemoteAccountClonerWorker<IAP, AFE, AUP, ADU, CC>
{
}
// SAFETY:
// we never produce references to RefCell in monitored_accounts
// especially not across await points, so this type is Sync
unsafe impl<IAP, AFE, AUP, ADU> Sync
for RemoteAccountClonerWorker<IAP, AFE, AUP, ADU>
unsafe impl<IAP, AFE, AUP, ADU, CC> Sync
for RemoteAccountClonerWorker<IAP, AFE, AUP, ADU, CC>
{
}

impl<IAP, AFE, AUP, ADU> RemoteAccountClonerWorker<IAP, AFE, AUP, ADU>
impl<IAP, AFE, AUP, ADU, CC> RemoteAccountClonerWorker<IAP, AFE, AUP, ADU, CC>
where
IAP: InternalAccountProvider,
AFE: AccountFetcher,
AUP: AccountUpdates,
ADU: AccountDumper,
CC: ChangesetCommittor,
{
#[allow(clippy::too_many_arguments)]
pub fn new(
internal_account_provider: IAP,
account_fetcher: AFE,
account_updates: AUP,
account_dumper: ADU,
changeset_committor: Arc<CC>,
allowed_program_ids: Option<HashSet<Pubkey>>,
blacklisted_accounts: HashSet<Pubkey>,
payer_init_lamports: Option<u64>,
Expand All @@ -162,6 +166,7 @@ where
account_fetcher,
account_updates,
account_dumper,
changeset_committor,
allowed_program_ids,
blacklisted_accounts,
payer_init_lamports,
Expand Down Expand Up @@ -289,7 +294,7 @@ where
let stream = stream::iter(account_keys);
// NOTE: depending on the RPC provider we may get rate limited if we request
// account states at a too high rate.
// I confirmed the the following concurrency working fine:
// I confirmed the following concurrency working fine:
// Solana Mainnet: 10
// Helius: 20
// If we go higher than this we hit 429s which causes the fetcher to have to
Expand Down Expand Up @@ -708,15 +713,27 @@ where
});
}

self.do_clone_delegated_account(
let sig = self.do_clone_delegated_account(
pubkey,
// TODO(GabrielePicco): Avoid cloning
&Account {
lamports: delegation_record.lamports,
..account.clone()
},
delegation_record,
)?
)?;

// Allow the committer service to reserve pubkeys in lookup tables
// that could be needed when we commit this account
map_committor_request_result(
self.changeset_committor.reserve_pubkeys_for_committee(
*pubkey,
delegation_record.owner,
),
)
.await?;

sig
}
};
// Return the result
Expand Down
Loading