@layerzerolabs/protocol-stellar-v2 0.2.20 → 0.2.22
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 +783 -802
- package/.turbo/turbo-lint.log +320 -157
- package/.turbo/turbo-test.log +1414 -1457
- package/Cargo.lock +109 -108
- package/Cargo.toml +32 -18
- package/contracts/common-macros/Cargo.toml +7 -7
- package/contracts/common-macros/src/auth.rs +18 -37
- package/contracts/common-macros/src/contract_ttl.rs +2 -2
- package/contracts/common-macros/src/lib.rs +27 -10
- package/contracts/common-macros/src/lz_contract.rs +38 -7
- package/contracts/common-macros/src/storage.rs +251 -292
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +6 -12
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +12 -17
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +2 -7
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +20 -9
- package/contracts/common-macros/src/tests/upgradeable.rs +26 -4
- package/contracts/common-macros/src/ttl_configurable.rs +2 -10
- package/contracts/common-macros/src/ttl_extendable.rs +2 -10
- package/contracts/common-macros/src/upgradeable.rs +56 -15
- package/contracts/common-macros/src/utils.rs +0 -9
- package/contracts/endpoint-v2/src/lib.rs +3 -2
- package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +2 -2
- package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +3 -3
- package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +4 -4
- package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +17 -5
- package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
- package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +2 -2
- package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +2 -2
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +6 -6
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +67 -37
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +5 -5
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +44 -54
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +7 -7
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +8 -8
- package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +3 -3
- package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +4 -4
- package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +3 -3
- package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +2 -2
- package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +3 -3
- package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +2 -2
- package/contracts/layerzero-views/Cargo.toml +0 -1
- package/contracts/layerzero-views/src/layerzero_view.rs +1 -13
- package/contracts/macro-integration-tests/Cargo.toml +5 -15
- package/contracts/macro-integration-tests/tests/runtime/oapp/mod.rs +48 -0
- package/contracts/macro-integration-tests/tests/runtime/oapp/oapp_core.rs +170 -0
- package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +154 -0
- package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +338 -0
- package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +435 -0
- package/contracts/macro-integration-tests/tests/runtime.rs +1 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.stderr +71 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.rs +10 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +5 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_all.rs +38 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_single_trait.rs +96 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/pass/minimal_contract.rs +64 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/pass/struct_with_fields.rs +46 -0
- package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.stderr +8 -0
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +1 -1
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/only_auth_env_param_variants.rs +1 -1
- package/contracts/macro-integration-tests/tests/ui_oapp.rs +11 -0
- package/contracts/message-libs/message-lib-common/Cargo.toml +0 -1
- package/contracts/message-libs/message-lib-common/src/errors.rs +1 -1
- package/contracts/message-libs/treasury/Cargo.toml +0 -2
- package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +7 -27
- package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +2 -2
- package/contracts/oapps/counter/Cargo.toml +4 -6
- package/contracts/oapps/counter/integration_tests/utils.rs +19 -12
- package/contracts/oapps/oapp/src/errors.rs +1 -1
- package/contracts/oapps/oapp/src/interfaces/mod.rs +3 -0
- package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +47 -0
- package/contracts/oapps/oapp/src/lib.rs +1 -0
- package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +4 -4
- package/contracts/oapps/oapp/src/oapp_core.rs +5 -5
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +12 -4
- package/contracts/oapps/oapp/src/oapp_receiver.rs +14 -9
- package/contracts/oapps/oapp/src/tests/mod.rs +4 -4
- package/contracts/oapps/oapp/src/tests/{test_oapp_core.rs → oapp_core.rs} +4 -4
- package/contracts/oapps/oapp/src/tests/{test_oapp_options_type3.rs → oapp_options_type3.rs} +3 -4
- package/contracts/oapps/oapp-macros/Cargo.toml +8 -4
- package/contracts/oapps/oapp-macros/src/generators.rs +9 -34
- package/contracts/oapps/oapp-macros/src/lib.rs +3 -0
- package/contracts/oapps/oapp-macros/src/tests/mod.rs +2 -0
- package/contracts/oapps/oapp-macros/src/tests/oapp.rs +88 -0
- package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +86 -0
- package/contracts/oapps/oapp-macros/src/tests/snapshots/oapp_macros__tests__oapp__snapshot_generate_oapp.snap +103 -0
- package/contracts/oapps/oft/integration-tests/utils.rs +28 -8
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +136 -74
- package/contracts/oapps/oft/src/extensions/pausable.rs +44 -10
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +170 -130
- package/contracts/oapps/oft/src/oft.rs +19 -12
- package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +1 -1
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -1
- package/contracts/oapps/oft-core/Cargo.toml +1 -4
- package/contracts/oapps/oft-core/integration-tests/setup.rs +2 -2
- package/contracts/oapps/oft-core/integration-tests/utils.rs +21 -3
- package/contracts/oapps/oft-core/src/errors.rs +3 -2
- package/contracts/oapps/oft-core/src/events.rs +6 -0
- package/contracts/oapps/oft-core/src/lib.rs +1 -1
- package/contracts/oapps/oft-core/src/oft_core.rs +115 -60
- package/contracts/oapps/oft-core/src/storage.rs +7 -3
- package/contracts/oapps/oft-core/src/tests/mod.rs +1 -0
- package/contracts/oapps/oft-core/src/tests/test_decimals.rs +37 -2
- package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +2 -2
- package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +323 -0
- package/contracts/oapps/oft-core/src/tests/test_send.rs +2 -2
- package/contracts/oapps/oft-core/src/tests/test_utils.rs +59 -14
- package/contracts/utils/Cargo.toml +0 -1
- package/contracts/utils/src/errors.rs +1 -1
- package/contracts/utils/src/multisig.rs +17 -8
- package/contracts/utils/src/ownable.rs +6 -6
- package/contracts/utils/src/testing_utils.rs +124 -54
- package/contracts/utils/src/tests/multisig.rs +12 -12
- package/contracts/utils/src/tests/ownable.rs +6 -6
- package/contracts/utils/src/tests/testing_utils.rs +50 -167
- package/contracts/utils/src/tests/ttl_configurable.rs +5 -5
- package/contracts/utils/src/tests/upgradeable.rs +1 -1
- package/contracts/utils/src/ttl_configurable.rs +10 -4
- package/contracts/utils/src/upgradeable.rs +5 -5
- package/contracts/workers/dvn/Cargo.toml +5 -6
- package/contracts/workers/dvn/src/dvn.rs +2 -12
- package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
- package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +37 -19
- package/contracts/workers/dvn-fee-lib/src/lib.rs +12 -2
- package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +15 -13
- package/contracts/workers/executor/Cargo.toml +3 -0
- package/contracts/workers/executor/src/executor.rs +2 -12
- package/contracts/workers/executor/src/lib.rs +2 -2
- package/contracts/workers/executor/src/tests/auth.rs +394 -0
- package/contracts/workers/executor/src/tests/executor.rs +410 -0
- package/contracts/workers/executor/src/tests/mod.rs +3 -0
- package/contracts/workers/executor/src/tests/setup.rs +250 -0
- package/contracts/workers/executor-fee-lib/Cargo.toml +5 -0
- package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +1 -12
- package/contracts/workers/executor-fee-lib/src/lib.rs +8 -2
- package/contracts/workers/executor-helper/Cargo.toml +0 -1
- package/contracts/workers/price-feed/Cargo.toml +5 -0
- package/contracts/workers/price-feed/src/lib.rs +9 -4
- package/contracts/workers/price-feed/src/price_feed.rs +1 -11
- package/contracts/workers/worker/src/errors.rs +1 -1
- package/contracts/workers/worker/src/tests/setup.rs +1 -1
- package/contracts/workers/worker/src/tests/worker.rs +55 -41
- package/contracts/workers/worker/src/worker.rs +34 -25
- package/docs/error-spec.md +55 -0
- package/docs/layerzero-v2-on-stellar.md +447 -0
- package/docs/oapp-guide.md +212 -0
- package/docs/oft-guide.md +314 -0
- package/package.json +3 -3
- package/sdk/.turbo/turbo-test.log +260 -257
- package/sdk/dist/generated/bml.d.ts +3 -3
- package/sdk/dist/generated/bml.js +4 -4
- package/sdk/dist/generated/counter.d.ts +295 -295
- package/sdk/dist/generated/counter.js +43 -43
- package/sdk/dist/generated/dvn.d.ts +91 -91
- package/sdk/dist/generated/dvn.js +24 -24
- package/sdk/dist/generated/dvn_fee_lib.d.ts +92 -92
- package/sdk/dist/generated/dvn_fee_lib.js +25 -25
- package/sdk/dist/generated/endpoint.d.ts +99 -99
- package/sdk/dist/generated/endpoint.js +16 -16
- package/sdk/dist/generated/executor.d.ts +91 -91
- package/sdk/dist/generated/executor.js +24 -24
- package/sdk/dist/generated/executor_fee_lib.d.ts +92 -92
- package/sdk/dist/generated/executor_fee_lib.js +25 -25
- package/sdk/dist/generated/executor_helper.d.ts +3 -3
- package/sdk/dist/generated/executor_helper.js +4 -4
- package/sdk/dist/generated/layerzero_view.d.ts +186 -186
- package/sdk/dist/generated/layerzero_view.js +35 -35
- package/sdk/dist/generated/oft.d.ts +366 -352
- package/sdk/dist/generated/oft.js +74 -79
- package/sdk/dist/generated/price_feed.d.ts +198 -198
- package/sdk/dist/generated/price_feed.js +39 -39
- package/sdk/dist/generated/sml.d.ts +99 -99
- package/sdk/dist/generated/sml.js +16 -16
- package/sdk/dist/generated/treasury.d.ts +99 -99
- package/sdk/dist/generated/treasury.js +16 -16
- package/sdk/dist/generated/uln302.d.ts +99 -99
- package/sdk/dist/generated/uln302.js +16 -16
- package/sdk/dist/generated/upgrader.d.ts +3 -3
- package/sdk/dist/generated/upgrader.js +3 -3
- package/sdk/package.json +1 -1
- package/sdk/test/suites/localnet.ts +84 -20
- package/contracts/ERROR_SPEC.md +0 -51
- package/contracts/endpoint-v2/ARCHITECTURE.md +0 -233
- /package/contracts/oapps/oapp/src/tests/{test_oapp_receiver.rs → oapp_receiver.rs} +0 -0
- /package/contracts/oapps/oapp/src/tests/{test_oapp_sender.rs → oapp_sender.rs} +0 -0
|
@@ -1,26 +1,76 @@
|
|
|
1
|
-
use soroban_sdk::{testutils::Events, xdr
|
|
1
|
+
use soroban_sdk::{testutils::Events, xdr, Address, Env, Event, TryFromVal, Val, Vec};
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
/// Decodes a raw emitted contract event (XDR) into `(topics, data)`.
|
|
4
|
+
///
|
|
5
|
+
/// Soroban testutils exposes events as [`ContractEvents`](soroban_sdk::testutils::ContractEvents),
|
|
6
|
+
/// which internally stores XDR [`ContractEvent`](soroban_sdk::xdr::ContractEvent) values.
|
|
7
|
+
/// This helper converts the XDR topics/data into `soroban_sdk::Val` so tests can inspect
|
|
8
|
+
/// topics and data using normal Soroban conversions (`TryFromVal` / `IntoVal`).
|
|
9
|
+
///
|
|
10
|
+
/// Returns `None` if any topic or the data payload can't be converted into `Val` for the
|
|
11
|
+
/// provided `Env`.
|
|
12
|
+
///
|
|
13
|
+
/// # Example
|
|
14
|
+
/// ```ignore
|
|
15
|
+
/// let events = env.events().all().filter_by_contract(&contract);
|
|
16
|
+
/// for ev in events.events().iter() {
|
|
17
|
+
/// let (topics, data) = utils::testing_utils::decode_event_topics_data(&env, ev).unwrap();
|
|
18
|
+
/// // ... inspect topics/data ...
|
|
19
|
+
/// }
|
|
20
|
+
/// ```
|
|
21
|
+
pub fn decode_event_topics_data(env: &Env, event: &xdr::ContractEvent) -> Option<(Vec<Val>, Val)> {
|
|
22
|
+
// In the current Soroban SDK version this is always `V0`.
|
|
23
|
+
// Using a single-variant match avoids "irrefutable let-else" warnings.
|
|
24
|
+
let v0 = match &event.body {
|
|
25
|
+
xdr::ContractEventBody::V0(v0) => v0,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
let mut topics = Vec::<Val>::new(env);
|
|
29
|
+
for t in v0.topics.iter() {
|
|
30
|
+
topics.push_back(Val::try_from_val(env, t).ok()?);
|
|
14
31
|
}
|
|
15
|
-
|
|
32
|
+
let data = Val::try_from_val(env, &v0.data).ok()?;
|
|
33
|
+
Some((topics, data))
|
|
16
34
|
}
|
|
17
35
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
/// Asserts that the environment emitted exactly one event: `expected`.
|
|
37
|
+
///
|
|
38
|
+
/// This is a **strict equality** assertion over `env.events().all()`:
|
|
39
|
+
/// the full event list must be exactly `[expected]` (no extra events).
|
|
40
|
+
///
|
|
41
|
+
/// Uses the event struct's `.topics()` and `.data()` methods (generated by `#[contractevent]`)
|
|
42
|
+
/// to compare against emitted events. No more hardcoding topic names or field keys!
|
|
43
|
+
///
|
|
44
|
+
/// # Example
|
|
45
|
+
/// ```ignore
|
|
46
|
+
/// use crate::events::OwnershipTransferred;
|
|
47
|
+
///
|
|
48
|
+
/// let expected = OwnershipTransferred {
|
|
49
|
+
/// previous_owner: owner.clone(),
|
|
50
|
+
/// new_owner: new_owner.clone(),
|
|
51
|
+
/// };
|
|
52
|
+
/// assert_eq_event(&env, &contract, expected);
|
|
53
|
+
/// ```
|
|
54
|
+
pub fn assert_eq_event<E: Event>(env: &Env, contract: &Address, expected: E) {
|
|
55
|
+
// Compare against the emitted `xdr::ContractEvent` directly. This avoids the
|
|
56
|
+
// `xdr -> Val` roundtrip and ensures we match exactly what was emitted.
|
|
57
|
+
//
|
|
58
|
+
// IMPORTANT: This asserts *equality* (not "contains").
|
|
59
|
+
extern crate std;
|
|
60
|
+
|
|
61
|
+
assert_eq!(
|
|
62
|
+
env.events().all(),
|
|
63
|
+
std::vec![expected.to_xdr(env, contract)],
|
|
64
|
+
"Expected exactly one event. Expected topics: {:?}, data: {:?}",
|
|
65
|
+
expected.topics(env),
|
|
66
|
+
expected.data(env),
|
|
67
|
+
);
|
|
21
68
|
}
|
|
22
69
|
|
|
23
|
-
/// Asserts that
|
|
70
|
+
/// Asserts that the contract emitted an event equal to `expected`.
|
|
71
|
+
///
|
|
72
|
+
/// This is a **contains** assertion: after filtering events by `contract`,
|
|
73
|
+
/// `expected` must appear at least once (order doesn't matter; extra events allowed).
|
|
24
74
|
///
|
|
25
75
|
/// Uses the event struct's `.topics()` and `.data()` methods (generated by `#[contractevent]`)
|
|
26
76
|
/// to compare against emitted events. No more hardcoding topic names or field keys!
|
|
@@ -33,68 +83,86 @@ fn data_eq(env: &Env, a: &Val, b: &Val) -> bool {
|
|
|
33
83
|
/// previous_owner: owner.clone(),
|
|
34
84
|
/// new_owner: new_owner.clone(),
|
|
35
85
|
/// };
|
|
36
|
-
///
|
|
86
|
+
/// assert_eq_event(&env, &contract, expected);
|
|
37
87
|
/// ```
|
|
38
|
-
pub fn
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
let
|
|
88
|
+
pub fn assert_contains_event<E: Event>(env: &Env, contract: &Address, expected: E) {
|
|
89
|
+
// Compare against the emitted `xdr::ContractEvent` directly. This avoids the
|
|
90
|
+
// `xdr -> Val` roundtrip and ensures we match exactly what was emitted.
|
|
91
|
+
let expected_xdr = expected.to_xdr(env, contract);
|
|
42
92
|
|
|
93
|
+
let events = env.events().all().filter_by_contract(contract);
|
|
43
94
|
let mut found = false;
|
|
44
|
-
for
|
|
45
|
-
if
|
|
95
|
+
for event in events.events().iter() {
|
|
96
|
+
if *event == expected_xdr {
|
|
46
97
|
found = true;
|
|
47
98
|
break;
|
|
48
99
|
}
|
|
49
100
|
}
|
|
50
101
|
|
|
51
|
-
assert!(
|
|
102
|
+
assert!(
|
|
103
|
+
found,
|
|
104
|
+
"Expected event not found. Expected topics: {:?}, data: {:?}",
|
|
105
|
+
expected.topics(env),
|
|
106
|
+
expected.data(env)
|
|
107
|
+
);
|
|
52
108
|
}
|
|
53
109
|
|
|
54
|
-
///
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
110
|
+
/// Asserts that the environment emitted events that match `expected_events` exactly.
|
|
111
|
+
///
|
|
112
|
+
/// This is a **strict equality** assertion over `env.events().all()`:
|
|
113
|
+
/// the full event list must match `expected_events` **in order** and **count**
|
|
114
|
+
/// (no missing/extra events).
|
|
115
|
+
///
|
|
116
|
+
/// # Example
|
|
117
|
+
/// ```ignore
|
|
118
|
+
/// assert_eq_events(env, &contract, &[
|
|
119
|
+
/// &Event1 { ... },
|
|
120
|
+
/// &Event2 { ... },
|
|
121
|
+
/// ]);
|
|
122
|
+
/// ```
|
|
59
123
|
|
|
60
|
-
pub
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
124
|
+
pub fn assert_eq_events(env: &Env, contract: &Address, expected_events: &[&dyn Event]) {
|
|
125
|
+
// Note: this module is only compiled for tests / testutils usage, where `std` is available.
|
|
126
|
+
extern crate std;
|
|
127
|
+
let expected_xdrs: std::vec::Vec<xdr::ContractEvent> =
|
|
128
|
+
expected_events.iter().map(|e| e.to_xdr(env, contract)).collect();
|
|
65
129
|
|
|
66
|
-
|
|
67
|
-
|
|
130
|
+
assert_eq!(env.events().all(), expected_xdrs, "Expected events to match exactly");
|
|
131
|
+
}
|
|
68
132
|
|
|
69
|
-
/// Asserts that all
|
|
70
|
-
///
|
|
133
|
+
/// Asserts that all `expected_events` were emitted by the contract (in any order).
|
|
134
|
+
///
|
|
135
|
+
/// This is a **contains** assertion with multiset semantics: after filtering events by
|
|
136
|
+
/// `contract`, every expected event must be present, and duplicates in `expected_events`
|
|
137
|
+
/// require duplicate emissions. Extra emitted events are allowed.
|
|
71
138
|
///
|
|
72
139
|
/// # Example
|
|
73
140
|
/// ```ignore
|
|
74
|
-
///
|
|
75
|
-
///
|
|
76
|
-
///
|
|
77
|
-
/// Event1 { ... }.expected(env),
|
|
78
|
-
/// Event2 { ... }.expected(env),
|
|
141
|
+
/// assert_eq_events(env, &contract, &[
|
|
142
|
+
/// &Event1 { ... },
|
|
143
|
+
/// &Event2 { ... },
|
|
79
144
|
/// ]);
|
|
80
145
|
/// ```
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// Track which emitted events have already been matched so that duplicate expectations
|
|
84
|
-
// require duplicate emissions (multiset semantics).
|
|
85
|
-
//
|
|
146
|
+
|
|
147
|
+
pub fn assert_contains_events(env: &Env, contract: &Address, expected_events: &[&dyn Event]) {
|
|
86
148
|
// Note: this module is only compiled for tests / testutils usage, where `std` is available.
|
|
87
149
|
extern crate std;
|
|
88
|
-
let
|
|
150
|
+
let events = env.events().all().filter_by_contract(contract);
|
|
151
|
+
let raw_events = events.events();
|
|
152
|
+
// Track which emitted events have already been matched so that duplicate expectations
|
|
153
|
+
// require duplicate emissions (multiset semantics).
|
|
154
|
+
// We use a `std::vec::Vec<bool>` as a "used" mask to implement multiset matching.
|
|
155
|
+
let mut used: std::vec::Vec<bool> = std::vec![false; raw_events.len()];
|
|
89
156
|
|
|
90
157
|
for (i, expected) in expected_events.iter().enumerate() {
|
|
158
|
+
let expected_xdr = expected.to_xdr(env, contract);
|
|
159
|
+
|
|
91
160
|
let mut found = false;
|
|
92
|
-
for (idx,
|
|
161
|
+
for (idx, event) in raw_events.iter().enumerate() {
|
|
93
162
|
if used[idx] {
|
|
94
163
|
continue;
|
|
95
164
|
}
|
|
96
|
-
if
|
|
97
|
-
{
|
|
165
|
+
if *event == expected_xdr {
|
|
98
166
|
used[idx] = true;
|
|
99
167
|
found = true;
|
|
100
168
|
break;
|
|
@@ -104,7 +172,9 @@ pub fn assert_events(env: &Env, contract: &Address, expected_events: &[ExpectedE
|
|
|
104
172
|
assert!(
|
|
105
173
|
found,
|
|
106
174
|
"Expected event #{} not found. Expected topics: {:?}, data: {:?}",
|
|
107
|
-
i,
|
|
175
|
+
i,
|
|
176
|
+
expected.topics(env),
|
|
177
|
+
expected.data(env)
|
|
108
178
|
);
|
|
109
179
|
}
|
|
110
180
|
}
|
|
@@ -9,6 +9,8 @@ use soroban_sdk::{
|
|
|
9
9
|
vec, Address, BytesN, Env, IntoVal, Symbol, TryIntoVal, Val, Vec,
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
use crate::testing_utils::decode_event_topics_data;
|
|
13
|
+
|
|
12
14
|
// Test contract implementing Multisig + Auth (self-owning)
|
|
13
15
|
#[contract]
|
|
14
16
|
pub struct TestContract;
|
|
@@ -60,14 +62,13 @@ fn assert_auth(env: &Env, contract: &Address, func: &str, expected_args: Vec<Val
|
|
|
60
62
|
|
|
61
63
|
fn assert_signer_set_event(env: &Env, contract: &Address, signer: &BytesN<20>, active: bool) {
|
|
62
64
|
use soroban_sdk::Map;
|
|
63
|
-
let events = env.events().all();
|
|
65
|
+
let events = env.events().all().filter_by_contract(contract);
|
|
64
66
|
// Find the signer_set event for this contract (snake_case event name)
|
|
65
|
-
let found = events.iter().any(|event| {
|
|
66
|
-
|
|
67
|
+
let found = events.events().iter().any(|event| {
|
|
68
|
+
let Some((topics, data)) = decode_event_topics_data(env, event) else {
|
|
67
69
|
return false;
|
|
68
|
-
}
|
|
70
|
+
};
|
|
69
71
|
// Check topics: ["signer_set", signer]
|
|
70
|
-
let topics = &event.1;
|
|
71
72
|
if topics.len() != 2 {
|
|
72
73
|
return false;
|
|
73
74
|
}
|
|
@@ -77,7 +78,7 @@ fn assert_signer_set_event(env: &Env, contract: &Address, signer: &BytesN<20>, a
|
|
|
77
78
|
return false;
|
|
78
79
|
}
|
|
79
80
|
// Check data is a map with "active" field
|
|
80
|
-
let data_map: Map<Symbol, bool> =
|
|
81
|
+
let data_map: Map<Symbol, bool> = data.try_into_val(env).unwrap();
|
|
81
82
|
data_map.get(Symbol::new(env, "active")) == Some(active)
|
|
82
83
|
});
|
|
83
84
|
assert!(found, "signer_set event not found");
|
|
@@ -85,14 +86,13 @@ fn assert_signer_set_event(env: &Env, contract: &Address, signer: &BytesN<20>, a
|
|
|
85
86
|
|
|
86
87
|
fn assert_threshold_set_event(env: &Env, contract: &Address, threshold: u32) {
|
|
87
88
|
use soroban_sdk::Map;
|
|
88
|
-
let events = env.events().all();
|
|
89
|
+
let events = env.events().all().filter_by_contract(contract);
|
|
89
90
|
// Find the threshold_set event for this contract (snake_case event name)
|
|
90
|
-
let found = events.iter().any(|event| {
|
|
91
|
-
|
|
91
|
+
let found = events.events().iter().any(|event| {
|
|
92
|
+
let Some((topics, data)) = decode_event_topics_data(env, event) else {
|
|
92
93
|
return false;
|
|
93
|
-
}
|
|
94
|
+
};
|
|
94
95
|
// Check topics: ["threshold_set"]
|
|
95
|
-
let topics = &event.1;
|
|
96
96
|
if topics.len() != 1 {
|
|
97
97
|
return false;
|
|
98
98
|
}
|
|
@@ -101,7 +101,7 @@ fn assert_threshold_set_event(env: &Env, contract: &Address, threshold: u32) {
|
|
|
101
101
|
return false;
|
|
102
102
|
}
|
|
103
103
|
// Check data is a map with "threshold" field
|
|
104
|
-
let data_map: Map<Symbol, u32> =
|
|
104
|
+
let data_map: Map<Symbol, u32> = data.try_into_val(env).unwrap();
|
|
105
105
|
data_map.get(Symbol::new(env, "threshold")) == Some(threshold)
|
|
106
106
|
});
|
|
107
107
|
assert!(found, "threshold_set event not found");
|
|
@@ -6,7 +6,7 @@ use crate::{
|
|
|
6
6
|
self, Ownable, OwnableInitializer, OwnableStorage, OwnershipRenounced, OwnershipTransferred,
|
|
7
7
|
OwnershipTransferring,
|
|
8
8
|
},
|
|
9
|
-
testing_utils::
|
|
9
|
+
testing_utils::assert_eq_event,
|
|
10
10
|
};
|
|
11
11
|
use soroban_sdk::{
|
|
12
12
|
contract, contractimpl,
|
|
@@ -137,7 +137,7 @@ fn transfer_ownership_with_event() {
|
|
|
137
137
|
}]);
|
|
138
138
|
client.transfer_ownership(&new_owner);
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
assert_eq_event(&env, &contract, OwnershipTransferred { old_owner: owner, new_owner: new_owner.clone() });
|
|
141
141
|
assert_eq!(client.owner(), Some(new_owner));
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -163,7 +163,7 @@ fn transfer_ownership_to_same_owner() {
|
|
|
163
163
|
client.transfer_ownership(&owner);
|
|
164
164
|
|
|
165
165
|
// Should still emit event and update (even if same owner)
|
|
166
|
-
|
|
166
|
+
assert_eq_event(&env, &contract, OwnershipTransferred { old_owner: owner.clone(), new_owner: owner.clone() });
|
|
167
167
|
assert_eq!(client.owner(), Some(owner));
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -270,7 +270,7 @@ fn propose_ownership_transfer_initiate_and_accept() {
|
|
|
270
270
|
}]);
|
|
271
271
|
client.propose_ownership_transfer(&new_owner, &ttl);
|
|
272
272
|
|
|
273
|
-
|
|
273
|
+
assert_eq_event(
|
|
274
274
|
&env,
|
|
275
275
|
&contract,
|
|
276
276
|
OwnershipTransferring { old_owner: owner.clone(), new_owner: new_owner.clone(), ttl },
|
|
@@ -290,7 +290,7 @@ fn propose_ownership_transfer_initiate_and_accept() {
|
|
|
290
290
|
}]);
|
|
291
291
|
client.accept_ownership();
|
|
292
292
|
|
|
293
|
-
|
|
293
|
+
assert_eq_event(&env, &contract, OwnershipTransferred { old_owner: owner, new_owner: new_owner.clone() });
|
|
294
294
|
assert_eq!(client.owner(), Some(new_owner)); // Now new owner
|
|
295
295
|
assert_eq!(client.pending_owner(), None);
|
|
296
296
|
}
|
|
@@ -564,7 +564,7 @@ fn renounce_ownership_with_event() {
|
|
|
564
564
|
}]);
|
|
565
565
|
client.renounce_ownership();
|
|
566
566
|
|
|
567
|
-
|
|
567
|
+
assert_eq_event(&env, &contract, OwnershipRenounced { old_owner: owner });
|
|
568
568
|
assert_eq!(client.owner(), None);
|
|
569
569
|
}
|
|
570
570
|
|