@layerzerolabs/protocol-stellar-v2 0.2.39 → 0.2.41

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.
Files changed (114) hide show
  1. package/.turbo/turbo-build.log +226 -313
  2. package/.turbo/turbo-lint.log +98 -227
  3. package/.turbo/turbo-test.log +1803 -1954
  4. package/contracts/common-macros/src/lib.rs +38 -15
  5. package/contracts/common-macros/src/lz_contract.rs +12 -21
  6. package/contracts/common-macros/src/tests/lz_contract.rs +17 -8
  7. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__lz_contract__snapshot_generated_lz_contract_code.snap +20 -0
  8. package/contracts/common-macros/src/upgradeable.rs +37 -30
  9. package/contracts/endpoint-v2/src/endpoint_v2.rs +4 -3
  10. package/contracts/endpoint-v2/src/errors.rs +2 -2
  11. package/contracts/endpoint-v2/src/messaging_channel.rs +11 -0
  12. package/contracts/endpoint-v2/src/messaging_composer.rs +1 -0
  13. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +12 -25
  14. package/contracts/endpoint-v2/src/tests/endpoint_v2/initializable.rs +4 -4
  15. package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +50 -10
  16. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +6 -35
  17. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +2 -2
  18. package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +50 -1
  19. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +78 -0
  20. package/contracts/endpoint-v2/src/tests/messaging_channel/insert_and_drain_pending_nonces.rs +272 -0
  21. package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +1 -0
  22. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +10 -5
  23. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +30 -0
  24. package/contracts/macro-integration-tests/tests/runtime/oapp/mod.rs +22 -1
  25. package/contracts/macro-integration-tests/tests/runtime/oapp/oapp_core.rs +13 -11
  26. package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +13 -10
  27. package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +15 -11
  28. package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +3 -2
  29. package/contracts/macro-integration-tests/tests/runtime/ownable/two_step_transfer.rs +14 -12
  30. package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +3 -9
  31. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_invalid_inner_option.stderr +24 -1
  32. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.stderr +3 -3
  33. package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/upgradeable_rbac.rs +44 -0
  34. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_all.rs +3 -0
  35. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_single_trait.rs +3 -0
  36. package/contracts/macro-integration-tests/tests/ui/ownable/pass/basic.rs +1 -1
  37. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/attr_args.stderr +1 -1
  38. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.stderr +2 -2
  39. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.stderr +2 -2
  40. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/rbac.rs +44 -0
  41. package/contracts/oapps/counter/integration_tests/utils.rs +5 -3
  42. package/contracts/oapps/counter/src/tests/mod.rs +16 -1
  43. package/contracts/oapps/counter/src/tests/test_counter.rs +5 -2
  44. package/contracts/oapps/oapp/src/oapp_core.rs +21 -7
  45. package/contracts/oapps/oapp/src/oapp_options_type3.rs +7 -5
  46. package/contracts/oapps/oapp/src/tests/mod.rs +21 -0
  47. package/contracts/oapps/oapp/src/tests/oapp_core.rs +12 -10
  48. package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +11 -7
  49. package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +4 -2
  50. package/contracts/oapps/oapp/src/tests/oapp_sender.rs +3 -2
  51. package/contracts/oapps/oapp/src/tests/test_macros.rs +15 -0
  52. package/contracts/oapps/oapp-macros/src/generators.rs +6 -0
  53. package/contracts/oapps/oapp-macros/src/tests/snapshots/oapp_macros__tests__oapp__snapshot_generate_oapp.snap +15 -0
  54. package/contracts/oapps/oft/integration-tests/setup.rs +22 -4
  55. package/contracts/oapps/oft/integration-tests/utils.rs +94 -13
  56. package/contracts/oapps/oft/src/extensions/oft_fee.rs +23 -10
  57. package/contracts/oapps/oft/src/extensions/pausable.rs +31 -10
  58. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +9 -4
  59. package/contracts/oapps/oft/src/oft.rs +1 -2
  60. package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +39 -27
  61. package/contracts/oapps/oft/src/tests/extensions/pausable.rs +38 -24
  62. package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +87 -69
  63. package/contracts/oapps/oft-core/integration-tests/setup.rs +27 -3
  64. package/contracts/oapps/oft-core/src/oft_core.rs +10 -5
  65. package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +20 -20
  66. package/contracts/oapps/oft-core/src/tests/test_utils.rs +31 -3
  67. package/contracts/upgrader/src/lib.rs +67 -30
  68. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract3.wasm +0 -0
  69. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract4.wasm +0 -0
  70. package/contracts/upgrader/src/tests/test_upgrader.rs +50 -4
  71. package/contracts/utils/src/ownable.rs +16 -5
  72. package/contracts/utils/src/tests/ownable.rs +39 -39
  73. package/contracts/utils/src/upgradeable.rs +60 -17
  74. package/docs/oapp-guide.md +4 -4
  75. package/package.json +3 -4
  76. package/sdk/.turbo/turbo-test.log +381 -366
  77. package/sdk/dist/generated/bml.d.ts +4 -4
  78. package/sdk/dist/generated/bml.js +6 -6
  79. package/sdk/dist/generated/counter.d.ts +158 -12
  80. package/sdk/dist/generated/counter.js +32 -12
  81. package/sdk/dist/generated/dvn.d.ts +4 -6
  82. package/sdk/dist/generated/dvn.js +8 -8
  83. package/sdk/dist/generated/dvn_fee_lib.d.ts +8 -10
  84. package/sdk/dist/generated/dvn_fee_lib.js +8 -8
  85. package/sdk/dist/generated/endpoint.d.ts +9 -9
  86. package/sdk/dist/generated/endpoint.js +9 -9
  87. package/sdk/dist/generated/executor.d.ts +9 -11
  88. package/sdk/dist/generated/executor.js +11 -11
  89. package/sdk/dist/generated/executor_fee_lib.d.ts +9 -11
  90. package/sdk/dist/generated/executor_fee_lib.js +11 -11
  91. package/sdk/dist/generated/executor_helper.d.ts +4 -4
  92. package/sdk/dist/generated/executor_helper.js +6 -6
  93. package/sdk/dist/generated/layerzero_view.d.ts +9 -11
  94. package/sdk/dist/generated/layerzero_view.js +11 -11
  95. package/sdk/dist/generated/oft.d.ts +194 -27
  96. package/sdk/dist/generated/oft.js +44 -22
  97. package/sdk/dist/generated/price_feed.d.ts +8 -10
  98. package/sdk/dist/generated/price_feed.js +8 -8
  99. package/sdk/dist/generated/sac_manager.d.ts +8 -8
  100. package/sdk/dist/generated/sac_manager.js +6 -6
  101. package/sdk/dist/generated/sml.d.ts +9 -9
  102. package/sdk/dist/generated/sml.js +9 -9
  103. package/sdk/dist/generated/treasury.d.ts +9 -9
  104. package/sdk/dist/generated/treasury.js +9 -9
  105. package/sdk/dist/generated/uln302.d.ts +9 -9
  106. package/sdk/dist/generated/uln302.js +9 -9
  107. package/sdk/dist/generated/upgrader.d.ts +25 -16
  108. package/sdk/dist/generated/upgrader.js +5 -5
  109. package/sdk/package.json +1 -1
  110. package/sdk/test/counter-sml.test.ts +20 -0
  111. package/sdk/test/counter-uln.test.ts +20 -0
  112. package/sdk/test/oft-sml.test.ts +22 -0
  113. package/sdk/test/upgrader.test.ts +1 -0
  114. package/turbo.json +1 -8
