Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

solana-trie: add support for witness account #387

Merged
merged 4 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions common/cf-guest/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<PK: guestchain::PubKey> ClientState<PK> {
is_frozen: bool,
) -> Self {
let prev_epoch_commitment =
prev_epoch_commitment.unwrap_or_else(|| epoch_commitment.clone());
prev_epoch_commitment.unwrap_or(epoch_commitment);
Self {
genesis_hash,
latest_height,
Expand All @@ -60,11 +60,11 @@ impl<PK: guestchain::PubKey> ClientState<PK> {

#[cfg(test)]
pub fn from_genesis(genesis: &guestchain::BlockHeader) -> Self {
let epoch_commitment = genesis.next_epoch_commitment.clone().unwrap();
let prev_epoch_commitment = epoch_commitment.clone();
let epoch_commitment = genesis.next_epoch_commitment.unwrap();
let prev_epoch_commitment = epoch_commitment;
Self {
genesis_hash: genesis.calc_hash(),
latest_height: genesis.block_height.into(),
latest_height: genesis.block_height,
trusting_period_ns: 24 * 3600 * 1_000_000_000,
epoch_commitment,
prev_epoch_commitment,
Expand All @@ -89,8 +89,8 @@ impl<PK: guestchain::PubKey> ClientState<PK> {
// accept headers from Epoch which has just ended (i.e. this header
// is the last block of) and the Epoch that has just started.
if let Some(ref next) = header.block_header.next_epoch_commitment {
this.prev_epoch_commitment = this.epoch_commitment.clone();
this.epoch_commitment = next.clone();
this.prev_epoch_commitment = this.epoch_commitment;
this.epoch_commitment = *next;
}
}
this
Expand Down Expand Up @@ -139,7 +139,7 @@ impl<PK: guestchain::PubKey> TryFrom<&proto::ClientState> for ClientState<PK> {
let genesis_hash = make_hash(&msg.genesis_hash)?;
let epoch_commitment = make_hash(&msg.epoch_commitment)?;
let prev_epoch_commitment = if msg.prev_epoch_commitment.is_empty() {
epoch_commitment.clone()
epoch_commitment
} else {
make_hash(&msg.prev_epoch_commitment)?
};
Expand Down
13 changes: 3 additions & 10 deletions common/cf-guest/src/client/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,7 @@ fn test_header_misbehaviour() {
let (fp, mut header) = {
let current = current.unwrap_or(&ctx.genesis);
let host_height = u64::from(current.host_height) + 1;
ctx.generate_next(
current,
host_height.into(),
timestamp,
state_root,
)
ctx.generate_next(current, host_height, timestamp, state_root)
};
header.signatures.push((0, ctx.sign(0, &fp)));
header.signatures.push((1, ctx.sign(1, &fp)));
Expand Down Expand Up @@ -200,7 +195,7 @@ impl TestContext {
let validators = epoch
.validators()
.iter()
.map(|validator| MockSigner(validator.pubkey.clone()))
.map(|validator| MockSigner(validator.pubkey))
.collect::<Vec<_>>();

let genesis = guestchain::BlockHeader::generate_genesis(
Expand Down Expand Up @@ -231,9 +226,7 @@ impl TestContext {
this
}

fn genesis_hash(&self) -> CryptoHash {
self.client_state.genesis_hash.clone()
}
fn genesis_hash(&self) -> CryptoHash { self.client_state.genesis_hash }

fn generate_next(
&self,
Expand Down
4 changes: 2 additions & 2 deletions common/cf-guest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl<PK: PubKey> Header<PK> {
base: Option<&Self>,
) -> Result<Self, proto::BadMessage> {
let genesis_hash = if msg.genesis_hash.is_empty() {
base.ok_or(proto::BadMessage)?.genesis_hash.clone()
base.ok_or(proto::BadMessage)?.genesis_hash
} else {
lib::hash::CryptoHash::try_from(msg.genesis_hash.as_slice())
.map_err(|_| proto::BadMessage)?
Expand All @@ -138,7 +138,7 @@ impl<PK: PubKey> Header<PK> {

let (epoch_commitment, epoch) = if msg.epoch.is_empty() {
let base = base.ok_or(proto::BadMessage)?;
(base.epoch_commitment.clone(), base.epoch.clone())
(base.epoch_commitment, base.epoch.clone())
} else {
let bytes = msg.epoch.as_slice();
let epoch = borsh::BorshDeserialize::try_from_slice(bytes)
Expand Down
20 changes: 8 additions & 12 deletions common/cf-guest/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl<'a> GenerateContext for &'a BlockHeader {

impl GenerateContext for () {
fn get_root(self, root: &CryptoHash) -> Result<CryptoHash, GenerateError> {
Ok(root.clone())
Ok(*root)
}
fn serialise_proof(
self,
Expand Down Expand Up @@ -282,7 +282,7 @@ fn verify_impl<const WITH_BLOCK: bool>(
} else {
let proof: sealable_trie::proof::Proof =
borsh::BorshDeserialize::deserialize_reader(&mut proof_bytes)?;
(root.clone(), proof)
(*root, proof)
};

let value = if let Some(value) = value {
Expand Down Expand Up @@ -356,7 +356,7 @@ mod tests {
impl Trie {
fn set(&mut self, key: &[u8], value: CryptoHash) {
self.trie.set(key, &value).unwrap();
self.header.state_root = self.trie.hash().clone();
self.header.state_root = *self.trie.hash();
}

fn root(&self) -> &CryptoHash { self.trie.hash() }
Expand All @@ -369,14 +369,10 @@ mod tests {
) -> IbcProof {
let mut bytes = proof.proof.as_slice();
let mut hdr = BlockHeader::deserialize_reader(&mut bytes).unwrap();
hdr.state_root = state_root.clone();
hdr.state_root = *state_root;
let mut buf = borsh::to_vec(&hdr).unwrap();
buf.extend_from_slice(bytes);
IbcProof {
proof: buf,
root: hdr.calc_hash(),
value: proof.value.clone(),
}
IbcProof { proof: buf, root: hdr.calc_hash(), value: proof.value }
}

fn generate(
Expand Down Expand Up @@ -421,7 +417,7 @@ mod tests {
guestchain::BlockHeight::from(0),
guestchain::HostHeight::from(42),
core::num::NonZeroU64::new(24).unwrap(),
trie.hash().clone(),
*trie.hash(),
CryptoHash::test(86),
),
trie,
Expand All @@ -443,7 +439,7 @@ mod tests {

// Verify non-membership fails if value is inserted.
let key = trie_ids::PathInfo::try_from(path.clone()).unwrap().key;
trie.set(&key, stored_hash.clone());
trie.set(&key, *stored_hash);

if for_block {
// Generate proof with block header with new state root, but use the
Expand Down Expand Up @@ -576,7 +572,7 @@ mod tests {
for_block,
&[],
&proof.proof,
&CryptoHash::test(11).as_slice(),
CryptoHash::test(11).as_slice(),
path.clone(),
Some(value),
)
Expand Down
15 changes: 7 additions & 8 deletions common/cf-solana/src/blake3.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub use ::blake3::Hasher;

use crate::types::Hash;
use lib::hash::CryptoHash;

const CONSIDER_SOL: bool =
!cfg!(feature = "no-blake3-syscall") && cfg!(target_os = "solana-program");
Expand All @@ -13,11 +12,11 @@ const USE_SOL: bool = CONSIDER_SOL && HAS_SOL;
/// When `solana-program` or `solana-program-2` feature is enabled and
/// building a solana program, this is using Solana’s `sol_blake3` syscall.
/// Otherwise, the calculation is done by `blake3` crate.
pub fn hash(bytes: &[u8]) -> Hash {
pub fn hash(bytes: &[u8]) -> CryptoHash {
if USE_SOL {
hashv(&[bytes])
} else {
Hash(::blake3::hash(bytes).into())
CryptoHash(::blake3::hash(bytes).into())
}
}

Expand All @@ -27,17 +26,17 @@ pub fn hash(bytes: &[u8]) -> Hash {
/// program, this is using Solana’s `sol_blake3` syscall. Otherwise, the
/// calculation is done by `blake3` crate.
#[allow(unreachable_code)]
pub fn hashv(slices: &[&[u8]]) -> Hash {
pub fn hashv(slices: &[&[u8]]) -> CryptoHash {
if USE_SOL {
#[cfg(feature = "solana-program-2")]
return Hash(solana_program_2::blake3::hashv(slices).0);
return CryptoHash(solana_program_2::blake3::hashv(slices).0);
#[cfg(feature = "solana-program")]
return Hash(solana_program::blake3::hashv(slices).0);
return CryptoHash(solana_program::blake3::hashv(slices).0);
}

let mut hasher = Hasher::default();
for bytes in slices {
hasher.update(bytes);
}
hasher.finalize().into()
CryptoHash(hasher.finalize().into())
}
4 changes: 1 addition & 3 deletions common/cf-solana/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ impl TryFrom<&crate::Header> for ConsensusState {

fn try_from(header: &crate::Header) -> Result<Self, Self::Error> {
header.decode_witness().ok_or(proto::BadMessage).map(
|(trie_root, timestamp_sec)| {
Self::new(trie_root.into(), timestamp_sec)
},
|(trie_root, timestamp_sec)| Self::new(trie_root, timestamp_sec),
)
}
}
Expand Down
18 changes: 9 additions & 9 deletions common/cf-solana/src/header.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use alloc::vec::Vec;
use core::num::NonZeroU64;

use crate::types::Hash;
use lib::hash::CryptoHash;

use crate::{proof, proto};

/// The consensus header of the guest blockchain.
Expand All @@ -14,7 +15,7 @@ pub struct Header {
pub slot: NonZeroU64,

/// Slot’s bank hash.
pub bank_hash: Hash,
pub bank_hash: CryptoHash,

/// Proof of the accounts delta hash.
pub delta_hash_proof: proof::DeltaHashProof,
Expand All @@ -33,13 +34,12 @@ impl Header {
/// trie and Solana block timestamp in seconds.
///
/// Returns None if the witness account data has unexpected format
/// (e.g. it’s not 40-byte long). See `WitnessedData` in
/// `solana-witnessed-trie`.
// TODO(mina86): Ideally we would use wittrie::api::WitnessedData here but
// wittrie depends on Solana and we don’t want to introduce required Solana
// dependencies here. Moving WitnessData to a crate in common/ is an option
// but for the time being we’re duplicating the logic here.
pub fn decode_witness(&self) -> Option<(&Hash, NonZeroU64)> {
/// (e.g. it’s not 40-byte long). See `witness::Data` in solana-trie.
// TODO(mina86): Ideally we would use solana_trie::witness::Data here but
// solana_trie depends on Solana and we don’t want to introduce required
// Solana dependencies here. Moving witness::Data to a crate in common/ is
// an option but for the time being we’re duplicating the logic here.
pub fn decode_witness(&self) -> Option<(&CryptoHash, NonZeroU64)> {
let data =
self.witness_proof.account_hash_data.data().try_into().ok()?;
let (root, rest) = stdx::split_array_ref::<32, 8, 40>(data);
Expand Down
Loading
Loading