Skip to content

Commit c313cf4

Browse files
committed
Improve duplicated test
1 parent 4132740 commit c313cf4

File tree

1 file changed

+57
-35
lines changed
  • sdk/pinocchio/src/entrypoint

1 file changed

+57
-35
lines changed

sdk/pinocchio/src/entrypoint/mod.rs

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -782,9 +782,9 @@ mod tests {
782782
/// duplicated accounts, and instruction data.
783783
///
784784
/// This function differs from `create_input` in that it creates accounts
785-
/// with a marker indicating that they are duplicated. There is only a single
786-
/// unique account - the first one - and all subsequent accounts
787-
/// are marked as duplicated.
785+
/// with a marker indicating that they are duplicated. There will be
786+
/// `accounts - duplicated` unique accounts, and the remaining `duplicated`
787+
/// accounts will be duplicates of the last unique account.
788788
///
789789
/// This function mimics the input buffer created by the SVM loader.
790790
/// Each account created has zeroed data, apart from the `data_len`
@@ -797,30 +797,37 @@ mod tests {
797797
unsafe fn create_input_with_duplicates(
798798
accounts: usize,
799799
instruction_data: &[u8],
800-
account_len: usize,
800+
duplicated: usize,
801801
) -> AlignedMemory {
802802
let mut input = AlignedMemory::new(1_000_000_000);
803803
// Number of accounts.
804804
input.write(&(accounts as u64).to_le_bytes(), 0);
805805
let mut offset = size_of::<u64>();
806806

807807
if accounts > 0 {
808-
// Account data.
809-
let mut account = [0u8; STATIC_ACCOUNT_DATA + size_of::<u64>()];
810-
account[0] = NON_DUP_MARKER;
811-
// Set the accounts data length. The actual account data is zeroed.
812-
account[80..88].copy_from_slice(&account_len.to_le_bytes());
813-
input.write(&account, offset);
814-
offset += account.len();
815-
// Padding for the account data to align to `BPF_ALIGN_OF_U128`.
816-
let padding_for_data =
817-
(account_len + (BPF_ALIGN_OF_U128 - 1)) & !(BPF_ALIGN_OF_U128 - 1);
818-
input.write(&vec![0u8; padding_for_data], offset);
819-
offset += padding_for_data;
808+
assert!(
809+
duplicated < accounts,
810+
"Duplicated accounts must be less than total accounts"
811+
);
812+
let unique = accounts - duplicated;
813+
814+
for i in 0..unique {
815+
// Account data.
816+
let mut account = [0u8; STATIC_ACCOUNT_DATA + size_of::<u64>()];
817+
account[0] = NON_DUP_MARKER;
818+
// Set the accounts data length. The actual account data is zeroed.
819+
account[80..88].copy_from_slice(&i.to_le_bytes());
820+
input.write(&account, offset);
821+
offset += account.len();
822+
// Padding for the account data to align to `BPF_ALIGN_OF_U128`.
823+
let padding_for_data = (i + (BPF_ALIGN_OF_U128 - 1)) & !(BPF_ALIGN_OF_U128 - 1);
824+
input.write(&vec![0u8; padding_for_data], offset);
825+
offset += padding_for_data;
826+
}
820827

821-
// Remaining accounts are duplicated of the first one (index 0)
822-
for _ in 1..accounts {
823-
input.write(&[0u8; 8], offset);
828+
// Remaining accounts are duplicated of the last unique account.
829+
for _ in unique..accounts {
830+
input.write(&[(unique - 1) as u8, 0, 0, 0, 0, 0, 0, 0], offset);
824831
offset += size_of::<u64>();
825832
}
826833
}
@@ -848,14 +855,25 @@ mod tests {
848855

849856
/// Asserts that the accounts slice contains the expected number of accounts
850857
/// and all accounts are duplicated, apart from the first one.
851-
fn assert_duplicated_accounts(accounts: &[MaybeUninit<AccountInfo>]) {
852-
assert!(!accounts.is_empty());
853-
let first_account = unsafe { accounts[0].assume_init_ref() };
858+
fn assert_duplicated_accounts(accounts: &[MaybeUninit<AccountInfo>], duplicated: usize) {
859+
assert!(accounts.len() > duplicated);
860+
861+
let unique = accounts.len() - duplicated;
862+
863+
// Unique accounts should have `data_len` equal to their index.
864+
for (i, account) in accounts[..unique].iter().enumerate() {
865+
let account_info = unsafe { account.assume_init_ref() };
866+
assert_eq!(account_info.data_len(), i);
867+
}
854868

855-
for account in accounts[1..].iter() {
869+
// Duplicated accounts should have the same `data_len` as the
870+
// last unique account.
871+
for account in accounts[unique..].iter() {
856872
let account_info = unsafe { account.assume_init_ref() };
857-
assert_eq!(account_info.raw, first_account.raw);
858-
assert_eq!(account_info.data_len(), first_account.data_len());
873+
let duplicated = unsafe { accounts[unique - 1].assume_init_ref() };
874+
875+
assert_eq!(account_info.raw, duplicated.raw);
876+
assert_eq!(account_info.data_len(), duplicated.data_len());
859877
}
860878
}
861879

@@ -910,7 +928,7 @@ mod tests {
910928

911929
// Input with 0 accounts.
912930

913-
let mut input = unsafe { create_input_with_duplicates(0, &ix_data, 50) };
931+
let mut input = unsafe { create_input_with_duplicates(0, &ix_data, 0) };
914932
let mut accounts = [UNINIT; 1];
915933

916934
let (program_id, count, parsed_ix_data) =
@@ -921,23 +939,27 @@ mod tests {
921939
assert_eq!(&ix_data, parsed_ix_data);
922940

923941
// Input with 3 (1 + 2 duplicated) accounts but the accounts array has only
924-
// space for 1.
942+
// space for 2. The assert checks that the second account is a duplicate of
943+
// the first one and the first one is unique.
925944

926-
let mut input = unsafe { create_input_with_duplicates(3, &ix_data, 50) };
927-
let mut accounts = [UNINIT; 1];
945+
let mut input = unsafe { create_input_with_duplicates(3, &ix_data, 2) };
946+
let mut accounts = [UNINIT; 2];
928947

929948
let (program_id, count, parsed_ix_data) =
930949
unsafe { deserialize(input.as_mut_ptr(), &mut accounts) };
931950

932-
assert_eq!(count, 1);
951+
assert_eq!(count, 2);
933952
assert_eq!(program_id, &MOCK_PROGRAM_ID);
934953
assert_eq!(&ix_data, parsed_ix_data);
935-
assert_duplicated_accounts(&accounts[..count]);
954+
assert_duplicated_accounts(&accounts[..count], 1);
936955

937-
// Input with `MAX_TX_ACCOUNTS` (1 + remaining duplicated) accounts but accounts
938-
// array has only space for 64.
956+
// Input with `MAX_TX_ACCOUNTS` accounts (only 32 unique ones) but accounts
957+
// array has only space for 64. The assert checks that the first 32 accounts
958+
// are unique and the rest are duplicates of the account at index 31.
939959

940-
let mut input = unsafe { create_input_with_duplicates(MAX_TX_ACCOUNTS, &ix_data, 50) };
960+
let mut input = unsafe {
961+
create_input_with_duplicates(MAX_TX_ACCOUNTS, &ix_data, MAX_TX_ACCOUNTS - 32)
962+
};
941963
let mut accounts = [UNINIT; 64];
942964

943965
let (program_id, count, parsed_ix_data) =
@@ -946,6 +968,6 @@ mod tests {
946968
assert_eq!(count, 64);
947969
assert_eq!(program_id, &MOCK_PROGRAM_ID);
948970
assert_eq!(&ix_data, parsed_ix_data);
949-
assert_duplicated_accounts(&accounts);
971+
assert_duplicated_accounts(&accounts, 32);
950972
}
951973
}

0 commit comments

Comments
 (0)