@@ -1,7 +1,9 @@
1
1
  extern crate std;
2
2
 
3
3
  use crate::extensions::pausable::{OFTPausable, OFTPausableError, OFTPausableInternal};
4
- use soroban_sdk::{contract, contractimpl, Address, Env};
4
+ use crate::extensions::pausable::{PAUSER_ROLE, UNPAUSER_ROLE};
5
+ use soroban_sdk::{contract, contractimpl, Address, Env, Symbol};
6
+ use utils::rbac::{grant_role_no_auth, RoleBasedAccessControl};
5
7
  use utils::auth::Auth;
6
8
 
7
9
  // ============================================================================
@@ -22,8 +24,18 @@ impl OFTPausableInternal for PausableTestContract {}
22
24
  #[contractimpl(contracttrait)]
23
25
  impl OFTPausable for PausableTestContract {}
24
26
 
27
+ #[contractimpl(contracttrait)]
28
+ impl RoleBasedAccessControl for PausableTestContract {}
29
+
25
30
  #[contractimpl]
26
31
  impl PausableTestContract {
32
+ /// Test-only: grants PAUSER_ROLE and UNPAUSER_ROLE to the contract.
33
+ pub fn init_roles(env: Env) {
34
+ let contract_id = env.current_contract_address();
35
+ grant_role_no_auth(&env, &contract_id, &Symbol::new(&env, PAUSER_ROLE), &contract_id);
36
+ grant_role_no_auth(&env, &contract_id, &Symbol::new(&env, UNPAUSER_ROLE), &contract_id);
37
+ }
38
+
27
39
  pub fn assert_not_paused(env: Env) {
28
40
  <Self as OFTPausableInternal>::__assert_not_paused(&env)
29
41
  }
@@ -35,6 +47,7 @@ impl PausableTestContract {
35
47
 
36
48
  struct TestSetup {
37
49
  client: PausableTestContractClient<'static>,
50
+ contract_id: Address,
38
51
  }
39
52
 
40
53
  fn setup() -> TestSetup {
@@ -43,7 +56,8 @@ fn setup() -> TestSetup {
43
56
 
44
57
  let contract_id = env.register(PausableTestContract, ());
45
58
  let client = PausableTestContractClient::new(&env, &contract_id);
46
- TestSetup { client }
59
+ client.init_roles();
60
+ TestSetup { client, contract_id }
47
61
  }
48
62
 
49
63
  // ============================================================================
@@ -58,45 +72,45 @@ fn test_initial_state_is_not_paused() {
58
72
  }
59
73
 
60
74
  // ============================================================================
61
- // Set Paused Tests
75
+ // Pause/Unpause Tests
62
76
  // ============================================================================
63
77
 
64
78
  #[test]
65
- fn test_set_paused_to_true() {
66
- let TestSetup { client, .. } = setup();
79
+ fn test_pause_sets_paused() {
80
+ let TestSetup { client, contract_id, .. } = setup();
67
81
 
68
- client.set_paused(&true);
82
+ client.pause(&contract_id);
69
83
  assert!(client.is_paused());
70
84
  }
71
85
 
72
86
  #[test]
73
- fn test_set_paused_to_false_after_pausing() {
74
- let TestSetup { client, .. } = setup();
87
+ fn test_unpause_after_pausing() {
88
+ let TestSetup { client, contract_id, .. } = setup();
75
89
 
76
- client.set_paused(&true);
90
+ client.pause(&contract_id);
77
91
  assert!(client.is_paused());
78
92
 
79
- client.set_paused(&false);
93
+ client.unpause(&contract_id);
80
94
  assert!(!client.is_paused());
81
95
  }
82
96
 
83
97
  #[test]
84
- fn test_set_paused_rejects_same_value_when_unpaused() {
85
- let TestSetup { client, .. } = setup();
98
+ fn test_unpause_unchanged_when_unpaused() {
99
+ let TestSetup { client, contract_id, .. } = setup();
86
100
 
87
- // Initially not paused, setting to false should fail
88
- let res = client.try_set_paused(&false);
101
+ // Initially not paused, unpause should fail
102
+ let res = client.try_unpause(&contract_id);
89
103
  assert_eq!(res.err().unwrap().ok().unwrap(), OFTPausableError::PauseStatusUnchanged.into());
90
104
  }
91
105
 
92
106
  #[test]
93
- fn test_set_paused_rejects_same_value_when_paused() {
94
- let TestSetup { client, .. } = setup();
107
+ fn test_pause_unchanged_when_paused() {
108
+ let TestSetup { client, contract_id, .. } = setup();
95
109
 
96
- client.set_paused(&true);
110
+ client.pause(&contract_id);
97
111
 
98
- // Already paused, setting to true should fail
99
- let res = client.try_set_paused(&true);
112
+ // Already paused, pause again should fail
113
+ let res = client.try_pause(&contract_id);
100
114
  assert_eq!(res.err().unwrap().ok().unwrap(), OFTPausableError::PauseStatusUnchanged.into());
101
115
  }
102
116
 
@@ -114,9 +128,9 @@ fn test_assert_not_paused_succeeds_when_not_paused() {
114
128
 
115
129
  #[test]
116
130
  fn test_assert_not_paused_fails_when_paused() {
117
- let TestSetup { client, .. } = setup();
131
+ let TestSetup { client, contract_id, .. } = setup();
118
132
 
119
- client.set_paused(&true);
133
+ client.pause(&contract_id);
120
134
 
121
135
  let res = client.try_assert_not_paused();
122
136
  assert_eq!(res.err().unwrap().ok().unwrap(), OFTPausableError::Paused.into());
@@ -128,14 +142,14 @@ fn test_assert_not_paused_fails_when_paused() {
128
142
 
129
143
  #[test]
130
144
  fn test_pause_unpause_toggle_multiple_times() {
131
- let TestSetup { client, .. } = setup();
145
+ let TestSetup { client, contract_id, .. } = setup();
132
146
 
133
147
  // Toggle multiple times
134
148
  for _ in 0..3 {
135
149
  assert!(!client.is_paused());
136
- client.set_paused(&true);
150
+ client.pause(&contract_id);
137
151
  assert!(client.is_paused());
138
- client.set_paused(&false);
152
+ client.unpause(&contract_id);
139
153
  }
140
154
  assert!(!client.is_paused());
141
155
  }
@@ -4,8 +4,10 @@ use crate as oft;
4
4
  use crate::extensions::rate_limiter::{
5
5
  Direction, Mode, RateLimitConfig, RateLimitError, RateLimiter, RateLimiterInternal,
6
6
  };
7
- use soroban_sdk::{contract, contractimpl, testutils::Ledger as _, Address, Env};
7
+ use crate::extensions::rate_limiter::RATE_LIMITER_ADMIN_ROLE;
8
+ use soroban_sdk::{contract, contractimpl, testutils::Ledger as _, Address, Env, Symbol};
8
9
  use utils::auth::Auth;
10
+ use utils::rbac::{grant_role_no_auth, RoleBasedAccessControl};
9
11
 
10
12
  // ============================================================================
11
13
  // Test Contract
@@ -25,8 +27,22 @@ impl RateLimiterInternal for RateLimiterTestContract {}
25
27
  #[contractimpl(contracttrait)]
26
28
  impl RateLimiter for RateLimiterTestContract {}
27
29
 
30
+ #[contractimpl(contracttrait)]
31
+ impl RoleBasedAccessControl for RateLimiterTestContract {}
32
+
28
33
  #[contractimpl]
29
34
  impl RateLimiterTestContract {
35
+ /// Test-only: grants RATE_LIMITER_ADMIN_ROLE to the contract.
36
+ pub fn init_roles(env: Env) {
37
+ let contract_id = env.current_contract_address();
38
+ grant_role_no_auth(
39
+ &env,
40
+ &contract_id,
41
+ &Symbol::new(&env, RATE_LIMITER_ADMIN_ROLE),
42
+ &contract_id,
43
+ );
44
+ }
45
+
30
46
  pub fn consume(env: Env, direction: Direction, eid: u32, amount: i128) {
31
47
  <Self as RateLimiterInternal>::__consume_rate_limit_capacity(&env, &direction, eid, amount)
32
48
  }
@@ -43,6 +59,7 @@ impl RateLimiterTestContract {
43
59
  struct TestSetup {
44
60
  env: Env,
45
61
  client: RateLimiterTestContractClient<'static>,
62
+ contract_id: Address,
46
63
  }
47
64
 
48
65
  fn setup() -> TestSetup {
@@ -53,7 +70,8 @@ fn setup() -> TestSetup {
53
70
 
54
71
  let contract_id = env.register(RateLimiterTestContract, ());
55
72
  let client = RateLimiterTestContractClient::new(&env, &contract_id);
56
- TestSetup { env, client }
73
+ client.init_roles();
74
+ TestSetup { env, client, contract_id }
57
75
  }
58
76
 
59
77
  fn config(limit: i128, window_seconds: u64) -> RateLimitConfig {
@@ -93,29 +111,29 @@ fn test_no_config_consume_and_release_are_noop() {
93
111
 
94
112
  #[test]
95
113
  fn test_set_rate_limit_rejects_invalid_config() {
96
- let TestSetup { client, .. } = setup();
114
+ let TestSetup { client, contract_id, .. } = setup();
97
115
 
98
116
  // Invalid: window_seconds == 0
99
- let res = client.try_set_rate_limit(&Direction::Outbound, &1u32, &Some(config(10, 0)));
117
+ let res = client.try_set_rate_limit(&Direction::Outbound, &1u32, &Some(config(10, 0)), &contract_id);
100
118
  assert_eq!(res.err().unwrap().ok().unwrap(), RateLimitError::InvalidConfig.into());
101
119
 
102
120
  // Invalid: limit < 0
103
- let res2 = client.try_set_rate_limit(&Direction::Outbound, &1u32, &Some(config(-1, 10)));
121
+ let res2 = client.try_set_rate_limit(&Direction::Outbound, &1u32, &Some(config(-1, 10)), &contract_id);
104
122
  assert_eq!(res2.err().unwrap().ok().unwrap(), RateLimitError::InvalidConfig.into());
105
123
  }
106
124
 
107
125
  #[test]
108
126
  fn test_set_rate_limit_rejects_same_value() {
109
- let TestSetup { client, .. } = setup();
127
+ let TestSetup { client, contract_id, .. } = setup();
110
128
 
111
129
  // SameValue when removing a non-existent config.
112
- let res = client.try_set_rate_limit(&Direction::Outbound, &1u32, &None);
130
+ let res = client.try_set_rate_limit(&Direction::Outbound, &1u32, &None, &contract_id);
113
131
  assert_eq!(res.err().unwrap().ok().unwrap(), RateLimitError::SameValue.into());
114
132
 
115
133
  // Set a valid config; setting same again should be SameValue.
116
134
  let cfg = config(100, 10);
117
- client.set_rate_limit(&Direction::Outbound, &1u32, &Some(cfg.clone()));
118
- let res2 = client.try_set_rate_limit(&Direction::Outbound, &1u32, &Some(cfg));
135
+ client.set_rate_limit(&Direction::Outbound, &1u32, &Some(cfg.clone()), &contract_id);
136
+ let res2 = client.try_set_rate_limit(&Direction::Outbound, &1u32, &Some(cfg), &contract_id);
119
137
  assert_eq!(res2.err().unwrap().ok().unwrap(), RateLimitError::SameValue.into());
120
138
  }
121
139
 
@@ -125,9 +143,9 @@ fn test_set_rate_limit_rejects_same_value() {
125
143
 
126
144
  #[test]
127
145
  fn test_consume_rejects_negative_amount() {
128
- let TestSetup { client, .. } = setup();
146
+ let TestSetup { client, contract_id, .. } = setup();
129
147
 
130
- client.set_rate_limit(&Direction::Outbound, &1u32, &Some(config(100, 100)));
148
+ client.set_rate_limit(&Direction::Outbound, &1u32, &Some(config(100, 100)), &contract_id);
131
149
 
132
150
  let res = client.try_consume(&Direction::Outbound, &1u32, &-1i128);
133
151
  assert_eq!(res.err().unwrap().ok().unwrap(), RateLimitError::InvalidAmount.into());
@@ -135,9 +153,9 @@ fn test_consume_rejects_negative_amount() {
135
153
 
136
154
  #[test]
137
155
  fn test_release_rejects_negative_amount() {
138
- let TestSetup { client, .. } = setup();
156
+ let TestSetup { client, contract_id, .. } = setup();
139
157
 
140
- client.set_rate_limit(&Direction::Outbound, &1u32, &Some(config(100, 100)));
158
+ client.set_rate_limit(&Direction::Outbound, &1u32, &Some(config(100, 100)), &contract_id);
141
159
 
142
160
  let res = client.try_release(&Direction::Outbound, &1u32, &-1i128);
143
161
  assert_eq!(res.err().unwrap().ok().unwrap(), RateLimitError::InvalidAmount.into());
@@ -145,11 +163,11 @@ fn test_release_rejects_negative_amount() {
145
163
 
146
164
  #[test]
147
165
  fn test_consume_within_capacity() {
148
- let TestSetup { client, .. } = setup();
166
+ let TestSetup { client, contract_id, .. } = setup();
149
167
  let direction = Direction::Outbound;
150
168
  let eid = 77u32;
151
169
 
152
- client.set_rate_limit(&direction, &eid, &Some(config(100, 100)));
170
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 100)), &contract_id);
153
171
 
154
172
  client.consume(&direction, &eid, &60i128);
155
173
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 60);
@@ -158,11 +176,11 @@ fn test_consume_within_capacity() {
158
176
 
159
177
  #[test]
160
178
  fn test_consume_exceeds_capacity() {
161
- let TestSetup { client, .. } = setup();
179
+ let TestSetup { client, contract_id, .. } = setup();
162
180
  let direction = Direction::Outbound;
163
181
  let eid = 77u32;
164
182
 
165
- client.set_rate_limit(&direction, &eid, &Some(config(100, 100)));
183
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 100)), &contract_id);
166
184
  client.consume(&direction, &eid, &60i128);
167
185
 
168
186
  let res = client.try_consume(&direction, &eid, &41i128);
@@ -171,11 +189,11 @@ fn test_consume_exceeds_capacity() {
171
189
 
172
190
  #[test]
173
191
  fn test_release_reduces_in_flight() {
174
- let TestSetup { client, .. } = setup();
192
+ let TestSetup { client, contract_id, .. } = setup();
175
193
  let direction = Direction::Outbound;
176
194
  let eid = 77u32;
177
195
 
178
- client.set_rate_limit(&direction, &eid, &Some(config(100, 100)));
196
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 100)), &contract_id);
179
197
  client.consume(&direction, &eid, &60i128);
180
198
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 60);
181
199
 
@@ -194,12 +212,12 @@ fn test_release_reduces_in_flight() {
194
212
 
195
213
  #[test]
196
214
  fn test_decay_reduces_in_flight_over_time() {
197
- let TestSetup { env, client } = setup();
215
+ let TestSetup { env, client, contract_id } = setup();
198
216
  let direction = Direction::Outbound;
199
217
  let eid = 5u32;
200
218
 
201
219
  env.ledger().set_timestamp(1_000);
202
- client.set_rate_limit(&direction, &eid, &Some(config(100, 10)));
220
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 10)), &contract_id);
203
221
 
204
222
  client.consume(&direction, &eid, &100i128);
205
223
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 100);
@@ -212,12 +230,12 @@ fn test_decay_reduces_in_flight_over_time() {
212
230
 
213
231
  #[test]
214
232
  fn test_timestamp_regression_errors() {
215
- let TestSetup { env, client } = setup();
233
+ let TestSetup { env, client, contract_id } = setup();
216
234
  let direction = Direction::Outbound;
217
235
  let eid = 5u32;
218
236
 
219
237
  env.ledger().set_timestamp(1_000);
220
- client.set_rate_limit(&direction, &eid, &Some(config(100, 10)));
238
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 10)), &contract_id);
221
239
  client.consume(&direction, &eid, &100i128);
222
240
 
223
241
  // Set timestamp backwards => should error.
@@ -232,17 +250,17 @@ fn test_timestamp_regression_errors() {
232
250
 
233
251
  #[test]
234
252
  fn test_updating_config_checkpoints_in_flight() {
235
- let TestSetup { env, client } = setup();
253
+ let TestSetup { env, client, contract_id } = setup();
236
254
  let direction = Direction::Outbound;
237
255
  let eid = 42u32;
238
256
 
239
257
  env.ledger().set_timestamp(1_000);
240
- client.set_rate_limit(&direction, &eid, &Some(config(100, 10)));
258
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 10)), &contract_id);
241
259
  client.consume(&direction, &eid, &100i128);
242
260
 
243
261
  // Move forward, then update config.
244
262
  env.ledger().set_timestamp(1_005);
245
- client.set_rate_limit(&direction, &eid, &Some(config(200, 20)));
263
+ client.set_rate_limit(&direction, &eid, &Some(config(200, 20)), &contract_id);
246
264
 
247
265
  // At t=1005, old config would have decayed to 50.
248
266
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 50);
@@ -255,29 +273,29 @@ fn test_updating_config_checkpoints_in_flight() {
255
273
 
256
274
  #[test]
257
275
  fn test_reducing_limit_below_in_flight_clamps_capacity() {
258
- let TestSetup { env, client } = setup();
276
+ let TestSetup { env, client, contract_id } = setup();
259
277
  let direction = Direction::Inbound;
260
278
  let eid = 123u32;
261
279
 
262
280
  env.ledger().set_timestamp(1_000);
263
- client.set_rate_limit(&direction, &eid, &Some(config(100, 100)));
281
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 100)), &contract_id);
264
282
  client.consume(&direction, &eid, &90i128);
265
283
 
266
284
  // Reduce limit below in-flight.
267
- client.set_rate_limit(&direction, &eid, &Some(config(50, 100)));
285
+ client.set_rate_limit(&direction, &eid, &Some(config(50, 100)), &contract_id);
268
286
  assert_eq!(client.rate_limit_capacity(&direction, &eid), 0);
269
287
  }
270
288
 
271
289
  #[test]
272
290
  fn test_removing_rate_limit_makes_unlimited() {
273
- let TestSetup { client, .. } = setup();
291
+ let TestSetup { client, contract_id, .. } = setup();
274
292
  let direction = Direction::Inbound;
275
293
  let eid = 321u32;
276
294
 
277
- client.set_rate_limit(&direction, &eid, &Some(config(10, 10)));
295
+ client.set_rate_limit(&direction, &eid, &Some(config(10, 10)), &contract_id);
278
296
  assert_eq!(client.rate_limit_capacity(&direction, &eid), 10);
279
297
 
280
- client.set_rate_limit(&direction, &eid, &None);
298
+ client.set_rate_limit(&direction, &eid, &None, &contract_id);
281
299
  assert_eq!(client.rate_limit_capacity(&direction, &eid), i128::MAX);
282
300
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 0);
283
301
  }
@@ -296,12 +314,12 @@ fn test_rate_limit_config_returns_none_when_unset() {
296
314
 
297
315
  #[test]
298
316
  fn test_rate_limit_config_returns_config_when_set() {
299
- let TestSetup { client, .. } = setup();
317
+ let TestSetup { client, contract_id, .. } = setup();
300
318
  let direction = Direction::Outbound;
301
319
  let eid = 42u32;
302
320
 
303
321
  let cfg = config(500, 60);
304
- client.set_rate_limit(&direction, &eid, &Some(cfg.clone()));
322
+ client.set_rate_limit(&direction, &eid, &Some(cfg.clone()), &contract_id);
305
323
 
306
324
  let result = client.rate_limit_config(&direction, &eid);
307
325
  assert_eq!(result, Some(cfg));
@@ -309,14 +327,14 @@ fn test_rate_limit_config_returns_config_when_set() {
309
327
 
310
328
  #[test]
311
329
  fn test_rate_limit_config_returns_none_after_removal() {
312
- let TestSetup { client, .. } = setup();
330
+ let TestSetup { client, contract_id, .. } = setup();
313
331
  let direction = Direction::Inbound;
314
332
  let eid = 77u32;
315
333
 
316
- client.set_rate_limit(&direction, &eid, &Some(config(100, 10)));
334
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 10)), &contract_id);
317
335
  assert!(client.rate_limit_config(&direction, &eid).is_some());
318
336
 
319
- client.set_rate_limit(&direction, &eid, &None);
337
+ client.set_rate_limit(&direction, &eid, &None, &contract_id);
320
338
  assert_eq!(client.rate_limit_config(&direction, &eid), None);
321
339
  }
322
340
 
@@ -326,12 +344,12 @@ fn test_rate_limit_config_returns_none_after_removal() {
326
344
 
327
345
  #[test]
328
346
  fn test_inbound_outbound_are_independent() {
329
- let TestSetup { client, .. } = setup();
347
+ let TestSetup { client, contract_id, .. } = setup();
330
348
  let eid = 10u32;
331
349
 
332
350
  // Set different configs for inbound and outbound
333
- client.set_rate_limit(&Direction::Inbound, &eid, &Some(config(100, 10)));
334
- client.set_rate_limit(&Direction::Outbound, &eid, &Some(config(200, 20)));
351
+ client.set_rate_limit(&Direction::Inbound, &eid, &Some(config(100, 10)), &contract_id);
352
+ client.set_rate_limit(&Direction::Outbound, &eid, &Some(config(200, 20)), &contract_id);
335
353
 
336
354
  assert_eq!(client.rate_limit_config(&Direction::Inbound, &eid), Some(config(100, 10)));
337
355
  assert_eq!(client.rate_limit_config(&Direction::Outbound, &eid), Some(config(200, 20)));
@@ -344,11 +362,11 @@ fn test_inbound_outbound_are_independent() {
344
362
 
345
363
  #[test]
346
364
  fn test_different_eids_are_independent() {
347
- let TestSetup { client, .. } = setup();
365
+ let TestSetup { client, contract_id, .. } = setup();
348
366
  let direction = Direction::Outbound;
349
367
 
350
- client.set_rate_limit(&direction, &1u32, &Some(config(100, 10)));
351
- client.set_rate_limit(&direction, &2u32, &Some(config(200, 20)));
368
+ client.set_rate_limit(&direction, &1u32, &Some(config(100, 10)), &contract_id);
369
+ client.set_rate_limit(&direction, &2u32, &Some(config(200, 20)), &contract_id);
352
370
 
353
371
  client.consume(&direction, &1u32, &50i128);
354
372
  assert_eq!(client.rate_limit_in_flight(&direction, &1u32), 50);
@@ -361,11 +379,11 @@ fn test_different_eids_are_independent() {
361
379
 
362
380
  #[test]
363
381
  fn test_gross_mode_does_not_release_capacity() {
364
- let TestSetup { client, .. } = setup();
382
+ let TestSetup { client, contract_id, .. } = setup();
365
383
  let direction = Direction::Outbound;
366
384
  let eid = 77u32;
367
385
 
368
- client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Gross)));
386
+ client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Gross)), &contract_id);
369
387
  client.consume(&direction, &eid, &60i128);
370
388
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 60);
371
389
 
@@ -376,11 +394,11 @@ fn test_gross_mode_does_not_release_capacity() {
376
394
 
377
395
  #[test]
378
396
  fn test_net_mode_does_release_capacity() {
379
- let TestSetup { client, .. } = setup();
397
+ let TestSetup { client, contract_id, .. } = setup();
380
398
  let direction = Direction::Outbound;
381
399
  let eid = 77u32;
382
400
 
383
- client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Net)));
401
+ client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Net)), &contract_id);
384
402
  client.consume(&direction, &eid, &60i128);
385
403
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 60);
386
404
 
