Move untested code out of SDK

verify_signature() was only used in a test that was testing
binary layout. It only worked because the test transaction only
had one signature.

from() was only used by verify_signature() and that's something
we'd typically called `pubkey()`.

hash() didn't return the hash of the Transaction, as you might
guess. It's only used for PoH, so move it into Entry.
This commit is contained in:
Greg Fitzgerald
2019-03-28 13:37:41 -06:00
parent 0482f153d0
commit 2ab50cbae8
4 changed files with 16 additions and 28 deletions

View File

@ -4,7 +4,7 @@
use crate::cluster_info::ClusterInfo; use crate::cluster_info::ClusterInfo;
use crate::entry; use crate::entry;
use crate::entry::Entry; use crate::entry::{hash_transactions, Entry};
use crate::leader_schedule_utils; use crate::leader_schedule_utils;
use crate::packet; use crate::packet;
use crate::packet::SharedPackets; use crate::packet::SharedPackets;
@ -236,7 +236,7 @@ impl BankingStage {
debug!("processed: {} ", processed_transactions.len()); debug!("processed: {} ", processed_transactions.len());
// unlock all the accounts with errors which are filtered by the above `filter_map` // unlock all the accounts with errors which are filtered by the above `filter_map`
if !processed_transactions.is_empty() { if !processed_transactions.is_empty() {
let hash = Transaction::hash(&processed_transactions); let hash = hash_transactions(&processed_transactions);
// record and unlock will unlock all the successfull transactions // record and unlock will unlock all the successfull transactions
poh.lock() poh.lock()
.unwrap() .unwrap()

View File

@ -9,7 +9,7 @@ use bincode::{deserialize, serialized_size};
use chrono::prelude::Utc; use chrono::prelude::Utc;
use rayon::prelude::*; use rayon::prelude::*;
use solana_budget_api::budget_instruction::BudgetInstruction; use solana_budget_api::budget_instruction::BudgetInstruction;
use solana_sdk::hash::Hash; use solana_sdk::hash::{Hash, Hasher};
use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::transaction::Transaction; use solana_sdk::transaction::Transaction;
use std::borrow::Borrow; use std::borrow::Borrow;
@ -155,6 +155,17 @@ impl Entry {
} }
} }
pub fn hash_transactions(transactions: &[Transaction]) -> Hash {
// a hash of a slice of transactions only needs to hash the signatures
let mut hasher = Hasher::default();
transactions.iter().for_each(|tx| {
if !tx.signatures.is_empty() {
hasher.hash(&tx.signatures[0].as_ref());
}
});
hasher.result()
}
/// Creates the hash `num_hashes` after `start_hash`. If the transaction contains /// Creates the hash `num_hashes` after `start_hash`. If the transaction contains
/// a signature, the final hash will be a hash of both the previous ID and /// a signature, the final hash will be a hash of both the previous ID and
/// the signature. If num_hashes is zero and there's no transaction data, /// the signature. If num_hashes is zero and there's no transaction data,
@ -173,7 +184,7 @@ fn next_hash(start_hash: &Hash, num_hashes: u64, transactions: &[Transaction]) -
if transactions.is_empty() { if transactions.is_empty() {
poh.tick().hash poh.tick().hash
} else { } else {
poh.record(Transaction::hash(transactions)).hash poh.record(hash_transactions(transactions)).hash
} }
} }

View File

@ -392,7 +392,6 @@ mod tests {
Some(sig_start as usize) Some(sig_start as usize)
); );
assert_eq!(sig_len, 1); assert_eq!(sig_len, 1);
assert!(tx.verify_signature());
} }
#[test] #[test]

View File

@ -1,6 +1,6 @@
//! Defines a Transaction type to package an atomic sequence of instructions. //! Defines a Transaction type to package an atomic sequence of instructions.
use crate::hash::{Hash, Hasher}; use crate::hash::Hash;
use crate::instruction::{CompiledInstruction, Instruction, InstructionError}; use crate::instruction::{CompiledInstruction, Instruction, InstructionError};
use crate::message::Message; use crate::message::Message;
use crate::packet::PACKET_DATA_SIZE; use crate::packet::PACKET_DATA_SIZE;
@ -215,13 +215,6 @@ impl Transaction {
self.sign_unchecked(keypairs, recent_blockhash); self.sign_unchecked(keypairs, recent_blockhash);
} }
/// Verify only the transaction signature.
pub fn verify_signature(&self) -> bool {
self.signatures
.iter()
.all(|s| s.verify(&self.from().as_ref(), &self.message()))
}
/// Verify that references in the instructions are valid /// Verify that references in the instructions are valid
pub fn verify_refs(&self) -> bool { pub fn verify_refs(&self) -> bool {
for instruction in &self.instructions { for instruction in &self.instructions {
@ -237,21 +230,6 @@ impl Transaction {
true true
} }
pub fn from(&self) -> &Pubkey {
&self.account_keys[0]
}
// a hash of a slice of transactions only needs to hash the signatures
pub fn hash(transactions: &[Transaction]) -> Hash {
let mut hasher = Hasher::default();
transactions.iter().for_each(|tx| {
if !tx.signatures.is_empty() {
hasher.hash(&tx.signatures[0].as_ref());
}
});
hasher.result()
}
pub fn serialized_size(&self) -> Result<u64, Error> { pub fn serialized_size(&self) -> Result<u64, Error> {
let mut buf = [0u8; size_of::<u64>() + 1]; let mut buf = [0u8; size_of::<u64>() + 1];
let mut wr = Cursor::new(&mut buf[..]); let mut wr = Cursor::new(&mut buf[..]);