@layerzerolabs/protocol-stellar-v2 0.2.34 → 0.2.36

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 (135) hide show
  1. package/.turbo/turbo-build.log +281 -276
  2. package/.turbo/turbo-lint.log +209 -211
  3. package/.turbo/turbo-test.log +1705 -1701
  4. package/Cargo.lock +10 -10
  5. package/Cargo.toml +1 -1
  6. package/contracts/common-macros/src/auth.rs +5 -5
  7. package/contracts/common-macros/src/lib.rs +69 -0
  8. package/contracts/common-macros/src/rbac.rs +90 -0
  9. package/contracts/common-macros/src/storage.rs +7 -5
  10. package/contracts/common-macros/src/tests/lz_contract.rs +5 -7
  11. package/contracts/common-macros/src/tests/mod.rs +1 -0
  12. package/contracts/common-macros/src/tests/rbac.rs +420 -0
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +4 -4
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +5 -12
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__rbac__snapshot_preserve_function_signature.snap +17 -0
  16. package/contracts/common-macros/src/tests/storage/parse_name.rs +0 -1
  17. package/contracts/common-macros/src/tests/storage/snapshots/common_macros__tests__storage__generate_storage__snapshot_generated_storage_code.snap +3 -3
  18. package/contracts/endpoint-v2/src/endpoint_v2.rs +5 -4
  19. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +7 -8
  20. package/contracts/endpoint-v2/src/messaging_channel.rs +78 -45
  21. package/contracts/endpoint-v2/src/storage.rs +8 -3
  22. package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +2 -2
  23. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +12 -15
  24. package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +46 -9
  25. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +7 -23
  26. package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +23 -20
  27. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +94 -1
  28. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_nonce.rs +17 -15
  29. package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +1 -1
  30. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +48 -13
  31. package/contracts/endpoint-v2/src/tests/messaging_channel/pending_inbound_nonces.rs +111 -0
  32. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +15 -25
  33. package/contracts/layerzero-views/src/layerzero_view.rs +2 -2
  34. package/contracts/layerzero-views/src/tests/layerzero_view_tests.rs +3 -4
  35. package/contracts/layerzero-views/src/tests/setup.rs +0 -21
  36. package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_default.rs +1 -1
  37. package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_multisig.rs +1 -1
  38. package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_multisig_upgradeable.rs +1 -1
  39. package/contracts/macro-integration-tests/tests/runtime/multisig/self_auth.rs +1 -1
  40. package/contracts/macro-integration-tests/tests/runtime/ownable/initialization.rs +8 -5
  41. package/contracts/macro-integration-tests/tests/runtime/ownable/ownership_transfer.rs +2 -2
  42. package/contracts/macro-integration-tests/tests/runtime/rbac/guard_behavior.rs +91 -0
  43. package/contracts/macro-integration-tests/tests/runtime/rbac/mod.rs +30 -0
  44. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/configuration.rs +2 -2
  45. package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +4 -4
  46. package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/basic.rs +1 -1
  47. package/contracts/macro-integration-tests/tests/ui/ownable/pass/basic.rs +1 -1
  48. package/contracts/macro-integration-tests/tests/ui/rbac/fail/missing_env.rs +18 -0
  49. package/contracts/macro-integration-tests/tests/ui/rbac/fail/missing_env.stderr +16 -0
  50. package/contracts/macro-integration-tests/tests/ui/rbac/fail/param_not_address.rs +18 -0
  51. package/contracts/macro-integration-tests/tests/ui/rbac/fail/param_not_address.stderr +24 -0
  52. package/contracts/macro-integration-tests/tests/ui/rbac/fail/param_not_found.rs +18 -0
  53. package/contracts/macro-integration-tests/tests/ui/rbac/fail/param_not_found.stderr +24 -0
  54. package/contracts/macro-integration-tests/tests/ui/rbac/pass/basic.rs +71 -0
  55. package/contracts/macro-integration-tests/tests/ui_rbac.rs +12 -0
  56. package/contracts/message-libs/blocked-message-lib/src/lib.rs +4 -4
  57. package/contracts/message-libs/uln-302/src/send_uln.rs +5 -5
  58. package/contracts/oapps/counter/src/counter.rs +6 -0
  59. package/contracts/oapps/oapp/src/oapp_sender.rs +3 -2
  60. package/contracts/oapps/oft/src/extensions/oft_fee.rs +5 -0
  61. package/contracts/oapps/oft/src/interfaces/mintable.rs +2 -2
  62. package/contracts/oapps/oft/src/oft.rs +5 -4
  63. package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +2 -2
  64. package/contracts/oapps/oft/src/tests/extensions/pausable.rs +2 -2
  65. package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +2 -2
  66. package/contracts/oapps/sac-manager/Cargo.toml +0 -1
  67. package/contracts/oapps/sac-manager/src/interfaces/mod.rs +3 -0
  68. package/contracts/oapps/sac-manager/src/interfaces/sac_admin_wrapper.rs +49 -0
  69. package/contracts/oapps/sac-manager/src/lib.rs +3 -3
  70. package/contracts/oapps/sac-manager/src/sac_manager.rs +45 -73
  71. package/contracts/oapps/sac-manager/src/storage.rs +2 -9
  72. package/contracts/oapps/sac-manager/src/tests/sac_manager/clawback.rs +8 -10
  73. package/contracts/oapps/sac-manager/src/tests/sac_manager/mint.rs +13 -18
  74. package/contracts/oapps/sac-manager/src/tests/sac_manager/mod.rs +0 -1
  75. package/contracts/oapps/sac-manager/src/tests/sac_manager/set_admin.rs +22 -12
  76. package/contracts/oapps/sac-manager/src/tests/sac_manager/set_authorized.rs +19 -9
  77. package/contracts/oapps/sac-manager/src/tests/sac_manager/test_helper.rs +27 -10
  78. package/contracts/oapps/sac-manager/src/tests/sac_manager/view_functions.rs +0 -15
  79. package/contracts/oapps/sac-manager/src/tests/test_helper.rs +19 -28
  80. package/contracts/upgrader/src/lib.rs +5 -2
  81. package/contracts/utils/src/auth.rs +6 -2
  82. package/contracts/utils/src/errors.rs +18 -0
  83. package/contracts/utils/src/lib.rs +1 -0
  84. package/contracts/utils/src/multisig.rs +5 -1
  85. package/contracts/utils/src/ownable.rs +1 -1
  86. package/contracts/utils/src/rbac.rs +428 -0
  87. package/contracts/utils/src/tests/auth.rs +2 -2
  88. package/contracts/utils/src/tests/mod.rs +1 -0
  89. package/contracts/utils/src/tests/multisig.rs +2 -2
  90. package/contracts/utils/src/tests/ownable.rs +4 -5
  91. package/contracts/utils/src/tests/rbac.rs +559 -0
  92. package/contracts/utils/src/tests/ttl_configurable.rs +5 -6
  93. package/contracts/utils/src/tests/upgradeable.rs +4 -5
  94. package/contracts/workers/worker/src/worker.rs +1 -1
  95. package/docs/layerzero-v2-on-stellar.md +46 -2
  96. package/package.json +3 -3
  97. package/sdk/.turbo/turbo-test.log +370 -372
  98. package/sdk/dist/generated/bml.d.ts +53 -3
  99. package/sdk/dist/generated/bml.js +27 -3
  100. package/sdk/dist/generated/counter.d.ts +84 -5
  101. package/sdk/dist/generated/counter.js +31 -4
  102. package/sdk/dist/generated/dvn.d.ts +55 -5
  103. package/sdk/dist/generated/dvn.js +28 -4
  104. package/sdk/dist/generated/dvn_fee_lib.d.ts +55 -5
  105. package/sdk/dist/generated/dvn_fee_lib.js +28 -4
  106. package/sdk/dist/generated/endpoint.d.ts +64 -15
  107. package/sdk/dist/generated/endpoint.js +32 -8
  108. package/sdk/dist/generated/executor.d.ts +55 -5
  109. package/sdk/dist/generated/executor.js +28 -4
  110. package/sdk/dist/generated/executor_fee_lib.d.ts +55 -5
  111. package/sdk/dist/generated/executor_fee_lib.js +28 -4
  112. package/sdk/dist/generated/executor_helper.d.ts +53 -3
  113. package/sdk/dist/generated/executor_helper.js +27 -3
  114. package/sdk/dist/generated/layerzero_view.d.ts +55 -5
  115. package/sdk/dist/generated/layerzero_view.js +28 -4
  116. package/sdk/dist/generated/oft.d.ts +84 -5
  117. package/sdk/dist/generated/oft.js +31 -4
  118. package/sdk/dist/generated/price_feed.d.ts +55 -5
  119. package/sdk/dist/generated/price_feed.js +28 -4
  120. package/sdk/dist/generated/sac_manager.d.ts +213 -666
  121. package/sdk/dist/generated/sac_manager.js +57 -238
  122. package/sdk/dist/generated/sml.d.ts +55 -5
  123. package/sdk/dist/generated/sml.js +28 -4
  124. package/sdk/dist/generated/treasury.d.ts +55 -5
  125. package/sdk/dist/generated/treasury.js +28 -4
  126. package/sdk/dist/generated/uln302.d.ts +55 -5
  127. package/sdk/dist/generated/uln302.js +28 -4
  128. package/sdk/dist/generated/upgrader.d.ts +53 -3
  129. package/sdk/dist/generated/upgrader.js +27 -3
  130. package/sdk/package.json +1 -1
  131. package/sdk/test/oft-sml.test.ts +10 -9
  132. package/sdk/test/{sac-manager-redistribution.test.ts → sac-manager.test.ts} +49 -25
  133. package/contracts/endpoint-v2/src/tests/messaging_channel/lazy_inbound_nonce.rs +0 -39
  134. package/contracts/oapps/sac-manager/src/errors.rs +0 -14
  135. package/contracts/oapps/sac-manager/src/tests/sac_manager/set_minter.rs +0 -69
