Skip to content

Commit

Permalink
storing data in trie in execution context
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvja committed Oct 18, 2023
1 parent 36b1ad2 commit e9e18ae
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 28 deletions.
153 changes: 151 additions & 2 deletions solana/solana-ibc/programs/solana-ibc/src/execution_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ use crate::{

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

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

const DEFAULT_PORT_ID: &str = "defaultPort";
const TRANSFER_PORT_ID: &str = "transfer";

impl ClientExecutionContext for SolanaIbcStorage<'_, '_> {
type ClientValidationContext = Self;
type AnyClientState = AnyClientState;
Expand Down Expand Up @@ -84,6 +90,21 @@ 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();
let consensus_state_hash =
borsh::to_vec(&serialized_consensus_state).unwrap();
trie.set(
&consensus_state_trie_key,
&lib::hash::CryptoHash::digest(&consensus_state_hash),
)
.unwrap();

self.consensus_states
.insert(consensus_state_key, serialized_consensus_state);
self.height.0 = consensus_state_path.epoch;
Expand Down Expand Up @@ -183,9 +204,26 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {
connection_path,
connection_end
);

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 trie = self.trie.as_mut().unwrap();
let consensus_state_hash =
borsh::to_vec(&serialized_connection_end).unwrap();
trie.set(
&consensus_state_trie_key,
&lib::hash::CryptoHash::digest(&consensus_state_hash),
)
.unwrap();

self.connections.insert(
connection_path.0.to_string(),
serde_json::to_string(&connection_end).unwrap(),
serialized_connection_end
);
Ok(())
}
Expand Down Expand Up @@ -224,6 +262,21 @@ 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 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 @@ -262,6 +315,19 @@ 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 trie = self.trie.as_mut().unwrap();
trie.set(
&receipt_trie_key,
&lib::hash::CryptoHash::DEFAULT,
).unwrap();
record_packet_sequence(
&mut self.packet_receipt_sequence_sets,
&receipt_path.port_id,
Expand All @@ -281,6 +347,20 @@ 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 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 @@ -317,6 +397,25 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {
channel_end_path.0.clone().to_string(),
channel_end_path.1.clone().to_string(),
));

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 trie = self.trie.as_mut().unwrap();
let channel_end_hash =
borsh::to_vec(&serialized_channel_end).unwrap();
trie.set(
&channel_end_trie_key,
&lib::hash::CryptoHash::digest(&channel_end_hash),
)
.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 @@ -336,6 +435,24 @@ 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 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 @@ -351,7 +468,23 @@ impl ExecutionContext for SolanaIbcStorage<'_, '_> {
seq
);
let seq_recv_key =
(seq_recv_path.0.to_string(), seq_recv_path.1.to_string());
(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 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 @@ -364,6 +497,22 @@ 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 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
56 changes: 30 additions & 26 deletions solana/solana-ibc/programs/solana-ibc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,15 @@ pub struct Deliver<'info> {

pub enum TrieKey {
ClientState { client_id: String },
ConsensusState { client_id: String, height: u64 },
ConsensusState { client_id: String, epoch: u64, height: u64 },
Connection { connection_id: u32 },
ChannelEnd { port_id: u32, channel_id: u32 },
NextSequenceSend { port_id: u32, channel_id: u32 },
NextSequenceRecv { port_id: u32, channel_id: u32 },
NextSequenceAck { port_id: u32, channel_id: u32 },
Commitment { port_id: u32, channel_id: u32, sequence: u64 },
Receipts { port_id: u32, channel_id: u32, sequence: u64 },
Acks { port_id: u32, channel_id: u32, sequence: u64 },
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)]
Expand All @@ -261,30 +261,30 @@ impl TrieKey {
size_of::<u8>() +
match self {
TrieKey::ClientState { client_id } => client_id.len(),
TrieKey::ConsensusState { client_id, height } => {
client_id.len() + size_of::<u64>()
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 } => {
size_of::<u32>() + size_of::<u32>()
port_id.len() + size_of::<u32>()
}
TrieKey::NextSequenceSend { port_id, channel_id } => {
size_of::<u32>() + size_of::<u32>()
port_id.len() + size_of::<u32>()
}
TrieKey::NextSequenceRecv { port_id, channel_id } => {
size_of::<u32>() + size_of::<u32>()
port_id.len() + size_of::<u32>()
}
TrieKey::NextSequenceAck { port_id, channel_id } => {
size_of::<u32>() + size_of::<u32>()
port_id.len() + size_of::<u32>()
}
TrieKey::Commitment { port_id, channel_id, sequence } => {
size_of::<u32>() + size_of::<u32>() + size_of::<u64>()
port_id.len() + size_of::<u32>() + size_of::<u64>()
}
TrieKey::Receipts { port_id, channel_id, sequence } => {
size_of::<u32>() + size_of::<u32>() + size_of::<u64>()
port_id.len() + size_of::<u32>() + size_of::<u64>()
}
TrieKey::Acks { port_id, channel_id, sequence } => {
size_of::<u32>() + size_of::<u32>() + size_of::<u64>()
port_id.len() + size_of::<u32>() + size_of::<u64>()
}
}
}
Expand All @@ -298,57 +298,61 @@ impl TrieKey {
buf.push(TrieKeyWithoutFields::ClientState as u8);
buf.extend(client_id.as_bytes());
}
TrieKey::ConsensusState { client_id, height } => {
TrieKey::ConsensusState { client_id, epoch, height } => {
buf.push(TrieKeyWithoutFields::ConsensusState as u8);
buf.extend(height.to_be_bytes())
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.to_be_bytes());
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.to_be_bytes());
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.to_be_bytes());
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.to_be_bytes());
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.to_be_bytes());
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.to_be_bytes());
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.to_be_bytes());
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);
Expand Down

0 comments on commit e9e18ae

Please sign in to comment.