Skip to content

Commit

Permalink
feat: refactor core interfaces to improve query exposures (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
Farhad-Shabani authored Sep 24, 2024
1 parent 0d86697 commit e58a5dc
Show file tree
Hide file tree
Showing 15 changed files with 361 additions and 110 deletions.
130 changes: 85 additions & 45 deletions cairo-contracts/packages/apps/src/transfer/components/transfer.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ pub mod TokenTransferComponent {
pub initial_supply: u256,
}

// -----------------------------------------------------------
// Transfer Initializer
// -----------------------------------------------------------

#[generate_trait]
pub impl TransferInitializerImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>,
Expand All @@ -86,6 +90,10 @@ pub mod TokenTransferComponent {
}
}

// -----------------------------------------------------------
// ISendTransfer
// -----------------------------------------------------------

#[embeddable_as(SendTransfer)]
impl SendTransferImpl<
TContractState,
Expand All @@ -98,6 +106,64 @@ pub mod TokenTransferComponent {
}
}

// -----------------------------------------------------------
// IAppCallback
// -----------------------------------------------------------

#[embeddable_as(TransferAppCallback)]
impl TransferAppCallbackImpl<
TContractState,
+HasComponent<TContractState>,
+ITransferrable<TContractState>,
+Drop<TContractState>,
impl Ownable: OwnableComponent::HasComponent<TContractState>,
> of IAppCallback<ComponentState<TContractState>> {
fn on_recv_packet(
ref self: ComponentState<TContractState>, packet: Packet
) -> Acknowledgement {
self.assert_owner();

self.recv_execute(packet);

Acknowledgement { ack: '0' }
}

fn on_acknowledgement_packet(
ref self: ComponentState<TContractState>, packet: Packet, ack: Acknowledgement
) {
self.assert_owner();
}

fn on_timeout_packet(ref self: ComponentState<TContractState>, packet: Packet) {
self.assert_owner();
}
}

// -----------------------------------------------------------
// ITokenAddress
// -----------------------------------------------------------

#[embeddable_as(IBCTokenAddress)]
impl ITokenAddressImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
> of ITokenAddress<ComponentState<TContractState>> {
fn ibc_token_address(
self: @ComponentState<TContractState>, token_key: felt252
) -> Option<ContractAddress> {
let token_address = self.read_ibc_token_address(token_key);

if token_address.is_non_zero() {
Option::Some(token_address)
} else {
Option::None
}
}
}

// -----------------------------------------------------------
// Transfer Handlers
// -----------------------------------------------------------

#[generate_trait]
pub(crate) impl SendTransferInternalImpl<
TContractState,
Expand Down Expand Up @@ -168,35 +234,6 @@ pub mod TokenTransferComponent {
}
}

#[embeddable_as(TransferAppCallback)]
impl TransferAppCallbackImpl<
TContractState,
+HasComponent<TContractState>,
+ITransferrable<TContractState>,
+Drop<TContractState>,
impl Ownable: OwnableComponent::HasComponent<TContractState>,
> of IAppCallback<ComponentState<TContractState>> {
fn on_recv_packet(
ref self: ComponentState<TContractState>, packet: Packet
) -> Acknowledgement {
self.assert_owner();

self.recv_execute(packet);

Acknowledgement { ack: '0' }
}

fn on_acknowledgement_packet(
ref self: ComponentState<TContractState>, packet: Packet, ack: Acknowledgement
) {
self.assert_owner();
}

fn on_timeout_packet(ref self: ComponentState<TContractState>, packet: Packet) {
self.assert_owner();
}
}

#[generate_trait]
pub(crate) impl RecvPacketInternalImpl<
TContractState,
Expand Down Expand Up @@ -281,22 +318,9 @@ pub mod TokenTransferComponent {
}
}

#[embeddable_as(IBCTokenAddress)]
impl ITokenAddressImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
> of ITokenAddress<ComponentState<TContractState>> {
fn ibc_token_address(
self: @ComponentState<TContractState>, token_key: felt252
) -> Option<ContractAddress> {
let token_address = self.read_ibc_token_address(token_key);

if token_address.is_non_zero() {
Option::Some(token_address)
} else {
Option::None
}
}
}
// -----------------------------------------------------------
// Transfer Validation/Execution
// -----------------------------------------------------------

