@layerzerolabs/protocol-stellar-v2 0.2.29 → 0.2.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +371 -321
- package/.turbo/turbo-lint.log +211 -202
- package/.turbo/turbo-test.log +1766 -1673
- package/Cargo.lock +11 -1
- package/contracts/common-macros/src/lib.rs +0 -2
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +1 -0
- package/contracts/endpoint-v2/src/messaging_channel.rs +32 -3
- package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +6 -6
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/outbound.rs +16 -10
- package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +10 -10
- package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +3 -3
- package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +4 -3
- package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +1 -57
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.stderr +0 -30
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -3
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +6 -4
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -3
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -3
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.stderr +0 -30
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.stderr +0 -30
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/basic.rs +0 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/multisig_contract.rs +0 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_migration.rs +0 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_user_contractimpl.rs +1 -3
- package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +3 -6
- package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs +10 -0
- package/contracts/message-libs/message-lib-common/src/worker_options.rs +6 -2
- package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +3 -3
- package/contracts/message-libs/treasury/src/lib.rs +2 -1
- package/contracts/message-libs/treasury/src/tests/setup.rs +1 -1
- package/contracts/message-libs/treasury/src/treasury.rs +5 -2
- package/contracts/message-libs/uln-302/src/errors.rs +2 -0
- package/contracts/message-libs/uln-302/src/events.rs +3 -3
- package/contracts/message-libs/uln-302/src/interfaces/receive_uln.rs +8 -0
- package/contracts/message-libs/uln-302/src/lib.rs +2 -1
- package/contracts/message-libs/uln-302/src/receive_uln.rs +16 -13
- package/contracts/message-libs/uln-302/src/send_uln.rs +51 -24
- package/contracts/message-libs/uln-302/src/storage.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +45 -1
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/verifiable.rs +63 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +47 -2
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +50 -1
- package/contracts/message-libs/uln-302/src/uln302.rs +0 -8
- package/contracts/oapps/counter/Cargo.toml +4 -4
- package/contracts/oapps/counter/integration_tests/setup_uln.rs +22 -2
- package/contracts/oapps/counter/src/counter.rs +8 -8
- package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +33 -10
- package/contracts/oapps/oapp/src/lib.rs +6 -2
- package/contracts/oapps/oapp/src/oapp_core.rs +49 -24
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +21 -14
- package/contracts/oapps/oapp/src/oapp_receiver.rs +17 -16
- package/contracts/oapps/oapp/src/oapp_sender.rs +66 -15
- package/contracts/oapps/oapp/src/tests/oapp_core.rs +5 -5
- package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +18 -18
- package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +4 -4
- package/contracts/oapps/oapp/src/tests/oapp_sender.rs +3 -3
- package/contracts/oapps/oapp-macros/Cargo.toml +0 -1
- package/contracts/oapps/oapp-macros/src/generators.rs +87 -46
- package/contracts/oapps/oapp-macros/src/lib.rs +3 -61
- package/contracts/oapps/oapp-macros/src/tests/oapp.rs +9 -23
- package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +15 -11
- package/contracts/oapps/oft/Cargo.toml +1 -1
- package/contracts/oapps/oft/integration-tests/extensions/test_oft_fee.rs +3 -3
- package/contracts/oapps/oft/integration-tests/extensions/test_pausable.rs +4 -4
- package/contracts/oapps/oft/integration-tests/extensions/test_rate_limiter.rs +144 -8
- package/contracts/oapps/oft/integration-tests/setup.rs +4 -2
- package/contracts/oapps/oft/integration-tests/utils.rs +25 -11
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +65 -63
- package/contracts/oapps/oft/src/extensions/pausable.rs +2 -3
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +22 -5
- package/contracts/oapps/oft/src/interfaces/mint_burnable.rs +18 -0
- package/contracts/oapps/oft/src/interfaces/mod.rs +3 -0
- package/contracts/oapps/oft/src/lib.rs +4 -2
- package/contracts/oapps/oft/src/oft.rs +35 -36
- package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +13 -9
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +14 -9
- package/contracts/oapps/oft/src/oft_types/mod.rs +14 -12
- package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +28 -20
- package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +136 -2
- package/contracts/oapps/oft/src/tests/oft_types/lock_unlock.rs +12 -8
- package/contracts/oapps/oft-core/integration-tests/setup.rs +8 -9
- package/contracts/oapps/oft-core/integration-tests/test_with_sml.rs +7 -6
- package/contracts/oapps/oft-core/integration-tests/utils.rs +5 -4
- package/contracts/oapps/oft-core/src/codec/oft_compose_msg_codec.rs +2 -2
- package/contracts/oapps/oft-core/src/codec/oft_msg_codec.rs +33 -37
- package/contracts/oapps/oft-core/src/errors.rs +2 -1
- package/contracts/oapps/oft-core/src/events.rs +6 -0
- package/contracts/oapps/oft-core/src/lib.rs +8 -4
- package/contracts/oapps/oft-core/src/oft_core.rs +205 -148
- package/contracts/oapps/oft-core/src/storage.rs +4 -2
- package/contracts/oapps/oft-core/src/tests/test_decimals.rs +2 -2
- package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +6 -6
- package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +7 -6
- package/contracts/oapps/oft-core/src/tests/test_oft_msg_codec.rs +11 -82
- package/contracts/oapps/oft-core/src/tests/test_quote_oft.rs +13 -13
- package/contracts/oapps/oft-core/src/tests/test_quote_send.rs +1 -1
- package/contracts/oapps/oft-core/src/tests/test_resolve_address.rs +2 -2
- package/contracts/oapps/oft-core/src/tests/test_send.rs +22 -22
- package/contracts/oapps/oft-core/src/tests/test_utils.rs +20 -22
- package/contracts/oapps/oft-core/src/utils.rs +12 -8
- package/contracts/sac-manager/Cargo.toml +25 -0
- package/contracts/sac-manager/src/errors.rs +18 -0
- package/contracts/sac-manager/src/extensions/mod.rs +6 -0
- package/contracts/sac-manager/src/extensions/redistribution.rs +109 -0
- package/contracts/sac-manager/src/extensions/supply_control/mod.rs +488 -0
- package/contracts/sac-manager/src/extensions/supply_control/rate_limit.rs +126 -0
- package/contracts/sac-manager/src/interfaces/mod.rs +3 -0
- package/contracts/sac-manager/src/interfaces/sac_manager.rs +52 -0
- package/contracts/sac-manager/src/lib.rs +23 -0
- package/contracts/sac-manager/src/sac_manager.rs +193 -0
- package/contracts/sac-manager/src/storage.rs +20 -0
- package/contracts/sac-manager/src/tests/mod.rs +14 -0
- package/contracts/sac-manager/src/tests/redistribution/mod.rs +1 -0
- package/contracts/sac-manager/src/tests/redistribution/redistribute_funds.rs +82 -0
- package/contracts/sac-manager/src/tests/sac_manager/admin_mint.rs +206 -0
- package/contracts/sac-manager/src/tests/sac_manager/burn.rs +215 -0
- package/contracts/sac-manager/src/tests/sac_manager/clawback.rs +209 -0
- package/contracts/sac-manager/src/tests/sac_manager/mint.rs +252 -0
- package/contracts/sac-manager/src/tests/sac_manager/mod.rs +9 -0
- package/contracts/sac-manager/src/tests/sac_manager/set_admin.rs +36 -0
- package/contracts/sac-manager/src/tests/sac_manager/set_authorized.rs +43 -0
- package/contracts/sac-manager/src/tests/sac_manager/set_oft_address.rs +47 -0
- package/contracts/sac-manager/src/tests/sac_manager/test_helper.rs +75 -0
- package/contracts/sac-manager/src/tests/sac_manager/view_functions.rs +60 -0
- package/contracts/sac-manager/src/tests/supply_control/enumerable_set.rs +256 -0
- package/contracts/sac-manager/src/tests/supply_control/mod.rs +8 -0
- package/contracts/sac-manager/src/tests/supply_control/refill.rs +90 -0
- package/contracts/sac-manager/src/tests/supply_control/set_mint_whitelist.rs +245 -0
- package/contracts/sac-manager/src/tests/supply_control/set_supply_controller.rs +267 -0
- package/contracts/sac-manager/src/tests/supply_control/set_supply_controller_manager.rs +122 -0
- package/contracts/sac-manager/src/tests/supply_control/test_helper.rs +38 -0
- package/contracts/sac-manager/src/tests/supply_control/update_allow_any_mint_burn.rs +114 -0
- package/contracts/sac-manager/src/tests/supply_control/update_limit_config.rs +257 -0
- package/contracts/sac-manager/src/tests/test_helper.rs +190 -0
- package/contracts/upgrader/src/lib.rs +2 -1
- package/contracts/utils/src/errors.rs +0 -1
- package/contracts/utils/src/tests/upgradeable.rs +0 -66
- package/contracts/utils/src/upgradeable.rs +0 -18
- package/contracts/workers/dvn/src/dvn.rs +2 -2
- package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
- package/contracts/workers/dvn/src/lib.rs +2 -1
- package/contracts/workers/dvn-fee-lib/src/lib.rs +3 -1
- package/contracts/workers/executor/src/auth.rs +42 -26
- package/contracts/workers/executor/src/executor.rs +28 -3
- package/contracts/workers/executor/src/lib.rs +4 -2
- package/contracts/workers/executor/src/storage.rs +21 -1
- package/contracts/workers/executor/src/tests/auth.rs +64 -20
- package/contracts/workers/executor/src/tests/executor.rs +1 -1
- package/contracts/workers/executor/src/tests/setup.rs +18 -0
- package/contracts/workers/executor-fee-lib/src/lib.rs +4 -1
- package/contracts/workers/executor-helper/src/executor_helper.rs +24 -10
- package/contracts/workers/executor-helper/src/tests/setup.rs +147 -34
- package/contracts/workers/price-feed/src/lib.rs +3 -1
- package/contracts/workers/worker/src/lib.rs +2 -1
- package/contracts/workers/worker/src/worker.rs +31 -17
- package/docs/oapp-guide.md +17 -8
- package/docs/oft-guide.md +3 -3
- package/package.json +3 -3
- package/sdk/.turbo/turbo-test.log +512 -351
- package/sdk/dist/generated/bml.d.ts +3 -9
- package/sdk/dist/generated/bml.js +6 -7
- package/sdk/dist/generated/counter.d.ts +22 -28
- package/sdk/dist/generated/counter.js +11 -12
- package/sdk/dist/generated/dvn.d.ts +36 -54
- package/sdk/dist/generated/dvn.js +10 -15
- package/sdk/dist/generated/dvn_fee_lib.d.ts +3 -21
- package/sdk/dist/generated/dvn_fee_lib.js +6 -11
- package/sdk/dist/generated/endpoint.d.ts +3 -9
- package/sdk/dist/generated/endpoint.js +6 -7
- package/sdk/dist/generated/executor.d.ts +80 -54
- package/sdk/dist/generated/executor.js +16 -16
- package/sdk/dist/generated/executor_fee_lib.d.ts +3 -21
- package/sdk/dist/generated/executor_fee_lib.js +6 -11
- package/sdk/dist/generated/executor_helper.d.ts +36 -42
- package/sdk/dist/generated/executor_helper.js +9 -10
- package/sdk/dist/generated/layerzero_view.d.ts +20 -32
- package/sdk/dist/generated/layerzero_view.js +25 -26
- package/sdk/dist/generated/oft.d.ts +147 -79
- package/sdk/dist/generated/oft.js +47 -54
- package/sdk/dist/generated/price_feed.d.ts +20 -38
- package/sdk/dist/generated/price_feed.js +15 -20
- package/sdk/dist/generated/sac_manager.d.ts +1309 -0
- package/sdk/dist/generated/sac_manager.js +484 -0
- package/sdk/dist/generated/sml.d.ts +3 -9
- package/sdk/dist/generated/sml.js +6 -7
- package/sdk/dist/generated/treasury.d.ts +3 -9
- package/sdk/dist/generated/treasury.js +8 -9
- package/sdk/dist/generated/uln302.d.ts +20 -20
- package/sdk/dist/generated/uln302.js +25 -22
- package/sdk/dist/generated/upgrader.d.ts +3 -9
- package/sdk/dist/generated/upgrader.js +6 -7
- package/sdk/dist/index.d.ts +1 -0
- package/sdk/dist/index.js +1 -0
- package/sdk/package.json +1 -1
- package/sdk/src/index.ts +1 -0
- package/sdk/test/oft-sml.test.ts +7 -5
- package/sdk/test/sac-manager-redistribution.test.ts +578 -0
- package/sdk/test/suites/globalSetup.ts +11 -6
- package/sdk/test/test_data/test_upgradeable_dvn.wasm +0 -0
- package/sdk/test/upgrader.test.ts +75 -202
- package/sdk/test/utils.ts +40 -0
- package/tools/ts-bindings-gen/src/main.rs +1 -0
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
use endpoint_v2::{
|
|
2
|
-
util::{build_payload, keccak256},
|
|
3
|
-
OutboundPacket,
|
|
4
|
-
};
|
|
1
|
+
use endpoint_v2::{util, OutboundPacket};
|
|
5
2
|
use soroban_sdk::{assert_with_error, Bytes, BytesN, Env};
|
|
6
3
|
use utils::{buffer_reader::BufferReader, buffer_writer::BufferWriter};
|
|
7
4
|
|
|
@@ -88,10 +85,10 @@ pub fn decode_packet_header(env: &Env, encoded_header: &Bytes) -> PacketHeader {
|
|
|
88
85
|
|
|
89
86
|
/// Returns the payload (GUID + message) from an outbound packet.
|
|
90
87
|
pub fn payload(env: &Env, packet: &OutboundPacket) -> Bytes {
|
|
91
|
-
build_payload(env, &packet.guid, &packet.message)
|
|
88
|
+
util::build_payload(env, &packet.guid, &packet.message)
|
|
92
89
|
}
|
|
93
90
|
|
|
94
91
|
/// Returns the keccak256 hash of the packet payload.
|
|
95
92
|
pub fn payload_hash(env: &Env, packet: &OutboundPacket) -> BytesN<32> {
|
|
96
|
-
keccak256(env, &payload(env, packet))
|
|
93
|
+
util::keccak256(env, &payload(env, packet))
|
|
97
94
|
}
|
package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs
CHANGED
|
@@ -115,6 +115,16 @@ fn test_extract_type_3_options_interleaved_executor_and_dvn_keeps_executor_order
|
|
|
115
115
|
assert_eq!(reader.remaining_len(), 0);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
#[test]
|
|
119
|
+
#[should_panic(expected = "Error(Contract, #1114)")] // WorkerOptionsError::InvalidOptions
|
|
120
|
+
fn test_extract_type_3_options_rejects_zero_option_size() {
|
|
121
|
+
let env = Env::default();
|
|
122
|
+
// worker_id = 1 (executor) + option_size = 0 (invalid)
|
|
123
|
+
let body = Bytes::from_slice(&env, &hex!("010000"));
|
|
124
|
+
let mut reader = BufferReader::new(&body);
|
|
125
|
+
extract_type_3_options(&env, &mut reader);
|
|
126
|
+
}
|
|
127
|
+
|
|
118
128
|
#[test]
|
|
119
129
|
#[should_panic(expected = "Error(Contract, #1115)")] // WorkerOptionsError::InvalidWorkerId
|
|
120
130
|
fn test_extract_type_3_options_rejects_unknown_worker_id() {
|
|
@@ -15,7 +15,7 @@ pub const DVN_WORKER_ID: u8 = 2;
|
|
|
15
15
|
pub const EXECUTOR_OPTION_TYPE_LZRECEIVE: u8 = 1;
|
|
16
16
|
pub const EXECUTOR_OPTION_TYPE_NATIVE_DROP: u8 = 2;
|
|
17
17
|
|
|
18
|
-
// DVN option byte offset
|
|
18
|
+
// DVN option byte offset for the dvn_idx field after the worker_id and option_size fields
|
|
19
19
|
pub const DVN_IDX_OFFSET: u32 = 3;
|
|
20
20
|
|
|
21
21
|
/// Splits worker options into separate executor and DVN option collections.
|
|
@@ -70,6 +70,7 @@ pub fn extract_type_3_options(env: &Env, options_reader: &mut BufferReader) -> (
|
|
|
70
70
|
while options_reader.remaining_len() > 0 {
|
|
71
71
|
let worker_id = options_reader.read_u8();
|
|
72
72
|
let option_size = options_reader.read_u16() as u32;
|
|
73
|
+
assert_with_error!(env, option_size > 0, WorkerOptionsError::InvalidOptions);
|
|
73
74
|
|
|
74
75
|
// Rewind to the start of the current option and read the complete option bytes
|
|
75
76
|
// 3 bytes for worker_id (1) + option_size (2)
|
|
@@ -147,8 +148,11 @@ pub fn convert_legacy_options(env: &Env, options: &mut BufferReader, option_type
|
|
|
147
148
|
///
|
|
148
149
|
/// Searches for existing DVN options with the same index and concatenates them,
|
|
149
150
|
/// or creates a new entry if this is the first option for this DVN index.
|
|
151
|
+
///
|
|
152
|
+
/// DVN option_bytes layout: `[worker_id: u8][option_size: u16][dvn_idx: u8][dvn_option_data: bytes]`
|
|
153
|
+
/// The dvn_idx at byte offset 3 (DVN_IDX_OFFSET) identifies which DVN this option belongs to.
|
|
150
154
|
fn append_dvn_option(env: &Env, dvn_options: &mut Map<u32, Bytes>, option_bytes: Bytes) {
|
|
151
|
-
let dvn_idx = option_bytes.get(DVN_IDX_OFFSET).
|
|
155
|
+
let dvn_idx = option_bytes.get(DVN_IDX_OFFSET).unwrap_or_panic(env, WorkerOptionsError::InvalidOptions) as u32;
|
|
152
156
|
let mut existing = dvn_options.get(dvn_idx).unwrap_or(bytes!(env));
|
|
153
157
|
existing.append(&option_bytes);
|
|
154
158
|
dvn_options.set(dvn_idx, existing);
|
|
@@ -6,15 +6,15 @@ use soroban_sdk::{contractclient, Address, Env};
|
|
|
6
6
|
/// This allows for custom fee calculation logic when users opt to pay fees in ZRO.
|
|
7
7
|
#[contractclient(name = "ZroFeeLibClient")]
|
|
8
8
|
pub trait IZroFeeLib {
|
|
9
|
-
/// Get the treasury fee in ZRO tokens based on the
|
|
9
|
+
/// Get the treasury fee in ZRO tokens based on the total native fee.
|
|
10
10
|
///
|
|
11
11
|
/// # Arguments
|
|
12
12
|
/// * `sender` - The sender OApp address
|
|
13
13
|
/// * `dst_eid` - The destination endpoint ID
|
|
14
|
-
/// * `
|
|
14
|
+
/// * `total_native_fee` - The total native fee charged to the sender
|
|
15
15
|
/// * `native_treasury_fee` - The treasury fee in native tokens
|
|
16
16
|
///
|
|
17
17
|
/// # Returns
|
|
18
18
|
/// The amount of ZRO tokens to be paid
|
|
19
|
-
fn get_fee(env: &Env, sender: &Address, dst_eid: u32,
|
|
19
|
+
fn get_fee(env: &Env, sender: &Address, dst_eid: u32, total_native_fee: i128, native_treasury_fee: i128) -> i128;
|
|
20
20
|
}
|
|
@@ -107,7 +107,7 @@ impl<'a> TestSetup<'a> {
|
|
|
107
107
|
|
|
108
108
|
/// Gets the token balance of an address
|
|
109
109
|
pub fn get_token_balance(&self, token: &Address, address: &Address) -> i128 {
|
|
110
|
-
let token_client = token::
|
|
110
|
+
let token_client = token::TokenClient::new(&self.env, token);
|
|
111
111
|
token_client.balance(address)
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -6,7 +6,7 @@ use crate::{
|
|
|
6
6
|
};
|
|
7
7
|
use common_macros::{contract_impl, lz_contract, only_auth};
|
|
8
8
|
use message_lib_common::interfaces::ILayerZeroTreasury;
|
|
9
|
-
use soroban_sdk::{assert_with_error, token::
|
|
9
|
+
use soroban_sdk::{assert_with_error, token::TokenClient, Address, Env};
|
|
10
10
|
use utils::option_ext::OptionExt;
|
|
11
11
|
|
|
12
12
|
/// Denominator for basis point calculations (10000 = 100%).
|
|
@@ -66,7 +66,7 @@ impl Treasury {
|
|
|
66
66
|
/// * `amount` - The amount to withdraw (must be positive)
|
|
67
67
|
#[only_auth]
|
|
68
68
|
pub fn withdraw_token(env: &Env, token: &Address, to: &Address, amount: i128) {
|
|
69
|
-
|
|
69
|
+
TokenClient::new(env, token).transfer(&env.current_contract_address(), to, &amount);
|
|
70
70
|
TokenWithdrawn { token: token.clone(), to: to.clone(), amount }.publish(env);
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -117,15 +117,18 @@ impl ILayerZeroTreasury for Treasury {
|
|
|
117
117
|
fn get_fee(env: &Env, sender: &Address, dst_eid: u32, total_native_fee: i128, pay_in_zro: bool) -> i128 {
|
|
118
118
|
assert_with_error!(env, total_native_fee >= 0, TreasuryError::InvalidTotalNativeFee);
|
|
119
119
|
|
|
120
|
+
// If fee collection is disabled, return 0
|
|
120
121
|
if !Self::fee_enabled(env) {
|
|
121
122
|
return 0;
|
|
122
123
|
}
|
|
123
124
|
|
|
125
|
+
// If paying in native, calculate and return the native treasury fee
|
|
124
126
|
let native_treasury_fee = Self::calculate_native_fee(env, total_native_fee);
|
|
125
127
|
if !pay_in_zro {
|
|
126
128
|
return native_treasury_fee;
|
|
127
129
|
}
|
|
128
130
|
|
|
131
|
+
// If paying in ZRO, quote the ZRO fee from the ZRO fee library
|
|
129
132
|
let zro_fee =
|
|
130
133
|
Self::expect_zro_fee_lib_client(env).get_fee(sender, &dst_eid, &total_native_fee, &native_treasury_fee);
|
|
131
134
|
assert_with_error!(env, zro_fee >= 0, TreasuryError::InvalidZroFee);
|
|
@@ -20,6 +20,8 @@ pub enum Uln302Error {
|
|
|
20
20
|
InvalidConfirmations,
|
|
21
21
|
/// Packet header destination EID does not match this endpoint's EID
|
|
22
22
|
InvalidEID,
|
|
23
|
+
/// Fee returned by a worker or treasury is negative
|
|
24
|
+
InvalidFee,
|
|
23
25
|
/// Message size exceeds executor's configured maximum
|
|
24
26
|
InvalidMessageSize,
|
|
25
27
|
/// Optional DVNs count exceeds maximum allowed (127)
|
|
@@ -12,7 +12,7 @@ pub struct ExecutorConfigSet {
|
|
|
12
12
|
pub sender: Address,
|
|
13
13
|
#[topic]
|
|
14
14
|
pub dst_eid: u32,
|
|
15
|
-
pub config: OAppExecutorConfig
|
|
15
|
+
pub config: Option<OAppExecutorConfig>,
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
#[contractevent]
|
|
@@ -22,7 +22,7 @@ pub struct SendUlnConfigSet {
|
|
|
22
22
|
pub sender: Address,
|
|
23
23
|
#[topic]
|
|
24
24
|
pub dst_eid: u32,
|
|
25
|
-
pub config: OAppUlnConfig
|
|
25
|
+
pub config: Option<OAppUlnConfig>,
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
#[contractevent]
|
|
@@ -32,7 +32,7 @@ pub struct ReceiveUlnConfigSet {
|
|
|
32
32
|
pub receiver: Address,
|
|
33
33
|
#[topic]
|
|
34
34
|
pub src_eid: u32,
|
|
35
|
-
pub config: OAppUlnConfig
|
|
35
|
+
pub config: Option<OAppUlnConfig>,
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
#[contractevent]
|
|
@@ -6,6 +6,10 @@ use soroban_sdk::{contractclient, Address, Bytes, BytesN, Env, Vec};
|
|
|
6
6
|
/// Handles DVN verification and message commitment on the receiving chain.
|
|
7
7
|
#[contractclient(name = "ReceiveUln302Client")]
|
|
8
8
|
pub trait IReceiveUln302 {
|
|
9
|
+
// ============================================================================================
|
|
10
|
+
// Verification Functions
|
|
11
|
+
// ============================================================================================
|
|
12
|
+
|
|
9
13
|
/// Called by a DVN to verify a message with a specific number of confirmations.
|
|
10
14
|
///
|
|
11
15
|
/// # Arguments
|
|
@@ -46,6 +50,10 @@ pub trait IReceiveUln302 {
|
|
|
46
50
|
/// * `payload_hash` - The hash of the message payload
|
|
47
51
|
fn commit_verification(env: &Env, packet_header: &Bytes, payload_hash: &BytesN<32>);
|
|
48
52
|
|
|
53
|
+
// ============================================================================================
|
|
54
|
+
// Configuration Functions
|
|
55
|
+
// ============================================================================================
|
|
56
|
+
|
|
49
57
|
/// Sets default receive ULN configurations for multiple source endpoints.
|
|
50
58
|
///
|
|
51
59
|
/// # Arguments
|
|
@@ -41,7 +41,7 @@ impl IReceiveUln302 for Uln302 {
|
|
|
41
41
|
/// (all required DVNs + optional DVN threshold). Once verified, cleans up DVN confirmation
|
|
42
42
|
/// storage and calls the endpoint to mark the message as verified and executable.
|
|
43
43
|
fn commit_verification(env: &Env, packet_header: &Bytes, payload_hash: &BytesN<32>) {
|
|
44
|
-
let (header, uln_config) = Self::decode_packet_header_with_config(env, packet_header);
|
|
44
|
+
let (header, uln_config, receiver) = Self::decode_packet_header_with_config(env, packet_header);
|
|
45
45
|
let header_hash = util::keccak256(env, packet_header);
|
|
46
46
|
|
|
47
47
|
// check if the message is verifiable
|
|
@@ -60,7 +60,7 @@ impl IReceiveUln302 for Uln302 {
|
|
|
60
60
|
LayerZeroEndpointV2Client::new(env, &Self::endpoint(env)).verify(
|
|
61
61
|
&env.current_contract_address(),
|
|
62
62
|
&Origin { src_eid: header.src_eid, sender: header.sender, nonce: header.nonce },
|
|
63
|
-
&
|
|
63
|
+
&receiver,
|
|
64
64
|
payload_hash,
|
|
65
65
|
);
|
|
66
66
|
}
|
|
@@ -92,7 +92,7 @@ impl IReceiveUln302 for Uln302 {
|
|
|
92
92
|
|
|
93
93
|
/// Checks if a message has been sufficiently verified by DVNs and is ready to commit.
|
|
94
94
|
fn verifiable(env: &Env, packet_header: &Bytes, payload_hash: &BytesN<32>) -> bool {
|
|
95
|
-
let (_, uln_config) = Self::decode_packet_header_with_config(env, packet_header);
|
|
95
|
+
let (_, uln_config, _) = Self::decode_packet_header_with_config(env, packet_header);
|
|
96
96
|
Self::verifiable_internal(env, &uln_config, &util::keccak256(env, packet_header), payload_hash)
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -124,13 +124,15 @@ impl IReceiveUln302 for Uln302 {
|
|
|
124
124
|
// ============================================================================================
|
|
125
125
|
|
|
126
126
|
impl Uln302 {
|
|
127
|
-
/// Sets OApp-specific receive ULN config.
|
|
127
|
+
/// Sets or removes OApp-specific receive ULN config.
|
|
128
128
|
///
|
|
129
|
+
/// If `config` is `None`, the OApp-specific config is removed (falling back to defaults).
|
|
129
130
|
/// Panics if the final effective config is invalid.
|
|
130
|
-
pub(super) fn set_receive_uln_config(env: &Env, receiver: &Address, src_eid: u32, config: &OAppUlnConfig) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
pub(super) fn set_receive_uln_config(env: &Env, receiver: &Address, src_eid: u32, config: &Option<OAppUlnConfig>) {
|
|
132
|
+
if let Some(c) = config {
|
|
133
|
+
c.validate_oapp_config(env);
|
|
134
|
+
}
|
|
135
|
+
UlnStorage::set_or_remove_oapp_receive_uln_configs(env, receiver, src_eid, config);
|
|
134
136
|
// validate the config by getting the effective config
|
|
135
137
|
let _ = Self::effective_receive_uln_config(env, receiver, src_eid);
|
|
136
138
|
|
|
@@ -141,8 +143,8 @@ impl Uln302 {
|
|
|
141
143
|
// Verification Helpers Functions
|
|
142
144
|
// ============================================================================================
|
|
143
145
|
|
|
144
|
-
/// Decodes packet header and returns header
|
|
145
|
-
fn decode_packet_header_with_config(env: &Env, packet_header: &Bytes) -> (PacketHeader, UlnConfig) {
|
|
146
|
+
/// Decodes packet header and returns header, effective ULN config, and receiver address.
|
|
147
|
+
fn decode_packet_header_with_config(env: &Env, packet_header: &Bytes) -> (PacketHeader, UlnConfig, Address) {
|
|
146
148
|
let header = packet_codec_v1::decode_packet_header(env, packet_header);
|
|
147
149
|
assert_with_error!(
|
|
148
150
|
env,
|
|
@@ -150,10 +152,11 @@ impl Uln302 {
|
|
|
150
152
|
Uln302Error::InvalidEID
|
|
151
153
|
);
|
|
152
154
|
|
|
155
|
+
// convert the receiver address from BytesN<32> to ContractAddress
|
|
153
156
|
let receiver = Address::from_payload(env, AddressPayload::ContractIdHash(header.receiver.clone()));
|
|
154
157
|
let uln_config = Self::effective_receive_uln_config(env, &receiver, header.src_eid);
|
|
155
158
|
|
|
156
|
-
(header, uln_config)
|
|
159
|
+
(header, uln_config, receiver)
|
|
157
160
|
}
|
|
158
161
|
|
|
159
162
|
/// Checks if all required DVNs verified and optional DVN threshold is met.
|
|
@@ -183,8 +186,8 @@ impl Uln302 {
|
|
|
183
186
|
dvn: &Address,
|
|
184
187
|
header_hash: &BytesN<32>,
|
|
185
188
|
payload_hash: &BytesN<32>,
|
|
186
|
-
|
|
189
|
+
required_confirmations: u64,
|
|
187
190
|
) -> bool {
|
|
188
|
-
Self::confirmations(env, dvn, header_hash, payload_hash).map(|c| c >=
|
|
191
|
+
Self::confirmations(env, dvn, header_hash, payload_hash).map(|c| c >= required_confirmations).unwrap_or(false)
|
|
189
192
|
}
|
|
190
193
|
}
|
|
@@ -45,8 +45,7 @@ impl ISendLib for Uln302 {
|
|
|
45
45
|
|
|
46
46
|
// Treasury fee
|
|
47
47
|
let workers_fee = executor_fee + dvns_fee;
|
|
48
|
-
let
|
|
49
|
-
let treasury_fee = treasury_client.get_fee(&packet.sender, &packet.dst_eid, &workers_fee, &pay_in_zro);
|
|
48
|
+
let (_, treasury_fee) = Self::quote_treasury(env, &packet.sender, packet.dst_eid, &workers_fee, &pay_in_zro);
|
|
50
49
|
|
|
51
50
|
if pay_in_zro {
|
|
52
51
|
MessagingFee { native_fee: workers_fee, zro_fee: treasury_fee }
|
|
@@ -91,13 +90,8 @@ impl ISendLib for Uln302 {
|
|
|
91
90
|
|
|
92
91
|
// Treasury fee
|
|
93
92
|
let total_worker_fee = native_fee_recipients.iter().map(|fee| fee.amount).sum();
|
|
94
|
-
let treasury_addr =
|
|
95
|
-
|
|
96
|
-
&packet.sender,
|
|
97
|
-
&packet.dst_eid,
|
|
98
|
-
&total_worker_fee,
|
|
99
|
-
&pay_in_zro,
|
|
100
|
-
);
|
|
93
|
+
let (treasury_addr, treasury_fee) =
|
|
94
|
+
Self::quote_treasury(env, &packet.sender, packet.dst_eid, &total_worker_fee, &pay_in_zro);
|
|
101
95
|
|
|
102
96
|
// Handle ZRO fee recipients
|
|
103
97
|
let mut zro_fee_recipients = vec![env];
|
|
@@ -207,19 +201,23 @@ impl ISendUln302 for Uln302 {
|
|
|
207
201
|
// ==============================================================================
|
|
208
202
|
|
|
209
203
|
impl Uln302 {
|
|
210
|
-
/// Sets OApp-specific executor configuration for a destination endpoint.
|
|
211
|
-
|
|
212
|
-
|
|
204
|
+
/// Sets or removes OApp-specific executor configuration for a destination endpoint.
|
|
205
|
+
///
|
|
206
|
+
/// If `config` is `None`, the OApp-specific config is removed (falling back to defaults).
|
|
207
|
+
pub(super) fn set_executor_config(env: &Env, sender: &Address, dst_eid: u32, config: &Option<OAppExecutorConfig>) {
|
|
208
|
+
UlnStorage::set_or_remove_oapp_executor_configs(env, sender, dst_eid, config);
|
|
213
209
|
ExecutorConfigSet { sender: sender.clone(), dst_eid, config: config.clone() }.publish(env);
|
|
214
210
|
}
|
|
215
211
|
|
|
216
|
-
/// Sets OApp-specific send ULN configuration for a destination endpoint.
|
|
212
|
+
/// Sets or removes OApp-specific send ULN configuration for a destination endpoint.
|
|
217
213
|
///
|
|
214
|
+
/// If `config` is `None`, the OApp-specific config is removed (falling back to defaults).
|
|
218
215
|
/// Panics if the final effective config is invalid.
|
|
219
|
-
pub(super) fn set_send_uln_config(env: &Env, sender: &Address, dst_eid: u32, config: &OAppUlnConfig) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
216
|
+
pub(super) fn set_send_uln_config(env: &Env, sender: &Address, dst_eid: u32, config: &Option<OAppUlnConfig>) {
|
|
217
|
+
if let Some(c) = config {
|
|
218
|
+
c.validate_oapp_config(env);
|
|
219
|
+
}
|
|
220
|
+
UlnStorage::set_or_remove_oapp_send_uln_configs(env, sender, dst_eid, config);
|
|
223
221
|
// validate the config by getting the effective config
|
|
224
222
|
let _ = Self::effective_send_uln_config(env, sender, dst_eid);
|
|
225
223
|
|
|
@@ -231,13 +229,15 @@ impl Uln302 {
|
|
|
231
229
|
// ============================================================================================
|
|
232
230
|
|
|
233
231
|
/// Quotes the executor fee for message execution.
|
|
234
|
-
fn quote_executor(env: &Env, sender: &Address, dst_eid: u32,
|
|
232
|
+
fn quote_executor(env: &Env, sender: &Address, dst_eid: u32, message_size: u32, options: &Bytes) -> i128 {
|
|
235
233
|
// Get the effective executor config and validate message size
|
|
236
234
|
let executor_config = Self::effective_executor_config(env, sender, dst_eid);
|
|
237
|
-
assert_with_error!(env,
|
|
235
|
+
assert_with_error!(env, message_size <= executor_config.max_message_size, Uln302Error::InvalidMessageSize);
|
|
238
236
|
|
|
239
237
|
let executor_client = LayerZeroExecutorClient::new(env, &executor_config.executor);
|
|
240
|
-
executor_client.get_fee(&env.current_contract_address(), sender, &dst_eid, &
|
|
238
|
+
let fee = executor_client.get_fee(&env.current_contract_address(), sender, &dst_eid, &message_size, options);
|
|
239
|
+
assert_with_error!(env, fee >= 0, Uln302Error::InvalidFee);
|
|
240
|
+
fee
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
/// Quotes the total DVN fees for message verification.
|
|
@@ -260,11 +260,36 @@ impl Uln302 {
|
|
|
260
260
|
.map(|(idx, dvn_addr)| {
|
|
261
261
|
let dvn_client = LayerZeroDVNClient::new(env, &dvn_addr);
|
|
262
262
|
let dvn_opts = dvn_options.get(idx as u32).unwrap_or(bytes!(env));
|
|
263
|
-
dvn_client.get_fee(
|
|
263
|
+
let fee = dvn_client.get_fee(
|
|
264
|
+
&send_lib,
|
|
265
|
+
sender,
|
|
266
|
+
&dst_eid,
|
|
267
|
+
packet_header,
|
|
268
|
+
payload_hash,
|
|
269
|
+
&confirmations,
|
|
270
|
+
&dvn_opts,
|
|
271
|
+
);
|
|
272
|
+
assert_with_error!(env, fee >= 0, Uln302Error::InvalidFee);
|
|
273
|
+
fee
|
|
264
274
|
})
|
|
265
275
|
.sum()
|
|
266
276
|
}
|
|
267
277
|
|
|
278
|
+
/// Quotes the treasury fee for the protocol.
|
|
279
|
+
fn quote_treasury(
|
|
280
|
+
env: &Env,
|
|
281
|
+
sender: &Address,
|
|
282
|
+
dst_eid: u32,
|
|
283
|
+
workers_fee: &i128,
|
|
284
|
+
pay_in_zro: &bool,
|
|
285
|
+
) -> (Address, i128) {
|
|
286
|
+
let treasury_addr = Self::treasury(env);
|
|
287
|
+
let treasury_fee =
|
|
288
|
+
LayerZeroTreasuryClient::new(env, &treasury_addr).get_fee(sender, &dst_eid, workers_fee, pay_in_zro);
|
|
289
|
+
assert_with_error!(env, treasury_fee >= 0, Uln302Error::InvalidFee);
|
|
290
|
+
(treasury_addr, treasury_fee)
|
|
291
|
+
}
|
|
292
|
+
|
|
268
293
|
// ============================================================================================
|
|
269
294
|
// Assign Job Functions
|
|
270
295
|
// ============================================================================================
|
|
@@ -275,16 +300,17 @@ impl Uln302 {
|
|
|
275
300
|
guid: &BytesN<32>,
|
|
276
301
|
sender: &Address,
|
|
277
302
|
dst_eid: u32,
|
|
278
|
-
|
|
303
|
+
message_size: u32,
|
|
279
304
|
options: &Bytes,
|
|
280
305
|
) -> FeeRecipient {
|
|
281
306
|
// Get the effective executor config and validate message size
|
|
282
307
|
let executor_config = Self::effective_executor_config(env, sender, dst_eid);
|
|
283
|
-
assert_with_error!(env,
|
|
308
|
+
assert_with_error!(env, message_size <= executor_config.max_message_size, Uln302Error::InvalidMessageSize);
|
|
284
309
|
|
|
285
310
|
let executor_client = LayerZeroExecutorClient::new(env, &executor_config.executor);
|
|
286
311
|
let recipient =
|
|
287
|
-
executor_client.assign_job(&env.current_contract_address(), sender, &dst_eid, &
|
|
312
|
+
executor_client.assign_job(&env.current_contract_address(), sender, &dst_eid, &message_size, options);
|
|
313
|
+
assert_with_error!(env, recipient.amount >= 0, Uln302Error::InvalidFee);
|
|
288
314
|
|
|
289
315
|
ExecutorFeePaid { guid: guid.clone(), executor: executor_client.address.clone(), fee: recipient.clone() }
|
|
290
316
|
.publish(env);
|
|
@@ -319,6 +345,7 @@ impl Uln302 {
|
|
|
319
345
|
&confirmations,
|
|
320
346
|
&dvn_opts,
|
|
321
347
|
);
|
|
348
|
+
assert_with_error!(env, dvn_fee_recipient.amount >= 0, Uln302Error::InvalidFee);
|
|
322
349
|
fees.push_back(dvn_fee_recipient);
|
|
323
350
|
dvns.push_back(dvn_addr);
|
|
324
351
|
}
|
|
@@ -5,11 +5,11 @@ use soroban_sdk::{Address, BytesN};
|
|
|
5
5
|
/// Storage for the Uln302 message library.
|
|
6
6
|
#[storage]
|
|
7
7
|
pub enum UlnStorage {
|
|
8
|
-
/// The endpoint address (set in constructor)
|
|
8
|
+
/// The endpoint address (immutable, set once in constructor)
|
|
9
9
|
#[instance(Address)]
|
|
10
10
|
Endpoint,
|
|
11
11
|
|
|
12
|
-
/// The treasury address for fee collection (set in constructor)
|
|
12
|
+
/// The treasury address for fee collection (immutable, set once in constructor)
|
|
13
13
|
#[instance(Address)]
|
|
14
14
|
Treasury,
|
|
15
15
|
|
package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs
CHANGED
|
@@ -60,7 +60,7 @@ fn test_effective_receive_uln_config_with_custom_config() {
|
|
|
60
60
|
assert_eq_event(
|
|
61
61
|
&env,
|
|
62
62
|
&uln302.address,
|
|
63
|
-
ReceiveUlnConfigSet { config: custom_config.clone(), receiver: oapp.clone(), src_eid: eid },
|
|
63
|
+
ReceiveUlnConfigSet { config: Some(custom_config.clone()), receiver: oapp.clone(), src_eid: eid },
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
let config = uln302.effective_receive_uln_config(&oapp, &eid);
|
|
@@ -100,3 +100,47 @@ fn test_effective_receive_uln_config_must_have_at_least_one_dvn() {
|
|
|
100
100
|
let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, ¶ms);
|
|
101
101
|
assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::UlnAtLeastOneDVN.into());
|
|
102
102
|
}
|
|
103
|
+
|
|
104
|
+
#[test]
|
|
105
|
+
fn test_remove_receive_uln_config_by_setting_none() {
|
|
106
|
+
let setup = setup();
|
|
107
|
+
|
|
108
|
+
let default_config = UlnConfig::generate(&setup.env, 15, 1, 2, 1);
|
|
109
|
+
let eid = 101;
|
|
110
|
+
|
|
111
|
+
setup.set_default_configs(eid, default_config.clone());
|
|
112
|
+
|
|
113
|
+
let TestSetup { env, uln302, endpoint, .. } = setup;
|
|
114
|
+
|
|
115
|
+
let oapp = Address::generate(&env);
|
|
116
|
+
|
|
117
|
+
// Step 1: Set a custom receive ULN config
|
|
118
|
+
let custom_config = OAppUlnConfig {
|
|
119
|
+
use_default_confirmations: true,
|
|
120
|
+
use_default_required_dvns: false,
|
|
121
|
+
use_default_optional_dvns: false,
|
|
122
|
+
uln_config: UlnConfig::generate(&env, 0, 3, 1, 1),
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
let config_bytes = custom_config.clone().to_xdr(&env);
|
|
126
|
+
let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_RECEIVE_ULN, config: config_bytes }];
|
|
127
|
+
endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, ¶ms);
|
|
128
|
+
|
|
129
|
+
// Verify custom config is applied
|
|
130
|
+
assert!(uln302.oapp_receive_uln_config(&oapp, &eid).is_some());
|
|
131
|
+
let config = uln302.effective_receive_uln_config(&oapp, &eid);
|
|
132
|
+
assert_eq!(config.required_dvns, custom_config.uln_config.required_dvns);
|
|
133
|
+
|
|
134
|
+
// Step 2: Remove the custom config by setting None
|
|
135
|
+
let none_config: Option<OAppUlnConfig> = None;
|
|
136
|
+
let config_bytes = none_config.to_xdr(&env);
|
|
137
|
+
let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_RECEIVE_ULN, config: config_bytes }];
|
|
138
|
+
endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, ¶ms);
|
|
139
|
+
|
|
140
|
+
// Verify the OApp-specific config is removed
|
|
141
|
+
assert_eq!(uln302.oapp_receive_uln_config(&oapp, &eid), None);
|
|
142
|
+
|
|
143
|
+
// Verify the effective config falls back to defaults
|
|
144
|
+
let config = uln302.effective_receive_uln_config(&oapp, &eid);
|
|
145
|
+
assert_eq!(config, default_config);
|
|
146
|
+
}
|
|
@@ -461,3 +461,66 @@ fn test_verifiable_partial_optional_verification() {
|
|
|
461
461
|
// Verifiable because threshold is met
|
|
462
462
|
assert!(receive_client.verifiable(&packet_header, &payload_hash));
|
|
463
463
|
}
|
|
464
|
+
|
|
465
|
+
#[test]
|
|
466
|
+
fn test_not_verifiable_required_verified_but_optional_threshold_not_met() {
|
|
467
|
+
let test_setup = setup();
|
|
468
|
+
let TestSetup { env, uln302, .. } = &test_setup;
|
|
469
|
+
|
|
470
|
+
let dvn1 = Address::generate(env);
|
|
471
|
+
let dvn2 = Address::generate(env);
|
|
472
|
+
let dvn3 = Address::generate(env);
|
|
473
|
+
let dvn4 = Address::generate(env);
|
|
474
|
+
let receiver = Address::generate(env);
|
|
475
|
+
|
|
476
|
+
// Set up config with 2 required DVNs and 2 optional DVNs with threshold of 2
|
|
477
|
+
let mut config = create_test_uln_config(env);
|
|
478
|
+
config.required_dvns = vec![env, dvn1.clone(), dvn2.clone()];
|
|
479
|
+
config.optional_dvns = vec![env, dvn3.clone(), dvn4.clone()];
|
|
480
|
+
config.optional_dvn_threshold = 2; // Need both optional DVNs
|
|
481
|
+
TestSetup::set_default_receive_uln_config(&test_setup, SRC_EID, config);
|
|
482
|
+
|
|
483
|
+
let packet_header = create_test_packet_header(env, &receiver);
|
|
484
|
+
let payload_hash = create_test_payload_hash(env);
|
|
485
|
+
|
|
486
|
+
let receive_client = ReceiveUln302Client::new(env, &uln302.address);
|
|
487
|
+
|
|
488
|
+
// Verify all required DVNs
|
|
489
|
+
env.mock_auths(&[MockAuth {
|
|
490
|
+
address: &dvn1,
|
|
491
|
+
invoke: &MockAuthInvoke {
|
|
492
|
+
contract: &uln302.address,
|
|
493
|
+
fn_name: "verify",
|
|
494
|
+
args: (&dvn1, &packet_header, &payload_hash, &CONFIRMATIONS).into_val(env),
|
|
495
|
+
sub_invokes: &[],
|
|
496
|
+
},
|
|
497
|
+
}]);
|
|
498
|
+
receive_client.verify(&dvn1, &packet_header, &payload_hash, &CONFIRMATIONS);
|
|
499
|
+
|
|
500
|
+
env.mock_auths(&[MockAuth {
|
|
501
|
+
address: &dvn2,
|
|
502
|
+
invoke: &MockAuthInvoke {
|
|
503
|
+
contract: &uln302.address,
|
|
504
|
+
fn_name: "verify",
|
|
505
|
+
args: (&dvn2, &packet_header, &payload_hash, &CONFIRMATIONS).into_val(env),
|
|
506
|
+
sub_invokes: &[],
|
|
507
|
+
},
|
|
508
|
+
}]);
|
|
509
|
+
receive_client.verify(&dvn2, &packet_header, &payload_hash, &CONFIRMATIONS);
|
|
510
|
+
|
|
511
|
+
// Verify only 1 optional DVN (need 2)
|
|
512
|
+
env.mock_auths(&[MockAuth {
|
|
513
|
+
address: &dvn3,
|
|
514
|
+
invoke: &MockAuthInvoke {
|
|
515
|
+
contract: &uln302.address,
|
|
516
|
+
fn_name: "verify",
|
|
517
|
+
args: (&dvn3, &packet_header, &payload_hash, &CONFIRMATIONS).into_val(env),
|
|
518
|
+
sub_invokes: &[],
|
|
519
|
+
},
|
|
520
|
+
}]);
|
|
521
|
+
receive_client.verify(&dvn3, &packet_header, &payload_hash, &CONFIRMATIONS);
|
|
522
|
+
// DVN4 doesn't verify
|
|
523
|
+
|
|
524
|
+
// Not verifiable because optional threshold (2) is not met (only 1 verified)
|
|
525
|
+
assert!(!receive_client.verifiable(&packet_header, &payload_hash));
|
|
526
|
+
}
|
|
@@ -7,7 +7,7 @@ use crate::{
|
|
|
7
7
|
uln302::CONFIG_TYPE_EXECUTOR,
|
|
8
8
|
};
|
|
9
9
|
use endpoint_v2::SetConfigParam;
|
|
10
|
-
use soroban_sdk::{log, testutils::Address as _, vec, xdr::ToXdr, Address, Env};
|
|
10
|
+
use soroban_sdk::{log, testutils::Address as _, vec, xdr::ToXdr, Address, Bytes, Env};
|
|
11
11
|
use utils::testing_utils::assert_eq_event;
|
|
12
12
|
|
|
13
13
|
#[test]
|
|
@@ -60,7 +60,7 @@ fn test_effective_executor_config_with_custom_executor() {
|
|
|
60
60
|
assert_eq_event(
|
|
61
61
|
&setup.env,
|
|
62
62
|
&setup.uln302.address,
|
|
63
|
-
ExecutorConfigSet { config: custom_config.clone(), dst_eid: eid, sender: oapp.clone() },
|
|
63
|
+
ExecutorConfigSet { config: Some(custom_config.clone()), dst_eid: eid, sender: oapp.clone() },
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
let config = setup.uln302.effective_executor_config(&oapp, &eid);
|
|
@@ -130,3 +130,48 @@ fn test_effective_executor_config_fully_custom() {
|
|
|
130
130
|
assert_eq!(config.executor, custom_executor);
|
|
131
131
|
assert_eq!(config.max_message_size, custom_config.max_message_size);
|
|
132
132
|
}
|
|
133
|
+
|
|
134
|
+
#[test]
|
|
135
|
+
fn test_remove_executor_config_by_setting_none() {
|
|
136
|
+
let setup = setup();
|
|
137
|
+
|
|
138
|
+
let eid = 102;
|
|
139
|
+
let default_executor = setup.register_executable_address();
|
|
140
|
+
let default_config = ExecutorConfig { max_message_size: 5000, executor: default_executor.clone() };
|
|
141
|
+
|
|
142
|
+
let default_uln_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
|
|
143
|
+
|
|
144
|
+
setup.set_default_executor_config(eid, default_config.clone());
|
|
145
|
+
setup.set_default_receive_uln_config(eid, default_uln_config.clone());
|
|
146
|
+
setup.set_default_send_uln_config(eid, default_uln_config.clone());
|
|
147
|
+
|
|
148
|
+
let oapp = Address::generate(&setup.env);
|
|
149
|
+
|
|
150
|
+
// Step 1: Set a custom executor config
|
|
151
|
+
let custom_executor = setup.register_executable_address();
|
|
152
|
+
let custom_config = OAppExecutorConfig { max_message_size: 8000, executor: Some(custom_executor.clone()) };
|
|
153
|
+
|
|
154
|
+
let config_bytes = custom_config.clone().to_xdr(&setup.env);
|
|
155
|
+
let params = vec![&setup.env, SetConfigParam { eid, config_type: CONFIG_TYPE_EXECUTOR, config: config_bytes }];
|
|
156
|
+
setup.endpoint.set_config(&Address::generate(&setup.env), &oapp, &setup.uln302.address, ¶ms);
|
|
157
|
+
|
|
158
|
+
// Verify custom config is applied
|
|
159
|
+
let config = setup.uln302.effective_executor_config(&oapp, &eid);
|
|
160
|
+
assert_eq!(config.executor, custom_executor);
|
|
161
|
+
assert_eq!(config.max_message_size, 8000);
|
|
162
|
+
assert!(setup.uln302.oapp_executor_config(&oapp, &eid).is_some());
|
|
163
|
+
|
|
164
|
+
// Step 2: Remove the custom config by setting None
|
|
165
|
+
let none_config: Option<OAppExecutorConfig> = None;
|
|
166
|
+
let config_bytes = none_config.to_xdr(&setup.env);
|
|
167
|
+
assert_eq!(config_bytes, Bytes::from_array(&setup.env, &[0, 0, 0, 1])); // ScVal::Void XDR encoding
|
|
168
|
+
let params = vec![&setup.env, SetConfigParam { eid, config_type: CONFIG_TYPE_EXECUTOR, config: config_bytes }];
|
|
169
|
+
setup.endpoint.set_config(&Address::generate(&setup.env), &oapp, &setup.uln302.address, ¶ms);
|
|
170
|
+
|
|
171
|
+
// Verify the OApp-specific config is removed
|
|
172
|
+
assert_eq!(setup.uln302.oapp_executor_config(&oapp, &eid), None);
|
|
173
|
+
|
|
174
|
+
// Verify the effective config falls back to defaults
|
|
175
|
+
let config = setup.uln302.effective_executor_config(&oapp, &eid);
|
|
176
|
+
assert_eq!(config, default_config);
|
|
177
|
+
}
|