Store address table lookups in blockstore and bigtable (#22402)

This commit is contained in:
Justin Starry
2022-01-14 15:24:41 +08:00
committed by GitHub
parent 4c577d7f8c
commit f804ccdece
28 changed files with 836 additions and 199 deletions

View File

@ -48,6 +48,9 @@ pub enum SignerError {
#[error("{0}")]
UserCancel(String),
#[error("too many signers")]
TooManySigners,
}
/// The `Signer` trait declares operations that all digital signature providers

View File

@ -176,6 +176,14 @@ impl SanitizedTransaction {
account_locks
}
/// Return the list of addresses loaded from on-chain address lookup tables
pub fn get_loaded_addresses(&self) -> LoadedAddresses {
match &self.message {
SanitizedMessage::Legacy(_) => LoadedAddresses::default(),
SanitizedMessage::V0(message) => message.loaded_addresses.clone(),
}
}
/// If the transaction uses a durable nonce, return the pubkey of the nonce account
pub fn get_durable_nonce(&self, nonce_must_be_writable: bool) -> Option<&Pubkey> {
self.message.get_durable_nonce(nonce_must_be_writable)

View File

@ -9,6 +9,8 @@ use {
sanitize::{Sanitize, SanitizeError},
short_vec,
signature::Signature,
signer::SignerError,
signers::Signers,
transaction::{Result, Transaction, TransactionError},
},
serde::Serialize,
@ -57,6 +59,40 @@ impl From<Transaction> for VersionedTransaction {
}
impl VersionedTransaction {
/// Signs a versioned message and if successful, returns a signed
/// transaction.
pub fn try_new<T: Signers>(
message: VersionedMessage,
keypairs: &T,
) -> std::result::Result<Self, SignerError> {
let static_account_keys = message.static_account_keys();
if static_account_keys.len() < message.header().num_required_signatures as usize {
return Err(SignerError::InvalidInput("invalid message".to_string()));
}
let signer_keys = keypairs.pubkeys();
let expected_signer_keys =
&static_account_keys[0..message.header().num_required_signatures as usize];
match signer_keys.len().cmp(&expected_signer_keys.len()) {
Ordering::Greater => Err(SignerError::TooManySigners),
Ordering::Less => Err(SignerError::NotEnoughSigners),
Ordering::Equal => Ok(()),
}?;
if signer_keys != expected_signer_keys {
return Err(SignerError::KeypairPubkeyMismatch);
}
let message_data = message.serialize();
let signatures = keypairs.try_sign_message(&message_data)?;
Ok(Self {
signatures,
message,
})
}
/// Returns a legacy transaction if the transaction message is legacy.
pub fn into_legacy_transaction(self) -> Option<Transaction> {
match self.message {