Skip to content

Commit b255655

Browse files
committed
pda & account renaming
1 parent 106bfe2 commit b255655

9 files changed

Lines changed: 99 additions & 111 deletions

File tree

client/src/instruction.rs

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

99
/// Creates an `Initialize` instruction.
10-
pub fn initialize(programmatic_signer_account: &Address, authority: &Address) -> SolanaInstruction {
10+
pub fn initialize(signer_nonce_account: &Address, authority: &Address) -> SolanaInstruction {
1111
SolanaInstruction {
1212
program_id: spl_ed25519_programmatic_signer_interface::id(),
1313
accounts: vec![
14-
AccountMeta::new(*programmatic_signer_account, false),
14+
AccountMeta::new(*signer_nonce_account, false),
1515
AccountMeta::new_readonly(*authority, false),
1616
AccountMeta::new_readonly(slot_hashes::id(), false),
1717
],

interface/src/instruction.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use {
99
#[derive(Clone, Copy, Debug, PartialEq, Eq, SchemaRead, SchemaWrite)]
1010
#[wincode(tag_encoding = "u8")]
1111
pub enum Instruction {
12-
/// Initializes a programmatic signer account for an authority.
12+
/// Initializes a signer nonce account for an authority.
1313
///
1414
/// The caller must first create and fund the account. Recommended to include
1515
/// `solana_system_interface::instruction::create_account` and `Initialize` in the same
@@ -18,70 +18,70 @@ pub enum Instruction {
1818
/// On success, the program:
1919
/// 1. Verifies the account is uninitialized, rent-exempt, and owned by this program.
2020
/// 2. Derives the initial `nonce` as
21-
/// `sha256("spl-ed25519-programmatic-signer::init-v1" ‖ programmatic_signer_account_address ‖ slot_hashes[0])`.
22-
/// 3. Writes `ProgrammaticSignerAccount { nonce, authority }` into the account data.
21+
/// `sha256("spl-ed25519-programmatic-signer::init-v1" ‖ signer_nonce_account_address ‖ slot_hashes[0])`.
22+
/// 3. Writes `SignerNonceAccount { nonce, authority }` into the account data.
2323
///
2424
/// Instruction data: instruction discriminator only
2525
///
2626
/// Accounts required:
27-
/// - `[writable]` Programmatic signer account
28-
/// - `[]` Authority to store in the programmatic signer account
27+
/// - `[writable]` Signer nonce account
28+
/// - `[]` Authority to store in the signer nonce account
2929
/// - `[]` `SlotHashes` sysvar
3030
Initialize,
3131

3232
/// Authorizes and executes a wrapped Solana transaction whose required signers are
33-
/// `ProgrammaticSignerPda` accounts.
33+
/// `ProgrammaticSigner` accounts.
3434
///
3535
/// Instruction data: instruction discriminator followed by a serialized
3636
/// `solana_transaction::versioned::VersionedTransaction`.
3737
/// All message variants supported by `VersionedTransaction` are accepted.
3838
///
3939
/// Wrapped required signers are paired by index:
40-
/// - `message.account_keys[i]`: `ProgrammaticSignerPda` promoted during CPI.
40+
/// - `message.account_keys[i]`: `ProgrammaticSigner` promoted during CPI.
4141
/// - `tx.signatures[i]`: wrapped-message signature from the matching authority address.
4242
///
4343
/// On success, the program:
4444
/// 1. Deserializes the transaction and sanitizes the wrapped message.
45-
/// 2. Reads the authority stored in the programmatic signer account.
46-
/// 3. Checks the passed programmatic signer account's authority signed the wrapped message.
45+
/// 2. Reads the authority stored in the signer nonce account.
46+
/// 3. Checks the passed signer nonce account's authority signed the wrapped message.
4747
/// 4. Checks the wrapped message's lifetime / recent blockhash field equals the account's
4848
/// `nonce`.
4949
/// 5. Verifies the outer transaction's only top-level instruction is `Submit`.
5050
/// 6. Iterates over the outer authority accounts in order. For each `authority_i`, requires
51-
/// `ProgrammaticSignerPda(authority_i) == message.account_keys[i]` and verifies
51+
/// `ProgrammaticSigner(authority_i) == message.account_keys[i]` and verifies
5252
/// `tx.signatures[i]` over the wrapped message with `authority_i`.
5353
/// 7. Executes each `message.instructions` entry by CPI, using `invoke_signed` to promote
54-
/// each authorized signer's corresponding `ProgrammaticSignerPda`.
54+
/// each authorized signer's corresponding `ProgrammaticSigner`.
5555
/// 8. Derives and stores the next nonce as
56-
/// `sha256("spl-ed25519-programmatic-signer::v1" ‖ programmatic_signer_account ‖ old_nonce ‖ slot_hashes[0] ‖ sha256(signed_message_bytes))`
56+
/// `sha256("spl-ed25519-programmatic-signer::v1" ‖ signer_nonce_account ‖ old_nonce ‖ slot_hashes[0] ‖ sha256(signed_message_bytes))`
5757
///
5858
/// Accounts required:
59-
/// - `[writable]` Programmatic signer account whose nonce is consumed and advanced
59+
/// - `[writable]` Signer nonce account whose nonce is consumed and advanced
6060
/// - `[]` `SlotHashes` sysvar
6161
/// - `[]` `Instructions` sysvar
6262
/// - Authority addresses, ordered to match the wrapped message's required signers.
6363
/// - Remaining accounts referenced by the wrapped message, in order. Writable flags
6464
/// must match the wrapped message.
6565
Submit,
6666

67-
/// Closes a programmatic signer account and refunds its lamports.
67+
/// Closes a signer nonce account and refunds its lamports.
6868
///
6969
/// Instruction data: instruction discriminator followed by [`CloseData`].
7070
///
7171
/// Runs only as an inner instruction of a wrapped transaction submitted through `Submit`
72-
/// because nothing outside this program can sign for `ProgrammaticSignerPda`.
72+
/// because nothing outside this program can sign for `ProgrammaticSigner`.
7373
///
7474
/// Accounts required:
75-
/// - `[signer]` `ProgrammaticSignerPda`
76-
/// - `[writable]` Programmatic signer account
75+
/// - `[signer]` `ProgrammaticSigner`
76+
/// - `[writable]` Signer nonce account
7777
/// - `[writable]` Lamport recipient
7878
Close,
7979
}
8080

8181
/// Data for [`Instruction::Close`].
8282
#[derive(Clone, Debug, PartialEq, Eq, SchemaRead, SchemaWrite)]
8383
pub struct CloseData {
84-
/// Address that receives all lamports from the closed programmatic signer account.
84+
/// Address that receives all lamports from the closed signer nonce account.
8585
pub recipient: Address,
8686
}
8787

interface/src/pda.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
use solana_address::Address;
22

3-
/// Programmatic signer PDA.
3+
/// Programmatic signer.
44
///
55
/// Program-owned runtime signer for an authority. `Submit` promotes it to `is_signer=true`
66
/// via `invoke_signed` wherever a wrapped instruction references it after the corresponding
77
/// authority has signed the wrapped message.
88
///
99
/// Seeds: `["programmatic-signer", authority, bump]`
10-
pub struct ProgrammaticSignerPda;
10+
pub struct ProgrammaticSigner;
1111

12-
impl ProgrammaticSignerPda {
12+
impl ProgrammaticSigner {
1313
pub const SEED_PREFIX: &[u8] = b"programmatic-signer";
1414

1515
#[inline(always)]
1616
pub fn derive_address_and_bump(program_id: &Address, authority: &Address) -> (Address, u8) {
1717
Address::derive_program_address(&[Self::SEED_PREFIX, authority.as_ref()], program_id)
18-
.expect("failed to derive ProgrammaticSignerPda from authority")
18+
.expect("failed to derive ProgrammaticSigner from authority")
1919
}
2020

2121
#[inline(always)]

interface/src/state.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ use {
1212
/// Tag for the initial nonce derivation.
1313
pub const INIT_NONCE_DERIVATION_TAG: &[u8] = b"spl-ed25519-programmatic-signer::init-v1";
1414

15-
/// On-chain data for a caller-created programmatic signer account.
15+
/// On-chain data for a caller-created signer nonce account.
1616
///
17-
/// One authority can control any number of independent programmatic signer accounts. This is useful for
17+
/// One authority can control any number of independent signer nonce accounts. This is useful for
1818
/// when that authority wants to prepare or submit more than one transaction concurrently. Each
1919
/// account carries its own nonce, so consuming one nonce does not advance or invalidate
20-
/// transactions prepared against another programmatic signer account.
20+
/// transactions prepared against another signer nonce account.
2121
#[derive(Clone, Debug, PartialEq, Eq, SchemaRead, SchemaWrite)]
22-
pub struct ProgrammaticSignerAccount {
22+
pub struct SignerNonceAccount {
2323
/// Single-use value that prevents a signed message from being replayed. `Submit` requires this
2424
/// to match the wrapped message's lifetime field: `lifetime_specifier` for `v1` messages or
2525
/// `recent_blockhash` for `legacy` and `v0` messages. On success, `Submit` advances it to a
@@ -31,7 +31,7 @@ pub struct ProgrammaticSignerAccount {
3131
pub authority: Address,
3232
}
3333

34-
impl ProgrammaticSignerAccount {
34+
impl SignerNonceAccount {
3535
/// Serialized account size: a 32-byte nonce followed by a 32-byte authority address.
3636
pub const LEN: usize = HASH_BYTES + ADDRESS_BYTES;
3737
}
@@ -71,18 +71,18 @@ unsafe impl<'de, C: Config> SchemaRead<'de, C> for HashBytes {
7171

7272
#[cfg(test)]
7373
mod tests {
74-
use super::{Address, Hash, ProgrammaticSignerAccount};
74+
use super::{Address, Hash, SignerNonceAccount};
7575

7676
#[test]
7777
fn len_matches_wincode_serialized_size() {
78-
let account = ProgrammaticSignerAccount {
78+
let account = SignerNonceAccount {
7979
nonce: Hash::new_from_array([1; 32]),
8080
authority: Address::new_from_array([2; 32]),
8181
};
8282

8383
assert_eq!(
8484
wincode::serialized_size(&account).unwrap() as usize,
85-
ProgrammaticSignerAccount::LEN
85+
SignerNonceAccount::LEN
8686
);
8787
}
8888
}

program/src/initialize.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,37 @@ use {
55
sysvars::{Sysvar, rent::Rent, slot_hashes::SlotHashes},
66
},
77
spl_ed25519_programmatic_signer_interface::state::{
8-
INIT_NONCE_DERIVATION_TAG, ProgrammaticSignerAccount,
8+
INIT_NONCE_DERIVATION_TAG, SignerNonceAccount,
99
},
1010
};
1111

12-
/// Turns a caller-created, program-owned account into a [`ProgrammaticSignerAccount`]
12+
/// Turns a caller-created, program-owned account into a [`SignerNonceAccount`]
1313
/// bound to `authority` with a fresh nonce.
1414
#[inline(always)]
1515
pub fn process_initialize(program_id: &Address, accounts: &mut [AccountView]) -> ProgramResult {
16-
let [
17-
programmatic_signer_account,
18-
authority,
19-
slot_hashes_account,
20-
..,
21-
] = accounts
22-
else {
16+
let [signer_nonce_account, authority, slot_hashes_account, ..] = accounts else {
2317
return Err(ProgramError::NotEnoughAccountKeys);
2418
};
2519

2620
// Caller must ensure account is pre-created with authority set to the program
27-
if !programmatic_signer_account.owned_by(program_id) {
21+
if !signer_nonce_account.owned_by(program_id) {
2822
return Err(ProgramError::IllegalOwner);
2923
}
3024

3125
// Ensure's the precise length matches the layout
32-
if programmatic_signer_account.data_len() != ProgrammaticSignerAccount::LEN {
26+
if signer_nonce_account.data_len() != SignerNonceAccount::LEN {
3327
return Err(ProgramError::InvalidAccountData);
3428
}
3529

3630
// A fresh account is zero-filled. Any nonzero byte means it is already initialized.
37-
let data = programmatic_signer_account.try_borrow()?;
31+
let data = signer_nonce_account.try_borrow()?;
3832
if data.iter().any(|byte| *byte != 0) {
3933
return Err(ProgramError::AccountAlreadyInitialized);
4034
}
4135
drop(data);
4236

43-
let rent_required = Rent::get()?.try_minimum_balance(ProgrammaticSignerAccount::LEN)?;
44-
if programmatic_signer_account.lamports() < rent_required {
37+
let rent_required = Rent::get()?.try_minimum_balance(SignerNonceAccount::LEN)?;
38+
if signer_nonce_account.lamports() < rent_required {
4539
return Err(ProgramError::AccountNotRentExempt);
4640
}
4741

@@ -56,18 +50,18 @@ pub fn process_initialize(program_id: &Address, accounts: &mut [AccountView]) ->
5650
// can never equal an advanced one.
5751
INIT_NONCE_DERIVATION_TAG,
5852
// so multiple accounts initialized in the same slot don't share the same nonce
59-
programmatic_signer_account.address().as_ref(),
53+
signer_nonce_account.address().as_ref(),
6054
// chain entropy the caller can't choose
6155
&recent_entry.hash,
6256
]);
6357

64-
let state = ProgrammaticSignerAccount {
58+
let state = SignerNonceAccount {
6559
nonce: initial_nonce,
6660
authority: Address::from(authority.address()),
6761
};
6862

6963
// Write data into the account
70-
let mut data = programmatic_signer_account.try_borrow_mut()?;
64+
let mut data = signer_nonce_account.try_borrow_mut()?;
7165
wincode::serialize_into(&mut *data, &state)
7266
.map_err(|_| ProgramError::InvalidInstructionData)?;
7367

program/tests/helpers/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
mollusk_svm::Mollusk, solana_account::Account,
3-
spl_ed25519_programmatic_signer_interface::state::ProgrammaticSignerAccount,
3+
spl_ed25519_programmatic_signer_interface::state::SignerNonceAccount,
44
};
55

66
pub fn init_mollusk() -> Mollusk {
@@ -10,6 +10,6 @@ pub fn init_mollusk() -> Mollusk {
1010
)
1111
}
1212

13-
pub fn decode_state(account: &Account) -> ProgrammaticSignerAccount {
13+
pub fn decode_state(account: &Account) -> SignerNonceAccount {
1414
wincode::deserialize_exact(&account.data).unwrap()
1515
}

program/tests/helpers/initialize_builder.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use {
2-
crate::helpers::{
3-
common::init_mollusk, signer_account_builder::ProgrammaticSignerAccountBuilder,
4-
},
2+
crate::helpers::{common::init_mollusk, signer_account_builder::SignerNonceAccountBuilder},
53
mollusk_svm::{
64
Mollusk,
75
result::{Check, InstructionResult},
@@ -13,7 +11,7 @@ use {
1311

1412
pub struct InitializeBuilder<'a> {
1513
mollusk: Mollusk,
16-
programmatic_signer: Option<(Address, Account)>,
14+
signer_nonce_account: Option<(Address, Account)>,
1715
authority_address: Option<Address>,
1816
instruction_data: Option<Vec<u8>>,
1917
checks: Vec<Check<'a>>,
@@ -23,7 +21,7 @@ impl Default for InitializeBuilder<'_> {
2321
fn default() -> Self {
2422
Self {
2523
mollusk: init_mollusk(),
26-
programmatic_signer: None,
24+
signer_nonce_account: None,
2725
authority_address: None,
2826
instruction_data: None,
2927
checks: vec![],
@@ -32,8 +30,8 @@ impl Default for InitializeBuilder<'_> {
3230
}
3331

3432
impl<'a> InitializeBuilder<'a> {
35-
pub fn programmatic_signer(mut self, programmatic_signer: (Address, Account)) -> Self {
36-
self.programmatic_signer = Some(programmatic_signer);
33+
pub fn signer_nonce_account(mut self, signer_nonce_account: (Address, Account)) -> Self {
34+
self.signer_nonce_account = Some(signer_nonce_account);
3735
self
3836
}
3937

@@ -53,21 +51,21 @@ impl<'a> InitializeBuilder<'a> {
5351
}
5452

5553
pub fn execute(mut self) -> InstructionResult {
56-
let programmatic_signer = self
57-
.programmatic_signer
58-
.unwrap_or_else(|| ProgrammaticSignerAccountBuilder::default().build());
54+
let signer_nonce_account = self
55+
.signer_nonce_account
56+
.unwrap_or_else(|| SignerNonceAccountBuilder::default().build());
5957
let authority_address = self
6058
.authority_address
6159
.unwrap_or_else(|| Address::from([2; 32]));
6260
let slot_hashes = self.mollusk.sysvars.keyed_account_for_slot_hashes_sysvar();
6361

64-
let mut instruction = initialize(&programmatic_signer.0, &authority_address);
62+
let mut instruction = initialize(&signer_nonce_account.0, &authority_address);
6563
if let Some(instruction_data) = self.instruction_data {
6664
instruction.data = instruction_data;
6765
}
6866

6967
let accounts = vec![
70-
programmatic_signer,
68+
signer_nonce_account,
7169
(authority_address, Account::default()),
7270
slot_hashes,
7371
];

program/tests/helpers/signer_account_builder.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
use {
22
solana_account::Account, solana_address::Address, solana_rent::Rent,
3-
spl_ed25519_programmatic_signer_interface::state::ProgrammaticSignerAccount,
3+
spl_ed25519_programmatic_signer_interface::state::SignerNonceAccount,
44
};
55

6-
pub struct ProgrammaticSignerAccountBuilder {
6+
pub struct SignerNonceAccountBuilder {
77
key: Address,
88
owner: Address,
99
lamports: Option<u64>,
1010
data: Option<Vec<u8>>,
1111
}
1212

13-
impl Default for ProgrammaticSignerAccountBuilder {
13+
impl Default for SignerNonceAccountBuilder {
1414
fn default() -> Self {
1515
Self {
1616
key: Address::from([1; 32]),
@@ -21,7 +21,7 @@ impl Default for ProgrammaticSignerAccountBuilder {
2121
}
2222
}
2323

24-
impl ProgrammaticSignerAccountBuilder {
24+
impl SignerNonceAccountBuilder {
2525
pub fn new() -> Self {
2626
Self::default()
2727
}
@@ -50,7 +50,7 @@ impl ProgrammaticSignerAccountBuilder {
5050
let data = self
5151
.data
5252
// Default to program-owned, zero-filled account (waiting to be initialized)
53-
.unwrap_or_else(|| vec![0; ProgrammaticSignerAccount::LEN]);
53+
.unwrap_or_else(|| vec![0; SignerNonceAccount::LEN]);
5454
let lamports = self
5555
.lamports
5656
.unwrap_or_else(|| Rent::default().minimum_balance(data.len()));

0 commit comments

Comments
 (0)