From 2a357b9d614aa937ae65176e6beec7035714b91a Mon Sep 17 00:00:00 2001 From: gcranju <134275268+gcranju@users.noreply.github.com> Date: Fri, 29 Nov 2024 21:51:32 +0545 Subject: [PATCH 01/14] fix: sui rlp upgrade (#417) * fix: sui-rlp upgrade compatible * fix: sui-rlp upgrade compatible --- .../sui/libs/sui_rlp/sources/encoder.move | 10 +++---- contracts/sui/libs/sui_rlp/sources/utils.move | 29 +++++++++++++++---- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/contracts/sui/libs/sui_rlp/sources/encoder.move b/contracts/sui/libs/sui_rlp/sources/encoder.move index 5e2b93b1..1e63672b 100644 --- a/contracts/sui/libs/sui_rlp/sources/encoder.move +++ b/contracts/sui/libs/sui_rlp/sources/encoder.move @@ -49,7 +49,7 @@ module sui_rlp::encoder { vector::append(&mut encoded_list,result); } else { - let length_bytes = utils::to_bytes_u64(len,false); + let length_bytes = utils::to_bytes_u64_sign(len,false); let prefix = (0xf7 + vector::length(&length_bytes)) as u8; vector::push_back(&mut encoded_list, prefix); vector::append(&mut encoded_list, length_bytes); @@ -69,7 +69,7 @@ module sui_rlp::encoder { let len_u8=(len as u8); vector::push_back(&mut length_info,(offset+len_u8)); }else { - let length_bytes=utils::to_bytes_u64(len,false); + let length_bytes=utils::to_bytes_u64_sign(len,false); let length_byte_len=vector::length(&length_bytes); let length_byte_len=offset+(length_byte_len as u8); vector::push_back(&mut length_info,length_byte_len); @@ -86,19 +86,19 @@ module sui_rlp::encoder { } public fun encode_u32(num:u32):vector{ - let vec= utils::to_bytes_u32(num,true); + let vec= utils::to_bytes_u32_sign(num,true); encode(&vec) } public fun encode_u64(num:u64):vector{ - let vec= utils::to_bytes_u64(num,true); + let vec= utils::to_bytes_u64_sign(num,true); encode(&vec) } public fun encode_u128(num:u128):vector{ - let vec= utils::to_bytes_u128(num,true); + let vec= utils::to_bytes_u128_sign(num,true); encode(&vec) } diff --git a/contracts/sui/libs/sui_rlp/sources/utils.move b/contracts/sui/libs/sui_rlp/sources/utils.move index af37a07d..53529c3d 100644 --- a/contracts/sui/libs/sui_rlp/sources/utils.move +++ b/contracts/sui/libs/sui_rlp/sources/utils.move @@ -41,18 +41,35 @@ module sui_rlp::utils { } - public fun to_bytes_u128(number:u128,signed:bool):vector{ + //Deprecated + public fun to_bytes_u128(number:u128):vector{ + let bytes=bcs::to_bytes(&number); + to_signed_bytes(bytes,true) + } + + public fun to_bytes_u128_sign(number:u128,signed:bool):vector{ let bytes=bcs::to_bytes(&number); to_signed_bytes(bytes,signed) } + //Deprecated + public fun to_bytes_u64(number:u64):vector{ + let bytes=bcs::to_bytes(&number); + to_signed_bytes(bytes,true) + } - public fun to_bytes_u64(number:u64,signed:bool):vector{ + public fun to_bytes_u64_sign(number:u64,signed:bool):vector{ let bytes=bcs::to_bytes(&number); to_signed_bytes(bytes,signed) } + + //Deprecated + public fun to_bytes_u32(number: u32): vector { + let bytes=bcs::to_bytes(&number); + to_signed_bytes(bytes,true) + } - public fun to_bytes_u32(number: u32,signed:bool): vector { + public fun to_bytes_u32_sign(number: u32,signed:bool): vector { let bytes=bcs::to_bytes(&number); to_signed_bytes(bytes,signed) } @@ -120,7 +137,7 @@ module sui_rlp::utils_test { #[test] fun test_u32_conversion() { let num= (122 as u32); - let bytes= utils::to_bytes_u32(num,true); + let bytes= utils::to_bytes_u32_sign(num,true); let converted=utils::from_bytes_u32(&bytes); assert!(num==converted,0x01); @@ -129,7 +146,7 @@ module sui_rlp::utils_test { #[test] fun test_u64_conversion() { let num= (55000 as u64); - let bytes= utils::to_bytes_u64(num,true); + let bytes= utils::to_bytes_u64_sign(num,true); let converted=utils::from_bytes_u64(&bytes); std::debug::print(&bytes); std::debug::print(&converted); @@ -140,7 +157,7 @@ module sui_rlp::utils_test { #[test] fun test_u128_conversion() { let num= (1222223333 as u128); - let bytes= utils::to_bytes_u128(num,true); + let bytes= utils::to_bytes_u128_sign(num,true); std::debug::print(&bytes); let converted=utils::from_bytes_u128(&bytes); std::debug::print(&converted); From b547292090ac29c797fc6c4ceceefe0ff4980ef8 Mon Sep 17 00:00:00 2001 From: gcranju Date: Mon, 2 Dec 2024 15:37:39 +0545 Subject: [PATCH 02/14] fix: storage optimization in xcall --- .../soroban/contracts/xcall/src/contract.rs | 5 ++ .../soroban/contracts/xcall/src/storage.rs | 75 +++++++------------ 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/contracts/soroban/contracts/xcall/src/contract.rs b/contracts/soroban/contracts/xcall/src/contract.rs index 8d81f6ac..6c5affce 100644 --- a/contracts/soroban/contracts/xcall/src/contract.rs +++ b/contracts/soroban/contracts/xcall/src/contract.rs @@ -162,4 +162,9 @@ impl Xcall { pub fn version(env: Env) -> u32 { storage::get_contract_version(&env) } + + pub fn extend_instance_storage(env: Env) -> Result<(), ContractError> { + storage::extend_instance(&env); + Ok(()) + } } diff --git a/contracts/soroban/contracts/xcall/src/storage.rs b/contracts/soroban/contracts/xcall/src/storage.rs index cfa43a98..8879c6dc 100644 --- a/contracts/soroban/contracts/xcall/src/storage.rs +++ b/contracts/soroban/contracts/xcall/src/storage.rs @@ -18,8 +18,8 @@ const LEDGER_BUMP_INSTANCE: u32 = LEDGER_THRESHOLD_INSTANCE + DAY_IN_LEDGERS; // const LEDGER_THRESHOLD_PERSISTENT: u32 = DAY_IN_LEDGERS * 30; // ~ 30 days const LEDGER_BUMP_PERSISTENT: u32 = LEDGER_THRESHOLD_PERSISTENT + DAY_IN_LEDGERS; // ~ 31 days -const LEDGER_THRESHOLD_REQUEST: u32 = DAY_IN_LEDGERS * 7; // ~ 7 days -const LEDGER_BUMP_REQUEST: u32 = LEDGER_THRESHOLD_REQUEST + DAY_IN_LEDGERS; // ~ 8 days +const LEDGER_THRESHOLD_REQUEST: u32 = DAY_IN_LEDGERS * 3; // ~ 3 days +const LEDGER_BUMP_REQUEST: u32 = LEDGER_THRESHOLD_REQUEST + DAY_IN_LEDGERS; // ~ 4 days pub const MAX_ROLLBACK_SIZE: u64 = 1024; pub const MAX_DATA_SIZE: u64 = 2048; @@ -72,10 +72,9 @@ pub fn default_connection(e: &Env, nid: String) -> Result Result bool { let key = StorageKey::SuccessfulResponses(sn); - let res = e.storage().persistent().get(&key).unwrap_or(false); - if res { - extend_persistent(e, &key) - } - + let res = e.storage().instance().get(&key).unwrap_or(false); res } @@ -114,31 +107,21 @@ pub fn get_proxy_request(e: &Env, req_id: u128) -> Result) -> Vec { let key = StorageKey::PendingRequests(hash); - let pending_request = e.storage().persistent().get(&key).unwrap_or(Vec::new(&e)); - if pending_request.len() > 0 { - extend_persistent_request(e, &key); - } - + let pending_request = e.storage().temporary().get(&key).unwrap_or(Vec::new(&e)); pending_request } pub fn get_pending_response(e: &Env, hash: BytesN<32>) -> Vec { let key = StorageKey::PendingResponses(hash); - let pending_response = e.storage().persistent().get(&key).unwrap_or(Vec::new(&e)); - if pending_response.len() > 0 { - extend_persistent_request(e, &key); - } - + let pending_response = e.storage().temporary().get(&key).unwrap_or(Vec::new(&e)); pending_response } @@ -196,53 +179,52 @@ pub fn store_protocol_fee(e: &Env, fee: u128) { pub fn store_default_connection(e: &Env, nid: String, address: &Address) { let key = StorageKey::DefaultConnections(nid); - e.storage().persistent().set(&key, &address); - extend_persistent(e, &key); + e.storage().instance().set(&key, &address); } pub fn store_rollback(e: &Env, sn: u128, rollback: &Rollback) { let key = StorageKey::Rollback(sn); - e.storage().persistent().set(&key, rollback); - extend_persistent_request(e, &key) + e.storage().temporary().set(&key, rollback); + extend_temporary_request(e, &key) } pub fn remove_rollback(e: &Env, sn: u128) { - e.storage().persistent().remove(&StorageKey::Rollback(sn)); + e.storage().temporary().remove(&StorageKey::Rollback(sn)); } pub fn store_proxy_request(e: &Env, req_id: u128, request: &CSMessageRequest) { let key = StorageKey::ProxyRequest(req_id); - e.storage().persistent().set(&key, request); - extend_persistent_request(e, &key) + e.storage().temporary().set(&key, request); + extend_temporary_request(e, &key) } pub fn remove_proxy_request(e: &Env, req_id: u128) { e.storage() - .persistent() + .temporary() .remove(&StorageKey::ProxyRequest(req_id)) } pub fn store_pending_request(e: &Env, hash: BytesN<32>, sources: &Vec) { let key = StorageKey::PendingRequests(hash.clone()); - e.storage().persistent().set(&key, sources); - extend_persistent_request(e, &key) + e.storage().temporary().set(&key, sources); + extend_temporary_request(e, &key) } pub fn remove_pending_request(e: &Env, hash: BytesN<32>) { e.storage() - .persistent() + .temporary() .remove(&StorageKey::PendingRequests(hash)) } pub fn store_pending_response(e: &Env, hash: BytesN<32>, sources: &Vec) { let key = StorageKey::PendingResponses(hash); - e.storage().persistent().set(&key, sources); - extend_persistent_request(e, &key) + e.storage().temporary().set(&key, sources); + extend_temporary_request(e, &key) } pub fn remove_pending_response(e: &Env, hash: BytesN<32>) { e.storage() - .persistent() + .temporary() .remove(&StorageKey::PendingResponses(hash)) } @@ -259,8 +241,8 @@ pub fn increment_last_request_id(e: &Env) -> u128 { pub fn save_success_response(e: &Env, sn: u128) { let key = StorageKey::SuccessfulResponses(sn); - e.storage().persistent().set(&key, &true); - extend_persistent(e, &key); + e.storage().instance().set(&key, &true); + extend_instance(e); } pub fn extend_instance(e: &Env) { @@ -269,14 +251,9 @@ pub fn extend_instance(e: &Env) { .extend_ttl(LEDGER_THRESHOLD_INSTANCE, LEDGER_BUMP_INSTANCE); } -pub fn extend_persistent(e: &Env, key: &StorageKey) { - e.storage() - .persistent() - .extend_ttl(key, LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT); -} - -pub fn extend_persistent_request(e: &Env, key: &StorageKey) { +pub fn extend_temporary_request(e: &Env, key: &StorageKey) { e.storage() - .persistent() + .temporary() .extend_ttl(key, LEDGER_THRESHOLD_REQUEST, LEDGER_BUMP_REQUEST); } + From c9a169e65f6426282285f454bf86b9cc51df4c66 Mon Sep 17 00:00:00 2001 From: gcranju Date: Mon, 2 Dec 2024 15:58:38 +0545 Subject: [PATCH 03/14] fix: successful response to persistent --- contracts/soroban/contracts/xcall/src/storage.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/contracts/soroban/contracts/xcall/src/storage.rs b/contracts/soroban/contracts/xcall/src/storage.rs index 8879c6dc..2e5ab547 100644 --- a/contracts/soroban/contracts/xcall/src/storage.rs +++ b/contracts/soroban/contracts/xcall/src/storage.rs @@ -91,7 +91,7 @@ pub fn get_rollback(e: &Env, sequence_no: u128) -> Result bool { let key = StorageKey::SuccessfulResponses(sn); - let res = e.storage().instance().get(&key).unwrap_or(false); + let res = e.storage().persistent().get(&key).unwrap_or(false); res } @@ -241,8 +241,8 @@ pub fn increment_last_request_id(e: &Env) -> u128 { pub fn save_success_response(e: &Env, sn: u128) { let key = StorageKey::SuccessfulResponses(sn); - e.storage().instance().set(&key, &true); - extend_instance(e); + e.storage().persistent().set(&key, &true); + extend_persistent(e); } pub fn extend_instance(e: &Env) { @@ -251,6 +251,12 @@ pub fn extend_instance(e: &Env) { .extend_ttl(LEDGER_THRESHOLD_INSTANCE, LEDGER_BUMP_INSTANCE); } +pub fn extend_persistent(e: &Env) { + e.storage() + .persistent() + .extend_ttl(LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT); +} + pub fn extend_temporary_request(e: &Env, key: &StorageKey) { e.storage() .temporary() From 5f7cb9c53ef30d94337a8e708a669c224e9108b7 Mon Sep 17 00:00:00 2001 From: gcranju Date: Mon, 2 Dec 2024 16:03:43 +0545 Subject: [PATCH 04/14] fix: successful response to persistent --- contracts/soroban/contracts/xcall/src/storage.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/soroban/contracts/xcall/src/storage.rs b/contracts/soroban/contracts/xcall/src/storage.rs index 2e5ab547..1fb56add 100644 --- a/contracts/soroban/contracts/xcall/src/storage.rs +++ b/contracts/soroban/contracts/xcall/src/storage.rs @@ -242,7 +242,7 @@ pub fn increment_last_request_id(e: &Env) -> u128 { pub fn save_success_response(e: &Env, sn: u128) { let key = StorageKey::SuccessfulResponses(sn); e.storage().persistent().set(&key, &true); - extend_persistent(e); + extend_persistent(e, &key); } pub fn extend_instance(e: &Env) { @@ -251,10 +251,10 @@ pub fn extend_instance(e: &Env) { .extend_ttl(LEDGER_THRESHOLD_INSTANCE, LEDGER_BUMP_INSTANCE); } -pub fn extend_persistent(e: &Env) { +pub fn extend_persistent(e: &Env, key: &StorageKey) { e.storage() .persistent() - .extend_ttl(LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT); + .extend_ttl(key, LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT); } pub fn extend_temporary_request(e: &Env, key: &StorageKey) { From 6a866bc5f942a96f4c23b7775803044612f74b1f Mon Sep 17 00:00:00 2001 From: gcranju Date: Tue, 3 Dec 2024 12:31:56 +0545 Subject: [PATCH 05/14] fix: javascore settngs.gradle --- contracts/javascore/settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/javascore/settings.gradle b/contracts/javascore/settings.gradle index bfa80980..4f1da5a8 100644 --- a/contracts/javascore/settings.gradle +++ b/contracts/javascore/settings.gradle @@ -4,7 +4,7 @@ include( 'xcall', 'xcall-lib', 'centralized-connection', - 'cluster-connection' + 'cluster-connection', 'aggregator' ) From dc50331b72fcd31f68cda2c0725ec4246a8f44e3 Mon Sep 17 00:00:00 2001 From: gcranju Date: Tue, 3 Dec 2024 12:44:47 +0545 Subject: [PATCH 06/14] fix: stellar script --- scripts/optimize-stellar.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/optimize-stellar.sh b/scripts/optimize-stellar.sh index 691c6e4b..b527d71f 100755 --- a/scripts/optimize-stellar.sh +++ b/scripts/optimize-stellar.sh @@ -11,7 +11,7 @@ cargo build --target wasm32-unknown-unknown --release for WASM in $build_directory/*.wasm; do NAME=$(basename "$WASM" .wasm)${SUFFIX}.wasm echo "Optimizing $NAME ... $WASM" - /usr/local/bin/stellar2 contract optimize --wasm "$WASM" + stellar contract optimize --wasm "$WASM" done cd - From 7662f6c7bc76a4487e2ba858e20e5bc2009fafc2 Mon Sep 17 00:00:00 2001 From: sherpalden Date: Wed, 4 Dec 2024 10:29:31 +0545 Subject: [PATCH 07/14] fix: remove unwanted code --- .../aggregator/src/main/java/relay/aggregator/Packet.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java b/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java index 0568de37..138ab2bb 100644 --- a/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java +++ b/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java @@ -66,8 +66,6 @@ public Packet(String srcNetwork, String srcContractAddress, BigInteger srcSn, Bi || srcHeight == null || dstNetwork == null || dstContractAddress == null || data == null; Context.require(!isIllegalArg, "srcNetwork, contractAddress, srcSn, srcHeight, dstNetwork, and data cannot be null"); - if (isIllegalArg) { - } this.srcNetwork = srcNetwork; this.srcContractAddress = srcContractAddress; this.srcSn = srcSn; From 1cea9f33b177bf79c70764ea4741a63ed2dba7fb Mon Sep 17 00:00:00 2001 From: sherpalden Date: Wed, 4 Dec 2024 11:45:29 +0545 Subject: [PATCH 08/14] fix: do not included admin as relayers --- .../main/java/relay/aggregator/RelayAggregator.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java b/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java index ec475a99..7525d24d 100644 --- a/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java +++ b/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java @@ -50,7 +50,6 @@ public RelayAggregator(Address _admin) { if (admin.get() == null) { admin.set(_admin); signatureThreshold.set(DEFAULT_SIGNATURE_THRESHOLD); - addRelayer(_admin); } } @@ -60,12 +59,6 @@ public void setAdmin(Address _admin) { Context.require(admin.get() != _admin, "admin already set"); - // add new admin as relayer - addRelayer(_admin); - - // remove old admin from relayer list - removeRelayer(admin.get()); - admin.set(_admin); } @@ -107,10 +100,9 @@ public void setRelayers(Address[] newRelayers, int threshold) { addRelayer(newRelayer); } - Address adminAdrr = admin.get(); for (int i = 0; i < relayers.size(); i++) { Address oldRelayer = relayers.get(i); - if (!oldRelayer.equals(adminAdrr) && !newRelayersMap.containsKey(oldRelayer)) { + if (!newRelayersMap.containsKey(oldRelayer)) { removeRelayer(oldRelayer); } } From 9dfbb74a9e2a218a891b677752fc367995b55688 Mon Sep 17 00:00:00 2001 From: sherpalden Date: Wed, 4 Dec 2024 12:23:22 +0545 Subject: [PATCH 09/14] fix: create packet id from the hash of entire packet && update unit tests --- .../main/java/relay/aggregator/Packet.java | 15 +- .../relay/aggregator/RelayAggregator.java | 28 +- .../relay/aggregator/RelayAggregatorTest.java | 596 +++++++++--------- 3 files changed, 320 insertions(+), 319 deletions(-) diff --git a/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java b/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java index 138ab2bb..16d600cf 100644 --- a/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java +++ b/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java @@ -2,6 +2,7 @@ import java.math.BigInteger; +import score.ByteArrayObjectWriter; import score.Context; import score.ObjectReader; import score.ObjectWriter; @@ -75,12 +76,8 @@ public Packet(String srcNetwork, String srcContractAddress, BigInteger srcSn, Bi this.data = data; } - public String getId() { - return createId(this.srcNetwork, this.srcContractAddress, this.srcSn); - } - - public static String createId(String srcNetwork, String contractAddress, BigInteger srcSn) { - return srcNetwork + "/" + contractAddress + "/" + srcSn.toString(); + public byte[] getId() { + return Context.hash("sha-256", this.toBytes()); } /** @@ -171,4 +168,10 @@ public static Packet readObject(ObjectReader r) { r.end(); return p; } + + public byte[] toBytes() { + ByteArrayObjectWriter writer = Context.newByteArrayObjectWriter("RLPn"); + Packet.writeObject(writer, this); + return writer.toByteArray(); + } } diff --git a/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java b/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java index 7525d24d..440b8c19 100644 --- a/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java +++ b/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java @@ -41,9 +41,9 @@ public class RelayAggregator { private final ArrayDB
relayers = Context.newArrayDB("relayers", Address.class); private final DictDB relayersLookup = Context.newDictDB("relayersLookup", Boolean.class); - private final DictDB packets = Context.newDictDB("packets", Packet.class); + private final DictDB packets = Context.newDictDB("packets", Packet.class); - private final BranchDB> signatures = Context.newBranchDB("signatures", + private final BranchDB> signatures = Context.newBranchDB("signatures", byte[].class); public RelayAggregator(Address _admin) { @@ -119,8 +119,13 @@ public boolean packetSubmitted( Address relayer, String srcNetwork, String srcContractAddress, - BigInteger srcSn) { - String pktID = Packet.createId(srcNetwork, srcContractAddress, srcSn); + BigInteger srcSn, + BigInteger srcHeight, + String dstNetwork, + String dstContractAddress, + byte[] data) { + Packet pkt = new Packet(srcNetwork, srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data); + byte[] pktID = pkt.getId(); byte[] existingSign = signatures.at(pktID).get(relayer); return existingSign != null; } @@ -139,7 +144,7 @@ public void submitPacket( relayersOnly(); Packet pkt = new Packet(srcNetwork, srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data); - String pktID = pkt.getId(); + byte[] pktID = pkt.getId(); if (packets.get(pktID) == null) { packets.set(pktID, pkt); @@ -162,7 +167,7 @@ public void submitPacket( setSignature(pktID, Context.getCaller(), signature); if (signatureThresholdReached(pktID)) { - byte[][] sigs = getSignatures(srcNetwork, srcContractAddress, srcSn); + byte[][] sigs = getSignatures(pktID); byte[] encodedSigs = serializeSignatures(sigs); PacketAcknowledged( pkt.getSrcNetwork(), @@ -177,8 +182,7 @@ public void submitPacket( } } - private byte[][] getSignatures(String srcNetwork, String srcContractAddress, BigInteger srcSn) { - String pktID = Packet.createId(srcNetwork, srcContractAddress, srcSn); + private byte[][] getSignatures(byte[] pktID) { DictDB signDict = signatures.at(pktID); ArrayList signatureList = new ArrayList(); @@ -197,7 +201,7 @@ private byte[][] getSignatures(String srcNetwork, String srcContractAddress, Big return sigs; } - protected void setSignature(String pktID, Address addr, byte[] sign) { + protected void setSignature(byte[] pktID, Address addr, byte[] sign) { signatures.at(pktID).set(addr, sign); } @@ -233,7 +237,7 @@ protected static byte[][] deserializeSignatures(byte[] encodedSigs) { } private void adminOnly() { - Context.require(Context.getCaller().equals(admin.get()), "Unauthorized: caller is not the leader relayer"); + Context.require(Context.getCaller().equals(admin.get()), "Unauthorized: caller is not the admin"); } private void relayersOnly() { @@ -262,7 +266,7 @@ private void removeRelayer(Address oldRelayer) { } } - private Boolean signatureThresholdReached(String pktID) { + private Boolean signatureThresholdReached(byte[] pktID) { int noOfSignatures = 0; for (int i = 0; i < relayers.size(); i++) { Address relayer = relayers.get(i); @@ -274,7 +278,7 @@ private Boolean signatureThresholdReached(String pktID) { return noOfSignatures >= signatureThreshold.get(); } - private void removePacket(String pktID) { + private void removePacket(byte[] pktID) { packets.set(pktID, null); DictDB signDict = signatures.at(pktID); diff --git a/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java b/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java index 0da3391f..4165d4e6 100644 --- a/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java +++ b/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java @@ -1,7 +1,6 @@ package relay.aggregator; import java.math.BigInteger; -import java.util.Arrays; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -21,347 +20,342 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; class RelayAggregatorTest extends TestBase { - private final ServiceManager sm = getServiceManager(); + private final ServiceManager sm = getServiceManager(); - private KeyWallet admin; - private Account adminAc; + private KeyWallet admin; + private Account adminAc; - private KeyWallet relayerOne; - private Account relayerOneAc; + private KeyWallet relayerOne; + private Account relayerOneAc; - private KeyWallet relayerTwo; - private Account relayerTwoAc; + private KeyWallet relayerTwo; + private Account relayerTwoAc; - private KeyWallet relayerThree; - private Account relayerThreeAc; + private KeyWallet relayerThree; + private Account relayerThreeAc; - private KeyWallet relayerFour; - private Account relayerFourAc; + private KeyWallet relayerFour; + private Account relayerFourAc; - private Score aggregator; - private RelayAggregator aggregatorSpy; + private Score aggregator; + private RelayAggregator aggregatorSpy; - @BeforeEach - void setup() throws Exception { - admin = KeyWallet.create(); - adminAc = sm.getAccount(Address.fromString(admin.getAddress().toString())); + @BeforeEach + void setup() throws Exception { + admin = KeyWallet.create(); + adminAc = sm.getAccount(Address.fromString(admin.getAddress().toString())); - relayerOne = KeyWallet.create(); - relayerOneAc = sm.getAccount(Address.fromString(relayerOne.getAddress().toString())); + relayerOne = KeyWallet.create(); + relayerOneAc = sm.getAccount(Address.fromString(relayerOne.getAddress().toString())); - relayerTwo = KeyWallet.create(); - relayerTwoAc = sm.getAccount(Address.fromString(relayerTwo.getAddress().toString())); + relayerTwo = KeyWallet.create(); + relayerTwoAc = sm.getAccount(Address.fromString(relayerTwo.getAddress().toString())); - relayerThree = KeyWallet.create(); - relayerThreeAc = sm.getAccount(Address.fromString(relayerThree.getAddress().toString())); + relayerThree = KeyWallet.create(); + relayerThreeAc = sm.getAccount(Address.fromString(relayerThree.getAddress().toString())); - relayerFour = KeyWallet.create(); - relayerFourAc = sm.getAccount(Address.fromString(relayerFour.getAddress().toString())); + relayerFour = KeyWallet.create(); + relayerFourAc = sm.getAccount(Address.fromString(relayerFour.getAddress().toString())); - aggregator = sm.deploy(adminAc, RelayAggregator.class, adminAc.getAddress()); + aggregator = sm.deploy(adminAc, RelayAggregator.class, adminAc.getAddress()); - Address[] relayers = new Address[] { adminAc.getAddress(), relayerOneAc.getAddress(), relayerTwoAc.getAddress(), - relayerThreeAc.getAddress() }; + Address[] relayers = new Address[] { relayerOneAc.getAddress(), relayerTwoAc.getAddress(), + relayerThreeAc.getAddress() }; - aggregator.invoke(adminAc, "setRelayers", (Object) relayers, 2); + aggregator.invoke(adminAc, "setRelayers", (Object) relayers, 2); - aggregatorSpy = (RelayAggregator) spy(aggregator.getInstance()); - aggregator.setInstance(aggregatorSpy); - } + aggregatorSpy = (RelayAggregator) spy(aggregator.getInstance()); + aggregator.setInstance(aggregatorSpy); + } + + @Test + public void testSetAdmin() { + Account newAdminAc = sm.createAccount(); + aggregator.invoke(adminAc, "setAdmin", newAdminAc.getAddress()); + + Address newAdmin = (Address) aggregator.call("getAdmin"); + assertEquals(newAdminAc.getAddress(), newAdmin); + } + + @Test + public void testSetAdmin_unauthorized() { + Account normalAc = sm.createAccount(); + Account newAdminAc = sm.createAccount(); + + Executable action = () -> aggregator.invoke(normalAc, "setAdmin", newAdminAc.getAddress()); + UserRevertedException e = assertThrows(UserRevertedException.class, action); + + assertEquals("Reverted(0): Unauthorized: caller is not the admin", e.getMessage()); + } + + @Test + public void testSetSignatureThreshold() { + int threshold = 3; + aggregator.invoke(adminAc, "setSignatureThreshold", threshold); + + Integer result = (Integer) aggregator.call("getSignatureThreshold"); + assertEquals(threshold, result); + } + + @Test + public void testSetSignatureThreshold_unauthorised() { + int threshold = 3; + + Executable action = () -> aggregator.invoke(relayerOneAc, + "setSignatureThreshold", threshold); + UserRevertedException e = assertThrows(UserRevertedException.class, action); + + assertEquals("Reverted(0): Unauthorized: caller is not the admin", + e.getMessage()); + } + + @Test + public void testSetRelayers() { + Account relayerFiveAc = sm.createAccount(); + Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; + + Integer threshold = 3; + aggregator.invoke(adminAc, "setRelayers", (Object) newRelayers, threshold); + + Address[] updatedRelayers = (Address[]) aggregator.call("getRelayers"); - @Test - public void testSetAdmin() { - Address oldAdmin = (Address) aggregator.call("getAdmin"); + Address[] expectedRelayers = new Address[] { relayerThreeAc.getAddress(), + relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; - Account newAdminAc = sm.createAccount(); - aggregator.invoke(adminAc, "setAdmin", newAdminAc.getAddress()); + HashSet
updatedRelayersSet = new HashSet
(); + for (Address rlr : updatedRelayers) { + updatedRelayersSet.add(rlr); + } - Address newAdmin = (Address) aggregator.call("getAdmin"); - assertEquals(newAdminAc.getAddress(), newAdmin); + HashSet
expectedRelayersSet = new HashSet
(); + for (Address rlr : expectedRelayers) { + expectedRelayersSet.add(rlr); + } + + assertEquals(expectedRelayersSet, updatedRelayersSet); + + Integer result = (Integer) aggregator.call("getSignatureThreshold"); + assertEquals(threshold, result); + } - Address[] relayers = (Address[]) aggregator.call("getRelayers"); + @Test + public void testSetRelayers_unauthorized() { + Account relayerFiveAc = sm.createAccount(); + Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; - boolean containsNewAdmin = Arrays.asList(relayers).contains(newAdmin); - boolean containsOldAdmin = Arrays.asList(relayers).contains(oldAdmin); + Integer threshold = 3; + Executable action = () -> aggregator.invoke(relayerOneAc, "setRelayers", + (Object) newRelayers, threshold); + UserRevertedException e = assertThrows(UserRevertedException.class, action); - assertTrue(containsNewAdmin); - assertFalse(containsOldAdmin); - } + assertEquals("Reverted(0): Unauthorized: caller is not the admin", + e.getMessage()); - @Test - public void testSetAdmin_unauthorized() { - Account normalAc = sm.createAccount(); - Account newAdminAc = sm.createAccount(); + } - Executable action = () -> aggregator.invoke(normalAc, "setAdmin", newAdminAc.getAddress()); - UserRevertedException e = assertThrows(UserRevertedException.class, action); + @Test + public void testSetRelayers_invalidThreshold() { + Account relayerFiveAc = sm.createAccount(); + Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; - assertEquals("Reverted(0): Unauthorized: caller is not the leader relayer", e.getMessage()); - } + Integer threshold = 5; + Executable action = () -> aggregator.invoke(adminAc, "setRelayers", + (Object) newRelayers, threshold); + UserRevertedException e = assertThrows(UserRevertedException.class, action); - @Test - public void testSetSignatureThreshold() { - int threshold = 3; - aggregator.invoke(adminAc, "setSignatureThreshold", threshold); + assertEquals("Reverted(0): threshold value should be at least 1 and not greater than relayers size", + e.getMessage()); - Integer result = (Integer) aggregator.call("getSignatureThreshold"); - assertEquals(threshold, result); - } + } - @Test - public void testSetSignatureThreshold_unauthorised() { - int threshold = 3; + @Test + public void testSetRelayers_invalidThresholdZero() { + Account relayerFiveAc = sm.createAccount(); + Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; - Executable action = () -> aggregator.invoke(relayerOneAc, - "setSignatureThreshold", threshold); - UserRevertedException e = assertThrows(UserRevertedException.class, action); + Integer threshold = 0; + Executable action = () -> aggregator.invoke(adminAc, "setRelayers", + (Object) newRelayers, threshold); + UserRevertedException e = assertThrows(UserRevertedException.class, action); - assertEquals("Reverted(0): Unauthorized: caller is not the leader relayer", - e.getMessage()); - } + assertEquals("Reverted(0): threshold value should be at least 1 and not greater than relayers size", + e.getMessage()); - @Test - public void testSetRelayers() { - Account relayerFiveAc = sm.createAccount(); - Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; + } - Integer threshold = 3; - aggregator.invoke(adminAc, "setRelayers", (Object) newRelayers, threshold); + @Test + public void testPacketSubmitted_true() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + aggregator.invoke(adminAc, "setSignatureThreshold", 2); + + byte[] dataHash = Context.hash("sha-256", data); + byte[] sign = relayerOne.sign(dataHash); + + aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, + dstContractAddress, data, + sign); + + boolean submitted = (boolean) aggregator.call("packetSubmitted", + relayerOneAc.getAddress(), srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data); + assertEquals(submitted, true); + } - Address[] updatedRelayers = (Address[]) aggregator.call("getRelayers"); + @Test + public void testPacketSubmitted_false() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + boolean submitted = (boolean) aggregator.call("packetSubmitted", + relayerOneAc.getAddress(), srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data); + assertEquals(submitted, false); + } - Address[] expectedRelayers = new Address[] { adminAc.getAddress(), relayerThreeAc.getAddress(), - relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; + @Test + public void testSubmitPacket() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + aggregator.invoke(adminAc, "setSignatureThreshold", 2); + + byte[] dataHash = Context.hash("sha-256", data); + byte[] sign = relayerOne.sign(dataHash); + + aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, + dstContractAddress, data, + sign); + + Packet pkt = new Packet(srcNetwork, srcContractAddress, srcSn, srcHeight, dstNetwork, + dstContractAddress, data); + byte[] pktID = pkt.getId(); + verify(aggregatorSpy).PacketRegistered(srcNetwork, srcContractAddress, srcSn, + srcHeight, dstNetwork, + dstContractAddress, data); + verify(aggregatorSpy).setSignature(pktID, relayerOneAc.getAddress(), sign); + } - HashSet
updatedRelayersSet = new HashSet
(); - for (Address rlr : updatedRelayers) { - updatedRelayersSet.add(rlr); + @Test + public void testSubmitPacket_thresholdReached() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + aggregator.invoke(adminAc, "setSignatureThreshold", 2); + + byte[] dataHash = Context.hash("sha-256", data); + + byte[] signOne = relayerOne.sign(dataHash); + aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, + dstContractAddress, + data, + signOne); + + byte[] signTwo = relayerTwo.sign(dataHash); + aggregator.invoke(relayerTwoAc, "submitPacket", srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, + dstContractAddress, + data, + signTwo); + + byte[][] sigs = new byte[2][]; + sigs[0] = signOne; + sigs[1] = signTwo; + + byte[] encodedSigs = RelayAggregator.serializeSignatures(sigs); + byte[][] decodedSigs = RelayAggregator.deserializeSignatures(encodedSigs); + + assertArrayEquals(signOne, decodedSigs[0]); + assertArrayEquals(signTwo, decodedSigs[1]); + + verify(aggregatorSpy).PacketAcknowledged(srcNetwork, srcContractAddress, + srcSn, srcHeight, dstNetwork, + dstContractAddress, data, + encodedSigs); } - HashSet
expectedRelayersSet = new HashSet
(); - for (Address rlr : expectedRelayers) { - expectedRelayersSet.add(rlr); + @Test + public void testSubmitPacket_unauthorized() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + byte[] dataHash = Context.hash("sha-256", data); + byte[] sign = relayerFour.sign(dataHash); + + Executable action = () -> aggregator.invoke(relayerFourAc, "submitPacket", + srcNetwork, srcContractAddress, + srcSn, + srcHeight, dstNetwork, dstContractAddress, data, sign); + + UserRevertedException e = assertThrows(UserRevertedException.class, action); + assertEquals("Reverted(0): Unauthorized: caller is not a registered relayer", + e.getMessage()); } - assertEquals(expectedRelayersSet, updatedRelayersSet); - - Integer result = (Integer) aggregator.call("getSignatureThreshold"); - assertEquals(threshold, result); - } - - @Test - public void testSetRelayers_unauthorized() { - Account relayerFiveAc = sm.createAccount(); - Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; - - Integer threshold = 3; - Executable action = () -> aggregator.invoke(relayerOneAc, "setRelayers", - (Object) newRelayers, threshold); - UserRevertedException e = assertThrows(UserRevertedException.class, action); - - assertEquals("Reverted(0): Unauthorized: caller is not the leader relayer", - e.getMessage()); - - } - - @Test - public void testSetRelayers_invalidThreshold() { - Account relayerFiveAc = sm.createAccount(); - Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; - - Integer threshold = 5; - Executable action = () -> aggregator.invoke(adminAc, "setRelayers", - (Object) newRelayers, threshold); - UserRevertedException e = assertThrows(UserRevertedException.class, action); - - assertEquals("Reverted(0): threshold value should be at least 1 and not greater than relayers size", - e.getMessage()); - - } - - @Test - public void testSetRelayers_invalidThresholdZero() { - Account relayerFiveAc = sm.createAccount(); - Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; - - Integer threshold = 0; - Executable action = () -> aggregator.invoke(adminAc, "setRelayers", - (Object) newRelayers, threshold); - UserRevertedException e = assertThrows(UserRevertedException.class, action); - - assertEquals("Reverted(0): threshold value should be at least 1 and not greater than relayers size", - e.getMessage()); - - } - - @Test - public void testPacketSubmitted_true() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - aggregator.invoke(adminAc, "setSignatureThreshold", 2); - - byte[] dataHash = Context.hash("sha-256", data); - byte[] sign = relayerOne.sign(dataHash); - - aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, - srcContractAddress, srcSn, srcHeight, dstNetwork, - dstContractAddress, data, - sign); - - boolean submitted = (boolean) aggregator.call("packetSubmitted", - relayerOneAc.getAddress(), srcNetwork, - srcContractAddress, srcSn); - assertEquals(submitted, true); - } - - @Test - public void testPacketSubmitted_false() throws Exception { - String srcNetwork = "0x2.icon"; - BigInteger srcSn = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - - boolean submitted = (boolean) aggregator.call("packetSubmitted", - relayerOneAc.getAddress(), srcNetwork, - srcContractAddress, srcSn); - assertEquals(submitted, false); - } - - @Test - public void testSubmitPacket() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - aggregator.invoke(adminAc, "setSignatureThreshold", 2); - - byte[] dataHash = Context.hash("sha-256", data); - byte[] sign = relayerOne.sign(dataHash); - - aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, - srcContractAddress, srcSn, srcHeight, dstNetwork, - dstContractAddress, data, - sign); - - String pktID = Packet.createId(srcNetwork, srcContractAddress, srcSn); - verify(aggregatorSpy).PacketRegistered(srcNetwork, srcContractAddress, srcSn, - srcHeight, dstNetwork, - dstContractAddress, data); - verify(aggregatorSpy).setSignature(pktID, relayerOneAc.getAddress(), sign); - } - - @Test - public void testSubmitPacket_thresholdReached() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - aggregator.invoke(adminAc, "setSignatureThreshold", 2); - - byte[] dataHash = Context.hash("sha-256", data); - - byte[] signAdmin = admin.sign(dataHash); - aggregator.invoke(adminAc, "submitPacket", srcNetwork, srcContractAddress, - srcSn, srcHeight, dstNetwork, - dstContractAddress, data, - signAdmin); - - byte[] signOne = relayerOne.sign(dataHash); - aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, - srcContractAddress, srcSn, srcHeight, dstNetwork, - dstContractAddress, - data, - signOne); - - byte[][] sigs = new byte[2][]; - sigs[0] = signAdmin; - sigs[1] = signOne; - - byte[] encodedSigs = RelayAggregator.serializeSignatures(sigs); - byte[][] decodedSigs = RelayAggregator.deserializeSignatures(encodedSigs); - - assertArrayEquals(signAdmin, decodedSigs[0]); - assertArrayEquals(signOne, decodedSigs[1]); - - verify(aggregatorSpy).PacketAcknowledged(srcNetwork, srcContractAddress, - srcSn, srcHeight, dstNetwork, - dstContractAddress, data, - encodedSigs); - } - - @Test - public void testSubmitPacket_unauthorized() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - byte[] dataHash = Context.hash("sha-256", data); - byte[] sign = relayerFour.sign(dataHash); - - Executable action = () -> aggregator.invoke(relayerFourAc, "submitPacket", - srcNetwork, srcContractAddress, - srcSn, - srcHeight, dstNetwork, dstContractAddress, data, sign); - - UserRevertedException e = assertThrows(UserRevertedException.class, action); - assertEquals("Reverted(0): Unauthorized: caller is not a registered relayer", - e.getMessage()); - } - - @Test - public void testSubmitPacket_duplicate() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - aggregator.invoke(adminAc, "setSignatureThreshold", 2); - - byte[] dataHash = Context.hash("sha-256", data); - byte[] sign = relayerOne.sign(dataHash); - - aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, - srcContractAddress, srcSn, srcHeight, dstNetwork, - dstContractAddress, data, sign); - - Executable action = () -> aggregator.invoke(relayerOneAc, "submitPacket", - srcNetwork, srcContractAddress, srcSn, - srcHeight, dstNetwork, dstContractAddress, - data, sign); - ; - UserRevertedException e = assertThrows(UserRevertedException.class, action); - assertEquals("Reverted(0): Signature already exists", e.getMessage()); - } + @Test + public void testSubmitPacket_duplicate() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + aggregator.invoke(adminAc, "setSignatureThreshold", 2); + + byte[] dataHash = Context.hash("sha-256", data); + byte[] sign = relayerOne.sign(dataHash); + + aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, + dstContractAddress, data, sign); + + Executable action = () -> aggregator.invoke(relayerOneAc, "submitPacket", + srcNetwork, srcContractAddress, srcSn, + srcHeight, dstNetwork, dstContractAddress, + data, sign); + ; + UserRevertedException e = assertThrows(UserRevertedException.class, action); + assertEquals("Reverted(0): Signature already exists", e.getMessage()); + } } From c72a55083bdddda033e582ab36de338cc62d2529 Mon Sep 17 00:00:00 2001 From: gcranju <134275268+gcranju@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:59:14 +0545 Subject: [PATCH 10/14] fix: rlp issue resolved (#420) --- contracts/soroban/libs/soroban-rlp/src/decoder.rs | 3 +++ contracts/soroban/libs/soroban-rlp/src/utils.rs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/contracts/soroban/libs/soroban-rlp/src/decoder.rs b/contracts/soroban/libs/soroban-rlp/src/decoder.rs index 37b83405..9d05760d 100644 --- a/contracts/soroban/libs/soroban-rlp/src/decoder.rs +++ b/contracts/soroban/libs/soroban-rlp/src/decoder.rs @@ -131,6 +131,9 @@ pub fn decode_u64(env: &Env, bytes: Bytes) -> u64 { } pub fn decode_u128(env: &Env, bytes: Bytes) -> u128 { + if bytes.len() == 1 { + return bytes_to_u128(bytes); + } let decoded = decode(&env, bytes); bytes_to_u128(decoded) } diff --git a/contracts/soroban/libs/soroban-rlp/src/utils.rs b/contracts/soroban/libs/soroban-rlp/src/utils.rs index b359078c..403cac52 100644 --- a/contracts/soroban/libs/soroban-rlp/src/utils.rs +++ b/contracts/soroban/libs/soroban-rlp/src/utils.rs @@ -53,7 +53,7 @@ pub fn bytes_to_u64(bytes: Bytes) -> u64 { } pub fn u128_to_bytes(env: &Env, number: u128) -> Bytes { - let mut bytes: Bytes = Bytes::new(&env); + let mut bytes = bytes!(&env, 0x00); let mut i = 15; let mut leading_zero = true; while i >= 0 { From 431c47e198bbf0de28f93ee6c842e8ca448bfee6 Mon Sep 17 00:00:00 2001 From: gcranju Date: Tue, 10 Dec 2024 11:01:42 +0545 Subject: [PATCH 11/14] fix: cluster connection audit fix --- .../cluster_connection/cluster_entry.move | 3 +- .../cluster_connection/cluster_state.move | 58 +++++++++++++------ contracts/sui/xcall/sources/utils.move | 3 +- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/contracts/sui/xcall/sources/cluster_connection/cluster_entry.move b/contracts/sui/xcall/sources/cluster_connection/cluster_entry.move index 1fab2e8f..0b5f9d5e 100644 --- a/contracts/sui/xcall/sources/cluster_connection/cluster_entry.move +++ b/contracts/sui/xcall/sources/cluster_connection/cluster_entry.move @@ -56,8 +56,9 @@ module xcall::cluster_entry{ } entry fun recieve_message_with_signatures(xcall:&mut XCallState,cap:&ConnCap,src_net_id:String,sn:u128,msg:vector,signatures:vector>,ctx: &mut TxContext){ + let dst_net_id=xcall_state::get_net_id(xcall); let state=get_state_mut(xcall_state::get_connection_states_mut(xcall),cap.connection_id()); - cluster_state::verify_signatures(state, src_net_id, sn, msg, signatures); + cluster_state::verify_signatures(state, src_net_id, sn, msg, dst_net_id, signatures); cluster_state::check_save_receipt(state, src_net_id, sn); xcall::handle_message(xcall, cap,src_net_id, msg,ctx); } diff --git a/contracts/sui/xcall/sources/cluster_connection/cluster_state.move b/contracts/sui/xcall/sources/cluster_connection/cluster_state.move index 07742c14..a29c6ac3 100644 --- a/contracts/sui/xcall/sources/cluster_connection/cluster_state.move +++ b/contracts/sui/xcall/sources/cluster_connection/cluster_state.move @@ -12,9 +12,9 @@ module xcall::cluster_state { use 0x2::ecdsa_k1::{secp256k1_ecrecover, decompress_pubkey}; //ERRORS - const VerifiedSignaturesLessThanThreshold: u64 = 100; const NotEnoughSignatures: u64 = 101; const InvalidThreshold: u64 = 102; + const VerifiedSignaturesLessThanThreshold: u64 = 104; const ValidatorCountMustBeGreaterThanThreshold: u64 = 105; const InvalidAdminCap: u64 = 106; @@ -139,9 +139,10 @@ module xcall::cluster_state { src_net_id: String, sn: u128, msg: vector, + dst_net_id: String, signatures: vector> ) { - let message_hash = utils::get_message_hash(src_net_id, sn, msg); + let message_hash = utils::get_message_hash(src_net_id, sn, msg, dst_net_id); let threshold = self.get_validator_threshold(); let validators = self.get_validators(); @@ -241,24 +242,40 @@ module xcall::cluster_state_tests { let mut state = xcall::cluster_state::create_state(); let validators = vector[ - x"045b419bdec0d2bbc16ce8ae144ff8e825123fd0cb3e36d0075b6d8de5aab53388ac8fb4c28a8a3843f3073cdaa40c943f74737fc0cea4a95f87778affac738190", + x"047799e5ded3a450ea95c27f078cdd2e1c41712a829122269e017387dbec0e182ac6a0e35a8788a9eb8db8087c9ba2e97cc419c3b21089a69f842663aac8b8b16e", x"04ae36a8bfd8cf6586f34c688528894835f5e7c19d36689bac5460656b613c5eabf1fa982212aa27caece23a2708eb3c8936e132b9fd82c5aee2aa4b06917b5713", - x"04f8c0afc6e4fa149e17fbb0f4d09647971bd016291e9ac66d0a708ec82fc8d5d2ac878d81b7d3f1d37f1013439fc3eb58a4df2f802f931c791c5d81b09034f337", - x"046bc928ee4932efd619ec4c00e0591e932cf2cfef13a59f6027da1c6cba36b35d91238b54aece19825025a9c7cb0bc58a60d5c49e7fc8e5b39fcc4c2193f5feb2" + x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f", + x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f" ]; - set_validators(&mut state, validators, 2); + set_validators(&mut state, validators, 3); let validators = get_validators(&state); - assert!((validators.length() == 4)); + assert!((validators.length() == 3)); - set_validator_threshold(&mut state, 3); - assert!(get_validator_threshold(&state)==3); + set_validator_threshold(&mut state, 2); + assert!(get_validator_threshold(&state)==2); state } + #[test] + #[expected_failure(abort_code = 105)] + fun test_add_validator_less_than_threshold(): State { + let mut state = xcall::cluster_state::create_state(); + + let validators = vector[ + x"047799e5ded3a450ea95c27f078cdd2e1c41712a829122269e017387dbec0e182ac6a0e35a8788a9eb8db8087c9ba2e97cc419c3b21089a69f842663aac8b8b16e", + x"04ae36a8bfd8cf6586f34c688528894835f5e7c19d36689bac5460656b613c5eabf1fa982212aa27caece23a2708eb3c8936e132b9fd82c5aee2aa4b06917b5713", + x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f", + x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f" + ]; + + set_validators(&mut state, validators, 4); + state + } + #[test] fun test_set_get_threshold(): State { @@ -325,41 +342,46 @@ module xcall::cluster_state_tests { let state = test_add_validator(); let msg: vector = x"68656c6c6f"; let src_net_id = b"0x2.icon".to_string(); + let dst_net_id = b"archway".to_string(); let conn_sn = 456456; - let signatures = vector[x"23f731c7fb3553337394233055cbb9ec05abdd1df7cbbec3d0dacced58bf5b4b30576ca14bea93ea4186e920f99f2b9f56d30175b0a7356322f3a5d75de843b81b", + let signatures = vector[x"b70de18ff69cccdedbc2d6bbd9f4ffe4c789e047dc01ccf167191c965909bee01f23971d260635c0171fcf6ef8335430686a8aa9d8da9b14e90671852d9a0cec1b", ]; - xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, signatures); + xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures); state } #[test] - #[expected_failure(abort_code = 100)] + #[expected_failure(abort_code = 104)] fun test_verify_signatures_invalid(): State { - let state = test_set_get_threshold(); + let state = test_add_validator(); let msg: vector = x"68656c6c6f"; let src_net_id = b"0x2.icon".to_string(); + let dst_net_id = b"archway".to_string(); let conn_sn = 456456; - let signatures = vector[x"23f731c7fb3553337394233055cbb9ec05abdd1df7cbbec3d0dacced58bf5b4b30576ca14bea93ea4186e920f99f2b9f56d30175b0a7356322f3a5d75de843b81c", + let signatures = vector[x"b70de18ff69cccdedbc2d6bbd9f4ffe4c789e047dc01ccf167191c965909bee01f23971d260635c0171fcf6ef8335430686a8aa9d8da9b14e90671852d9a0cec1b", + x"b70de18ff69cccdedbc2d6bbd9f4ffe4c789e047dc01ccf167191c965909bee01f23971d260635c0171fcf6ef8335430686a8aa9d8da9b14e90671852d9a0cec1b", ]; - xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, signatures); + xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures); state } #[test] fun test_verify_signatures(): State { - let state = test_set_get_threshold(); + let state = test_add_validator(); let msg: vector = x"68656c6c6f"; let src_net_id = b"0x2.icon".to_string(); + let dst_net_id = b"archway".to_string(); let conn_sn = 456456; - let signatures = vector[x"23f731c7fb3553337394233055cbb9ec05abdd1df7cbbec3d0dacced58bf5b4b30576ca14bea93ea4186e920f99f2b9f56d30175b0a7356322f3a5d75de843b81b", + let signatures = vector[x"b70de18ff69cccdedbc2d6bbd9f4ffe4c789e047dc01ccf167191c965909bee01f23971d260635c0171fcf6ef8335430686a8aa9d8da9b14e90671852d9a0cec1b", + x"6800a26740ed36a3df8f660580cc3b2a5f7bc11ccc7868165953979072e864b52909a758d15a508e003953f007e5cdff696276078265445be10ebf242d2c551b1c", ]; - xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, signatures); + xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures); state } diff --git a/contracts/sui/xcall/sources/utils.move b/contracts/sui/xcall/sources/utils.move index 489a4481..0f9b7a83 100644 --- a/contracts/sui/xcall/sources/utils.move +++ b/contracts/sui/xcall/sources/utils.move @@ -26,11 +26,12 @@ module xcall::xcall_utils { } } - public fun get_message_hash(src_net_id: String, sn: u128, msg: vector): vector { + public fun get_message_hash(src_net_id: String, sn: u128, msg: vector, dst_net_id: String): vector { let mut list=vector::empty>(); vector::push_back(&mut list, encoder::encode_string(&src_net_id)); vector::push_back(&mut list, encoder::encode_u128(sn)); vector::push_back(&mut list, encoder::encode(&msg)); + vector::push_back(&mut list, encoder::encode_string(&dst_net_id)); let encoded=encoder::encode_list(&list,false); encoded } From fb2cb1353d9f04f8d6323dd3c0b7b93d215bb793 Mon Sep 17 00:00:00 2001 From: gcranju Date: Tue, 10 Dec 2024 13:37:04 +0545 Subject: [PATCH 12/14] fix: stellar cluster fixes --- contracts/soroban/Cargo.lock | 1 + .../contracts/cluster-connection/Cargo.toml | 1 + .../cluster-connection/src/helpers.rs | 21 ++++++++- .../src/interfaces/interface_xcall.rs | 2 + .../contracts/cluster-connection/src/test.rs | 43 ++++++++++--------- .../cluster_connection/cluster_state.move | 11 +++-- 6 files changed, 51 insertions(+), 28 deletions(-) diff --git a/contracts/soroban/Cargo.lock b/contracts/soroban/Cargo.lock index fbf3411e..3b10ba1f 100644 --- a/contracts/soroban/Cargo.lock +++ b/contracts/soroban/Cargo.lock @@ -159,6 +159,7 @@ version = "0.0.0" dependencies = [ "soroban-rlp", "soroban-sdk", + "soroban-xcall-lib", ] [[package]] diff --git a/contracts/soroban/contracts/cluster-connection/Cargo.toml b/contracts/soroban/contracts/cluster-connection/Cargo.toml index e6f6b482..e1cb631f 100644 --- a/contracts/soroban/contracts/cluster-connection/Cargo.toml +++ b/contracts/soroban/contracts/cluster-connection/Cargo.toml @@ -11,6 +11,7 @@ doctest = false [dependencies] soroban-sdk = { workspace = true, features = ["alloc"] } soroban-rlp = { path = "../../libs/soroban-rlp" } +soroban-xcall-lib = { path = "../../libs/soroban-xcall-lib" } [dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/contracts/soroban/contracts/cluster-connection/src/helpers.rs b/contracts/soroban/contracts/cluster-connection/src/helpers.rs index f37ed14f..96162581 100644 --- a/contracts/soroban/contracts/cluster-connection/src/helpers.rs +++ b/contracts/soroban/contracts/cluster-connection/src/helpers.rs @@ -1,6 +1,7 @@ use soroban_sdk::{token, vec, Address, Bytes, BytesN, Env, Map, String, Vec}; use crate::{errors::ContractError, interfaces::interface_xcall::XcallClient, storage}; use soroban_rlp::encoder; +use soroban_xcall_lib::network_address::NetworkAddress; pub fn ensure_relayer(e: &Env) -> Result { let relayer = storage::relayer(&e)?; @@ -63,13 +64,14 @@ pub fn verify_signatures( conn_sn: &u128, message: &Bytes, ) -> bool { + let dst_network = get_network_id(e); let validators = storage::get_validators(e).unwrap(); let threshold = storage::get_validators_threshold(e).unwrap(); if signatures.len() < threshold { return false } - let message_hash = e.crypto().keccak256(&get_encoded_message(e, src_network, conn_sn, message)); + let message_hash = e.crypto().keccak256(&get_encoded_message(e, src_network, conn_sn, message, &dst_network)); let mut unique_validators = Map::new(e); let mut count = 0; @@ -98,15 +100,30 @@ pub fn verify_signatures( } -pub fn get_encoded_message(e: &Env, src_network: &String, conn_sn: &u128, message: &Bytes) -> Bytes { +pub fn get_encoded_message(e: &Env, src_network: &String, conn_sn: &u128, message: &Bytes, dst_network: &String) -> Bytes { let mut list = vec![&e]; list.push_back(encoder::encode_string(&e, src_network.clone())); list.push_back(encoder::encode_u128(&e, conn_sn.clone())); list.push_back(encoder::encode(&e, message.clone())); + list.push_back(encoder::encode_string(&e, dst_network.clone())); encoder::encode_list(&e, list, false) } +#[cfg(not(test))] +pub fn get_network_id(e: &Env) -> String { + let xcall_addr = storage::get_xcall(&e).unwrap(); + let client = XcallClient::new(&e, &xcall_addr); + let network_address = NetworkAddress::from_string(client.get_network_address()); + network_address.nid(&e) +} + +#[cfg(test)] +pub fn get_network_id(e: &Env) -> String { + let network_address = NetworkAddress::from_string(String::from_str(e, "archway/testnet")); + network_address.nid(&e) +} + #[cfg(not(test))] pub fn call_xcall_handle_message(e: &Env, nid: &String, msg: Bytes) -> Result<(), ContractError> { let xcall_addr = storage::get_xcall(&e)?; diff --git a/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs b/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs index c49d6c9c..12ed8edb 100644 --- a/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs +++ b/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs @@ -12,4 +12,6 @@ pub trait IXcall { ) -> Result<(), ContractError>; fn handle_error(env: Env, sender: Address, sequence_no: u128) -> Result<(), ContractError>; + + fn get_network_address(env: Env) -> Result; } diff --git a/contracts/soroban/contracts/cluster-connection/src/test.rs b/contracts/soroban/contracts/cluster-connection/src/test.rs index fe375ba5..b27240e2 100644 --- a/contracts/soroban/contracts/cluster-connection/src/test.rs +++ b/contracts/soroban/contracts/cluster-connection/src/test.rs @@ -356,14 +356,16 @@ fn test_add_validator() { ctx.init_context(&client); - let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; - let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; + let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; + let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; + let val4 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; let mut validators = Vec::new(&ctx.env); validators.push_back(BytesN::from_array(&ctx.env, &val1)); validators.push_back(BytesN::from_array(&ctx.env, &val2)); validators.push_back(BytesN::from_array(&ctx.env, &val3)); + validators.push_back(BytesN::from_array(&ctx.env, &val4)); client.update_validators(&validators, &3_u32); assert_eq!( @@ -395,10 +397,10 @@ fn test_set_threshold() { ctx.init_context(&client); - let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; - let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; + let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; + let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; - + let mut validators = Vec::new(&ctx.env); validators.push_back(BytesN::from_array(&ctx.env, &val1)); validators.push_back(BytesN::from_array(&ctx.env, &val2)); @@ -437,22 +439,22 @@ fn test_receive_message() { ctx.init_context(&client); - let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; - let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; - let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; - + let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; + let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; + let val3 = [4,72,52,12,151,129,229,77,65,79,250,130,156,185,218,183,93,60,240,174,254,0,10,249,91,17,34,19,35,65,175,22,101,71,12,189,246,242,98,40,120,227,159,144,137,5,226,115,100,5,122,135,101,42,21,6,81,160,242,118,232,108,43,93,213]; + let mut validators = Vec::new(&ctx.env); validators.push_back(BytesN::from_array(&ctx.env, &val1)); validators.push_back(BytesN::from_array(&ctx.env, &val2)); validators.push_back(BytesN::from_array(&ctx.env, &val3)); client.update_validators(&validators, &1_u32); - let conn_sn = 456456_u128; + let conn_sn = 127_u128; let msg = Bytes::from_array(&ctx.env,&[104, 101, 108, 108, 111]); let src_network = String::from_str(&ctx.env, "0x2.icon"); let mut signatures = Vec::new(&ctx.env); - signatures.push_back(BytesN::from_array(&ctx.env, &[35, 247, 49, 199, 251, 53, 83, 51, 115, 148, 35, 48, 85, 203, 185, 236, 5, 171, 221, 29, 247, 203, 190, 195, 208, 218, 204, 237, 88, 191, 91, 75, 48, 87, 108, 161, 75, 234, 147, 234, 65, 134, 233, 32, 249, 159, 43, 159, 86, 211, 1, 117, 176, 167, 53, 99, 34, 243, 165, 215, 93, 232, 67, 184, 27])); + signatures.push_back(BytesN::from_array(&ctx.env, &[207,162,211,248,150,229,247,29,124,190,102,71,216,156,41,167,107,55,84,207,134,97,88,23,86,221,210,155,0,72,136,69,10,134,60,204,148,30,34,104,236,3,111,107,145,70,45,101,0,204,86,135,118,172,233,102,113,116,136,57,13,76,19,24,27])); client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures); } @@ -465,10 +467,10 @@ fn test_receive_message_less_signatures() { ctx.init_context(&client); - let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; - let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; + let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; + let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; - + let mut validators = Vec::new(&ctx.env); validators.push_back(BytesN::from_array(&ctx.env, &val1)); validators.push_back(BytesN::from_array(&ctx.env, &val2)); @@ -480,7 +482,7 @@ fn test_receive_message_less_signatures() { let src_network = String::from_str(&ctx.env, "0x2.icon"); let mut signatures = Vec::new(&ctx.env); - signatures.push_back(BytesN::from_array(&ctx.env, &[35, 247, 49, 199, 251, 53, 83, 51, 115, 148, 35, 48, 85, 203, 185, 236, 5, 171, 221, 29, 247, 203, 190, 195, 208, 218, 204, 237, 88, 191, 91, 75, 48, 87, 108, 161, 75, 234, 147, 234, 65, 134, 233, 32, 249, 159, 43, 159, 86, 211, 1, 117, 176, 167, 53, 99, 34, 243, 165, 215, 93, 232, 67, 184, 27])); + signatures.push_back(BytesN::from_array(&ctx.env, &[104,0,162,103,64,237,54,163,223,143,102,5,128,204,59,42,95,123,193,28,204,120,104,22,89,83,151,144,114,232,100,181,41,9,167,88,209,90,80,142,0,57,83,240,7,229,205,255,105,98,118,7,130,101,68,91,225,14,191,36,45,44,85,27,28])); client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures); } @@ -493,22 +495,23 @@ fn test_receive_message_with_invalid_signature() { ctx.init_context(&client); - let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19]; - let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144]; + let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; + let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; - + let mut validators = Vec::new(&ctx.env); validators.push_back(BytesN::from_array(&ctx.env, &val1)); validators.push_back(BytesN::from_array(&ctx.env, &val2)); validators.push_back(BytesN::from_array(&ctx.env, &val3)); - client.update_validators(&validators, &1_u32); + client.update_validators(&validators, &2_u32); let conn_sn = 456456_u128; let msg = Bytes::from_array(&ctx.env,&[104, 100, 108, 108, 111]); let src_network = String::from_str(&ctx.env, "0x2.icon"); let mut signatures = Vec::new(&ctx.env); - signatures.push_back(BytesN::from_array(&ctx.env, &[35, 247, 49, 199, 251, 53, 83, 51, 115, 148, 35, 48, 85, 203, 185, 236, 5, 171, 221, 29, 247, 203, 190, 195, 208, 218, 204, 237, 88, 191, 91, 75, 48, 87, 108, 161, 75, 234, 147, 234, 65, 134, 233, 32, 249, 159, 43, 159, 86, 211, 1, 117, 176, 167, 53, 99, 34, 243, 165, 215, 93, 232, 67, 184, 27])); + signatures.push_back(BytesN::from_array(&ctx.env, &[104,0,162,103,64,237,54,163,223,143,102,5,128,204,59,42,95,123,193,28,204,120,104,22,89,83,151,144,114,232,100,181,41,9,167,88,209,90,80,142,0,57,83,240,7,229,205,255,105,98,118,7,130,101,68,91,225,14,191,36,45,44,85,27,28])); + signatures.push_back(BytesN::from_array(&ctx.env, &[104,0,162,103,64,237,54,163,223,143,102,5,128,204,59,42,95,123,193,28,204,120,104,22,89,83,151,144,114,232,100,181,41,9,167,88,209,90,80,142,0,57,83,240,7,229,205,255,105,98,118,7,130,101,68,91,225,14,191,36,45,44,85,27,28])); client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures); } diff --git a/contracts/sui/xcall/sources/cluster_connection/cluster_state.move b/contracts/sui/xcall/sources/cluster_connection/cluster_state.move index a29c6ac3..1a1ee7f9 100644 --- a/contracts/sui/xcall/sources/cluster_connection/cluster_state.move +++ b/contracts/sui/xcall/sources/cluster_connection/cluster_state.move @@ -243,7 +243,7 @@ module xcall::cluster_state_tests { let validators = vector[ x"047799e5ded3a450ea95c27f078cdd2e1c41712a829122269e017387dbec0e182ac6a0e35a8788a9eb8db8087c9ba2e97cc419c3b21089a69f842663aac8b8b16e", - x"04ae36a8bfd8cf6586f34c688528894835f5e7c19d36689bac5460656b613c5eabf1fa982212aa27caece23a2708eb3c8936e132b9fd82c5aee2aa4b06917b5713", + x"0448340c9781e54d414ffa829cb9dab75d3cf0aefe000af95b1122132341af1665470cbdf6f2622878e39f908905e27364057a87652a150651a0f276e86c2b5dd5", x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f", x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f" ]; @@ -267,7 +267,7 @@ module xcall::cluster_state_tests { let validators = vector[ x"047799e5ded3a450ea95c27f078cdd2e1c41712a829122269e017387dbec0e182ac6a0e35a8788a9eb8db8087c9ba2e97cc419c3b21089a69f842663aac8b8b16e", - x"04ae36a8bfd8cf6586f34c688528894835f5e7c19d36689bac5460656b613c5eabf1fa982212aa27caece23a2708eb3c8936e132b9fd82c5aee2aa4b06917b5713", + x"0448340c9781e54d414ffa829cb9dab75d3cf0aefe000af95b1122132341af1665470cbdf6f2622878e39f908905e27364057a87652a150651a0f276e86c2b5dd5", x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f", x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f" ]; @@ -371,14 +371,13 @@ module xcall::cluster_state_tests { #[test] fun test_verify_signatures(): State { - let state = test_add_validator(); + let state = test_set_get_threshold(); let msg: vector = x"68656c6c6f"; let src_net_id = b"0x2.icon".to_string(); let dst_net_id = b"archway".to_string(); - let conn_sn = 456456; + let conn_sn = 128; - let signatures = vector[x"b70de18ff69cccdedbc2d6bbd9f4ffe4c789e047dc01ccf167191c965909bee01f23971d260635c0171fcf6ef8335430686a8aa9d8da9b14e90671852d9a0cec1b", - x"6800a26740ed36a3df8f660580cc3b2a5f7bc11ccc7868165953979072e864b52909a758d15a508e003953f007e5cdff696276078265445be10ebf242d2c551b1c", + let signatures = vector[x"cfa2d3f896e5f71d7cbe6647d89c29a76b3754cf8661581756ddd29b004888450a863ccc941e2268ec036f6b91462d6500cc568776ace966717488390d4c13181b", ]; xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures); From 85e933b226319a7e4efc9812e2324690e0a105a4 Mon Sep 17 00:00:00 2001 From: gcranju Date: Tue, 10 Dec 2024 17:15:50 +0545 Subject: [PATCH 13/14] fix: sui convert to rlp --- .../cluster_connection/cluster_state.move | 21 ++++++++++--------- contracts/sui/xcall/sources/utils.move | 12 +++++------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/contracts/sui/xcall/sources/cluster_connection/cluster_state.move b/contracts/sui/xcall/sources/cluster_connection/cluster_state.move index 1a1ee7f9..67125903 100644 --- a/contracts/sui/xcall/sources/cluster_connection/cluster_state.move +++ b/contracts/sui/xcall/sources/cluster_connection/cluster_state.move @@ -242,8 +242,8 @@ module xcall::cluster_state_tests { let mut state = xcall::cluster_state::create_state(); let validators = vector[ - x"047799e5ded3a450ea95c27f078cdd2e1c41712a829122269e017387dbec0e182ac6a0e35a8788a9eb8db8087c9ba2e97cc419c3b21089a69f842663aac8b8b16e", - x"0448340c9781e54d414ffa829cb9dab75d3cf0aefe000af95b1122132341af1665470cbdf6f2622878e39f908905e27364057a87652a150651a0f276e86c2b5dd5", + x"04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209", + x"04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01", x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f", x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f" ]; @@ -266,8 +266,8 @@ module xcall::cluster_state_tests { let mut state = xcall::cluster_state::create_state(); let validators = vector[ - x"047799e5ded3a450ea95c27f078cdd2e1c41712a829122269e017387dbec0e182ac6a0e35a8788a9eb8db8087c9ba2e97cc419c3b21089a69f842663aac8b8b16e", - x"0448340c9781e54d414ffa829cb9dab75d3cf0aefe000af95b1122132341af1665470cbdf6f2622878e39f908905e27364057a87652a150651a0f276e86c2b5dd5", + x"04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209", + x"04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01", x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f", x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f" ]; @@ -345,7 +345,7 @@ module xcall::cluster_state_tests { let dst_net_id = b"archway".to_string(); let conn_sn = 456456; - let signatures = vector[x"b70de18ff69cccdedbc2d6bbd9f4ffe4c789e047dc01ccf167191c965909bee01f23971d260635c0171fcf6ef8335430686a8aa9d8da9b14e90671852d9a0cec1b", + let signatures = vector[x"660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c", ]; xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures); @@ -359,10 +359,10 @@ module xcall::cluster_state_tests { let msg: vector = x"68656c6c6f"; let src_net_id = b"0x2.icon".to_string(); let dst_net_id = b"archway".to_string(); - let conn_sn = 456456; + let conn_sn = 128; - let signatures = vector[x"b70de18ff69cccdedbc2d6bbd9f4ffe4c789e047dc01ccf167191c965909bee01f23971d260635c0171fcf6ef8335430686a8aa9d8da9b14e90671852d9a0cec1b", - x"b70de18ff69cccdedbc2d6bbd9f4ffe4c789e047dc01ccf167191c965909bee01f23971d260635c0171fcf6ef8335430686a8aa9d8da9b14e90671852d9a0cec1b", + let signatures = vector[x"660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c", + x"6a219f99495d3c093641648b96e0f4be4baba36e37f3054fb61ada7b82ed79c66a192af03314b8edfaecf6f541e1410d8b61f78649432f5b51b333f8b5ca40321b", ]; xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures); @@ -371,13 +371,14 @@ module xcall::cluster_state_tests { #[test] fun test_verify_signatures(): State { - let state = test_set_get_threshold(); + let state = test_add_validator(); let msg: vector = x"68656c6c6f"; let src_net_id = b"0x2.icon".to_string(); let dst_net_id = b"archway".to_string(); let conn_sn = 128; - let signatures = vector[x"cfa2d3f896e5f71d7cbe6647d89c29a76b3754cf8661581756ddd29b004888450a863ccc941e2268ec036f6b91462d6500cc568776ace966717488390d4c13181b", + let signatures = vector[x"660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c", + x"8024de4c7b003df96bb699cfaa1bfb8a682787cd0853f555d48494c65c766f8104804848095890a9a6d15946da52dafb18e5c1d0dbe7f33fc7a5fa5cf8b1f6e21c" ]; xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures); diff --git a/contracts/sui/xcall/sources/utils.move b/contracts/sui/xcall/sources/utils.move index 0f9b7a83..4fd9b1da 100644 --- a/contracts/sui/xcall/sources/utils.move +++ b/contracts/sui/xcall/sources/utils.move @@ -27,12 +27,12 @@ module xcall::xcall_utils { } public fun get_message_hash(src_net_id: String, sn: u128, msg: vector, dst_net_id: String): vector { - let mut list=vector::empty>(); - vector::push_back(&mut list, encoder::encode_string(&src_net_id)); - vector::push_back(&mut list, encoder::encode_u128(sn)); - vector::push_back(&mut list, encoder::encode(&msg)); - vector::push_back(&mut list, encoder::encode_string(&dst_net_id)); - let encoded=encoder::encode_list(&list,false); + + let mut encoded=vector::empty(); + vector::append(&mut encoded, src_net_id.into_bytes()); + vector::append(&mut encoded, (sn.to_string()).into_bytes()); + vector::append(&mut encoded, msg); + vector::append(&mut encoded, dst_net_id.into_bytes()); encoded } From 4d33e710affd25f52cb4ed34fdca5fb39a6e2bf0 Mon Sep 17 00:00:00 2001 From: gcranju Date: Tue, 10 Dec 2024 19:16:28 +0545 Subject: [PATCH 14/14] fix: stellar rlp to string bytes --- .../contracts/cluster-connection/Cargo.toml | 1 - .../cluster-connection/src/helpers.rs | 57 +++++++++-- .../contracts/cluster-connection/src/test.rs | 97 ++++++++++--------- 3 files changed, 102 insertions(+), 53 deletions(-) diff --git a/contracts/soroban/contracts/cluster-connection/Cargo.toml b/contracts/soroban/contracts/cluster-connection/Cargo.toml index e1cb631f..8166e5e4 100644 --- a/contracts/soroban/contracts/cluster-connection/Cargo.toml +++ b/contracts/soroban/contracts/cluster-connection/Cargo.toml @@ -10,7 +10,6 @@ doctest = false [dependencies] soroban-sdk = { workspace = true, features = ["alloc"] } -soroban-rlp = { path = "../../libs/soroban-rlp" } soroban-xcall-lib = { path = "../../libs/soroban-xcall-lib" } [dev-dependencies] diff --git a/contracts/soroban/contracts/cluster-connection/src/helpers.rs b/contracts/soroban/contracts/cluster-connection/src/helpers.rs index 96162581..d7343698 100644 --- a/contracts/soroban/contracts/cluster-connection/src/helpers.rs +++ b/contracts/soroban/contracts/cluster-connection/src/helpers.rs @@ -1,6 +1,5 @@ -use soroban_sdk::{token, vec, Address, Bytes, BytesN, Env, Map, String, Vec}; +use soroban_sdk::{token, xdr::ToXdr, Address, Bytes, BytesN, Env, Map, String, Vec}; use crate::{errors::ContractError, interfaces::interface_xcall::XcallClient, storage}; -use soroban_rlp::encoder; use soroban_xcall_lib::network_address::NetworkAddress; pub fn ensure_relayer(e: &Env) -> Result { @@ -100,14 +99,44 @@ pub fn verify_signatures( } +pub fn string_to_bytes(env: &Env, value: String) -> Bytes { + let string_xdr = value.clone().to_xdr(&env); + let mut bytes = Bytes::new(&env); + for i in 8..(8 + value.len()) { + if let Some(byte) = string_xdr.get(i) { + bytes.push_back(byte); + } + } + bytes +} + pub fn get_encoded_message(e: &Env, src_network: &String, conn_sn: &u128, message: &Bytes, dst_network: &String) -> Bytes { - let mut list = vec![&e]; - list.push_back(encoder::encode_string(&e, src_network.clone())); - list.push_back(encoder::encode_u128(&e, conn_sn.clone())); - list.push_back(encoder::encode(&e, message.clone())); - list.push_back(encoder::encode_string(&e, dst_network.clone())); + let mut encoded = Bytes::new(e); + encoded.append(&string_to_bytes(e, src_network.clone())); + encoded.append(&u128_to_string(e, *conn_sn)); + encoded.append(message); + encoded.append(&string_to_bytes(e, dst_network.clone())); + encoded +} - encoder::encode_list(&e, list, false) +pub fn u128_to_string(env: &Env, value: u128) -> Bytes { + let mut num = value; + let mut temp_bytes = Bytes::new(&env); + let mut bytes = Bytes::new(&env); + + if value == 0 { + temp_bytes.push_back(b'0'); + return temp_bytes; + } + while num > 0 { + let digit = (num % 10) as u8 + b'0'; + temp_bytes.push_back(digit); + num /= 10; + } + for byte in temp_bytes.iter().rev() { + bytes.push_back(byte); + } + bytes } #[cfg(not(test))] @@ -147,3 +176,15 @@ pub fn call_xcall_handle_error(e: &Env, sn: u128) -> Result<(), ContractError> { Ok(()) } + +#[test] +fn verify_encoded_message() { + use soroban_sdk::bytes; + let env = Env::default(); + let src_network = String::from_str(&env, "0x2.icon"); + let conn_sn = 128; + let message = bytes!(&env, 0x68656c6c6f); + let dst_network = String::from_str(&env, "archway"); + let encoded = get_encoded_message(&env, &src_network, &conn_sn, &message, &dst_network); + assert_eq!(encoded, bytes!(&env,0x3078322e69636f6e31323868656c6c6f61726368776179)); +} \ No newline at end of file diff --git a/contracts/soroban/contracts/cluster-connection/src/test.rs b/contracts/soroban/contracts/cluster-connection/src/test.rs index b27240e2..6b0cec87 100644 --- a/contracts/soroban/contracts/cluster-connection/src/test.rs +++ b/contracts/soroban/contracts/cluster-connection/src/test.rs @@ -13,7 +13,7 @@ use crate::{ types::InitializeMsg, }; use soroban_sdk::{ - symbol_short, testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, Events}, token, vec, Address, Bytes, BytesN, Env, IntoVal, String, Symbol, Vec + bytesn, symbol_short, testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, Events}, token, vec, Address, Bytes, BytesN, Env, IntoVal, String, Symbol, Vec }; pub struct TestContext { @@ -356,16 +356,16 @@ fn test_add_validator() { ctx.init_context(&client); - let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; - let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; - let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; - let val4 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; + let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209); + let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01); + let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); + let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); let mut validators = Vec::new(&ctx.env); - validators.push_back(BytesN::from_array(&ctx.env, &val1)); - validators.push_back(BytesN::from_array(&ctx.env, &val2)); - validators.push_back(BytesN::from_array(&ctx.env, &val3)); - validators.push_back(BytesN::from_array(&ctx.env, &val4)); + validators.push_back(val1); + validators.push_back(val2); + validators.push_back(val3); + validators.push_back(val4); client.update_validators(&validators, &3_u32); assert_eq!( @@ -397,14 +397,16 @@ fn test_set_threshold() { ctx.init_context(&client); - let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; - let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; - let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; - + let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209); + let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01); + let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); + let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); + let mut validators = Vec::new(&ctx.env); - validators.push_back(BytesN::from_array(&ctx.env, &val1)); - validators.push_back(BytesN::from_array(&ctx.env, &val2)); - validators.push_back(BytesN::from_array(&ctx.env, &val3)); + validators.push_back(val1); + validators.push_back(val2); + validators.push_back(val3); + validators.push_back(val4); client.update_validators(&validators, &3_u32); let threshold: u32 = 2_u32; @@ -439,22 +441,25 @@ fn test_receive_message() { ctx.init_context(&client); - let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; - let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; - let val3 = [4,72,52,12,151,129,229,77,65,79,250,130,156,185,218,183,93,60,240,174,254,0,10,249,91,17,34,19,35,65,175,22,101,71,12,189,246,242,98,40,120,227,159,144,137,5,226,115,100,5,122,135,101,42,21,6,81,160,242,118,232,108,43,93,213]; - + let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209); + let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01); + let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); + let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); + let mut validators = Vec::new(&ctx.env); - validators.push_back(BytesN::from_array(&ctx.env, &val1)); - validators.push_back(BytesN::from_array(&ctx.env, &val2)); - validators.push_back(BytesN::from_array(&ctx.env, &val3)); - client.update_validators(&validators, &1_u32); + validators.push_back(val1); + validators.push_back(val2); + validators.push_back(val3); + validators.push_back(val4); + client.update_validators(&validators, &2_u32); - let conn_sn = 127_u128; + let conn_sn = 128_u128; let msg = Bytes::from_array(&ctx.env,&[104, 101, 108, 108, 111]); let src_network = String::from_str(&ctx.env, "0x2.icon"); let mut signatures = Vec::new(&ctx.env); - signatures.push_back(BytesN::from_array(&ctx.env, &[207,162,211,248,150,229,247,29,124,190,102,71,216,156,41,167,107,55,84,207,134,97,88,23,86,221,210,155,0,72,136,69,10,134,60,204,148,30,34,104,236,3,111,107,145,70,45,101,0,204,86,135,118,172,233,102,113,116,136,57,13,76,19,24,27])); + signatures.push_back(bytesn!(&ctx.env, 0x660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c)); + signatures.push_back(bytesn!(&ctx.env, 0x8024de4c7b003df96bb699cfaa1bfb8a682787cd0853f555d48494c65c766f8104804848095890a9a6d15946da52dafb18e5c1d0dbe7f33fc7a5fa5cf8b1f6e21c)); client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures); } @@ -467,22 +472,24 @@ fn test_receive_message_less_signatures() { ctx.init_context(&client); - let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; - let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; - let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; - + let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209); + let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01); + let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); + let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); + let mut validators = Vec::new(&ctx.env); - validators.push_back(BytesN::from_array(&ctx.env, &val1)); - validators.push_back(BytesN::from_array(&ctx.env, &val2)); - validators.push_back(BytesN::from_array(&ctx.env, &val3)); + validators.push_back(val1); + validators.push_back(val2); + validators.push_back(val3); + validators.push_back(val4); client.update_validators(&validators, &2_u32); - let conn_sn = 456456_u128; + let conn_sn = 128_u128; let msg = Bytes::from_array(&ctx.env,&[104, 101, 108, 108, 111]); let src_network = String::from_str(&ctx.env, "0x2.icon"); let mut signatures = Vec::new(&ctx.env); - signatures.push_back(BytesN::from_array(&ctx.env, &[104,0,162,103,64,237,54,163,223,143,102,5,128,204,59,42,95,123,193,28,204,120,104,22,89,83,151,144,114,232,100,181,41,9,167,88,209,90,80,142,0,57,83,240,7,229,205,255,105,98,118,7,130,101,68,91,225,14,191,36,45,44,85,27,28])); + signatures.push_back(bytesn!(&ctx.env, 0x660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c)); client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures); } @@ -495,14 +502,16 @@ fn test_receive_message_with_invalid_signature() { ctx.init_context(&client); - let val1 = [4,29,127,165,180,31,228,10,232,81,48,196,204,51,79,120,82,194,92,25,231,243,38,169,22,212,159,107,156,63,53,161,33,107,245,60,128,93,23,124,40,247,190,220,45,37,33,203,15,19,220,131,46,246,137,121,121,101,39,77,38,223,80,205,15]; - let val2 = [4,119,153,229,222,211,164,80,234,149,194,127,7,140,221,46,28,65,113,42,130,145,34,38,158,1,115,135,219,236,14,24,42,198,160,227,90,135,136,169,235,141,184,8,124,155,162,233,124,196,25,195,178,16,137,166,159,132,38,99,170,200,184,177,110]; - let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55]; - + let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209); + let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01); + let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); + let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f); + let mut validators = Vec::new(&ctx.env); - validators.push_back(BytesN::from_array(&ctx.env, &val1)); - validators.push_back(BytesN::from_array(&ctx.env, &val2)); - validators.push_back(BytesN::from_array(&ctx.env, &val3)); + validators.push_back(val1); + validators.push_back(val2); + validators.push_back(val3); + validators.push_back(val4); client.update_validators(&validators, &2_u32); let conn_sn = 456456_u128; @@ -510,8 +519,8 @@ fn test_receive_message_with_invalid_signature() { let src_network = String::from_str(&ctx.env, "0x2.icon"); let mut signatures = Vec::new(&ctx.env); - signatures.push_back(BytesN::from_array(&ctx.env, &[104,0,162,103,64,237,54,163,223,143,102,5,128,204,59,42,95,123,193,28,204,120,104,22,89,83,151,144,114,232,100,181,41,9,167,88,209,90,80,142,0,57,83,240,7,229,205,255,105,98,118,7,130,101,68,91,225,14,191,36,45,44,85,27,28])); - signatures.push_back(BytesN::from_array(&ctx.env, &[104,0,162,103,64,237,54,163,223,143,102,5,128,204,59,42,95,123,193,28,204,120,104,22,89,83,151,144,114,232,100,181,41,9,167,88,209,90,80,142,0,57,83,240,7,229,205,255,105,98,118,7,130,101,68,91,225,14,191,36,45,44,85,27,28])); + signatures.push_back(bytesn!(&ctx.env, 0x660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c)); + signatures.push_back(bytesn!(&ctx.env, 0x660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c)); client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures); }