@@ -391,11 +409,11 @@ fn test_net_mode_does_release_capacity() {
391
409
 
392
410
  #[test]
393
411
  fn test_gross_mode_enforces_absolute_limit() {
394
- let TestSetup { client, .. } = setup();
412
+ let TestSetup { client, contract_id, .. } = setup();
395
413
  let direction = Direction::Outbound;
396
414
  let eid = 1u32;
397
415
 
398
- client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Gross)));
416
+ client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Gross)), &contract_id);
399
417
 
400
418
  // Consume 80
401
419
  client.consume(&direction, &eid, &80i128);
@@ -418,12 +436,12 @@ fn test_gross_mode_enforces_absolute_limit() {
418
436
 
419
437
  #[test]
420
438
  fn test_gross_mode_decay_still_works() {
421
- let TestSetup { env, client } = setup();
439
+ let TestSetup { env, client, contract_id } = setup();
422
440
  let direction = Direction::Outbound;
423
441
  let eid = 1u32;
424
442
 
425
443
  env.ledger().set_timestamp(1_000);
426
- client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 10, Mode::Gross)));
444
+ client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 10, Mode::Gross)), &contract_id);
427
445
 
428
446
  // Consume full capacity
429
447
  client.consume(&direction, &eid, &100i128);
@@ -441,18 +459,18 @@ fn test_gross_mode_decay_still_works() {
441
459
 
442
460
  #[test]
443
461
  fn test_switching_from_net_to_gross_mode() {
444
- let TestSetup { client, .. } = setup();
462
+ let TestSetup { client, contract_id, .. } = setup();
445
463
  let direction = Direction::Outbound;
446
464
  let eid = 1u32;
447
465
 
448
466
  // Start with Net mode
449
- client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Net)));
467
+ client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Net)), &contract_id);
450
468
  client.consume(&direction, &eid, &60i128);
