@layerzerolabs/protocol-stellar-v2 0.2.15 → 0.2.18
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 +350 -309
- package/.turbo/turbo-lint.log +146 -108
- package/.turbo/turbo-test.log +1423 -1238
- package/Cargo.lock +12 -0
- package/Cargo.toml +3 -0
- package/contracts/ERROR_SPEC.md +44 -0
- package/contracts/common-macros/src/auth.rs +113 -0
- package/contracts/common-macros/src/contract_ttl.rs +84 -0
- package/contracts/common-macros/src/lib.rs +181 -30
- package/contracts/common-macros/src/lz_contract.rs +83 -0
- package/contracts/common-macros/src/tests/{ownable.rs → auth.rs} +48 -15
- package/contracts/common-macros/src/tests/contract_ttl.rs +662 -0
- package/contracts/common-macros/src/tests/mod.rs +2 -2
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +20 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +24 -0
- package/contracts/common-macros/src/tests/snapshots/{common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap → common_macros__tests__auth__snapshot_only_auth_preserves_function_signature.snap} +4 -4
- package/contracts/common-macros/src/tests/snapshots/{common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap → common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap} +3 -3
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contracttrait_code.snap +69 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +7 -21
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +2 -2
- package/contracts/common-macros/src/ttl_configurable.rs +19 -34
- package/contracts/common-macros/src/ttl_extendable.rs +36 -0
- package/contracts/common-macros/src/upgradeable.rs +5 -5
- package/contracts/common-macros/src/utils.rs +9 -0
- package/contracts/endpoint-v2/src/constants.rs +4 -4
- package/contracts/endpoint-v2/src/endpoint_v2.rs +38 -40
- package/contracts/endpoint-v2/src/errors.rs +4 -3
- package/contracts/endpoint-v2/src/events.rs +1 -1
- package/contracts/endpoint-v2/src/message_lib_manager.rs +18 -5
- package/contracts/endpoint-v2/src/messaging_channel.rs +11 -1
- package/contracts/endpoint-v2/src/messaging_composer.rs +11 -1
- package/contracts/endpoint-v2/src/storage.rs +1 -1
- package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +3 -3
- package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +1 -1
- package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +2 -2
- package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +3 -3
- package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_receive_lib_for_eid.rs +3 -3
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +1 -1
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_send_lib_for_eid.rs +3 -3
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +4 -4
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +1 -1
- package/contracts/layerzero-views/src/layerzero_view.rs +3 -6
- package/contracts/macro-integration-tests/tests/runtime/ownable/mod.rs +2 -2
- package/contracts/macro-integration-tests/tests/runtime/ownable/{only_owner_guard.rs → only_auth_guard.rs} +1 -1
- package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/configuration.rs +1 -1
- package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/freeze.rs +1 -1
- package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/mod.rs +0 -1
- package/contracts/macro-integration-tests/tests/ui/ownable/fail/{only_owner_missing_env.rs → only_auth_missing_env.rs} +3 -3
- package/contracts/macro-integration-tests/tests/ui/ownable/fail/{only_owner_missing_env.stderr → only_auth_missing_env.stderr} +4 -4
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +2 -3
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/{only_owner_env_param_variants.rs → only_auth_env_param_variants.rs} +9 -9
- package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/minimal_contract.rs +6 -6
- package/contracts/message-libs/message-lib-common/src/errors.rs +7 -2
- package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/decode_packet_header.rs +3 -3
- package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_lz_receive_option.rs +1 -2
- package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_native_drop_option.rs +1 -2
- package/contracts/message-libs/message-lib-common/src/tests/worker_options/convert_legacy_options.rs +9 -9
- package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs +1 -1
- package/contracts/message-libs/message-lib-common/src/tests/worker_options/left_pad_to_bytes32.rs +1 -1
- package/contracts/message-libs/message-lib-common/src/tests/worker_options/split_worker_options.rs +2 -2
- package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +7 -9
- package/contracts/message-libs/treasury/src/errors.rs +2 -2
- package/contracts/message-libs/treasury/src/events.rs +1 -1
- package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +2 -2
- package/contracts/message-libs/treasury/src/storage.rs +1 -1
- package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +1 -1
- package/contracts/message-libs/treasury/src/treasury.rs +14 -16
- package/contracts/message-libs/uln-302/src/receive_uln.rs +13 -2
- package/contracts/message-libs/uln-302/src/send_uln.rs +23 -3
- package/contracts/message-libs/uln-302/src/uln302.rs +6 -24
- package/contracts/oapps/counter/Cargo.toml +14 -1
- package/contracts/oapps/counter/integration_tests/mod.rs +4 -1
- package/contracts/oapps/counter/integration_tests/{setup.rs → setup_sml.rs} +48 -80
- package/contracts/oapps/counter/integration_tests/setup_uln.rs +997 -0
- package/contracts/oapps/counter/integration_tests/signing.rs +62 -0
- package/contracts/oapps/counter/integration_tests/test_with_sml.rs +24 -55
- package/contracts/oapps/counter/integration_tests/test_with_uln.rs +314 -0
- package/contracts/oapps/counter/integration_tests/utils.rs +196 -53
- package/contracts/oapps/counter/src/counter.rs +67 -43
- package/contracts/oapps/counter/src/tests/mod.rs +0 -13
- package/contracts/oapps/counter/src/tests/test_counter.rs +5 -7
- package/contracts/oapps/oapp/src/errors.rs +5 -1
- package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +93 -78
- package/contracts/oapps/oapp/src/oapp_core.rs +36 -21
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +48 -12
- package/contracts/oapps/oapp/src/oapp_receiver.rs +106 -41
- package/contracts/oapps/oapp/src/oapp_sender.rs +26 -34
- package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +9 -8
- package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +25 -17
- package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +7 -7
- package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +14 -15
- package/contracts/oapps/oapp-macros/src/generators.rs +128 -0
- package/contracts/oapps/oapp-macros/src/lib.rs +113 -56
- package/contracts/oapps/oft/integration-tests/setup.rs +25 -7
- package/contracts/oapps/oft/src/errors.rs +6 -1
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +8 -8
- package/contracts/oapps/oft/src/extensions/pausable.rs +4 -4
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +5 -5
- package/contracts/oapps/oft/src/lib.rs +4 -2
- package/contracts/oapps/oft/src/oft.rs +24 -64
- package/contracts/oapps/oft/src/oft_impl.rs +201 -0
- package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +1 -3
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -4
- package/contracts/oapps/oft/src/storage.rs +2 -0
- package/contracts/oapps/oft/src/tests/extensions/setup.rs +36 -22
- package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +5 -3
- package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +5 -3
- package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +5 -3
- package/contracts/oapps/oft/src/tests/test_decimals.rs +2 -2
- package/contracts/oapps/oft/src/tests/test_oft_msg_codec.rs +1 -2
- package/contracts/oapps/oft/src/tests/test_utils.rs +45 -23
- package/contracts/oapps/oft/src/types.rs +20 -0
- package/contracts/oapps/oft-std/integration-tests/setup.rs +4 -2
- package/contracts/oapps/oft-std/src/oft.rs +24 -6
- package/contracts/upgrader/src/lib.rs +4 -4
- package/contracts/utils/src/auth.rs +44 -0
- package/contracts/utils/src/errors.rs +27 -5
- package/contracts/utils/src/lib.rs +3 -0
- package/contracts/utils/src/multisig.rs +211 -0
- package/contracts/utils/src/ownable.rs +12 -10
- package/contracts/utils/src/tests/buffer_reader.rs +6 -6
- package/contracts/utils/src/tests/buffer_writer.rs +6 -6
- package/contracts/utils/src/tests/bytes_ext.rs +2 -4
- package/contracts/utils/src/tests/mod.rs +1 -0
- package/contracts/utils/src/tests/multisig.rs +731 -0
- package/contracts/utils/src/tests/option_ext.rs +2 -5
- package/contracts/utils/src/tests/ownable.rs +16 -5
- package/contracts/utils/src/tests/ttl_configurable.rs +27 -16
- package/contracts/utils/src/tests/upgradeable.rs +4 -2
- package/contracts/utils/src/ttl_configurable.rs +23 -8
- package/contracts/utils/src/ttl_extendable.rs +27 -0
- package/contracts/utils/src/upgradeable.rs +2 -0
- package/contracts/workers/dvn/Cargo.toml +1 -1
- package/contracts/workers/dvn/src/auth.rs +7 -7
- package/contracts/workers/dvn/src/dvn.rs +10 -38
- package/contracts/workers/dvn/src/errors.rs +0 -7
- package/contracts/workers/dvn/src/events.rs +1 -14
- package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
- package/contracts/workers/dvn/src/interfaces/mod.rs +0 -2
- package/contracts/workers/dvn/src/storage.rs +3 -13
- package/contracts/workers/dvn/src/tests/auth.rs +4 -4
- package/contracts/workers/dvn/src/tests/dvn.rs +1 -2
- package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +7 -8
- package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +11 -8
- package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +11 -12
- package/contracts/workers/dvn/src/tests/setup.rs +5 -5
- package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
- package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +3 -6
- package/contracts/workers/executor/src/auth.rs +80 -16
- package/contracts/workers/executor/src/executor.rs +5 -31
- package/contracts/workers/executor/src/storage.rs +2 -9
- package/contracts/workers/executor-fee-lib/Cargo.toml +1 -1
- package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +3 -6
- package/contracts/workers/executor-helper/Cargo.toml +1 -1
- package/contracts/workers/executor-helper/src/executor_helper.rs +53 -73
- package/contracts/workers/price-feed/Cargo.toml +1 -1
- package/contracts/workers/price-feed/src/price_feed.rs +7 -10
- package/contracts/workers/worker/src/errors.rs +4 -0
- package/contracts/workers/worker/src/tests/worker.rs +7 -6
- package/contracts/workers/worker/src/worker.rs +20 -16
- package/package.json +8 -5
- package/sdk/.turbo/turbo-build.log +1 -0
- package/sdk/.turbo/turbo-test.log +1009 -0
- package/sdk/dist/generated/bml.d.ts +65 -8
- package/sdk/dist/generated/bml.js +70 -34
- package/sdk/dist/generated/counter.d.ts +167 -42
- package/sdk/dist/generated/counter.js +86 -45
- package/sdk/dist/generated/dvn.d.ts +282 -229
- package/sdk/dist/generated/dvn.js +119 -81
- package/sdk/dist/generated/dvn_fee_lib.d.ts +142 -67
- package/sdk/dist/generated/dvn_fee_lib.js +64 -24
- package/sdk/dist/generated/endpoint.d.ts +97 -22
- package/sdk/dist/generated/endpoint.js +75 -37
- package/sdk/dist/generated/executor.d.ts +117 -85
- package/sdk/dist/generated/executor.js +102 -59
- package/sdk/dist/generated/executor_fee_lib.d.ts +162 -78
- package/sdk/dist/generated/executor_fee_lib.js +104 -57
- package/sdk/dist/generated/executor_helper.d.ts +133 -21
- package/sdk/dist/generated/executor_helper.js +99 -50
- package/sdk/dist/generated/oft_std.d.ts +233 -55
- package/sdk/dist/generated/oft_std.js +99 -54
- package/sdk/dist/generated/price_feed.d.ts +142 -67
- package/sdk/dist/generated/price_feed.js +64 -24
- package/sdk/dist/generated/sml.d.ts +113 -32
- package/sdk/dist/generated/sml.js +93 -49
- package/sdk/dist/generated/treasury.d.ts +896 -0
- package/sdk/dist/generated/treasury.js +219 -0
- package/sdk/dist/generated/uln302.d.ts +113 -32
- package/sdk/dist/generated/uln302.js +93 -49
- package/sdk/dist/generated/upgrader.d.ts +2 -2
- package/sdk/dist/generated/upgrader.js +1 -1
- package/sdk/dist/index.d.ts +2 -0
- package/sdk/dist/index.js +3 -0
- package/sdk/dist/wasm/blocked-message-lib.d.ts +1 -0
- package/sdk/dist/wasm/blocked-message-lib.js +2 -0
- package/sdk/dist/wasm/counter.d.ts +1 -0
- package/sdk/dist/wasm/counter.js +2 -0
- package/sdk/dist/wasm/dvn-fee-lib.d.ts +1 -0
- package/sdk/dist/wasm/dvn-fee-lib.js +2 -0
- package/sdk/dist/wasm/dvn.d.ts +1 -0
- package/sdk/dist/wasm/dvn.js +2 -0
- package/sdk/dist/wasm/endpoint-v2.d.ts +1 -0
- package/sdk/dist/wasm/endpoint-v2.js +2 -0
- package/sdk/dist/wasm/executor-fee-lib.d.ts +1 -0
- package/sdk/dist/wasm/executor-fee-lib.js +2 -0
- package/sdk/dist/wasm/executor-helper.d.ts +1 -0
- package/sdk/dist/wasm/executor-helper.js +2 -0
- package/sdk/dist/wasm/executor.d.ts +1 -0
- package/sdk/dist/wasm/executor.js +2 -0
- package/sdk/dist/wasm/layerzero-views.d.ts +1 -0
- package/sdk/dist/wasm/layerzero-views.js +2 -0
- package/sdk/dist/wasm/oft-std.d.ts +1 -0
- package/sdk/dist/wasm/oft-std.js +2 -0
- package/sdk/dist/wasm/price-feed.d.ts +1 -0
- package/sdk/dist/wasm/price-feed.js +2 -0
- package/sdk/dist/wasm/simple-message-lib.d.ts +1 -0
- package/sdk/dist/wasm/simple-message-lib.js +2 -0
- package/sdk/dist/wasm/treasury.d.ts +1 -0
- package/sdk/dist/wasm/treasury.js +2 -0
- package/sdk/dist/wasm/uln302.d.ts +1 -0
- package/sdk/dist/wasm/uln302.js +2 -0
- package/sdk/dist/wasm/upgrader.d.ts +1 -0
- package/sdk/dist/wasm/upgrader.js +2 -0
- package/sdk/dist/wasm.d.ts +15 -0
- package/sdk/dist/wasm.js +15 -0
- package/sdk/package.json +4 -2
- package/sdk/src/index.ts +4 -0
- package/sdk/test/counter-sml.test.ts +376 -0
- package/sdk/test/counter-uln.test.ts +493 -0
- package/sdk/test/{oft.test.ts → oft-sml.test.ts} +185 -310
- package/sdk/test/suites/constants.ts +22 -2
- package/sdk/test/suites/globalSetup.ts +450 -0
- package/sdk/test/suites/localnet.ts +23 -6
- package/sdk/test/upgrader.test.ts +7 -16
- package/sdk/test/utils.ts +558 -85
- package/sdk/vitest.config.ts +21 -0
- package/tools/ts-bindings-gen/src/main.rs +1 -0
- package/turbo.json +2 -0
- package/contracts/common-macros/src/contract_impl.rs +0 -52
- package/contracts/common-macros/src/ownable.rs +0 -41
- package/contracts/common-macros/src/tests/contract_impl.rs +0 -386
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +0 -12
- package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/extend_instance_ttl.rs +0 -50
- package/contracts/oapps/oapp-macros/src/oapp_core.rs +0 -41
- package/contracts/oapps/oapp-macros/src/oapp_full.rs +0 -21
- package/contracts/oapps/oapp-macros/src/oapp_options_type3.rs +0 -31
- package/contracts/oapps/oapp-macros/src/oapp_receiver.rs +0 -48
- package/contracts/oapps/oapp-macros/src/oapp_sender.rs +0 -21
- package/contracts/oapps/oapp-macros/src/util.rs +0 -107
- package/contracts/oapps/oft/src/constants.rs +0 -5
- package/contracts/oapps/oft/src/default_oft_impl.rs +0 -152
- package/contracts/workers/dvn/src/interfaces/multisig.rs +0 -56
- package/contracts/workers/dvn/src/multisig.rs +0 -157
- package/sdk/test/index.test.ts +0 -375
- /package/sdk/test/suites/{testUpgradeable.ts → dummyContractClient.ts} +0 -0
|
@@ -0,0 +1,997 @@
|
|
|
1
|
+
extern crate std;
|
|
2
|
+
|
|
3
|
+
use crate::{
|
|
4
|
+
counter::{Counter, CounterClient},
|
|
5
|
+
integration_tests::{
|
|
6
|
+
signing::{Ed25519KeyPair, Secp256k1KeyPair},
|
|
7
|
+
utils::{address_to_bytes32, decode_packet, register_library, set_peer, set_zro, ChainSetupCommon},
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
use dvn::{DVNClient, DstConfig as DvnDstConfig, DstConfigParam as DvnDstConfigParam, LzDVN};
|
|
11
|
+
use dvn_fee_lib::DvnFeeLib;
|
|
12
|
+
use endpoint_v2::{EndpointV2, EndpointV2Client};
|
|
13
|
+
use executor::{DstConfig as ExecutorDstConfig, ExecutorClient, LzExecutor, SetDstConfigParam};
|
|
14
|
+
use executor_fee_lib::ExecutorFeeLib;
|
|
15
|
+
use executor_helper::{ExecutorHelper, ExecutorHelperClient};
|
|
16
|
+
use price_feed::{types::UpdatePrice, LzPriceFeed};
|
|
17
|
+
use soroban_sdk::{
|
|
18
|
+
testutils::{Address as _, MockAuth, MockAuthInvoke},
|
|
19
|
+
token::TokenClient,
|
|
20
|
+
vec, Address, BytesN, Env, IntoVal, Vec,
|
|
21
|
+
};
|
|
22
|
+
use treasury::Treasury;
|
|
23
|
+
use uln302::{
|
|
24
|
+
ExecutorConfig, ReceiveUln302Client, SendUln302Client, SetDefaultExecutorConfigParam, SetDefaultUlnConfigParam,
|
|
25
|
+
Uln302, Uln302Client, UlnConfig,
|
|
26
|
+
};
|
|
27
|
+
use utils::{buffer_reader::BufferReader, buffer_writer::BufferWriter};
|
|
28
|
+
use worker::Price;
|
|
29
|
+
|
|
30
|
+
pub const CONFIRMATIONS: u64 = 1;
|
|
31
|
+
pub const MAX_MESSAGE_SIZE: u32 = 10000;
|
|
32
|
+
pub const DVN_VID: u32 = 1; // DVN Verifier ID
|
|
33
|
+
|
|
34
|
+
// Price feed constants for testing
|
|
35
|
+
const PRICE_RATIO_DENOMINATOR: u128 = 10_u128.pow(20);
|
|
36
|
+
const DEFAULT_GAS_PRICE: u64 = 100;
|
|
37
|
+
const DEFAULT_GAS_PER_BYTE: u32 = 1;
|
|
38
|
+
const DEFAULT_MULTIPLIER_BPS: u32 = 10000; // 100%
|
|
39
|
+
|
|
40
|
+
// Worker options constants
|
|
41
|
+
const OPTIONS_TYPE_3: u16 = 3;
|
|
42
|
+
const EXECUTOR_WORKER_ID: u8 = 1;
|
|
43
|
+
const EXECUTOR_OPTION_TYPE_LZRECEIVE: u8 = 1;
|
|
44
|
+
|
|
45
|
+
#[allow(dead_code)]
|
|
46
|
+
const EXECUTOR_OPTION_TYPE_NATIVE_DROP: u8 = 2;
|
|
47
|
+
|
|
48
|
+
const EXECUTOR_OPTION_TYPE_LZCOMPOSE: u8 = 3;
|
|
49
|
+
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Options Creation Functions
|
|
52
|
+
// ============================================================================
|
|
53
|
+
|
|
54
|
+
/// Creates default ULN302 options with Type 3 format and basic lzReceive gas (no lzCompose).
|
|
55
|
+
/// This is required because ULN302 expects at least 2 bytes for the options type header.
|
|
56
|
+
pub fn create_default_options(env: &Env) -> soroban_sdk::Bytes {
|
|
57
|
+
create_options_with_gas(env, 100000, 0)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// Extracts the executor value (native token amount) from Type 3 options.
|
|
61
|
+
/// Returns 0 if no value is specified in the options.
|
|
62
|
+
pub fn get_executor_value_from_options(_env: &Env, options: &soroban_sdk::Bytes) -> i128 {
|
|
63
|
+
let mut reader = BufferReader::new(options);
|
|
64
|
+
|
|
65
|
+
// Skip options type header (2 bytes)
|
|
66
|
+
let _options_type = reader.read_u16();
|
|
67
|
+
|
|
68
|
+
// Parse options until we find lzReceive with value
|
|
69
|
+
while reader.remaining_len() > 0 {
|
|
70
|
+
let _worker_id = reader.read_u8();
|
|
71
|
+
let option_size = reader.read_u16();
|
|
72
|
+
let option_type = reader.read_u8();
|
|
73
|
+
|
|
74
|
+
if option_type == EXECUTOR_OPTION_TYPE_LZRECEIVE {
|
|
75
|
+
// option_size includes option_type(1) + data
|
|
76
|
+
// If data is 32 bytes (gas + value), extract value
|
|
77
|
+
// If data is 16 bytes (gas only), value is 0
|
|
78
|
+
let data_size = option_size - 1; // subtract option_type byte
|
|
79
|
+
let _gas = reader.read_u128();
|
|
80
|
+
if data_size == 32 {
|
|
81
|
+
return reader.read_u128() as i128;
|
|
82
|
+
}
|
|
83
|
+
return 0;
|
|
84
|
+
} else {
|
|
85
|
+
// Skip this option's data (option_size - 1 for option_type already read)
|
|
86
|
+
reader.skip((option_size - 1).into());
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
0
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// Extracts the lzCompose value (native token amount) from Type 3 options.
|
|
94
|
+
/// Returns 0 if no lzCompose value is specified in the options.
|
|
95
|
+
pub fn get_compose_value_from_options(_env: &Env, options: &soroban_sdk::Bytes) -> i128 {
|
|
96
|
+
let mut reader = BufferReader::new(options);
|
|
97
|
+
|
|
98
|
+
// Skip options type header (2 bytes)
|
|
99
|
+
let _options_type = reader.read_u16();
|
|
100
|
+
|
|
101
|
+
// Parse options until we find lzCompose with value
|
|
102
|
+
while reader.remaining_len() > 0 {
|
|
103
|
+
let _worker_id = reader.read_u8();
|
|
104
|
+
let option_size = reader.read_u16();
|
|
105
|
+
let option_type = reader.read_u8();
|
|
106
|
+
|
|
107
|
+
if option_type == EXECUTOR_OPTION_TYPE_LZCOMPOSE {
|
|
108
|
+
// option_size includes option_type(1) + data
|
|
109
|
+
// lzCompose format: [index: u16][gas: u128] (18 bytes) or [index: u16][gas: u128][value: u128] (34 bytes)
|
|
110
|
+
// So data_size is 18 or 34
|
|
111
|
+
let data_size = option_size - 1; // subtract option_type byte
|
|
112
|
+
let _index = reader.read_u16();
|
|
113
|
+
let _gas = reader.read_u128();
|
|
114
|
+
if data_size == 34 {
|
|
115
|
+
return reader.read_u128() as i128;
|
|
116
|
+
}
|
|
117
|
+
return 0;
|
|
118
|
+
} else {
|
|
119
|
+
// Skip this option's data (option_size - 1 for option_type already read)
|
|
120
|
+
reader.skip((option_size - 1).into());
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
0
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/// Creates ULN302 options with lzReceive gas and optional lzCompose gas.
|
|
128
|
+
/// Format: [options_type(2)][lzReceive option][lzCompose option (if lz_compose_gas > 0)]
|
|
129
|
+
///
|
|
130
|
+
/// # Arguments
|
|
131
|
+
/// * `env` - Soroban environment
|
|
132
|
+
/// * `gas` - Gas limit for lzReceive execution (always required)
|
|
133
|
+
/// * `lz_compose_gas` - Gas limit for lzCompose execution (only added if > 0)
|
|
134
|
+
pub fn create_options_with_gas(env: &Env, gas: u128, lz_compose_gas: u128) -> soroban_sdk::Bytes {
|
|
135
|
+
create_options_with_gas_and_value(env, gas, 0, lz_compose_gas, 0)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/// Creates ULN302 options with lzReceive gas/value and optional lzCompose gas/value.
|
|
139
|
+
/// Format: [options_type(2)][lzReceive option][lzCompose option (if lz_compose_gas > 0)]
|
|
140
|
+
///
|
|
141
|
+
/// # Arguments
|
|
142
|
+
/// * `env` - Soroban environment
|
|
143
|
+
/// * `gas` - Gas limit for lzReceive execution (always required)
|
|
144
|
+
/// * `value` - Native value for lzReceive (only added if > 0)
|
|
145
|
+
/// * `lz_compose_gas` - Gas limit for lzCompose execution (only added if > 0)
|
|
146
|
+
/// * `lz_compose_value` - Native value for lzCompose (only added if > 0)
|
|
147
|
+
pub fn create_options_with_gas_and_value(
|
|
148
|
+
env: &Env,
|
|
149
|
+
gas: u128,
|
|
150
|
+
value: u128,
|
|
151
|
+
lz_compose_gas: u128,
|
|
152
|
+
lz_compose_value: u128,
|
|
153
|
+
) -> soroban_sdk::Bytes {
|
|
154
|
+
let mut writer = BufferWriter::new(env);
|
|
155
|
+
|
|
156
|
+
// Type 3 options header
|
|
157
|
+
writer.write_u16(OPTIONS_TYPE_3);
|
|
158
|
+
|
|
159
|
+
// Add lzReceive option - include value only if > 0
|
|
160
|
+
if value > 0 {
|
|
161
|
+
writer
|
|
162
|
+
.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
|
|
163
|
+
.write_u16(33) // option_size: option_type(1) + gas(16) + value(16) = 33 bytes
|
|
164
|
+
.write_u8(EXECUTOR_OPTION_TYPE_LZRECEIVE) // option_type (1 byte)
|
|
165
|
+
.write_u128(gas) // execution gas (16 bytes)
|
|
166
|
+
.write_u128(value); // value (16 bytes)
|
|
167
|
+
} else {
|
|
168
|
+
writer
|
|
169
|
+
.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
|
|
170
|
+
.write_u16(17) // option_size: option_type(1) + gas(16) = 17 bytes
|
|
171
|
+
.write_u8(EXECUTOR_OPTION_TYPE_LZRECEIVE) // option_type (1 byte)
|
|
172
|
+
.write_u128(gas); // execution gas (16 bytes)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Add lzCompose option only if lz_compose_gas > 0
|
|
176
|
+
if lz_compose_gas > 0 {
|
|
177
|
+
if lz_compose_value > 0 {
|
|
178
|
+
// lzCompose with gas and value: [index: u16][gas: u128][value: u128] = 34 bytes
|
|
179
|
+
writer
|
|
180
|
+
.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
|
|
181
|
+
.write_u16(35) // option_size: option_type(1) + index(2) + gas(16) + value(16) = 35 bytes
|
|
182
|
+
.write_u8(EXECUTOR_OPTION_TYPE_LZCOMPOSE) // option_type (1 byte)
|
|
183
|
+
.write_u16(0) // compose index (2 bytes)
|
|
184
|
+
.write_u128(lz_compose_gas) // compose gas (16 bytes)
|
|
185
|
+
.write_u128(lz_compose_value); // compose value (16 bytes)
|
|
186
|
+
} else {
|
|
187
|
+
// lzCompose with gas only: [index: u16][gas: u128] = 18 bytes
|
|
188
|
+
writer
|
|
189
|
+
.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
|
|
190
|
+
.write_u16(19) // option_size: option_type(1) + index(2) + gas(16) = 19 bytes
|
|
191
|
+
.write_u8(EXECUTOR_OPTION_TYPE_LZCOMPOSE) // option_type (1 byte)
|
|
192
|
+
.write_u16(0) // compose index (2 bytes)
|
|
193
|
+
.write_u128(lz_compose_gas); // compose gas (16 bytes)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
writer.to_bytes()
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/// Creates ULN302 options with lzReceive gas and value (for ABA return messages).
|
|
201
|
+
/// Format: [options_type(2)][lzReceive option with gas and value]
|
|
202
|
+
pub fn create_aba_return_options(env: &Env) -> soroban_sdk::Bytes {
|
|
203
|
+
let mut writer = BufferWriter::new(env);
|
|
204
|
+
|
|
205
|
+
// Type 3 options header
|
|
206
|
+
writer.write_u16(OPTIONS_TYPE_3);
|
|
207
|
+
|
|
208
|
+
// Add lzReceive option with gas=200000 and value=10 (matching Counter's ABA return)
|
|
209
|
+
writer
|
|
210
|
+
.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
|
|
211
|
+
.write_u16(33) // option_size: option_type(1) + gas(16) + value(16) = 33 bytes
|
|
212
|
+
.write_u8(EXECUTOR_OPTION_TYPE_LZRECEIVE) // option_type (1 byte)
|
|
213
|
+
.write_u128(200000) // execution gas (16 bytes)
|
|
214
|
+
.write_u128(10); // value (16 bytes)
|
|
215
|
+
|
|
216
|
+
writer.to_bytes()
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/// Creates ULN302 options for ComposedABA return (gas=200000, no lzCompose).
|
|
220
|
+
pub fn create_composed_aba_return_options(env: &Env) -> soroban_sdk::Bytes {
|
|
221
|
+
create_options_with_gas(env, 200000, 0)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/// Creates ULN302 options with native drop included.
|
|
225
|
+
/// Format: [options_type(2)][lzReceive option][native drop option]
|
|
226
|
+
#[allow(dead_code)]
|
|
227
|
+
pub fn create_options_with_native_drop(env: &Env, amount: u128, receiver: &BytesN<32>) -> soroban_sdk::Bytes {
|
|
228
|
+
let mut writer = BufferWriter::new(env);
|
|
229
|
+
|
|
230
|
+
// Type 3 options header
|
|
231
|
+
writer.write_u16(OPTIONS_TYPE_3);
|
|
232
|
+
|
|
233
|
+
// Add a basic lzReceive option with default gas (100000)
|
|
234
|
+
writer
|
|
235
|
+
.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
|
|
236
|
+
.write_u16(17) // option_size: option_type(1) + data(16) = 17 bytes
|
|
237
|
+
.write_u8(EXECUTOR_OPTION_TYPE_LZRECEIVE) // option_type (1 byte)
|
|
238
|
+
.write_u128(100000); // execution gas data (16 bytes)
|
|
239
|
+
|
|
240
|
+
// Add native drop option
|
|
241
|
+
writer
|
|
242
|
+
.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
|
|
243
|
+
.write_u16(49) // option_size: option_type(1) + amount(16) + receiver(32) = 49 bytes
|
|
244
|
+
.write_u8(EXECUTOR_OPTION_TYPE_NATIVE_DROP) // option_type (1 byte)
|
|
245
|
+
.write_u128(amount) // drop amount (16 bytes)
|
|
246
|
+
.write_bytes_n(receiver); // receiver address (32 bytes)
|
|
247
|
+
|
|
248
|
+
writer.to_bytes()
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// ============================================================================
|
|
252
|
+
// Test Setup
|
|
253
|
+
// ============================================================================
|
|
254
|
+
|
|
255
|
+
/// DVN credentials for initialization (addresses for signers and admin).
|
|
256
|
+
pub struct DvnCredentials {
|
|
257
|
+
/// secp256k1 addresses for DVN multisig
|
|
258
|
+
pub signers: std::vec::Vec<Secp256k1KeyPair>,
|
|
259
|
+
/// Ed25519 key pair for DVN admin address
|
|
260
|
+
pub admin_keypair: Ed25519KeyPair,
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
impl DvnCredentials {
|
|
264
|
+
/// Generate new DVN credentials with the specified number of signers.
|
|
265
|
+
pub fn generate(num_signers: usize) -> Self {
|
|
266
|
+
Self {
|
|
267
|
+
signers: (0..num_signers).map(|_| Secp256k1KeyPair::generate()).collect(),
|
|
268
|
+
admin_keypair: Ed25519KeyPair::generate(),
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/// Get the signer addresses as a Soroban Vec<BytesN<20>>.
|
|
273
|
+
pub fn signer_addresses(&self, env: &Env) -> Vec<BytesN<20>> {
|
|
274
|
+
let mut addrs: Vec<BytesN<20>> = vec![env];
|
|
275
|
+
for kp in &self.signers {
|
|
276
|
+
addrs.push_back(kp.signer(env));
|
|
277
|
+
}
|
|
278
|
+
addrs
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/// Get the admin address for DVN registration.
|
|
282
|
+
pub fn admin_address(&self, env: &Env) -> Address {
|
|
283
|
+
self.admin_keypair.address(env)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
pub struct ChainSetup<'a> {
|
|
288
|
+
pub eid: u32,
|
|
289
|
+
pub owner: Address,
|
|
290
|
+
pub admin: Address, // Worker admin
|
|
291
|
+
pub native_token: Address,
|
|
292
|
+
pub endpoint: EndpointV2Client<'a>,
|
|
293
|
+
pub uln302: Uln302Client<'a>,
|
|
294
|
+
pub dvn: DVNClient<'a>,
|
|
295
|
+
pub dvn2: DVNClient<'a>, // Second DVN for multi-DVN tests
|
|
296
|
+
pub executor: ExecutorClient<'a>,
|
|
297
|
+
pub executor_helper: ExecutorHelperClient<'a>,
|
|
298
|
+
pub price_feed: Address,
|
|
299
|
+
pub counter: CounterClient<'a>,
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
impl<'a> ChainSetupCommon<'a> for ChainSetup<'a> {
|
|
303
|
+
fn counter(&self) -> &CounterClient<'a> {
|
|
304
|
+
&self.counter
|
|
305
|
+
}
|
|
306
|
+
fn endpoint(&self) -> &EndpointV2Client<'a> {
|
|
307
|
+
&self.endpoint
|
|
308
|
+
}
|
|
309
|
+
fn native_token(&self) -> &Address {
|
|
310
|
+
&self.native_token
|
|
311
|
+
}
|
|
312
|
+
fn owner(&self) -> &Address {
|
|
313
|
+
&self.owner
|
|
314
|
+
}
|
|
315
|
+
fn validate_packet(
|
|
316
|
+
&self,
|
|
317
|
+
env: &Env,
|
|
318
|
+
packet_event: &(soroban_sdk::Bytes, soroban_sdk::Bytes, Address),
|
|
319
|
+
) -> endpoint_v2::OutboundPacket {
|
|
320
|
+
use message_lib_common::packet_codec_v1;
|
|
321
|
+
|
|
322
|
+
let packet = decode_packet(env, &packet_event.0);
|
|
323
|
+
let encoded_header = packet_codec_v1::encode_packet_header(env, &packet);
|
|
324
|
+
let payload_hash = packet_codec_v1::payload_hash(env, &packet);
|
|
325
|
+
|
|
326
|
+
// DVN verify with mock_auths
|
|
327
|
+
let receive_uln302 = ReceiveUln302Client::new(env, &self.uln302.address);
|
|
328
|
+
|
|
329
|
+
env.mock_auths(&[soroban_sdk::testutils::MockAuth {
|
|
330
|
+
address: &self.dvn.address,
|
|
331
|
+
invoke: &soroban_sdk::testutils::MockAuthInvoke {
|
|
332
|
+
contract: &self.uln302.address,
|
|
333
|
+
fn_name: "verify",
|
|
334
|
+
args: (&self.dvn.address, &encoded_header, &payload_hash, &CONFIRMATIONS).into_val(env),
|
|
335
|
+
sub_invokes: &[],
|
|
336
|
+
},
|
|
337
|
+
}]);
|
|
338
|
+
receive_uln302.verify(&self.dvn.address, &encoded_header, &payload_hash, &CONFIRMATIONS);
|
|
339
|
+
|
|
340
|
+
// Commit verification (permissionless)
|
|
341
|
+
receive_uln302.commit_verification(&encoded_header, &payload_hash);
|
|
342
|
+
|
|
343
|
+
packet
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
pub struct TestSetup<'a> {
|
|
348
|
+
pub env: Env,
|
|
349
|
+
pub chain_a: ChainSetup<'a>,
|
|
350
|
+
pub chain_b: ChainSetup<'a>,
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/// Intermediate structure to hold chain infrastructure before DVN/Executor creation
|
|
354
|
+
struct ChainInfra {
|
|
355
|
+
endpoint_address: Address,
|
|
356
|
+
uln302_address: Address,
|
|
357
|
+
#[allow(dead_code)]
|
|
358
|
+
treasury_address: Address,
|
|
359
|
+
price_feed_address: Address,
|
|
360
|
+
dvn_fee_lib_address: Address,
|
|
361
|
+
executor_fee_lib_address: Address,
|
|
362
|
+
zro_token: Address,
|
|
363
|
+
admin: Address,
|
|
364
|
+
deposit_address: Address,
|
|
365
|
+
/// DVN credentials (addresses for initialization)
|
|
366
|
+
dvn_credentials: DvnCredentials,
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/// Phase 1: Create basic chain infrastructure (Endpoint, ULN302, Treasury, etc.)
|
|
370
|
+
fn setup_chain_infrastructure(env: &Env, owner: &Address) -> ChainInfra {
|
|
371
|
+
// Create ZRO token
|
|
372
|
+
let zro_sac = env.register_stellar_asset_contract_v2(owner.clone());
|
|
373
|
+
let zro_token = zro_sac.address();
|
|
374
|
+
|
|
375
|
+
// Register endpoint
|
|
376
|
+
let endpoint_address = env.register(EndpointV2, (owner,));
|
|
377
|
+
|
|
378
|
+
// Register Treasury (real)
|
|
379
|
+
let treasury_address = env.register(Treasury, (owner,));
|
|
380
|
+
|
|
381
|
+
// Register PriceFeed (real)
|
|
382
|
+
let price_updater = Address::generate(env);
|
|
383
|
+
let price_feed_address = env.register(LzPriceFeed, (owner, &price_updater));
|
|
384
|
+
|
|
385
|
+
// Register fee libs
|
|
386
|
+
let dvn_fee_lib_address = env.register(DvnFeeLib, (owner,));
|
|
387
|
+
let executor_fee_lib_address = env.register(ExecutorFeeLib, (owner,));
|
|
388
|
+
|
|
389
|
+
// Register ULN302
|
|
390
|
+
let uln302_address = env.register(Uln302, (owner, &endpoint_address, &treasury_address));
|
|
391
|
+
|
|
392
|
+
// Create admin for workers
|
|
393
|
+
let admin = Address::generate(env);
|
|
394
|
+
|
|
395
|
+
// Deposit address for fee collection
|
|
396
|
+
let deposit_address = Address::generate(env);
|
|
397
|
+
|
|
398
|
+
// Generate real DVN credentials (1 signer with threshold 1)
|
|
399
|
+
let dvn_credentials = DvnCredentials::generate(1);
|
|
400
|
+
|
|
401
|
+
ChainInfra {
|
|
402
|
+
endpoint_address,
|
|
403
|
+
uln302_address,
|
|
404
|
+
treasury_address: treasury_address.clone(),
|
|
405
|
+
price_feed_address,
|
|
406
|
+
dvn_fee_lib_address,
|
|
407
|
+
executor_fee_lib_address,
|
|
408
|
+
zro_token,
|
|
409
|
+
admin,
|
|
410
|
+
deposit_address,
|
|
411
|
+
dvn_credentials,
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/// Phase 2: Create DVN, Executor, and ExecutorHelper with cross-chain ULN302 support
|
|
416
|
+
fn setup_chain_workers<'a>(
|
|
417
|
+
env: &Env,
|
|
418
|
+
owner: &Address,
|
|
419
|
+
infra: &ChainInfra,
|
|
420
|
+
all_uln302_addresses: &Vec<Address>, // All ULN302 addresses across chains
|
|
421
|
+
) -> (DVNClient<'a>, DVNClient<'a>, ExecutorClient<'a>, ExecutorHelperClient<'a>) {
|
|
422
|
+
// Use the DVN admin address from credentials, plus the worker admin
|
|
423
|
+
let admins = vec![env, infra.admin.clone(), infra.dvn_credentials.admin_address(env)];
|
|
424
|
+
|
|
425
|
+
// Use real secp256k1 signers from credentials
|
|
426
|
+
let signers = infra.dvn_credentials.signer_addresses(env);
|
|
427
|
+
let threshold: u32 = infra.dvn_credentials.signers.len() as u32;
|
|
428
|
+
|
|
429
|
+
// Register first DVN with ALL ULN302 addresses as supported message libs
|
|
430
|
+
let dvn_address = env.register(
|
|
431
|
+
LzDVN,
|
|
432
|
+
(
|
|
433
|
+
DVN_VID, // vid
|
|
434
|
+
&signers, // signers (real secp256k1 addresses)
|
|
435
|
+
threshold, // threshold
|
|
436
|
+
&admins, // admins
|
|
437
|
+
all_uln302_addresses, // supported_msglibs - ALL chains' ULN302s
|
|
438
|
+
&infra.price_feed_address, // price_feed
|
|
439
|
+
DEFAULT_MULTIPLIER_BPS, // default_multiplier_bps
|
|
440
|
+
&infra.dvn_fee_lib_address, // worker_fee_lib
|
|
441
|
+
&infra.deposit_address, // deposit_address
|
|
442
|
+
),
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
// Register second DVN for multi-DVN verification tests
|
|
446
|
+
let dvn2_credentials = DvnCredentials::generate(1);
|
|
447
|
+
let admins2 = vec![env, infra.admin.clone(), dvn2_credentials.admin_address(env)];
|
|
448
|
+
let signers2 = dvn2_credentials.signer_addresses(env);
|
|
449
|
+
let dvn2_address = env.register(
|
|
450
|
+
LzDVN,
|
|
451
|
+
(
|
|
452
|
+
DVN_VID + 1, // Different vid for second DVN
|
|
453
|
+
&signers2,
|
|
454
|
+
1u32, // threshold
|
|
455
|
+
&admins2,
|
|
456
|
+
all_uln302_addresses,
|
|
457
|
+
&infra.price_feed_address,
|
|
458
|
+
DEFAULT_MULTIPLIER_BPS,
|
|
459
|
+
&infra.dvn_fee_lib_address,
|
|
460
|
+
&infra.deposit_address,
|
|
461
|
+
),
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
// Register ExecutorHelper (stateless entry point for executor AA workflow)
|
|
465
|
+
let executor_helper_address = env.register(ExecutorHelper, ());
|
|
466
|
+
|
|
467
|
+
// Register real Executor with ALL ULN302 addresses as supported message libs
|
|
468
|
+
let executor_address = env.register(
|
|
469
|
+
LzExecutor,
|
|
470
|
+
(
|
|
471
|
+
&infra.endpoint_address,
|
|
472
|
+
owner,
|
|
473
|
+
&admins,
|
|
474
|
+
all_uln302_addresses, // supported_msglibs - ALL chains' ULN302s
|
|
475
|
+
&infra.price_feed_address,
|
|
476
|
+
DEFAULT_MULTIPLIER_BPS,
|
|
477
|
+
&infra.executor_fee_lib_address, // worker_fee_lib
|
|
478
|
+
&infra.deposit_address, // deposit_address
|
|
479
|
+
),
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
let dvn = DVNClient::new(env, &dvn_address);
|
|
483
|
+
let dvn2 = DVNClient::new(env, &dvn2_address);
|
|
484
|
+
let executor = ExecutorClient::new(env, &executor_address);
|
|
485
|
+
let executor_helper = ExecutorHelperClient::new(env, &executor_helper_address);
|
|
486
|
+
|
|
487
|
+
(dvn, dvn2, executor, executor_helper)
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/// Phase 3: Complete chain setup by creating Counter and finalizing configuration
|
|
491
|
+
fn finalize_chain_setup<'a>(
|
|
492
|
+
env: &Env,
|
|
493
|
+
owner: &Address,
|
|
494
|
+
infra: ChainInfra,
|
|
495
|
+
dvn: DVNClient<'a>,
|
|
496
|
+
dvn2: DVNClient<'a>,
|
|
497
|
+
executor: ExecutorClient<'a>,
|
|
498
|
+
executor_helper: ExecutorHelperClient<'a>,
|
|
499
|
+
) -> ChainSetup<'a> {
|
|
500
|
+
// Register Counter OApp
|
|
501
|
+
let counter_address = env.register(Counter, (owner, &infra.endpoint_address, owner));
|
|
502
|
+
|
|
503
|
+
// Create clients
|
|
504
|
+
let endpoint = EndpointV2Client::new(env, &infra.endpoint_address);
|
|
505
|
+
|
|
506
|
+
let native_token = endpoint.native_token();
|
|
507
|
+
|
|
508
|
+
let uln302 = Uln302Client::new(env, &infra.uln302_address);
|
|
509
|
+
let counter = CounterClient::new(env, &counter_address);
|
|
510
|
+
|
|
511
|
+
set_zro(env, owner, &endpoint, &infra.zro_token);
|
|
512
|
+
register_library(env, owner, &endpoint, &uln302.address);
|
|
513
|
+
|
|
514
|
+
let eid = endpoint.eid();
|
|
515
|
+
|
|
516
|
+
// Set up price feed with initial prices for this chain's eid
|
|
517
|
+
setup_price_feed(env, owner, &infra.price_feed_address, eid);
|
|
518
|
+
|
|
519
|
+
let chain_setup = ChainSetup {
|
|
520
|
+
owner: owner.clone(),
|
|
521
|
+
admin: infra.admin,
|
|
522
|
+
endpoint,
|
|
523
|
+
uln302,
|
|
524
|
+
dvn,
|
|
525
|
+
dvn2,
|
|
526
|
+
executor,
|
|
527
|
+
executor_helper,
|
|
528
|
+
price_feed: infra.price_feed_address,
|
|
529
|
+
counter,
|
|
530
|
+
eid,
|
|
531
|
+
native_token,
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
// Allow executor self-spend so transfer_from succeeds in compose tests.
|
|
535
|
+
env.mock_all_auths();
|
|
536
|
+
TokenClient::new(env, &chain_setup.native_token).approve(
|
|
537
|
+
&chain_setup.executor.address,
|
|
538
|
+
&chain_setup.executor.address,
|
|
539
|
+
&i128::MAX,
|
|
540
|
+
&10_u32,
|
|
541
|
+
);
|
|
542
|
+
|
|
543
|
+
chain_setup
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/// Set up price feed with test prices
|
|
547
|
+
fn setup_price_feed(env: &Env, owner: &Address, price_feed: &Address, eid: u32) {
|
|
548
|
+
let client = price_feed::LzPriceFeedClient::new(env, price_feed);
|
|
549
|
+
|
|
550
|
+
// Set price ratio denominator
|
|
551
|
+
env.mock_auths(&[MockAuth {
|
|
552
|
+
address: owner,
|
|
553
|
+
invoke: &MockAuthInvoke {
|
|
554
|
+
contract: price_feed,
|
|
555
|
+
fn_name: "set_price_ratio_denominator",
|
|
556
|
+
args: (&PRICE_RATIO_DENOMINATOR,).into_val(env),
|
|
557
|
+
sub_invokes: &[],
|
|
558
|
+
},
|
|
559
|
+
}]);
|
|
560
|
+
client.set_price_ratio_denominator(&PRICE_RATIO_DENOMINATOR);
|
|
561
|
+
|
|
562
|
+
// Set native token price in USD (1 XLM = 1 USD for simplicity, scaled)
|
|
563
|
+
let native_price_usd: u128 = 10_000_000; // 1 USD with 7 decimals
|
|
564
|
+
env.mock_auths(&[MockAuth {
|
|
565
|
+
address: owner,
|
|
566
|
+
invoke: &MockAuthInvoke {
|
|
567
|
+
contract: price_feed,
|
|
568
|
+
fn_name: "set_native_token_price_usd",
|
|
569
|
+
args: (owner, &native_price_usd).into_val(env),
|
|
570
|
+
sub_invokes: &[],
|
|
571
|
+
},
|
|
572
|
+
}]);
|
|
573
|
+
client.set_native_token_price_usd(owner, &native_price_usd);
|
|
574
|
+
|
|
575
|
+
// Set price for this eid (for testing, use 1:1 price ratio)
|
|
576
|
+
// Price feed internally uses eid % 30000 for lookups, so we need to normalize
|
|
577
|
+
let normalized_eid = eid % 30_000;
|
|
578
|
+
let price = Price {
|
|
579
|
+
price_ratio: PRICE_RATIO_DENOMINATOR,
|
|
580
|
+
gas_price_in_unit: DEFAULT_GAS_PRICE,
|
|
581
|
+
gas_per_byte: DEFAULT_GAS_PER_BYTE,
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
// Note: STELLAR_EID (30111) normalizes to 111, which is the Optimism mainnet EID.
|
|
585
|
+
// The Optimism fee model requires prices for BOTH L2 (111) AND L1 Ethereum (101).
|
|
586
|
+
// So we set prices for both.
|
|
587
|
+
let mut prices = vec![env, UpdatePrice { eid: normalized_eid, price: price.clone() }];
|
|
588
|
+
|
|
589
|
+
// If this is an Optimism-style chain (111, 10132, 20132), also set L1 Ethereum price
|
|
590
|
+
if normalized_eid == 111 {
|
|
591
|
+
prices.push_back(UpdatePrice { eid: 101, price: price.clone() }); // Ethereum mainnet
|
|
592
|
+
} else if normalized_eid == 10132 {
|
|
593
|
+
prices.push_back(UpdatePrice { eid: 10121, price: price.clone() }); // Ethereum Goerli
|
|
594
|
+
} else if normalized_eid == 20132 {
|
|
595
|
+
prices.push_back(UpdatePrice { eid: 20121, price: price.clone() }); // Ethereum Goerli
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
env.mock_auths(&[MockAuth {
|
|
599
|
+
address: owner,
|
|
600
|
+
invoke: &MockAuthInvoke {
|
|
601
|
+
contract: price_feed,
|
|
602
|
+
fn_name: "set_price",
|
|
603
|
+
args: (owner, &prices).into_val(env),
|
|
604
|
+
sub_invokes: &[],
|
|
605
|
+
},
|
|
606
|
+
}]);
|
|
607
|
+
client.set_price(owner, &prices);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
pub fn setup<'a>() -> TestSetup<'a> {
|
|
611
|
+
let env = Env::default();
|
|
612
|
+
env.mock_all_auths(); // Required for contract registration (DVN multisig init, etc.)
|
|
613
|
+
let owner = Address::generate(&env);
|
|
614
|
+
|
|
615
|
+
// Phase 1: Create basic infrastructure for both chains
|
|
616
|
+
let infra_a = setup_chain_infrastructure(&env, &owner);
|
|
617
|
+
let infra_b = setup_chain_infrastructure(&env, &owner);
|
|
618
|
+
|
|
619
|
+
// Collect all ULN302 addresses for cross-chain support
|
|
620
|
+
let all_uln302_addresses: Vec<Address> = vec![&env, infra_a.uln302_address.clone(), infra_b.uln302_address.clone()];
|
|
621
|
+
|
|
622
|
+
// Phase 2: Create workers with cross-chain ULN302 support
|
|
623
|
+
let (dvn_a, dvn2_a, executor_a, executor_helper_a) =
|
|
624
|
+
setup_chain_workers(&env, &owner, &infra_a, &all_uln302_addresses);
|
|
625
|
+
let (dvn_b, dvn2_b, executor_b, executor_helper_b) =
|
|
626
|
+
setup_chain_workers(&env, &owner, &infra_b, &all_uln302_addresses);
|
|
627
|
+
|
|
628
|
+
// Phase 3: Finalize chain setup
|
|
629
|
+
let chain_a = finalize_chain_setup(&env, &owner, infra_a, dvn_a, dvn2_a, executor_a, executor_helper_a);
|
|
630
|
+
let chain_b = finalize_chain_setup(&env, &owner, infra_b, dvn_b, dvn2_b, executor_b, executor_helper_b);
|
|
631
|
+
|
|
632
|
+
TestSetup { env, chain_a, chain_b }
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/// DVN configuration mode for endpoint wiring.
|
|
636
|
+
#[derive(Clone, Copy)]
|
|
637
|
+
pub enum DvnMode {
|
|
638
|
+
/// Single DVN: required = [dvn], no optional
|
|
639
|
+
Single,
|
|
640
|
+
/// Two required DVNs: required = [dvn, dvn2], no optional
|
|
641
|
+
TwoRequired,
|
|
642
|
+
/// Duplicate DVN in optional: required = [dvn], optional = [dvn, dvn2], threshold = 1
|
|
643
|
+
DuplicateOptional,
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/// Creates a fully wired test setup with the specified DVN mode.
|
|
647
|
+
pub fn wired_setup_with_dvn_mode<'a>(mode: DvnMode) -> TestSetup<'a> {
|
|
648
|
+
let test_setup = setup();
|
|
649
|
+
wire_endpoint(&test_setup.env, &[&test_setup.chain_a, &test_setup.chain_b], mode);
|
|
650
|
+
wire_counter(&test_setup.env, &[&test_setup.chain_a, &test_setup.chain_b]);
|
|
651
|
+
test_setup
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// ============================================================================
|
|
655
|
+
// Wire functions
|
|
656
|
+
// ============================================================================
|
|
657
|
+
|
|
658
|
+
pub fn wire_endpoint(env: &Env, chains: &[&ChainSetup<'_>], mode: DvnMode) {
|
|
659
|
+
// First pass: Set up price feeds with cross-chain prices
|
|
660
|
+
for chain in chains {
|
|
661
|
+
for other_chain in chains {
|
|
662
|
+
if chain.endpoint.address == other_chain.endpoint.address {
|
|
663
|
+
continue;
|
|
664
|
+
}
|
|
665
|
+
setup_price_feed(env, &chain.owner, &chain.price_feed, other_chain.eid);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// Second pass: Set up DVN and Executor dst configs
|
|
670
|
+
for chain in chains {
|
|
671
|
+
for other_chain in chains {
|
|
672
|
+
if chain.endpoint.address == other_chain.endpoint.address {
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
set_dvn_dst_config(env, &chain.admin, &chain.dvn, other_chain.eid);
|
|
676
|
+
// For multi-DVN modes, also configure dvn2
|
|
677
|
+
if matches!(mode, DvnMode::TwoRequired | DvnMode::DuplicateOptional) {
|
|
678
|
+
set_dvn_dst_config(env, &chain.admin, &chain.dvn2, other_chain.eid);
|
|
679
|
+
}
|
|
680
|
+
set_executor_dst_config(env, &chain.admin, &chain.executor, other_chain.eid);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Third pass: Set up ULN configs based on DVN mode
|
|
685
|
+
for chain in chains {
|
|
686
|
+
for other_chain in chains {
|
|
687
|
+
if chain.endpoint.address == other_chain.endpoint.address {
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
let (send_required, recv_required, send_optional, recv_optional, optional_threshold) = match mode {
|
|
692
|
+
DvnMode::Single => (
|
|
693
|
+
vec![env, other_chain.dvn.address.clone()],
|
|
694
|
+
vec![env, chain.dvn.address.clone()],
|
|
695
|
+
vec![env],
|
|
696
|
+
vec![env],
|
|
697
|
+
0,
|
|
698
|
+
),
|
|
699
|
+
DvnMode::TwoRequired => (
|
|
700
|
+
vec![env, other_chain.dvn.address.clone(), other_chain.dvn2.address.clone()],
|
|
701
|
+
vec![env, chain.dvn.address.clone(), chain.dvn2.address.clone()],
|
|
702
|
+
vec![env],
|
|
703
|
+
vec![env],
|
|
704
|
+
0,
|
|
705
|
+
),
|
|
706
|
+
DvnMode::DuplicateOptional => (
|
|
707
|
+
vec![env, other_chain.dvn.address.clone()],
|
|
708
|
+
vec![env, chain.dvn.address.clone()],
|
|
709
|
+
vec![env, other_chain.dvn.address.clone(), other_chain.dvn2.address.clone()],
|
|
710
|
+
vec![env, chain.dvn.address.clone(), chain.dvn2.address.clone()],
|
|
711
|
+
1,
|
|
712
|
+
),
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
set_default_send_uln_config_with_optional(
|
|
716
|
+
env,
|
|
717
|
+
&chain.owner,
|
|
718
|
+
&chain.uln302,
|
|
719
|
+
other_chain.eid,
|
|
720
|
+
&send_required,
|
|
721
|
+
&send_optional,
|
|
722
|
+
optional_threshold,
|
|
723
|
+
);
|
|
724
|
+
|
|
725
|
+
set_default_receive_uln_config_with_optional(
|
|
726
|
+
env,
|
|
727
|
+
&chain.owner,
|
|
728
|
+
&chain.uln302,
|
|
729
|
+
other_chain.eid,
|
|
730
|
+
&recv_required,
|
|
731
|
+
&recv_optional,
|
|
732
|
+
optional_threshold,
|
|
733
|
+
);
|
|
734
|
+
|
|
735
|
+
set_default_executor_config(env, &chain.owner, &chain.uln302, other_chain.eid, &chain.executor.address);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// Fourth pass: Set default send and receive libraries
|
|
740
|
+
for chain in chains {
|
|
741
|
+
for other_chain in chains {
|
|
742
|
+
if chain.endpoint.address == other_chain.endpoint.address {
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
set_default_send_library(env, &chain.owner, &chain.endpoint, other_chain.eid, &chain.uln302.address);
|
|
747
|
+
set_default_receive_library(env, &chain.owner, &chain.endpoint, other_chain.eid, &chain.uln302.address);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/// Set DVN destination config
|
|
753
|
+
fn set_dvn_dst_config(env: &Env, admin: &Address, dvn: &DVNClient<'_>, dst_eid: u32) {
|
|
754
|
+
let config = DvnDstConfig {
|
|
755
|
+
gas: 100_000, // Gas for verification
|
|
756
|
+
multiplier_bps: 10000, // 100%
|
|
757
|
+
floor_margin_usd: 0, // No floor margin for tests
|
|
758
|
+
};
|
|
759
|
+
let params = vec![env, DvnDstConfigParam { dst_eid, config }];
|
|
760
|
+
|
|
761
|
+
env.mock_auths(&[MockAuth {
|
|
762
|
+
address: admin,
|
|
763
|
+
invoke: &MockAuthInvoke {
|
|
764
|
+
contract: &dvn.address,
|
|
765
|
+
fn_name: "set_dst_config",
|
|
766
|
+
args: (admin, ¶ms).into_val(env),
|
|
767
|
+
sub_invokes: &[],
|
|
768
|
+
},
|
|
769
|
+
}]);
|
|
770
|
+
dvn.set_dst_config(admin, ¶ms);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/// Set Executor destination config
|
|
774
|
+
fn set_executor_dst_config(env: &Env, admin: &Address, executor: &ExecutorClient<'_>, dst_eid: u32) {
|
|
775
|
+
let config = ExecutorDstConfig {
|
|
776
|
+
lz_receive_base_gas: 50_000, // Base gas for lz_receive
|
|
777
|
+
multiplier_bps: 10000, // 100%
|
|
778
|
+
floor_margin_usd: 0, // No floor margin for tests
|
|
779
|
+
native_cap: 1_000_000_000, // Max native drop
|
|
780
|
+
lz_compose_base_gas: 30_000, // Base gas for lz_compose
|
|
781
|
+
};
|
|
782
|
+
let params = vec![env, SetDstConfigParam { dst_eid, dst_config: config }];
|
|
783
|
+
|
|
784
|
+
env.mock_auths(&[MockAuth {
|
|
785
|
+
address: admin,
|
|
786
|
+
invoke: &MockAuthInvoke {
|
|
787
|
+
contract: &executor.address,
|
|
788
|
+
fn_name: "set_dst_config",
|
|
789
|
+
args: (admin, ¶ms).into_val(env),
|
|
790
|
+
sub_invokes: &[],
|
|
791
|
+
},
|
|
792
|
+
}]);
|
|
793
|
+
executor.set_dst_config(admin, ¶ms);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
pub fn wire_counter(env: &Env, chains: &[&ChainSetup<'_>]) {
|
|
797
|
+
for chain in chains {
|
|
798
|
+
for other_chain in chains {
|
|
799
|
+
if chain.endpoint.address == other_chain.endpoint.address {
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
set_peer(
|
|
803
|
+
env,
|
|
804
|
+
&chain.owner,
|
|
805
|
+
&chain.counter,
|
|
806
|
+
other_chain.eid,
|
|
807
|
+
&address_to_bytes32(&other_chain.counter.address),
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
pub fn set_default_send_library(
|
|
814
|
+
env: &Env,
|
|
815
|
+
owner: &Address,
|
|
816
|
+
endpoint: &EndpointV2Client<'_>,
|
|
817
|
+
dst_eid: u32,
|
|
818
|
+
lib: &Address,
|
|
819
|
+
) {
|
|
820
|
+
env.mock_auths(&[MockAuth {
|
|
821
|
+
address: owner,
|
|
822
|
+
invoke: &MockAuthInvoke {
|
|
823
|
+
contract: &endpoint.address,
|
|
824
|
+
fn_name: "set_default_send_library",
|
|
825
|
+
args: (&dst_eid, lib).into_val(env),
|
|
826
|
+
sub_invokes: &[],
|
|
827
|
+
},
|
|
828
|
+
}]);
|
|
829
|
+
endpoint.set_default_send_library(&dst_eid, lib);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
pub fn set_default_receive_library(
|
|
833
|
+
env: &Env,
|
|
834
|
+
owner: &Address,
|
|
835
|
+
endpoint: &EndpointV2Client<'_>,
|
|
836
|
+
src_eid: u32,
|
|
837
|
+
lib: &Address,
|
|
838
|
+
) {
|
|
839
|
+
env.mock_auths(&[MockAuth {
|
|
840
|
+
address: owner,
|
|
841
|
+
invoke: &MockAuthInvoke {
|
|
842
|
+
contract: &endpoint.address,
|
|
843
|
+
fn_name: "set_default_receive_library",
|
|
844
|
+
args: (&src_eid, lib, &0u64).into_val(env),
|
|
845
|
+
sub_invokes: &[],
|
|
846
|
+
},
|
|
847
|
+
}]);
|
|
848
|
+
endpoint.set_default_receive_library(&src_eid, lib, &0u64);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
pub fn set_default_send_uln_config_with_optional(
|
|
852
|
+
env: &Env,
|
|
853
|
+
owner: &Address,
|
|
854
|
+
uln302: &Uln302Client<'_>,
|
|
855
|
+
dst_eid: u32,
|
|
856
|
+
required_dvns: &soroban_sdk::Vec<Address>,
|
|
857
|
+
optional_dvns: &soroban_sdk::Vec<Address>,
|
|
858
|
+
optional_dvn_threshold: u32,
|
|
859
|
+
) {
|
|
860
|
+
let config = UlnConfig {
|
|
861
|
+
confirmations: CONFIRMATIONS,
|
|
862
|
+
required_dvns: required_dvns.clone(),
|
|
863
|
+
optional_dvns: optional_dvns.clone(),
|
|
864
|
+
optional_dvn_threshold,
|
|
865
|
+
};
|
|
866
|
+
let params = vec![env, SetDefaultUlnConfigParam { eid: dst_eid, config }];
|
|
867
|
+
|
|
868
|
+
env.mock_auths(&[MockAuth {
|
|
869
|
+
address: owner,
|
|
870
|
+
invoke: &MockAuthInvoke {
|
|
871
|
+
contract: &uln302.address,
|
|
872
|
+
fn_name: "set_default_send_uln_configs",
|
|
873
|
+
args: (¶ms,).into_val(env),
|
|
874
|
+
sub_invokes: &[],
|
|
875
|
+
},
|
|
876
|
+
}]);
|
|
877
|
+
SendUln302Client::new(env, &uln302.address).set_default_send_uln_configs(¶ms);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
pub fn set_default_receive_uln_config_with_optional(
|
|
881
|
+
env: &Env,
|
|
882
|
+
owner: &Address,
|
|
883
|
+
uln302: &Uln302Client<'_>,
|
|
884
|
+
src_eid: u32,
|
|
885
|
+
required_dvns: &soroban_sdk::Vec<Address>,
|
|
886
|
+
optional_dvns: &soroban_sdk::Vec<Address>,
|
|
887
|
+
optional_dvn_threshold: u32,
|
|
888
|
+
) {
|
|
889
|
+
let config = UlnConfig {
|
|
890
|
+
confirmations: CONFIRMATIONS,
|
|
891
|
+
required_dvns: required_dvns.clone(),
|
|
892
|
+
optional_dvns: optional_dvns.clone(),
|
|
893
|
+
optional_dvn_threshold,
|
|
894
|
+
};
|
|
895
|
+
let params = vec![env, SetDefaultUlnConfigParam { eid: src_eid, config }];
|
|
896
|
+
|
|
897
|
+
env.mock_auths(&[MockAuth {
|
|
898
|
+
address: owner,
|
|
899
|
+
invoke: &MockAuthInvoke {
|
|
900
|
+
contract: &uln302.address,
|
|
901
|
+
fn_name: "set_default_receive_uln_configs",
|
|
902
|
+
args: (¶ms,).into_val(env),
|
|
903
|
+
sub_invokes: &[],
|
|
904
|
+
},
|
|
905
|
+
}]);
|
|
906
|
+
ReceiveUln302Client::new(env, &uln302.address).set_default_receive_uln_configs(¶ms);
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
pub fn set_default_executor_config(
|
|
910
|
+
env: &Env,
|
|
911
|
+
owner: &Address,
|
|
912
|
+
uln302: &Uln302Client<'_>,
|
|
913
|
+
dst_eid: u32,
|
|
914
|
+
executor: &Address,
|
|
915
|
+
) {
|
|
916
|
+
let config = ExecutorConfig { max_message_size: MAX_MESSAGE_SIZE, executor: executor.clone() };
|
|
917
|
+
let params = vec![env, SetDefaultExecutorConfigParam { dst_eid, config }];
|
|
918
|
+
|
|
919
|
+
env.mock_auths(&[MockAuth {
|
|
920
|
+
address: owner,
|
|
921
|
+
invoke: &MockAuthInvoke {
|
|
922
|
+
contract: &uln302.address,
|
|
923
|
+
fn_name: "set_default_executor_configs",
|
|
924
|
+
args: (¶ms,).into_val(env),
|
|
925
|
+
sub_invokes: &[],
|
|
926
|
+
},
|
|
927
|
+
}]);
|
|
928
|
+
SendUln302Client::new(env, &uln302.address).set_default_executor_configs(¶ms);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// ============================================================================
|
|
932
|
+
// Executor Helper Functions
|
|
933
|
+
// ============================================================================
|
|
934
|
+
|
|
935
|
+
use crate::tests::mint_to;
|
|
936
|
+
use endpoint_v2::{Origin, OutboundPacket};
|
|
937
|
+
use executor_helper::{ComposeParams, ExecutionParams};
|
|
938
|
+
use soroban_sdk::Bytes;
|
|
939
|
+
|
|
940
|
+
/// Execute lz_receive via ExecutorHelper (executor AA workflow).
|
|
941
|
+
/// Automatically mints native tokens to the admin if value > 0.
|
|
942
|
+
pub fn lz_receive_via_executor(
|
|
943
|
+
env: &Env,
|
|
944
|
+
chain: &ChainSetup<'_>,
|
|
945
|
+
admin: &Address,
|
|
946
|
+
packet: &OutboundPacket,
|
|
947
|
+
value: i128,
|
|
948
|
+
) {
|
|
949
|
+
// Mint native tokens to admin if value > 0
|
|
950
|
+
if value > 0 {
|
|
951
|
+
mint_to(env, &chain.owner, &chain.native_token, admin, value);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
let origin = Origin { src_eid: packet.src_eid, sender: address_to_bytes32(&packet.sender), nonce: packet.nonce };
|
|
955
|
+
|
|
956
|
+
let params = ExecutionParams {
|
|
957
|
+
receiver: chain.counter.address.clone(),
|
|
958
|
+
origin: origin.clone(),
|
|
959
|
+
guid: packet.guid.clone(),
|
|
960
|
+
message: packet.message.clone(),
|
|
961
|
+
extra_data: Bytes::new(env),
|
|
962
|
+
value,
|
|
963
|
+
gas_limit: 1_000_000, // Arbitrary gas limit for tests
|
|
964
|
+
};
|
|
965
|
+
|
|
966
|
+
env.mock_all_auths_allowing_non_root_auth();
|
|
967
|
+
chain.executor_helper.execute(&chain.executor.address, ¶ms, admin);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/// Execute lz_compose via ExecutorHelper (executor AA workflow).
|
|
971
|
+
/// Automatically mints native tokens to the admin if value > 0.
|
|
972
|
+
pub fn lz_compose_via_executor(
|
|
973
|
+
env: &Env,
|
|
974
|
+
chain: &ChainSetup<'_>,
|
|
975
|
+
admin: &Address,
|
|
976
|
+
packet: &OutboundPacket,
|
|
977
|
+
value: i128,
|
|
978
|
+
) {
|
|
979
|
+
// Mint native tokens to admin if value > 0
|
|
980
|
+
if value > 0 {
|
|
981
|
+
mint_to(env, &chain.owner, &chain.native_token, admin, value);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
let params = ComposeParams {
|
|
985
|
+
from: chain.counter.address.clone(),
|
|
986
|
+
to: chain.counter.address.clone(),
|
|
987
|
+
guid: packet.guid.clone(),
|
|
988
|
+
index: 0,
|
|
989
|
+
message: packet.message.clone(),
|
|
990
|
+
extra_data: Bytes::new(env),
|
|
991
|
+
value,
|
|
992
|
+
gas_limit: 1_000_000, // Arbitrary gas limit for tests
|
|
993
|
+
};
|
|
994
|
+
|
|
995
|
+
env.mock_all_auths_allowing_non_root_auth();
|
|
996
|
+
chain.executor_helper.compose(&chain.executor.address, ¶ms, admin);
|
|
997
|
+
}
|