Skip to content

Commit 71ed627

Browse files
committed
Add remaining instructions
1 parent dabd6b7 commit 71ed627

14 files changed

+504
-14
lines changed

programs/system/src/instructions/advance_nonce_account.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ use pinocchio::{
55
program::invoke_signed,
66
};
77

8+
/// Consumes a stored nonce, replacing it with a successor.
9+
///
10+
/// ### Accounts:
11+
/// 0. `[WRITE]` Nonce account
12+
/// 1. `[]` RecentBlockhashes sysvar
13+
/// 2. `[SIGNER]` Nonce authority
814
pub struct AdvanceNonceAccount<'a> {
915
/// Nonce account.
1016
pub account: &'a AccountInfo,
@@ -30,18 +36,17 @@ impl<'a> AdvanceNonceAccount<'a> {
3036
AccountMeta::readonly_signer(self.authority.key()),
3137
];
3238

33-
// instruction data
34-
// - [0..4 ]: instruction discriminator
35-
let mut instruction_data = [0; 4];
36-
// assign instruction has a '1' discriminator
37-
instruction_data[0] = 4;
38-
39+
// instruction
3940
let instruction = Instruction {
4041
program_id: &crate::ID,
4142
accounts: &account_metas,
42-
data: &instruction_data,
43+
data: &[4],
4344
};
4445

45-
invoke_signed(&instruction, &[self.account], signers)
46+
invoke_signed(
47+
&instruction,
48+
&[self.account, self.recent_blockhashes_sysvar, self.authority],
49+
signers,
50+
)
4651
}
4752
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use pinocchio::{
2+
account_info::AccountInfo,
3+
entrypoint::ProgramResult,
4+
instruction::{AccountMeta, Instruction, Signer},
5+
program::invoke_signed,
6+
};
7+
8+
/// Allocate space in a (possibly new) account without funding.
9+
///
10+
/// ### Accounts:
11+
/// 0. `[WRITE, SIGNER]` New account
12+
pub struct Allocate<'a> {
13+
/// Account to be assigned.
14+
pub account: &'a AccountInfo,
15+
16+
/// Number of bytes of memory to allocate.
17+
pub space: u64,
18+
}
19+
20+
impl<'a> Allocate<'a> {
21+
#[inline(always)]
22+
pub fn invoke(&self) -> ProgramResult {
23+
self.invoke_signed(&[])
24+
}
25+
26+
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
27+
// account metadata
28+
let account_metas: [AccountMeta; 1] = [AccountMeta::writable_signer(self.account.key())];
29+
30+
// instruction data
31+
// - [0..4 ]: instruction discriminator
32+
// - [4..12]: space
33+
let mut instruction_data = [0; 12];
34+
instruction_data[0] = 8;
35+
instruction_data[4..12].copy_from_slice(&self.space.to_le_bytes());
36+
37+
let instruction = Instruction {
38+
program_id: &crate::ID,
39+
accounts: &account_metas,
40+
data: &instruction_data,
41+
};
42+
43+
invoke_signed(&instruction, &[self.account], signers)
44+
}
45+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use pinocchio::{
2+
account_info::AccountInfo,
3+
entrypoint::ProgramResult,
4+
instruction::{AccountMeta, Instruction, Signer},
5+
program::invoke_signed,
6+
pubkey::Pubkey,
7+
};
8+
9+
/// Allocate space for and assign an account at an address derived
10+
/// from a base public key and a seed.
11+
///
12+
/// ### Accounts:
13+
/// 0. `[WRITE]` Allocated account
14+
/// 1. `[SIGNER]` Base account
15+
pub struct AllocateWithSeed<'a, 'b, 'c> {
16+
/// Allocated account.
17+
pub account: &'a AccountInfo,
18+
19+
/// Base account.
20+
///
21+
/// The account matching the base Pubkey below must be provided as
22+
/// a signer, but may be the same as the funding account and provided
23+
/// as account 0.
24+
pub base: &'a AccountInfo,
25+
26+
/// String of ASCII chars, no longer than `Pubkey::MAX_SEED_LEN`.
27+
pub seed: &'b str,
28+
29+
/// Number of bytes of memory to allocate.
30+
pub space: u64,
31+
32+
/// Address of program that will own the new account.
33+
pub owner: &'c Pubkey,
34+
}
35+
36+
impl<'a, 'b, 'c> AllocateWithSeed<'a, 'b, 'c> {
37+
#[inline(always)]
38+
pub fn invoke(&self) -> ProgramResult {
39+
self.invoke_signed(&[])
40+
}
41+
42+
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
43+
// account metadata
44+
let account_metas: [AccountMeta; 2] = [
45+
AccountMeta::writable_signer(self.account.key()),
46+
AccountMeta::readonly_signer(self.base.key()),
47+
];
48+
49+
// instruction data
50+
// - [0..4 ]: instruction discriminator
51+
// - [4..36 ]: base pubkey
52+
// - [36..40]: seed length
53+
// - [40.. ]: seed (max 32)
54+
// - [.. +8]: account space
55+
// - [.. +32]: owner pubkey
56+
let mut instruction_data = [0; 112];
57+
instruction_data[0] = 9;
58+
instruction_data[4..36].copy_from_slice(self.base.key());
59+
instruction_data[36..40].copy_from_slice(&u32::to_le_bytes(self.seed.len() as u32));
60+
61+
let offset = 40 + self.seed.len();
62+
instruction_data[40..offset].copy_from_slice(self.seed.as_bytes());
63+
instruction_data[offset..offset + 8].copy_from_slice(&self.space.to_le_bytes());
64+
instruction_data[offset + 8..offset + 40].copy_from_slice(self.owner.as_ref());
65+
66+
let instruction = Instruction {
67+
program_id: &crate::ID,
68+
accounts: &account_metas,
69+
data: &instruction_data[..offset + 40],
70+
};
71+
72+
invoke_signed(&instruction, &[self.account, self.base], signers)
73+
}
74+
}

