Merge pull request from GHSA-8v47-8c53-wwrc
* Track transaction check time separately from account loads * banking packet process metrics * Remove signature clone in status cache lookup * Reduce allocations when converting packets to transactions * Add blake3 hash of transaction messages in status cache * Bug fixes * fix tests and run fmt * Address feedback * fix simd tx entry verification * Fix rebase * Feedback * clean up * Add tests * Remove feature switch and fall back to signature check * Bump programs/bpf Cargo.lock * clippy * nudge benches * Bump `BankSlotDelta` frozen ABI hash` * Add blake3 to sdk/programs/Cargo.lock * nudge bpf tests * short circuit status cache checks Co-authored-by: Trent Nelson <trent@solana.com>
This commit is contained in:
@ -39,9 +39,9 @@ impl Packet {
|
||||
Self { data, meta }
|
||||
}
|
||||
|
||||
pub fn from_data<T: Serialize>(dest: &SocketAddr, data: T) -> Result<Self> {
|
||||
pub fn from_data<T: Serialize>(dest: Option<&SocketAddr>, data: T) -> Result<Self> {
|
||||
let mut packet = Packet::default();
|
||||
Self::populate_packet(&mut packet, Some(dest), &data)?;
|
||||
Self::populate_packet(&mut packet, dest, &data)?;
|
||||
Ok(packet)
|
||||
}
|
||||
|
||||
|
@ -50,11 +50,11 @@ pub enum TransactionError {
|
||||
#[error("This account may not be used to pay transaction fees")]
|
||||
InvalidAccountForFee,
|
||||
|
||||
/// The bank has seen this `Signature` before. This can occur under normal operation
|
||||
/// The bank has seen this transaction before. This can occur under normal operation
|
||||
/// when a UDP packet is duplicated, as a user error from a client not updating
|
||||
/// its `recent_blockhash`, or as a double-spend attack.
|
||||
#[error("The bank has seen this signature before")]
|
||||
DuplicateSignature,
|
||||
#[error("This transaction has already been processed")]
|
||||
AlreadyProcessed,
|
||||
|
||||
/// The bank has not seen the given `recent_blockhash` or the transaction is too old and
|
||||
/// the `recent_blockhash` has been discarded.
|
||||
@ -317,18 +317,11 @@ impl Transaction {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn verify_with_results(&self) -> Vec<bool> {
|
||||
self.signatures
|
||||
.iter()
|
||||
.zip(&self.message.account_keys)
|
||||
.map(|(signature, pubkey)| signature.verify(pubkey.as_ref(), &self.message_data()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Verify the transaction
|
||||
pub fn verify(&self) -> Result<()> {
|
||||
let message_bytes = self.message_data();
|
||||
if !self
|
||||
.verify_with_results()
|
||||
._verify_with_results(&message_bytes)
|
||||
.iter()
|
||||
.all(|verify_result| *verify_result)
|
||||
{
|
||||
@ -338,6 +331,32 @@ impl Transaction {
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify the transaction and hash its message
|
||||
pub fn verify_and_hash_message(&self) -> Result<Hash> {
|
||||
let message_bytes = self.message_data();
|
||||
if !self
|
||||
._verify_with_results(&message_bytes)
|
||||
.iter()
|
||||
.all(|verify_result| *verify_result)
|
||||
{
|
||||
Err(TransactionError::SignatureFailure)
|
||||
} else {
|
||||
Ok(Message::hash_raw_message(&message_bytes))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify_with_results(&self) -> Vec<bool> {
|
||||
self._verify_with_results(&self.message_data())
|
||||
}
|
||||
|
||||
pub(crate) fn _verify_with_results(&self, message_bytes: &[u8]) -> Vec<bool> {
|
||||
self.signatures
|
||||
.iter()
|
||||
.zip(&self.message.account_keys)
|
||||
.map(|(signature, pubkey)| signature.verify(pubkey.as_ref(), message_bytes))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn verify_precompiles(&self) -> Result<()> {
|
||||
for instruction in &self.message().instructions {
|
||||
// The Transaction may not be sanitized at this point
|
||||
|
Reference in New Issue
Block a user