@@ -57,6 +57,18 @@ impl InstructionKeys {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the pubkey of the first writable signer in the given set of instructions.
|
||||
fn find_writable_signer(instructions: &[Instruction]) -> Option<&Pubkey> {
|
||||
for instruction in instructions {
|
||||
for account in &instruction.accounts {
|
||||
if account.is_signer && account.is_writable {
|
||||
return Some(&account.pubkey);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// 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. Read-only signed
|
||||
/// accounts are placed last in the set of signed accounts. Read-only unsigned accounts,
|
||||
@@ -143,7 +155,7 @@ pub struct MessageHeader {
|
||||
pub num_readonly_unsigned_accounts: u8,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Message {
|
||||
/// The message header, identifying signed and read-only `account_keys`
|
||||
@@ -221,7 +233,8 @@ impl Message {
|
||||
}
|
||||
|
||||
pub fn new(instructions: &[Instruction]) -> Self {
|
||||
Self::new_with_payer(instructions, None)
|
||||
let payer = find_writable_signer(instructions).expect("no suitable key for fee-payer");
|
||||
Self::new_with_payer(instructions, Some(payer))
|
||||
}
|
||||
|
||||
pub fn new_with_payer(instructions: &[Instruction], payer: Option<&Pubkey>) -> Self {
|
||||
@@ -465,7 +478,7 @@ mod tests {
|
||||
let program_id = Pubkey::default();
|
||||
let id0 = Pubkey::default();
|
||||
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]);
|
||||
let message = Message::new(&[ix]);
|
||||
let message = Message::new_with_payer(&[ix], None);
|
||||
assert_eq!(message.header.num_required_signatures, 0);
|
||||
|
||||
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]);
|
||||
|
Reference in New Issue
Block a user