@@ -1,6 +1,6 @@
1
1
  use soroban_sdk::{testutils::Address as _, Address, BytesN};
2
2
 
3
- use crate::{endpoint_v2::EndpointV2, tests::endpoint_setup::setup};
3
+ use crate::{endpoint_v2::EndpointV2, storage, tests::endpoint_setup::setup};
4
4
 
5
5
  // Internal inbound() stores payload hash per nonce and rejects empty payload hash
6
6
  #[test]
@@ -92,3 +92,96 @@ fn test_inbound_rejects_empty_payload_hash() {
92
92
  EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, nonce, &empty_hash)
93
93
  });
94
94
  }
95
+
96
+ #[test]
97
+ fn test_inbound_out_of_order_populates_pending_and_drains_when_gap_closed() {
98
+ let context = setup();
99
+ let env = &context.env;
100
+ let endpoint_client = &context.endpoint_client;
101
+
102
+ let receiver = Address::generate(env);
103
+ let src_eid = 2;
104
+ let sender = BytesN::from_array(env, &[1u8; 32]);
105
+
106
+ let hash_2 = BytesN::from_array(env, &[0x22u8; 32]);
107
+ env.as_contract(&endpoint_client.address, || {
108
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 2, &hash_2)
109
+ });
110
+
111
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 0);
112
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender), soroban_sdk::vec![env, 2u64]);
113
+
114
+ let hash_1 = BytesN::from_array(env, &[0x11u8; 32]);
115
+ env.as_contract(&endpoint_client.address, || {
116
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 1, &hash_1)
117
+ });
118
+
119
+ // Gap is closed, so pending drains and inbound nonce advances to 2.
120
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 2);
121
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
122
+ assert_eq!(endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &1u64), Some(hash_1));
123
+ assert_eq!(endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &2u64), Some(hash_2));
124
+ }
125
+
126
+ #[test]
127
+ #[should_panic(expected = "Error(Contract, #11)")] // EndpointError::InvalidNonce
128
+ fn test_inbound_rejects_nonce_beyond_pending_window() {
129
+ let context = setup();
130
+ let env = &context.env;
131
+ let endpoint_client = &context.endpoint_client;
132
+
133
+ let receiver = Address::generate(env);
134
+ let src_eid = 2;
135
+ let sender = BytesN::from_array(env, &[1u8; 32]);
136
+ let hash = BytesN::from_array(env, &[0xabu8; 32]);
137
+
138
+ // inbound_nonce is 0, so nonce 257 is out of range (max is 256).
139
+ env.as_contract(&endpoint_client.address, || {
140
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 257, &hash)
141
+ });
142
+ }
143
+
144
+ #[test]
145
+ #[should_panic(expected = "Error(Contract, #11)")] // EndpointError::InvalidNonce
146
+ fn test_inbound_rejects_reverify_when_nonce_leq_inbound_and_payload_missing() {
147
+ let context = setup();
148
+ let env = &context.env;
149
+ let endpoint_client = &context.endpoint_client;
150
+
151
+ let receiver = Address::generate(env);
152
+ let src_eid = 2;
153
+ let sender = BytesN::from_array(env, &[1u8; 32]);
154
+
155
+ // Force inbound_nonce to 1 without storing any payload hashes.
156
+ context.set_inbound_nonce(&receiver, src_eid, &sender, 1);
157
+
158
+ let hash = BytesN::from_array(env, &[0xabu8; 32]);
159
+ env.as_contract(&endpoint_client.address, || {
160
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 1, &hash)
161
+ });
162
+ }
163
+
164
+ #[test]
165
+ fn test_inbound_allows_reverify_when_nonce_leq_inbound_and_payload_exists() {
166
+ let context = setup();
167
+ let env = &context.env;
168
+ let endpoint_client = &context.endpoint_client;
169
+
170
+ let receiver = Address::generate(env);
171
+ let src_eid = 2;
172
+ let sender = BytesN::from_array(env, &[1u8; 32]);
173
+
174
+ let old_hash = BytesN::from_array(env, &[0xabu8; 32]);
175
+ env.as_contract(&endpoint_client.address, || {
176
+ storage::EndpointStorage::set_inbound_payload_hash(env, &receiver, src_eid, &sender, 1u64, &old_hash);
177
+ storage::EndpointStorage::set_inbound_nonce(env, &receiver, src_eid, &sender, &1u64);
178
+ });
179
+ assert_eq!(endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &1u64), Some(old_hash));
180
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 1);
181
+
182
+ let new_hash = BytesN::from_array(env, &[0xcdu8; 32]);
183
+ env.as_contract(&endpoint_client.address, || {
184
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 1u64, &new_hash)
185
+ });
186
+ assert_eq!(endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &1u64), Some(new_hash));
187
+ }
@@ -1,4 +1,4 @@
1
- use soroban_sdk::{testutils::Address as _, Address, BytesN};
1
+ use soroban_sdk::{testutils::Address as _, vec, Address, BytesN};
2
2
 
