Skip to content

Commit

Permalink
solana-ibc: refactor events handling
Browse files Browse the repository at this point in the history
Firstly, remove ibc_events_history from the storage.  The field only
ever grows which isn’t sustainable.  The contract has no use for the
field and off-chain customers should look at history of Solana logs
rather than looking at the field.

Secondly, encode the IBC event directly in an event struct rather than
first borsh serialising it and then emitting that.  Since emitting
causes another borsh serialisation this leads to somewhat awkward and
unnecessary double serialisation.

Lastly, use Solana logging directly rather than using Anchor’s logging
infrastructure.  Anchor really doesn’t give us much as far as I can
tell and having an enum with all possible events which is serialised
is just as if not more convenient.
  • Loading branch information
mina86 committed Nov 9, 2023
1 parent 6488fa9 commit 6051af3
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 27 deletions.
1 change: 1 addition & 0 deletions solana/solana-ibc/programs/solana-ibc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mocks = ["ibc/mocks", "ibc/std"]
anchor-lang.workspace = true
base64.workspace = true
bytemuck.workspace = true
derive_more.workspace = true
ibc-proto.workspace = true
ibc.workspace = true
serde.workspace = true
Expand Down
29 changes: 29 additions & 0 deletions solana/solana-ibc/programs/solana-ibc/src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use anchor_lang::prelude::borsh;
use anchor_lang::solana_program;

/// Possible events emitted by the smart contract.
///
/// The events are logged in their borsh-serialised form.
#[derive(
Clone,
PartialEq,
Eq,
borsh::BorshSerialize,
borsh::BorshDeserialize,
derive_more::From,
)]
pub enum Event {
IBCEvent(ibc::core::events::IbcEvent),
}

impl Event {
pub fn emit(&self) -> Result<(), String> {
borsh::BorshSerialize::try_to_vec(self)
.map(|data| solana_program::log::sol_log_data(&[data.as_slice()]))
.map_err(|err| err.to_string())
}
}

pub fn emit(event: impl Into<Event>) -> Result<(), String> {
event.into().emit()
}
20 changes: 2 additions & 18 deletions solana/solana-ibc/programs/solana-ibc/src/execution_context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use alloc::collections::BTreeMap;

use anchor_lang::emit;
use anchor_lang::prelude::borsh;
use anchor_lang::solana_program::msg;
use ibc::core::events::IbcEvent;
Expand All @@ -27,7 +26,6 @@ use crate::client_state::AnyClientState;
use crate::consensus_state::AnyConsensusState;
use crate::storage::{self, IbcStorage};
use crate::trie_key::TrieKey;
use crate::EmitIBCEvent;

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

Expand Down Expand Up @@ -382,22 +380,8 @@ impl ExecutionContext for IbcStorage<'_, '_> {
}

fn emit_ibc_event(&mut self, event: IbcEvent) -> Result {
let mut store = self.borrow_mut();
let host_height =
ibc::Height::new(store.private.height.0, store.private.height.1)?;
let ibc_event = borsh::to_vec(&event).map_err(|err| {
ClientError::Other { description: err.to_string() }
})?;
let inner_host_height =
(host_height.revision_height(), host_height.revision_number());
store
.private
.ibc_events_history
.entry(inner_host_height)
.or_default()
.push(ibc_event.clone());
emit!(EmitIBCEvent { ibc_event });
Ok(())
crate::events::emit(event)
.map_err(|description| ClientError::Other { description }.into())
}

fn log_message(&mut self, message: String) -> Result {
Expand Down
6 changes: 1 addition & 5 deletions solana/solana-ibc/programs/solana-ibc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ declare_id!("EnfDJsAK7BGgetnmKzBx86CsgC5kfSPcsktFCQ4YLC81");
mod client_state;
mod consensus_state;
mod ed25519;
mod events;
mod execution_context;
mod storage;
#[cfg(test)]
Expand Down Expand Up @@ -132,11 +133,6 @@ impl From<Error<'_>> for u32 {
}
}

#[event]
pub struct EmitIBCEvent {
pub ibc_event: Vec<u8>,
}

impl Router for storage::IbcStorage<'_, '_> {
//
fn get_route(&self, module_id: &ModuleId) -> Option<&dyn Module> {
Expand Down
4 changes: 0 additions & 4 deletions solana/solana-ibc/programs/solana-ibc/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ pub(crate) type InnerClientId = String;
pub(crate) type InnerConnectionId = String;
pub(crate) type InnerPortId = String;
pub(crate) type InnerChannelId = String;
pub(crate) type InnerIbcEvent = Vec<u8>;
pub(crate) type InnerClient = Vec<u8>; // Serialized
pub(crate) type InnerConnectionEnd = Vec<u8>; // Serialized
pub(crate) type InnerChannelEnd = Vec<u8>; // Serialized
Expand Down Expand Up @@ -120,9 +119,6 @@ pub(crate) struct PrivateStorage {
/// different maps we need to maintain. This saves us on the amount of
/// trie nodes we need to maintain.
pub next_sequence: BTreeMap<(InnerPortId, InnerChannelId), SequenceTriple>,

/// The history of IBC events.
pub ibc_events_history: BTreeMap<InnerHeight, Vec<InnerIbcEvent>>,
}

/// Provable storage, i.e. the trie, held in an account.
Expand Down

0 comments on commit 6051af3

Please sign in to comment.