Skip to content

Commit

Permalink
fix: bump cainome and fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
glihm committed Sep 5, 2024
2 parents 86b4aec + e8cfc90 commit e05285b
Show file tree
Hide file tree
Showing 10 changed files with 3,588 additions and 393 deletions.
1,096 changes: 715 additions & 381 deletions bindings/Cargo.lock

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions bindings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cainome = { git = "https://github.com/cartridge-gg/cainome", tag = "v0.1.10", features = ["abigen-rs"] }

cainome = { git = "https://github.com/cartridge-gg/cainome", rev = "v0.4.0", features = ["abigen-rs"] }
2,721 changes: 2,720 additions & 1 deletion bindings/src/bindings.rs

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ use cainome::rs::abigen;
abigen!(
AppChain,
"../target/dev/piltover_appchain.contract_class.json",
output_path("src/bindings.rs")
output_path("src/bindings.rs"),
derives(Debug, PartialEq, Eq, Clone, Copy)
);
19 changes: 18 additions & 1 deletion src/appchain.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ mod appchain {
ReentrancyGuardComponent,
ReentrancyGuardComponent::InternalTrait as InternalReentrancyGuardImpl
};
use openzeppelin::upgrades::{
UpgradeableComponent as upgradeable_cpt,
UpgradeableComponent::InternalTrait as UpgradeableInternal, interface::IUpgradeable
};
use piltover::components::onchain_data_fact_tree_encoder::{
encode_fact_with_onchain_data, DataAvailabilityFact
};
Expand All @@ -37,13 +41,14 @@ mod appchain {
use piltover::snos_output;
use piltover::state::component::state_cpt::HasComponent;
use piltover::state::{state_cpt, state_cpt::InternalTrait as StateInternal, IState};
use starknet::ContractAddress;
use starknet::{ContractAddress, ClassHash};
use super::errors;

/// The default cancellation delay of 5 days.
const CANCELLATION_DELAY_SECS: u64 = 432000;

component!(path: ownable_cpt, storage: ownable, event: OwnableEvent);
component!(path: upgradeable_cpt, storage: upgradeable, event: UpgradeableEvent);
component!(path: config_cpt, storage: config, event: ConfigEvent);
component!(path: messaging_cpt, storage: messaging, event: MessagingEvent);
component!(path: state_cpt, storage: state, event: StateEvent);
Expand All @@ -63,6 +68,8 @@ mod appchain {
#[substorage(v0)]
ownable: ownable_cpt::Storage,
#[substorage(v0)]
upgradeable: upgradeable_cpt::Storage,
#[substorage(v0)]
config: config_cpt::Storage,
#[substorage(v0)]
messaging: messaging_cpt::Storage,
Expand All @@ -78,6 +85,8 @@ mod appchain {
#[flat]
OwnableEvent: ownable_cpt::Event,
#[flat]
UpgradeableEvent: upgradeable_cpt::Event,
#[flat]
ConfigEvent: config_cpt::Event,
#[flat]
MessagingEvent: messaging_cpt::Event,
Expand Down Expand Up @@ -197,4 +206,12 @@ mod appchain {
);
}
}

#[abi(embed_v0)]
impl UpgradeableImpl of IUpgradeable<ContractState> {
fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {
self.ownable.assert_only_owner();
self.upgradeable.upgrade(new_class_hash);
}
}
}
1 change: 1 addition & 0 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ mod messaging {
mod interface;
mod mock;
mod output_process;
mod types;

use component::messaging_cpt;
use interface::{IMessaging, IMessagingDispatcher, IMessagingDispatcherTrait};
Expand Down
25 changes: 22 additions & 3 deletions src/messaging/component.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,11 @@ mod messaging_cpt {
};
use piltover::messaging::{
hash, interface::IMessaging, output_process::{MessageToStarknet, MessageToAppchain},
types::{MessageToAppchainStatus, MessageToStarknetStatus, MessageHash, Nonce}
};
use starknet::ContractAddress;
use super::errors;

type MessageHash = felt252;
type Nonce = felt252;

#[storage]
struct Storage {
/// Cancellation delay in seconds for message from Starknet to Appchain.
Expand Down Expand Up @@ -189,6 +187,27 @@ mod messaging_cpt {
(message_hash, nonce)
}

fn sn_to_appchain_messages(
self: @ComponentState<TContractState>, message_hash: MessageHash
) -> MessageToAppchainStatus {
let nonce = self.sn_to_appc_messages.read(message_hash);
if nonce == 0 {
return MessageToAppchainStatus::SealedOrNotSent;
}
return MessageToAppchainStatus::Pending(nonce);
}


fn appchain_to_sn_messages(
self: @ComponentState<TContractState>, message_hash: MessageHash
) -> MessageToStarknetStatus {
let message_count = self.appc_to_sn_messages.read(message_hash);
if (message_count == 0) {
return MessageToStarknetStatus::NothingToConsume;
}
return MessageToStarknetStatus::ReadyToConsume(message_count);
}

fn consume_message_from_appchain(
ref self: ComponentState<TContractState>,
from_address: ContractAddress,
Expand Down
36 changes: 32 additions & 4 deletions src/messaging/interface.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use piltover::messaging::types::{
MessageHash, Nonce, MessageToAppchainStatus, MessageToStarknetStatus
};
//! SPDX-License-Identifier: MIT
//!
//! Interface for Appchain - Starknet messaging.
Expand All @@ -20,7 +23,7 @@ trait IMessaging<T> {
/// The message hash and the updated nonce of the message.
fn send_message_to_appchain(
ref self: T, to_address: ContractAddress, selector: felt252, payload: Span<felt252>
) -> (felt252, felt252);
) -> (MessageHash, Nonce);

/// Consumes a message received from a state update of the Appchain.
///
Expand All @@ -36,7 +39,32 @@ trait IMessaging<T> {
/// Returns the hash of the consummed message.
fn consume_message_from_appchain(
ref self: T, from_address: ContractAddress, payload: Span<felt252>
) -> felt252;
) -> MessageHash;

/// Checks the status of message sent to the Appchain from Starknet
/// <https://github.com/starkware-libs/cairo-lang/blob/caba294d82eeeccc3d86a158adb8ba209bf2d8fc/src/starkware/starknet/solidity/StarknetMessaging.sol#L39>
///
/// # Arguments
///
/// * `message_hash` - The hash of the message that was sent to the Appchain.
///
/// # Returns
///
/// Returns the Nonce used for the message with the given `msgHash`,
/// or 0 if no message with such a hash is pending.
fn sn_to_appchain_messages(self: @T, message_hash: felt252) -> MessageToAppchainStatus;

/// Checks the status of message sent to the Starknet from the Appchain
/// <https://github.com/starkware-libs/cairo-lang/blob/caba294d82eeeccc3d86a158adb8ba209bf2d8fc/src/starkware/starknet/solidity/StarknetMessaging.sol#L43>
///
/// # Arguments
///
/// * `message_hash` - The hash of the message that was sent to Starknet.
///
/// # Returns
///
/// Returns the count of messages with given `msg_hash` that are pending to be consumed on starknet, otherwise 0
fn appchain_to_sn_messages(self: @T, message_hash: felt252) -> MessageToStarknetStatus;

/// Starts the cancellation procedure for a message sent from
/// Starknet to the Appchain.
Expand All @@ -61,7 +89,7 @@ trait IMessaging<T> {
selector: felt252,
payload: Span<felt252>,
nonce: felt252,
) -> felt252;
) -> MessageHash;

/// Cancels a message from Starknet to Appchain if the cancellation delays has expired.
///
Expand All @@ -83,5 +111,5 @@ trait IMessaging<T> {
selector: felt252,
payload: Span<felt252>,
nonce: felt252,
) -> felt252;
) -> MessageHash;
}
63 changes: 63 additions & 0 deletions src/messaging/tests/test_messaging.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::array::ArrayTrait;
use core::zeroable::Zeroable;
use piltover::messaging::tests::constants as c;
use piltover::messaging::{
Expand All @@ -7,6 +8,7 @@ use piltover::messaging::{
Event, MessageSent, MessageCancellationStarted, MessageCanceled, MessageToStarknetReceived,
MessageToAppchainSealed,
},
types::{MessageHash, MessageToAppchainStatus, MessageToStarknetStatus},
output_process::{MessageToStarknet, MessageToAppchain}, hash, output_process,
};
use snforge_std as snf;
Expand Down Expand Up @@ -175,6 +177,44 @@ fn send_message_ok() {
spy.assert_emitted(@array![(mock.contract_address, Event::MessageSent(expected_event))]);
}

