v1.5: Use blake3 message hash in status cache (#16513)
* v1.5: Use blake3 message hash in status cache * bump bpf ix count
This commit is contained in:
@@ -11,6 +11,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.3.1"
|
||||
blake3 = "0.3.7"
|
||||
borsh = "0.8.1"
|
||||
borsh-derive = "0.8.1"
|
||||
bs58 = "0.3.1"
|
||||
@@ -32,7 +33,8 @@ solana-sdk-macro = { path = "../macro", version = "=1.5.19" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[target.'cfg(not(target_arch = "bpf"))'.dependencies]
|
||||
curve25519-dalek = { version = "2.1.0" }
|
||||
blake3 = "0.3.6"
|
||||
curve25519-dalek = "2.1.0"
|
||||
rand = "0.7.0"
|
||||
solana-logger = { path = "../../logger", version = "=1.5.19" }
|
||||
|
||||
|
@@ -5,11 +5,12 @@ use crate::serialize_utils::{
|
||||
append_slice, append_u16, append_u8, read_pubkey, read_slice, read_u16, read_u8,
|
||||
};
|
||||
use crate::{
|
||||
hash::Hash,
|
||||
hash::{Hash, HASH_BYTES},
|
||||
instruction::{AccountMeta, CompiledInstruction, Instruction},
|
||||
pubkey::Pubkey,
|
||||
short_vec, system_instruction,
|
||||
};
|
||||
use blake3::traits::digest::Digest;
|
||||
use itertools::Itertools;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
@@ -272,6 +273,20 @@ impl Message {
|
||||
Self::new(&instructions, payer)
|
||||
}
|
||||
|
||||
/// Compute the blake3 hash of this transaction's message
|
||||
pub fn hash(&self) -> Hash {
|
||||
let message_bytes = self.serialize();
|
||||
Self::hash_raw_message(&message_bytes)
|
||||
}
|
||||
|
||||
/// Compute the blake3 hash of a raw transaction message
|
||||
pub fn hash_raw_message(message_bytes: &[u8]) -> Hash {
|
||||
let mut hasher = blake3::Hasher::new();
|
||||
hasher.update(b"solana-tx-message-v1");
|
||||
hasher.update(message_bytes);
|
||||
Hash(<[u8; HASH_BYTES]>::try_from(hasher.finalize().as_slice()).unwrap())
|
||||
}
|
||||
|
||||
pub fn compile_instruction(&self, ix: &Instruction) -> CompiledInstruction {
|
||||
compile_instruction(ix, &self.account_keys)
|
||||
}
|
||||
@@ -453,6 +468,7 @@ impl Message {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::instruction::AccountMeta;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn test_message_unique_program_ids() {
|
||||
@@ -896,4 +912,36 @@ mod tests {
|
||||
assert!(message.is_non_loader_key(&key1, 1));
|
||||
assert!(!message.is_non_loader_key(&loader2, 2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_message_hash() {
|
||||
// when this test fails, it's most likely due to a new serialized format of a message.
|
||||
// in this case, the domain prefix `solana-tx-message-v1` should be updated.
|
||||
let program_id0 = Pubkey::from_str("4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM").unwrap();
|
||||
let program_id1 = Pubkey::from_str("8opHzTAnfzRpPEx21XtnrVTX28YQuCpAjcn1PczScKh").unwrap();
|
||||
let id0 = Pubkey::from_str("CiDwVBFgWV9E5MvXWoLgnEgn2hK7rJikbvfWavzAQz3").unwrap();
|
||||
let id1 = Pubkey::from_str("GcdayuLaLyrdmUu324nahyv33G5poQdLUEZ1nEytDeP").unwrap();
|
||||
let id2 = Pubkey::from_str("LX3EUdRUBUa3TbsYXLEUdj9J3prXkWXvLYSWyYyc2Jj").unwrap();
|
||||
let id3 = Pubkey::from_str("QRSsyMWN1yHT9ir42bgNZUNZ4PdEhcSWCrL2AryKpy5").unwrap();
|
||||
let instructions = vec![
|
||||
Instruction::new_with_bincode(program_id0, &0, vec![AccountMeta::new(id0, false)]),
|
||||
Instruction::new_with_bincode(program_id0, &0, vec![AccountMeta::new(id1, true)]),
|
||||
Instruction::new_with_bincode(
|
||||
program_id1,
|
||||
&0,
|
||||
vec![AccountMeta::new_readonly(id2, false)],
|
||||
),
|
||||
Instruction::new_with_bincode(
|
||||
program_id1,
|
||||
&0,
|
||||
vec![AccountMeta::new_readonly(id3, true)],
|
||||
),
|
||||
];
|
||||
|
||||
let message = Message::new(&instructions, Some(&id1));
|
||||
assert_eq!(
|
||||
message.hash(),
|
||||
Hash::from_str("CXRH7GHLieaQZRUjH1mpnNnUZQtU4V4RpJpAFgy77i3z").unwrap()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user