Skip to content

Commit

Permalink
💚 Add support for composite accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
lukacan committed Jan 13, 2025
1 parent 0f05457 commit 03756e2
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ incremented upon a breaking change and the patch version will be incremented for

**Added**

- added support for composite accounts ([245](https://github.com/Ackee-Blockchain/trident/pull/245))
- Trident SVM + AFL (see the PR for more details) ([234](https://github.com/Ackee-Blockchain/trident/pull/234))

**Removed**
Expand Down
72 changes: 71 additions & 1 deletion crates/client/tests/anchor_idl/idl_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,26 @@
108
],
"accounts": [
{
"name": "composite_account_nested",
"accounts": [
{
"name": "some_account"
},
{
"name": "nested_inner",
"accounts": [
{
"name": "some_account"
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
]
}
]
},
{
"name": "signer",
"signer": true
Expand All @@ -41,6 +61,21 @@
},
{
"name": "data_account_6"
},
{
"name": "composite_account",
"accounts": [
{
"name": "some_account"
},
{
"name": "signer",
"signer": true
},
{
"name": "data_account_1"
}
]
}
],
"args": [
Expand Down Expand Up @@ -167,6 +202,26 @@
246
],
"accounts": [
{
"name": "composite_account_nested",
"accounts": [
{
"name": "some_account"
},
{
"name": "nested_inner",
"accounts": [
{
"name": "some_account"
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
]
}
]
},
{
"name": "signer",
"signer": true
Expand All @@ -188,6 +243,21 @@
},
{
"name": "data_account_6"
},
{
"name": "composite_account",
"accounts": [
{
"name": "some_account"
},
{
"name": "signer",
"signer": true
},
{
"name": "data_account_1"
}
]
}
],
"args": [
Expand Down Expand Up @@ -832,4 +902,4 @@
}
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ pub struct ProcessCustomTypes {
}
#[derive(Arbitrary, Debug)]
pub struct ProcessCustomTypesAccounts {
pub some_account: AccountId,
pub some_account: AccountId,
pub signer: AccountId,
pub data_account_1: AccountId,
pub data_account_2: AccountId,
pub data_account_3: AccountId,
pub data_account_4: AccountId,
pub data_account_5: AccountId,
pub data_account_6: AccountId,
pub some_account: AccountId,
pub signer: AccountId,
pub data_account_1: AccountId,
}
/// Custom data types must derive `Debug` and `Arbitrary`.
/// To do this, redefine the type in the fuzz test and implement the `From`
Expand Down Expand Up @@ -50,13 +55,18 @@ pub struct ProcessRustTypes {
}
#[derive(Arbitrary, Debug)]
pub struct ProcessRustTypesAccounts {
pub some_account: AccountId,
pub some_account: AccountId,
pub signer: AccountId,
pub data_account_1: AccountId,
pub data_account_2: AccountId,
pub data_account_3: AccountId,
pub data_account_4: AccountId,
pub data_account_5: AccountId,
pub data_account_6: AccountId,
pub some_account: AccountId,
pub signer: AccountId,
pub data_account_1: AccountId,
}
/// Custom data types must derive `Debug` and `Arbitrary`.
/// To do this, redefine the type in the fuzz test and implement the `From`
Expand Down Expand Up @@ -167,6 +177,20 @@ impl IxOps for ProcessCustomTypes {
) -> Result<(Vec<Keypair>, Vec<AccountMeta>), FuzzingError> {
let mut account_metas = vec![];
let mut signers = vec![];
{
let some_account = todo!();
account_metas.push(todo!());
}
{
let some_account = todo!();
account_metas.push(todo!());
}
{
account_metas.push(AccountMeta::new_readonly(
pubkey!("11111111111111111111111111111111"),
false,
));
}
{
let signer = fuzz_accounts.signer.get_or_create_account(
self.accounts.signer,
Expand Down Expand Up @@ -200,6 +224,23 @@ impl IxOps for ProcessCustomTypes {
let data_account_6 = todo!();
account_metas.push(todo!());
}
{
let some_account = todo!();
account_metas.push(todo!());
}
{
let signer = fuzz_accounts.signer.get_or_create_account(
self.accounts.signer,
client,
500 * LAMPORTS_PER_SOL,
);
account_metas.push(AccountMeta::new_readonly(signer.pubkey(), true));
signers.push(signer.insecure_clone());
}
{
let data_account_1 = todo!();
account_metas.push(todo!());
}
Ok((signers, account_metas))
}
}
Expand Down Expand Up @@ -284,6 +325,20 @@ impl IxOps for ProcessRustTypes {
) -> Result<(Vec<Keypair>, Vec<AccountMeta>), FuzzingError> {
let mut account_metas = vec![];
let mut signers = vec![];
{
let some_account = todo!();
account_metas.push(todo!());
}
{
let some_account = todo!();
account_metas.push(todo!());
}
{
account_metas.push(AccountMeta::new_readonly(
pubkey!("11111111111111111111111111111111"),
false,
));
}
{
let signer = fuzz_accounts.signer.get_or_create_account(
self.accounts.signer,
Expand Down Expand Up @@ -317,6 +372,23 @@ impl IxOps for ProcessRustTypes {
let data_account_6 = todo!();
account_metas.push(todo!());
}
{
let some_account = todo!();
account_metas.push(todo!());
}
{
let signer = fuzz_accounts.signer.get_or_create_account(
self.accounts.signer,
client,
500 * LAMPORTS_PER_SOL,
);
account_metas.push(AccountMeta::new_readonly(signer.pubkey(), true));
signers.push(signer.insecure_clone());
}
{
let data_account_1 = todo!();
account_metas.push(todo!());
}
Ok((signers, account_metas))
}
}
Expand Down Expand Up @@ -370,6 +442,7 @@ pub struct FuzzAccounts {
data_account_5: AccountsStorage<todo!()>,
data_account_6: AccountsStorage<todo!()>,
signer: AccountsStorage<KeypairStore>,
some_account: AccountsStorage<todo!()>,
}
#[derive(Arbitrary, Debug, BorshDeserialize, BorshSerialize, Clone)]
pub struct ClassicStruct {
Expand Down
35 changes: 29 additions & 6 deletions crates/template/src/fuzz_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ pub(crate) fn get_fuzz_accounts(
.fold(&mut fuzz_accounts, |fuzz_accounts, account| {
match account {
IdlInstructionAccountItem::Composite(idl_instruction_accounts) => {
process_composite_account(idl_instruction_accounts);
process_composite_account(
idl_instruction_accounts,
fuzz_accounts,
instructions_accounts,
);
}
IdlInstructionAccountItem::Single(idl_instruction_account) => {
process_single_account(
Expand All @@ -48,11 +52,30 @@ pub(crate) fn get_fuzz_accounts(
sorted_accounts.into_iter().map(|(_, v)| v).collect()
}

fn process_composite_account(idl_instruction_accounts: &IdlInstructionAccounts) {
panic!(
"Composite accounts not supported. Composite account with name {} found",
idl_instruction_accounts.name
)
fn process_composite_account(
idl_instruction_accounts: &IdlInstructionAccounts,
fuzz_accounts: &mut HashMap<syn::Ident, syn::FnArg>,
instructions_accounts: &HashMap<String, InstructionAccount>,
) {
for account in &idl_instruction_accounts.accounts {
match account {
IdlInstructionAccountItem::Single(idl_instruction_account) => {
process_single_account(
idl_instruction_account,
fuzz_accounts,
instructions_accounts,
);
}
// This creates recursion, but there should not be infinite recursion
IdlInstructionAccountItem::Composite(idl_instruction_accounts) => {
process_composite_account(
idl_instruction_accounts,
fuzz_accounts,
instructions_accounts,
);
}
}
}
}

fn process_single_account(
Expand Down
43 changes: 33 additions & 10 deletions crates/template/src/fuzz_instructions_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,15 @@ fn get_instructions_accounts(idl: &Idl) -> HashMap<String, InstructionAccount> {
for account in &instruction.accounts {
match account {
IdlInstructionAccountItem::Composite(idl_instruction_accounts) => {
process_composite_account(idl_instruction_accounts)
process_composite_account(
&instruction.name,
idl_instruction_accounts,
&mut instruction_accounts,
);
}
IdlInstructionAccountItem::Single(idl_instruction_account) => {
process_single_account(
instruction.name.clone(),
&instruction.name,
idl_instruction_account,
&mut instruction_accounts,
);
Expand All @@ -86,15 +90,34 @@ fn get_instructions_accounts(idl: &Idl) -> HashMap<String, InstructionAccount> {
)
}

fn process_composite_account(idl_instruction_accounts: &IdlInstructionAccounts) {
panic!(
"Composite accounts not supported. Composite account with name {} found",
idl_instruction_accounts.name
)
fn process_composite_account(
instruction_name: &str,
idl_instruction_accounts: &IdlInstructionAccounts,
instruction_accounts: &mut HashMap<String, InstructionAccount>,
) {
for account in &idl_instruction_accounts.accounts {
match account {
IdlInstructionAccountItem::Single(idl_instruction_account) => {
process_single_account(
instruction_name,
idl_instruction_account,
instruction_accounts,
);
}
// This creates recursion, but there should not be infinite recursion
IdlInstructionAccountItem::Composite(idl_instruction_accounts) => {
process_composite_account(
instruction_name,
idl_instruction_accounts,
instruction_accounts,
);
}
}
}
}

fn process_single_account(
instruction_name: String,
instruction_name: &str,
idl_instruction_account: &IdlInstructionAccount,
instruction_accounts: &mut HashMap<String, InstructionAccount>,
) {
Expand All @@ -107,13 +130,13 @@ fn process_single_account(
let mut new_account = InstructionAccount::new(account_name.to_string());

// insert infor about current instruction and the account type within the instruction
new_account.insert(instruction_name, account_type);
new_account.insert(instruction_name.to_owned(), account_type);
entry.insert(new_account);
}
Entry::Occupied(mut entry) => {
// if there is an entry, insert infor about current instruction and the account type within the instruction
let account = entry.get_mut();
account.insert(instruction_name, account_type);
account.insert(instruction_name.to_owned(), account_type);
}
};
}
Expand Down
Loading

0 comments on commit 03756e2

Please sign in to comment.