451
469
  client.release(&direction, &eid, &20i128);
452
470
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 40, "Net mode should release");
453
471
 
454
472
  // Switch to Gross mode
455
- client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Gross)));
473
+ client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Gross)), &contract_id);
456
474
 
457
475
  // in-flight should be checkpointed
458
476
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 40);
@@ -464,18 +482,18 @@ fn test_switching_from_net_to_gross_mode() {
464
482
 
465
483
  #[test]
466
484
  fn test_switching_from_gross_to_net_mode() {
467
- let TestSetup { client, .. } = setup();
485
+ let TestSetup { client, contract_id, .. } = setup();
468
486
  let direction = Direction::Outbound;
469
487
  let eid = 1u32;
470
488
 
471
489
  // Start with Gross mode
472
- client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Gross)));
490
+ client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Gross)), &contract_id);
473
491
  client.consume(&direction, &eid, &60i128);
474
492
  client.release(&direction, &eid, &20i128);
475
493
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 60, "Gross mode should not release");
476
494
 
477
495
  // Switch to Net mode
478
- client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Net)));
496
+ client.set_rate_limit(&direction, &eid, &Some(config_with_mode(100, 100, Mode::Net)), &contract_id);
479
497
 
480
498
  // in-flight should be checkpointed
481
499
  assert_eq!(client.rate_limit_in_flight(&direction, &eid), 60);
