Skip to content

Commit

Permalink
added from impl for trie key
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvja committed Oct 18, 2023
1 parent b04dac9 commit b7bb648
Show file tree
Hide file tree
Showing 5 changed files with 286 additions and 226 deletions.
86 changes: 11 additions & 75 deletions solana/solana-ibc/programs/solana-ibc/src/execution_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@ 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, TrieKey,
InnerSequence, SolanaIbcStorage, SolanaTimestamp,
};

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

const CONNECTION_ID_PREFIX: &str = "connection-";
const CHANNEL_ID_PREFIX: &str = "channel-";

impl ClientExecutionContext for SolanaIbcStorage<'_, '_> {
type ClientValidationContext = Self;
type AnyClientState = AnyClientState;
Expand Down Expand Up @@ -205,18 +203,12 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {

let serialized_connection_end =
serde_json::to_string(&connection_end).unwrap();
let connection_prefix_length = CONNECTION_ID_PREFIX.len();
let connection_id =
&connection_path.0.to_string()[connection_prefix_length..];
let consensus_state_trie_key = &TrieKey::Connection {
connection_id: connection_id.parse().unwrap(),
}
.to_vec();
let connection_trie_key = &TrieKey::from(connection_path).to_vec();
let trie = self.trie.as_mut().unwrap();
let consensus_state_hash =
borsh::to_vec(&serialized_connection_end).unwrap();
trie.set(
consensus_state_trie_key,
connection_trie_key,
&lib::hash::CryptoHash::digest(&consensus_state_hash),
)
.unwrap();
Expand Down Expand Up @@ -260,16 +252,7 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {
commitment_path,
commitment
);
let channel_prefix_length = CHANNEL_ID_PREFIX.len();
let channel_id =
&commitment_path.channel_id.to_string()[channel_prefix_length..];

let commitment_trie_key = &TrieKey::Commitment {
port_id: commitment_path.port_id.clone().to_string(),
channel_id: channel_id.parse().unwrap(),
sequence: u64::from(commitment_path.sequence),
}
.to_vec();
let commitment_trie_key = &TrieKey::from(commitment_path).to_vec();
let trie = self.trie.as_mut().unwrap();
trie.set(
commitment_trie_key,
Expand Down Expand Up @@ -315,16 +298,7 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {
receipt_path,
receipt
);
let channel_prefix_length = CHANNEL_ID_PREFIX.len();
let channel_id =
&receipt_path.channel_id.to_string()[channel_prefix_length..];

let receipt_trie_key = &TrieKey::Receipts {
port_id: receipt_path.port_id.clone().to_string(),
channel_id: channel_id.parse().unwrap(),
sequence: u64::from(receipt_path.sequence),
}
.to_vec();
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();
Expand All @@ -347,16 +321,7 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {
ack_path,
ack_commitment
);
let channel_prefix_length = CHANNEL_ID_PREFIX.len();
let channel_id =
&ack_path.channel_id.to_string()[channel_prefix_length..];

let ack_commitment_trie_key = &TrieKey::Acks {
port_id: ack_path.port_id.clone().to_string(),
channel_id: channel_id.parse().unwrap(),
sequence: u64::from(ack_path.sequence),
}
.to_vec();
let ack_commitment_trie_key = &TrieKey::from(ack_path).to_vec();
let trie = self.trie.as_mut().unwrap();
trie.set(
ack_commitment_trie_key,
Expand Down Expand Up @@ -402,15 +367,7 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {

let serialized_channel_end =
serde_json::to_string(&channel_end).unwrap();
let channel_prefix_length = CHANNEL_ID_PREFIX.len();
let channel_id =
&channel_end_path.1.to_string()[channel_prefix_length..];

let channel_end_trie_key = &TrieKey::ChannelEnd {
port_id: channel_end_path.0.clone().to_string(),
channel_id: channel_id.parse().unwrap(),
}
.to_vec();
let channel_end_trie_key = &TrieKey::from(channel_end_path).to_vec();
let trie = self.trie.as_mut().unwrap();
let channel_end_hash = borsh::to_vec(&serialized_channel_end).unwrap();
trie.set(
Expand Down Expand Up @@ -439,14 +396,7 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {
let seq_send_key =
(seq_send_path.0.to_string(), seq_send_path.1.to_string());

let channel_prefix_length = CHANNEL_ID_PREFIX.len();
let channel_id = &seq_send_path.1.to_string()[channel_prefix_length..];

let next_seq_send_trie_key = &TrieKey::NextSequenceSend {
port_id: seq_send_path.0.clone().to_string(),
channel_id: channel_id.parse().unwrap(),
}
.to_vec();
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();
Expand All @@ -473,14 +423,7 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {
);
let seq_recv_key =
(seq_recv_path.0.to_string(), seq_recv_path.1.to_string());
let channel_prefix_length = CHANNEL_ID_PREFIX.len();
let channel_id = &seq_recv_path.1.to_string()[channel_prefix_length..];

let next_seq_recv_trie_key = &TrieKey::NextSequenceRecv {
port_id: seq_recv_path.0.clone().to_string(),
channel_id: channel_id.parse().unwrap(),
}
.to_vec();
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();
Expand All @@ -502,14 +445,7 @@ 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 channel_prefix_length = CHANNEL_ID_PREFIX.len();
let channel_id = &seq_ack_path.1.to_string()[channel_prefix_length..];

let next_seq_ack_trie_key = &TrieKey::NextSequenceAck {
port_id: seq_ack_path.0.clone().to_string(),
channel_id: channel_id.parse().unwrap(),
}
.to_vec();
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();
Expand Down
152 changes: 6 additions & 146 deletions solana/solana-ibc/programs/solana-ibc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
#![allow(clippy::result_large_err)]

use std::collections::BTreeMap;
use std::mem::size_of;

use anchor_lang::prelude::*;
use borsh::{BorshDeserialize, BorshSerialize};
use ibc::core::ics24_host::identifier::PortId;

use ibc::core::router::{Module, ModuleId, Router};
use module_holder::ModuleHolder;

const SOLANA_IBC_STORAGE_SEED: &[u8] = b"solana_ibc_storage";
const TEST_TRIE_SEED: &[u8] = b"test_trie";
pub const CONNECTION_ID_PREFIX: &str = "connection-";
pub const CHANNEL_ID_PREFIX: &str = "channel-";

declare_id!("EnfDJsAK7BGgetnmKzBx86CsgC5kfSPcsktFCQ4YLC81");

Expand All @@ -24,6 +26,7 @@ mod module_holder;
mod tests;
mod transfer;
mod trie;
mod trie_key;
mod validation_context;
// mod client_context;

Expand Down Expand Up @@ -167,8 +170,7 @@ pub mod solana_ibc {
solana_ibc_store.clients = solana_real_storage.clients.clone();
solana_ibc_store.client_id_set =
solana_real_storage.client_id_set.clone();
solana_ibc_store.client_counter =
solana_real_storage.client_counter;
solana_ibc_store.client_counter = solana_real_storage.client_counter;
solana_ibc_store.client_processed_times =
solana_real_storage.client_processed_times.clone();
solana_ibc_store.client_processed_heights =
Expand All @@ -188,8 +190,7 @@ pub mod solana_ibc {
solana_real_storage.connection_to_client.clone();
solana_ibc_store.port_channel_id_set =
solana_real_storage.port_channel_id_set.clone();
solana_ibc_store.channel_counter =
solana_real_storage.channel_counter;
solana_ibc_store.channel_counter = solana_real_storage.channel_counter;
solana_ibc_store.next_sequence_send =
solana_real_storage.next_sequence_send.clone();
solana_ibc_store.next_sequence_recv =
Expand Down Expand Up @@ -228,147 +229,6 @@ pub struct Deliver<'info> {
pub system_program: Program<'info, System>,
}

pub enum TrieKey {
ClientState { client_id: String },
ConsensusState { client_id: String, epoch: u64, height: u64 },
Connection { connection_id: u32 },
ChannelEnd { port_id: String, channel_id: u32 },
NextSequenceSend { port_id: String, channel_id: u32 },
NextSequenceRecv { port_id: String, channel_id: u32 },
NextSequenceAck { port_id: String, channel_id: u32 },
Commitment { port_id: String, channel_id: u32, sequence: u64 },
Receipts { port_id: String, channel_id: u32, sequence: u64 },
Acks { port_id: String, channel_id: u32, sequence: u64 },
}

#[repr(u8)]
pub enum TrieKeyWithoutFields {
ClientState = 1,
ConsensusState = 2,
Connection = 3,
ChannelEnd = 4,
NextSequenceSend = 5,
NextSequenceRecv = 6,
NextSequenceAck = 7,
Commitment = 8,
Receipts = 9,
Acks = 10,
}


impl TrieKey {
fn len(&self) -> usize {
size_of::<u8>() +
match self {
TrieKey::ClientState { client_id } => client_id.len(),
TrieKey::ConsensusState { client_id, epoch: _u64, height: _ } => {
client_id.len() + size_of::<u64>() + size_of::<u64>()
}
TrieKey::Connection { connection_id: _ } => size_of::<u32>(),
TrieKey::ChannelEnd { port_id, channel_id: _ } => {
port_id.len() + size_of::<u32>()
}
TrieKey::NextSequenceSend { port_id, channel_id: _ } => {
port_id.len() + size_of::<u32>()
}
TrieKey::NextSequenceRecv { port_id, channel_id: _ } => {
port_id.len() + size_of::<u32>()
}
TrieKey::NextSequenceAck { port_id, channel_id: _ } => {
port_id.len() + size_of::<u32>()
}
TrieKey::Commitment { port_id, channel_id: _, sequence: _ } => {
port_id.len() + size_of::<u32>() + size_of::<u64>()
}
TrieKey::Receipts { port_id, channel_id: _, sequence: _ } => {
port_id.len() + size_of::<u32>() + size_of::<u64>()
}
TrieKey::Acks { port_id, channel_id: _, sequence: _ } => {
port_id.len() + size_of::<u32>() + size_of::<u64>()
}
}
}

pub fn append_into(&self, buf: &mut Vec<u8>) {
let expected_len = self.len();
let start_len = buf.len();
buf.reserve(self.len());
match self {
TrieKey::ClientState { client_id } => {
buf.push(TrieKeyWithoutFields::ClientState as u8);
buf.extend(client_id.as_bytes());
}
TrieKey::ConsensusState { client_id, epoch, height } => {
buf.push(TrieKeyWithoutFields::ConsensusState as u8);
buf.extend(client_id.as_bytes());
buf.push(TrieKeyWithoutFields::ConsensusState as u8);
buf.extend(height.to_be_bytes());
buf.push(TrieKeyWithoutFields::ConsensusState as u8);
buf.extend(epoch.to_be_bytes())
}
TrieKey::Connection { connection_id } => {
buf.push(TrieKeyWithoutFields::Connection as u8);
buf.extend(connection_id.to_be_bytes())
}
TrieKey::ChannelEnd { port_id, channel_id } => {
buf.push(TrieKeyWithoutFields::ChannelEnd as u8);
buf.extend(port_id.as_bytes());
buf.push(TrieKeyWithoutFields::ChannelEnd as u8);
buf.extend(channel_id.to_be_bytes());
}
TrieKey::NextSequenceSend { port_id, channel_id } => {
buf.push(TrieKeyWithoutFields::NextSequenceSend as u8);
buf.extend(port_id.as_bytes());
buf.push(TrieKeyWithoutFields::NextSequenceSend as u8);
buf.extend(channel_id.to_be_bytes());
}
TrieKey::NextSequenceRecv { port_id, channel_id } => {
buf.push(TrieKeyWithoutFields::NextSequenceRecv as u8);
buf.extend(port_id.as_bytes());
buf.push(TrieKeyWithoutFields::NextSequenceRecv as u8);
buf.extend(channel_id.to_be_bytes());
}
TrieKey::NextSequenceAck { port_id, channel_id } => {
buf.push(TrieKeyWithoutFields::NextSequenceAck as u8);
buf.extend(port_id.as_bytes());
buf.push(TrieKeyWithoutFields::NextSequenceAck as u8);
buf.extend(channel_id.to_be_bytes());
}
TrieKey::Commitment { port_id, channel_id, sequence } => {
buf.push(TrieKeyWithoutFields::Commitment as u8);
buf.extend(port_id.as_bytes());
buf.push(TrieKeyWithoutFields::Commitment as u8);
buf.extend(channel_id.to_be_bytes());
buf.push(TrieKeyWithoutFields::Commitment as u8);
buf.extend(sequence.to_be_bytes());
}
TrieKey::Receipts { port_id, channel_id, sequence } => {
buf.push(TrieKeyWithoutFields::Receipts as u8);
buf.extend(port_id.as_bytes());
buf.push(TrieKeyWithoutFields::Receipts as u8);
buf.extend(channel_id.to_be_bytes());
buf.push(TrieKeyWithoutFields::Receipts as u8);
buf.extend(sequence.to_be_bytes());
}
TrieKey::Acks { port_id, channel_id, sequence } => {
buf.push(TrieKeyWithoutFields::Acks as u8);
buf.extend(port_id.as_bytes());
buf.push(TrieKeyWithoutFields::Acks as u8);
buf.extend(channel_id.to_be_bytes());
buf.push(TrieKeyWithoutFields::Acks as u8);
buf.extend(sequence.to_be_bytes());
}
}
debug_assert_eq!(expected_len, buf.len() - start_len);
}

pub fn to_vec(&self) -> Vec<u8> {
let mut buf = Vec::with_capacity(self.len());
self.append_into(&mut buf);
buf
}
}

#[event]
pub struct EmitIBCEvent {
pub ibc_event: Vec<u8>,
Expand Down
4 changes: 2 additions & 2 deletions solana/solana-ibc/programs/solana-ibc/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use ibc::Any;
use ibc_proto::protobuf::Protobuf;

use crate::{
accounts, instruction, AnyCheck, SolanaIbcStorageTemp,
ID, SOLANA_IBC_STORAGE_SEED, TEST_TRIE_SEED,
accounts, instruction, AnyCheck, SolanaIbcStorageTemp, ID,
SOLANA_IBC_STORAGE_SEED, TEST_TRIE_SEED,
};

const TYPE_URL: &str = "/ibc.core.client.v1.MsgCreateClient";
Expand Down
5 changes: 2 additions & 3 deletions solana/solana-ibc/programs/solana-ibc/src/trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ use core::cell::RefMut;
use core::mem::ManuallyDrop;
use std::result::Result;

#[cfg(test)]
use anchor_lang::solana_program;
use lib::hash::CryptoHash;
use memory::Ptr;

use crate::magic;

#[cfg(test)]
use anchor_lang::solana_program;

type DataRef<'a, 'b> = RefMut<'a, &'b mut [u8]>;

const SZ: usize = sealable_trie::nodes::RawNode::SIZE;
Expand Down
Loading

0 comments on commit b7bb648

Please sign in to comment.