magicblock_account/
patch.rs1use core::fmt;
2
3use solana_clock::Slot;
4use solana_pubkey::Pubkey;
5
6use crate::{AccountMode, AccountSharedData, OwnedAccount, WritableAccount};
7
8const MAX_DATA_CHUNK_SIZE: usize = (u16::MAX - 256) as usize;
9
10#[derive(Clone, Copy, Debug, Eq, PartialEq, thiserror::Error)]
12pub enum AccountPatchError {
13 #[error("invalid account mode transition: {from:?} -> {to:?}")]
15 InvalidModeTransition {
16 from: AccountMode,
18 to: AccountMode,
20 },
21 #[error("invalid account slot transition: {from} -> {to}")]
23 InvalidSlotTransition {
24 from: Slot,
26 to: Slot,
28 },
29}
30
31#[cfg_attr(feature = "wincode", derive(wincode::SchemaRead, wincode::SchemaWrite))]
33pub enum AccountFieldPatch {
34 Lamports(u64),
36 Owner(Pubkey),
38 DataAt {
40 offset: usize,
42 data: Vec<u8>,
44 },
45 Lifecycle {
47 mode: AccountMode,
49 slot: Slot,
51 },
52 DataLen(usize),
54}
55
56impl AccountFieldPatch {
57 pub fn apply(self, account: &mut AccountSharedData) -> Result<(), AccountPatchError> {
63 match self {
64 Self::Lamports(v) => account.set_lamports(v),
65 Self::Owner(v) => account.set_owner(v),
66 Self::Lifecycle { mode, slot } => return account.set_lifecycle(mode, slot),
67 Self::DataAt { offset, data } => account.set_data_at(offset, &data),
68 Self::DataLen(len) => account.resize(len, 0),
69 }
70 Ok(())
71 }
72
73 pub fn sequence(account: OwnedAccount) -> Vec<Self> {
77 let mut sequence = Vec::with_capacity(5);
78 sequence.push(Self::Lamports(account.core.lamports));
79 sequence.push(Self::Lifecycle {
80 mode: account.core.mode,
81 slot: account.core.slot,
82 });
83 sequence.push(Self::Owner(account.core.owner));
84 sequence.push(Self::DataLen(account.data.len()));
85 let mut offset = 0;
86 for data in account.data.chunks(MAX_DATA_CHUNK_SIZE) {
87 sequence.push(Self::DataAt { offset, data: data.into() });
88 offset += data.len();
89 }
90 sequence
91 }
92}
93
94impl fmt::Debug for AccountFieldPatch {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self {
99 Self::Lamports(v) => write!(f, "lamports={v}"),
100 Self::Owner(v) => write!(f, "owner={v}"),
101 Self::Lifecycle { mode, slot } => write!(f, "lifecycle={mode:?}@{slot}"),
102 Self::DataAt { offset, data } => write!(f, "data@{offset}+{}", data.len()),
103 Self::DataLen(len) => write!(f, "data_len={len}"),
104 }
105 }
106}