diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 5a533773f..97cd6a985 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -70,8 +70,9 @@ pub fn serialize_parameters( v.write_u8(position as u8).unwrap(); } else { v.write_u8(0).unwrap(); - v.write_u64::(keyed_account.signer_key().is_some() as u64) + v.write_u8(keyed_account.signer_key().is_some() as u8) .unwrap(); + v.write_u8(keyed_account.is_writable() as u8).unwrap(); v.write_all(keyed_account.unsigned_key().as_ref()).unwrap(); v.write_u64::(keyed_account.lamports()?) .unwrap(); @@ -98,7 +99,8 @@ pub fn deserialize_parameters( let (is_dup, _) = is_dup(&keyed_accounts[..i], keyed_account); start += 1; // is_dup if !is_dup { - start += mem::size_of::(); // is_signer + start += mem::size_of::(); // is_signer + start += mem::size_of::(); // is_writable start += mem::size_of::(); // pubkey keyed_account.try_account_ref_mut()?.lamports = LittleEndian::read_u64(&buffer[start..]); diff --git a/programs/bpf_loader/test_elfs/noop.so b/programs/bpf_loader/test_elfs/noop.so index 6790a77e7..3e459f031 100755 Binary files a/programs/bpf_loader/test_elfs/noop.so and b/programs/bpf_loader/test_elfs/noop.so differ diff --git a/sdk/bpf/c/inc/solana_sdk.h b/sdk/bpf/c/inc/solana_sdk.h index ceb3ca67c..1010f078a 100644 --- a/sdk/bpf/c/inc/solana_sdk.h +++ b/sdk/bpf/c/inc/solana_sdk.h @@ -146,8 +146,9 @@ SOL_FN_PREFIX bool SolPubkey_same(const SolPubkey *one, const SolPubkey *two) { */ typedef struct { SolPubkey *key; /** Public key of the account */ - bool is_signer; /** Transaction was signed by this account's key */ - uint64_t *lamports; /** Number of lamports owned by this account */ + bool is_signer; /** Transaction was signed by this account's key? */ + bool is_writable; /** Is the account writable? */ + uint64_t *lamports; /** Number of lamports owned by this account */ uint64_t userdata_len; /** Length of data in bytes */ uint8_t *userdata; /** On-chain data within this account */ SolPubkey *owner; /** Program that owns this account */ @@ -265,9 +266,15 @@ SOL_FN_PREFIX bool sol_deserialize( uint8_t dup_info = input[0]; input += sizeof(uint8_t); if (dup_info == 0) { + // is signer? + params->ka[i].is_signer = *(uint8_t *) input != 0; + input += sizeof(uint8_t); + + // is writable? + params->ka[i].is_writable = *(uint8_t *) input != 0; + input += sizeof(uint8_t); + // key - params->ka[i].is_signer = *(uint64_t *) input != 0; - input += sizeof(uint64_t); params->ka[i].key = (SolPubkey *) input; input += sizeof(SolPubkey); @@ -346,6 +353,8 @@ SOL_FN_PREFIX void sol_log_params(const SolParameters *params) { for (int i = 0; i < params->ka_num; i++) { sol_log(" - Is signer"); sol_log_64(0, 0, 0, 0, params->ka[i].is_signer); + sol_log(" - Is writable"); + sol_log_64(0, 0, 0, 0, params->ka[i].is_writable); sol_log(" - Key"); sol_log_key(params->ka[i].key); sol_log(" - Lamports"); diff --git a/sdk/src/account_info.rs b/sdk/src/account_info.rs index 62e874819..90f036eed 100644 --- a/sdk/src/account_info.rs +++ b/sdk/src/account_info.rs @@ -12,6 +12,8 @@ pub struct AccountInfo<'a> { pub key: &'a Pubkey, // Was the transaction signed by this account's public key? pub is_signer: bool, + // Is the account writable? + pub is_writable: bool, /// Account members that are mutable by the program pub lamports: Rc>, /// Account members that are mutable by the program @@ -55,6 +57,10 @@ impl<'a> AccountInfo<'a> { self.key } + pub fn is_writable(&self) -> bool { + self.is_writable + } + pub fn lamports(&self) -> u64 { **self.lamports.borrow() } @@ -106,6 +112,7 @@ impl<'a> AccountInfo<'a> { pub fn new( key: &'a Pubkey, is_signer: bool, + is_writable: bool, lamports: &'a mut u64, data: &'a mut [u8], owner: &'a Pubkey, @@ -113,6 +120,7 @@ impl<'a> AccountInfo<'a> { Self { key, is_signer, + is_writable, lamports: Rc::new(RefCell::new(lamports)), data: Rc::new(RefCell::new(data)), owner, @@ -136,6 +144,7 @@ impl<'a> From<(&'a Pubkey, &'a mut Account)> for AccountInfo<'a> { Self::new( key, false, + false, &mut account.lamports, &mut account.data, &account.owner, @@ -148,6 +157,7 @@ impl<'a> From<(&'a Pubkey, bool, &'a mut Account)> for AccountInfo<'a> { Self::new( key, is_signer, + false, &mut account.lamports, &mut account.data, &account.owner, @@ -160,6 +170,7 @@ impl<'a> From<&'a mut (Pubkey, Account)> for AccountInfo<'a> { Self::new( key, false, + false, &mut account.lamports, &mut account.data, &account.owner, @@ -180,6 +191,7 @@ pub fn create_is_signer_account_infos<'a>( AccountInfo::new( key, *is_signer, + false, &mut account.lamports, &mut account.data, &account.owner, diff --git a/sdk/src/entrypoint.rs b/sdk/src/entrypoint.rs index 1035ea4f9..50174bc95 100644 --- a/sdk/src/entrypoint.rs +++ b/sdk/src/entrypoint.rs @@ -69,10 +69,17 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> (&'a Pubkey, Vec(); + offset += size_of::(); + + let is_writable = { + #[allow(clippy::cast_ptr_alignment)] + let is_writable = *(input.add(offset) as *const u8); + (is_writable != 0) + }; + offset += size_of::(); let key: &Pubkey = &*(input.add(offset) as *const Pubkey); offset += size_of::(); @@ -95,6 +102,7 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> (&'a Pubkey, Vec