3
3
  use crate::tests::endpoint_setup::{setup, TestSetup};
4
4
 
@@ -25,13 +25,13 @@ fn test_inbound_nonce_initially_zero() {
25
25
  let src_eid = 2;
26
26
  let sender = BytesN::from_array(env, &[1u8; 32]);
27
27
 
28
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 0);
29
28
  assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 0);
29
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
30
30
  }
31
31
 
32
- // Lazy nonce is the baseline when there are no consecutive payload hashes
32
+ // Stored inbound nonce is the baseline when there are no pending nonces
33
33
  #[test]
34
- fn test_inbound_nonce_equals_lazy_nonce_when_no_payload_hashes() {
34
+ fn test_inbound_nonce_equals_stored_value_when_no_pending_nonces() {
35
35
  let context = setup();
36
36
  let env = &context.env;
37
37
  let endpoint_client = &context.endpoint_client;
@@ -40,9 +40,9 @@ fn test_inbound_nonce_equals_lazy_nonce_when_no_payload_hashes() {
40
40
  let src_eid = 2;
41
41
  let sender = BytesN::from_array(env, &[1u8; 32]);
42
42
 
43
- context.set_lazy_inbound_nonce(&receiver, src_eid, &sender, 5);
44
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 5);
43
+ context.set_inbound_nonce(&receiver, src_eid, &sender, 5);
45
44
  assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 5);
45
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
46
46
  }
47
47
 
48
48
  // The inbound_nonce advances through the longest gapless consecutive sequence
@@ -56,13 +56,14 @@ fn test_inbound_nonce_advances_through_consecutive_verified_payload_hashes() {
56
56
  let src_eid = 2;
57
57
  let sender = BytesN::from_array(env, &[1u8; 32]);
58
58
 
59
- // Start from lazy_nonce = 2 and add payloads at 3,4,5.
60
- context.set_lazy_inbound_nonce(&receiver, src_eid, &sender, 2);
59
+ // Start from inbound_nonce = 2 and add payloads at 3,4,5.
60
+ context.set_inbound_nonce(&receiver, src_eid, &sender, 2);
61
61
  inbound_as_verified_with_fixed_hash(&context, &receiver, src_eid, &sender, 3);
62
62
  inbound_as_verified_with_fixed_hash(&context, &receiver, src_eid, &sender, 4);
63
63
  inbound_as_verified_with_fixed_hash(&context, &receiver, src_eid, &sender, 5);
64
64
 
65
65
  assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 5);