#[generate_trait]
pub impl TransferValidationImpl<
Expand Down Expand Up @@ -415,6 +439,10 @@ pub mod TokenTransferComponent {
}
}

// -----------------------------------------------------------
// Transfer Owner Assertion
// -----------------------------------------------------------

#[generate_trait]
pub(crate) impl OwnerAssertionImpl<
TContractState,
Expand All @@ -428,6 +456,10 @@ pub mod TokenTransferComponent {
}
}

// -----------------------------------------------------------
// Transfer Internal
// -----------------------------------------------------------

#[generate_trait]
pub(crate) impl TransferInternalImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
Expand Down Expand Up @@ -500,6 +532,10 @@ pub mod TokenTransferComponent {
}
}

// -----------------------------------------------------------
// Transfer Reader/Writer
// -----------------------------------------------------------

#[generate_trait]
pub(crate) impl TransferReaderImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
Expand Down Expand Up @@ -556,6 +592,10 @@ pub mod TokenTransferComponent {
}
}

// -----------------------------------------------------------
// Transfer Event Emitter
// -----------------------------------------------------------

#[generate_trait]
pub(crate) impl TransferEventImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
Expand Down
96 changes: 70 additions & 26 deletions cairo-contracts/packages/clients/src/cometbft/component.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub mod CometClientComponent {
use starknet_ibc_core::client::{
MsgCreateClient, MsgUpdateClient, MsgRecoverClient, MsgUpgradeClient, Height, Timestamp,
Status, StatusTrait, CreateResponse, CreateResponseImpl, UpdateResponse, IClientHandler,
IClientState, IClientStateValidation, IClientStateExecution
IClientQuery, IClientStateValidation, IClientStateExecution,
};
use starknet_ibc_core::host::ClientIdImpl;
use starknet_ibc_utils::ValidateBasic;
Expand All @@ -27,6 +27,10 @@ pub mod CometClientComponent {
#[derive(Debug, Drop, starknet::Event)]
pub enum Event {}

// -----------------------------------------------------------
// IClientHandler
// -----------------------------------------------------------

#[embeddable_as(CometClientHandler)]
impl ClientHandlerImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
Expand All @@ -50,6 +54,60 @@ pub mod CometClientComponent {
fn upgrade_client(ref self: ComponentState<TContractState>, msg: MsgUpgradeClient) {}
}

// -----------------------------------------------------------
// IClientQuery
// -----------------------------------------------------------

#[embeddable_as(CometClientQuery)]
impl ClientQueryImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
> of IClientQuery<ComponentState<TContractState>> {
fn client_type(self: @ComponentState<TContractState>) -> felt252 {
'07-cometbft'
}

fn latest_height(self: @ComponentState<TContractState>, client_sequence: u64) -> Height {
let comet_client_state: CometClientState = self.read_client_state(client_sequence);

comet_client_state.latest_height
}

fn status(self: @ComponentState<TContractState>, client_sequence: u64) -> Status {
let comet_client_state: CometClientState = self.read_client_state(client_sequence);

let latest_consensus_state = self
.read_consensus_state(client_sequence, comet_client_state.latest_height.clone());

assert(!latest_consensus_state.is_zero(), CometErrors::ZERO_CONSENSUS_STATE);

self._status(comet_client_state, latest_consensus_state, client_sequence)
}

fn client_state(
self: @ComponentState<TContractState>, client_sequence: u64
) -> Array<felt252> {
let mut client_state: Array<felt252> = ArrayTrait::new();

self.read_client_state(client_sequence).serialize(ref client_state);

client_state
}

fn consensus_state(
self: @ComponentState<TContractState>, client_sequence: u64, height: Height
) -> Array<felt252> {
let mut consensus_state: Array<felt252> = ArrayTrait::new();

self.read_consensus_state(client_sequence, height).serialize(ref consensus_state);

consensus_state
}
}

// -----------------------------------------------------------
// Client handler implementations
// -----------------------------------------------------------

#[generate_trait]
pub(crate) impl CreateClientImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
Expand Down Expand Up @@ -141,31 +199,9 @@ pub mod CometClientComponent {
fn upgrade_execute(ref self: ComponentState<TContractState>, msg: MsgUpgradeClient,) {}
}

#[embeddable_as(CometCommonClientState)]
impl ClientStateImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
> of IClientState<ComponentState<TContractState>> {
fn client_type(self: @ComponentState<TContractState>) -> felt252 {
'07-cometbft'
}

fn latest_height(self: @ComponentState<TContractState>, client_sequence: u64) -> Height {
let comet_client_state: CometClientState = self.read_client_state(client_sequence);

comet_client_state.latest_height
}

fn status(self: @ComponentState<TContractState>, client_sequence: u64) -> Status {
let comet_client_state: CometClientState = self.read_client_state(client_sequence);

let latest_consensus_state = self
.read_consensus_state(client_sequence, comet_client_state.latest_height.clone());

assert(!latest_consensus_state.is_zero(), CometErrors::ZERO_CONSENSUS_STATE);

self._status(comet_client_state, latest_consensus_state, client_sequence)
}
}
// -----------------------------------------------------------
// Client Validation/Execution
// -----------------------------------------------------------

#[embeddable_as(CometClientValidation)]
impl ClientValidationImpl<
Expand Down Expand Up @@ -293,6 +329,10 @@ pub mod CometClientComponent {
) {}
}

// -----------------------------------------------------------
// Client Internal
// -----------------------------------------------------------

#[generate_trait]
pub(crate) impl ClientInternalImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
Expand Down Expand Up @@ -359,6 +399,10 @@ pub mod CometClientComponent {
}
}

