diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1c5adb9c7..753fb861b 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -2,7 +2,7 @@ name: Pre-release on: push: tags: - - 'v*.*.*-alpha.*' + - '*' permissions: contents: write packages: write @@ -105,7 +105,7 @@ jobs: body: | ${{ steps.Changelog.outputs.changelog }} draft: false - prerelease: true + prerelease: false - name: Upload Javascore contracts to release uses: svenstaro/upload-release-action@v2 diff --git a/.gitignore b/.gitignore index 89f694a48..3cd37e2d1 100644 --- a/.gitignore +++ b/.gitignore @@ -200,4 +200,6 @@ lcov.info vendor/** scripts/download_buf.sh -test/e2e-demo/ibc-config/** \ No newline at end of file +test/e2e-demo/ibc-config/** + +.xcall-multi \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 19e32654e..a301fa4e1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,3 @@ [submodule "contracts/javascore/gochain-btp"] path = contracts/javascore/gochain-btp url = https://github.com/izyak/gochain-btp.git - -[submodule "xcall-multi"] - path = xcall-multi - url = https://github.com/icon-project/xcall-multi.git - branch = main - diff --git a/Cargo.lock b/Cargo.lock index 5271cdb09..08aeee577 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -428,7 +428,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.1.0", - "cw-xcall-lib", + "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", "debug_print", "getrandom", "hex", @@ -514,9 +514,9 @@ dependencies = [ "cw-mock-ibc-core", "cw-multi-test", "cw-storage-plus 1.1.0", - "cw-xcall", + "cw-xcall 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", "cw-xcall-ibc-connection", - "cw-xcall-lib", + "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", "hex", "ibc", "prost 0.11.9", @@ -528,14 +528,14 @@ dependencies = [ [[package]] name = "cw-mock-dapp" version = "0.1.0" -source = "git+https://github.com/icon-project/xCall.git?branch=main#59960dcb8bcfb43e7e079ebe7e86dbf9baf05160" +source = "git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5#7f250bc9c6560591ccc16289cb8159dd100bbe76" dependencies = [ "common 0.1.0 (git+https://github.com/icon-project/IBC-Integration.git?branch=main)", "cosmwasm-schema", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.1.0", - "cw-xcall-lib", + "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", "cw2", "schemars 0.8.12", "serde", @@ -546,14 +546,14 @@ dependencies = [ [[package]] name = "cw-mock-dapp-multi" version = "0.1.0" -source = "git+https://github.com/icon-project/xCall.git?branch=main#59960dcb8bcfb43e7e079ebe7e86dbf9baf05160" +source = "git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5#7f250bc9c6560591ccc16289cb8159dd100bbe76" dependencies = [ "common 0.1.0 (git+https://github.com/icon-project/IBC-Integration.git?branch=main)", "cosmwasm-schema", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.1.0", - "cw-xcall-lib", + "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", "cw2", "schemars 0.8.12", "serde", @@ -572,8 +572,8 @@ dependencies = [ "cosmwasm-storage", "cw-common", "cw-storage-plus 1.1.0", - "cw-xcall", - "cw-xcall-lib", + "cw-xcall 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", + "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", "cw2", "debug_print", "getrandom", @@ -593,7 +593,7 @@ dependencies = [ "cosmwasm-storage", "cw-common", "cw-storage-plus 1.1.0", - "cw-xcall", + "cw-xcall 0.1.0 (git+https://github.com/icon-project/xCall.git?branch=main)", "cw2", "getrandom", "hex", @@ -677,6 +677,24 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw-xcall" +version = "0.1.0" +source = "git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5#7f250bc9c6560591ccc16289cb8159dd100bbe76" +dependencies = [ + "common 0.1.0 (git+https://github.com/icon-project/IBC-Integration.git?branch=main)", + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus 1.1.0", + "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", + "cw2", + "debug_print", + "schemars 0.8.12", + "serde", + "thiserror", +] + [[package]] name = "cw-xcall" version = "0.1.0" @@ -687,7 +705,7 @@ dependencies = [ "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.1.0", - "cw-xcall-lib", + "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?branch=main)", "cw2", "debug_print", "schemars 0.8.12", @@ -706,8 +724,8 @@ dependencies = [ "cosmwasm-storage", "cw-common", "cw-storage-plus 1.1.0", - "cw-xcall", - "cw-xcall-lib", + "cw-xcall 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", + "cw-xcall-lib 0.1.0 (git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5)", "cw2", "debug_print", "getrandom", @@ -717,6 +735,22 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw-xcall-lib" +version = "0.1.0" +source = "git+https://github.com/icon-project/xCall.git?tag=v0.1.0-alpha.5#7f250bc9c6560591ccc16289cb8159dd100bbe76" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus 1.1.0", + "cw2", + "debug_print", + "schemars 0.8.12", + "serde", + "thiserror", +] + [[package]] name = "cw-xcall-lib" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 0acc4348a..9db606564 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,10 +18,10 @@ cosmwasm-storage = "1.2.2" cosmwasm-schema = "1.2.2" schemars = "0.8.12" cw-storage-plus = {git="https://github.com/icon-project/cw-storage-plus.git", branch="fix-raw"} -cw-xcall-lib={package="cw-xcall-lib", git="https://github.com/icon-project/xCall.git", branch="main"} -cw-xcall = {package="cw-xcall", git="https://github.com/icon-project/xCall.git", branch="main"} -cw-mock-dapp = { git="https://github.com/icon-project/xCall.git", branch="main" } -cw-mock-dapp-multi = { git="https://github.com/icon-project/xCall.git", branch="main" } +cw-xcall-lib={package="cw-xcall-lib", git="https://github.com/icon-project/xCall.git", tag="v0.1.0-alpha.5"} +cw-xcall = {package="cw-xcall", git="https://github.com/icon-project/xCall.git", tag="v0.1.0-alpha.5"} +cw-mock-dapp = { git="https://github.com/icon-project/xCall.git", tag="v0.1.0-alpha.5" } +cw-mock-dapp-multi = { git="https://github.com/icon-project/xCall.git", tag="v0.1.0-alpha.5" } cw2 = "1.0.1" ibc-proto = { version = "0.26.0", default-features = false} diff --git a/Makefile b/Makefile index cdaa5c9a4..d3147a0e8 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ DOCKER := $(shell which docker) DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf:1.9.0 PROJECT_NAME = $(shell git remote get-url origin | xargs basename -s .git) - +BRANCH ?= "main" export GO111MODULE = on @@ -44,20 +44,20 @@ build-builder-img: optimize-jar: @echo "Generating optimized jar for ICON contracts" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerBuilder}-icon$$"; then docker start -a "${containerBuilder}-icon" ; else docker run --name "${containerBuilder}-icon" -v $(CURDIR):/workspace --workdir /workspace $(builderImage) sh ./scripts/optimize-jar.sh; fi + @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerBuilder}-icon$$"; then docker start -a "${containerBuilder}-icon" ; else docker run --name "${containerBuilder}-icon" -v $(CURDIR):/workspace --workdir /workspace $(builderImage) bash ./scripts/optimize-jar.sh; fi optimize-cosmwasm: @echo "Generating optimized cosmwasm for Archway contracts" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerBuilder}-cosmwasm$$"; then docker start -a "${containerBuilder}-cosmwasm" ; else docker run --name "${containerBuilder}-cosmwasm" -v $(CURDIR):/workspace --workdir /workspace $(builderImage) sh ./scripts/optimize-cosmwasm.sh; fi + @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerBuilder}-cosmwasm$$"; then docker start -a "${containerBuilder}-cosmwasm" ; else docker run --name "${containerBuilder}-cosmwasm" -v $(CURDIR):/workspace --workdir /workspace $(builderImage) bash ./scripts/optimize-cosmwasm.sh; fi optimize-xcall: - @echo "Generating optimized xcall cosmwasm for Archway contracts" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerBuilder}-xcall$$"; then docker start -a "${containerBuilder}-xcall" ; else docker run --name "${containerBuilder}-xcall" -v $(CURDIR):/workspace --workdir /workspace $(builderImage) sh ./scripts/build-xcall.sh; fi + @echo "Generating optimized xcall contracts ..." + @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerBuilder}-xcall$$"; then docker start -a "${containerBuilder}-xcall" ; else docker run --name "${containerBuilder}-xcall" -v $(CURDIR):/workspace --workdir /workspace $(builderImage) bash ./scripts/optimize-xcall-build.sh build $(BRANCH); fi optimize-build: @echo "Generating optimized contracts..." - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerBuilder}$$"; then docker start -a ${containerBuilder}; else docker run --name $(containerBuilder) -v $(CURDIR):/workspace --workdir /workspace $(builderImage) sh ./scripts/optimize-build.sh; fi + @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerBuilder}$$"; then docker start -a ${containerBuilder}; else docker run --name $(containerBuilder) -v $(CURDIR):/workspace --workdir /workspace $(builderImage) bash ./scripts/optimize-build.sh build; fi gobuild: go build . @@ -75,4 +75,4 @@ e2e-demo-clean: go test -v ./test/e2e-demo -testify.m TestCleanup -.PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps gobuild +.PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps gobuild optimize-build optimize-xcall e2e-demo-setup e2e-demo-clean diff --git a/contracts/cosmwasm-vm/cw-common/src/core_msg.rs b/contracts/cosmwasm-vm/cw-common/src/core_msg.rs index 8712290ce..154e5fbf5 100644 --- a/contracts/cosmwasm-vm/cw-common/src/core_msg.rs +++ b/contracts/cosmwasm-vm/cw-common/src/core_msg.rs @@ -207,4 +207,11 @@ pub enum QueryMsg { }, #[returns(Vec)] GetPreviousConsensusStateHeight { client_id: String, height: u64 }, + #[returns(HashMap)] + GetAckHeights { + port_id: String, + channel_id: String, + start_sequence: u64, + end_sequence: u64, + }, } diff --git a/contracts/cosmwasm-vm/cw-ibc-core/src/context.rs b/contracts/cosmwasm-vm/cw-ibc-core/src/context.rs index 25a19e244..b2d8d0ba1 100644 --- a/contracts/cosmwasm-vm/cw-ibc-core/src/context.rs +++ b/contracts/cosmwasm-vm/cw-ibc-core/src/context.rs @@ -97,6 +97,20 @@ impl<'a> CwIbcCoreContext<'a> { return self.ibc_store().callback_data().remove(store, id); } + pub fn store_write_ack( + &self, + store: &mut dyn Storage, + port_id: &PortId, + channel_id: &ChannelId, + seq: u64, + height: u64, + ) -> Result<(), ContractError> { + self.ibc_store() + .write_acks() + .save(store, (port_id, channel_id, seq), &height) + .map_err(ContractError::Std) + } + pub fn get_callback_data( &self, store: &dyn Storage, diff --git a/contracts/cosmwasm-vm/cw-ibc-core/src/contract.rs b/contracts/cosmwasm-vm/cw-ibc-core/src/contract.rs index c30f91692..fda115c85 100644 --- a/contracts/cosmwasm-vm/cw-ibc-core/src/contract.rs +++ b/contracts/cosmwasm-vm/cw-ibc-core/src/contract.rs @@ -234,7 +234,7 @@ impl<'a> CwIbcCoreContext<'a> { } => { cw_println!(deps, "[IBCCore] Write Acknowledgement Called"); let ack = acknowledgement.to_bytes()?; - self.write_acknowledgement(deps, info, packet, ack) + self.write_acknowledgement(deps, info, &env, packet, ack) } } // Ok(Response::new()) @@ -290,10 +290,10 @@ impl<'a> CwIbcCoreContext<'a> { let client_val = IbcClientId::from_str(&client_id).unwrap(); let client = self.get_light_client(deps.storage, &client_val).unwrap(); let res = client - .get_consensus_state(deps, &client_val, height) + .get_consensus_state_any(deps, &client_val, height) .unwrap(); - let state = res.as_bytes(); - to_binary(&hex::encode(state)) + + to_binary(&hex::encode(res.encode_to_vec())) } QueryMsg::GetClientState { client_id } => { let res = self @@ -475,6 +475,26 @@ impl<'a> CwIbcCoreContext<'a> { .unwrap(); to_binary(&heights) } + QueryMsg::GetAckHeights { + port_id, + channel_id, + start_sequence, + end_sequence, + } => { + let port_id = IbcPortId::from_str(&port_id).unwrap(); + let channel_id = IbcChannelId::from_str(&channel_id).unwrap(); + let heights = self + .ibc_store() + .get_ack_heights( + deps.storage, + &port_id, + &channel_id, + start_sequence, + end_sequence, + ) + .unwrap(); + to_binary(&heights) + } QueryMsg::GetMissingPacketReceipts { port_id, diff --git a/contracts/cosmwasm-vm/cw-ibc-core/src/ics04_channel/packet/write_acknowledgement.rs b/contracts/cosmwasm-vm/cw-ibc-core/src/ics04_channel/packet/write_acknowledgement.rs index 3c11c9965..c8249d3b5 100644 --- a/contracts/cosmwasm-vm/cw-ibc-core/src/ics04_channel/packet/write_acknowledgement.rs +++ b/contracts/cosmwasm-vm/cw-ibc-core/src/ics04_channel/packet/write_acknowledgement.rs @@ -15,6 +15,7 @@ impl<'a> CwIbcCoreContext<'a> { &self, deps: DepsMut, info: MessageInfo, + env: &Env, packet: CwPacket, ack: Vec, ) -> Result { @@ -47,6 +48,8 @@ impl<'a> CwIbcCoreContext<'a> { Sequence::from(seq), AcknowledgementCommitment::from(ack_commitment), )?; + let height = env.block.height; + self.store_write_ack(deps.storage, &ibc_port, &ibc_channel, seq, height)?; let event = create_packet_event( IbcEventType::WriteAck, diff --git a/contracts/cosmwasm-vm/cw-ibc-core/src/state.rs b/contracts/cosmwasm-vm/cw-ibc-core/src/state.rs index cc0cd1dde..a3f5539da 100644 --- a/contracts/cosmwasm-vm/cw-ibc-core/src/state.rs +++ b/contracts/cosmwasm-vm/cw-ibc-core/src/state.rs @@ -116,6 +116,7 @@ pub struct CwIbcStore<'a> { // Stores data by replyid to be used later on reply from cross contract call callback_data: Map<'a, u64, Vec>, sent_packets: Map<'a, (&'a PortId, &'a ChannelId, u64), u64>, + write_acks: Map<'a, (&'a PortId, &'a ChannelId, u64), u64>, } impl<'a> Default for CwIbcStore<'a> { @@ -147,6 +148,7 @@ impl<'a> CwIbcStore<'a> { last_processed_on: Map::new(StorageKey::LastProcessedOn.as_str()), callback_data: Map::new(StorageKey::CallbackData.as_str()), sent_packets: Map::new(StorageKey::SentPackets.as_str()), + write_acks: Map::new(StorageKey::WriteAcks.as_str()), } } pub fn client_registry(&self) -> &Map<'a, IbcClientType, String> { @@ -214,6 +216,10 @@ impl<'a> CwIbcStore<'a> { &self.sent_packets } + pub fn write_acks(&self) -> &Map<'a, (&'a PortId, &'a ChannelId, u64), u64> { + &self.write_acks + } + pub fn clear_storage(&self, store: &mut dyn Storage) { let keys: Vec<_> = store .range(None, None, Order::Ascending) @@ -290,6 +296,28 @@ impl<'a> CwIbcStore<'a> { Ok(missing) } + pub fn get_ack_heights( + &self, + store: &dyn Storage, + port_id: &PortId, + channel_id: &ChannelId, + start_seq: u64, + end_seq: u64, + ) -> Result, ContractError> { + let min_key = (port_id, channel_id, start_seq); + let max_key = (port_id, channel_id, end_seq); + let min_bound = Bound::Inclusive::<(&PortId, &ChannelId, u64)>((min_key, PhantomData)); + let max_bound = Bound::Inclusive::<(&PortId, &ChannelId, u64)>((max_key, PhantomData)); + + let result: HashMap = self + .write_acks + .range(store, Some(min_bound), Some(max_bound), Order::Ascending) + .filter_map(|p| p.ok().map(|r| (r.0 .2, r.1))) + .collect(); + + Ok(result) + } + pub fn save_commitment( &self, store: &mut dyn Storage, diff --git a/contracts/cosmwasm-vm/cw-ibc-core/src/storage_keys.rs b/contracts/cosmwasm-vm/cw-ibc-core/src/storage_keys.rs index 9133c0083..d741cbc6c 100644 --- a/contracts/cosmwasm-vm/cw-ibc-core/src/storage_keys.rs +++ b/contracts/cosmwasm-vm/cw-ibc-core/src/storage_keys.rs @@ -30,6 +30,7 @@ pub enum StorageKey { LastProcessedOn, CallbackData, SentPackets, + WriteAcks, } impl StorageKey { @@ -58,6 +59,7 @@ impl StorageKey { StorageKey::LastProcessedOn => "last_processed_on", StorageKey::CallbackData => "callback_data", StorageKey::SentPackets => "sent_packets", + StorageKey::WriteAcks => "write_acks", } } } diff --git a/contracts/cosmwasm-vm/cw-ibc-core/tests/channel/test_write_acknowledgement.rs b/contracts/cosmwasm-vm/cw-ibc-core/tests/channel/test_write_acknowledgement.rs index d795ba3a0..bec648c0c 100644 --- a/contracts/cosmwasm-vm/cw-ibc-core/tests/channel/test_write_acknowledgement.rs +++ b/contracts/cosmwasm-vm/cw-ibc-core/tests/channel/test_write_acknowledgement.rs @@ -136,7 +136,7 @@ fn test_write_acknowledgement() { let mut test_context = TestContext::for_receive_packet(env.clone(), &msg); test_context.init_receive_packet(deps.as_mut().storage, &contract); mock_lightclient_query(test_context.mock_queries, &mut deps); - let res = contract.validate_receive_packet(deps.as_mut(), info, env, &msg); + let res = contract.validate_receive_packet(deps.as_mut(), info, env.clone(), &msg); println!("{:?}", res); assert!(res.is_ok()); assert_eq!( @@ -144,12 +144,26 @@ fn test_write_acknowledgement() { VALIDATE_ON_PACKET_RECEIVE_ON_MODULE ); let packet = msg.packet.unwrap(); - let ibc_packet = to_ibc_packet(packet).unwrap(); + let ibc_packet = to_ibc_packet(packet.clone()).unwrap(); let info = create_mock_info("moduleaddress", "umlg", 2000000000); - let ack_result = contract.write_acknowledgement(deps.as_mut(), info, ibc_packet, vec![11, 22]); + let ack_result = + contract.write_acknowledgement(deps.as_mut(), info, &env, ibc_packet, vec![11, 22]); println!("{ack_result:?}"); - assert!(ack_result.is_ok()) + assert!(ack_result.is_ok()); + let ack_height_saved = contract + .ibc_store() + .get_ack_heights( + deps.as_ref().storage, + &to_ibc_port_id(&packet.destination_port).unwrap(), + &to_ibc_channel_id(&packet.destination_channel).unwrap(), + packet.sequence, + packet.sequence + 1, + ) + .unwrap(); + let mut expected_result = HashMap::::new(); + expected_result.insert(packet.sequence, env.block.height); + assert_eq!(expected_result, ack_height_saved); } #[test] @@ -174,7 +188,8 @@ pub fn test_write_acknowledgement_fails_unauthorized() { let ibc_packet = to_ibc_packet(packet).unwrap(); let info = create_mock_info("invalidmoduleaddress", "umlg", 2000000000); - let ack_result = contract.write_acknowledgement(deps.as_mut(), info, ibc_packet, vec![11, 22]); + let ack_result = + contract.write_acknowledgement(deps.as_mut(), info, &mock_env(), ibc_packet, vec![11, 22]); println!("{ack_result:?}"); ack_result.unwrap(); } @@ -202,7 +217,8 @@ pub fn test_write_acknowledgement_fails_invalid_ack() { let ibc_packet = to_ibc_packet(packet).unwrap(); let info = create_mock_info("moduleaddress", "umlg", 2000000000); - let ack_result = contract.write_acknowledgement(deps.as_mut(), info, ibc_packet, vec![]); + let ack_result = + contract.write_acknowledgement(deps.as_mut(), info, &mock_env(), ibc_packet, vec![]); println!("{ack_result:?}"); ack_result.unwrap(); } @@ -238,7 +254,8 @@ pub fn test_write_acknowledgement_fails_invalid_channel_state() { let ibc_packet = to_ibc_packet(packet).unwrap(); let info = create_mock_info("moduleaddress", "umlg", 2000000000); - let ack_result = contract.write_acknowledgement(deps.as_mut(), info, ibc_packet, vec![11, 22]); + let ack_result = + contract.write_acknowledgement(deps.as_mut(), info, &mock_env(), ibc_packet, vec![11, 22]); println!("{ack_result:?}"); ack_result.unwrap(); } diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/admin.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/admin.rs index 47ffb136a..b6e625578 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/admin.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/admin.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{Addr, Api, MessageInfo, Response, Storage}; +use cosmwasm_std::{Addr, Api, Response, Storage}; use crate::{error::ContractError, state::CwIbcConnection}; @@ -42,11 +42,10 @@ impl<'a> CwIbcConnection<'a> { /// a `Result`. If the `admin` parameter is empty, it returns an `Err` with /// the `ContractError::AdminAddressCannotBeNull` variant. If the `info.sender` is not the owner, it /// returns an `Err` with the `ContractError::Unauthorized` variant. If an admin already exists, it - /// returns an `Err` with - pub fn add_admin( + /// returns an `Err` + pub fn update_admin( &self, store: &mut dyn Storage, - info: MessageInfo, admin: Addr, ) -> Result { self.admin().save(store, &admin)?; diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/contract.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/contract.rs index 020df5dab..5c20301c4 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/contract.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/contract.rs @@ -94,10 +94,10 @@ impl<'a> CwIbcConnection<'a> { ) -> Result { match msg { ExecuteMsg::SetAdmin { address } => { + self.ensure_admin(deps.as_ref().storage, info.sender)?; let validated_address = CwIbcConnection::validate_address(deps.api, address.as_str())?; - self.ensure_admin(deps.storage, info.clone().sender)?; - self.add_admin(deps.storage, info, validated_address) + self.update_admin(deps.storage, validated_address) } ExecuteMsg::SendMessage { to, sn, msg } => { println!("{LOG_PREFIX} Received Payload From XCall App"); @@ -305,7 +305,7 @@ impl<'a> CwIbcConnection<'a> { let owner = info.clone().sender; self.add_owner(store, owner.clone())?; - self.add_admin(store, info, owner)?; + self.update_admin(store, owner)?; // self.set_timeout_height(store, msg.timeout_height)?; self.set_ibc_host(store, msg.ibc_host.clone())?; self.set_xcall_host(store, msg.xcall_address)?; diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/fee.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/fee.rs index b9b148fe7..c61dc0786 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/fee.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/fee.rs @@ -14,7 +14,7 @@ impl<'a> CwIbcConnection<'a> { nid: NetId, address: String, ) -> Result { - let caller = info.sender.clone(); + let caller = info.sender; let fees = self.get_unclaimed_packet_fee(deps.as_ref().storage, &nid, caller.as_ref()); if fees == 0 { return Err(ContractError::NoFeesAccrued); @@ -31,7 +31,7 @@ impl<'a> CwIbcConnection<'a> { let timeout_height = self.query_timeout_height(deps.as_ref(), &ibc_config.src_endpoint().channel_id)?; let packet = self.create_packet(ibc_config, timeout_height, sequence_no, message); - let sub_msg = self.call_host_send_message(deps, info, packet)?; + let sub_msg = self.call_host_send_message(deps, packet)?; Ok(sub_msg) } diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/ibc_host.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/ibc_host.rs index f37f2fd20..32445009a 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/ibc_host.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/ibc_host.rs @@ -1,7 +1,7 @@ use crate::state::IbcConfig; use crate::types::LOG_PREFIX; use common::ibc::Height; -use cosmwasm_std::{to_binary, CosmosMsg, Deps, DepsMut, MessageInfo, Storage, SubMsg, WasmMsg}; +use cosmwasm_std::{to_binary, CosmosMsg, Deps, DepsMut, Storage, SubMsg, WasmMsg}; use cw_common::cw_types::CwPacket; use cw_common::query_helpers::build_smart_query; use cw_common::{hex_string::HexString, raw_types::channel::RawPacket, ProstMessage}; @@ -45,7 +45,6 @@ impl<'a> CwIbcConnection<'a> { pub fn call_host_send_message( &self, deps: DepsMut, - info: MessageInfo, packet: RawPacket, ) -> Result { let message = cw_common::core_msg::ExecuteMsg::SendPacket { @@ -57,7 +56,7 @@ impl<'a> CwIbcConnection<'a> { msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: ibc_host.to_string(), msg: to_binary(&message).map_err(ContractError::Std)?, - funds: info.funds, + funds: vec![], }), gas_limit: None, reply_on: cosmwasm_std::ReplyOn::Always, @@ -108,15 +107,14 @@ impl<'a> CwIbcConnection<'a> { #[cfg(test)] mod tests { + use crate::state::{CwIbcConnection, HOST_SEND_MESSAGE_REPLY_ID}; use cosmwasm_std::{ coin, testing::{mock_dependencies_with_balance, mock_env}, - to_binary, Addr, CosmosMsg, MessageInfo, SubMsg, WasmMsg, + to_binary, Addr, CosmosMsg, SubMsg, WasmMsg, }; use cw_common::{hex_string::HexString, raw_types::channel::RawPacket, ProstMessage}; - use crate::state::{CwIbcConnection, HOST_SEND_MESSAGE_REPLY_ID}; - #[test] fn test_call_host_send_message() { let mut deps = mock_dependencies_with_balance(&[coin(100, "ATOM")]); @@ -128,14 +126,11 @@ mod tests { connection .set_ibc_host(store, Addr::unchecked("ibc-host")) .unwrap(); - let env = mock_env(); - let info = MessageInfo { - sender: env.contract.address, - funds: vec![coin(100, "ATOM")], - }; + let _env = mock_env(); + let packet = RawPacket::default(); - let res = connection.call_host_send_message(deps.as_mut(), info, packet.clone()); + let res = connection.call_host_send_message(deps.as_mut(), packet.clone()); println!("{:?}", res); assert!(res.is_ok()); @@ -151,7 +146,7 @@ mod tests { msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: expected_ibc_host, msg: to_binary(&expected_message).unwrap(), - funds: vec![coin(100, "ATOM")], + funds: vec![], }), gas_limit: None, reply_on: cosmwasm_std::ReplyOn::Always, diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/send_message.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/send_message.rs index c6eab1861..72a93f347 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/send_message.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/send_message.rs @@ -18,7 +18,7 @@ impl<'a> CwIbcConnection<'a> { sn: i64, message: Vec, ) -> Result { - self.ensure_xcall_handler(deps.as_ref().storage, info.sender.clone())?; + self.ensure_xcall_handler(deps.as_ref().storage, info.sender)?; println!("{LOG_PREFIX} Packet Validated"); let ibc_config = self.get_ibc_config(deps.as_ref().storage, &nid)?; @@ -32,7 +32,7 @@ impl<'a> CwIbcConnection<'a> { let mut total_fee = network_fee.send_packet_fee; if sn > 0 { - total_fee = total_fee + network_fee.ack_fee; + total_fee += network_fee.ack_fee; self.add_unclaimed_ack_fees( deps.storage, &nid, @@ -75,7 +75,7 @@ impl<'a> CwIbcConnection<'a> { println!("{} Raw Packet Created {:?}", LOG_PREFIX, &packet_data); - let submessage = self.call_host_send_message(deps, info, packet_data)?; + let submessage = self.call_host_send_message(deps, packet_data)?; Ok(Response::new() .add_submessage(submessage) .add_attribute("method", "send_message")) diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/xcall.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/xcall.rs index 537b67a4c..6d060622f 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/xcall.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/src/xcall.rs @@ -15,7 +15,7 @@ impl<'a> CwIbcConnection<'a> { ) -> Result { let xcall_host = self.get_xcall_host(store)?; let xcall_msg = cw_xcall_lib::xcall_msg::ExecuteMsg::HandleMessage { - from: nid.clone(), + from_nid: nid.clone(), msg, }; let call_message: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { @@ -69,7 +69,7 @@ mod tests { let expected_xcall_host = connection.get_xcall_host(store).unwrap().to_string(); let expected_xcall_msg = - cw_xcall_lib::xcall_msg::ExecuteMsg::HandleMessage { msg, from: nid }; + cw_xcall_lib::xcall_msg::ExecuteMsg::HandleMessage { msg, from_nid: nid }; let expected_call_message = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: expected_xcall_host, msg: to_binary(&expected_xcall_msg).unwrap(), diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_admin.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_admin.rs index 0e039b0f6..752b429e6 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_admin.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_admin.rs @@ -6,38 +6,6 @@ use cw_common::xcall_connection_msg::{ExecuteMsg, QueryMsg}; use cw_xcall_ibc_connection::{execute, state::CwIbcConnection}; use setup::*; -#[test] -fn add_admin() { - let mut mock_deps = deps(); - - let mock_info = create_mock_info(&alice().to_string(), "umlg", 2000); - - let contract = CwIbcConnection::default(); - - contract - .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) - .unwrap(); - - let response = contract - .add_admin( - mock_deps.as_mut().storage, - mock_info, - Addr::unchecked(Addr::unchecked(admin_one().to_string())), - ) - .unwrap(); - - assert_eq!(response.attributes[0].value, "add_admin"); - - assert_eq!( - response.attributes[1].value, - Addr::unchecked(admin_one().to_string()) - ); - - let result = contract.query_admin(mock_deps.as_ref().storage).unwrap(); - - assert_eq!(result, Addr::unchecked(admin_one().to_string())) -} - #[test] #[should_panic(expected = "OnlyAdmin")] fn update_admin_unauthorzied() { @@ -48,13 +16,12 @@ fn update_admin_unauthorzied() { let contract = CwIbcConnection::default(); contract - .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) + .add_owner(mock_deps.as_mut().storage, mock_info.sender) .unwrap(); contract - .add_admin( + .update_admin( mock_deps.as_mut().storage, - mock_info, Addr::unchecked(Addr::unchecked(admin_one().to_string())), ) .unwrap(); @@ -81,13 +48,12 @@ fn update_admin() { let contract = CwIbcConnection::default(); contract - .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) + .add_owner(mock_deps.as_mut().storage, mock_info.sender) .unwrap(); contract - .add_admin( + .update_admin( mock_deps.as_mut().storage, - mock_info, Addr::unchecked(admin_one().to_string()), ) .unwrap(); @@ -133,7 +99,7 @@ fn add_invalid_char_as_admin() { let mut contract = CwIbcConnection::default(); contract - .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) + .update_admin(mock_deps.as_mut().storage, mock_info.clone().sender) .unwrap(); contract @@ -161,7 +127,7 @@ fn validate_address_add_admin_size_lessthan_3() { let mut contract = CwIbcConnection::default(); contract - .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) + .update_admin(mock_deps.as_mut().storage, mock_info.clone().sender) .unwrap(); contract @@ -189,7 +155,7 @@ fn validate_address_add_admin_size_more_than_45() { let mut contract = CwIbcConnection::default(); contract - .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) + .update_admin(mock_deps.as_mut().storage, mock_info.clone().sender) .unwrap(); contract @@ -209,18 +175,13 @@ fn validate_address_add_admin_size_more_than_45() { fn update_admin_fails() { let mut mock_deps = deps(); - let mock_info = create_mock_info(&alice().to_string(), "umlg", 2000); + let mock_info = create_mock_info(&admin_one().to_string(), "umlg", 2000); let contract = CwIbcConnection::default(); contract - .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) - .unwrap(); - - contract - .add_admin( + .update_admin( mock_deps.as_mut().storage, - mock_info.clone(), Addr::unchecked(admin_one().to_string()), ) .unwrap(); diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_ibc_functions.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_ibc_functions.rs index 047c23046..d99399080 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_ibc_functions.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_ibc_functions.rs @@ -14,7 +14,7 @@ use cw_xcall_ibc_connection::ack::{on_ack_failure, on_ack_sucess}; use cw_xcall_ibc_connection::types::config::Config; use cw_xcall_lib::network_address::{NetId, NetworkAddress}; -use cw_xcall::types::response::CallServiceMessageResponse; +use cw_xcall::types::response::CSMessageResponse; use cw_xcall_ibc_connection::msg::InstantiateMsg; use cw_xcall_ibc_connection::types::channel_config::ChannelConfig; use cw_xcall_ibc_connection::types::message::Message; @@ -26,8 +26,8 @@ use account::alice; use cosmwasm_std::from_binary; use cw_common::xcall_connection_msg::{ExecuteMsg, QueryMsg}; -use cw_xcall::types::message::CallServiceMessage; -use cw_xcall::types::request::CallServiceMessageRequest; +use cw_xcall::types::message::CSMessage; +use cw_xcall::types::request::CSMessageRequest; use cw_xcall_ibc_connection::state::CwIbcConnection; #[test] @@ -448,7 +448,7 @@ fn sucess_receive_packet_for_call_message_request() { .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) .unwrap(); - let data = CallServiceMessageRequest::new( + let data = CSMessageRequest::new( NetworkAddress::new("nid", mock_info.sender.as_str()), Addr::unchecked("alice"), 1, @@ -457,7 +457,7 @@ fn sucess_receive_packet_for_call_message_request() { vec![], ); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let message: Message = Message { sn: Nullable::new(Some(1)), fee: 0, @@ -564,7 +564,7 @@ fn sucess_on_ack_packet() { channel_id: "channel-3".to_string(), }; - let data = CallServiceMessageRequest::new( + let data = CSMessageRequest::new( NetworkAddress::new("nid", mock_info.sender.as_str()), Addr::unchecked("alice"), 1, @@ -591,7 +591,7 @@ fn sucess_on_ack_packet() { contract .store_channel_config(mock_deps.as_mut().storage, &channel, &channel_config) .unwrap(); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let packet = IbcPacket::new(to_binary(&message).unwrap(), src, dst, 0, timeout); @@ -651,7 +651,7 @@ fn fails_receive_packet_for_call_message_request() { .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) .unwrap(); - let data = CallServiceMessageRequest::new( + let data = CSMessageRequest::new( NetworkAddress::new("nid", mock_info.sender.as_str()), Addr::unchecked("alice"), 1, @@ -660,7 +660,7 @@ fn fails_receive_packet_for_call_message_request() { vec![], ); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let timeout_block = IbcTimeoutBlock { revision: 0, @@ -813,7 +813,7 @@ fn fails_on_configure_connection_unauthorized() { fn test_ack_success_on_call_request() { let mock_info = create_mock_info("alice", "umlg", 2000); - let data = CallServiceMessageRequest::new( + let data = CSMessageRequest::new( NetworkAddress::new("nid", mock_info.sender.as_str()), Addr::unchecked("alice"), 1, @@ -822,7 +822,7 @@ fn test_ack_success_on_call_request() { vec![], ); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let timeout_block = IbcTimeoutBlock { revision: 0, @@ -850,12 +850,12 @@ fn test_ack_success_on_call_request() { #[test] fn test_ack_success_on_call_response() { - let data = cw_xcall::types::response::CallServiceMessageResponse::new( + let data = cw_xcall::types::response::CSMessageResponse::new( 0, cw_xcall::types::response::CallServiceResponseType::CallServiceResponseSuccess, ); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let timeout_block = IbcTimeoutBlock { revision: 0, @@ -885,7 +885,7 @@ fn test_ack_success_on_call_response() { fn test_ack_failure_on_call_request() { let mock_info = create_mock_info("alice", "umlg", 2000); - let data = CallServiceMessageRequest::new( + let data = CSMessageRequest::new( NetworkAddress::new("nid", mock_info.sender.as_str()), Addr::unchecked("alice"), 1, @@ -894,7 +894,7 @@ fn test_ack_failure_on_call_request() { vec![], ); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let timeout_block = IbcTimeoutBlock { revision: 0, @@ -922,12 +922,12 @@ fn test_ack_failure_on_call_request() { #[test] fn test_ack_failure_on_call_response() { - let data = CallServiceMessageResponse::new( + let data = CSMessageResponse::new( 0, cw_xcall::types::response::CallServiceResponseType::CallServiceResponseSuccess, ); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let timeout_block = IbcTimeoutBlock { revision: 0, @@ -974,12 +974,12 @@ fn test_handle_response() { .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) .unwrap(); - let data = CallServiceMessageResponse::new( + let data = CSMessageResponse::new( 0, cw_xcall::types::response::CallServiceResponseType::CallServiceResponseSuccess, ); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let message = Message { sn: Nullable::new(Some(0)), fee: 0, @@ -1042,9 +1042,9 @@ fn test_handle_response() { fn test_for_call_service_request_from_rlp_bytes() { let hex_decode_rlp_data = hex::decode("f1976e69642f736f6d65636f6e74726163746164647265737393736f6d65636f6e7472616374616464726573730100f800c0").unwrap(); - let cs_message_request = CallServiceMessageRequest::try_from(&hex_decode_rlp_data).unwrap(); + let cs_message_request = CSMessageRequest::try_from(&hex_decode_rlp_data).unwrap(); - let expected_data = CallServiceMessageRequest::new( + let expected_data = CSMessageRequest::new( NetworkAddress::new("nid", "somecontractaddress"), Addr::unchecked("somecontractaddress"), 1, @@ -1059,9 +1059,9 @@ fn test_for_call_service_request_from_rlp_bytes() { #[test] fn test_for_call_service_response_from_rlp_bytes() { let hex_decode_rlp_data = hex::decode("c20100").unwrap(); - let cs_response_message = CallServiceMessageResponse::try_from(&hex_decode_rlp_data).unwrap(); + let cs_response_message = CSMessageResponse::try_from(&hex_decode_rlp_data).unwrap(); - let expected_data = CallServiceMessageResponse::new( + let expected_data = CSMessageResponse::new( 1, cw_xcall::types::response::CallServiceResponseType::CallServiceResponseFailure, ); @@ -1072,11 +1072,11 @@ fn test_for_call_service_response_from_rlp_bytes() { fn test_for_call_message_data_from_rlp_bytes() { let hex_decode = hex::decode("f401b2f1976e69642f736f6d65636f6e74726163746164647265737393736f6d65636f6e7472616374616464726573730100f800c0").unwrap(); - let cs_message = CallServiceMessage::try_from(hex_decode).unwrap(); + let cs_message = CSMessage::try_from(hex_decode).unwrap(); - let cs_message_request = CallServiceMessageRequest::try_from(cs_message.payload()).unwrap(); + let cs_message_request = CSMessageRequest::try_from(cs_message.payload()).unwrap(); - let expected_data = CallServiceMessageRequest::new( + let expected_data = CSMessageRequest::new( NetworkAddress::new("nid", "somecontractaddress"), Addr::unchecked("somecontractaddress"), 1, @@ -1092,11 +1092,11 @@ fn test_for_call_message_data_from_rlp_bytes() { fn test_call_message_from_raw_message() { let data=hex::decode("f401b2f1976e69642f736f6d65636f6e74726163746164647265737393736f6d65636f6e7472616374616464726573730100f800c0").unwrap(); - let cs_message = CallServiceMessage::try_from(data).unwrap(); + let cs_message = CSMessage::try_from(data).unwrap(); - let cs_message_request = CallServiceMessageRequest::try_from(cs_message.payload()).unwrap(); + let cs_message_request = CSMessageRequest::try_from(cs_message.payload()).unwrap(); - let expected_data = CallServiceMessageRequest::new( + let expected_data = CSMessageRequest::new( NetworkAddress::new("nid", "somecontractaddress"), Addr::unchecked("somecontractaddress"), 1, diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_owner.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_owner.rs index e1013ceba..eb8f1b8de 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_owner.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_owner.rs @@ -40,6 +40,6 @@ fn add_existing_owner() { assert_eq!(result, mock_info.sender.to_string()); contract - .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) + .add_owner(mock_deps.as_mut().storage, mock_info.sender) .unwrap(); } diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_receive_packet.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_receive_packet.rs index 3e21ff8b4..480fa1d32 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_receive_packet.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_receive_packet.rs @@ -9,9 +9,9 @@ use cosmwasm_std::{ }; use cw_xcall::types::{ - message::CallServiceMessage, - request::CallServiceMessageRequest, - response::CallServiceMessageResponse, + message::CSMessage, + request::CSMessageRequest, + response::CSMessageResponse, rlp::{self}, }; use cw_xcall_ibc_connection::{ @@ -36,7 +36,7 @@ fn test_receive_packet_for_call_message_request() { .set_xcall_host(mock_deps.as_mut().storage, Addr::unchecked("xcallhost")) .unwrap(); - let data = CallServiceMessageRequest::new( + let data = CSMessageRequest::new( NetworkAddress::new("nid", mock_info.sender.as_str()), Addr::unchecked(alice().to_string()), 1, @@ -45,7 +45,7 @@ fn test_receive_packet_for_call_message_request() { vec![], ); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let message: Message = Message { sn: common::rlp::Nullable::new(Some(0)), fee: 0, @@ -84,18 +84,18 @@ fn test_receive_packet_for_call_message_response() { let contract = CwIbcConnection::default(); contract - .add_owner(mock_deps.as_mut().storage, mock_info.clone().sender) + .add_owner(mock_deps.as_mut().storage, mock_info.sender) .unwrap(); contract .set_xcall_host(mock_deps.as_mut().storage, Addr::unchecked("xcallhost")) .unwrap(); - let data = CallServiceMessageResponse::new( + let data = CSMessageResponse::new( 1, cw_xcall::types::response::CallServiceResponseType::CallServiceResponseSuccess, ); - let message: CallServiceMessage = data.try_into().unwrap(); + let message: CSMessage = data.try_into().unwrap(); let message: Message = Message { sn: common::rlp::Nullable::new(Some(0)), fee: 0, diff --git a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_send_message.rs b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_send_message.rs index 3dd9931c8..cd838398c 100644 --- a/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_send_message.rs +++ b/contracts/cosmwasm-vm/cw-xcall-ibc-connection/tests/test_send_message.rs @@ -57,8 +57,8 @@ fn send_message_setup() -> ( contract .store_ibc_config( deps.as_mut().storage, - &nid.clone(), - &IbcConfig::new(src.clone(), dst.clone()), + &nid, + &IbcConfig::new(src.clone(), dst), ) .unwrap(); @@ -69,7 +69,7 @@ fn send_message_setup() -> ( let xcall_address = Addr::unchecked("xcalladdress"); contract - .set_xcall_host(deps.as_mut().storage, xcall_address.clone()) + .set_xcall_host(deps.as_mut().storage, xcall_address) .unwrap(); contract @@ -163,7 +163,7 @@ fn send_message_with_negative_sn() { }; let timeout = IbcTimeout::with_block(timeout_block); - let packet = IbcPacket::new(vec![], src.clone(), dst.clone(), 0, timeout); + let packet = IbcPacket::new(vec![], src.clone(), dst, 0, timeout); contract .store_incoming_packet(deps.as_mut().storage, &src.channel_id, 1, packet) diff --git a/contracts/javascore/build.gradle b/contracts/javascore/build.gradle index 1061b85be..5592363f3 100644 --- a/contracts/javascore/build.gradle +++ b/contracts/javascore/build.gradle @@ -116,7 +116,9 @@ task collectOptimizedJars(type: Copy) { task zipOutputOptimizedJars(type: Zip) { dependsOn collectOptimizedJars from("$buildDir/output-jars") { - include '**/*-optimized.jar' + include '**/ibc-*.jar' + include '**/tendermint-*.jar' + include '**/xcall-connection-*.jar' } archiveFileName = "javascore-contracts.zip" destinationDirectory = file("$buildDir") diff --git a/contracts/javascore/ibc/src/main/java/ibc/ics04/channel/IBCPacket.java b/contracts/javascore/ibc/src/main/java/ibc/ics04/channel/IBCPacket.java index c4c96407e..548588506 100644 --- a/contracts/javascore/ibc/src/main/java/ibc/ics04/channel/IBCPacket.java +++ b/contracts/javascore/ibc/src/main/java/ibc/ics04/channel/IBCPacket.java @@ -44,9 +44,9 @@ public void _sendPacket(Packet packet) { Context.require(packet.getTimeoutTimestamp().equals(BigInteger.ZERO), "Timeout timestamps are not available, use timeout height instead"); - DictDB nextSequenceSourcePort = nextSequenceSends.at(packet.getSourcePort()); - BigInteger nextSequenceSend = nextSequenceSourcePort.getOrDefault(packet.getSourceChannel(), BigInteger.ZERO); + BigInteger nextSequenceSend = nextSequenceSourcePort.getOrDefault(packet.getSourceChannel(), + BigInteger.ZERO); Context.require( packet.getSequence().equals(nextSequenceSend), "packet sequence != next send sequence"); @@ -59,14 +59,16 @@ public void _sendPacket(Packet packet) { byte[] packetCommitment = createPacketCommitment(packet); commitments.set(packetCommitmentKey, packetCommitment); - packetHeights.at(packet.getSourcePort()).at(packet.getSourceChannel()).set(packet.getSequence(), Context.getBlockHeight()); + packetHeights.at(packet.getSourcePort()).at(packet.getSourceChannel()).set(packet.getSequence(), + Context.getBlockHeight()); sendBTPMessage(connection.getClientId(), ByteUtil.join(packetCommitmentKey, packetCommitment)); } public void _recvPacket(Packet packet, byte[] proof, byte[] proofHeight) { - Channel channel = Channel.decode(channels.at(packet.getDestinationPort()).get(packet.getDestinationChannel())); + Channel channel = Channel + .decode(channels.at(packet.getDestinationPort()).get(packet.getDestinationChannel())); Context.require(channel.getState() == Channel.State.STATE_OPEN, "channel state must be OPEN"); Context.require( @@ -85,7 +87,8 @@ public void _recvPacket(Packet packet, byte[] proof, byte[] proofHeight) { Context.require( packet.getTimeoutHeight().getRevisionHeight().equals(BigInteger.ZERO) || BigInteger.valueOf(Context.getBlockHeight()) - .compareTo(packet.getTimeoutHeight().getRevisionHeight()) < 0, + .compareTo(packet.getTimeoutHeight() + .getRevisionHeight()) < 0, "block height >= packet timeout height"); Context.require( packet.getTimeoutTimestamp().equals(BigInteger.ZERO) @@ -114,12 +117,14 @@ public void _recvPacket(Packet packet, byte[] proof, byte[] proofHeight) { } else if (channel.getOrdering() == Channel.Order.ORDER_ORDERED) { DictDB nextSequenceDestinationPort = nextSequenceReceives .at(packet.getDestinationPort()); - BigInteger nextSequenceRecv = nextSequenceDestinationPort.getOrDefault(packet.getDestinationChannel(), + BigInteger nextSequenceRecv = nextSequenceDestinationPort.getOrDefault( + packet.getDestinationChannel(), BigInteger.ZERO); Context.require( nextSequenceRecv.equals(packet.getSequence()), "packet sequence != next receive sequence"); - nextSequenceDestinationPort.set(packet.getDestinationChannel(), nextSequenceRecv.add(BigInteger.ONE)); + nextSequenceDestinationPort.set(packet.getDestinationChannel(), + nextSequenceRecv.add(BigInteger.ONE)); } else { Context.revert("unknown ordering type"); } @@ -141,6 +146,9 @@ public void _writeAcknowledgement(String destinationPortId, String destinationCh Context.require(commitments.get(ackCommitmentKey) == null, "acknowledgement for packet already exists"); byte[] ackCommitment = IBCCommitment.keccak256(acknowledgement); commitments.set(ackCommitmentKey, ackCommitment); + ackHeights.at(destinationPortId).at(destinationChannel).set(sequence, + Context.getBlockHeight()); + sendBTPMessage(connection.getClientId(), ByteUtil.join(ackCommitmentKey, ackCommitment)); } @@ -216,7 +224,7 @@ public void _requestTimeout(MsgRequestTimeoutPacket msg) { Context.require(connection.getState() == ConnectionEnd.State.STATE_OPEN, "connection state is not OPEN"); - BigInteger revisionHeight=packet.getTimeoutHeight().getRevisionHeight(); + BigInteger revisionHeight = packet.getTimeoutHeight().getRevisionHeight(); boolean heightTimeout = revisionHeight.compareTo(BigInteger.ZERO) > 0 && BigInteger.valueOf(Context.getBlockHeight()) .compareTo(revisionHeight) >= 0; @@ -282,7 +290,8 @@ public void _timeoutPacket(Packet packet, byte[] proofHeight, byte[] proof, BigI // check that timeout height or timeout timestamp has passed on the other end Height height = Height.decode(proofHeight); boolean heightTimeout = packet.getTimeoutHeight().getRevisionHeight().compareTo(BigInteger.ZERO) > 0 - && height.getRevisionHeight().compareTo(packet.getTimeoutHeight().getRevisionHeight()) >= 0; + && height.getRevisionHeight() + .compareTo(packet.getTimeoutHeight().getRevisionHeight()) >= 0; Context.require(heightTimeout, "Packet has not yet timed out"); // verify we actually sent this packet, check the store @@ -304,8 +313,7 @@ public void _timeoutPacket(Packet packet, byte[] proofHeight, byte[] proof, BigI connection, proofHeight, proof, - packetReceiptKey - ); + packetReceiptKey); } else if (channel.getOrdering() == Channel.Order.ORDER_ORDERED) { // ordered channel: check that packet has not been received // only allow timeout on next sequence so all sequences before the timed out @@ -327,14 +335,16 @@ public void _timeoutPacket(Packet packet, byte[] proofHeight, byte[] proof, BigI channel.setState(Channel.State.STATE_CLOSED); byte[] encodedChannel = channel.encode(); - updateChannelCommitment(connection.getClientId(), packet.getSourcePort(), packet.getSourceChannel(), encodedChannel); + updateChannelCommitment(connection.getClientId(), packet.getSourcePort(), + packet.getSourceChannel(), encodedChannel); channels.at(packet.getSourcePort()).set(packet.getSourceChannel(), encodedChannel); } else { Context.revert("unknown ordering type"); } commitments.set(packetCommitmentKey, null); - packetHeights.at(packet.getSourcePort()).at(packet.getSourceChannel()).set(packet.getSequence(), Context.getBlockHeight()); + packetHeights.at(packet.getSourcePort()).at(packet.getSourceChannel()).set(packet.getSequence(), + Context.getBlockHeight()); } diff --git a/contracts/javascore/ibc/src/main/java/ibc/ics24/host/IBCStore.java b/contracts/javascore/ibc/src/main/java/ibc/ics24/host/IBCStore.java index 6f3fb5581..ba067e754 100644 --- a/contracts/javascore/ibc/src/main/java/ibc/ics24/host/IBCStore.java +++ b/contracts/javascore/ibc/src/main/java/ibc/ics24/host/IBCStore.java @@ -1,7 +1,7 @@ package ibc.ics24.host; -import ibc.icon.interfaces.ILightClient; import ibc.icon.interfaces.IIBCHost; +import ibc.icon.interfaces.ILightClient; import ibc.icon.interfaces.ILightClientScoreInterface; import ibc.icon.score.util.NullChecker; import ibc.ics05.port.ModuleManager; @@ -25,7 +25,7 @@ public abstract class IBCStore extends ModuleManager implements IIBCHost { private static final String NEXT_SEQUENCE_RECEIVES = "nextSequenceReceives"; private static final String NEXT_SEQUENCE_ACKNOWLEDGEMENTS = "nextSequenceAcknowledgements"; private static final String PACKET_RECEIPTS = "packetReceipts"; - private static final String PACKET_HEIGHTS= "packetHeights"; + private static final String PACKET_HEIGHTS = "packetHeights"; private static final String CAPABILITIES = "capabilities"; private static final String PORT_IDS = "portIds"; private static final String EXPECTED_TIME_PER_BLOCK = "expectedTimePerBlock"; @@ -34,6 +34,7 @@ public abstract class IBCStore extends ModuleManager implements IIBCHost { private static final String NEXT_CHANNEL_SEQUENCE = "nextChannelSequence"; private static final String BTP_NETWORK_ID = "btpNetworkId"; private static final String TIMEOUT_REQUESTS = "timeout_requests"; + private static final String ACK_HEIGHTS = "ackHeights"; // DB Variables // Commitments @@ -61,17 +62,21 @@ public abstract class IBCStore extends ModuleManager implements IIBCHost { .newBranchDB(PACKET_RECEIPTS, Boolean.class); public static final BranchDB>> packetHeights = Context .newBranchDB(PACKET_HEIGHTS, Long.class); + public static final BranchDB>> ackHeights = Context + .newBranchDB(ACK_HEIGHTS, Long.class); - public static final DictDB capabilities = Context.newDictDB(CAPABILITIES, Address.class); + public static final DictDB capabilities = Context.newDictDB(CAPABILITIES, Address.class); public static final ArrayDB portIds = Context.newArrayDB(PORT_IDS, String.class); // Host Parameters - public static final VarDB expectedTimePerBlock = Context.newVarDB(EXPECTED_TIME_PER_BLOCK, BigInteger.class); + public static final VarDB expectedTimePerBlock = Context.newVarDB(EXPECTED_TIME_PER_BLOCK, + BigInteger.class); // Sequences for identifiers public static final VarDB nextClientSequence = Context.newVarDB(NEXT_CLIENT_SEQUENCE, BigInteger.class); public static final VarDB nextConnectionSequence = Context.newVarDB(NEXT_CONNECTION_SEQUENCE, BigInteger.class); - public static final VarDB nextChannelSequence = Context.newVarDB(NEXT_CHANNEL_SEQUENCE, BigInteger.class); + public static final VarDB nextChannelSequence = Context.newVarDB(NEXT_CHANNEL_SEQUENCE, + BigInteger.class); public static final DictDB btpNetworkId = Context.newDictDB(BTP_NETWORK_ID, Integer.class); public static final DictDB timeoutRequests = Context.newDictDB(TIMEOUT_REQUESTS, Boolean.class); @@ -123,7 +128,7 @@ public BigInteger getNextSequenceAcknowledgement(String portId, String channelId @External(readonly = true) public boolean getPacketReceipt(String portId, String channelId, BigInteger sequence) { - return packetReceipts.at(portId).at(channelId).getOrDefault(sequence, false); + return packetReceipts.at(portId).at(channelId).getOrDefault(sequence, false); } @External(readonly = true) @@ -189,7 +194,22 @@ public Map getPacketHeights(String portId, String channelId, int s for (int i = startSequence; i <= endSequence; i++) { BigInteger sequence = BigInteger.valueOf(i); Long height = packets.get(sequence); - if (height != null){ + if (height != null) { + heights.put(sequence.toString(), height); + } + } + + return heights; + } + + @External(readonly = true) + public Map getAckHeights(String portId, String channelId, int startSequence, int endSequence) { + DictDB acks = ackHeights.at(portId).at(channelId); + Map heights = new HashMap<>(); + for (int i = startSequence; i <= endSequence; i++) { + BigInteger sequence = BigInteger.valueOf(i); + Long height = acks.get(sequence); + if (height != null) { heights.put(sequence.toString(), height); } } diff --git a/contracts/javascore/ibc/src/test/java/ibc/ics25/handler/IBCHandlerTest.java b/contracts/javascore/ibc/src/test/java/ibc/ics25/handler/IBCHandlerTest.java index b4b877748..71bf7524e 100644 --- a/contracts/javascore/ibc/src/test/java/ibc/ics25/handler/IBCHandlerTest.java +++ b/contracts/javascore/ibc/src/test/java/ibc/ics25/handler/IBCHandlerTest.java @@ -10,6 +10,7 @@ import java.math.BigInteger; import java.util.List; +import java.util.Map; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -100,6 +101,23 @@ void sendAndAckPacket() throws Exception { acknowledgePacket(); } + @Test + @SuppressWarnings("unchecked") + void ackResponse_checkAckHeightSaved() throws Exception{ + + establishCommunication(); + + receivePacket(); + Map ackHeights = (Map) handler.call("getAckHeights", portId, channelId, 0,10); + assertEquals( ackHeights.keySet().size(), 0); + + + writeAcknowledgement(); + ackHeights = (Map) handler.call("getAckHeights", portId, channelId, 0, 10); + assertEquals( ackHeights.keySet().size(), 1); + assertTrue(ackHeights.get("1") !=null, "ack height is not saved properly" ); + } + @Test void sendAndTimeoutPacket() throws Exception { establishCommunication(); diff --git a/contracts/javascore/xcall-connection/src/main/java/ibc/xcall/connection/IBCConnection.java b/contracts/javascore/xcall-connection/src/main/java/ibc/xcall/connection/IBCConnection.java index 54bdff5bb..baed21b2c 100644 --- a/contracts/javascore/xcall-connection/src/main/java/ibc/xcall/connection/IBCConnection.java +++ b/contracts/javascore/xcall-connection/src/main/java/ibc/xcall/connection/IBCConnection.java @@ -168,8 +168,9 @@ public byte[] onRecvPacket(byte[] calldata, Address relayer) { String nid = networkIds.get(packet.getDestinationChannel()); Context.require(nid != null, "Channel is not configured"); - if (msg.getSn() == null) { - Context.transfer(new Address(msg.getData()), msg.getFee()); + if (msg.getSn() == null) { + String to = new String(msg.getData()); + Context.transfer(Address.fromString(to), msg.getFee()); return new byte[0]; } diff --git a/contracts/javascore/xcall-connection/src/test/java/ibc/xcall/connection/IBCConnectionTest.java b/contracts/javascore/xcall-connection/src/test/java/ibc/xcall/connection/IBCConnectionTest.java index fc323812d..740bd7a54 100644 --- a/contracts/javascore/xcall-connection/src/test/java/ibc/xcall/connection/IBCConnectionTest.java +++ b/contracts/javascore/xcall-connection/src/test/java/ibc/xcall/connection/IBCConnectionTest.java @@ -12,6 +12,7 @@ import com.iconloop.score.test.Account; import com.iconloop.score.test.ServiceManager; +import ibc.icon.score.util.StringUtil; import icon.proto.core.channel.Packet; import icon.proto.core.client.Height; @@ -22,6 +23,7 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import score.Address; public class IBCConnectionTest extends IBCConnectionTestBase { @@ -326,7 +328,7 @@ public void recvClaimFees() { Packet pct = new Packet(); pct.setSequence(seq); - pct.setData(new Message(null, fee, relayer.getAddress().toByteArray()).toBytes()); + pct.setData(new Message(null, fee, relayer.getAddress().toString().getBytes()).toBytes()); pct.setSourcePort(defaultCounterpartyPort); pct.setSourceChannel(defaultCounterpartyChannel); pct.setDestinationPort(IBCConnection.PORT); @@ -424,4 +426,14 @@ public void entryPermissions() { () -> connection.invoke(nonAuthorized, "configureConnection", "", "", "", "", BigInteger.ZERO)); assertEquals(expectedErrorMessage, e.getMessage()); } + + @Test + public void decodeAddress() { + String str = "f6f800883782dace9d900000aa687862366235373931626530623565663637303633623363313062383430666238313531346462326664"; + byte[] val = StringUtil.hexToBytes(str); + Message m = Message.fromBytes(val); + + assertNull(m.getSn()); + assertEquals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"), Address.fromString(new String(m.getData()))); + } } \ No newline at end of file diff --git a/docs/e2e-integration-test-setup.md b/docs/e2e-integration-test-setup.md index 657b94414..fd184544b 100644 --- a/docs/e2e-integration-test-setup.md +++ b/docs/e2e-integration-test-setup.md @@ -95,10 +95,28 @@ export GOLOOP_IMAGE_ENV=goloop-icon export GOLOOP_IMAGE_TAG_ENV=latest ``` -#### 2. Execute the Test Suite +#### 2. Run the Test Script + +Use the appropriate command to run the test suite. Depending on your specific testing requirements, you can use the following command: + +```bash +./scripts/execute-test.sh [options] +``` + +Replace `[options]` with any command-line options or arguments that the test script supports. To view more details about available options and usage, run the following command: + +```bash +./scripts/execute-test.sh --help +``` + +This will display the available options, explain how to use them, and provide additional information about running the tests. + + +#### 3. Execute the Test Suite Depending on your specific testing requirements, employ the appropriate commands to run the test suite: + - To execute the end-to-end tests: ```bash go test -v ./test/e2e -timeout 0 diff --git a/scripts/.DockerfileContractBuilder b/scripts/.DockerfileContractBuilder index da2343e45..cc6eb5bd1 100644 --- a/scripts/.DockerfileContractBuilder +++ b/scripts/.DockerfileContractBuilder @@ -10,6 +10,7 @@ ENV RUSTUP_HOME=/usr/local/rustup \ RUN set -eux; \ apt update; \ apt-get install -y --no-install-recommends \ + git bash \ ca-certificates \ gcc \ libc6-dev \ diff --git a/scripts/build-xcall.sh b/scripts/build-xcall.sh deleted file mode 100755 index 8f2bbd813..000000000 --- a/scripts/build-xcall.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -set -e -mkdir -p artifacts/icon -mkdir -p artifacts/archway - -echo "building xcall contracts..." -cd xcall-multi -./scripts/optimize-cosmwasm.sh -./scripts/optimize-jar.sh -echo "$PWD" -cp artifacts/archway/*.wasm ../artifacts/archway/ -cp artifacts/icon/*.jar ../artifacts/icon/ diff --git a/scripts/clean-build-and-exexute-e2e.sh b/scripts/clean-build-and-exexute-e2e.sh deleted file mode 100755 index 32a03cb8c..000000000 --- a/scripts/clean-build-and-exexute-e2e.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -set -e -echo "cleaning contract directories..." -find artifacts/icon -type f -exec rm {} \; -find artifacts/archway -type f -exec rm {} \; -echo "building contracts..." -./scripts/build-xcall.sh -./scripts/optimize-cosmwasm.sh -./scripts/optimize-jar.sh -echo "executing e2e test..." -go test -v ./test/e2e -timeout 0 -count=1 - - diff --git a/scripts/deploy_cosmwasm.sh b/scripts/deploy_cosmwasm.sh index 802094a26..149214f41 100755 --- a/scripts/deploy_cosmwasm.sh +++ b/scripts/deploy_cosmwasm.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -e diff --git a/scripts/execute-test.sh b/scripts/execute-test.sh new file mode 100755 index 000000000..3e99e8b7d --- /dev/null +++ b/scripts/execute-test.sh @@ -0,0 +1,124 @@ +#!/bin/bash +set -e + +# Source external scripts +. scripts/optimize-xcall-build.sh +. scripts/optimize-build.sh + +# Define a usage function to display how to use the script +usage() { + echo "Usage: $0 [options]" + echo "Options:" + echo " --clean : Clean contract directories (true/false, default: false)." + echo " --build-ibc : Build IBC contracts (true/false, default: false)." + echo " --build-xcall : Build xCall contracts (true/false, default: false)." + echo " --xcall-branch : Specify the xCall branch to build (default: main)." + echo " --use-docker : Use Docker for building contracts(true/false, default: false)." + echo " --test : Specify the type of test (e2e, e2e-demo, integration, default: e2e)." + exit 1 +} + +# Define variables with default values +use_docker="false" +clean="false" +build_ibc="false" +build_xcall="false" +test="e2e" +xcall_branch="main" + +# Define functions + +clean_contracts() { + echo "Cleaning contract directories..." + find artifacts/icon -type f -exec rm {} \; + find artifacts/archway -type f -exec rm {} \; +} + +e2e_test() { + echo "Running e2e test..." + go test -v ./test/e2e -timeout 0 -count=1 +} + +e2e_demo() { + echo "Configuring e2e demo..." + export PRESERVE_DOCKER=true && go test -v ./test/e2e-demo -testify.m TestSetup +} + +integration_test() { + echo "Running integration test..." + go test -v ./test/integration -timeout 0 -count=1 +} + +# Parse command line arguments +while [ $# -gt 0 ]; do + case "$1" in + --clean) + clean="true" + ;; + --build-ibc) + build_ibc="true" + ;; + --build-xcall) + build_xcall="true" + ;; + --xcall-branch) + shift + xcall_branch="$1" + ;; + --use-docker) + use_docker="true" + ;; + --test) + shift + test="$1" + ;; + *) + echo "Error: Unknown option '$1'." + usage + ;; + esac + shift +done +# Perform actions based on command line arguments + +if [ "$clean" = "true" ]; then + clean_contracts +fi + +if [ "$build_ibc" = "true" ]; then + echo "building IBC contracts..." + if [ "$use_docker" = "true" ]; then + make optimize-build & + wait + else + build_ibc_contracts + fi +fi + +if [ "$build_xcall" = "true" ]; then + echo "building xCall contracts..." + if [ "$use_docker" = "true" ]; then + make optimize-xcall BRANCH="$xcall_branch" & + wait + else + build_xCall_contracts "$xcall_branch" + fi +fi + +# Run the selected test +echo "running $test......" +case "$test" in +"e2e") + e2e_test + ;; +"e2e-demo") + e2e_demo + ;; +"integration") + integration_test + ;; +*) + echo "Error: Unknown test type '$test'." + exit 1 + ;; +esac diff --git a/scripts/optimize-build.sh b/scripts/optimize-build.sh index f38d748f4..8192f9f0d 100755 --- a/scripts/optimize-build.sh +++ b/scripts/optimize-build.sh @@ -1,8 +1,12 @@ #!/bin/bash set -e -echo "Generating optimized cosmwasm for Archway contracts..." -sh ./scripts/optimize-cosmwasm.sh -echo "Generating optimized cosmwasm (xCall) for icon contracts..." -sh ./scripts/build-xcall.sh -echo "Generating optimized jar for icon contracts..." -sh ./scripts/optimize-jar.sh +build_ibc_contracts() { + echo "Generating optimized cosmwasm for Archway contracts..." + bash ./scripts/optimize-cosmwasm.sh + echo "Generating optimized jar for icon contracts..." + bash ./scripts/optimize-jar.sh +} + +if [ "$1" = "build" ]; then + build_ibc_contracts +fi diff --git a/scripts/optimize-cosmwasm.sh b/scripts/optimize-cosmwasm.sh index a6a447775..4e9cf1ba4 100755 --- a/scripts/optimize-cosmwasm.sh +++ b/scripts/optimize-cosmwasm.sh @@ -54,7 +54,13 @@ cosmwasm-check artifacts/archway/cw_xcall_ibc_connection.wasm # Update version get_version() { local cargo_toml="contracts/cosmwasm-vm/$1/Cargo.toml" - grep -m 1 "version" "$cargo_toml" | awk -F '"' '{print $2}' + version=$(grep -m 1 "version" "$cargo_toml" | awk -F '"' '{print $2}') + if [ ! -z "$version" ];then + echo $version + else + # Echo version from root workspace Cargo.toml + echo $(grep -m 1 "version" Cargo.toml | awk -F '"' '{print $2}') + fi } # Rename filename with version in it @@ -90,3 +96,13 @@ fi echo "$file : $size KB" done echo "The size of all contracts is well within the $MAX_WASM_SIZE KB limit." + +# if release build, remove unnecessary artifacts and make zip +if [ "$1" == "release" ]; then + ls artifacts/archway/*.wasm \ + | egrep -v '(cw_ibc_core_[0-9]+\.[0-9]+\.[0-9]+\.wasm$|cw_icon_light_client_[0-9]+\.[0-9]+\.[0-9]+\.wasm$|cw_xcall_ibc_connection_[0-9]+\.[0-9]+\.[0-9]+\.wasm$)' \ + | xargs rm + zip -r artifacts/archway/cosmwasm-contracts.zip artifacts/archway/*.wasm -j + +fi + diff --git a/scripts/optimize-xcall-build.sh b/scripts/optimize-xcall-build.sh new file mode 100755 index 000000000..b1093b4ab --- /dev/null +++ b/scripts/optimize-xcall-build.sh @@ -0,0 +1,29 @@ +#!/bin/bash +set -e +mkdir -p artifacts/icon +mkdir -p artifacts/archway + +LOCAL_X_CALL_REPO=".xcall-multi" + +clone_xCall_multi() { + echo "Cloning xcall-multi repo..." + X_CALL_BRANCH="${1:-main}" + rm -rf "$LOCAL_X_CALL_REPO" + git clone -b "$X_CALL_BRANCH" --single-branch "https://github.com/icon-project/xcall-multi.git" "$LOCAL_X_CALL_REPO" +} + +build_xCall_contracts() { + echo "Generating optimized cosmwasm/jar of xcall-multi contracts..." + clone_xCall_multi "${1:-main}" + cd "$LOCAL_X_CALL_REPO" + ./scripts/optimize-cosmwasm.sh + ./scripts/optimize-jar.sh + cp artifacts/archway/*.wasm ../artifacts/archway/ + cp artifacts/icon/*.jar ../artifacts/icon/ + cd - +} + +if [ "$1" = "build" ]; then + shift + build_xCall_contracts "$@" +fi diff --git a/test/integration/tests/relayer.go b/test/integration/tests/relayer.go index 0a122cd91..4ef3a93a2 100644 --- a/test/integration/tests/relayer.go +++ b/test/integration/tests/relayer.go @@ -3,11 +3,12 @@ package tests import ( "context" "fmt" - "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - "github.com/stretchr/testify/assert" "testing" "time" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/stretchr/testify/assert" + "github.com/icon-project/ibc-integration/test/chains" "github.com/icon-project/ibc-integration/test/testsuite" "github.com/strangelove-ventures/interchaintest/v7/ibc" @@ -147,13 +148,13 @@ func (r *RelayerTestSuite) TestRelayer(ctx context.Context, relayer ibc.Relayer) }) r.T.Run("single relay packet flow chainA-chainB", func(t *testing.T) { - response, err := r.SendPacket(ctx, chainA, chainB, "data", 1000) + response, err := r.SendPacket(ctx, chainA, chainB, "data", 1000, false) assert.NoErrorf(t, err, "Error while sending package from chainA-chainB") assert.Truef(t, response.IsPacketSent, "The packet has not been sent to the target chain.") assert.Truef(t, response.IsPacketReceiptEventFound, "The packet event has not received on the target chain.") }) r.T.Run("single relay packet flow chainB-chainA", func(t *testing.T) { - response, err := r.SendPacket(ctx, chainB, chainA, "data", 1000) + response, err := r.SendPacket(ctx, chainB, chainA, "data", 1000, false) assert.NoErrorf(t, err, "Error while sending package from chainB-chainA") assert.Truef(t, response.IsPacketSent, "The packet has not been sent to the target chain.") assert.Truef(t, response.IsPacketReceiptEventFound, "The packet event has not received on the target chain.") @@ -218,14 +219,14 @@ func (r *RelayerTestSuite) TestRelayer(ctx context.Context, relayer ibc.Relayer) }) r.T.Run("single relay packet flow chainA-chainB", func(t *testing.T) { - response, err := r.SendPacket(ctx, chainA, chainB, "data", 1000) + response, err := r.SendPacket(ctx, chainA, chainB, "data", 1000, false) assert.NoErrorf(t, err, "Error while sending package from chainA-chainB") assert.Truef(t, response.IsPacketSent, "The packet has not been sent to the target chain.") assert.Truef(t, response.IsPacketReceiptEventFound, "The packet event has not received on the target chain.") }) r.T.Run("single relay packet flow chainB-chainA", func(t *testing.T) { - response, err := r.SendPacket(ctx, chainB, chainA, "data", 1000) + response, err := r.SendPacket(ctx, chainB, chainA, "data", 1000, false) assert.NoErrorf(t, err, "Error while sending package from chainB-chainA") assert.Truef(t, response.IsPacketSent, "The packet has not been sent to the target chain.") assert.Truef(t, response.IsPacketReceiptEventFound, "The packet event has not received on the target chain.") @@ -240,6 +241,19 @@ func (r *RelayerTestSuite) TestRelayer(ctx context.Context, relayer ibc.Relayer) }) }) + r.T.Run("send multiple packets on same ChainA height", func(t *testing.T) { + chainA, chainB := r.GetChains() + height, err := chainA.(ibc.Chain).Height(ctx) + r.Require().NoError(err) + r.Require().NoError(r.multiplePacketsOnSameHeight(chainA, chainB, height+100, 5)) + }) + + r.T.Run("send multiple packets on same ChainB height", func(t *testing.T) { + chainA, chainB := r.GetChains() + height, err := chainB.(ibc.Chain).Height(ctx) + r.Require().NoError(err) + r.Require().NoError(r.multiplePacketsOnSameHeight(chainB, chainA, height+100, 5)) + }) } func (r *RelayerTestSuite) PacketFlowTest(ctx context.Context, t *testing.T, src, target chains.Chain, order ibc.Order) { @@ -257,7 +271,7 @@ func (r *RelayerTestSuite) PacketFlowTest(ctx context.Context, t *testing.T, src assert.Falsef(t, isPacketReceived, "The packet event has received on the target chain.\n%v\n", packet) msg := "new-message" - response, err := r.SendPacket(ctx, src, target, msg, 1000) //new packet + response, err := r.SendPacket(ctx, src, target, msg, 1000, false) //new packet if order == ibc.Ordered { assert.Errorf(t, err, "Error on sending packet (%s): %v", msg, err) assert.Falsef(t, response.IsPacketReceiptEventFound, "The packet event has been received on the target chain.") @@ -302,7 +316,7 @@ func (r *RelayerTestSuite) RelayerCrashTest(ctx context.Context, chainA, chainB // check if relay is working as expected with ping pong to cross chain msg := "new-message" - response, err := r.SendPacket(ctx, chainA, chainB, msg, 1000) + response, err := r.SendPacket(ctx, chainA, chainB, msg, 1000, false) assert.NoErrorf(r.T, err, "Error on sending packet (%s) %v", msg, err) assert.Truef(r.T, response.IsPacketSent, "The packet has not been sent to the target chain.") assert.Truef(r.T, response.IsPacketReceiptEventFound, "The packet event has NOT been received on the target chain.") @@ -330,7 +344,7 @@ func (r *RelayerTestSuite) handleCrashAndSendPacket(ctx context.Context, src cha r.T.Logf("crashed at: %s %d", chainID, crashedHeight) // send packet from src to target crashed node and check if it is received var msg = fmt.Sprintf("data-%s", chainID) - response, _ := r.SendPacket(ctx, src, target, msg, 1000000) + response, _ := r.SendPacket(ctx, src, target, msg, 1000000, false) packet := response.Packet assert.NotEqualf(r.T, types.Packet{}, packet, "packet is empty") assert.Truef(r.T, response.IsPacketSent, "The packet has not been sent to the target chain.") @@ -361,3 +375,18 @@ func findPacket(ctx context.Context, chain chains.Chain, params map[string]inter } } } + +func (r *RelayerTestSuite) multiplePacketsOnSameHeight(src, dst chains.Chain, height uint64, numPackets uint) error { + ctx := context.Background() + res, err := r.SendPacket(ctx, src, dst, fmt.Sprintf("test-%d", numPackets), height, true) + if err != nil { + return err + } + if !res.IsPacketSent { + return fmt.Errorf("packet not sent") + } + if numPackets == 0 { + return nil + } + return r.multiplePacketsOnSameHeight(src, dst, height, numPackets-1) +} diff --git a/test/testsuite/integration_suite.go b/test/testsuite/integration_suite.go index dd8a27093..a9e4e7982 100644 --- a/test/testsuite/integration_suite.go +++ b/test/testsuite/integration_suite.go @@ -128,8 +128,11 @@ func (s *E2ETestSuite) GetNextConnectionSequence(ctx context.Context, chain chai } // SendPacket sends a packet from src to dst -func (s *E2ETestSuite) SendPacket(ctx context.Context, src, target chains.Chain, msg string, timeout uint64) (chains.PacketTransferResponse, error) { - height, _ := src.(ibc.Chain).Height(ctx) +func (s *E2ETestSuite) SendPacket(ctx context.Context, src, target chains.Chain, msg string, timeout uint64, isCurrentHeight bool) (chains.PacketTransferResponse, error) { + var height uint64 + if !isCurrentHeight { + height, _ = src.(ibc.Chain).Height(ctx) + } params := map[string]interface{}{ "msg": chains.BufferArray(msg), "timeout_height": height + timeout, diff --git a/xcall-multi b/xcall-multi deleted file mode 160000 index b9113742f..000000000 --- a/xcall-multi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b9113742f145c77073610e13a0ebc6ed0fcf9a87