Skip to content

Commit

Permalink
solana-ibc: integrate with the sealable-trie
Browse files Browse the repository at this point in the history
Add account for the sealable-trie and use it for storing data that
needs to be kept in provable storage.
  • Loading branch information
dhruvja authored Oct 18, 2023
1 parent a1c5e6d commit 87301cb
Show file tree
Hide file tree
Showing 9 changed files with 936 additions and 63 deletions.
5 changes: 5 additions & 0 deletions solana/solana-ibc/programs/solana-ibc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ ibc-proto.workspace = true
serde.workspace = true
serde_json.workspace = true

lib.workspace = true
memory.workspace = true
sealable-trie.workspace = true
stdx.workspace = true

[dev-dependencies]
anchor-client.workspace = true
anyhow.workspace = true
Expand Down
14 changes: 9 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 @@ -82,7 +82,7 @@ impl From<AnyClientState> for Any {
}
}

impl ClientStateValidation<SolanaIbcStorage> for AnyClientState {
impl ClientStateValidation<SolanaIbcStorage<'_, '_>> for AnyClientState {
fn verify_client_message(
&self,
ctx: &SolanaIbcStorage,
Expand Down Expand Up @@ -283,7 +283,7 @@ impl From<MockClientState> for AnyClientState {
fn from(value: MockClientState) -> Self { AnyClientState::Mock(value) }
}

impl ClientStateExecution<SolanaIbcStorage> for AnyClientState {
impl ClientStateExecution<SolanaIbcStorage<'_, '_>> for AnyClientState {
fn initialise(
&self,
ctx: &mut SolanaIbcStorage,
Expand Down Expand Up @@ -371,7 +371,9 @@ impl ClientStateExecution<SolanaIbcStorage> for AnyClientState {
}
}

impl ibc::clients::ics07_tendermint::CommonContext for SolanaIbcStorage {
impl ibc::clients::ics07_tendermint::CommonContext
for SolanaIbcStorage<'_, '_>
{
type ConversionError = ClientError;

type AnyConsensusState = AnyConsensusState;
Expand All @@ -385,7 +387,7 @@ impl ibc::clients::ics07_tendermint::CommonContext for SolanaIbcStorage {
}

#[cfg(any(test, feature = "mocks"))]
impl MockClientContext for SolanaIbcStorage {
impl MockClientContext for SolanaIbcStorage<'_, '_> {
type ConversionError = ClientError;
type AnyConsensusState = AnyConsensusState;

Expand All @@ -401,7 +403,9 @@ impl MockClientContext for SolanaIbcStorage {
}
}

impl ibc::clients::ics07_tendermint::ValidationContext for SolanaIbcStorage {
impl ibc::clients::ics07_tendermint::ValidationContext
for SolanaIbcStorage<'_, '_>
{
fn host_timestamp(&self) -> Result<Timestamp, ContextError> {
ValidationContext::host_timestamp(self)
}
Expand Down
118 changes: 112 additions & 6 deletions solana/solana-ibc/programs/solana-ibc/src/execution_context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::BTreeMap;

use anchor_lang::emit;
use anchor_lang::prelude::borsh;
use anchor_lang::solana_program::msg;
use ibc::core::events::IbcEvent;
use ibc::core::ics02_client::ClientExecutionContext;
Expand All @@ -24,14 +25,15 @@ use ibc::Height;

use crate::client_state::AnyClientState;
use crate::consensus_state::AnyConsensusState;
use crate::trie_key::TrieKey;
use crate::{
EmitIBCEvent, HostHeight, InnerChannelId, InnerHeight, InnerPortId,
InnerSequence, SolanaIbcStorage, SolanaTimestamp,
};

type Result<T = (), E = ibc::core::ContextError> = core::result::Result<T, E>;

impl ClientExecutionContext for SolanaIbcStorage {
impl ClientExecutionContext for SolanaIbcStorage<'_, '_> {
type ClientValidationContext = Self;
type AnyClientState = AnyClientState;
type AnyConsensusState = AnyConsensusState;
Expand All @@ -49,7 +51,23 @@ impl ClientExecutionContext for SolanaIbcStorage {
let client_state_key = client_state_path.0.to_string();
let serialized_client_state =
serde_json::to_string(&client_state).unwrap();

let client_state_trie_key = &TrieKey::ClientState {
client_id: client_state_path.0.to_string(),
}
.to_vec();
let trie = self.trie.as_mut().unwrap();
msg!(
"THis is serialized client state {}",
&lib::hash::CryptoHash::digest(serialized_client_state.as_bytes())
);
trie.set(
client_state_trie_key,
&lib::hash::CryptoHash::digest(serialized_client_state.as_bytes()),
)
.unwrap();
self.clients.insert(client_state_key, serialized_client_state);
self.client_id_set.push(client_state_path.0.to_string());
Ok(())
}

Expand All @@ -69,6 +87,22 @@ impl ClientExecutionContext for SolanaIbcStorage {
);
let serialized_consensus_state =
serde_json::to_string(&consensus_state).unwrap();

let consensus_state_trie_key = &TrieKey::ConsensusState {
client_id: consensus_state_path.client_id.to_string(),
height: consensus_state_path.height,
epoch: consensus_state_path.epoch,
}
.to_vec();
let trie = self.trie.as_mut().unwrap();
trie.set(
consensus_state_trie_key,
&lib::hash::CryptoHash::digest(
serialized_consensus_state.as_bytes(),
),
)
.unwrap();

self.consensus_states
.insert(consensus_state_key, serialized_consensus_state);
self.height.0 = consensus_state_path.epoch;
Expand All @@ -77,7 +111,7 @@ impl ClientExecutionContext for SolanaIbcStorage {
}
}

impl ExecutionContext for SolanaIbcStorage {
impl ExecutionContext for SolanaIbcStorage<'_, '_> {
fn increase_client_counter(&mut self) -> Result {
self.client_counter.checked_add(1).unwrap();
msg!("client_counter has increased to: {}", self.client_counter);
Expand Down Expand Up @@ -168,10 +202,21 @@ impl ExecutionContext for SolanaIbcStorage {
connection_path,
connection_end
);
self.connections.insert(
connection_path.0.to_string(),
serde_json::to_string(&connection_end).unwrap(),
);

let serialized_connection_end =
serde_json::to_string(&connection_end).unwrap();
let connection_trie_key = &TrieKey::from(connection_path).to_vec();
let trie = self.trie.as_mut().unwrap();
trie.set(
connection_trie_key,
&lib::hash::CryptoHash::digest(
serialized_connection_end.as_bytes(),
),
)
.unwrap();

self.connections
.insert(connection_path.0.to_string(), serialized_connection_end);
Ok(())
}

Expand Down Expand Up @@ -209,6 +254,14 @@ impl ExecutionContext for SolanaIbcStorage {
commitment_path,
commitment
);
let commitment_trie_key = &TrieKey::from(commitment_path).to_vec();
let trie = self.trie.as_mut().unwrap();
trie.set(
commitment_trie_key,
&lib::hash::CryptoHash::digest(&commitment.into_vec()),
)
.unwrap();

record_packet_sequence(
&mut self.packet_commitment_sequence_sets,
&commitment_path.port_id,
Expand Down Expand Up @@ -247,6 +300,10 @@ impl ExecutionContext for SolanaIbcStorage {
receipt_path,
receipt
);
let receipt_trie_key = &TrieKey::from(receipt_path).to_vec();
let trie = self.trie.as_mut().unwrap();
trie.set(receipt_trie_key, &lib::hash::CryptoHash::DEFAULT).unwrap();
trie.seal(receipt_trie_key).unwrap();
record_packet_sequence(
&mut self.packet_receipt_sequence_sets,
&receipt_path.port_id,
Expand All @@ -266,6 +323,13 @@ impl ExecutionContext for SolanaIbcStorage {
ack_path,
ack_commitment
);
let ack_commitment_trie_key = &TrieKey::from(ack_path).to_vec();
let trie = self.trie.as_mut().unwrap();
trie.set(
ack_commitment_trie_key,
&lib::hash::CryptoHash::digest(&ack_commitment.into_vec()),
)
.unwrap();
record_packet_sequence(
&mut self.packet_acknowledgement_sequence_sets,
&ack_path.port_id,
Expand Down Expand Up @@ -302,6 +366,16 @@ impl ExecutionContext for SolanaIbcStorage {
channel_end_path.0.clone().to_string(),
channel_end_path.1.clone().to_string(),
));

let serialized_channel_end = borsh::to_vec(&channel_end).unwrap();
let channel_end_trie_key = &TrieKey::from(channel_end_path).to_vec();
let trie = self.trie.as_mut().unwrap();
trie.set(
channel_end_trie_key,
&lib::hash::CryptoHash::digest(&serialized_channel_end),
)
.unwrap();

self.channel_ends.insert(
(channel_end_path.0.to_string(), channel_end_path.1.to_string()),
serde_json::to_string(&channel_end).unwrap(),
Expand All @@ -321,6 +395,18 @@ impl ExecutionContext for SolanaIbcStorage {
);
let seq_send_key =
(seq_send_path.0.to_string(), seq_send_path.1.to_string());

let next_seq_send_trie_key = &TrieKey::from(seq_send_path).to_vec();
let trie = self.trie.as_mut().unwrap();
let seq_in_u64: u64 = seq.into();
let seq_in_bytes = seq_in_u64.to_be_bytes();

trie.set(
next_seq_send_trie_key,
&lib::hash::CryptoHash::digest(&seq_in_bytes),
)
.unwrap();

self.next_sequence_send.insert(seq_send_key, u64::from(seq));
Ok(())
}
Expand All @@ -337,6 +423,16 @@ impl ExecutionContext for SolanaIbcStorage {
);
let seq_recv_key =
(seq_recv_path.0.to_string(), seq_recv_path.1.to_string());
let next_seq_recv_trie_key = &TrieKey::from(seq_recv_path).to_vec();
let trie = self.trie.as_mut().unwrap();
let seq_in_u64: u64 = seq.into();
let seq_in_bytes = seq_in_u64.to_be_bytes();

trie.set(
next_seq_recv_trie_key,
&lib::hash::CryptoHash::digest(&seq_in_bytes),
)
.unwrap();
self.next_sequence_recv.insert(seq_recv_key, u64::from(seq));
Ok(())
}
Expand All @@ -349,6 +445,16 @@ impl ExecutionContext for SolanaIbcStorage {
msg!("store_next_sequence_ack: path: {}, seq: {:?}", seq_ack_path, seq);
let seq_ack_key =
(seq_ack_path.0.to_string(), seq_ack_path.1.to_string());
let next_seq_ack_trie_key = &TrieKey::from(seq_ack_path).to_vec();
let trie = self.trie.as_mut().unwrap();
let seq_in_u64: u64 = seq.into();
let seq_in_bytes = seq_in_u64.to_be_bytes();

trie.set(
next_seq_ack_trie_key,
&lib::hash::CryptoHash::digest(&seq_in_bytes),
)
.unwrap();
self.next_sequence_ack.insert(seq_ack_key, u64::from(seq));
Ok(())
}
Expand Down
Loading

0 comments on commit 87301cb

Please sign in to comment.