// -----------------------------------------------------------
// Client Reader/Writer
// -----------------------------------------------------------

#[generate_trait]
pub(crate) impl ClientReaderImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ pub(crate) mod MockCometClient {
impl CometClientHandlerImpl =
CometClientComponent::CometClientHandler<ContractState>;
#[abi(embed_v0)]
impl CometCommonClientStateImpl =
CometClientComponent::CometCommonClientState<ContractState>;
impl CometClientQueryImpl =
CometClientComponent::CometClientQuery<ContractState>;

#[abi(embed_v0)]
impl CometClientValidationImpl =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use snforge_std::start_cheat_block_timestamp_global;
use starknet_ibc_clients::cometbft::CometClientComponent::{
CometClientHandler, CometCommonClientState, ClientReaderImpl
CometClientHandler, CometClientQuery, ClientReaderImpl
};
use starknet_ibc_clients::cometbft::CometClientComponent;
use starknet_ibc_clients::tests::{MockCometClient, CometClientConfigTrait};
Expand Down
4 changes: 2 additions & 2 deletions cairo-contracts/packages/contracts/src/clients/cometbft.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ pub mod CometClient {
impl CometClientHandlerImpl =
CometClientComponent::CometClientHandler<ContractState>;
#[abi(embed_v0)]
impl CometCommonClientStateImpl =
CometClientComponent::CometCommonClientState<ContractState>;
impl CometClientQueryImpl =
CometClientComponent::CometClientQuery<ContractState>;

// NOTE: The client state validation interface is exposed for public use.
// However, only the handler contract can invoke the execution methods.
Expand Down
4 changes: 4 additions & 0 deletions cairo-contracts/packages/contracts/src/core.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod IBCCore {
// -----------------------------------------------------------
// Setup Client Components
// -----------------------------------------------------------

component!(
path: ClientEventEmitterComponent, storage: client_emitter, event: ClientEventEmitterEvent
);
Expand Down Expand Up @@ -36,6 +37,9 @@ pub mod IBCCore {
#[abi(embed_v0)]
impl CoreChannelHanderImpl =
ChannelHandlerComponent::CoreChannelHandler<ContractState>;
#[abi(embed_v0)]
impl CoreChannelQueryImpl =
ChannelHandlerComponent::CoreChannelQuery<ContractState>;
impl ChannelInitializerImpl = ChannelHandlerComponent::ChannelInitializerImpl<ContractState>;

// -----------------------------------------------------------
Expand Down
Loading

0 comments on commit e58a5dc

Please sign in to comment.