programs/system/src/instructions/assign.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ use pinocchio::{
66
pubkey::Pubkey,
77
};
88

9+
/// Assign account to a program
10+
///
11+
/// ### Accounts:
12+
/// 0. `[WRITE, SIGNER]` Assigned account public key
913
pub struct Assign<'a, 'b> {
1014
/// Account to be assigned.
1115
pub account: &'a AccountInfo,
@@ -28,7 +32,6 @@ impl<'a, 'b> Assign<'a, 'b> {
2832
// - [0..4 ]: instruction discriminator
2933
// - [4..36]: owner pubkey
3034
let mut instruction_data = [0; 36];
31-
// assign instruction has a '1' discriminator
3235
instruction_data[0] = 1;
3336
instruction_data[4..36].copy_from_slice(self.owner.as_ref());
3437

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use pinocchio::{
2+
account_info::AccountInfo,
3+
entrypoint::ProgramResult,
4+
instruction::{AccountMeta, Instruction, Signer},
5+
program::invoke_signed,
6+
pubkey::Pubkey,
7+
};
8+
9+
/// Assign account to a program based on a seed.
10+
///
11+
/// ### Accounts:
12+
/// 0. `[WRITE]` Assigned account
13+
/// 1. `[SIGNER]` Base account
14+
pub struct AssignWithSeed<'a, 'b, 'c> {
15+
/// Allocated account.
16+
pub account: &'a AccountInfo,
17+
18+
/// Base account.
19+
///
20+
/// The account matching the base Pubkey below must be provided as
21+
/// a signer, but may be the same as the funding account and provided
22+
/// as account 0.
23+
pub base: &'a AccountInfo,
24+
25+
/// String of ASCII chars, no longer than `Pubkey::MAX_SEED_LEN`.
26+
pub seed: &'b str,
27+
28+
/// Address of program that will own the new account.
29+
pub owner: &'c Pubkey,
30+
}
31+
32+
impl<'a, 'b, 'c> AssignWithSeed<'a, 'b, 'c> {
33+
#[inline(always)]
34+
pub fn invoke(&self) -> ProgramResult {
35+
self.invoke_signed(&[])
36+
}
37+
38+
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
39+
// account metadata
40+
let account_metas: [AccountMeta; 2] = [
41+
AccountMeta::writable_signer(self.account.key()),
42+
AccountMeta::readonly_signer(self.base.key()),
43+
];
44+
45+
// instruction data
46+
// - [0..4 ]: instruction discriminator
47+
// - [4..36 ]: base pubkey
48+
// - [36..40]: seed length
49+
// - [40.. ]: seed (max 32)
50+
// - [.. +32]: owner pubkey
51+
let mut instruction_data = [0; 104];
52+
instruction_data[0] = 10;
53+
instruction_data[4..36].copy_from_slice(self.base.key());
54+
instruction_data[36..40].copy_from_slice(&u32::to_le_bytes(self.seed.len() as u32));
55+
56+
let offset = 40 + self.seed.len();
57+
instruction_data[40..offset].copy_from_slice(self.seed.as_bytes());
58+
instruction_data[offset..offset + 32].copy_from_slice(self.owner.as_ref());
59+
60+
let instruction = Instruction {
61+
program_id: &crate::ID,
62+
accounts: &account_metas,
63+
data: &instruction_data[..offset + 32],
64+
};
65+
66+
invoke_signed(&instruction, &[self.account, self.base], signers)
67+
}
68+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use pinocchio::{
2+
account_info::AccountInfo,
3+
entrypoint::ProgramResult,
4+
instruction::{AccountMeta, Instruction, Signer},
5+
program::invoke_signed,
6+
pubkey::Pubkey,
7+
};
8+
9+
/// Change the entity authorized to execute nonce instructions on the account.
10+
///
11+
/// The `Pubkey` parameter identifies the entity to authorize.
12+
///
13+
/// ### Accounts:
14+
/// 0. `[WRITE]` Nonce account
15+
/// 1. `[SIGNER]` Nonce authority
16+
pub struct AuthorizeNonceAccount<'a, 'b> {
17+
/// Nonce account.
18+
pub account: &'a AccountInfo,
19+
20+
/// Nonce authority.
21+
pub authority: &'a AccountInfo,
22+
23+
/// New entity authorized to execute nonce instructions on the account.
24+
pub new_authority: &'b Pubkey,
25+
}
26+
27+
impl<'a, 'b> AuthorizeNonceAccount<'a, 'b> {
28+
#[inline(always)]
29+
pub fn invoke(&self) -> ProgramResult {
30+
self.invoke_signed(&[])
31+
}
32+
33+
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
34+
// account metadata
35+
let account_metas: [AccountMeta; 2] = [
36+
AccountMeta::writable(self.account.key()),
37+
AccountMeta::readonly_signer(self.authority.key()),
38+
];
39+
40+
// instruction data
41+
// - [0..4 ]: instruction discriminator
42+
// - [4..12]: lamports
43+
let mut instruction_data = [0; 36];
44+
instruction_data[0] = 7;
45+
instruction_data[4..36].copy_from_slice(self.new_authority);
46+
47+
let instruction = Instruction {
48+
program_id: &crate::ID,
49+
accounts: &account_metas,
50+
data: &instruction_data,
51+
};
52+
53+
invoke_signed(&instruction, &[self.account, self.authority], signers)
54+
}
55+
}