@@ -491,11 +509,11 @@ fn test_switching_from_gross_to_net_mode() {
491
509
 
492
510
  #[test]
493
511
  fn test_consume_zero_amount_succeeds() {
494
- let TestSetup { client, .. } = setup();
512
+ let TestSetup { client, contract_id, .. } = setup();
495
513
  let direction = Direction::Outbound;
496
514
  let eid = 1u32;
497
515
 
498
- client.set_rate_limit(&direction, &eid, &Some(config(100, 100)));
516
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 100)), &contract_id);
499
517
 
500
518
  // Consuming zero should succeed
501
519
  client.consume(&direction, &eid, &0i128);
@@ -504,11 +522,11 @@ fn test_consume_zero_amount_succeeds() {
504
522
 
505
523
  #[test]
506
524
  fn test_release_zero_amount_succeeds() {
507
- let TestSetup { client, .. } = setup();
525
+ let TestSetup { client, contract_id, .. } = setup();
508
526
  let direction = Direction::Outbound;
509
527
  let eid = 1u32;
510
528
 
511
- client.set_rate_limit(&direction, &eid, &Some(config(100, 100)));
529
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 100)), &contract_id);
512
530
  client.consume(&direction, &eid, &50i128);
513
531
 
514
532
  // Releasing zero should succeed
