Skip to content
Open
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
38 changes: 19 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions magicblock-account-cloner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ magicblock-ledger = { workspace = true }
magicblock-program = { workspace = true }
magicblock-magic-program-api = { workspace = true }
magicblock-rpc-client = { workspace = true }
rand = { workspace = true }
solana-instruction = { workspace = true }
solana-sdk = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
Expand Down
103 changes: 76 additions & 27 deletions magicblock-account-cloner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use magicblock_accounts_db::AccountsDb;
use magicblock_chainlink::{
cloner::{
errors::{ClonerError, ClonerResult},
Cloner,
AccountCloneRequest, Cloner,
},
remote_account_provider::program_account::{
DeployableV4Program, LoadedProgram, RemoteProgramLoader,
Expand All @@ -24,15 +24,22 @@ use magicblock_core::link::transactions::TransactionSchedulerHandle;
use magicblock_ledger::LatestBlock;
use magicblock_magic_program_api::instruction::AccountModification;
use magicblock_program::{
instruction_utils::InstructionUtils, validator::validator_authority,
args::ScheduleTaskArgs,
instruction::MagicBlockInstruction,
instruction_utils::InstructionUtils,
validator::{validator_authority, validator_authority_id},
MAGIC_CONTEXT_PUBKEY,
};
use solana_instruction::Instruction;
use solana_sdk::{
account::{AccountSharedData, ReadableAccount},
account::ReadableAccount,
hash::Hash,
instruction::AccountMeta,
loader_v4,
pubkey::Pubkey,
rent::Rent,
signature::{Signature, Signer},
signer::SignerError,
transaction::Transaction,
};
use tokio::sync::oneshot;
Expand Down Expand Up @@ -81,23 +88,63 @@ impl ChainlinkCloner {

fn transaction_to_clone_regular_account(
&self,
pubkey: &Pubkey,
account: &AccountSharedData,
request: &AccountCloneRequest,
recent_blockhash: Hash,
) -> Transaction {
) -> Result<Transaction, SignerError> {
let account_modification = AccountModification {
pubkey: *pubkey,
lamports: Some(account.lamports()),
owner: Some(*account.owner()),
rent_epoch: Some(account.rent_epoch()),
data: Some(account.data().to_owned()),
executable: Some(account.executable()),
delegated: Some(account.delegated()),
pubkey: request.pubkey,
lamports: Some(request.account.lamports()),
owner: Some(*request.account.owner()),
rent_epoch: Some(request.account.rent_epoch()),
data: Some(request.account.data().to_owned()),
executable: Some(request.account.executable()),
delegated: Some(request.account.delegated()),
};
InstructionUtils::modify_accounts(
vec![account_modification],
recent_blockhash,
)

let modify_ix = InstructionUtils::modify_accounts_instruction(vec![
account_modification,
]);
// Defined positive commit frequency means commits should be scheduled
let ixs = match request.commit_frequency_ms {
Some(commit_frequency_ms) if commit_frequency_ms > 0 => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like defensive programming, why not just use plain u64 instead of redundant Option wrapping, and treat u64::MIN as a condition?

// The task ID is randomly generated to avoid conflicts with other tasks
// TODO: remove once the program handles generating tasks instead of the client
// https://github.com/magicblock-labs/magicblock-validator/issues/625
let task_id = rand::random();
let schedule_commit_ix = Instruction::new_with_bincode(
magicblock_program::ID,
&MagicBlockInstruction::ScheduleCommit,
vec![
AccountMeta::new(validator_authority_id(), true),
AccountMeta::new(MAGIC_CONTEXT_PUBKEY, false),
AccountMeta::new_readonly(request.pubkey, false),
],
);
let crank_commits_ix =
InstructionUtils::schedule_task_instruction(
&validator_authority_id(),
ScheduleTaskArgs {
task_id,
execution_interval_millis: commit_frequency_ms
as i64,
iterations: i64::MAX,
instructions: vec![schedule_commit_ix.clone()],
},
&[
request.pubkey,
MAGIC_CONTEXT_PUBKEY,
validator_authority_id(),
],
);
vec![modify_ix, crank_commits_ix]
}
_ => vec![modify_ix],
};

let mut tx =
Transaction::new_with_payer(&ixs, Some(&validator_authority_id()));
tx.try_sign(&[&validator_authority()], recent_blockhash)?;
Ok(tx)
}

/// Creates a transaction to clone the given program into the validator.
Expand Down Expand Up @@ -319,20 +366,22 @@ impl ChainlinkCloner {
impl Cloner for ChainlinkCloner {
async fn clone_account(
&self,
pubkey: Pubkey,
account: AccountSharedData,
request: AccountCloneRequest,
) -> ClonerResult<Signature> {
let recent_blockhash = self.block.load().blockhash;
let tx = self.transaction_to_clone_regular_account(
&pubkey,
&account,
recent_blockhash,
);
if account.delegated() {
self.maybe_prepare_lookup_tables(pubkey, *account.owner());
let tx = self
.transaction_to_clone_regular_account(&request, recent_blockhash)?;
if request.account.delegated() {
self.maybe_prepare_lookup_tables(
request.pubkey,
*request.account.owner(),
);
}
self.send_transaction(tx).await.map_err(|err| {
ClonerError::FailedToCloneRegularAccount(pubkey, Box::new(err))
ClonerError::FailedToCloneRegularAccount(
request.pubkey,
Box::new(err),
)
})
}

Expand Down
3 changes: 2 additions & 1 deletion magicblock-chainlink/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ lru = { workspace = true }
magicblock-core = { workspace = true }
magicblock-magic-program-api = { workspace = true }
magicblock-metrics = { workspace = true }
magicblock-delegation-program = { workspace = true }
magicblock-delegation-program = { workspace = true }
serde_json = { workspace = true }
solana-account = { workspace = true }
solana-account-decoder = { workspace = true }
Expand All @@ -27,6 +27,7 @@ solana-rpc-client = { workspace = true }
solana-rpc-client-api = { workspace = true }
solana-sdk = { workspace = true }
solana-sdk-ids = { workspace = true }
solana-signer = { workspace = true }
solana-system-interface = { workspace = true }
solana-transaction-error = { workspace = true }
thiserror = { workspace = true }
Expand Down
Loading
Loading