Panic if no fee-payer found via Message::new() (#10050)

automerge
This commit is contained in:
Greg Fitzgerald
2020-05-15 13:23:09 -06:00
committed by GitHub
parent 7080fb9b37
commit 5e89bd8868
11 changed files with 39 additions and 30 deletions

View File

@ -183,7 +183,7 @@ mod tests {
#[test]
fn test_fee_calculator_calculate_fee() {
// Default: no fee.
let message = Message::new(&[]);
let message = Message::default();
assert_eq!(FeeCalculator::default().calculate_fee(&message), 0);
// No signature, no fee.

View File

@ -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)]);

View File

@ -80,7 +80,7 @@ impl std::fmt::Display for TransactionError {
}
/// An atomic transaction
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[derive(Debug, PartialEq, Default, Eq, Clone, Serialize, Deserialize)]
pub struct Transaction {
/// A set of digital signatures of `account_keys`, `program_ids`, `recent_blockhash`, and `instructions`, signed by the first
/// signatures.len() keys of account_keys