@@ -518,11 +536,11 @@ fn test_release_zero_amount_succeeds() {
518
536
 
519
537
  #[test]
520
538
  fn test_consume_exact_capacity() {
521
- let TestSetup { client, .. } = setup();
539
+ let TestSetup { client, contract_id, .. } = setup();
522
540
  let direction = Direction::Outbound;
523
541
  let eid = 1u32;
524
542
 
525
- client.set_rate_limit(&direction, &eid, &Some(config(100, 100)));
543
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 100)), &contract_id);
526
544
 
527
545
  // Consuming exact capacity should succeed
528
546
  client.consume(&direction, &eid, &100i128);
@@ -532,12 +550,12 @@ fn test_consume_exact_capacity() {
532
550
 
533
551
  #[test]
534
552
  fn test_decay_fully_restores_capacity() {
535
- let TestSetup { env, client } = setup();
553
+ let TestSetup { env, client, contract_id } = setup();
536
554
  let direction = Direction::Outbound;
537
555
  let eid = 1u32;
538
556
 
539
557
  env.ledger().set_timestamp(1_000);
540
- client.set_rate_limit(&direction, &eid, &Some(config(100, 10)));
558
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 10)), &contract_id);
541
559
 
542
560
  client.consume(&direction, &eid, &100i128);
