use {
ephemeral_rollups_sdk::{
access_control::structs::EphemeralPermission, consts::PERMISSION_PROGRAM_ID,
},
magicsvm::{MagicSVM, TransactionTarget},
solana_address::Address,
solana_keypair::Keypair,
solana_signer::Signer,
};
const MEMBER_SIZE: usize = 33;
fn permission_account(
permissioned_account: Address,
private: bool,
members: &[Address],
) -> magicblock_account::Account {
let mut data = vec![0u8; 35 + members.len() * MEMBER_SIZE];
data[0] = 1;
data[2..34].copy_from_slice(permissioned_account.as_ref());
data[34] = u8::from(private);
for (index, member) in members.iter().enumerate() {
let offset = 35 + index * MEMBER_SIZE;
data[offset] = 1;
data[offset + 1..offset + 33].copy_from_slice(member.as_ref());
}
magicblock_account::Account {
lamports: 1_000_000,
data,
owner: PERMISSION_PROGRAM_ID,
executable: false,
rent_epoch: 0,
}
}
fn secret_account() -> magicblock_account::Account {
magicblock_account::Account {
lamports: 1_000_000,
data: vec![7, 8, 9],
owner: Address::new_from_array([9; 32]),
executable: false,
rent_epoch: 0,
}
}
fn put_ephemeral_account(
svm: &mut MagicSVM,
address: Address,
account: magicblock_account::Account,
) {
svm.ephemeral_mut().set_account(address, account).unwrap();
}
#[test_log::test]
fn private_account_is_hidden_until_authorized_user_is_a_member() {
let member = Keypair::new().pubkey();
let stranger = Keypair::new().pubkey();
let secret = Address::new_from_array([3; 32]);
let (permission_pda, _) = EphemeralPermission::find_pda(&secret);
let mut svm = MagicSVM::new();
put_ephemeral_account(&mut svm, secret, secret_account());
put_ephemeral_account(
&mut svm,
permission_pda,
permission_account(secret, true, &[member]),
);
assert!(svm
.get_account_for(TransactionTarget::Ephemeral, &secret)
.is_none());
svm.set_authorized_user(Some(stranger));
assert!(svm
.get_account_for(TransactionTarget::Ephemeral, &secret)
.is_none());
svm.set_authorized_user(Some(member));
let visible = svm
.get_account_for(TransactionTarget::Ephemeral, &secret)
.unwrap();
assert_eq!(visible.data, vec![7, 8, 9]);
svm.set_authorized_user(None);
assert!(svm
.get_account_for(TransactionTarget::Ephemeral, &secret)
.is_none());
}
#[test_log::test]
fn public_permission_does_not_hide_ephemeral_accounts() {
let secret = Address::new_from_array([4; 32]);
let (permission_pda, _) = EphemeralPermission::find_pda(&secret);
let mut svm = MagicSVM::new();
put_ephemeral_account(&mut svm, secret, secret_account());
put_ephemeral_account(
&mut svm,
permission_pda,
permission_account(secret, false, &[]),
);
let visible = svm
.get_account_for(TransactionTarget::Ephemeral, &secret)
.unwrap();
assert_eq!(visible.data, vec![7, 8, 9]);
}
#[test_log::test]
fn authorized_user_does_not_filter_base_accounts() {
let member = Keypair::new().pubkey();
let secret = Address::new_from_array([5; 32]);
let (permission_pda, _) = EphemeralPermission::find_pda(&secret);
let mut svm = MagicSVM::new();
svm.set_account(
secret,
solana_account::Account {
lamports: 1_000_000,
data: vec![7, 8, 9],
owner: Address::new_from_array([9; 32]),
executable: false,
rent_epoch: 0,
},
)
.unwrap();
put_ephemeral_account(
&mut svm,
permission_pda,
permission_account(secret, true, &[member]),
);
assert!(svm
.get_account_for(TransactionTarget::Base, &secret)
.is_some());
}
#[test_log::test]
fn magic_svm_loads_permission_program_on_ephemeral() {
let svm = MagicSVM::new();
let program = svm.ephemeral().get_account(&PERMISSION_PROGRAM_ID).unwrap();
assert!(program.executable);
}