66
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
66
67
  }
67
68
 
68
69
  #[test]
@@ -75,12 +76,13 @@ fn test_inbound_nonce_stops_at_first_gap() {
75
76
  let src_eid = 2;
76
77
  let sender = BytesN::from_array(env, &[1u8; 32]);
77
78
 
78
- // Start from lazy_nonce = 2 and add payloads at 3 and 5 (gap at 4).
79
- context.set_lazy_inbound_nonce(&receiver, src_eid, &sender, 2);
79
+ // Start from inbound_nonce = 2 and add payloads at 3 and 5 (gap at 4).
80
+ context.set_inbound_nonce(&receiver, src_eid, &sender, 2);
80
81
  inbound_as_verified_with_fixed_hash(&context, &receiver, src_eid, &sender, 3);
81
82
  inbound_as_verified_with_fixed_hash(&context, &receiver, src_eid, &sender, 5);
82
83
 
83
84
  assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 3);
85
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender), vec![env, 5u64]);
84
86
  }
85
87
 
86
88
  // Path isolation (receiver/src_eid/sender are isolated)
@@ -97,22 +99,22 @@ fn test_inbound_nonce_isolated_by_path() {
97
99
  let sender_a = BytesN::from_array(env, &[1u8; 32]);
98
100
  let sender_b = BytesN::from_array(env, &[2u8; 32]);
99
101
 
100
- // Path A: lazy 10 + payload at 11 => inbound_nonce 11.
101
- context.set_lazy_inbound_nonce(&receiver_a, src_eid_a, &sender_a, 10);
102
+ // Path A: inbound 10 + payload at 11 => inbound_nonce 11.
103
+ context.set_inbound_nonce(&receiver_a, src_eid_a, &sender_a, 10);
102
104
  inbound_as_verified_with_fixed_hash(&context, &receiver_a, src_eid_a, &sender_a, 11);
103
105
  assert_eq!(endpoint_client.inbound_nonce(&receiver_a, &src_eid_a, &sender_a), 11);
104
106
 
105
107
  // Path B: different receiver => independent.
106
- context.set_lazy_inbound_nonce(&receiver_b, src_eid_a, &sender_a, 20);
108
+ context.set_inbound_nonce(&receiver_b, src_eid_a, &sender_a, 20);
107
109
  assert_eq!(endpoint_client.inbound_nonce(&receiver_b, &src_eid_a, &sender_a), 20);
108
110
 
109
111
  // Path C: different src_eid => independent (two consecutive payloads).
110
- context.set_lazy_inbound_nonce(&receiver_a, src_eid_b, &sender_a, 30);
112
+ context.set_inbound_nonce(&receiver_a, src_eid_b, &sender_a, 30);
111
113
  inbound_as_verified_with_fixed_hash(&context, &receiver_a, src_eid_b, &sender_a, 31);
112
114
  inbound_as_verified_with_fixed_hash(&context, &receiver_a, src_eid_b, &sender_a, 32);
113
115
  assert_eq!(endpoint_client.inbound_nonce(&receiver_a, &src_eid_b, &sender_a), 32);
114
116
 
115
117
  // Path D: different sender => independent.
116
- context.set_lazy_inbound_nonce(&receiver_a, src_eid_a, &sender_b, 40);
118
+ context.set_inbound_nonce(&receiver_a, src_eid_a, &sender_b, 40);
117
119
  assert_eq!(endpoint_client.inbound_nonce(&receiver_a, &src_eid_a, &sender_b), 40);
118
120
  }
@@ -3,7 +3,7 @@ mod clear_payload;
3
3
  mod inbound;
4
4
  mod inbound_nonce;
5
5
  mod inbound_payload_hash;
6
- mod lazy_inbound_nonce;
6
+ mod pending_inbound_nonces;
7
7
  mod next_guid;
8
8
  mod nilify;
9
9
  mod outbound;
@@ -128,9 +128,9 @@ fn test_nilify_success_with_empty_payload() {
128
128
  let sender = BytesN::from_array(env, &[1u8; 32]);
129
129
  let nonce = 2;
130
130
 
131
- // Set lazy nonce to 1 so nonce 2 is greater than lazy nonce.
131
+ // Set inbound nonce to 1 so nonce 2 is the next expected nonce.
132
132
  env.as_contract(&endpoint_client.address, || {
133
- storage::EndpointStorage::set_lazy_inbound_nonce(env, &receiver, src_eid, &sender, &1)
133
+ storage::EndpointStorage::set_inbound_nonce(env, &receiver, src_eid, &sender, &1)
134
134
  });
135
135
 
136
136
  // Nilify with None.
@@ -147,6 +147,7 @@ fn test_nilify_success_with_empty_payload() {
147
147
  let nilified_hash = endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &nonce);
148
148
  let expected_nil_hash = nil_hash(&context);
149
149
  assert_eq!(nilified_hash, Some(expected_nil_hash));
150
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 2);
150
151
  }
151
152
 
152
153
  // Nilify with None counts as "verified" for inbound_nonce (but does not change lazy nonce)
@@ -161,17 +162,53 @@ fn test_nilify_with_none_advances_inbound_nonce_without_changing_lazy_nonce() {
161
162
  let sender = BytesN::from_array(env, &[1u8; 32]);
162
163
 
163
164
  // Initial state.
164
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 0);
165
165
  assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 0);