543
561
  assert_eq!(client.rate_limit_capacity(&direction, &eid), 0);
@@ -550,12 +568,12 @@ fn test_decay_fully_restores_capacity() {
550
568
 
551
569
  #[test]
552
570
  fn test_decay_beyond_window_clamps_to_zero() {
553
- let TestSetup { env, client } = setup();
571
+ let TestSetup { env, client, contract_id } = setup();
554
572
  let direction = Direction::Outbound;
555
573
  let eid = 1u32;
556
574
 
557
575
  env.ledger().set_timestamp(1_000);
558
- client.set_rate_limit(&direction, &eid, &Some(config(100, 10)));
576
+ client.set_rate_limit(&direction, &eid, &Some(config(100, 10)), &contract_id);
559
577
 
560
578
  client.consume(&direction, &eid, &50i128);
561
579
 
@@ -566,12 +584,12 @@ fn test_decay_beyond_window_clamps_to_zero() {
566
584
 
567
585
  #[test]
568
586
  fn test_limit_zero_blocks_all_consumption() {
569
- let TestSetup { client, .. } = setup();
587
+ let TestSetup { client, contract_id, .. } = setup();
570
588
  let direction = Direction::Outbound;
571
589
  let eid = 1u32;
572
590
 
573
591
  // Set limit to 0 (valid config)
574
- client.set_rate_limit(&direction, &eid, &Some(config(0, 10)));
592
+ client.set_rate_limit(&direction, &eid, &Some(config(0, 10)), &contract_id);
575
593
  assert_eq!(client.rate_limit_capacity(&direction, &eid), 0);
576
594
 
577
595
  // Any non-zero consumption should fail