@layerzerolabs/protocol-stellar-v2 0.2.18 → 0.2.20
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 +303 -253
- package/.turbo/turbo-lint.log +66 -65
- package/.turbo/turbo-test.log +1312 -1282
- package/Cargo.lock +21 -8
- package/Cargo.toml +2 -0
- package/contracts/ERROR_SPEC.md +9 -2
- package/contracts/common-macros/src/contract_ttl.rs +18 -7
- package/contracts/common-macros/src/lib.rs +4 -4
- package/contracts/common-macros/src/tests/contract_ttl.rs +1 -1
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +2 -1
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +7 -12
- package/contracts/common-macros/src/upgradeable.rs +15 -21
- package/contracts/message-libs/uln-302/src/events.rs +4 -0
- package/contracts/message-libs/uln-302/src/send_uln.rs +23 -7
- package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +38 -64
- package/contracts/oapps/counter/Cargo.toml +1 -0
- package/contracts/oapps/counter/integration_tests/setup_uln.rs +1 -1
- package/contracts/oapps/oapp/src/oapp_receiver.rs +1 -1
- package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +113 -65
- package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +111 -82
- package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +293 -65
- package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +331 -56
- package/contracts/oapps/oft/Cargo.toml +10 -7
- package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_oft_fee.rs +3 -4
- package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_pausable.rs +2 -3
- package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_rate_limiter.rs +1 -1
- package/contracts/oapps/oft/integration-tests/mod.rs +1 -1
- package/contracts/oapps/oft/integration-tests/setup.rs +28 -127
- package/contracts/oapps/oft/integration-tests/utils.rs +254 -21
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +23 -8
- package/contracts/oapps/oft/src/extensions/pausable.rs +19 -4
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +52 -28
- package/contracts/oapps/oft/src/lib.rs +10 -14
- package/contracts/oapps/oft/src/oft.rs +143 -193
- package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +9 -11
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +12 -14
- package/contracts/oapps/oft/src/oft_types/mod.rs +13 -0
- package/contracts/oapps/{oft-std → oft-core}/Cargo.toml +6 -4
- package/contracts/oapps/{oft-std → oft-core}/integration-tests/mod.rs +1 -1
- package/contracts/oapps/{oft-std → oft-core}/integration-tests/setup.rs +126 -29
- package/contracts/oapps/{oft → oft-core}/integration-tests/test_with_sml.rs +3 -3
- package/contracts/oapps/oft-core/integration-tests/utils.rs +201 -0
- package/contracts/oapps/oft-core/src/lib.rs +18 -0
- package/contracts/oapps/oft-core/src/oft_core.rs +479 -0
- package/contracts/oapps/{oft → oft-core}/src/tests/mod.rs +0 -2
- package/contracts/oapps/{oft → oft-core}/src/tests/test_lz_receive.rs +7 -7
- package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_msg_codec.rs +4 -4
- package/contracts/oapps/{oft → oft-core}/src/tests/test_resolve_address.rs +3 -3
- package/contracts/oapps/{oft → oft-core}/src/tests/test_utils.rs +46 -27
- package/contracts/oapps/{oft → oft-core}/src/utils.rs +1 -1
- package/contracts/upgrader/src/lib.rs +30 -57
- package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract1.wasm +0 -0
- package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract2.wasm +0 -0
- package/contracts/upgrader/src/tests/test_upgrader.rs +44 -35
- package/contracts/utils/src/buffer_reader.rs +1 -0
- package/contracts/utils/src/errors.rs +8 -2
- package/contracts/utils/src/ownable.rs +125 -3
- package/contracts/utils/src/tests/option_ext.rs +1 -1
- package/contracts/utils/src/tests/ownable.rs +445 -7
- package/contracts/utils/src/tests/ttl_configurable.rs +2 -2
- package/contracts/utils/src/tests/upgradeable.rs +372 -175
- package/contracts/utils/src/ttl_configurable.rs +3 -3
- package/contracts/utils/src/upgradeable.rs +48 -23
- package/contracts/workers/dvn/Cargo.toml +1 -0
- package/contracts/workers/dvn/src/auth.rs +12 -42
- package/contracts/workers/dvn/src/dvn.rs +16 -31
- package/contracts/workers/dvn/src/errors.rs +0 -1
- package/contracts/workers/dvn/src/interfaces/dvn.rs +35 -0
- package/contracts/workers/dvn/src/lib.rs +4 -3
- package/contracts/workers/dvn/src/tests/auth.rs +1 -1
- package/contracts/workers/dvn/src/tests/dvn.rs +19 -15
- package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +2 -4
- package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +1 -3
- package/contracts/workers/dvn/src/tests/setup.rs +5 -9
- package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
- package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +3 -5
- package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +2 -3
- package/contracts/workers/executor/Cargo.toml +1 -0
- package/contracts/workers/executor/src/executor.rs +15 -26
- package/contracts/workers/executor-fee-lib/Cargo.toml +2 -1
- package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +63 -5
- package/contracts/workers/executor-fee-lib/src/executor_option.rs +28 -1
- package/contracts/workers/executor-fee-lib/src/lib.rs +3 -0
- package/contracts/workers/executor-fee-lib/src/tests/executor_fee_lib.rs +701 -0
- package/contracts/workers/executor-fee-lib/src/tests/executor_option.rs +370 -0
- package/contracts/workers/executor-fee-lib/src/tests/mod.rs +4 -0
- package/contracts/workers/executor-fee-lib/src/tests/setup.rs +60 -0
- package/contracts/workers/executor-helper/src/lib.rs +3 -0
- package/contracts/workers/executor-helper/src/tests/executor_helper.rs +184 -0
- package/contracts/workers/executor-helper/src/tests/mod.rs +2 -0
- package/contracts/workers/executor-helper/src/tests/setup.rs +366 -0
- package/contracts/workers/fee-lib-interfaces/Cargo.toml +14 -0
- package/contracts/workers/{worker/src/interfaces/mod.rs → fee-lib-interfaces/src/lib.rs} +4 -3
- package/contracts/workers/price-feed/Cargo.toml +2 -1
- package/contracts/workers/price-feed/src/events.rs +1 -1
- package/contracts/workers/price-feed/src/lib.rs +3 -0
- package/contracts/workers/price-feed/src/price_feed.rs +6 -12
- package/contracts/workers/price-feed/src/storage.rs +1 -1
- package/contracts/workers/price-feed/src/tests/mod.rs +2 -0
- package/contracts/workers/price-feed/src/tests/price_feed.rs +869 -0
- package/contracts/workers/price-feed/src/tests/setup.rs +70 -0
- package/contracts/workers/price-feed/src/types.rs +1 -1
- package/contracts/workers/worker/src/errors.rs +0 -3
- package/contracts/workers/worker/src/lib.rs +0 -2
- package/contracts/workers/worker/src/storage.rs +32 -29
- package/contracts/workers/worker/src/tests/setup.rs +1 -7
- package/contracts/workers/worker/src/tests/worker.rs +50 -42
- package/contracts/workers/worker/src/worker.rs +49 -58
- package/package.json +4 -5
- package/sdk/.turbo/turbo-test.log +229 -217
- package/sdk/dist/generated/bml.d.ts +39 -1
- package/sdk/dist/generated/bml.js +33 -8
- package/sdk/dist/generated/counter.d.ts +131 -3
- package/sdk/dist/generated/counter.js +41 -10
- package/sdk/dist/generated/dvn.d.ts +431 -362
- package/sdk/dist/generated/dvn.js +80 -55
- package/sdk/dist/generated/dvn_fee_lib.d.ts +327 -251
- package/sdk/dist/generated/dvn_fee_lib.js +55 -57
- package/sdk/dist/generated/endpoint.d.ts +131 -3
- package/sdk/dist/generated/endpoint.js +41 -10
- package/sdk/dist/generated/executor.d.ts +503 -339
- package/sdk/dist/generated/executor.js +80 -48
- package/sdk/dist/generated/executor_fee_lib.d.ts +395 -319
- package/sdk/dist/generated/executor_fee_lib.js +54 -56
- package/sdk/dist/generated/executor_helper.d.ts +53 -187
- package/sdk/dist/generated/executor_helper.js +47 -29
- package/sdk/dist/generated/layerzero_view.d.ts +1271 -0
- package/sdk/dist/generated/layerzero_view.js +294 -0
- package/sdk/dist/generated/oft.d.ts +1851 -0
- package/sdk/dist/generated/oft.js +347 -0
- package/sdk/dist/generated/price_feed.d.ts +329 -253
- package/sdk/dist/generated/price_feed.js +55 -57
- package/sdk/dist/generated/sml.d.ts +131 -3
- package/sdk/dist/generated/sml.js +41 -10
- package/sdk/dist/generated/treasury.d.ts +131 -3
- package/sdk/dist/generated/treasury.js +41 -10
- package/sdk/dist/generated/uln302.d.ts +131 -3
- package/sdk/dist/generated/uln302.js +43 -12
- package/sdk/dist/generated/upgrader.d.ts +201 -15
- package/sdk/dist/generated/upgrader.js +99 -1
- package/sdk/dist/index.d.ts +2 -2
- package/sdk/dist/index.js +3 -3
- package/sdk/package.json +3 -2
- package/sdk/src/index.ts +3 -3
- package/sdk/test/oft-sml.test.ts +20 -20
- package/sdk/test/upgrader.test.ts +2 -3
- package/sdk/turbo.json +8 -0
- package/tools/ts-bindings-gen/Cargo.toml +2 -0
- package/tools/ts-bindings-gen/src/main.rs +53 -5
- package/turbo.json +0 -2
- package/contracts/oapps/oft/src/interfaces/mint_burn_token.rs +0 -23
- package/contracts/oapps/oft/src/interfaces/mod.rs +0 -3
- package/contracts/oapps/oft/src/oft_impl.rs +0 -201
- package/contracts/oapps/oft/src/tests/extensions/mod.rs +0 -11
- package/contracts/oapps/oft/src/tests/extensions/setup.rs +0 -917
- package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +0 -751
- package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +0 -434
- package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +0 -1080
- package/contracts/oapps/oft-std/integration-tests/utils.rs +0 -427
- package/contracts/oapps/oft-std/src/lib.rs +0 -16
- package/contracts/oapps/oft-std/src/oft.rs +0 -174
- package/sdk/dist/generated/oft_std.d.ts +0 -1722
- package/sdk/dist/generated/oft_std.js +0 -316
- package/sdk/dist/wasm/blocked-message-lib.d.ts +0 -1
- package/sdk/dist/wasm/blocked-message-lib.js +0 -2
- package/sdk/dist/wasm/counter.d.ts +0 -1
- package/sdk/dist/wasm/counter.js +0 -2
- package/sdk/dist/wasm/dvn-fee-lib.d.ts +0 -1
- package/sdk/dist/wasm/dvn-fee-lib.js +0 -2
- package/sdk/dist/wasm/dvn.d.ts +0 -1
- package/sdk/dist/wasm/dvn.js +0 -2
- package/sdk/dist/wasm/endpoint-v2.d.ts +0 -1
- package/sdk/dist/wasm/endpoint-v2.js +0 -2
- package/sdk/dist/wasm/executor-fee-lib.d.ts +0 -1
- package/sdk/dist/wasm/executor-fee-lib.js +0 -2
- package/sdk/dist/wasm/executor-helper.d.ts +0 -1
- package/sdk/dist/wasm/executor-helper.js +0 -2
- package/sdk/dist/wasm/executor.d.ts +0 -1
- package/sdk/dist/wasm/executor.js +0 -2
- package/sdk/dist/wasm/layerzero-views.d.ts +0 -1
- package/sdk/dist/wasm/layerzero-views.js +0 -2
- package/sdk/dist/wasm/oft-std.d.ts +0 -1
- package/sdk/dist/wasm/oft-std.js +0 -2
- package/sdk/dist/wasm/price-feed.d.ts +0 -1
- package/sdk/dist/wasm/price-feed.js +0 -2
- package/sdk/dist/wasm/simple-message-lib.d.ts +0 -1
- package/sdk/dist/wasm/simple-message-lib.js +0 -2
- package/sdk/dist/wasm/treasury.d.ts +0 -1
- package/sdk/dist/wasm/treasury.js +0 -2
- package/sdk/dist/wasm/uln302.d.ts +0 -1
- package/sdk/dist/wasm/uln302.js +0 -2
- package/sdk/dist/wasm/upgrader.d.ts +0 -1
- package/sdk/dist/wasm/upgrader.js +0 -2
- package/sdk/dist/wasm.d.ts +0 -15
- package/sdk/dist/wasm.js +0 -15
- /package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/mod.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/codec/mod.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/codec/oft_compose_msg_codec.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/codec/oft_msg_codec.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/errors.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/events.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/storage.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_decimals.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_compose_msg_codec.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_version.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_quote_oft.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_quote_send.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_send.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_token.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/types.rs +0 -0
- /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/dvn_fee_lib.rs +0 -0
- /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/executor_fee_lib.rs +0 -0
- /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/price_feed.rs +0 -0
|
@@ -1,1080 +0,0 @@
|
|
|
1
|
-
//! Tests for the rate limiter extension functionality.
|
|
2
|
-
//!
|
|
3
|
-
//! Tests verify:
|
|
4
|
-
//! - Rate limit configuration (set/unset)
|
|
5
|
-
//! - Capacity tracking and decay over time
|
|
6
|
-
//! - Rate limit enforcement on send (outbound)
|
|
7
|
-
//! - Rate limit enforcement on lz_receive (inbound)
|
|
8
|
-
//! - Capacity release on opposite direction
|
|
9
|
-
|
|
10
|
-
use crate::{
|
|
11
|
-
extensions::rate_limiter::{Direction, RateLimitError},
|
|
12
|
-
tests::test_utils::{create_origin, create_recipient_address, encode_oft_message},
|
|
13
|
-
utils::address_to_bytes32,
|
|
14
|
-
};
|
|
15
|
-
use endpoint_v2::MessagingFee;
|
|
16
|
-
use soroban_sdk::{
|
|
17
|
-
testutils::{Address as _, Ledger as _},
|
|
18
|
-
Address, Bytes, BytesN, Env, IntoVal,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
use super::setup::ExtensiveOFTTestSetup;
|
|
22
|
-
|
|
23
|
-
// ==================== Rate Limit Configuration Tests ====================
|
|
24
|
-
|
|
25
|
-
#[test]
|
|
26
|
-
fn test_initial_no_rate_limit() {
|
|
27
|
-
let env = Env::default();
|
|
28
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
29
|
-
|
|
30
|
-
let dst_eid = 100u32;
|
|
31
|
-
|
|
32
|
-
// No rate limit configured, capacity should be MAX
|
|
33
|
-
let capacity = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
34
|
-
assert_eq!(capacity, i128::MAX);
|
|
35
|
-
|
|
36
|
-
let (limit, window) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
37
|
-
assert_eq!(limit, 0);
|
|
38
|
-
assert_eq!(window, 0);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
#[test]
|
|
42
|
-
fn test_set_rate_limit_outbound() {
|
|
43
|
-
let env = Env::default();
|
|
44
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
45
|
-
|
|
46
|
-
let dst_eid = 100u32;
|
|
47
|
-
let limit = 1_000_000i128;
|
|
48
|
-
let window_seconds = 3600u64; // 1 hour
|
|
49
|
-
|
|
50
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, window_seconds);
|
|
51
|
-
|
|
52
|
-
let (stored_limit, stored_window) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
53
|
-
assert_eq!(stored_limit, limit);
|
|
54
|
-
assert_eq!(stored_window, window_seconds);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
#[test]
|
|
58
|
-
fn test_set_rate_limit_inbound() {
|
|
59
|
-
let env = Env::default();
|
|
60
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
61
|
-
|
|
62
|
-
let src_eid = 100u32;
|
|
63
|
-
let limit = 2_000_000i128;
|
|
64
|
-
let window_seconds = 7200u64; // 2 hours
|
|
65
|
-
|
|
66
|
-
setup.set_rate_limit(&Direction::Inbound, src_eid, limit, window_seconds);
|
|
67
|
-
|
|
68
|
-
let (stored_limit, stored_window) = setup.rate_limit_config(&Direction::Inbound, src_eid);
|
|
69
|
-
assert_eq!(stored_limit, limit);
|
|
70
|
-
assert_eq!(stored_window, window_seconds);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
#[test]
|
|
74
|
-
fn test_set_rate_limit_both_directions() {
|
|
75
|
-
let env = Env::default();
|
|
76
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
77
|
-
|
|
78
|
-
let eid = 100u32;
|
|
79
|
-
|
|
80
|
-
setup.set_rate_limit(&Direction::Outbound, eid, 1_000_000, 3600);
|
|
81
|
-
setup.set_rate_limit(&Direction::Inbound, eid, 2_000_000, 7200);
|
|
82
|
-
|
|
83
|
-
let (outbound_limit, outbound_window) = setup.rate_limit_config(&Direction::Outbound, eid);
|
|
84
|
-
let (inbound_limit, inbound_window) = setup.rate_limit_config(&Direction::Inbound, eid);
|
|
85
|
-
|
|
86
|
-
assert_eq!(outbound_limit, 1_000_000);
|
|
87
|
-
assert_eq!(outbound_window, 3600);
|
|
88
|
-
assert_eq!(inbound_limit, 2_000_000);
|
|
89
|
-
assert_eq!(inbound_window, 7200);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
#[test]
|
|
93
|
-
fn test_set_rate_limit_zero_limit_fails() {
|
|
94
|
-
let env = Env::default();
|
|
95
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
96
|
-
|
|
97
|
-
let result = setup.try_set_rate_limit(&Direction::Outbound, 100, 0, 3600);
|
|
98
|
-
assert_eq!(result.err().unwrap().ok().unwrap(), RateLimitError::InvalidLimit.into());
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
#[test]
|
|
102
|
-
fn test_set_rate_limit_zero_window_fails() {
|
|
103
|
-
let env = Env::default();
|
|
104
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
105
|
-
|
|
106
|
-
let result = setup.try_set_rate_limit(&Direction::Outbound, 100, 1_000_000, 0);
|
|
107
|
-
assert_eq!(result.err().unwrap().ok().unwrap(), RateLimitError::InvalidWindowSeconds.into());
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
#[test]
|
|
111
|
-
fn test_set_rate_limit_same_values_fails() {
|
|
112
|
-
let env = Env::default();
|
|
113
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
114
|
-
|
|
115
|
-
let dst_eid = 100u32;
|
|
116
|
-
let limit = 1_000_000i128;
|
|
117
|
-
let window_seconds = 3600u64;
|
|
118
|
-
|
|
119
|
-
// Set rate limit
|
|
120
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, window_seconds);
|
|
121
|
-
|
|
122
|
-
// Try to set same values again - should fail with SameValue
|
|
123
|
-
let result = setup.try_set_rate_limit(&Direction::Outbound, dst_eid, limit, window_seconds);
|
|
124
|
-
assert_eq!(result.err().unwrap().ok().unwrap(), RateLimitError::SameValue.into());
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
#[test]
|
|
128
|
-
fn test_unset_rate_limit() {
|
|
129
|
-
let env = Env::default();
|
|
130
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
131
|
-
|
|
132
|
-
let dst_eid = 100u32;
|
|
133
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 1_000_000, 3600);
|
|
134
|
-
|
|
135
|
-
let (limit, _) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
136
|
-
assert_eq!(limit, 1_000_000);
|
|
137
|
-
|
|
138
|
-
setup.unset_rate_limit(&Direction::Outbound, dst_eid);
|
|
139
|
-
|
|
140
|
-
let (limit_after, _) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
141
|
-
assert_eq!(limit_after, 0);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
#[test]
|
|
145
|
-
fn test_unset_rate_limit_not_found() {
|
|
146
|
-
let env = Env::default();
|
|
147
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
148
|
-
|
|
149
|
-
let dst_eid = 100u32;
|
|
150
|
-
|
|
151
|
-
// Try to unset rate limit that doesn't exist - should fail with SameValue
|
|
152
|
-
let result = setup.try_unset_rate_limit(&Direction::Outbound, dst_eid);
|
|
153
|
-
assert_eq!(result.err().unwrap().ok().unwrap(), RateLimitError::SameValue.into());
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
#[test]
|
|
157
|
-
fn test_update_rate_limit() {
|
|
158
|
-
let env = Env::default();
|
|
159
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
160
|
-
|
|
161
|
-
let dst_eid = 100u32;
|
|
162
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 1_000_000, 3600);
|
|
163
|
-
|
|
164
|
-
// Update to new values
|
|
165
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 2_000_000, 7200);
|
|
166
|
-
|
|
167
|
-
let (limit, window) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
168
|
-
assert_eq!(limit, 2_000_000);
|
|
169
|
-
assert_eq!(window, 7200);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
#[test]
|
|
173
|
-
fn test_update_rate_limit_only_limit() {
|
|
174
|
-
let env = Env::default();
|
|
175
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
176
|
-
|
|
177
|
-
let dst_eid = 100u32;
|
|
178
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 1_000_000, 3600);
|
|
179
|
-
|
|
180
|
-
// Update only the limit (keep same window)
|
|
181
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 2_000_000, 3600);
|
|
182
|
-
|
|
183
|
-
let (limit, window) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
184
|
-
assert_eq!(limit, 2_000_000);
|
|
185
|
-
assert_eq!(window, 3600);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
#[test]
|
|
189
|
-
fn test_update_rate_limit_only_window() {
|
|
190
|
-
let env = Env::default();
|
|
191
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
192
|
-
|
|
193
|
-
let dst_eid = 100u32;
|
|
194
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 1_000_000, 3600);
|
|
195
|
-
|
|
196
|
-
// Update only the window (keep same limit)
|
|
197
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 1_000_000, 7200);
|
|
198
|
-
|
|
199
|
-
let (limit, window) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
200
|
-
assert_eq!(limit, 1_000_000);
|
|
201
|
-
assert_eq!(window, 7200);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// ==================== Capacity Tests ====================
|
|
205
|
-
|
|
206
|
-
#[test]
|
|
207
|
-
fn test_initial_capacity_equals_limit() {
|
|
208
|
-
let env = Env::default();
|
|
209
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
210
|
-
|
|
211
|
-
let dst_eid = 100u32;
|
|
212
|
-
let limit = 1_000_000i128;
|
|
213
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, 3600);
|
|
214
|
-
|
|
215
|
-
let capacity = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
216
|
-
assert_eq!(capacity, limit);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
#[test]
|
|
220
|
-
fn test_in_flight_initially_zero() {
|
|
221
|
-
let env = Env::default();
|
|
222
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
223
|
-
|
|
224
|
-
let dst_eid = 100u32;
|
|
225
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 1_000_000, 3600);
|
|
226
|
-
|
|
227
|
-
let in_flight = setup.rate_limit_in_flight(&Direction::Outbound, dst_eid);
|
|
228
|
-
assert_eq!(in_flight, 0);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
#[test]
|
|
232
|
-
fn test_rate_limit_in_flight_no_rate_limit_returns_zero() {
|
|
233
|
-
let env = Env::default();
|
|
234
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
235
|
-
|
|
236
|
-
let dst_eid = 100u32;
|
|
237
|
-
|
|
238
|
-
// No rate limit set - in_flight should return 0
|
|
239
|
-
let in_flight = setup.rate_limit_in_flight(&Direction::Outbound, dst_eid);
|
|
240
|
-
assert_eq!(in_flight, 0);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
#[test]
|
|
244
|
-
fn test_rate_limit_capacity_zero_when_in_flight_exceeds_limit() {
|
|
245
|
-
let env = Env::default();
|
|
246
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
247
|
-
|
|
248
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
249
|
-
let fee_collector = create_recipient_address(&env);
|
|
250
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
251
|
-
|
|
252
|
-
let sender = Address::generate(&env);
|
|
253
|
-
let dst_eid = 100u32;
|
|
254
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
255
|
-
setup.set_peer(dst_eid, &peer);
|
|
256
|
-
|
|
257
|
-
// Set outbound rate limit
|
|
258
|
-
let limit = 1_000_000i128;
|
|
259
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, 3600);
|
|
260
|
-
|
|
261
|
-
// Use all capacity
|
|
262
|
-
let amount_ld = limit;
|
|
263
|
-
setup.fund_tokens(&sender, amount_ld);
|
|
264
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
265
|
-
|
|
266
|
-
let send_param = setup.create_send_param(dst_eid, amount_ld, amount_ld);
|
|
267
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
268
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
269
|
-
setup.send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
270
|
-
|
|
271
|
-
// Capacity should be exactly 0 after using all of it
|
|
272
|
-
let capacity = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
273
|
-
assert_eq!(capacity, 0);
|
|
274
|
-
|
|
275
|
-
// In-flight should equal limit
|
|
276
|
-
let in_flight = setup.rate_limit_in_flight(&Direction::Outbound, dst_eid);
|
|
277
|
-
assert_eq!(in_flight, limit);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
#[test]
|
|
281
|
-
fn test_update_rate_limit_preserves_in_flight() {
|
|
282
|
-
let env = Env::default();
|
|
283
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
284
|
-
|
|
285
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
286
|
-
let fee_collector = create_recipient_address(&env);
|
|
287
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
288
|
-
|
|
289
|
-
let sender = Address::generate(&env);
|
|
290
|
-
let dst_eid = 100u32;
|
|
291
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
292
|
-
setup.set_peer(dst_eid, &peer);
|
|
293
|
-
|
|
294
|
-
// Set initial rate limit
|
|
295
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 1_000_000, 3600);
|
|
296
|
-
|
|
297
|
-
// Use some capacity
|
|
298
|
-
let amount_ld = 300_000i128;
|
|
299
|
-
setup.fund_tokens(&sender, amount_ld);
|
|
300
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
301
|
-
|
|
302
|
-
let send_param = setup.create_send_param(dst_eid, amount_ld, amount_ld);
|
|
303
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
304
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
305
|
-
setup.send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
306
|
-
|
|
307
|
-
// In-flight should be 300_000
|
|
308
|
-
let in_flight_before = setup.rate_limit_in_flight(&Direction::Outbound, dst_eid);
|
|
309
|
-
assert_eq!(in_flight_before, amount_ld);
|
|
310
|
-
|
|
311
|
-
// Update rate limit to higher value
|
|
312
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 2_000_000, 3600);
|
|
313
|
-
|
|
314
|
-
// In-flight should be preserved (checkpointed)
|
|
315
|
-
let in_flight_after = setup.rate_limit_in_flight(&Direction::Outbound, dst_eid);
|
|
316
|
-
assert_eq!(in_flight_after, amount_ld);
|
|
317
|
-
|
|
318
|
-
// New capacity should be new_limit - in_flight
|
|
319
|
-
let capacity = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
320
|
-
assert_eq!(capacity, 2_000_000 - amount_ld);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// ==================== Capacity Decay Tests ====================
|
|
324
|
-
|
|
325
|
-
#[test]
|
|
326
|
-
fn test_rate_limit_invalid_timestamp_fails() {
|
|
327
|
-
let env = Env::default();
|
|
328
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
329
|
-
|
|
330
|
-
let dst_eid = 100u32;
|
|
331
|
-
|
|
332
|
-
// Start with a timestamp in the future
|
|
333
|
-
setup.advance_time(10000);
|
|
334
|
-
|
|
335
|
-
// Set rate limit (last_update will be set to current timestamp: 10000)
|
|
336
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, 1_000_000, 3600);
|
|
337
|
-
|
|
338
|
-
// Move time backwards by modifying ledger info directly
|
|
339
|
-
env.ledger().with_mut(|li| {
|
|
340
|
-
li.timestamp = 5000; // Earlier than last_update
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
// Querying in_flight should fail because timestamp < last_update
|
|
344
|
-
let result = setup.try_rate_limit_in_flight(&Direction::Outbound, dst_eid);
|
|
345
|
-
assert!(result.is_err());
|
|
346
|
-
let err = result.err().unwrap().ok().unwrap();
|
|
347
|
-
assert_eq!(err, RateLimitError::InvalidTimestamp.into());
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
#[test]
|
|
351
|
-
fn test_consume_rate_limit_when_capacity_exactly_zero() {
|
|
352
|
-
let env = Env::default();
|
|
353
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
354
|
-
|
|
355
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
356
|
-
let fee_collector = create_recipient_address(&env);
|
|
357
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
358
|
-
|
|
359
|
-
let sender = Address::generate(&env);
|
|
360
|
-
let dst_eid = 100u32;
|
|
361
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
362
|
-
setup.set_peer(dst_eid, &peer);
|
|
363
|
-
|
|
364
|
-
// Set outbound rate limit
|
|
365
|
-
let limit = 1_000_000i128;
|
|
366
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, 3600);
|
|
367
|
-
|
|
368
|
-
// Use all capacity
|
|
369
|
-
setup.fund_tokens(&sender, limit);
|
|
370
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
371
|
-
|
|
372
|
-
let send_param = setup.create_send_param(dst_eid, limit, limit);
|
|
373
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
374
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
375
|
-
setup.send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
376
|
-
|
|
377
|
-
// Capacity should be 0 now (in_flight equals limit)
|
|
378
|
-
assert_eq!(setup.rate_limit_capacity(&Direction::Outbound, dst_eid), 0);
|
|
379
|
-
|
|
380
|
-
// Try to send a small amount - should fail because capacity is exactly 0
|
|
381
|
-
// This tests the branch where capacity = 0 (limit <= in_flight) in __consume_rate_limit_capacity
|
|
382
|
-
// Use amount that survives dust removal (conversion_rate = 10)
|
|
383
|
-
let small_amount = 100i128;
|
|
384
|
-
setup.fund_tokens(&sender, small_amount);
|
|
385
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
386
|
-
|
|
387
|
-
// quote_oft will report the limit in OFTLimit but won't enforce
|
|
388
|
-
let send_param_2 = setup.create_send_param(dst_eid, small_amount, small_amount);
|
|
389
|
-
let oft_receipt_2 = setup.quote_oft(&send_param_2);
|
|
390
|
-
|
|
391
|
-
// send will fail because capacity is 0
|
|
392
|
-
let result = setup.try_send(&sender, &send_param_2, &fee, &sender, &oft_receipt_2);
|
|
393
|
-
assert_eq!(result.err().unwrap().ok().unwrap(), RateLimitError::ExceededRateLimit.into());
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
#[test]
|
|
397
|
-
fn test_capacity_recovers_over_time() {
|
|
398
|
-
let env = Env::default();
|
|
399
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
400
|
-
|
|
401
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
402
|
-
let fee_collector = create_recipient_address(&env);
|
|
403
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
404
|
-
|
|
405
|
-
let sender = Address::generate(&env);
|
|
406
|
-
let dst_eid = 100u32;
|
|
407
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
408
|
-
setup.set_peer(dst_eid, &peer);
|
|
409
|
-
|
|
410
|
-
// Set outbound rate limit: 1_000_000 per hour (3600 seconds)
|
|
411
|
-
let limit = 1_000_000i128;
|
|
412
|
-
let window_seconds = 3600u64;
|
|
413
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, window_seconds);
|
|
414
|
-
|
|
415
|
-
// Use all capacity
|
|
416
|
-
let amount_ld = limit;
|
|
417
|
-
setup.fund_tokens(&sender, amount_ld);
|
|
418
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
419
|
-
|
|
420
|
-
let send_param = setup.create_send_param(dst_eid, amount_ld, amount_ld);
|
|
421
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
422
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
423
|
-
setup.send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
424
|
-
|
|
425
|
-
// Capacity should be 0
|
|
426
|
-
assert_eq!(setup.rate_limit_capacity(&Direction::Outbound, dst_eid), 0);
|
|
427
|
-
|
|
428
|
-
// Advance time by half the window (1800 seconds)
|
|
429
|
-
setup.advance_time(1800);
|
|
430
|
-
|
|
431
|
-
// Capacity should recover to ~50%
|
|
432
|
-
let capacity_after_half = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
433
|
-
assert!(capacity_after_half >= 490_000 && capacity_after_half <= 510_000);
|
|
434
|
-
|
|
435
|
-
// Advance time by another half (full window elapsed)
|
|
436
|
-
setup.advance_time(1800);
|
|
437
|
-
|
|
438
|
-
// Capacity should be fully recovered
|
|
439
|
-
let capacity_after_full = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
440
|
-
assert_eq!(capacity_after_full, limit);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
#[test]
|
|
444
|
-
fn test_send_after_capacity_recovery() {
|
|
445
|
-
let env = Env::default();
|
|
446
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
447
|
-
|
|
448
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
449
|
-
let fee_collector = create_recipient_address(&env);
|
|
450
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
451
|
-
|
|
452
|
-
let sender = Address::generate(&env);
|
|
453
|
-
let dst_eid = 100u32;
|
|
454
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
455
|
-
setup.set_peer(dst_eid, &peer);
|
|
456
|
-
|
|
457
|
-
// Set outbound rate limit
|
|
458
|
-
let limit = 1_000_000i128;
|
|
459
|
-
let window_seconds = 3600u64;
|
|
460
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, window_seconds);
|
|
461
|
-
|
|
462
|
-
// Use all capacity
|
|
463
|
-
setup.fund_tokens(&sender, limit);
|
|
464
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
465
|
-
|
|
466
|
-
let send_param = setup.create_send_param(dst_eid, limit, limit);
|
|
467
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
468
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
469
|
-
setup.send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
470
|
-
|
|
471
|
-
// Advance time to fully recover
|
|
472
|
-
setup.advance_time(window_seconds);
|
|
473
|
-
|
|
474
|
-
// Should be able to send again
|
|
475
|
-
setup.fund_tokens(&sender, limit);
|
|
476
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
477
|
-
|
|
478
|
-
let send_param_2 = setup.create_send_param(dst_eid, limit, limit);
|
|
479
|
-
let oft_receipt_2 = setup.quote_oft(&send_param_2);
|
|
480
|
-
let (msg_receipt, _) = setup.send(&sender, &send_param_2, &fee, &sender, &oft_receipt_2);
|
|
481
|
-
assert!(msg_receipt.nonce > 0);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// ==================== Send Tests (Outbound Rate Limit) ====================
|
|
485
|
-
|
|
486
|
-
#[test]
|
|
487
|
-
fn test_send_within_rate_limit() {
|
|
488
|
-
let env = Env::default();
|
|
489
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
490
|
-
|
|
491
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
492
|
-
let fee_collector = create_recipient_address(&env);
|
|
493
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
494
|
-
|
|
495
|
-
let sender = Address::generate(&env);
|
|
496
|
-
let dst_eid = 100u32;
|
|
497
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
498
|
-
setup.set_peer(dst_eid, &peer);
|
|
499
|
-
|
|
500
|
-
// Set outbound rate limit
|
|
501
|
-
let limit = 1_000_000i128;
|
|
502
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, 3600);
|
|
503
|
-
|
|
504
|
-
let amount_ld = 500_000i128; // Within limit
|
|
505
|
-
setup.fund_tokens(&sender, amount_ld);
|
|
506
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
507
|
-
|
|
508
|
-
let send_param = setup.create_send_param(dst_eid, amount_ld, amount_ld);
|
|
509
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
510
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
511
|
-
|
|
512
|
-
// Should succeed within limit
|
|
513
|
-
let (msg_receipt, _) = setup.send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
514
|
-
assert!(msg_receipt.nonce > 0);
|
|
515
|
-
|
|
516
|
-
// Check capacity decreased
|
|
517
|
-
let capacity = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
518
|
-
assert_eq!(capacity, limit - amount_ld);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
#[test]
|
|
522
|
-
fn test_send_exactly_at_rate_limit() {
|
|
523
|
-
let env = Env::default();
|
|
524
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
525
|
-
|
|
526
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
527
|
-
let fee_collector = create_recipient_address(&env);
|
|
528
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
529
|
-
|
|
530
|
-
let sender = Address::generate(&env);
|
|
531
|
-
let dst_eid = 100u32;
|
|
532
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
533
|
-
setup.set_peer(dst_eid, &peer);
|
|
534
|
-
|
|
535
|
-
// Set outbound rate limit
|
|
536
|
-
let limit = 1_000_000i128;
|
|
537
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, 3600);
|
|
538
|
-
|
|
539
|
-
let amount_ld = limit; // Exactly at limit
|
|
540
|
-
setup.fund_tokens(&sender, amount_ld);
|
|
541
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
542
|
-
|
|
543
|
-
let send_param = setup.create_send_param(dst_eid, amount_ld, amount_ld);
|
|
544
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
545
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
546
|
-
|
|
547
|
-
// Should succeed at exactly limit
|
|
548
|
-
let (msg_receipt, _) = setup.send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
549
|
-
assert!(msg_receipt.nonce > 0);
|
|
550
|
-
|
|
551
|
-
// Capacity should be zero
|
|
552
|
-
let capacity = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
553
|
-
assert_eq!(capacity, 0);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
#[test]
|
|
557
|
-
fn test_send_exceeds_rate_limit() {
|
|
558
|
-
let env = Env::default();
|
|
559
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
560
|
-
|
|
561
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
562
|
-
let fee_collector = create_recipient_address(&env);
|
|
563
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
564
|
-
|
|
565
|
-
let sender = Address::generate(&env);
|
|
566
|
-
let dst_eid = 100u32;
|
|
567
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
568
|
-
setup.set_peer(dst_eid, &peer);
|
|
569
|
-
|
|
570
|
-
// Set outbound rate limit
|
|
571
|
-
let limit = 1_000_000i128;
|
|
572
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, 3600);
|
|
573
|
-
|
|
574
|
-
// Use amount that exceeds limit and use min_amount_ld = 0 to avoid slippage errors
|
|
575
|
-
let amount_ld = limit + 10; // Exceeds limit (use +10 to account for dust)
|
|
576
|
-
setup.fund_tokens(&sender, amount_ld);
|
|
577
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
578
|
-
|
|
579
|
-
// Use min_amount_ld = 0 to avoid slippage check interference
|
|
580
|
-
let send_param = setup.create_send_param(dst_eid, amount_ld, 0);
|
|
581
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
582
|
-
|
|
583
|
-
// quote_oft returns the limit but doesn't enforce - the send will fail
|
|
584
|
-
let (oft_limit, _, _) = setup.oft.quote_oft(&send_param);
|
|
585
|
-
assert_eq!(oft_limit.max_amount_ld, limit); // Capacity is 1_000_000
|
|
586
|
-
|
|
587
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
588
|
-
|
|
589
|
-
// Should fail at send - amount exceeds rate limit
|
|
590
|
-
let result = setup.try_send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
591
|
-
assert_eq!(result.err().unwrap().ok().unwrap(), RateLimitError::ExceededRateLimit.into());
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
#[test]
|
|
595
|
-
fn test_send_multiple_within_limit() {
|
|
596
|
-
let env = Env::default();
|
|
597
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
598
|
-
|
|
599
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
600
|
-
let fee_collector = create_recipient_address(&env);
|
|
601
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
602
|
-
|
|
603
|
-
let sender = Address::generate(&env);
|
|
604
|
-
let dst_eid = 100u32;
|
|
605
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
606
|
-
setup.set_peer(dst_eid, &peer);
|
|
607
|
-
|
|
608
|
-
// Set outbound rate limit
|
|
609
|
-
let limit = 1_000_000i128;
|
|
610
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, 3600);
|
|
611
|
-
|
|
612
|
-
// First send
|
|
613
|
-
let amount_1 = 300_000i128;
|
|
614
|
-
setup.fund_tokens(&sender, amount_1);
|
|
615
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
616
|
-
|
|
617
|
-
let send_param_1 = setup.create_send_param(dst_eid, amount_1, amount_1);
|
|
618
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
619
|
-
let oft_receipt_1 = setup.quote_oft(&send_param_1);
|
|
620
|
-
setup.send(&sender, &send_param_1, &fee, &sender, &oft_receipt_1);
|
|
621
|
-
|
|
622
|
-
// Second send
|
|
623
|
-
let amount_2 = 400_000i128;
|
|
624
|
-
setup.fund_tokens(&sender, amount_2);
|
|
625
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
626
|
-
|
|
627
|
-
let send_param_2 = setup.create_send_param(dst_eid, amount_2, amount_2);
|
|
628
|
-
let oft_receipt_2 = setup.quote_oft(&send_param_2);
|
|
629
|
-
setup.send(&sender, &send_param_2, &fee, &sender, &oft_receipt_2);
|
|
630
|
-
|
|
631
|
-
// Check remaining capacity
|
|
632
|
-
let capacity = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
633
|
-
assert_eq!(capacity, limit - amount_1 - amount_2);
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
#[test]
|
|
637
|
-
fn test_send_multiple_exceeds_cumulative_limit() {
|
|
638
|
-
let env = Env::default();
|
|
639
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
640
|
-
|
|
641
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
642
|
-
let fee_collector = create_recipient_address(&env);
|
|
643
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
644
|
-
|
|
645
|
-
let sender = Address::generate(&env);
|
|
646
|
-
let dst_eid = 100u32;
|
|
647
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
648
|
-
setup.set_peer(dst_eid, &peer);
|
|
649
|
-
|
|
650
|
-
// Set outbound rate limit
|
|
651
|
-
let limit = 1_000_000i128;
|
|
652
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, 3600);
|
|
653
|
-
|
|
654
|
-
// First send - uses most of the limit
|
|
655
|
-
let amount_1 = 800_000i128;
|
|
656
|
-
setup.fund_tokens(&sender, amount_1);
|
|
657
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
658
|
-
|
|
659
|
-
let send_param_1 = setup.create_send_param(dst_eid, amount_1, amount_1);
|
|
660
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
661
|
-
let oft_receipt_1 = setup.quote_oft(&send_param_1);
|
|
662
|
-
setup.send(&sender, &send_param_1, &fee, &sender, &oft_receipt_1);
|
|
663
|
-
|
|
664
|
-
// Verify capacity was consumed
|
|
665
|
-
let remaining_capacity = setup.rate_limit_capacity(&Direction::Outbound, dst_eid);
|
|
666
|
-
assert_eq!(remaining_capacity, limit - amount_1); // 200_000 remaining
|
|
667
|
-
|
|
668
|
-
// Second send - would exceed remaining capacity
|
|
669
|
-
let amount_2 = 300_000i128; // Only 200_000 capacity left
|
|
670
|
-
setup.fund_tokens(&sender, amount_2);
|
|
671
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
672
|
-
|
|
673
|
-
let send_param_2 = setup.create_send_param(dst_eid, amount_2, amount_2);
|
|
674
|
-
let oft_receipt_2 = setup.quote_oft(&send_param_2);
|
|
675
|
-
|
|
676
|
-
// Should fail at send - cumulative exceeds rate limit
|
|
677
|
-
let result = setup.try_send(&sender, &send_param_2, &fee, &sender, &oft_receipt_2);
|
|
678
|
-
let err = result.err().unwrap().ok().unwrap();
|
|
679
|
-
assert_eq!(err, RateLimitError::ExceededRateLimit.into());
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
// ==================== lz_receive Tests (Inbound Rate Limit) ====================
|
|
683
|
-
|
|
684
|
-
#[test]
|
|
685
|
-
fn test_lz_receive_within_rate_limit() {
|
|
686
|
-
let env = Env::default();
|
|
687
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
688
|
-
|
|
689
|
-
let executor = Address::generate(&env);
|
|
690
|
-
let recipient = create_recipient_address(&env);
|
|
691
|
-
let src_eid = 100u32;
|
|
692
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
693
|
-
setup.set_peer(src_eid, &peer);
|
|
694
|
-
|
|
695
|
-
// Set inbound rate limit
|
|
696
|
-
let limit = 10_000_000i128; // 10M in local decimals
|
|
697
|
-
setup.set_rate_limit(&Direction::Inbound, src_eid, limit, 3600);
|
|
698
|
-
|
|
699
|
-
let amount_sd = 500_000u64; // Within limit (will be converted to ld)
|
|
700
|
-
let recipient_bytes32 = address_to_bytes32(&recipient);
|
|
701
|
-
let message = encode_oft_message(&env, &recipient_bytes32, amount_sd);
|
|
702
|
-
|
|
703
|
-
let guid = BytesN::from_array(&env, &[1u8; 32]);
|
|
704
|
-
let origin = create_origin(src_eid, &peer, 1);
|
|
705
|
-
let extra_data = Bytes::new(&env);
|
|
706
|
-
|
|
707
|
-
let initial_balance = setup.token_client.balance(&recipient);
|
|
708
|
-
|
|
709
|
-
// Should succeed within limit
|
|
710
|
-
setup.lz_receive(&executor, &origin, &guid, &message, &extra_data, 0);
|
|
711
|
-
|
|
712
|
-
let conversion_rate = setup.oft.decimal_conversion_rate();
|
|
713
|
-
let expected_amount_ld = (amount_sd as i128) * conversion_rate;
|
|
714
|
-
assert_eq!(setup.token_client.balance(&recipient), initial_balance + expected_amount_ld);
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
#[test]
|
|
718
|
-
fn test_lz_receive_exceeds_rate_limit() {
|
|
719
|
-
let env = Env::default();
|
|
720
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
721
|
-
|
|
722
|
-
let executor = Address::generate(&env);
|
|
723
|
-
let recipient = create_recipient_address(&env);
|
|
724
|
-
let src_eid = 100u32;
|
|
725
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
726
|
-
setup.set_peer(src_eid, &peer);
|
|
727
|
-
|
|
728
|
-
// Set small inbound rate limit
|
|
729
|
-
let limit = 100_000i128; // Small limit
|
|
730
|
-
setup.set_rate_limit(&Direction::Inbound, src_eid, limit, 3600);
|
|
731
|
-
|
|
732
|
-
// Try to receive more than limit
|
|
733
|
-
// conversion_rate is 10, so 100_000 sd = 1_000_000 ld > limit of 100_000
|
|
734
|
-
let amount_sd = 100_000u64;
|
|
735
|
-
let recipient_bytes32 = address_to_bytes32(&recipient);
|
|
736
|
-
let message = encode_oft_message(&env, &recipient_bytes32, amount_sd);
|
|
737
|
-
|
|
738
|
-
let guid = BytesN::from_array(&env, &[1u8; 32]);
|
|
739
|
-
let origin = create_origin(src_eid, &peer, 1);
|
|
740
|
-
let extra_data = Bytes::new(&env);
|
|
741
|
-
|
|
742
|
-
// Should fail - exceeds limit
|
|
743
|
-
let result = setup.try_lz_receive(&executor, &origin, &guid, &message, &extra_data, 0);
|
|
744
|
-
assert!(result.is_err());
|
|
745
|
-
let err = result.err().unwrap().ok().unwrap();
|
|
746
|
-
assert_eq!(err, RateLimitError::ExceededRateLimit.into());
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
// ==================== Capacity Release Tests (Bidirectional) ====================
|
|
750
|
-
|
|
751
|
-
#[test]
|
|
752
|
-
fn test_inbound_release_outbound_capacity() {
|
|
753
|
-
let env = Env::default();
|
|
754
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
755
|
-
|
|
756
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
757
|
-
let fee_collector = create_recipient_address(&env);
|
|
758
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
759
|
-
|
|
760
|
-
let sender = Address::generate(&env);
|
|
761
|
-
let recipient = create_recipient_address(&env);
|
|
762
|
-
let eid = 100u32;
|
|
763
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
764
|
-
setup.set_peer(eid, &peer);
|
|
765
|
-
|
|
766
|
-
// Set outbound rate limit
|
|
767
|
-
let limit = 1_000_000i128;
|
|
768
|
-
setup.set_rate_limit(&Direction::Outbound, eid, limit, 3600);
|
|
769
|
-
|
|
770
|
-
// Use half the outbound capacity
|
|
771
|
-
let outbound_amount = 500_000i128;
|
|
772
|
-
setup.fund_tokens(&sender, outbound_amount);
|
|
773
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
774
|
-
|
|
775
|
-
let send_param = setup.create_send_param(eid, outbound_amount, outbound_amount);
|
|
776
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
777
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
778
|
-
setup.send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
779
|
-
|
|
780
|
-
// Outbound in-flight should be 500_000
|
|
781
|
-
let in_flight_before = setup.rate_limit_in_flight(&Direction::Outbound, eid);
|
|
782
|
-
assert_eq!(in_flight_before, outbound_amount);
|
|
783
|
-
|
|
784
|
-
// Now receive tokens (which releases outbound capacity)
|
|
785
|
-
let executor = Address::generate(&env);
|
|
786
|
-
let amount_sd = 30_000u64; // 300_000 in ld (conversion rate is 10)
|
|
787
|
-
let recipient_bytes32 = address_to_bytes32(&recipient);
|
|
788
|
-
let message = encode_oft_message(&env, &recipient_bytes32, amount_sd);
|
|
789
|
-
|
|
790
|
-
let guid = BytesN::from_array(&env, &[1u8; 32]);
|
|
791
|
-
let origin = create_origin(eid, &peer, 1);
|
|
792
|
-
let extra_data = Bytes::new(&env);
|
|
793
|
-
|
|
794
|
-
setup.lz_receive(&executor, &origin, &guid, &message, &extra_data, 0);
|
|
795
|
-
|
|
796
|
-
// Outbound in-flight should be reduced by inbound amount
|
|
797
|
-
let conversion_rate = setup.oft.decimal_conversion_rate();
|
|
798
|
-
let inbound_amount_ld = (amount_sd as i128) * conversion_rate;
|
|
799
|
-
let in_flight_after = setup.rate_limit_in_flight(&Direction::Outbound, eid);
|
|
800
|
-
assert_eq!(in_flight_after, outbound_amount - inbound_amount_ld);
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
#[test]
|
|
804
|
-
fn test_release_rate_limit_more_than_in_flight_resets_to_zero() {
|
|
805
|
-
let env = Env::default();
|
|
806
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
807
|
-
|
|
808
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
809
|
-
let fee_collector = create_recipient_address(&env);
|
|
810
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
811
|
-
|
|
812
|
-
let sender = Address::generate(&env);
|
|
813
|
-
let recipient = create_recipient_address(&env);
|
|
814
|
-
let eid = 100u32;
|
|
815
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
816
|
-
setup.set_peer(eid, &peer);
|
|
817
|
-
|
|
818
|
-
// Set outbound rate limit
|
|
819
|
-
let limit = 1_000_000i128;
|
|
820
|
-
setup.set_rate_limit(&Direction::Outbound, eid, limit, 3600);
|
|
821
|
-
|
|
822
|
-
// Use small amount of outbound capacity
|
|
823
|
-
let outbound_amount = 100_000i128;
|
|
824
|
-
setup.fund_tokens(&sender, outbound_amount);
|
|
825
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
826
|
-
|
|
827
|
-
let send_param = setup.create_send_param(eid, outbound_amount, outbound_amount);
|
|
828
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
829
|
-
let oft_receipt = setup.quote_oft(&send_param);
|
|
830
|
-
setup.send(&sender, &send_param, &fee, &sender, &oft_receipt);
|
|
831
|
-
|
|
832
|
-
// Outbound in-flight should be 100_000
|
|
833
|
-
let in_flight_before = setup.rate_limit_in_flight(&Direction::Outbound, eid);
|
|
834
|
-
assert_eq!(in_flight_before, outbound_amount);
|
|
835
|
-
|
|
836
|
-
// Receive MORE tokens than were sent (releases more than in-flight)
|
|
837
|
-
let executor = Address::generate(&env);
|
|
838
|
-
let amount_sd = 50_000u64; // 500_000 in ld (more than 100_000 in flight)
|
|
839
|
-
let recipient_bytes32 = address_to_bytes32(&recipient);
|
|
840
|
-
let message = encode_oft_message(&env, &recipient_bytes32, amount_sd);
|
|
841
|
-
|
|
842
|
-
let guid = BytesN::from_array(&env, &[1u8; 32]);
|
|
843
|
-
let origin = create_origin(eid, &peer, 1);
|
|
844
|
-
let extra_data = Bytes::new(&env);
|
|
845
|
-
|
|
846
|
-
setup.lz_receive(&executor, &origin, &guid, &message, &extra_data, 0);
|
|
847
|
-
|
|
848
|
-
// Outbound in-flight should reset to 0 (not go negative)
|
|
849
|
-
let in_flight_after = setup.rate_limit_in_flight(&Direction::Outbound, eid);
|
|
850
|
-
assert_eq!(in_flight_after, 0);
|
|
851
|
-
|
|
852
|
-
// Capacity should be back to full limit
|
|
853
|
-
let capacity = setup.rate_limit_capacity(&Direction::Outbound, eid);
|
|
854
|
-
assert_eq!(capacity, limit);
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
// ==================== quote_oft Tests (Rate Limit in OFTLimit) ====================
|
|
858
|
-
|
|
859
|
-
#[test]
|
|
860
|
-
fn test_quote_oft_returns_rate_limit_capacity() {
|
|
861
|
-
let env = Env::default();
|
|
862
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
863
|
-
|
|
864
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
865
|
-
let fee_collector = create_recipient_address(&env);
|
|
866
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
867
|
-
|
|
868
|
-
let dst_eid = 100u32;
|
|
869
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
870
|
-
setup.set_peer(dst_eid, &peer);
|
|
871
|
-
|
|
872
|
-
// Set outbound rate limit
|
|
873
|
-
let limit = 1_000_000i128;
|
|
874
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, 3600);
|
|
875
|
-
|
|
876
|
-
let amount_ld = 500_000i128;
|
|
877
|
-
let send_param = setup.create_send_param(dst_eid, amount_ld, amount_ld);
|
|
878
|
-
|
|
879
|
-
let (oft_limit, _, _) = setup.oft.quote_oft(&send_param);
|
|
880
|
-
|
|
881
|
-
// max_amount_ld should reflect rate limit capacity
|
|
882
|
-
assert_eq!(oft_limit.max_amount_ld, limit);
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
#[test]
|
|
886
|
-
fn test_quote_oft_no_rate_limit_returns_max() {
|
|
887
|
-
let env = Env::default();
|
|
888
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
889
|
-
|
|
890
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
891
|
-
let fee_collector = create_recipient_address(&env);
|
|
892
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
893
|
-
|
|
894
|
-
let dst_eid = 100u32;
|
|
895
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
896
|
-
setup.set_peer(dst_eid, &peer);
|
|
897
|
-
|
|
898
|
-
// No rate limit set
|
|
899
|
-
|
|
900
|
-
let amount_ld = 500_000i128;
|
|
901
|
-
let send_param = setup.create_send_param(dst_eid, amount_ld, amount_ld);
|
|
902
|
-
|
|
903
|
-
let (oft_limit, _, _) = setup.oft.quote_oft(&send_param);
|
|
904
|
-
|
|
905
|
-
// max_amount_ld should be i128::MAX when no rate limit
|
|
906
|
-
assert_eq!(oft_limit.max_amount_ld, i128::MAX);
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
// ==================== Different Destinations Tests ====================
|
|
910
|
-
|
|
911
|
-
#[test]
|
|
912
|
-
fn test_rate_limits_independent_per_destination() {
|
|
913
|
-
let env = Env::default();
|
|
914
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
915
|
-
|
|
916
|
-
// Set fee deposit address (required by ExtensiveOFT)
|
|
917
|
-
let fee_collector = create_recipient_address(&env);
|
|
918
|
-
setup.set_fee_deposit_address(&fee_collector);
|
|
919
|
-
|
|
920
|
-
let sender = Address::generate(&env);
|
|
921
|
-
|
|
922
|
-
let dst_eid_1 = 100u32;
|
|
923
|
-
let dst_eid_2 = 200u32;
|
|
924
|
-
let peer = BytesN::from_array(&env, &[2u8; 32]);
|
|
925
|
-
setup.set_peer(dst_eid_1, &peer);
|
|
926
|
-
setup.set_peer(dst_eid_2, &peer);
|
|
927
|
-
|
|
928
|
-
// Set different limits for different destinations
|
|
929
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid_1, 1_000_000, 3600);
|
|
930
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid_2, 2_000_000, 3600);
|
|
931
|
-
|
|
932
|
-
// Use all capacity for dst_eid_1
|
|
933
|
-
let amount_1 = 1_000_000i128;
|
|
934
|
-
setup.fund_tokens(&sender, amount_1);
|
|
935
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
936
|
-
|
|
937
|
-
let send_param_1 = setup.create_send_param(dst_eid_1, amount_1, amount_1);
|
|
938
|
-
let fee = MessagingFee { native_fee: setup.native_fee, zro_fee: 0 };
|
|
939
|
-
let oft_receipt_1 = setup.quote_oft(&send_param_1);
|
|
940
|
-
setup.send(&sender, &send_param_1, &fee, &sender, &oft_receipt_1);
|
|
941
|
-
|
|
942
|
-
// dst_eid_1 should have no capacity
|
|
943
|
-
assert_eq!(setup.rate_limit_capacity(&Direction::Outbound, dst_eid_1), 0);
|
|
944
|
-
|
|
945
|
-
// dst_eid_2 should still have full capacity
|
|
946
|
-
assert_eq!(setup.rate_limit_capacity(&Direction::Outbound, dst_eid_2), 2_000_000);
|
|
947
|
-
|
|
948
|
-
// Should be able to send to dst_eid_2
|
|
949
|
-
let amount_2 = 1_500_000i128;
|
|
950
|
-
setup.fund_tokens(&sender, amount_2);
|
|
951
|
-
setup.fund_native_fees(&sender, setup.native_fee);
|
|
952
|
-
|
|
953
|
-
let send_param_2 = setup.create_send_param(dst_eid_2, amount_2, amount_2);
|
|
954
|
-
let oft_receipt_2 = setup.quote_oft(&send_param_2);
|
|
955
|
-
let (msg_receipt, _) = setup.send(&sender, &send_param_2, &fee, &sender, &oft_receipt_2);
|
|
956
|
-
assert!(msg_receipt.nonce > 0);
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
// ==================== Authentication Tests ====================
|
|
960
|
-
|
|
961
|
-
#[test]
|
|
962
|
-
fn test_set_rate_limit_requires_owner_auth() {
|
|
963
|
-
let env = Env::default();
|
|
964
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
965
|
-
|
|
966
|
-
let dst_eid = 100u32;
|
|
967
|
-
let limit = 1_000_000i128;
|
|
968
|
-
let window_seconds = 3600u64;
|
|
969
|
-
|
|
970
|
-
// Try to set rate limit without auth
|
|
971
|
-
let result = setup.oft.try_set_rate_limit(&Direction::Outbound, &dst_eid, &limit, &window_seconds);
|
|
972
|
-
assert!(result.is_err());
|
|
973
|
-
|
|
974
|
-
// Rate limit should not be set
|
|
975
|
-
let (stored_limit, stored_window) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
976
|
-
assert_eq!(stored_limit, 0);
|
|
977
|
-
assert_eq!(stored_window, 0);
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
#[test]
|
|
981
|
-
fn test_set_rate_limit_wrong_auth_fails() {
|
|
982
|
-
let env = Env::default();
|
|
983
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
984
|
-
|
|
985
|
-
let non_owner = Address::generate(&env);
|
|
986
|
-
let dst_eid = 100u32;
|
|
987
|
-
let limit = 1_000_000i128;
|
|
988
|
-
let window_seconds = 3600u64;
|
|
989
|
-
|
|
990
|
-
// Try to set rate limit with wrong auth (non-owner)
|
|
991
|
-
env.mock_auths(&[soroban_sdk::testutils::MockAuth {
|
|
992
|
-
address: &non_owner,
|
|
993
|
-
invoke: &soroban_sdk::testutils::MockAuthInvoke {
|
|
994
|
-
contract: &setup.oft.address,
|
|
995
|
-
fn_name: "set_rate_limit",
|
|
996
|
-
args: (&Direction::Outbound, dst_eid, limit, window_seconds).into_val(&env),
|
|
997
|
-
sub_invokes: &[],
|
|
998
|
-
},
|
|
999
|
-
}]);
|
|
1000
|
-
let result = setup.oft.try_set_rate_limit(&Direction::Outbound, &dst_eid, &limit, &window_seconds);
|
|
1001
|
-
assert!(result.is_err());
|
|
1002
|
-
|
|
1003
|
-
// Rate limit should not be set
|
|
1004
|
-
let (stored_limit, stored_window) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
1005
|
-
assert_eq!(stored_limit, 0);
|
|
1006
|
-
assert_eq!(stored_window, 0);
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
#[test]
|
|
1010
|
-
fn test_set_rate_limit_inbound_requires_owner_auth() {
|
|
1011
|
-
let env = Env::default();
|
|
1012
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
1013
|
-
|
|
1014
|
-
let src_eid = 100u32;
|
|
1015
|
-
let limit = 1_000_000i128;
|
|
1016
|
-
let window_seconds = 3600u64;
|
|
1017
|
-
|
|
1018
|
-
// Try to set inbound rate limit without auth
|
|
1019
|
-
let result = setup.oft.try_set_rate_limit(&Direction::Inbound, &src_eid, &limit, &window_seconds);
|
|
1020
|
-
assert!(result.is_err());
|
|
1021
|
-
|
|
1022
|
-
// Rate limit should not be set
|
|
1023
|
-
let (stored_limit, stored_window) = setup.rate_limit_config(&Direction::Inbound, src_eid);
|
|
1024
|
-
assert_eq!(stored_limit, 0);
|
|
1025
|
-
assert_eq!(stored_window, 0);
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
#[test]
|
|
1029
|
-
fn test_unset_rate_limit_requires_owner_auth() {
|
|
1030
|
-
let env = Env::default();
|
|
1031
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
1032
|
-
|
|
1033
|
-
let dst_eid = 100u32;
|
|
1034
|
-
let limit = 1_000_000i128;
|
|
1035
|
-
let window_seconds = 3600u64;
|
|
1036
|
-
|
|
1037
|
-
// First set rate limit as owner
|
|
1038
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, window_seconds);
|
|
1039
|
-
let (stored_limit, _) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
1040
|
-
assert_eq!(stored_limit, limit);
|
|
1041
|
-
|
|
1042
|
-
// Try to unset rate limit without auth
|
|
1043
|
-
let result = setup.oft.try_unset_rate_limit(&Direction::Outbound, &dst_eid);
|
|
1044
|
-
assert!(result.is_err());
|
|
1045
|
-
|
|
1046
|
-
// Rate limit should still be set
|
|
1047
|
-
let (stored_limit, _) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
1048
|
-
assert_eq!(stored_limit, limit);
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
#[test]
|
|
1052
|
-
fn test_unset_rate_limit_wrong_auth_fails() {
|
|
1053
|
-
let env = Env::default();
|
|
1054
|
-
let setup = ExtensiveOFTTestSetup::new(&env);
|
|
1055
|
-
|
|
1056
|
-
let non_owner = Address::generate(&env);
|
|
1057
|
-
let dst_eid = 100u32;
|
|
1058
|
-
let limit = 1_000_000i128;
|
|
1059
|
-
let window_seconds = 3600u64;
|
|
1060
|
-
|
|
1061
|
-
// First set rate limit as owner
|
|
1062
|
-
setup.set_rate_limit(&Direction::Outbound, dst_eid, limit, window_seconds);
|
|
1063
|
-
|
|
1064
|
-
// Try to unset rate limit with wrong auth (non-owner)
|
|
1065
|
-
env.mock_auths(&[soroban_sdk::testutils::MockAuth {
|
|
1066
|
-
address: &non_owner,
|
|
1067
|
-
invoke: &soroban_sdk::testutils::MockAuthInvoke {
|
|
1068
|
-
contract: &setup.oft.address,
|
|
1069
|
-
fn_name: "unset_rate_limit",
|
|
1070
|
-
args: (&Direction::Outbound, dst_eid).into_val(&env),
|
|
1071
|
-
sub_invokes: &[],
|
|
1072
|
-
},
|
|
1073
|
-
}]);
|
|
1074
|
-
let result = setup.oft.try_unset_rate_limit(&Direction::Outbound, &dst_eid);
|
|
1075
|
-
assert!(result.is_err());
|
|
1076
|
-
|
|
1077
|
-
// Rate limit should still be set
|
|
1078
|
-
let (stored_limit, _) = setup.rate_limit_config(&Direction::Outbound, dst_eid);
|
|
1079
|
-
assert_eq!(stored_limit, limit);
|
|
1080
|
-
}
|