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-ibc: introduce Serialised wrapper in storage #101

Merged
merged 3 commits into from
Nov 18, 2023
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
7 changes: 2 additions & 5 deletions solana/solana-ibc/programs/solana-ibc/src/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,11 +544,8 @@ impl IbcStorage<'_, '_> {
let store = self.borrow();
let mut range = store.private.consensus_states.range(range);
if dir == Direction::Next { range.next() } else { range.next_back() }
.map(|(_, data)| borsh::BorshDeserialize::try_from_slice(data))
.map(|(_, data)| data.get())
.transpose()
.map_err(|err| err.to_string())
.map_err(|description| {
ContextError::from(ClientError::ClientSpecific { description })
})
.map_err(|err| err.into())
}
}
117 changes: 50 additions & 67 deletions solana/solana-ibc/programs/solana-ibc/src/execution_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,40 +37,30 @@ impl ClientExecutionContext for IbcStorage<'_, '_> {
fn store_client_state(
&mut self,
path: ClientStatePath,
client_state: Self::AnyClientState,
state: Self::AnyClientState,
) -> Result {
msg!("store_client_state({}, {:?})", path, client_state);
let mut store = self.borrow_mut();
let serialized = store_serialised_proof(
&mut store.provable,
msg!("store_client_state({}, {:?})", path, state);
self.borrow_mut().store_serialised_proof(
|private| &mut private.clients,
path.0.to_string(),
&TrieKey::from(&path),
&client_state,
)?;
let key = path.0.to_string();
store.private.clients.insert(key.clone(), serialized);
Ok(())
&state,
)
}

fn store_consensus_state(
&mut self,
path: ClientConsensusStatePath,
consensus_state: Self::AnyConsensusState,
state: Self::AnyConsensusState,
) -> Result {
msg!(
"store_consensus_state - path: {}, consensus_state: {:?}",
path,
consensus_state
);
let mut store = self.borrow_mut();
let serialized = store_serialised_proof(
&mut store.provable,
&TrieKey::from(&path),
&consensus_state,
)?;
msg!("store_consensus_state({}, {:?})", path, state);
let height = Height::new(path.epoch, path.height)?;
let key = (path.client_id.to_string(), height);
store.private.consensus_states.insert(key, serialized);
Ok(())
self.borrow_mut().store_serialised_proof(
|private| &mut private.consensus_states,
(path.client_id.to_string(), height),
&TrieKey::from(&path),
&state,
)
}

fn delete_consensus_state(
Expand Down Expand Up @@ -164,14 +154,12 @@ impl ExecutionContext for IbcStorage<'_, '_> {
connection_end: ConnectionEnd,
) -> Result {
msg!("store_connection({}, {:?})", path, connection_end);
let mut store = self.borrow_mut();
let serialized = store_serialised_proof(
&mut store.provable,
self.borrow_mut().store_serialised_proof(
|private| &mut private.connections,
path.0.to_string(),
&TrieKey::from(path),
&connection_end,
)?;
store.private.connections.insert(path.0.to_string(), serialized);
Ok(())
)
}

fn store_connection_to_client(
Expand Down Expand Up @@ -289,15 +277,12 @@ impl ExecutionContext for IbcStorage<'_, '_> {
channel_end: ChannelEnd,
) -> Result {
msg!("store_channel({}, {:?})", path, channel_end);
let mut store = self.borrow_mut();
let serialized = store_serialised_proof(
&mut store.provable,
self.borrow_mut().store_serialised_proof(
|private| &mut private.channel_ends,
(path.0.to_string(), path.1.to_string()),
&TrieKey::from(path),
&channel_end,
)?;
let key = (path.0.to_string(), path.1.to_string());
store.private.channel_ends.insert(key.clone(), serialized);
Ok(())
)
}

fn store_next_sequence_send(
Expand All @@ -308,7 +293,7 @@ impl ExecutionContext for IbcStorage<'_, '_> {
msg!("store_next_sequence_send: path: {}, seq: {}", path, seq);
self.borrow_mut().store_next_sequence(
path.into(),
crate::storage::SequenceTripleIdx::Send,
storage::SequenceTripleIdx::Send,
seq,
)
}
Expand All @@ -321,7 +306,7 @@ impl ExecutionContext for IbcStorage<'_, '_> {
msg!("store_next_sequence_recv: path: {}, seq: {}", path, seq);
self.borrow_mut().store_next_sequence(
path.into(),
crate::storage::SequenceTripleIdx::Recv,
storage::SequenceTripleIdx::Recv,
seq,
)
}
Expand All @@ -334,7 +319,7 @@ impl ExecutionContext for IbcStorage<'_, '_> {
msg!("store_next_sequence_ack: path: {}, seq: {}", path, seq);
self.borrow_mut().store_next_sequence(
path.into(),
crate::storage::SequenceTripleIdx::Ack,
storage::SequenceTripleIdx::Ack,
seq,
)
}
Expand Down Expand Up @@ -362,11 +347,11 @@ impl ExecutionContext for IbcStorage<'_, '_> {
fn get_client_execution_context(&mut self) -> &mut Self::E { self }
}

impl crate::storage::IbcStorageInner<'_, '_> {
impl storage::IbcStorageInner<'_, '_> {
fn store_next_sequence(
&mut self,
path: crate::trie_key::SequencePath<'_>,
index: crate::storage::SequenceTripleIdx,
index: storage::SequenceTripleIdx,
seq: Sequence,
) -> Result {
let trie = &mut self.provable;
Expand All @@ -380,32 +365,30 @@ impl crate::storage::IbcStorageInner<'_, '_> {

Ok(())
}
}

/// Serialises value and stores its hash in trie under given key. Returns the
/// serialised value.
fn store_serialised_proof(
trie: &mut crate::storage::AccountTrie<'_, '_>,
key: &TrieKey,
value: &impl borsh::BorshSerialize,
) -> Result<Vec<u8>> {
fn store_impl(
trie: &mut crate::storage::AccountTrie<'_, '_>,
key: &TrieKey,
value: borsh::maybestd::io::Result<Vec<u8>>,
) -> Result<Vec<u8>> {
value
.map_err(|err| err.to_string())
.and_then(|value| {
let hash = lib::hash::CryptoHash::digest(&value);
trie.set(key, &hash)
.map(|()| value)
.map_err(|err| err.to_string())
})
.map_err(|description| ClientError::Other { description })
.map_err(ContextError::ClientError)
/// Serialises `value` and stores it in private storage along with its
/// commitment in provable storage.
///
/// Serialises `value` and a) stores hash of the serialised object (i.e. its
/// commitment) in the provable storage under key `trie_key` and b) stores
/// the serialised object itself in map returned my `get_map` under the key
/// `key`.
fn store_serialised_proof<K: Ord, V: borsh::BorshSerialize>(
&mut self,
get_map: impl FnOnce(
&mut storage::PrivateStorage,
) -> &mut BTreeMap<K, storage::Serialised<V>>,
key: K,
trie_key: &TrieKey,
value: &V,
) -> Result {
let serialised = storage::Serialised::new(value)?;
self.provable
.set(trie_key, &serialised.digest())
.map_err(|e| ClientError::Other { description: e.to_string() })?;
get_map(self.private).insert(key, serialised);
Ok(())
}
store_impl(trie, key, borsh::to_vec(value))
}

type SequencesMap =
Expand Down
6 changes: 2 additions & 4 deletions solana/solana-ibc/programs/solana-ibc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ const TRIE_SEED: &[u8] = b"trie";
const CONNECTION_ID_PREFIX: &str = "connection-";
const CHANNEL_ID_PREFIX: &str = "channel-";

use crate::storage::IBCPackets;

declare_id!("EnfDJsAK7BGgetnmKzBx86CsgC5kfSPcsktFCQ4YLC81");

mod chain;
Expand Down Expand Up @@ -122,7 +120,7 @@ pub mod solana_ibc {
let private: &mut storage::PrivateStorage = &mut ctx.accounts.storage;
msg!("This is private: {:?}", private);
let provable = storage::get_provable_from(&ctx.accounts.trie, "trie")?;
let packets: &mut IBCPackets = &mut ctx.accounts.packets;
let packets = &mut ctx.accounts.packets;
let host_head = host::Head::get()?;

// Before anything else, try generating a new guest block. However, if
Expand Down Expand Up @@ -227,7 +225,7 @@ pub struct Deliver<'info> {

/// The account holding packets.
#[account(init_if_needed, payer = sender, seeds = [PACKET_SEED], bump, space = 1000)]
packets: Account<'info, IBCPackets>,
packets: Account<'info, storage::IbcPackets>,

/// The guest blockchain data.
#[account(init_if_needed, payer = sender, seeds = [CHAIN_SEED], bump, space = 10000)]
Expand Down
Loading
Loading