Relax `Sized` bound for `Signers` in `Transaction` and `Client` (#30568)

* relax Sized bound for Signers in Transaction and Client

* also relax Sized bounds in client, runtime, thin-client and tpu-client

* add tests for using non-sized transaction signers

* fix macro for thin_client vs ?Sized

* move tests to transactions, add Sized relaxation to mut macro

* fix clippy warning

* get rid of unnecessary imports
This commit is contained in:
blackghost1987 2023-03-30 15:12:48 +02:00 committed by GitHub
parent 38e054f4a6
commit 9f9d6f8a89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 48 additions and 30 deletions

View File

@ -145,20 +145,20 @@ impl Default for ConnectionCache {
} }
macro_rules! dispatch { macro_rules! dispatch {
($(#[$meta:meta])* $vis:vis fn $name:ident$(<$($t:ident: $cons:ident),*>)?(&self $(, $arg:ident: $ty:ty)*) $(-> $out:ty)?) => { ($(#[$meta:meta])* $vis:vis fn $name:ident$(<$($t:ident: $cons:ident + ?Sized),*>)?(&self $(, $arg:ident: $ty:ty)*) $(-> $out:ty)?) => {
#[inline] #[inline]
$(#[$meta])* $(#[$meta])*
$vis fn $name$(<$($t: $cons),*>)?(&self $(, $arg:$ty)*) $(-> $out)? { $vis fn $name$(<$($t: $cons + ?Sized),*>)?(&self $(, $arg:$ty)*) $(-> $out)? {
match self { match self {
Self::Quic(this) => this.$name($($arg, )*), Self::Quic(this) => this.$name($($arg, )*),
Self::Udp(this) => this.$name($($arg, )*), Self::Udp(this) => this.$name($($arg, )*),
} }
} }
}; };
($(#[$meta:meta])* $vis:vis fn $name:ident$(<$($t:ident: $cons:ident),*>)?(&mut self $(, $arg:ident: $ty:ty)*) $(-> $out:ty)?) => { ($(#[$meta:meta])* $vis:vis fn $name:ident$(<$($t:ident: $cons:ident + ?Sized),*>)?(&mut self $(, $arg:ident: $ty:ty)*) $(-> $out:ty)?) => {
#[inline] #[inline]
$(#[$meta])* $(#[$meta])*
$vis fn $name$(<$($t: $cons),*>)?(&mut self $(, $arg:$ty)*) $(-> $out)? { $vis fn $name$(<$($t: $cons + ?Sized),*>)?(&mut self $(, $arg:$ty)*) $(-> $out)? {
match self { match self {
Self::Quic(this) => this.$name($($arg, )*), Self::Quic(this) => this.$name($($arg, )*),
Self::Udp(this) => this.$name($($arg, )*), Self::Udp(this) => this.$name($($arg, )*),

View File

@ -120,7 +120,7 @@ where
}) })
} }
pub async fn send_and_confirm_messages_with_spinner<T: Signers>( pub async fn send_and_confirm_messages_with_spinner<T: Signers + ?Sized>(
&self, &self,
messages: &[Message], messages: &[Message],
signers: &T, signers: &T,

View File

@ -124,7 +124,7 @@ impl ThinClient {
tries: usize tries: usize
) -> TransportResult<Signature>); ) -> TransportResult<Signature>);
dispatch!(pub fn send_and_confirm_transaction<T: Signers>( dispatch!(pub fn send_and_confirm_transaction<T: Signers + ?Sized>(
&self, &self,
keypairs: &T, keypairs: &T,
transaction: &mut Transaction, transaction: &mut Transaction,
@ -172,7 +172,7 @@ impl Client for ThinClient {
} }
impl SyncClient for ThinClient { impl SyncClient for ThinClient {
dispatch!(fn send_and_confirm_message<T: Signers>( dispatch!(fn send_and_confirm_message<T: Signers + ?Sized>(
&self, &self,
keypairs: &T, keypairs: &T,
message: Message message: Message

View File

@ -111,7 +111,7 @@ where
}) })
} }
pub fn send_and_confirm_messages_with_spinner<T: Signers>( pub fn send_and_confirm_messages_with_spinner<T: Signers + ?Sized>(
&self, &self,
messages: &[Message], messages: &[Message],
signers: &T, signers: &T,

View File

@ -51,7 +51,7 @@ impl AsyncClient for BankClient {
} }
impl SyncClient for BankClient { impl SyncClient for BankClient {
fn send_and_confirm_message<T: Signers>( fn send_and_confirm_message<T: Signers + ?Sized>(
&self, &self,
keypairs: &T, keypairs: &T,
message: Message, message: Message,

View File

@ -213,7 +213,7 @@ pub mod solana_sdk {
} }
impl VersionedTransaction { impl VersionedTransaction {
pub fn try_new<T: Signers>( pub fn try_new<T: Signers + ?Sized>(
message: VersionedMessage, message: VersionedMessage,
_keypairs: &T, _keypairs: &T,
) -> std::result::Result<Self, SignerError> { ) -> std::result::Result<Self, SignerError> {
@ -230,7 +230,7 @@ pub mod solana_sdk {
} }
impl Transaction { impl Transaction {
pub fn new<T: Signers>( pub fn new<T: Signers + ?Sized>(
_from_keypairs: &T, _from_keypairs: &T,
_message: Message, _message: Message,
_recent_blockhash: Hash, _recent_blockhash: Hash,
@ -252,7 +252,7 @@ pub mod solana_sdk {
} }
} }
pub fn new_signed_with_payer<T: Signers>( pub fn new_signed_with_payer<T: Signers + ?Sized>(
instructions: &[Instruction], instructions: &[Instruction],
payer: Option<&Pubkey>, payer: Option<&Pubkey>,
signing_keypairs: &T, signing_keypairs: &T,
@ -262,9 +262,9 @@ pub mod solana_sdk {
Self::new(signing_keypairs, message, recent_blockhash) Self::new(signing_keypairs, message, recent_blockhash)
} }
pub fn sign<T: Signers>(&mut self, _keypairs: &T, _recent_blockhash: Hash) {} pub fn sign<T: Signers + ?Sized>(&mut self, _keypairs: &T, _recent_blockhash: Hash) {}
pub fn try_sign<T: Signers>( pub fn try_sign<T: Signers + ?Sized>(
&mut self, &mut self,
_keypairs: &T, _keypairs: &T,
_recent_blockhash: Hash, _recent_blockhash: Hash,

View File

@ -34,7 +34,7 @@ pub trait Client: SyncClient + AsyncClient {
pub trait SyncClient { pub trait SyncClient {
/// Create a transaction from the given message, and send it to the /// Create a transaction from the given message, and send it to the
/// server, retrying as-needed. /// server, retrying as-needed.
fn send_and_confirm_message<T: Signers>( fn send_and_confirm_message<T: Signers + ?Sized>(
&self, &self,
keypairs: &T, keypairs: &T,
message: Message, message: Message,
@ -204,7 +204,7 @@ pub trait AsyncClient {
/// Create a transaction from the given message, and send it to the /// Create a transaction from the given message, and send it to the
/// server, but don't wait for to see if the server accepted it. /// server, but don't wait for to see if the server accepted it.
fn async_send_message<T: Signers>( fn async_send_message<T: Signers + ?Sized>(
&self, &self,
keypairs: &T, keypairs: &T,
message: Message, message: Message,

View File

@ -346,7 +346,7 @@ impl Transaction {
/// # /// #
/// # Ok::<(), anyhow::Error>(()) /// # Ok::<(), anyhow::Error>(())
/// ``` /// ```
pub fn new<T: Signers>( pub fn new<T: Signers + ?Sized>(
from_keypairs: &T, from_keypairs: &T,
message: Message, message: Message,
recent_blockhash: Hash, recent_blockhash: Hash,
@ -501,7 +501,7 @@ impl Transaction {
/// # /// #
/// # Ok::<(), anyhow::Error>(()) /// # Ok::<(), anyhow::Error>(())
/// ``` /// ```
pub fn new_signed_with_payer<T: Signers>( pub fn new_signed_with_payer<T: Signers + ?Sized>(
instructions: &[Instruction], instructions: &[Instruction],
payer: Option<&Pubkey>, payer: Option<&Pubkey>,
signing_keypairs: &T, signing_keypairs: &T,
@ -526,7 +526,7 @@ impl Transaction {
/// ///
/// Panics when signing fails. See [`Transaction::try_sign`] and for a full /// Panics when signing fails. See [`Transaction::try_sign`] and for a full
/// description of failure conditions. /// description of failure conditions.
pub fn new_with_compiled_instructions<T: Signers>( pub fn new_with_compiled_instructions<T: Signers + ?Sized>(
from_keypairs: &T, from_keypairs: &T,
keys: &[Pubkey], keys: &[Pubkey],
recent_blockhash: Hash, recent_blockhash: Hash,
@ -705,7 +705,7 @@ impl Transaction {
/// # /// #
/// # Ok::<(), anyhow::Error>(()) /// # Ok::<(), anyhow::Error>(())
/// ``` /// ```
pub fn sign<T: Signers>(&mut self, keypairs: &T, recent_blockhash: Hash) { pub fn sign<T: Signers + ?Sized>(&mut self, keypairs: &T, recent_blockhash: Hash) {
if let Err(e) = self.try_sign(keypairs, recent_blockhash) { if let Err(e) = self.try_sign(keypairs, recent_blockhash) {
panic!("Transaction::sign failed with error {e:?}"); panic!("Transaction::sign failed with error {e:?}");
} }
@ -731,7 +731,7 @@ impl Transaction {
/// handle the error. See the documentation for /// handle the error. See the documentation for
/// [`Transaction::try_partial_sign`] for a full description of failure /// [`Transaction::try_partial_sign`] for a full description of failure
/// conditions. /// conditions.
pub fn partial_sign<T: Signers>(&mut self, keypairs: &T, recent_blockhash: Hash) { pub fn partial_sign<T: Signers + ?Sized>(&mut self, keypairs: &T, recent_blockhash: Hash) {
if let Err(e) = self.try_partial_sign(keypairs, recent_blockhash) { if let Err(e) = self.try_partial_sign(keypairs, recent_blockhash) {
panic!("Transaction::partial_sign failed with error {e:?}"); panic!("Transaction::partial_sign failed with error {e:?}");
} }
@ -750,7 +750,7 @@ impl Transaction {
/// ///
/// Panics if signing fails. Use [`Transaction::try_partial_sign_unchecked`] /// Panics if signing fails. Use [`Transaction::try_partial_sign_unchecked`]
/// to handle the error. /// to handle the error.
pub fn partial_sign_unchecked<T: Signers>( pub fn partial_sign_unchecked<T: Signers + ?Sized>(
&mut self, &mut self,
keypairs: &T, keypairs: &T,
positions: Vec<usize>, positions: Vec<usize>,
@ -843,7 +843,7 @@ impl Transaction {
/// # /// #
/// # Ok::<(), anyhow::Error>(()) /// # Ok::<(), anyhow::Error>(())
/// ``` /// ```
pub fn try_sign<T: Signers>( pub fn try_sign<T: Signers + ?Sized>(
&mut self, &mut self,
keypairs: &T, keypairs: &T,
recent_blockhash: Hash, recent_blockhash: Hash,
@ -906,7 +906,7 @@ impl Transaction {
/// [`PresignerError::VerificationFailure`]: crate::signer::presigner::PresignerError::VerificationFailure /// [`PresignerError::VerificationFailure`]: crate::signer::presigner::PresignerError::VerificationFailure
/// [`solana-remote-wallet`]: https://docs.rs/solana-remote-wallet/latest/ /// [`solana-remote-wallet`]: https://docs.rs/solana-remote-wallet/latest/
/// [`RemoteKeypair`]: https://docs.rs/solana-remote-wallet/latest/solana_remote_wallet/remote_keypair/struct.RemoteKeypair.html /// [`RemoteKeypair`]: https://docs.rs/solana-remote-wallet/latest/solana_remote_wallet/remote_keypair/struct.RemoteKeypair.html
pub fn try_partial_sign<T: Signers>( pub fn try_partial_sign<T: Signers + ?Sized>(
&mut self, &mut self,
keypairs: &T, keypairs: &T,
recent_blockhash: Hash, recent_blockhash: Hash,
@ -932,7 +932,7 @@ impl Transaction {
/// # Errors /// # Errors
/// ///
/// Returns an error if signing fails. /// Returns an error if signing fails.
pub fn try_partial_sign_unchecked<T: Signers>( pub fn try_partial_sign_unchecked<T: Signers + ?Sized>(
&mut self, &mut self,
keypairs: &T, keypairs: &T,
positions: Vec<usize>, positions: Vec<usize>,
@ -1668,4 +1668,22 @@ mod tests {
.unwrap_err(); .unwrap_err();
assert_eq!(err, SignerError::KeypairPubkeyMismatch); assert_eq!(err, SignerError::KeypairPubkeyMismatch);
} }
#[test]
fn test_unsized_signers() {
fn instructions_to_tx(
instructions: &[Instruction],
signers: Box<dyn Signers>,
) -> Transaction {
let pubkeys = signers.pubkeys();
let first_signer = pubkeys.first().expect("should exist");
let message = Message::new(instructions, Some(first_signer));
Transaction::new(signers.as_ref(), message, Hash::default())
}
let signer: Box<dyn Signer> = Box::new(Keypair::new());
let tx = instructions_to_tx(&[], Box::new(vec![signer]));
assert!(tx.is_signed());
}
} }

View File

@ -68,7 +68,7 @@ impl From<Transaction> for VersionedTransaction {
impl VersionedTransaction { impl VersionedTransaction {
/// Signs a versioned message and if successful, returns a signed /// Signs a versioned message and if successful, returns a signed
/// transaction. /// transaction.
pub fn try_new<T: Signers>( pub fn try_new<T: Signers + ?Sized>(
message: VersionedMessage, message: VersionedMessage,
keypairs: &T, keypairs: &T,
) -> std::result::Result<Self, SignerError> { ) -> std::result::Result<Self, SignerError> {

View File

@ -209,7 +209,7 @@ where
self.send_and_confirm_transaction(&[keypair], transaction, tries, 0) self.send_and_confirm_transaction(&[keypair], transaction, tries, 0)
} }
pub fn send_and_confirm_transaction<T: Signers>( pub fn send_and_confirm_transaction<T: Signers + ?Sized>(
&self, &self,
keypairs: &T, keypairs: &T,
transaction: &mut Transaction, transaction: &mut Transaction,
@ -340,7 +340,7 @@ where
M: ConnectionManager<ConnectionPool = P, NewConnectionConfig = C>, M: ConnectionManager<ConnectionPool = P, NewConnectionConfig = C>,
C: NewConnectionConfig, C: NewConnectionConfig,
{ {
fn send_and_confirm_message<T: Signers>( fn send_and_confirm_message<T: Signers + ?Sized>(
&self, &self,
keypairs: &T, keypairs: &T,
message: Message, message: Message,

View File

@ -437,7 +437,7 @@ where
} }
#[cfg(feature = "spinner")] #[cfg(feature = "spinner")]
pub async fn send_and_confirm_messages_with_spinner<T: Signers>( pub async fn send_and_confirm_messages_with_spinner<T: Signers + ?Sized>(
&self, &self,
messages: &[Message], messages: &[Message],
signers: &T, signers: &T,

View File

@ -158,7 +158,7 @@ where
} }
#[cfg(feature = "spinner")] #[cfg(feature = "spinner")]
pub fn send_and_confirm_messages_with_spinner<T: Signers>( pub fn send_and_confirm_messages_with_spinner<T: Signers + ?Sized>(
&self, &self,
messages: &[Message], messages: &[Message],
signers: &T, signers: &T,