Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(contract): implement ICS23 vector commitment in Cairo (WIP) #200

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
14 changes: 13 additions & 1 deletion cairo-contracts/Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ dependencies = [
"alexandria_data_structures",
]

[[package]]
name = "ics23"
version = "0.1.0"
dependencies = [
"alexandria_numeric",
"protobuf",
]

[[package]]
name = "openzeppelin_access"
version = "0.18.0"
Expand Down Expand Up @@ -110,6 +118,10 @@ version = "0.18.0"
source = "registry+https://scarbs.xyz/"
checksum = "sha256:725b212839f3eddc32791408609099c5e808c167ca0cf331d8c1d778b07a4e21"

[[package]]
name = "protobuf"
version = "0.1.0"

[[package]]
name = "serde_json"
version = "0.1.0"
Expand Down Expand Up @@ -182,7 +194,7 @@ dependencies = [
name = "starknet_ibc_core"
version = "0.1.0"
dependencies = [
"alexandria_numeric",
"ics23",
"openzeppelin_testing",
"snforge_std",
"starknet_ibc_testkit",
Expand Down
2 changes: 1 addition & 1 deletion cairo-contracts/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ test = "snforge test"

[workspace.dependencies]
# external dependencies
alexandria_numeric = { git = "https://github.com/keep-starknet-strange/alexandria.git", rev = "95d98a5" }
alexandria_sorting = { git = "https://github.com/keep-starknet-strange/alexandria.git", rev = "95d98a5" }
assert_macros = "2.8.4"
starknet = "2.8.4"
Expand All @@ -36,6 +35,7 @@ openzeppelin_utils = "0.18.0"
snforge_std = "0.31.0"

# internal dependencies
ics23 = { path = "../cairo-libs/packages/ics23" }
serde_json = { path = "../cairo-libs/packages/serde_json" }

# ibc dependencies
Expand Down
6 changes: 4 additions & 2 deletions cairo-contracts/packages/core/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ fmt = { workspace = true }

[dependencies]
# external dependencies
alexandria_numeric = { workspace = true }
starknet = { workspace = true }
starknet = { workspace = true }

# internal dependencies
ics23 = { workspace = true }

# ibc dependencies
starknet_ibc_utils = { workspace = true }
Expand Down
5 changes: 2 additions & 3 deletions cairo-contracts/packages/core/src/channel/types.cairo
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use core::num::traits::Zero;
use ics23::{IntoArrayU32, array_u8_into_array_u32};
use starknet_ibc_core::channel::ChannelErrors;
use starknet_ibc_core::client::{Height, Timestamp, HeightPartialOrd, TimestampPartialOrd};
use starknet_ibc_core::commitment::{
array_u8_into_array_u32, IntoArrayU32, StateValueZero, StateValue
};
use starknet_ibc_core::commitment::{StateValueZero, StateValue};
use starknet_ibc_core::host::{
ConnectionId, ChannelId, ChannelIdZero, PortId, PortIdTrait, Sequence
};
Expand Down
3 changes: 2 additions & 1 deletion cairo-contracts/packages/core/src/client/types.cairo
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use core::num::traits::{CheckedAdd, Zero};
use core::traits::PartialOrd;
use ics23::IntoArrayU32;
use starknet::SyscallResult;
use starknet::storage_access::{Store, StorageBaseAddress};
use starknet_ibc_core::client::ClientErrors;
use starknet_ibc_core::commitment::{IntoArrayU32, U32CollectorImpl};
use starknet_ibc_core::commitment::U32CollectorImpl;
use starknet_ibc_core::host::ClientId;

#[derive(Clone, Debug, Drop, PartialEq, Serde)]
Expand Down
5 changes: 3 additions & 2 deletions cairo-contracts/packages/core/src/commitment/types.cairo
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use core::num::traits::Zero;
use core::sha256::{compute_sha256_byte_array, compute_sha256_u32_array};
use ics23::{IntoArrayU32, array_u32_into_array_u8};
use starknet_ibc_core::channel::Acknowledgement;
use starknet_ibc_core::client::{Height, Timestamp};
use starknet_ibc_core::commitment::{U32CollectorImpl, IntoArrayU32, array_u32_into_array_u8};
use starknet_ibc_core::commitment::U32CollectorImpl;

// -----------------------------------------------------------
// Commitment Value
Expand Down Expand Up @@ -43,7 +44,7 @@ pub impl CommitmentZero of Zero<Commitment> {

pub impl CommitmentIntoStateValue of Into<Commitment, StateValue> {
fn into(self: Commitment) -> StateValue {
let value = array_u32_into_array_u8(self.into());
let value = array_u32_into_array_u8(self.into(), 0, 0);
StateValue { value }
}
}
Expand Down
72 changes: 1 addition & 71 deletions cairo-contracts/packages/core/src/commitment/utils.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alexandria_numeric::integers::UIntBytes;
use ics23::IntoArrayU32;

#[derive(Drop, Clone)]
pub struct U32Collector {
Expand Down Expand Up @@ -31,73 +31,3 @@ pub impl U32CollectorImpl of U32CollectorTrait {
}
}

/// Converts the give type `T` into an array of `u32` values. If the last word
/// is not a full word, the method returns the last word and its length.
pub trait IntoArrayU32<T> {
fn into_array_u32(self: T) -> (Array<u32>, u32, u32);
}

pub impl U64IntoArrayU32 of IntoArrayU32<u64> {
fn into_array_u32(self: u64) -> (Array<u32>, u32, u32) {
(u64_into_array_u32(self), 0, 0)
}
}

pub fn u64_into_array_u32(value: u64) -> Array<u32> {
let mut array: Array<u32> = ArrayTrait::new();
let upper = (value / 0x100000000).try_into().unwrap();
let lower = (value % 0x100000000).try_into().unwrap();
array.append(upper);
array.append(lower);
array
}

pub impl ArrayU8IntoArrayU32 of IntoArrayU32<Array<u8>> {
fn into_array_u32(self: Array<u8>) -> (Array<u32>, u32, u32) {
array_u8_into_array_u32(self)
}
}

pub fn array_u8_into_array_u32(input: Array<u8>) -> (Array<u32>, u32, u32) {
let mut result: Array<u32> = ArrayTrait::new();
let mut last_word: u32 = 0;
let mut last_word_len: u32 = 0;

let mut i: usize = 0;
while i < input.len() {
let mut value: u32 = 0;
let mut j: usize = 0;
while j < 4 {
if i + j >= input.len() {
break;
};
value *= 0x100;
value = value + (*input.at(i + j)).into();
j += 1;
};
if j % 4 == 0 {
result.append(value);
} else {
last_word = value;
last_word_len = j.try_into().unwrap();
}
i += 4;
};

(result, last_word, last_word_len)
}

pub fn array_u32_into_array_u8(input: Array<u32>) -> Array<u8> {
let mut result: Array<u8> = ArrayTrait::new();
for i in input {
let a = i.to_bytes();
result.append_span(a);
};
result
}

pub impl ArrayU32IntoArrayU8 of Into<Array<u32>, Array<u8>> {
fn into(self: Array<u32>) -> Array<u8> {
array_u32_into_array_u8(self)
}
}
3 changes: 2 additions & 1 deletion cairo-contracts/packages/core/src/host/identifiers.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use core::num::traits::CheckedAdd;
use core::num::traits::Zero;
use core::to_byte_array::FormatAsByteArray;
use core::traits::TryInto;
use starknet_ibc_core::commitment::{ArrayU32IntoArrayU8, StateValue, u64_into_array_u32};
use ics23::{ArrayU32IntoArrayU8, u64_into_array_u32};
use starknet_ibc_core::commitment::StateValue;
use starknet_ibc_core::host::errors::HostErrors;
use starknet_ibc_utils::{ValidateBasic, ComputeKey, poseidon_hash};

Expand Down
5 changes: 1 addition & 4 deletions cairo-contracts/packages/core/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ pub mod commitment {
Commitment, CommitmentZero, StateValue, StateValueZero, StateProof, StateProofZero,
StateRoot, StateRootZero, compute_packet_commitment, compute_ack_commitment,
};
pub use utils::{
IntoArrayU32, U64IntoArrayU32, U32Collector, U32CollectorImpl, U32CollectorTrait,
u64_into_array_u32, array_u8_into_array_u32, array_u32_into_array_u8, ArrayU32IntoArrayU8
};
pub use utils::{U32Collector, U32CollectorImpl, U32CollectorTrait,};
}
pub mod connection {
mod errors;
Expand Down
47 changes: 1 addition & 46 deletions cairo-contracts/packages/core/src/tests/commitment.cairo
Original file line number Diff line number Diff line change
@@ -1,51 +1,6 @@
use starknet_ibc_core::commitment::{
u64_into_array_u32, array_u8_into_array_u32, compute_ack_commitment
};
use starknet_ibc_core::commitment::compute_ack_commitment;
use starknet_ibc_testkit::dummies::{ERC20, PACKET_COMMITMENT_ON_SN};

#[test]
fn test_u64_into_array_u32() {
assert_eq!(u64_into_array_u32(0), array![0, 0]);
assert_eq!(u64_into_array_u32(1), array![0, 1]);
assert_eq!(u64_into_array_u32(4294967296), array![1, 0]);
assert_eq!(u64_into_array_u32(4294967297), array![1, 1]);
assert_eq!(u64_into_array_u32(8589934592), array![2, 0]);
assert_eq!(u64_into_array_u32(8589934593), array![2, 1]);
assert_eq!(u64_into_array_u32(4294967295), array![0, 4294967295]);
assert_eq!(u64_into_array_u32(18446744073709551615), array![4294967295, 4294967295]);
}

#[test]
fn test_array_u8_into_array_u32() {
let array = array![];
let result = array_u8_into_array_u32(array);
assert_eq!(result, (array![], 0, 0));

let array = array![0];
let result = array_u8_into_array_u32(array);
assert_eq!(result, (array![], 0, 1));

let array = array![0, 0, 0, 1];
let result = array_u8_into_array_u32(array);
assert_eq!(result, (array![1], 0, 0));

let array = array![255, 255, 255, 255];
let result = array_u8_into_array_u32(array);
assert_eq!(result, (array![4294967295], 0, 0));

// This corresponds to the following JSON: {"result": "AQ=="}, which
// represents the successful acknowledgement in ICS-20 application.
let array = array![123, 34, 114, 101, 115, 117, 108, 116, 34, 58, 34, 65, 81, 61, 61, 34, 125];
let result = array_u8_into_array_u32(array);
assert_eq!(result, (array![2065855077, 1937075316, 574235201, 1362967842], 125, 1));

let array = array![
123, 34, 114, 101, 115, 117, 108, 116, 34, 58, 34, 65, 81, 61, 61, 34, 125, 126
];
let result = array_u8_into_array_u32(array);
assert_eq!(result, (array![2065855077, 1937075316, 574235201, 1362967842], 32126, 2));
}

// Snapshot test to ensure the computation of packet commitment stays
// consistent.
#[test]
Expand Down
60 changes: 60 additions & 0 deletions cairo-libs/Scarb.lock
Original file line number Diff line number Diff line change
@@ -1,10 +1,70 @@
# Code generated by scarb DO NOT EDIT.
version = 1

[[package]]
name = "alexandria_bytes"
version = "0.1.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5#95d98a5182001d07673b856a356eff0e6bd05354"
dependencies = [
"alexandria_data_structures",
"alexandria_math",
]

[[package]]
name = "alexandria_data_structures"
version = "0.2.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5#95d98a5182001d07673b856a356eff0e6bd05354"
dependencies = [
"alexandria_encoding",
]

[[package]]
name = "alexandria_encoding"
version = "0.1.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5#95d98a5182001d07673b856a356eff0e6bd05354"
dependencies = [
"alexandria_bytes",
"alexandria_math",
"alexandria_numeric",
]

[[package]]
name = "alexandria_math"
version = "0.2.1"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5#95d98a5182001d07673b856a356eff0e6bd05354"

[[package]]
name = "alexandria_numeric"
version = "0.1.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5#95d98a5182001d07673b856a356eff0e6bd05354"
dependencies = [
"alexandria_math",
"alexandria_searching",
]

[[package]]
name = "alexandria_searching"
version = "0.1.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5#95d98a5182001d07673b856a356eff0e6bd05354"
dependencies = [
"alexandria_data_structures",
]

[[package]]
name = "cometbft"
version = "0.1.0"
dependencies = [
"ics23",
"protobuf",
"snforge_std",
]

[[package]]
name = "ics23"
version = "0.1.0"
dependencies = [
"alexandria_math",
"alexandria_numeric",
"protobuf",
"snforge_std",
]
Expand Down
15 changes: 11 additions & 4 deletions cairo-libs/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = [
"packages/protobuf",
"packages/cometbft",
"packages/serde_json",
"packages/ics23",
]

[workspace.package]
Expand All @@ -22,10 +23,16 @@ test = "snforge test"

[workspace.dependencies]
# external dependencies
assert_macros = "2.8.4"
cairo_test = "2.8.4"
starknet = "2.8.4"
snforge_std = "0.31.0"
alexandria_numeric = { git = "https://github.com/keep-starknet-strange/alexandria.git", rev = "95d98a5" }
alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git", rev = "95d98a5" }
assert_macros = "2.8.4"
cairo_test = "2.8.4"
starknet = "2.8.4"
snforge_std = "0.31.0"

# internal dependencies
protobuf = { path = "packages/protobuf" }
ics23 = { path = "packages/ics23" }

[workspace.tool.fmt]
sort-module-level-items = true
3 changes: 2 additions & 1 deletion cairo-libs/packages/cometbft/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ version = "0.1.0"
edition = { workspace = true }

[dependencies]
protobuf = { path = "../protobuf" }
protobuf = { workspace = true }
ics23 = { workspace = true }

[dev-dependencies]
cairo_test = { workspace = true }
Expand Down
Loading
Loading