166
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
166
167
 
167
168
  // Nilify nonce 1 with None (non-verified nonce).
168
169
  nilify_with_auth(&context, &receiver, &receiver, src_eid, &sender, 1, &None);
169
170
 
170
171
  // Nilify writes a payload hash, so inbound_nonce can now advance to 1.
171
172
  assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 1);
173
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
174
+ }
175
+
176
+ #[test]
177
+ fn test_nilify_closes_gap_and_drains_pending_nonces() {
178
+ let context = setup();
179
+ let env = &context.env;
180
+ let endpoint_client = &context.endpoint_client;
172
181
 
173
- // But nilify does not update lazy_inbound_nonce.
174
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 0);
182
+ let receiver = Address::generate(env);
183
+ let src_eid = 2;
184
+ let sender = BytesN::from_array(env, &[1u8; 32]);
185
+
186
+ // Force inbound nonce to 1 and create a gap by verifying nonce 3 first.
187
+ context.set_inbound_nonce(&receiver, src_eid, &sender, 1);
188
+ let payload_hash_3 = BytesN::from_array(env, &[0x33u8; 32]);
189
+ env.as_contract(&endpoint_client.address, || {
190
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 3u64, &payload_hash_3)
191
+ });
192
+
193
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 1);
194
+ assert_eq!(
195
+ endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender),
196
+ soroban_sdk::vec![env, 3u64]
197
+ );
198
+
199
+ // Nilify nonce 2 with None closes the gap and should drain pending to advance inbound nonce to 3.
200
+ nilify_with_auth(&context, &receiver, &receiver, src_eid, &sender, 2u64, &None);
201
+
202
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 3);
203
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
204
+ assert_eq!(
205
+ endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &2u64),
206
+ Some(nil_hash(&context))
207
+ );
208
+ assert_eq!(
209
+ endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &3u64),
210
+ Some(payload_hash_3)
211
+ );
175
212
  }
176
213
 
177
214
  // Nilify is allowed when nonce <= lazy nonce if a payload hash exists
@@ -187,14 +224,12 @@ fn test_nilify_allows_when_nonce_is_checkpointed_if_payload_exists() {
187
224
  let nonce = 5u64;
188
225
  let payload_hash = BytesN::from_array(env, &[0xabu8; 32]);
189
226
 
190
- // Checkpoint past the target nonce.
227
+ // Advance inbound nonce past the target nonce and store a payload hash at nonce 5.
191
228
  env.as_contract(&endpoint_client.address, || {
192
- storage::EndpointStorage::set_lazy_inbound_nonce(env, &receiver, src_eid, &sender, &10)
229
+ storage::EndpointStorage::set_inbound_nonce(env, &receiver, src_eid, &sender, &10);
230
+ storage::EndpointStorage::set_inbound_payload_hash(env, &receiver, src_eid, &sender, nonce, &payload_hash);
193
231
  });
194
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 10);
195
-
196
- // Store a verified payload hash at nonce 5.
197
- context.inbound_as_verified(&receiver, src_eid, &sender, nonce, &payload_hash);
232
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 10);
198
233
  assert_eq!(endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &nonce), Some(payload_hash.clone()));
199
234
 
200
235
  // Even though nonce <= lazy_nonce, this should succeed because a payload hash exists.