programs/system/src/instructions/create_account.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ use pinocchio::{
77
};
88

99
/// Create a new account.
10+
///
11+
/// ### Accounts:
12+
/// 0. `[WRITE, SIGNER]` Funding account
13+
/// 1. `[WRITE, SIGNER]` New account
1014
pub struct CreateAccount<'a> {
1115
/// Funding account.
1216
pub from: &'a AccountInfo,

programs/system/src/instructions/create_account_with_seed.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ use pinocchio::{
77
};
88

99
/// Create a new account at an address derived from a base pubkey and a seed.
10+
///
11+
/// ### Accounts:
12+
/// 0. `[WRITE, SIGNER]` Funding account
13+
/// 1. `[WRITE]` Created account
14+
/// 2. `[SIGNER]` (optional) Base account; the account matching the base Pubkey below must be
15+
/// provided as a signer, but may be the same as the funding account
16+
///
1017
pub struct CreateAccountWithSeed<'a, 'b, 'c> {
1118
/// Funding account.
1219
pub from: &'a AccountInfo,
@@ -57,7 +64,6 @@ impl<'a, 'b, 'c> CreateAccountWithSeed<'a, 'b, 'c> {
5764
// - [.. +8]: account space
5865
// - [.. +32]: owner pubkey
5966
let mut instruction_data = [0; 120];
60-
// create account with seed instruction has a '3' discriminator
6167
instruction_data[0] = 3;
6268
instruction_data[4..36].copy_from_slice(self.base.unwrap_or(self.from).key());
6369
instruction_data[36..40].copy_from_slice(&u32::to_le_bytes(self.seed.len() as u32));
@@ -74,6 +80,10 @@ impl<'a, 'b, 'c> CreateAccountWithSeed<'a, 'b, 'c> {
7480
data: &instruction_data[..offset + 48],
7581
};
7682

77-
invoke_signed(&instruction, &[self.from, self.to], signers)
83+
invoke_signed(
84+
&instruction,
85+
&[self.from, self.to, self.base.unwrap_or(self.from)],
86+
signers,
87+
)
7888
}
7989
}

0 commit comments

Comments
 (0)