From d6c49122ca21536114ebe8492fb24428459e137d Mon Sep 17 00:00:00 2001 From: bishalbikram Date: Thu, 19 Sep 2024 14:29:57 +0545 Subject: [PATCH 1/3] fix: return default network fee --- .../centralized-connection/src/storage.rs | 14 ++++++++++---- .../contracts/centralized-connection/src/types.rs | 9 +++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/contracts/soroban/contracts/centralized-connection/src/storage.rs b/contracts/soroban/contracts/centralized-connection/src/storage.rs index 8503d123..3bed6670 100644 --- a/contracts/soroban/contracts/centralized-connection/src/storage.rs +++ b/contracts/soroban/contracts/centralized-connection/src/storage.rs @@ -62,8 +62,11 @@ pub fn get_msg_fee(e: &Env, network_id: String) -> Result { .storage() .persistent() .get(&key) - .ok_or(ContractError::NetworkNotSupported)?; - extend_persistent(e, &key); + .unwrap_or(NetworkFee::default()); + + if network_fee.message_fee > 0 { + extend_persistent(e, &key); + } Ok(network_fee.message_fee) } @@ -74,8 +77,11 @@ pub fn get_res_fee(e: &Env, network_id: String) -> Result { .storage() .persistent() .get(&key) - .ok_or(ContractError::NetworkNotSupported)?; - extend_persistent(e, &key); + .unwrap_or(NetworkFee::default()); + + if network_fee.response_fee > 0 { + extend_persistent(e, &key); + } Ok(network_fee.response_fee) } diff --git a/contracts/soroban/contracts/centralized-connection/src/types.rs b/contracts/soroban/contracts/centralized-connection/src/types.rs index efd90306..fb275b75 100644 --- a/contracts/soroban/contracts/centralized-connection/src/types.rs +++ b/contracts/soroban/contracts/centralized-connection/src/types.rs @@ -23,3 +23,12 @@ pub struct NetworkFee { pub message_fee: u128, pub response_fee: u128, } + +impl NetworkFee { + pub fn default() -> Self { + Self { + message_fee: 0, + response_fee: 0, + } + } +} From b3552eeae88a474948d66de1b959b69e88980144 Mon Sep 17 00:00:00 2001 From: bishalbikram Date: Thu, 19 Sep 2024 14:31:38 +0545 Subject: [PATCH 2/3] chore: remove unnecessary comments --- .../centralized-connection/src/contract.rs | 75 ------------------- 1 file changed, 75 deletions(-) diff --git a/contracts/soroban/contracts/centralized-connection/src/contract.rs b/contracts/soroban/contracts/centralized-connection/src/contract.rs index b884406f..5dcd9913 100644 --- a/contracts/soroban/contracts/centralized-connection/src/contract.rs +++ b/contracts/soroban/contracts/centralized-connection/src/contract.rs @@ -7,18 +7,6 @@ pub struct CentralizedConnection; #[contractimpl] impl CentralizedConnection { - /// It checks if contract is not already initialized and initialize the contract otherwise - /// returns the ContractError - /// - /// Arguments: - /// - /// * `env`: The `Env` type provides access to the environment the contract is executing within - /// * `msg`: `msg` is a struct which includes admin, xcall and native token address to initialize - /// the contract - /// - /// Returns: - /// - /// a `Result<(), ContractError>` pub fn initialize(env: Env, msg: InitializeMsg) -> Result<(), ContractError> { storage::is_initialized(&env)?; @@ -30,31 +18,11 @@ impl CentralizedConnection { Ok(()) } - /// It quries the admin from the contract and returns ContractError if the contract is - /// not initialized - /// - /// Arguments: - /// - /// * `env`: The `Env` type provides access to the environment the contract is executing within - /// - /// Returns: - /// - /// a `Result` pub fn get_admin(env: Env) -> Result { let address = storage::admin(&env)?; Ok(address) } - /// It ensures if the caller is an admin and sets the new admin for the contract - /// - /// Arguments: - /// - /// * `env`: The `Env` type provides access to the environment the contract is executing within - /// * `address`: The new admin address - /// - /// Returns: - /// - /// a `Result<(), ContractError>` pub fn set_admin(env: Env, address: Address) -> Result<(), ContractError> { helpers::ensure_admin(&env)?; storage::store_admin(&env, address); @@ -102,17 +70,6 @@ impl CentralizedConnection { Ok(()) } - /// The function receives message sequence `sn` of failed message from the destination chain - /// and call xcall to handle the response of failure message - /// - /// Arguments: - /// - /// * `env`: The `Env` type provides access to the environment the contract is executing within - /// * `sn`: `sn` is the unique ID of the message send from source chain to the destination chain - /// - /// Returns: - /// - /// a `Result<(), ContractError)` pub fn revert_message(env: &Env, sn: u128) -> Result<(), ContractError> { helpers::ensure_admin(&env)?; helpers::call_xcall_handle_error(&env, sn)?; @@ -120,19 +77,6 @@ impl CentralizedConnection { Ok(()) } - /// It sets fee required to send and recieve message from source chain to destination chain - /// - /// Arguments: - /// * `env`: The `Env` type provides access to the environment the contract is executing within - /// * `network_id`: `network_id` is the unique identifier of a blockchain network - /// * `message_fee`: `message_fee` is the amount of XLM Asset required to send message from - /// source chain to the destination chain - /// * `response_fee`: `response_fee` is the amount of XLM Asset required to receive response of - /// send message from the destination chain - /// - /// Returns: - /// - /// a `Result<(), ContractError>` pub fn set_fee( env: Env, network_id: String, @@ -145,13 +89,6 @@ impl CentralizedConnection { Ok(()) } - /// This function allows admin to claim all the native (XLM) token stored in the contract. First - /// it checks if the caller is an admin, then it sends `transfer` message to Stellar Asset - /// Contract (SAC) of native XLM asset and transfers all the contract fund to admin address - /// - /// Returns: - /// - /// a `Result<(), ContractError>` pub fn claim_fees(env: Env) -> Result<(), ContractError> { let admin = helpers::ensure_admin(&env)?; @@ -163,18 +100,6 @@ impl CentralizedConnection { Ok(()) } - /// It returns the fee required to send the message for specific blockchain network - /// - /// Arguments: - /// - /// * `env`: The `Env` type provides access to the environment the contract is executing within. - /// * `network_id`: `network_id` is the unique blockchain network id stored in the contract storage - /// * `response`: `response` is a boolean value which indicates if the response fee should be - /// included or not. - /// - /// Returns: - /// - /// a `u128` fee required to send message pub fn get_fee(env: Env, network_id: String, response: bool) -> Result { helpers::get_network_fee(&env, network_id, response) } From cbd3825fad365c97374bf30f1cbc9a9223a1cec8 Mon Sep 17 00:00:00 2001 From: bishalbikram Date: Thu, 19 Sep 2024 14:41:03 +0545 Subject: [PATCH 3/3] fix: add zero prefix for numeric types --- .../libs/soroban-rlp/src/test/encoder.rs | 53 ++++++++++--------- .../libs/soroban-rlp/src/test/utils.rs | 2 +- .../soroban/libs/soroban-rlp/src/utils.rs | 19 ++++--- 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/contracts/soroban/libs/soroban-rlp/src/test/encoder.rs b/contracts/soroban/libs/soroban-rlp/src/test/encoder.rs index 64ddaf5d..1bef6239 100644 --- a/contracts/soroban/libs/soroban-rlp/src/test/encoder.rs +++ b/contracts/soroban/libs/soroban-rlp/src/test/encoder.rs @@ -16,10 +16,7 @@ fn test_encode_u32() { let env = Env::default(); let encoded = encode_u32(&env, 2000022458); - assert_eq!(encoded, bytes!(&env, 0x847735EBBA)); - - let encoded = encode_u128(&env, 128); - assert_eq!(encoded, bytes!(&env, 0x8180)) + assert_eq!(encoded, bytes!(&env, 0x85007735EBBA)); } #[test] @@ -27,18 +24,21 @@ fn test_encode_u64() { let env = Env::default(); let encoded = encode_u64(&env, 1999999999999999999); - assert_eq!(encoded, bytes!(&env, 0x881BC16D674EC7FFFF)); + assert_eq!(encoded, bytes!(&env, 0x89001BC16D674EC7FFFF)); let encoded = encode_u64(&env, 199999999); - assert_eq!(encoded, bytes!(&env, 0x840BEBC1FF)) + assert_eq!(encoded, bytes!(&env, 0x85000BEBC1FF)) } #[test] -fn test_u128_u128() { +fn test_encode_u128() { let env = Env::default(); let encoded = encode_u128(&env, 199999999999999999999999999999999999999); - assert_eq!(encoded, bytes!(&env, 0x9096769950B50D88F41314447FFFFFFFFF)) + assert_eq!( + encoded, + bytes!(&env, 0x910096769950B50D88F41314447FFFFFFFFF) + ) } #[test] @@ -63,10 +63,11 @@ fn test_encode_string_with_larger_bytes_length() { let encoded = encode_string(&env, String::from_str(&env, "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s")); - let expected_rlp_byte = 184; + let expected_rlp_byte = 185; let str_bytes_slice = b"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s"; let mut expected_bytes = Bytes::new(&env); expected_bytes.push_back(expected_rlp_byte); + expected_bytes.push_back(0); expected_bytes.push_back(0x97); expected_bytes.extend_from_slice(str_bytes_slice); @@ -107,29 +108,29 @@ fn test_encode_strings_with_longer_bytes() { let encoded = encode_strings(&env, strings); - let rlp_byte = 0xf7 + 2; + let rlp_byte = 0xf7 + 3; let mut expected_encode = Bytes::new(&env); // rlp byte and data length bytes expected_encode.push_back(rlp_byte); - expected_encode.extend_from_array(&[0x01, 0x71]); + expected_encode.extend_from_array(&[0x00, 0x01, 0x74]); // strings - let string_rlp_byte = 0xb7 + 1; + let string_rlp_byte = 0xb7 + 2; let string_len_byte = 0x7c; - expected_encode.extend_from_array(&[string_rlp_byte, string_len_byte]); + expected_encode.extend_from_array(&[string_rlp_byte, 0, string_len_byte]); expected_encode.extend_from_slice(b"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."); let string_len_byte = 0x7b; - expected_encode.extend_from_array(&[string_rlp_byte, string_len_byte]); + expected_encode.extend_from_array(&[string_rlp_byte, 0, string_len_byte]); expected_encode.extend_from_slice(b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); let string_len_byte = 0x74; - expected_encode.extend_from_array(&[string_rlp_byte, string_len_byte]); + expected_encode.extend_from_array(&[string_rlp_byte, 0, string_len_byte]); expected_encode.extend_from_slice(b"Egestas maecenas pharetra convallis posuere morbi. Velit laoreet id donec ultrices tincidunt arcu non sodales neque."); assert_eq!(encoded, expected_encode); - assert_eq!(encoded.len(), 372); + assert_eq!(encoded.len(), 376); } #[test] @@ -153,7 +154,7 @@ fn test_encode_list_with_smaller_bytes() { let encoded = encode_list(&env, list, true); - let expected_rlp_byte = 0xc0 + 17; + let expected_rlp_byte = 0xc0 + 18; let mut expected_bytes = Bytes::new(&env); expected_bytes.push_back(expected_rlp_byte); expected_bytes.append(&encode_u32(&env, 4294967295)); @@ -183,30 +184,30 @@ fn test_encode_list_with_longer_bytes() { let mut expected_bytes = Bytes::new(&env); // rlp and data len bytes - let rlp_byte = 0xf7 + 1; - let data_len_byte = 0xAA; - expected_bytes.extend_from_array(&[rlp_byte, data_len_byte]); + let rlp_byte = 0xf7 + 2; + let data_len_byte = 0xAA + 4; + expected_bytes.extend_from_array(&[rlp_byte, 0, data_len_byte]); // u8 expected_bytes.extend_from_array(&[0x81, 0xF5]); // u32 - expected_bytes.extend_from_array(&[0x84, 0x01, 0x71, 0x34, 0x67]); + expected_bytes.extend_from_array(&[0x85, 0x00, 0x01, 0x71, 0x34, 0x67]); // u64 - expected_bytes.extend_from_array(&[0x88, 0x01, 0x71, 0x34, 0x67, 0xff, 0xff, 0xff, 0xff]); + expected_bytes.extend_from_array(&[0x89, 0x00, 0x01, 0x71, 0x34, 0x67, 0xff, 0xff, 0xff, 0xff]); // u128 expected_bytes.extend_from_array(&[ - 0x90, 0x87, 0xdc, 0xfa, 0xcd, 0x87, 0x98, 0x27, 0x36, 0xcd, 0xef, 0xcd, 0xef, 0xff, 0xff, - 0xff, 0xff, + 0x91, 0x00, 0x87, 0xdc, 0xfa, 0xcd, 0x87, 0x98, 0x27, 0x36, 0xcd, 0xef, 0xcd, 0xef, 0xff, + 0xff, 0xff, 0xff, ]); // strings - let array_rlp_byte = 0xf7 + 1; + let array_rlp_byte = 0xf7 + 2; let total_rlp_bytes_in_array = 2; let strings_len_byte = 0x56 + total_rlp_bytes_in_array; - expected_bytes.extend_from_array(&[array_rlp_byte, strings_len_byte]); + expected_bytes.extend_from_array(&[array_rlp_byte, 0, strings_len_byte]); let rlp_byte = 0x80 + 46; expected_bytes.push_back(rlp_byte); diff --git a/contracts/soroban/libs/soroban-rlp/src/test/utils.rs b/contracts/soroban/libs/soroban-rlp/src/test/utils.rs index 4d1f8b65..a7ebf346 100644 --- a/contracts/soroban/libs/soroban-rlp/src/test/utils.rs +++ b/contracts/soroban/libs/soroban-rlp/src/test/utils.rs @@ -41,5 +41,5 @@ fn test_slice_vector() { let bytes = u128_to_bytes(&env, 1844674407); let slice = slice_vector(&env, bytes.clone(), 1, 2); - assert_eq!(slice, bytes!(&env, 0xF37F)); + assert_eq!(slice, bytes!(&env, 0x6DF3)); } diff --git a/contracts/soroban/libs/soroban-rlp/src/utils.rs b/contracts/soroban/libs/soroban-rlp/src/utils.rs index 90b000de..403cac52 100644 --- a/contracts/soroban/libs/soroban-rlp/src/utils.rs +++ b/contracts/soroban/libs/soroban-rlp/src/utils.rs @@ -1,14 +1,17 @@ use soroban_sdk::{ + bytes, xdr::{FromXdr, ToXdr}, Bytes, Env, String, }; pub fn u32_to_bytes(env: &Env, number: u32) -> Bytes { - let mut bytes = Bytes::new(&env); + let mut bytes = bytes!(&env, 0x00); let mut i = 3; + let mut leading_zero = true; while i >= 0 { let val = (number >> (i * 8) & 0xff) as u8; - if val > 0 { + if val > 0 || !leading_zero { + leading_zero = false; bytes.push_back(val); } @@ -26,11 +29,13 @@ pub fn bytes_to_u32(bytes: Bytes) -> u32 { } pub fn u64_to_bytes(env: &Env, number: u64) -> Bytes { - let mut bytes = Bytes::new(&env); + let mut bytes = bytes!(&env, 0x00); let mut i = 7; + let mut leading_zero = true; while i >= 0 { let val = (number >> (i * 8) & 0xff) as u8; - if val > 0 { + if val > 0 || !leading_zero { + leading_zero = false; bytes.push_back(val); } @@ -48,11 +53,13 @@ pub fn bytes_to_u64(bytes: Bytes) -> u64 { } pub fn u128_to_bytes(env: &Env, number: u128) -> Bytes { - let mut bytes = Bytes::new(&env); + let mut bytes = bytes!(&env, 0x00); let mut i = 15; + let mut leading_zero = true; while i >= 0 { let val = (number >> (i * 8) & 0xff) as u8; - if val > 0 { + if val > 0 || !leading_zero { + leading_zero = false; bytes.push_back(val); }