@@ -430,9 +465,9 @@ fn test_nilify_invalid_nonce_when_already_checkpointed_without_payload() {
430
465
  let sender = BytesN::from_array(env, &[1u8; 32]);
431
466
  let nonce = 1u64;
432
467
 
433
- // Set lazy nonce to 1 and ensure there is NO payload for nonce 1.
468
+ // Set inbound nonce to 1 and ensure there is NO payload for nonce 1.
434
469
  env.as_contract(&endpoint_client.address, || {
435
- storage::EndpointStorage::set_lazy_inbound_nonce(env, &receiver, src_eid, &sender, &1)
470
+ storage::EndpointStorage::set_inbound_nonce(env, &receiver, src_eid, &sender, &1)
436
471
  });
437
472
 
438
473
  let result = try_nilify_with_auth(&context, &receiver, &receiver, src_eid, &sender, nonce, &None);
@@ -0,0 +1,111 @@
1
+ use soroban_sdk::{testutils::Address as _, vec, Address, BytesN};
2
+
3
+ use crate::{endpoint_v2::EndpointV2, tests::endpoint_setup::setup};
4
+
5
+ #[test]
6
+ fn test_pending_inbound_nonces_initially_empty() {
7
+ let context = setup();
8
+ let env = &context.env;
9
+ let endpoint_client = &context.endpoint_client;
10
+
11
+ let receiver = Address::generate(env);
12
+ let src_eid = 2u32;
13
+ let sender = BytesN::from_array(env, &[1u8; 32]);
14
+
15
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
16
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 0);
17
+ }
18
+
19
+ #[test]
20
+ fn test_pending_inbound_nonces_sorted_and_no_duplicates() {
21
+ let context = setup();
22
+ let env = &context.env;
23
+ let endpoint_client = &context.endpoint_client;
24
+
25
+ let receiver = Address::generate(env);
26
+ let src_eid = 2u32;
27
+ let sender = BytesN::from_array(env, &[1u8; 32]);
28
+
29
+ let hash_5 = BytesN::from_array(env, &[0x05u8; 32]);
30
+ env.as_contract(&endpoint_client.address, || {
31
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 5u64, &hash_5)
32
+ });
33
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender), vec![env, 5u64]);
34
+
35
+ let hash_2 = BytesN::from_array(env, &[0x02u8; 32]);
36
+ env.as_contract(&endpoint_client.address, || {
37
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 2u64, &hash_2)
38
+ });
39
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender), vec![env, 2u64, 5u64]);
40
+
41
+ let hash_4 = BytesN::from_array(env, &[0x04u8; 32]);
42
+ env.as_contract(&endpoint_client.address, || {
43
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 4u64, &hash_4)
44
+ });
45
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender), vec![env, 2u64, 4u64, 5u64]);
46
+
47
+ // Re-verify the same nonce should not duplicate it in the pending list.
48
+ let hash_4b = BytesN::from_array(env, &[0x44u8; 32]);
49
+ env.as_contract(&endpoint_client.address, || {
50
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 4u64, &hash_4b)
51
+ });
52
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender), vec![env, 2u64, 4u64, 5u64]);
53
+ }
54
+
55
+ #[test]
56
+ fn test_pending_inbound_nonces_drains_when_consecutive_sequence_completed() {
57
+ let context = setup();
58
+ let env = &context.env;
59
+ let endpoint_client = &context.endpoint_client;
60
+
61
+ let receiver = Address::generate(env);
62
+ let src_eid = 2u32;
63
+ let sender = BytesN::from_array(env, &[1u8; 32]);
64
+
65
+ let hash_2 = BytesN::from_array(env, &[0x02u8; 32]);
66
+ let hash_3 = BytesN::from_array(env, &[0x03u8; 32]);
67
+ env.as_contract(&endpoint_client.address, || {
68
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 2u64, &hash_2);
69
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 3u64, &hash_3);
70
+ });
71
+
72
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 0);
73
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender), vec![env, 2u64, 3u64]);
74
+
75
+ // Inserting nonce 1 closes the gap, so pending drains and inbound nonce advances to 3.
76
+ let hash_1 = BytesN::from_array(env, &[0x01u8; 32]);
77
+ env.as_contract(&endpoint_client.address, || {
78
+ EndpointV2::inbound_for_test(env, &receiver, src_eid, &sender, 1u64, &hash_1)
79
+ });
80
+
81
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 3);
82
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
83
+ }
84
+
85
+ #[test]
86
+ fn test_pending_inbound_nonces_isolated_by_path() {
87
+ let context = setup();
88
+ let env = &context.env;
89
+ let endpoint_client = &context.endpoint_client;
90
+
91
+ let receiver_a = Address::generate(env);
92
+ let receiver_b = Address::generate(env);
93
+ let src_eid_a = 2u32;
94
+ let src_eid_b = 3u32;
95
+ let sender_a = BytesN::from_array(env, &[1u8; 32]);
96
+ let sender_b = BytesN::from_array(env, &[2u8; 32]);
97
+
98
+ let hash = BytesN::from_array(env, &[0xabu8; 32]);
99
+ env.as_contract(&endpoint_client.address, || {
100
+ EndpointV2::inbound_for_test(env, &receiver_a, src_eid_a, &sender_a, 2u64, &hash);
101
+ EndpointV2::inbound_for_test(env, &receiver_b, src_eid_a, &sender_a, 2u64, &hash);
102
+ EndpointV2::inbound_for_test(env, &receiver_a, src_eid_b, &sender_a, 2u64, &hash);
103
+ EndpointV2::inbound_for_test(env, &receiver_a, src_eid_a, &sender_b, 2u64, &hash);
104
+ });
105
+
106
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver_a, &src_eid_a, &sender_a), vec![env, 2u64]);
107
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver_b, &src_eid_a, &sender_a), vec![env, 2u64]);
108
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver_a, &src_eid_b, &sender_a), vec![env, 2u64]);
109
+ assert_eq!(endpoint_client.pending_inbound_nonces(&receiver_a, &src_eid_a, &sender_b), vec![env, 2u64]);
110
+ }
111
+
@@ -53,7 +53,7 @@ fn test_skip_requires_auth_even_when_caller_is_receiver() {
53
53
  endpoint_client.skip(&receiver, &receiver, &src_eid, &sender, &nonce);
54
54
  }
55
55
 
56
- // Successful skip updates inbound/lazy nonces and emits InboundNonceSkipped
56
+ // Successful skip updates inbound nonce and emits InboundNonceSkipped
57
57
  #[test]
58
58
  fn test_skip_success() {
59
59
  let context = setup();
@@ -65,13 +65,10 @@ fn test_skip_success() {
65
65
  let sender = BytesN::from_array(env, &[1u8; 32]);
66
66
  let nonce = 1;
67
67
 
68
- // Verify initial state: lazy inbound nonce should be 0.
69
- let initial_lazy_nonce = endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender);
70
- assert_eq!(initial_lazy_nonce, 0, "Initial lazy inbound nonce should be 0");
71
-
72
68
  // Initially, inbound nonce should be 0.
73
69
  let initial_nonce = endpoint_client.inbound_nonce(&receiver, &src_eid, &sender);
74
70
  assert_eq!(initial_nonce, 0);
71
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
75
72
 
76
73
  // Skip nonce 1 (expected nonce is initial_nonce + 1 = 1).
77
74
  skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, nonce);
@@ -86,10 +83,7 @@ fn test_skip_success() {
86
83
  // Verify inbound nonce reflects the skip via public interface.
87
84
  let updated_nonce = endpoint_client.inbound_nonce(&receiver, &src_eid, &sender);
88
85
  assert_eq!(updated_nonce, nonce);
89
-
90
- // Verify lazy inbound nonce was updated.
91
- let lazy_nonce = endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender);
92
- assert_eq!(lazy_nonce, nonce);
86
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
93
87
  }
94
88
 
95
89
  // Multiple sequential skips update to the latest nonce
@@ -111,13 +105,10 @@ fn test_skip_multiple_nonces() {
111
105
  let nonce2 = 2;
112
106
  skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, nonce2);
113
107
 
114
- // Verify lazy inbound nonce was updated to nonce2.
115
- let lazy_nonce = endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender);
116
- assert_eq!(lazy_nonce, nonce2);
117
-
118
108
  // Verify inbound nonce reflects the latest skip.
119
109
  let updated_nonce = endpoint_client.inbound_nonce(&receiver, &src_eid, &sender);
120
110
  assert_eq!(updated_nonce, nonce2);
111
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
121
112
  }
122
113
 
123
114
  // Delegate authorization (delegate(receiver) is allowed)
@@ -146,9 +137,8 @@ fn test_skip_with_delegate() {
146
137
  InboundNonceSkipped { src_eid, sender: sender.clone(), receiver: receiver.clone(), nonce },
147
138
  );
148
139
 
149
- // Verify lazy inbound nonce was updated.
150
- let lazy_nonce = endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender);
151
- assert_eq!(lazy_nonce, nonce);
140
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), nonce);
141
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
152
142
  }
153
143
 
154
144
  // Path isolation (receiver/src_eid/sender are isolated)
@@ -176,11 +166,11 @@ fn test_skip_different_paths() {
176
166
  // Skip for different senders.
177
167
  skip_with_auth(&context, &receiver1, &receiver1, src_eid1, &sender2, nonce);
178
168
 
179
- // Verify all paths have independent lazy nonces.
180
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver1, &src_eid1, &sender1), nonce);
181
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver2, &src_eid1, &sender1), nonce);
182
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver1, &src_eid2, &sender1), nonce);
183
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver1, &src_eid1, &sender2), nonce);
169
+ // Verify all paths have independent inbound nonces.
170
+ assert_eq!(endpoint_client.inbound_nonce(&receiver1, &src_eid1, &sender1), nonce);
171
+ assert_eq!(endpoint_client.inbound_nonce(&receiver2, &src_eid1, &sender1), nonce);
172
+ assert_eq!(endpoint_client.inbound_nonce(&receiver1, &src_eid2, &sender1), nonce);
173
+ assert_eq!(endpoint_client.inbound_nonce(&receiver1, &src_eid1, &sender2), nonce);
184
174
  }
185
175
 
186
176
  // Invalid nonce rejection (must match expected nonce)
@@ -224,10 +214,10 @@ fn test_skip_next_nonce_accounts_for_verified_payload_hashes() {
224
214
  let result = endpoint_client.try_skip(&receiver, &receiver, &src_eid, &sender, &1);
225
215
  assert_eq!(result.err().unwrap().ok().unwrap(), EndpointError::InvalidNonce.into());
226
216
 
227
- // Skipping 2 should succeed and advance lazy inbound nonce to 2.
217
+ // Skipping 2 should succeed and advance inbound nonce to 2.
228
218
  skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, 2);
229
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 2);
230
219
  assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 2);
220
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
231
221
 
232
222
  // skip() does not clear any existing payload hashes.
233
223
  assert_eq!(endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &1), Some(payload_hash_1));
@@ -251,8 +241,8 @@ fn test_skip_closes_gap_and_advances_inbound_nonce() {
251
241
 
252
242
  // Skip nonce 1 to close the gap. This should allow inbound_nonce to advance to 2.
253
243
  skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, 1);
254
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 1);
255
244
  assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 2);
245
+ assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
256
246
 
257
247
  // Payload hash at nonce 2 remains intact.
258
248
  assert_eq!(endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &2), Some(payload_hash_2));
@@ -271,7 +261,7 @@ fn test_skip_rejects_repeated_same_nonce() {
271
261
 
272
262
  // Skip nonce 1 successfully.
273
263
  skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, 1);
274
- assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 1);
264
+ assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 1);
275
265
 
276
266
  // Skipping nonce 1 again should fail since the next expected nonce is now 2.
277
267
  context.mock_auth(&receiver, "skip", (&receiver, &receiver, &src_eid, &sender, &1u64));
@@ -104,9 +104,9 @@ impl LayerZeroView {
104
104
  let empty_hash = empty_payload_hash(env);
105
105
  let nil_hash = nil_payload_hash(env);
106
106
 
107
- // Executed: payload hash has been cleared (None) and nonce <= lazy_inbound_nonce
107
+ // Executed: payload hash has been cleared (None) and nonce <= inbound_nonce
108
108
  if payload_hash.is_none()
109
- && origin.nonce <= messaging_channel.lazy_inbound_nonce(receiver, &origin.src_eid, &origin.sender)
109
+ && origin.nonce <= messaging_channel.inbound_nonce(receiver, &origin.src_eid, &origin.sender)
110
110
  {
111
111
  return ExecutionState::Executed;
112
112
  }
@@ -206,9 +206,9 @@ fn test_executable_state_executed() {
206
206
  let receiver = test_setup.register_oapp();
207
207
  let sender = soroban_sdk::Address::generate(&test_setup.env);
208
208
 
209
- // Clear payload hash (None) and set lazy_inbound_nonce >= nonce = Executed
209
+ // Clear payload hash (None) and set inbound_nonce >= nonce = Executed
210
210
  test_setup.set_payload_hash(&receiver, REMOTE_EID, &sender, 1, &None);
211
- test_setup.set_lazy_inbound_nonce(&receiver, REMOTE_EID, &sender, 1);
211
+ test_setup.set_inbound_nonce(&receiver, REMOTE_EID, &sender, 1);
212
212
 
213
213
  let origin = Origin { src_eid: REMOTE_EID, sender: address_to_bytes32(&sender), nonce: 1 };
214
214
 
@@ -262,9 +262,8 @@ fn test_executable_multiple_nonces_in_sequence() {
262
262
  assert_eq!(test_setup.view_client.executable(&origin_2, &receiver), ExecutionState::VerifiedButNotExecutable);
263
263
  assert_eq!(test_setup.view_client.executable(&origin_3, &receiver), ExecutionState::VerifiedButNotExecutable);
264
264
 
265
- // Now execute nonce 1 (set lazy_inbound_nonce)
265
+ // Now execute nonce 1 (clear payload hash, advance inbound_nonce)
266
266
  test_setup.set_payload_hash(&receiver, REMOTE_EID, &sender, 1, &None);
267
- test_setup.set_lazy_inbound_nonce(&receiver, REMOTE_EID, &sender, 1);
268
267
  test_setup.set_inbound_nonce(&receiver, REMOTE_EID, &sender, 2);
269
268
 
270
269
  assert_eq!(test_setup.view_client.executable(&origin_1, &receiver), ExecutionState::Executed);
@@ -30,7 +30,6 @@ mod endpoint_storage {
30
30
  Initializable(Address, u32, BytesN<32>),
31
31
  Verifiable(Address, u32, BytesN<32>),
32
32
  // State for executable tests
33
- LazyInboundNonce(Address, u32, BytesN<32>),
34
33
  InboundNonce(Address, u32, BytesN<32>),
35
34
  InboundPayloadHash(Address, u32, BytesN<32>, u64),
36
35
  ReceiveLibrary(Address, u32),
@@ -91,13 +90,6 @@ impl MockEndpoint {
91
90
  .set(&endpoint_storage::MockEndpointStorage::Verifiable(receiver.clone(), *src_eid, sender.clone()), value);
92
91
  }
93
92
 
94
- pub fn set_lazy_inbound_nonce(env: &Env, receiver: &Address, src_eid: &u32, sender: &BytesN<32>, nonce: &u64) {
95
- env.storage().persistent().set(
96
- &endpoint_storage::MockEndpointStorage::LazyInboundNonce(receiver.clone(), *src_eid, sender.clone()),
97
- nonce,
98
- );
99
- }
100
-
101
93
  pub fn set_inbound_nonce(env: &Env, receiver: &Address, src_eid: &u32, sender: &BytesN<32>, nonce: &u64) {
102
94
  env.storage().persistent().set(
103
95
  &endpoint_storage::MockEndpointStorage::InboundNonce(receiver.clone(), *src_eid, sender.clone()),
@@ -135,13 +127,6 @@ impl MockEndpoint {
135
127
  // Getters required by LayerZeroView
136
128
  // =========================================================================
137
129
 
138
- pub fn lazy_inbound_nonce(env: &Env, receiver: &Address, src_eid: &u32, sender: &BytesN<32>) -> u64 {
139
- env.storage()
140
- .persistent()
141
- .get(&endpoint_storage::MockEndpointStorage::LazyInboundNonce(receiver.clone(), *src_eid, sender.clone()))
142
- .unwrap_or(0)
143
- }
144
-
145
130
  pub fn inbound_nonce(env: &Env, receiver: &Address, src_eid: &u32, sender: &BytesN<32>) -> u64 {
146
131
  env.storage()
147
132
  .persistent()
@@ -282,12 +267,6 @@ impl<'a> TestSetup<'a> {
282
267
  self.endpoint_client.set_verifiable(receiver, &src_eid, &sender_bytes32, &value);
283
268
  }
284
269
 
285
- /// Set lazy inbound nonce (marks messages up to this nonce as processed).
286
- pub fn set_lazy_inbound_nonce(&self, receiver: &Address, src_eid: u32, sender: &Address, nonce: u64) {
287
- let sender_bytes32 = address_to_bytes32(sender);
288
- self.endpoint_client.set_lazy_inbound_nonce(receiver, &src_eid, &sender_bytes32, &nonce);
289
- }
290
-
291
270
  /// Set inbound nonce (marks messages up to this nonce as verified and executable).
292
271
  pub fn set_inbound_nonce(&self, receiver: &Address, src_eid: u32, sender: &Address, nonce: u64) {
293
272
  let sender_bytes32 = address_to_bytes32(sender);
@@ -27,7 +27,7 @@ fn exposes_ttl_and_ownable_features() {
27
27
  // Ownable helper works.
28
28
  let owner = Address::generate(&env);
29
29
  client.init(&owner);
30
- assert_eq!(client.authorizer(), owner);
30
+ assert_eq!(client.authorizer(), Some(owner));
31
31
 
32
32
  // TTL-configurable read methods exist.
33
33
  let _cfg = client.ttl_configs();
@@ -16,7 +16,7 @@ fn uses_self_owning_auth_and_exposes_ttl() {
16
16
 
17
17
  // MultiSig auth => authorizer should be the contract address, without any init.
18
18
  let expected = env.as_contract(&contract_id, || env.current_contract_address());
19
- assert_eq!(client.authorizer(), expected);
19
+ assert_eq!(client.authorizer(), Some(expected));
20
20
 
21
21
  // TTL-configurable read methods exist.
22
22
  let _cfg = client.ttl_configs();
@@ -30,7 +30,7 @@ fn self_auth_can_migrate_when_flag_set() {
30
30
 
31
31
  // MultiSig auth => authorizer should be the contract address, without any init.
32
32
  let expected = env.as_contract(&contract_id, || env.current_contract_address());
33
- assert_eq!(client.authorizer(), expected);
33
+ assert_eq!(client.authorizer(), Some(expected));
34
34
 
35
35
  // Unauthorized migrate should fail.
36
36
  let unauthorized = client.try_migrate(&migration_data);