#[test]
fn sn_to_appchain_messages_ok() {
let (mock, mut spy) = deploy_mock();

let from = c::SPENDER();
let to = c::RECIPIENT();
let selector = selector!("func1");
let payload = array![1, 2, 3];

snf::start_cheat_caller_address(mock.contract_address, from);

// Calculate the message_hash
let message_hash = hash::compute_message_hash_sn_to_appc(
nonce: 1, to_address: to, :selector, payload: payload.span()
);
let is_pending_before = mock.sn_to_appchain_messages(message_hash);
assert(
is_pending_before == MessageToAppchainStatus::SealedOrNotSent,
'Should not be pending before'
);

snf::start_cheat_caller_address(from, from);
let (message_hash, nonce) = mock.send_message_to_appchain(to, selector, payload.span());

// Ensure the message is pending to consume
let is_pending_after = mock.sn_to_appchain_messages(message_hash);
assert(
is_pending_after == MessageToAppchainStatus::Pending(nonce),
'message not registered/pending'
);

let expected_event = MessageSent {
message_hash, from, to, selector, nonce: nonce, payload: payload.span(),
};

spy.assert_emitted(@array![(mock.contract_address, Event::MessageSent(expected_event))]);
}

#[test]
fn start_cancellation_ok() {
let (mock, mut spy) = deploy_mock();
Expand Down Expand Up @@ -412,6 +452,29 @@ fn consume_message_from_appchain_ok() {
mock.consume_message_from_appchain(from, payload);
}

#[test]
fn appchain_to_sn_messages_ok() {
let mut mock = mock_state_testing();

let from = c::SPENDER();
let to = starknet::get_contract_address();
let payload = array![1, 2, 3].span();

let messages = array![MessageToStarknet { from_address: from, to_address: to, payload, }]
.span();

let message_hash = hash::compute_message_hash_appc_to_sn(from, to, payload);

let previous_status = mock.appchain_to_sn_messages(message_hash);
assert(previous_status == MessageToStarknetStatus::NothingToConsume, 'message already present');

mock.process_messages_to_starknet(messages);

// Ensure that message is available to consume
let count_after = mock.appchain_to_sn_messages(message_hash);
assert(count_after == MessageToStarknetStatus::ReadyToConsume(1), 'message not be present');
}

#[test]
#[should_panic(expected: ('INVALID_MESSAGE_TO_CONSUME',))]
fn consume_message_from_appchain_invalid_to_consume() {
Expand Down
14 changes: 14 additions & 0 deletions src/messaging/types.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub type MessageHash = felt252;
pub type Nonce = felt252;

#[derive(Serde, Drop, Eq, PartialEq)]
pub enum MessageToAppchainStatus {
SealedOrNotSent, // sn->appc: The nonce is 0 for the message hash.
Pending: Nonce, // sn->appc: The nonce > 0.
}

#[derive(Serde, Drop, Eq, PartialEq)]
pub enum MessageToStarknetStatus {
NothingToConsume, // appc->sn: the ref count is 0.
ReadyToConsume: felt252 // appc->sn: the ref count > 0.
}

0 comments on commit e05285b

Please sign in to comment.