Relax keypair ordering restriction for `VersionedTransaction::try_new` (#27397)
* Relax keypair ordering restriction for VersionedTransaction::try_new * feedback
This commit is contained in:
parent
a19b5c1536
commit
56cebf9da2
|
@ -71,7 +71,7 @@ impl VersionedTransaction {
|
||||||
return Err(SignerError::InvalidInput("invalid message".to_string()));
|
return Err(SignerError::InvalidInput("invalid message".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let signer_keys = keypairs.pubkeys();
|
let signer_keys = keypairs.try_pubkeys()?;
|
||||||
let expected_signer_keys =
|
let expected_signer_keys =
|
||||||
&static_account_keys[0..message.header().num_required_signatures as usize];
|
&static_account_keys[0..message.header().num_required_signatures as usize];
|
||||||
|
|
||||||
|
@ -81,12 +81,27 @@ impl VersionedTransaction {
|
||||||
Ordering::Equal => Ok(()),
|
Ordering::Equal => Ok(()),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
if signer_keys != expected_signer_keys {
|
|
||||||
return Err(SignerError::KeypairPubkeyMismatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
let message_data = message.serialize();
|
let message_data = message.serialize();
|
||||||
let signatures = keypairs.try_sign_message(&message_data)?;
|
let signature_indexes: Vec<usize> = expected_signer_keys
|
||||||
|
.iter()
|
||||||
|
.map(|signer_key| {
|
||||||
|
signer_keys
|
||||||
|
.iter()
|
||||||
|
.position(|key| key == signer_key)
|
||||||
|
.ok_or(SignerError::KeypairPubkeyMismatch)
|
||||||
|
})
|
||||||
|
.collect::<std::result::Result<_, SignerError>>()?;
|
||||||
|
|
||||||
|
let unordered_signatures = keypairs.try_sign_message(&message_data)?;
|
||||||
|
let signatures: Vec<Signature> = signature_indexes
|
||||||
|
.into_iter()
|
||||||
|
.map(|index| {
|
||||||
|
unordered_signatures
|
||||||
|
.get(index)
|
||||||
|
.copied()
|
||||||
|
.ok_or_else(|| SignerError::InvalidInput("invalid keypairs".to_string()))
|
||||||
|
})
|
||||||
|
.collect::<std::result::Result<_, SignerError>>()?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
signatures,
|
signatures,
|
||||||
|
@ -167,3 +182,62 @@ impl VersionedTransaction {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use {
|
||||||
|
super::*,
|
||||||
|
crate::{
|
||||||
|
message::Message as LegacyMessage,
|
||||||
|
signer::{keypair::Keypair, Signer},
|
||||||
|
},
|
||||||
|
solana_program::{
|
||||||
|
instruction::{AccountMeta, Instruction},
|
||||||
|
pubkey::Pubkey,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_try_new() {
|
||||||
|
let keypair0 = Keypair::new();
|
||||||
|
let keypair1 = Keypair::new();
|
||||||
|
let keypair2 = Keypair::new();
|
||||||
|
|
||||||
|
let message = VersionedMessage::Legacy(LegacyMessage::new(
|
||||||
|
&[Instruction::new_with_bytes(
|
||||||
|
Pubkey::new_unique(),
|
||||||
|
&[],
|
||||||
|
vec![
|
||||||
|
AccountMeta::new_readonly(keypair1.pubkey(), true),
|
||||||
|
AccountMeta::new_readonly(keypair2.pubkey(), false),
|
||||||
|
],
|
||||||
|
)],
|
||||||
|
Some(&keypair0.pubkey()),
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
VersionedTransaction::try_new(message.clone(), &[&keypair0]),
|
||||||
|
Err(SignerError::NotEnoughSigners)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
VersionedTransaction::try_new(message.clone(), &[&keypair0, &keypair0]),
|
||||||
|
Err(SignerError::KeypairPubkeyMismatch)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
VersionedTransaction::try_new(message.clone(), &[&keypair1, &keypair2]),
|
||||||
|
Err(SignerError::KeypairPubkeyMismatch)
|
||||||
|
);
|
||||||
|
|
||||||
|
match VersionedTransaction::try_new(message.clone(), &[&keypair0, &keypair1]) {
|
||||||
|
Ok(tx) => assert_eq!(tx.verify_with_results(), vec![true; 2]),
|
||||||
|
Err(err) => assert_eq!(Some(err), None),
|
||||||
|
}
|
||||||
|
|
||||||
|
match VersionedTransaction::try_new(message, &[&keypair1, &keypair0]) {
|
||||||
|
Ok(tx) => assert_eq!(tx.verify_with_results(), vec![true; 2]),
|
||||||
|
Err(err) => assert_eq!(Some(err), None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue