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:
Justin Starry
2021-04-13 14:28:08 +08:00
committed by GitHub
parent 70f3f7e679
commit 85eb37fab0
30 changed files with 938 additions and 617 deletions

View File

@ -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)
}

View File

@ -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