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 {
($(#[$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]
$(#[$meta])*
$vis fn $name$(<$($t: $cons),*>)?(&self $(, $arg:$ty)*) $(-> $out)? {
$vis fn $name$(<$($t: $cons + ?Sized),*>)?(&self $(, $arg:$ty)*) $(-> $out)? {
match self {
Self::Quic(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]
$(#[$meta])*
$vis fn $name$(<$($t: $cons),*>)?(&mut self $(, $arg:$ty)*) $(-> $out)? {
$vis fn $name$(<$($t: $cons + ?Sized),*>)?(&mut self $(, $arg:$ty)*) $(-> $out)? {
match self {
Self::Quic(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,
messages: &[Message],
signers: &T,

View File

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

View File

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

View File

@ -213,7 +213,7 @@ pub mod solana_sdk {
}
impl VersionedTransaction {
pub fn try_new<T: Signers>(
pub fn try_new<T: Signers + ?Sized>(
message: VersionedMessage,
_keypairs: &T,
) -> std::result::Result<Self, SignerError> {
@ -230,7 +230,7 @@ pub mod solana_sdk {
}
impl Transaction {
pub fn new<T: Signers>(
pub fn new<T: Signers + ?Sized>(
_from_keypairs: &T,
_message: Message,
_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],
payer: Option<&Pubkey>,
signing_keypairs: &T,
@ -262,9 +262,9 @@ pub mod solana_sdk {
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,
_keypairs: &T,
_recent_blockhash: Hash,

View File

@ -34,7 +34,7 @@ pub trait Client: SyncClient + AsyncClient {
pub trait SyncClient {
/// Create a transaction from the given message, and send it to the
/// server, retrying as-needed.
fn send_and_confirm_message<T: Signers>(
fn send_and_confirm_message<T: Signers + ?Sized>(
&self,
keypairs: &T,
message: Message,
@ -204,7 +204,7 @@ pub trait AsyncClient {
/// 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.
fn async_send_message<T: Signers>(
fn async_send_message<T: Signers + ?Sized>(
&self,
keypairs: &T,
message: Message,

View File

@ -346,7 +346,7 @@ impl Transaction {
/// #
/// # Ok::<(), anyhow::Error>(())
/// ```
pub fn new<T: Signers>(
pub fn new<T: Signers + ?Sized>(
from_keypairs: &T,
message: Message,
recent_blockhash: Hash,
@ -501,7 +501,7 @@ impl Transaction {
/// #
/// # Ok::<(), anyhow::Error>(())
/// ```
pub fn new_signed_with_payer<T: Signers>(
pub fn new_signed_with_payer<T: Signers + ?Sized>(
instructions: &[Instruction],
payer: Option<&Pubkey>,
signing_keypairs: &T,
@ -526,7 +526,7 @@ impl Transaction {
///
/// Panics when signing fails. See [`Transaction::try_sign`] and for a full
/// description of failure conditions.
pub fn new_with_compiled_instructions<T: Signers>(
pub fn new_with_compiled_instructions<T: Signers + ?Sized>(
from_keypairs: &T,
keys: &[Pubkey],
recent_blockhash: Hash,
@ -705,7 +705,7 @@ impl Transaction {
/// #
/// # 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) {
panic!("Transaction::sign failed with error {e:?}");
}
@ -731,7 +731,7 @@ impl Transaction {
/// handle the error. See the documentation for
/// [`Transaction::try_partial_sign`] for a full description of failure
/// 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) {
panic!("Transaction::partial_sign failed with error {e:?}");
}
@ -750,7 +750,7 @@ impl Transaction {
///
/// Panics if signing fails. Use [`Transaction::try_partial_sign_unchecked`]
/// to handle the error.
pub fn partial_sign_unchecked<T: Signers>(
pub fn partial_sign_unchecked<T: Signers + ?Sized>(
&mut self,
keypairs: &T,
positions: Vec<usize>,
@ -843,7 +843,7 @@ impl Transaction {
/// #
/// # Ok::<(), anyhow::Error>(())
/// ```
pub fn try_sign<T: Signers>(
pub fn try_sign<T: Signers + ?Sized>(
&mut self,
keypairs: &T,
recent_blockhash: Hash,
@ -906,7 +906,7 @@ impl Transaction {
/// [`PresignerError::VerificationFailure`]: crate::signer::presigner::PresignerError::VerificationFailure
/// [`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
pub fn try_partial_sign<T: Signers>(
pub fn try_partial_sign<T: Signers + ?Sized>(
&mut self,
keypairs: &T,
recent_blockhash: Hash,
@ -932,7 +932,7 @@ impl Transaction {
/// # Errors
///
/// 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,
keypairs: &T,
positions: Vec<usize>,
@ -1668,4 +1668,22 @@ mod tests {
.unwrap_err();
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 {
/// Signs a versioned message and if successful, returns a signed
/// transaction.
pub fn try_new<T: Signers>(
pub fn try_new<T: Signers + ?Sized>(
message: VersionedMessage,
keypairs: &T,
) -> std::result::Result<Self, SignerError> {

View File

@ -209,7 +209,7 @@ where
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,
keypairs: &T,
transaction: &mut Transaction,
@ -340,7 +340,7 @@ where
M: ConnectionManager<ConnectionPool = P, NewConnectionConfig = C>,
C: NewConnectionConfig,
{
fn send_and_confirm_message<T: Signers>(
fn send_and_confirm_message<T: Signers + ?Sized>(
&self,
keypairs: &T,
message: Message,

View File

@ -437,7 +437,7 @@ where
}
#[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,
messages: &[Message],
signers: &T,

View File

@ -158,7 +158,7 @@ where
}
#[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,
messages: &[Message],
signers: &T,