Remove credit-only account handling (#6726)
* Renaming - credit-only/credit-debit to read-only/read-write - debitable to writable * Remove credit handling, making credit-only accounts read-only * Update programs to remove deprecated credit-only account designation * Use readonly and writable instead of underscored types
This commit is contained in:
		@@ -109,13 +109,11 @@ impl Account {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub type LamportCredit = u64;
 | 
			
		||||
 | 
			
		||||
#[repr(C)]
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct KeyedAccount<'a> {
 | 
			
		||||
    is_signer: bool, // Transaction was signed by this account's key
 | 
			
		||||
    is_debitable: bool,
 | 
			
		||||
    is_writable: bool,
 | 
			
		||||
    key: &'a Pubkey,
 | 
			
		||||
    pub account: &'a mut Account,
 | 
			
		||||
}
 | 
			
		||||
@@ -133,27 +131,27 @@ impl<'a> KeyedAccount<'a> {
 | 
			
		||||
        self.key
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn is_debitable(&self) -> bool {
 | 
			
		||||
        self.is_debitable
 | 
			
		||||
    pub fn is_writable(&self) -> bool {
 | 
			
		||||
        self.is_writable
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn new(key: &'a Pubkey, is_signer: bool, account: &'a mut Account) -> KeyedAccount<'a> {
 | 
			
		||||
        KeyedAccount {
 | 
			
		||||
            is_signer,
 | 
			
		||||
            is_debitable: true,
 | 
			
		||||
            is_writable: true,
 | 
			
		||||
            key,
 | 
			
		||||
            account,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn new_credit_only(
 | 
			
		||||
    pub fn new_readonly(
 | 
			
		||||
        key: &'a Pubkey,
 | 
			
		||||
        is_signer: bool,
 | 
			
		||||
        account: &'a mut Account,
 | 
			
		||||
    ) -> KeyedAccount<'a> {
 | 
			
		||||
        KeyedAccount {
 | 
			
		||||
            is_signer,
 | 
			
		||||
            is_debitable: false,
 | 
			
		||||
            is_writable: false,
 | 
			
		||||
            key,
 | 
			
		||||
            account,
 | 
			
		||||
        }
 | 
			
		||||
@@ -164,7 +162,7 @@ impl<'a> From<(&'a Pubkey, &'a mut Account)> for KeyedAccount<'a> {
 | 
			
		||||
    fn from((key, account): (&'a Pubkey, &'a mut Account)) -> Self {
 | 
			
		||||
        KeyedAccount {
 | 
			
		||||
            is_signer: false,
 | 
			
		||||
            is_debitable: true,
 | 
			
		||||
            is_writable: true,
 | 
			
		||||
            key,
 | 
			
		||||
            account,
 | 
			
		||||
        }
 | 
			
		||||
@@ -175,7 +173,7 @@ impl<'a> From<&'a mut (Pubkey, Account)> for KeyedAccount<'a> {
 | 
			
		||||
    fn from((key, account): &'a mut (Pubkey, Account)) -> Self {
 | 
			
		||||
        KeyedAccount {
 | 
			
		||||
            is_signer: false,
 | 
			
		||||
            is_debitable: true,
 | 
			
		||||
            is_writable: true,
 | 
			
		||||
            key,
 | 
			
		||||
            account,
 | 
			
		||||
        }
 | 
			
		||||
@@ -186,12 +184,12 @@ pub fn create_keyed_accounts(accounts: &mut [(Pubkey, Account)]) -> Vec<KeyedAcc
 | 
			
		||||
    accounts.iter_mut().map(Into::into).collect()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn create_keyed_credit_only_accounts(accounts: &mut [(Pubkey, Account)]) -> Vec<KeyedAccount> {
 | 
			
		||||
pub fn create_keyed_readonly_accounts(accounts: &mut [(Pubkey, Account)]) -> Vec<KeyedAccount> {
 | 
			
		||||
    accounts
 | 
			
		||||
        .iter_mut()
 | 
			
		||||
        .map(|(key, account)| KeyedAccount {
 | 
			
		||||
            is_signer: false,
 | 
			
		||||
            is_debitable: false,
 | 
			
		||||
            is_writable: false,
 | 
			
		||||
            key,
 | 
			
		||||
            account,
 | 
			
		||||
        })
 | 
			
		||||
 
 | 
			
		||||
@@ -52,11 +52,11 @@ pub enum InstructionError {
 | 
			
		||||
    /// Program modified the data of an account that doesn't belong to it
 | 
			
		||||
    ExternalAccountDataModified,
 | 
			
		||||
 | 
			
		||||
    /// Credit-only account spent lamports
 | 
			
		||||
    CreditOnlyLamportSpend,
 | 
			
		||||
    /// Read-only account modified lamports
 | 
			
		||||
    ReadonlyLamportChange,
 | 
			
		||||
 | 
			
		||||
    /// Credit-only account modified data
 | 
			
		||||
    CreditOnlyDataModified,
 | 
			
		||||
    /// Read-only account modified data
 | 
			
		||||
    ReadonlyDataModified,
 | 
			
		||||
 | 
			
		||||
    /// An account was referenced more than once in a single instruction
 | 
			
		||||
    DuplicateAccountIndex,
 | 
			
		||||
@@ -116,8 +116,8 @@ pub struct AccountMeta {
 | 
			
		||||
    pub pubkey: Pubkey,
 | 
			
		||||
    /// True if an Instruciton requires a Transaction signature matching `pubkey`.
 | 
			
		||||
    pub is_signer: bool,
 | 
			
		||||
    /// True if the `pubkey` can be loaded as a credit-debit account.
 | 
			
		||||
    pub is_debitable: bool,
 | 
			
		||||
    /// True if the `pubkey` can be loaded as a read-write account.
 | 
			
		||||
    pub is_writable: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl AccountMeta {
 | 
			
		||||
@@ -125,15 +125,15 @@ impl AccountMeta {
 | 
			
		||||
        Self {
 | 
			
		||||
            pubkey,
 | 
			
		||||
            is_signer,
 | 
			
		||||
            is_debitable: true,
 | 
			
		||||
            is_writable: true,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn new_credit_only(pubkey: Pubkey, is_signer: bool) -> Self {
 | 
			
		||||
    pub fn new_readonly(pubkey: Pubkey, is_signer: bool) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            pubkey,
 | 
			
		||||
            is_signer,
 | 
			
		||||
            is_debitable: false,
 | 
			
		||||
            is_writable: false,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,34 +30,34 @@ fn compile_instructions(ixs: Vec<Instruction>, keys: &[Pubkey]) -> Vec<CompiledI
 | 
			
		||||
        .collect()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// A helper struct to collect pubkeys referenced by a set of instructions and credit-only counts
 | 
			
		||||
/// A helper struct to collect pubkeys referenced by a set of instructions and read-only counts
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
struct InstructionKeys {
 | 
			
		||||
    pub signed_keys: Vec<Pubkey>,
 | 
			
		||||
    pub unsigned_keys: Vec<Pubkey>,
 | 
			
		||||
    pub num_credit_only_signed_accounts: u8,
 | 
			
		||||
    pub num_credit_only_unsigned_accounts: u8,
 | 
			
		||||
    pub num_readonly_signed_accounts: u8,
 | 
			
		||||
    pub num_readonly_unsigned_accounts: u8,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl InstructionKeys {
 | 
			
		||||
    fn new(
 | 
			
		||||
        signed_keys: Vec<Pubkey>,
 | 
			
		||||
        unsigned_keys: Vec<Pubkey>,
 | 
			
		||||
        num_credit_only_signed_accounts: u8,
 | 
			
		||||
        num_credit_only_unsigned_accounts: u8,
 | 
			
		||||
        num_readonly_signed_accounts: u8,
 | 
			
		||||
        num_readonly_unsigned_accounts: u8,
 | 
			
		||||
    ) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            signed_keys,
 | 
			
		||||
            unsigned_keys,
 | 
			
		||||
            num_credit_only_signed_accounts,
 | 
			
		||||
            num_credit_only_unsigned_accounts,
 | 
			
		||||
            num_readonly_signed_accounts,
 | 
			
		||||
            num_readonly_unsigned_accounts,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Return pubkeys referenced by all instructions, with the ones needing signatures first. If the
 | 
			
		||||
/// payer key is provided, it is always placed first in the list of signed keys. Credit-only signed
 | 
			
		||||
/// accounts are placed last in the set of signed accounts. Credit-only unsigned accounts,
 | 
			
		||||
/// payer key is provided, it is always placed first in the list of signed keys. Read-only signed
 | 
			
		||||
/// accounts are placed last in the set of signed accounts. Read-only unsigned accounts,
 | 
			
		||||
/// including program ids, are placed last in the set. No duplicates and order is preserved.
 | 
			
		||||
fn get_keys(instructions: &[Instruction], payer: Option<&Pubkey>) -> InstructionKeys {
 | 
			
		||||
    let programs: Vec<_> = get_program_ids(instructions)
 | 
			
		||||
@@ -65,7 +65,7 @@ fn get_keys(instructions: &[Instruction], payer: Option<&Pubkey>) -> Instruction
 | 
			
		||||
        .map(|program_id| AccountMeta {
 | 
			
		||||
            pubkey: *program_id,
 | 
			
		||||
            is_signer: false,
 | 
			
		||||
            is_debitable: false,
 | 
			
		||||
            is_writable: false,
 | 
			
		||||
        })
 | 
			
		||||
        .collect();
 | 
			
		||||
    let mut keys_and_signed: Vec<_> = instructions
 | 
			
		||||
@@ -76,7 +76,7 @@ fn get_keys(instructions: &[Instruction], payer: Option<&Pubkey>) -> Instruction
 | 
			
		||||
    keys_and_signed.sort_by(|x, y| {
 | 
			
		||||
        y.is_signer
 | 
			
		||||
            .cmp(&x.is_signer)
 | 
			
		||||
            .then(y.is_debitable.cmp(&x.is_debitable))
 | 
			
		||||
            .then(y.is_writable.cmp(&x.is_writable))
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let payer_account_meta;
 | 
			
		||||
@@ -84,33 +84,33 @@ fn get_keys(instructions: &[Instruction], payer: Option<&Pubkey>) -> Instruction
 | 
			
		||||
        payer_account_meta = AccountMeta {
 | 
			
		||||
            pubkey: *payer,
 | 
			
		||||
            is_signer: true,
 | 
			
		||||
            is_debitable: true,
 | 
			
		||||
            is_writable: true,
 | 
			
		||||
        };
 | 
			
		||||
        keys_and_signed.insert(0, &payer_account_meta);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mut signed_keys = vec![];
 | 
			
		||||
    let mut unsigned_keys = vec![];
 | 
			
		||||
    let mut num_credit_only_signed_accounts = 0;
 | 
			
		||||
    let mut num_credit_only_unsigned_accounts = 0;
 | 
			
		||||
    let mut num_readonly_signed_accounts = 0;
 | 
			
		||||
    let mut num_readonly_unsigned_accounts = 0;
 | 
			
		||||
    for account_meta in keys_and_signed.into_iter().unique_by(|x| x.pubkey) {
 | 
			
		||||
        if account_meta.is_signer {
 | 
			
		||||
            signed_keys.push(account_meta.pubkey);
 | 
			
		||||
            if !account_meta.is_debitable {
 | 
			
		||||
                num_credit_only_signed_accounts += 1;
 | 
			
		||||
            if !account_meta.is_writable {
 | 
			
		||||
                num_readonly_signed_accounts += 1;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            unsigned_keys.push(account_meta.pubkey);
 | 
			
		||||
            if !account_meta.is_debitable {
 | 
			
		||||
                num_credit_only_unsigned_accounts += 1;
 | 
			
		||||
            if !account_meta.is_writable {
 | 
			
		||||
                num_readonly_unsigned_accounts += 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    InstructionKeys::new(
 | 
			
		||||
        signed_keys,
 | 
			
		||||
        unsigned_keys,
 | 
			
		||||
        num_credit_only_signed_accounts,
 | 
			
		||||
        num_credit_only_unsigned_accounts,
 | 
			
		||||
        num_readonly_signed_accounts,
 | 
			
		||||
        num_readonly_unsigned_accounts,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -130,19 +130,19 @@ pub struct MessageHeader {
 | 
			
		||||
    /// NOTE: Serialization-related changes must be paired with the direct read at sigverify.
 | 
			
		||||
    pub num_required_signatures: u8,
 | 
			
		||||
 | 
			
		||||
    /// The last num_credit_only_signed_accounts of the signed keys are credit-only accounts.
 | 
			
		||||
    /// Programs may process multiple transactions that add lamports to the same credit-only
 | 
			
		||||
    /// account within a single PoH entry, but are not permitted to debit lamports or modify
 | 
			
		||||
    /// account data. Transactions targeting the same debit account are evaluated sequentially.
 | 
			
		||||
    pub num_credit_only_signed_accounts: u8,
 | 
			
		||||
    /// The last num_readonly_signed_accounts of the signed keys are read-only accounts. Programs
 | 
			
		||||
    /// may process multiple transactions that load read-only accounts within a single PoH entry,
 | 
			
		||||
    /// but are not permitted to credit or debit lamports or modify account data. Transactions
 | 
			
		||||
    /// targeting the same read-write account are evaluated sequentially.
 | 
			
		||||
    pub num_readonly_signed_accounts: u8,
 | 
			
		||||
 | 
			
		||||
    /// The last num_credit_only_unsigned_accounts of the unsigned keys are credit-only accounts.
 | 
			
		||||
    pub num_credit_only_unsigned_accounts: u8,
 | 
			
		||||
    /// The last num_readonly_unsigned_accounts of the unsigned keys are read-only accounts.
 | 
			
		||||
    pub num_readonly_unsigned_accounts: u8,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
 | 
			
		||||
pub struct Message {
 | 
			
		||||
    /// The message header, identifying signed and credit-only `account_keys`
 | 
			
		||||
    /// The message header, identifying signed and read-only `account_keys`
 | 
			
		||||
    /// NOTE: Serialization-related changes must be paired with the direct read at sigverify.
 | 
			
		||||
    pub header: MessageHeader,
 | 
			
		||||
 | 
			
		||||
@@ -162,8 +162,8 @@ pub struct Message {
 | 
			
		||||
impl Message {
 | 
			
		||||
    pub fn new_with_compiled_instructions(
 | 
			
		||||
        num_required_signatures: u8,
 | 
			
		||||
        num_credit_only_signed_accounts: u8,
 | 
			
		||||
        num_credit_only_unsigned_accounts: u8,
 | 
			
		||||
        num_readonly_signed_accounts: u8,
 | 
			
		||||
        num_readonly_unsigned_accounts: u8,
 | 
			
		||||
        account_keys: Vec<Pubkey>,
 | 
			
		||||
        recent_blockhash: Hash,
 | 
			
		||||
        instructions: Vec<CompiledInstruction>,
 | 
			
		||||
@@ -171,8 +171,8 @@ impl Message {
 | 
			
		||||
        Self {
 | 
			
		||||
            header: MessageHeader {
 | 
			
		||||
                num_required_signatures,
 | 
			
		||||
                num_credit_only_signed_accounts,
 | 
			
		||||
                num_credit_only_unsigned_accounts,
 | 
			
		||||
                num_readonly_signed_accounts,
 | 
			
		||||
                num_readonly_unsigned_accounts,
 | 
			
		||||
            },
 | 
			
		||||
            account_keys,
 | 
			
		||||
            recent_blockhash,
 | 
			
		||||
@@ -188,16 +188,16 @@ impl Message {
 | 
			
		||||
        let InstructionKeys {
 | 
			
		||||
            mut signed_keys,
 | 
			
		||||
            unsigned_keys,
 | 
			
		||||
            num_credit_only_signed_accounts,
 | 
			
		||||
            num_credit_only_unsigned_accounts,
 | 
			
		||||
            num_readonly_signed_accounts,
 | 
			
		||||
            num_readonly_unsigned_accounts,
 | 
			
		||||
        } = get_keys(&instructions, payer);
 | 
			
		||||
        let num_required_signatures = signed_keys.len() as u8;
 | 
			
		||||
        signed_keys.extend(&unsigned_keys);
 | 
			
		||||
        let instructions = compile_instructions(instructions, &signed_keys);
 | 
			
		||||
        Self::new_with_compiled_instructions(
 | 
			
		||||
            num_required_signatures,
 | 
			
		||||
            num_credit_only_signed_accounts,
 | 
			
		||||
            num_credit_only_unsigned_accounts,
 | 
			
		||||
            num_readonly_signed_accounts,
 | 
			
		||||
            num_readonly_unsigned_accounts,
 | 
			
		||||
            signed_keys,
 | 
			
		||||
            Hash::default(),
 | 
			
		||||
            instructions,
 | 
			
		||||
@@ -218,25 +218,25 @@ impl Message {
 | 
			
		||||
            .position(|&&pubkey| pubkey == self.account_keys[index])
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn is_debitable(&self, i: usize) -> bool {
 | 
			
		||||
        i < (self.header.num_required_signatures - self.header.num_credit_only_signed_accounts)
 | 
			
		||||
    pub fn is_writable(&self, i: usize) -> bool {
 | 
			
		||||
        i < (self.header.num_required_signatures - self.header.num_readonly_signed_accounts)
 | 
			
		||||
            as usize
 | 
			
		||||
            || (i >= self.header.num_required_signatures as usize
 | 
			
		||||
                && i < self.account_keys.len()
 | 
			
		||||
                    - self.header.num_credit_only_unsigned_accounts as usize)
 | 
			
		||||
                    - self.header.num_readonly_unsigned_accounts as usize)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_account_keys_by_lock_type(&self) -> (Vec<&Pubkey>, Vec<&Pubkey>) {
 | 
			
		||||
        let mut credit_debit_keys = vec![];
 | 
			
		||||
        let mut credit_only_keys = vec![];
 | 
			
		||||
        let mut writable_keys = vec![];
 | 
			
		||||
        let mut readonly_keys = vec![];
 | 
			
		||||
        for (i, key) in self.account_keys.iter().enumerate() {
 | 
			
		||||
            if self.is_debitable(i) {
 | 
			
		||||
                credit_debit_keys.push(key);
 | 
			
		||||
            if self.is_writable(i) {
 | 
			
		||||
                writable_keys.push(key);
 | 
			
		||||
            } else {
 | 
			
		||||
                credit_only_keys.push(key);
 | 
			
		||||
                readonly_keys.push(key);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        (credit_debit_keys, credit_only_keys)
 | 
			
		||||
        (writable_keys, readonly_keys)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -399,7 +399,7 @@ mod tests {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_message_credit_only_keys_last() {
 | 
			
		||||
    fn test_message_readonly_keys_last() {
 | 
			
		||||
        let program_id = Pubkey::default();
 | 
			
		||||
        let id0 = Pubkey::default(); // Identical key/program_id should be de-duped
 | 
			
		||||
        let id1 = Pubkey::new_rand();
 | 
			
		||||
@@ -407,16 +407,8 @@ mod tests {
 | 
			
		||||
        let id3 = Pubkey::new_rand();
 | 
			
		||||
        let keys = get_keys(
 | 
			
		||||
            &[
 | 
			
		||||
                Instruction::new(
 | 
			
		||||
                    program_id,
 | 
			
		||||
                    &0,
 | 
			
		||||
                    vec![AccountMeta::new_credit_only(id0, false)],
 | 
			
		||||
                ),
 | 
			
		||||
                Instruction::new(
 | 
			
		||||
                    program_id,
 | 
			
		||||
                    &0,
 | 
			
		||||
                    vec![AccountMeta::new_credit_only(id1, true)],
 | 
			
		||||
                ),
 | 
			
		||||
                Instruction::new(program_id, &0, vec![AccountMeta::new_readonly(id0, false)]),
 | 
			
		||||
                Instruction::new(program_id, &0, vec![AccountMeta::new_readonly(id1, true)]),
 | 
			
		||||
                Instruction::new(program_id, &0, vec![AccountMeta::new(id2, false)]),
 | 
			
		||||
                Instruction::new(program_id, &0, vec![AccountMeta::new(id3, true)]),
 | 
			
		||||
            ],
 | 
			
		||||
@@ -484,16 +476,8 @@ mod tests {
 | 
			
		||||
        let id1 = Pubkey::new_rand();
 | 
			
		||||
        let keys = get_keys(
 | 
			
		||||
            &[
 | 
			
		||||
                Instruction::new(
 | 
			
		||||
                    program_id,
 | 
			
		||||
                    &0,
 | 
			
		||||
                    vec![AccountMeta::new_credit_only(id0, false)],
 | 
			
		||||
                ),
 | 
			
		||||
                Instruction::new(
 | 
			
		||||
                    program_id,
 | 
			
		||||
                    &0,
 | 
			
		||||
                    vec![AccountMeta::new_credit_only(id1, true)],
 | 
			
		||||
                ),
 | 
			
		||||
                Instruction::new(program_id, &0, vec![AccountMeta::new_readonly(id0, false)]),
 | 
			
		||||
                Instruction::new(program_id, &0, vec![AccountMeta::new_readonly(id1, true)]),
 | 
			
		||||
            ],
 | 
			
		||||
            None,
 | 
			
		||||
        );
 | 
			
		||||
@@ -518,7 +502,7 @@ mod tests {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_is_debitable() {
 | 
			
		||||
    fn test_is_writable() {
 | 
			
		||||
        let key0 = Pubkey::new_rand();
 | 
			
		||||
        let key1 = Pubkey::new_rand();
 | 
			
		||||
        let key2 = Pubkey::new_rand();
 | 
			
		||||
@@ -529,19 +513,19 @@ mod tests {
 | 
			
		||||
        let message = Message {
 | 
			
		||||
            header: MessageHeader {
 | 
			
		||||
                num_required_signatures: 3,
 | 
			
		||||
                num_credit_only_signed_accounts: 2,
 | 
			
		||||
                num_credit_only_unsigned_accounts: 1,
 | 
			
		||||
                num_readonly_signed_accounts: 2,
 | 
			
		||||
                num_readonly_unsigned_accounts: 1,
 | 
			
		||||
            },
 | 
			
		||||
            account_keys: vec![key0, key1, key2, key3, key4, key5],
 | 
			
		||||
            recent_blockhash: Hash::default(),
 | 
			
		||||
            instructions: vec![],
 | 
			
		||||
        };
 | 
			
		||||
        assert_eq!(message.is_debitable(0), true);
 | 
			
		||||
        assert_eq!(message.is_debitable(1), false);
 | 
			
		||||
        assert_eq!(message.is_debitable(2), false);
 | 
			
		||||
        assert_eq!(message.is_debitable(3), true);
 | 
			
		||||
        assert_eq!(message.is_debitable(4), true);
 | 
			
		||||
        assert_eq!(message.is_debitable(5), false);
 | 
			
		||||
        assert_eq!(message.is_writable(0), true);
 | 
			
		||||
        assert_eq!(message.is_writable(1), false);
 | 
			
		||||
        assert_eq!(message.is_writable(2), false);
 | 
			
		||||
        assert_eq!(message.is_writable(3), true);
 | 
			
		||||
        assert_eq!(message.is_writable(4), true);
 | 
			
		||||
        assert_eq!(message.is_writable(5), false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
@@ -554,16 +538,8 @@ mod tests {
 | 
			
		||||
        let message = Message::new(vec![
 | 
			
		||||
            Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]),
 | 
			
		||||
            Instruction::new(program_id, &0, vec![AccountMeta::new(id1, true)]),
 | 
			
		||||
            Instruction::new(
 | 
			
		||||
                program_id,
 | 
			
		||||
                &0,
 | 
			
		||||
                vec![AccountMeta::new_credit_only(id2, false)],
 | 
			
		||||
            ),
 | 
			
		||||
            Instruction::new(
 | 
			
		||||
                program_id,
 | 
			
		||||
                &0,
 | 
			
		||||
                vec![AccountMeta::new_credit_only(id3, true)],
 | 
			
		||||
            ),
 | 
			
		||||
            Instruction::new(program_id, &0, vec![AccountMeta::new_readonly(id2, false)]),
 | 
			
		||||
            Instruction::new(program_id, &0, vec![AccountMeta::new_readonly(id3, true)]),
 | 
			
		||||
        ]);
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            message.get_account_keys_by_lock_type(),
 | 
			
		||||
 
 | 
			
		||||
@@ -418,12 +418,12 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
        let len_size = 1;
 | 
			
		||||
        let num_required_sigs_size = 1;
 | 
			
		||||
        let num_credit_only_accounts_size = 2;
 | 
			
		||||
        let num_readonly_accounts_size = 2;
 | 
			
		||||
        let blockhash_size = size_of::<Hash>();
 | 
			
		||||
        let expected_transaction_size = len_size
 | 
			
		||||
            + (tx.signatures.len() * size_of::<Signature>())
 | 
			
		||||
            + num_required_sigs_size
 | 
			
		||||
            + num_credit_only_accounts_size
 | 
			
		||||
            + num_readonly_accounts_size
 | 
			
		||||
            + len_size
 | 
			
		||||
            + (tx.message.account_keys.len() * size_of::<Pubkey>())
 | 
			
		||||
            + blockhash_size
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user