@layerzerolabs/protocol-stellar-v2 0.2.8
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 +727 -0
- package/.turbo/turbo-lint.log +158 -0
- package/.turbo/turbo-test.log +796 -0
- package/Cargo.lock +2237 -0
- package/Cargo.toml +63 -0
- package/clippy.toml +7 -0
- package/contracts/common-macros/Cargo.toml +20 -0
- package/contracts/common-macros/src/error.rs +53 -0
- package/contracts/common-macros/src/event.rs +16 -0
- package/contracts/common-macros/src/lib.rs +255 -0
- package/contracts/common-macros/src/ownable.rs +63 -0
- package/contracts/common-macros/src/snapshots/common_macros__tests__tests__snapshot_generated_storage_code.snap +310 -0
- package/contracts/common-macros/src/storage.rs +439 -0
- package/contracts/common-macros/src/tests.rs +287 -0
- package/contracts/common-macros/src/ttl_configurable.rs +60 -0
- package/contracts/endpoint-v2/ARCHITECTURE.md +233 -0
- package/contracts/endpoint-v2/Cargo.toml +30 -0
- package/contracts/endpoint-v2/src/constants.rs +52 -0
- package/contracts/endpoint-v2/src/endpoint_v2.rs +305 -0
- package/contracts/endpoint-v2/src/errors.rs +29 -0
- package/contracts/endpoint-v2/src/events.rs +207 -0
- package/contracts/endpoint-v2/src/interfaces/layerzero_composer.rs +26 -0
- package/contracts/endpoint-v2/src/interfaces/layerzero_endpoint_v2.rs +170 -0
- package/contracts/endpoint-v2/src/interfaces/layerzero_receiver.rs +43 -0
- package/contracts/endpoint-v2/src/interfaces/message_lib.rs +62 -0
- package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +220 -0
- package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +121 -0
- package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +63 -0
- package/contracts/endpoint-v2/src/interfaces/mod.rs +17 -0
- package/contracts/endpoint-v2/src/interfaces/send_lib.rs +70 -0
- package/contracts/endpoint-v2/src/lib.rs +22 -0
- package/contracts/endpoint-v2/src/message_lib_manager.rs +315 -0
- package/contracts/endpoint-v2/src/messaging_channel.rs +218 -0
- package/contracts/endpoint-v2/src/messaging_composer.rs +76 -0
- package/contracts/endpoint-v2/src/storage.rs +78 -0
- package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +131 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +237 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/delegate.rs +42 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/initializable.rs +76 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +211 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/mod.rs +18 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/native_token.rs +10 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/owner.rs +10 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +424 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +144 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/recover_token.rs +72 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +29 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +513 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +43 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +27 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/transfer_ownership.rs +30 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +202 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +59 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +172 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/zro.rs +23 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/mod.rs +10 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +131 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +35 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +28 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_config.rs +79 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +246 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +285 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +180 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +405 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +80 -0
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +131 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +358 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/clear.rs +316 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_nonce.rs +288 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +316 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/internal.rs +388 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/lazy_inbound_nonce.rs +307 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +10 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/next_guid.rs +239 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +324 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/outbound_nonce.rs +242 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +232 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +212 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/compose_queue.rs +213 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +269 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/mod.rs +4 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +173 -0
- package/contracts/endpoint-v2/src/tests/mock.rs +132 -0
- package/contracts/endpoint-v2/src/tests/mod.rs +12 -0
- package/contracts/endpoint-v2/src/tests/util/build_payload.rs +126 -0
- package/contracts/endpoint-v2/src/tests/util/compute_guid.rs +82 -0
- package/contracts/endpoint-v2/src/tests/util/keccak256.rs +115 -0
- package/contracts/endpoint-v2/src/tests/util/mod.rs +3 -0
- package/contracts/endpoint-v2/src/util.rs +52 -0
- package/contracts/message-libs/Cargo.toml +12 -0
- package/contracts/message-libs/block-message-lib/Cargo.toml +19 -0
- package/contracts/message-libs/block-message-lib/src/lib.rs +70 -0
- package/contracts/message-libs/lib.rs +2 -0
- package/contracts/message-libs/message-lib-common/Cargo.toml +24 -0
- package/contracts/message-libs/message-lib-common/src/errors.rs +20 -0
- package/contracts/message-libs/message-lib-common/src/interfaces/dvn.rs +55 -0
- package/contracts/message-libs/message-lib-common/src/interfaces/executor.rs +46 -0
- package/contracts/message-libs/message-lib-common/src/interfaces/mod.rs +7 -0
- package/contracts/message-libs/message-lib-common/src/interfaces/treasury.rs +17 -0
- package/contracts/message-libs/message-lib-common/src/lib.rs +14 -0
- package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +99 -0
- package/contracts/message-libs/message-lib-common/src/testing_utils.rs +27 -0
- package/contracts/message-libs/message-lib-common/src/tests/mod.rs +2 -0
- package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +162 -0
- package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +319 -0
- package/contracts/message-libs/message-lib-common/src/worker_options.rs +190 -0
- package/contracts/message-libs/simple-message-lib/Cargo.toml +26 -0
- package/contracts/message-libs/simple-message-lib/src/errors.rs +11 -0
- package/contracts/message-libs/simple-message-lib/src/lib.rs +14 -0
- package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +136 -0
- package/contracts/message-libs/simple-message-lib/src/storage.rs +27 -0
- package/contracts/message-libs/simple-message-lib/src/test.rs +280 -0
- package/contracts/message-libs/treasury/Cargo.toml +27 -0
- package/contracts/message-libs/treasury/src/errors.rs +10 -0
- package/contracts/message-libs/treasury/src/events.rs +28 -0
- package/contracts/message-libs/treasury/src/interfaces/mod.rs +3 -0
- package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +20 -0
- package/contracts/message-libs/treasury/src/lib.rs +20 -0
- package/contracts/message-libs/treasury/src/storage.rs +18 -0
- package/contracts/message-libs/treasury/src/tests/mod.rs +2 -0
- package/contracts/message-libs/treasury/src/tests/setup.rs +112 -0
- package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +562 -0
- package/contracts/message-libs/treasury/src/treasury.rs +140 -0
- package/contracts/message-libs/uln-302/Cargo.toml +28 -0
- package/contracts/message-libs/uln-302/src/config_validation.rs +173 -0
- package/contracts/message-libs/uln-302/src/errors.rs +29 -0
- package/contracts/message-libs/uln-302/src/events.rs +72 -0
- package/contracts/message-libs/uln-302/src/interfaces/mod.rs +5 -0
- package/contracts/message-libs/uln-302/src/interfaces/receive.rs +82 -0
- package/contracts/message-libs/uln-302/src/interfaces/send.rs +159 -0
- package/contracts/message-libs/uln-302/src/lib.rs +20 -0
- package/contracts/message-libs/uln-302/src/receive.rs +199 -0
- package/contracts/message-libs/uln-302/src/send.rs +349 -0
- package/contracts/message-libs/uln-302/src/storage.rs +47 -0
- package/contracts/message-libs/uln-302/src/tests/config/mod.rs +2 -0
- package/contracts/message-libs/uln-302/src/tests/config/oapp_uln_config.rs +291 -0
- package/contracts/message-libs/uln-302/src/tests/config/uln_config.rs +163 -0
- package/contracts/message-libs/uln-302/src/tests/mod.rs +7 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/commit_verification.rs +183 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/confirmations.rs +128 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +104 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/mod.rs +66 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +79 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/verifiable.rs +463 -0
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +173 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +132 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +117 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/mod.rs +6 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/quote.rs +586 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +834 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +95 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +80 -0
- package/contracts/message-libs/uln-302/src/tests/setup.rs +268 -0
- package/contracts/message-libs/uln-302/src/tests/testing_utils.rs +47 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/get_app_receive_uln_config.rs +51 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/get_app_send_uln_config.rs +51 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/get_oapp_executor_config.rs +48 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/mod.rs +4 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +998 -0
- package/contracts/message-libs/uln-302/src/uln302.rs +117 -0
- package/contracts/oapp-macros/Cargo.toml +21 -0
- package/contracts/oapp-macros/src/lib.rs +408 -0
- package/contracts/oapp-macros/src/oapp_core.rs +49 -0
- package/contracts/oapp-macros/src/oapp_full.rs +15 -0
- package/contracts/oapp-macros/src/oapp_options_type3.rs +46 -0
- package/contracts/oapp-macros/src/oapp_receiver.rs +67 -0
- package/contracts/oapp-macros/src/oapp_sender.rs +23 -0
- package/contracts/oapp-macros/src/util.rs +103 -0
- package/contracts/oapp-macros/tests/test_macros.rs +522 -0
- package/contracts/oapps/Cargo.toml +12 -0
- package/contracts/oapps/counter/Cargo.toml +24 -0
- package/contracts/oapps/counter/integration_tests/mod.rs +3 -0
- package/contracts/oapps/counter/integration_tests/setup.rs +201 -0
- package/contracts/oapps/counter/integration_tests/test_with_sml.rs +166 -0
- package/contracts/oapps/counter/integration_tests/utils.rs +144 -0
- package/contracts/oapps/counter/src/codec.rs +63 -0
- package/contracts/oapps/counter/src/counter.rs +235 -0
- package/contracts/oapps/counter/src/errors.rs +9 -0
- package/contracts/oapps/counter/src/lib.rs +16 -0
- package/contracts/oapps/counter/src/options.rs +30 -0
- package/contracts/oapps/counter/src/storage.rs +33 -0
- package/contracts/oapps/counter/src/tests/mod.rs +37 -0
- package/contracts/oapps/counter/src/tests/test_codec.rs +64 -0
- package/contracts/oapps/counter/src/tests/test_counter.rs +390 -0
- package/contracts/oapps/counter/src/u256_ext.rs +21 -0
- package/contracts/oapps/lib.rs +2 -0
- package/contracts/oapps/oapp/Cargo.toml +21 -0
- package/contracts/oapps/oapp/src/errors.rs +9 -0
- package/contracts/oapps/oapp/src/lib.rs +10 -0
- package/contracts/oapps/oapp/src/oapp_core.rs +92 -0
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +89 -0
- package/contracts/oapps/oapp/src/oapp_receiver.rs +72 -0
- package/contracts/oapps/oapp/src/oapp_sender.rs +66 -0
- package/contracts/oapps/oapp/src/tests/mod.rs +4 -0
- package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +162 -0
- package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +180 -0
- package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +157 -0
- package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +283 -0
- package/contracts/utils/Cargo.toml +21 -0
- package/contracts/utils/src/buffer_reader.rs +143 -0
- package/contracts/utils/src/buffer_writer.rs +117 -0
- package/contracts/utils/src/bytes_ext.rs +19 -0
- package/contracts/utils/src/errors.rs +30 -0
- package/contracts/utils/src/lib.rs +15 -0
- package/contracts/utils/src/option_ext.rs +38 -0
- package/contracts/utils/src/ownable.rs +88 -0
- package/contracts/utils/src/testing_utils.rs +100 -0
- package/contracts/utils/src/tests/buffer_reader.rs +1006 -0
- package/contracts/utils/src/tests/buffer_writer.rs +330 -0
- package/contracts/utils/src/tests/bytes_ext.rs +77 -0
- package/contracts/utils/src/tests/mod.rs +4 -0
- package/contracts/utils/src/tests/ownable.rs +149 -0
- package/contracts/utils/src/ttl.rs +164 -0
- package/contracts/workers/Cargo.toml +13 -0
- package/contracts/workers/executor/Cargo.toml +26 -0
- package/contracts/workers/executor/src/events.rs +22 -0
- package/contracts/workers/executor/src/executor.rs +347 -0
- package/contracts/workers/executor/src/interfaces/executor.rs +40 -0
- package/contracts/workers/executor/src/interfaces/mod.rs +5 -0
- package/contracts/workers/executor/src/interfaces/types.rs +51 -0
- package/contracts/workers/executor/src/lib.rs +10 -0
- package/contracts/workers/executor/src/storage.rs +23 -0
- package/contracts/workers/lib.rs +2 -0
- package/contracts/workers/worker-common/Cargo.toml +18 -0
- package/contracts/workers/worker-common/src/constants.rs +17 -0
- package/contracts/workers/worker-common/src/errors.rs +6 -0
- package/contracts/workers/worker-common/src/events.rs +34 -0
- package/contracts/workers/worker-common/src/interfaces/executor_fee_lib.rs +35 -0
- package/contracts/workers/worker-common/src/interfaces/mod.rs +7 -0
- package/contracts/workers/worker-common/src/interfaces/price_feed.rs +40 -0
- package/contracts/workers/worker-common/src/interfaces/worker.rs +60 -0
- package/contracts/workers/worker-common/src/lib.rs +19 -0
- package/contracts/workers/worker-common/src/storage.rs +32 -0
- package/contracts/workers/worker-common/src/worker_common.rs +166 -0
- package/package.json +25 -0
- package/rust-toolchain.toml +4 -0
- package/rustfmt.toml +17 -0
- package/sdk/.turbo/turbo-build.log +4 -0
- package/sdk/dist/generated/bml.d.ts +452 -0
- package/sdk/dist/generated/bml.js +72 -0
- package/sdk/dist/generated/counter.d.ts +824 -0
- package/sdk/dist/generated/counter.js +125 -0
- package/sdk/dist/generated/endpoint.d.ts +1676 -0
- package/sdk/dist/generated/endpoint.js +216 -0
- package/sdk/dist/generated/sml.d.ts +810 -0
- package/sdk/dist/generated/sml.js +132 -0
- package/sdk/dist/generated/uln302.d.ts +1227 -0
- package/sdk/dist/generated/uln302.js +185 -0
- package/sdk/dist/index.d.ts +5 -0
- package/sdk/dist/index.js +5 -0
- package/sdk/node_modules/.bin/tsc +21 -0
- package/sdk/node_modules/.bin/tsserver +21 -0
- package/sdk/node_modules/.bin/vitest +21 -0
- package/sdk/node_modules/.bin/zx +21 -0
- package/sdk/package.json +40 -0
- package/sdk/src/index.ts +5 -0
- package/sdk/test/index.test.ts +271 -0
- package/sdk/test/suites/constants.ts +13 -0
- package/sdk/test/suites/deploy.ts +277 -0
- package/sdk/test/suites/localnet.ts +42 -0
- package/sdk/test/suites/scan.ts +189 -0
- package/sdk/tsconfig.json +106 -0
- package/tools/ts-bindings-gen/Cargo.toml +14 -0
- package/tools/ts-bindings-gen/src/main.rs +147 -0
- package/turbo.json +12 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
use crate::worker_options::{
|
|
2
|
+
convert_legacy_options, split_worker_options, EXECUTOR_OPTION_TYPE_LZRECEIVE, EXECUTOR_OPTION_TYPE_NATIVE_DROP,
|
|
3
|
+
EXECUTOR_WORKER_ID, LEGACY_OPTIONS_TYPE_1, LEGACY_OPTIONS_TYPE_2, OPTIONS_TYPE_3,
|
|
4
|
+
};
|
|
5
|
+
use hex_literal::hex;
|
|
6
|
+
use soroban_sdk::{Bytes, BytesN, Env};
|
|
7
|
+
use utils::buffer_reader::BufferReader;
|
|
8
|
+
|
|
9
|
+
#[test]
|
|
10
|
+
fn test_split_worker_options_dvn_only() {
|
|
11
|
+
let env = Env::default();
|
|
12
|
+
|
|
13
|
+
// Build TYPE_3 options with only DVN options
|
|
14
|
+
// x"0003" + x"020002000102000302ff0102000200010200020101"
|
|
15
|
+
let mut options = Bytes::new(&env);
|
|
16
|
+
options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
|
|
17
|
+
options.extend_from_slice(&hex!("020002000102000302ff0102000200010200020101"));
|
|
18
|
+
|
|
19
|
+
let (executor_options, dvn_options) = split_worker_options(&env, &options);
|
|
20
|
+
|
|
21
|
+
assert_eq!(executor_options.len(), 0);
|
|
22
|
+
assert_eq!(dvn_options.len(), 3);
|
|
23
|
+
|
|
24
|
+
// Check DVN options are grouped correctly by index
|
|
25
|
+
assert_eq!(dvn_options.get(0).unwrap(), Bytes::from_slice(&env, &hex!("02000200010200020001")));
|
|
26
|
+
assert_eq!(dvn_options.get(1).unwrap(), Bytes::from_slice(&env, &hex!("0200020101")));
|
|
27
|
+
assert_eq!(dvn_options.get(2).unwrap(), Bytes::from_slice(&env, &hex!("02000302ff01")));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#[test]
|
|
31
|
+
fn test_split_worker_options_executor_only() {
|
|
32
|
+
let env = Env::default();
|
|
33
|
+
|
|
34
|
+
// Build TYPE_3 options with two executor options
|
|
35
|
+
// x"0003" + x"0100110100000000000000000000000000009470010011010000000000000000000000000000ea60"
|
|
36
|
+
let executor_options_raw = hex!("0100110100000000000000000000000000009470010011010000000000000000000000000000ea60");
|
|
37
|
+
let mut options = Bytes::new(&env);
|
|
38
|
+
options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
|
|
39
|
+
options.extend_from_slice(&executor_options_raw);
|
|
40
|
+
|
|
41
|
+
let (executor_options, dvn_options) = split_worker_options(&env, &options);
|
|
42
|
+
|
|
43
|
+
assert_eq!(executor_options, Bytes::from_slice(&env, &executor_options_raw));
|
|
44
|
+
assert_eq!(dvn_options.len(), 0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#[test]
|
|
48
|
+
fn test_split_worker_options_options() {
|
|
49
|
+
let env = Env::default();
|
|
50
|
+
|
|
51
|
+
// Build TYPE_3 options with executor and DVN options
|
|
52
|
+
// executor: x"0100110100000000000000000000000000009470010011010000000000000000000000000000ea60"
|
|
53
|
+
// dvn: x"020002000102000302ff0102000200010200020101"
|
|
54
|
+
let executor_options_raw = hex!("0100110100000000000000000000000000009470010011010000000000000000000000000000ea60");
|
|
55
|
+
let dvn_options_raw = hex!("020002000102000302ff0102000200010200020101");
|
|
56
|
+
|
|
57
|
+
let mut options = Bytes::new(&env);
|
|
58
|
+
options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
|
|
59
|
+
options.extend_from_slice(&executor_options_raw);
|
|
60
|
+
options.extend_from_slice(&dvn_options_raw);
|
|
61
|
+
|
|
62
|
+
let (executor_options, dvn_options) = split_worker_options(&env, &options);
|
|
63
|
+
|
|
64
|
+
assert_eq!(executor_options, Bytes::from_slice(&env, &executor_options_raw));
|
|
65
|
+
assert_eq!(dvn_options.len(), 3);
|
|
66
|
+
|
|
67
|
+
// Check DVN options grouped by index
|
|
68
|
+
assert_eq!(dvn_options.get(0).unwrap(), Bytes::from_slice(&env, &hex!("02000200010200020001")));
|
|
69
|
+
assert_eq!(dvn_options.get(1).unwrap(), Bytes::from_slice(&env, &hex!("0200020101")));
|
|
70
|
+
assert_eq!(dvn_options.get(2).unwrap(), Bytes::from_slice(&env, &hex!("02000302ff01")));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#[test]
|
|
74
|
+
fn test_decode_legacy_options_type_1() {
|
|
75
|
+
let env = Env::default();
|
|
76
|
+
|
|
77
|
+
// Legacy type 1: x"0001" + gas as u256 (200000 = 0x30d40)
|
|
78
|
+
let mut options = Bytes::new(&env);
|
|
79
|
+
options.extend_from_slice(&LEGACY_OPTIONS_TYPE_1.to_be_bytes());
|
|
80
|
+
options.extend_from_slice(&hex!("0000000000000000000000000000000000000000000000000000000000030d40"));
|
|
81
|
+
|
|
82
|
+
let (executor_options, dvn_options) = split_worker_options(&env, &options);
|
|
83
|
+
|
|
84
|
+
// Expected: x"0100110100000000000000000000000000030d40"
|
|
85
|
+
assert_eq!(executor_options, Bytes::from_slice(&env, &hex!("0100110100000000000000000000000000030d40")));
|
|
86
|
+
assert_eq!(dvn_options.len(), 0);
|
|
87
|
+
|
|
88
|
+
// Verify by parsing
|
|
89
|
+
let mut reader = BufferReader::new(&executor_options);
|
|
90
|
+
assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
|
|
91
|
+
assert_eq!(reader.read_u16(), 17);
|
|
92
|
+
assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_LZRECEIVE);
|
|
93
|
+
assert_eq!(reader.read_u128(), 200000);
|
|
94
|
+
assert_eq!(reader.remaining(), 0);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#[test]
|
|
98
|
+
fn test_decode_legacy_options_type_2() {
|
|
99
|
+
let env = Env::default();
|
|
100
|
+
|
|
101
|
+
// Legacy type 2: gas(u256) + amount(u256) + receiver(20 bytes)
|
|
102
|
+
// gas: 200000 (0x30d40), amount: 10000000 (0x989680), receiver: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
|
|
103
|
+
let legacy_options = Bytes::from_slice(&env, &hex!("0000000000000000000000000000000000000000000000000000000000030d400000000000000000000000000000000000000000000000000000000000989680f39fd6e51aad88f6f4ce6ab8827279cfffb92266"));
|
|
104
|
+
let expected_options = hex!("0100110100000000000000000000000000030d400100310200000000000000000000000000989680000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266");
|
|
105
|
+
|
|
106
|
+
let executor_options = convert_legacy_options(&env, &mut BufferReader::new(&legacy_options), LEGACY_OPTIONS_TYPE_2);
|
|
107
|
+
|
|
108
|
+
// adapter params type 2 includes both lzReceive and nativeDrop
|
|
109
|
+
assert_eq!(executor_options, Bytes::from_slice(&env, &expected_options));
|
|
110
|
+
|
|
111
|
+
// Verify by parsing
|
|
112
|
+
let mut reader = BufferReader::new(&executor_options);
|
|
113
|
+
|
|
114
|
+
// lzReceive option
|
|
115
|
+
assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
|
|
116
|
+
assert_eq!(reader.read_u16(), 17);
|
|
117
|
+
assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_LZRECEIVE);
|
|
118
|
+
assert_eq!(reader.read_u128(), 200000);
|
|
119
|
+
|
|
120
|
+
// nativeDrop option
|
|
121
|
+
assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
|
|
122
|
+
assert_eq!(reader.read_u16(), 49);
|
|
123
|
+
assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_NATIVE_DROP);
|
|
124
|
+
assert_eq!(reader.read_u128(), 10000000);
|
|
125
|
+
assert_eq!(
|
|
126
|
+
reader.read_bytes_n(),
|
|
127
|
+
BytesN::from_array(&env, &hex!("000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266"))
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
#[test]
|
|
132
|
+
fn test_split_worker_options_using_legacy_option() {
|
|
133
|
+
let env = Env::default();
|
|
134
|
+
|
|
135
|
+
// Same as test_decode_legacy_options_type_2
|
|
136
|
+
let mut legacy_options = Bytes::new(&env);
|
|
137
|
+
legacy_options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
|
|
138
|
+
legacy_options.extend_from_slice(&hex!("0000000000000000000000000000000000000000000000000000000000030d400000000000000000000000000000000000000000000000000000000000989680f39fd6e51aad88f6f4ce6ab8827279cfffb92266"));
|
|
139
|
+
let expected_options = hex!("0100110100000000000000000000000000030d400100310200000000000000000000000000989680000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266");
|
|
140
|
+
|
|
141
|
+
let (executor_options, _) = split_worker_options(&env, &legacy_options);
|
|
142
|
+
|
|
143
|
+
// adapter params type 2 includes both lzReceive and nativeDrop
|
|
144
|
+
assert_eq!(executor_options, Bytes::from_slice(&env, &expected_options));
|
|
145
|
+
|
|
146
|
+
let mut reader = BufferReader::new(&executor_options);
|
|
147
|
+
|
|
148
|
+
// lzReceive
|
|
149
|
+
assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
|
|
150
|
+
assert_eq!(reader.read_u16(), 17);
|
|
151
|
+
assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_LZRECEIVE);
|
|
152
|
+
assert_eq!(reader.read_u128(), 200000);
|
|
153
|
+
|
|
154
|
+
// nativeDrop
|
|
155
|
+
assert_eq!(reader.read_u8(), EXECUTOR_WORKER_ID);
|
|
156
|
+
assert_eq!(reader.read_u16(), 49);
|
|
157
|
+
assert_eq!(reader.read_u8(), EXECUTOR_OPTION_TYPE_NATIVE_DROP);
|
|
158
|
+
assert_eq!(reader.read_u128(), 10000000);
|
|
159
|
+
assert_eq!(
|
|
160
|
+
reader.read_bytes_n(),
|
|
161
|
+
BytesN::from_array(&env, &hex!("000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266"))
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#[test]
|
|
166
|
+
fn test_group_dvn_options_by_index() {
|
|
167
|
+
let env = Env::default();
|
|
168
|
+
|
|
169
|
+
let dvn_option_bytes = hex!("020002000102000302ff0102000200010200020101");
|
|
170
|
+
let mut options = Bytes::new(&env);
|
|
171
|
+
options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
|
|
172
|
+
options.extend_from_slice(&dvn_option_bytes);
|
|
173
|
+
|
|
174
|
+
let (_, dvn_options) = split_worker_options(&env, &options);
|
|
175
|
+
|
|
176
|
+
let expected_dvn_0_options = hex!("02000200010200020001"); // 2 DVN options, id = 0
|
|
177
|
+
let expected_dvn_1_options = hex!("0200020101"); // 1 DVN option, id = 1
|
|
178
|
+
let expected_dvn_2_options = hex!("02000302ff01"); // 1 DVN option, id = 2
|
|
179
|
+
|
|
180
|
+
let mut found_0 = false;
|
|
181
|
+
let mut found_1 = false;
|
|
182
|
+
let mut found_2 = false;
|
|
183
|
+
|
|
184
|
+
// Check that DVN options are grouped correctly by index
|
|
185
|
+
for (index, option) in dvn_options.iter() {
|
|
186
|
+
if index == 0 {
|
|
187
|
+
found_0 = true;
|
|
188
|
+
assert_eq!(option, Bytes::from_slice(&env, &expected_dvn_0_options));
|
|
189
|
+
}
|
|
190
|
+
if index == 1 {
|
|
191
|
+
found_1 = true;
|
|
192
|
+
assert_eq!(option, Bytes::from_slice(&env, &expected_dvn_1_options));
|
|
193
|
+
}
|
|
194
|
+
if index == 2 {
|
|
195
|
+
found_2 = true;
|
|
196
|
+
assert_eq!(option, Bytes::from_slice(&env, &expected_dvn_2_options));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
assert!(found_0 && found_1 && found_2);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
#[test]
|
|
203
|
+
fn test_get_matching_options() {
|
|
204
|
+
let env = Env::default();
|
|
205
|
+
|
|
206
|
+
// Same DVN options as test_split_worker_options_dvn_only
|
|
207
|
+
let mut options = Bytes::new(&env);
|
|
208
|
+
options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
|
|
209
|
+
options.extend_from_slice(&hex!("020002000102000302ff0102000200010200020101"));
|
|
210
|
+
|
|
211
|
+
let (_, dvn_options) = split_worker_options(&env, &options);
|
|
212
|
+
|
|
213
|
+
assert_eq!(dvn_options.get(0).unwrap(), Bytes::from_slice(&env, &hex!("02000200010200020001")));
|
|
214
|
+
assert_eq!(dvn_options.get(1).unwrap(), Bytes::from_slice(&env, &hex!("0200020101")));
|
|
215
|
+
assert_eq!(dvn_options.get(2).unwrap(), Bytes::from_slice(&env, &hex!("02000302ff01")));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ============ Error tests ============
|
|
219
|
+
|
|
220
|
+
#[test]
|
|
221
|
+
#[should_panic(expected = "Error(Contract, #11101)")] // WorkerOptionsError::InvalidOptions
|
|
222
|
+
fn test_decode_invalid_options_too_short() {
|
|
223
|
+
let env = Env::default();
|
|
224
|
+
let mut options = Bytes::new(&env);
|
|
225
|
+
options.push_back(OPTIONS_TYPE_3 as u8);
|
|
226
|
+
split_worker_options(&env, &options);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
#[test]
|
|
230
|
+
#[should_panic(expected = "Error(Contract, #11102)")] // WorkerOptionsError::InvalidWorkerId
|
|
231
|
+
fn test_decode_invalid_worker_id() {
|
|
232
|
+
let env = Env::default();
|
|
233
|
+
let mut options = Bytes::new(&env);
|
|
234
|
+
options.extend_from_slice(&OPTIONS_TYPE_3.to_be_bytes());
|
|
235
|
+
options.extend_from_slice(&hex!("00000501020304050607")); // Invalid worker_id = 0
|
|
236
|
+
split_worker_options(&env, &options);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
#[test]
|
|
240
|
+
#[should_panic(expected = "Error(Contract, #11104)")] // WorkerOptionsError::LegacyOptionsType1GasOverflow
|
|
241
|
+
fn test_legacy_type1_gas_overflow() {
|
|
242
|
+
let env = Env::default();
|
|
243
|
+
let mut options = Bytes::new(&env);
|
|
244
|
+
options.extend_from_slice(&LEGACY_OPTIONS_TYPE_1.to_be_bytes());
|
|
245
|
+
options.extend_from_slice(&hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); // u256 max
|
|
246
|
+
split_worker_options(&env, &options);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
#[test]
|
|
250
|
+
#[should_panic(expected = "Error(Contract, #11106)")] // WorkerOptionsError::LegacyOptionsType2GasOverflow
|
|
251
|
+
fn test_legacy_type2_gas_overflow() {
|
|
252
|
+
let env = Env::default();
|
|
253
|
+
let mut options = Bytes::new(&env);
|
|
254
|
+
options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
|
|
255
|
+
options.extend_from_slice(&hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000003e84242424242424242424242424242424242424242424242424242424242424242"));
|
|
256
|
+
split_worker_options(&env, &options);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
#[test]
|
|
260
|
+
#[should_panic(expected = "Error(Contract, #11107)")] // WorkerOptionsError::LegacyOptionsType2AmountOverflow
|
|
261
|
+
fn test_legacy_type2_amount_overflow() {
|
|
262
|
+
let env = Env::default();
|
|
263
|
+
let mut options = Bytes::new(&env);
|
|
264
|
+
options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
|
|
265
|
+
options.extend_from_slice(&hex!("0000000000000000000000000000000000000000000000000000000000030d40ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4242424242424242424242424242424242424242424242424242424242424242"));
|
|
266
|
+
split_worker_options(&env, &options);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
#[test]
|
|
270
|
+
#[should_panic(expected = "Error(Contract, #11103)")] // WorkerOptionsError::InvalidLegacyOptionsType1
|
|
271
|
+
fn test_legacy_type1_invalid_size_too_short() {
|
|
272
|
+
let env = Env::default();
|
|
273
|
+
let mut options = Bytes::new(&env);
|
|
274
|
+
options.extend_from_slice(&LEGACY_OPTIONS_TYPE_1.to_be_bytes());
|
|
275
|
+
options.extend_from_slice(&hex!("00000000000000000000000000000000")); // Only 16 bytes
|
|
276
|
+
split_worker_options(&env, &options);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
#[test]
|
|
280
|
+
#[should_panic(expected = "Error(Contract, #11103)")] // WorkerOptionsError::InvalidLegacyOptionsType1
|
|
281
|
+
fn test_legacy_type1_invalid_size_too_long() {
|
|
282
|
+
let env = Env::default();
|
|
283
|
+
let mut options = Bytes::new(&env);
|
|
284
|
+
options.extend_from_slice(&LEGACY_OPTIONS_TYPE_1.to_be_bytes());
|
|
285
|
+
options.extend_from_slice(&hex!(
|
|
286
|
+
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
287
|
+
)); // 48 bytes
|
|
288
|
+
split_worker_options(&env, &options);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
#[test]
|
|
292
|
+
#[should_panic(expected = "Error(Contract, #11105)")] // WorkerOptionsError::InvalidLegacyOptionsType2
|
|
293
|
+
fn test_legacy_type2_invalid_size_too_short() {
|
|
294
|
+
let env = Env::default();
|
|
295
|
+
let mut options = Bytes::new(&env);
|
|
296
|
+
options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
|
|
297
|
+
options.extend_from_slice(&hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")); // 64 bytes, no receiver
|
|
298
|
+
split_worker_options(&env, &options);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
#[test]
|
|
302
|
+
#[should_panic(expected = "Error(Contract, #11105)")] // WorkerOptionsError::InvalidLegacyOptionsType2
|
|
303
|
+
fn test_legacy_type2_invalid_size_too_long() {
|
|
304
|
+
let env = Env::default();
|
|
305
|
+
let mut options = Bytes::new(&env);
|
|
306
|
+
options.extend_from_slice(&LEGACY_OPTIONS_TYPE_2.to_be_bytes());
|
|
307
|
+
options.extend_from_slice(&[0u8; 97]); // 97 bytes, too long
|
|
308
|
+
split_worker_options(&env, &options);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
#[test]
|
|
312
|
+
#[should_panic(expected = "Error(Contract, #11108)")] // WorkerOptionsError::InvalidOptionType
|
|
313
|
+
fn test_unsupported_option_type() {
|
|
314
|
+
let env = Env::default();
|
|
315
|
+
let mut options = Bytes::new(&env);
|
|
316
|
+
options.extend_from_slice(&hex!("0063")); // Invalid type 99
|
|
317
|
+
options.extend_from_slice(&hex!("0000000000000000000000000000000000000000000000000000000000000000"));
|
|
318
|
+
split_worker_options(&env, &options);
|
|
319
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
use crate::errors::WorkerOptionsError;
|
|
2
|
+
use soroban_sdk::{assert_with_error, bytes, map, panic_with_error, Bytes, BytesN, Env, Map};
|
|
3
|
+
use utils::{buffer_reader::BufferReader, buffer_writer::BufferWriter, option_ext::OptionExt};
|
|
4
|
+
|
|
5
|
+
// Option type constants
|
|
6
|
+
pub const LEGACY_OPTIONS_TYPE_1: u16 = 1; // legacy options type 1
|
|
7
|
+
pub const LEGACY_OPTIONS_TYPE_2: u16 = 2; // legacy options type 2
|
|
8
|
+
pub const OPTIONS_TYPE_3: u16 = 3; // modern options type 3
|
|
9
|
+
|
|
10
|
+
// Worker ID constants
|
|
11
|
+
pub const EXECUTOR_WORKER_ID: u8 = 1;
|
|
12
|
+
pub const DVN_WORKER_ID: u8 = 2;
|
|
13
|
+
|
|
14
|
+
// Executor option type constants
|
|
15
|
+
pub const EXECUTOR_OPTION_TYPE_LZRECEIVE: u8 = 1;
|
|
16
|
+
pub const EXECUTOR_OPTION_TYPE_NATIVE_DROP: u8 = 2;
|
|
17
|
+
|
|
18
|
+
// DVN option byte offset (dvn_idx is the 4th byte of the option bytes)
|
|
19
|
+
pub const DVN_IDX_OFFSET: u32 = 3;
|
|
20
|
+
|
|
21
|
+
/// Splits worker options into separate executor and DVN option collections.
|
|
22
|
+
///
|
|
23
|
+
/// This is the main entry point for processing worker options. It automatically
|
|
24
|
+
/// detects the option format version and delegates to the appropriate parser.
|
|
25
|
+
///
|
|
26
|
+
/// Format detection:
|
|
27
|
+
/// - Type 3: Modern flexible format with multiple worker types
|
|
28
|
+
/// - Type 1 & 2: Legacy formats (executor options only, no DVN options)
|
|
29
|
+
///
|
|
30
|
+
/// # Arguments
|
|
31
|
+
/// * `options` - The raw options bytes
|
|
32
|
+
///
|
|
33
|
+
/// # Returns
|
|
34
|
+
/// A tuple of (executor_options, dvn_options_map)
|
|
35
|
+
pub fn split_worker_options(env: &Env, options: &Bytes) -> (Bytes, Map<u32, Bytes>) {
|
|
36
|
+
assert_with_error!(env, options.len() >= 2, WorkerOptionsError::InvalidOptions);
|
|
37
|
+
|
|
38
|
+
let mut reader = BufferReader::new(options);
|
|
39
|
+
let options_type = reader.read_u16();
|
|
40
|
+
|
|
41
|
+
if options_type == OPTIONS_TYPE_3 {
|
|
42
|
+
extract_type_3_options(env, &mut reader)
|
|
43
|
+
} else {
|
|
44
|
+
let executor_options = convert_legacy_options(env, &mut reader, options_type);
|
|
45
|
+
(executor_options, map![env])
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Extracts options from the modern Type 3 format.
|
|
50
|
+
///
|
|
51
|
+
/// Type 3 format supports multiple workers (executors and DVNs) with flexible
|
|
52
|
+
/// option structures. Each worker option includes its own size header.
|
|
53
|
+
///
|
|
54
|
+
/// Format Structure:
|
|
55
|
+
/// ```text
|
|
56
|
+
/// [worker_option][worker_option][worker_option]...
|
|
57
|
+
///
|
|
58
|
+
/// Worker Option:
|
|
59
|
+
/// [worker_id: u8][option_size: u16][option_data: bytes(option_size)]
|
|
60
|
+
/// ```
|
|
61
|
+
///
|
|
62
|
+
/// # Arguments
|
|
63
|
+
/// * `options_reader` - Buffer reader positioned after the options type header
|
|
64
|
+
///
|
|
65
|
+
/// # Returns
|
|
66
|
+
/// A tuple of (executor_options, dvn_options_map)
|
|
67
|
+
pub fn extract_type_3_options(env: &Env, options_reader: &mut BufferReader) -> (Bytes, Map<u32, Bytes>) {
|
|
68
|
+
let mut executor_options = bytes!(env);
|
|
69
|
+
let mut dvn_options = map![env];
|
|
70
|
+
|
|
71
|
+
while options_reader.remaining() > 0 {
|
|
72
|
+
let worker_id = options_reader.read_u8();
|
|
73
|
+
let option_size = options_reader.read_u16() as u32;
|
|
74
|
+
|
|
75
|
+
// Rewind to the start of the current option and read the complete option bytes
|
|
76
|
+
// 3 bytes for worker_id (1) + option_size (2)
|
|
77
|
+
let current_option = options_reader.rewind(3).read_bytes(3 + option_size);
|
|
78
|
+
|
|
79
|
+
match worker_id {
|
|
80
|
+
EXECUTOR_WORKER_ID => executor_options.append(¤t_option),
|
|
81
|
+
DVN_WORKER_ID => append_dvn_option(&mut dvn_options, current_option),
|
|
82
|
+
_ => panic_with_error!(env, WorkerOptionsError::InvalidWorkerId),
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
(executor_options, dvn_options)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/// Converts legacy option formats (Type 1 and Type 2) to executor options in Type 3 format.
|
|
90
|
+
///
|
|
91
|
+
/// Legacy formats only supported executor options and did not include DVN options.
|
|
92
|
+
///
|
|
93
|
+
/// Legacy Format Details:
|
|
94
|
+
/// - **Type 1**: `[execution_gas: u256]` (32 bytes total)
|
|
95
|
+
/// - **Type 2**: `[execution_gas: u256][amount: u256][receiver: bytes(0-32)]` (64-96 bytes total)
|
|
96
|
+
///
|
|
97
|
+
/// Note: Legacy formats use u256 for gas/amounts, but Type 3 uses u128.
|
|
98
|
+
/// The conversion will panic if values exceed u128 range.
|
|
99
|
+
///
|
|
100
|
+
/// # Arguments
|
|
101
|
+
/// * `options` - Buffer reader positioned after the options type header
|
|
102
|
+
/// * `option_type` - The legacy option type (1 or 2)
|
|
103
|
+
///
|
|
104
|
+
/// # Returns
|
|
105
|
+
/// Executor options in Type 3 format
|
|
106
|
+
pub fn convert_legacy_options(env: &Env, options: &mut BufferReader, option_type: u16) -> Bytes {
|
|
107
|
+
let mut executor_options = BufferWriter::new(env);
|
|
108
|
+
let options_size = options.remaining();
|
|
109
|
+
|
|
110
|
+
match option_type {
|
|
111
|
+
LEGACY_OPTIONS_TYPE_1 => {
|
|
112
|
+
assert_with_error!(env, options_size == 32, WorkerOptionsError::InvalidLegacyOptionsType1);
|
|
113
|
+
// Execution gas (u256 -> u128)
|
|
114
|
+
let execution_gas =
|
|
115
|
+
options.read_u256().to_u128().unwrap_or_panic(env, WorkerOptionsError::LegacyOptionsType1GasOverflow);
|
|
116
|
+
|
|
117
|
+
append_lz_receive_option(&mut executor_options, execution_gas);
|
|
118
|
+
}
|
|
119
|
+
LEGACY_OPTIONS_TYPE_2 => {
|
|
120
|
+
assert_with_error!(
|
|
121
|
+
env,
|
|
122
|
+
options_size > 64 && options_size <= 96,
|
|
123
|
+
WorkerOptionsError::InvalidLegacyOptionsType2
|
|
124
|
+
);
|
|
125
|
+
// Execution gas & amount (u256 -> u128)
|
|
126
|
+
let execution_gas =
|
|
127
|
+
options.read_u256().to_u128().unwrap_or_panic(env, WorkerOptionsError::LegacyOptionsType2GasOverflow);
|
|
128
|
+
let amount = options
|
|
129
|
+
.read_u256()
|
|
130
|
+
.to_u128()
|
|
131
|
+
.unwrap_or_panic(env, WorkerOptionsError::LegacyOptionsType2AmountOverflow);
|
|
132
|
+
|
|
133
|
+
let receiver = left_pad_to_bytes32(env, &options.read_bytes_until_end());
|
|
134
|
+
|
|
135
|
+
append_lz_receive_option(&mut executor_options, execution_gas);
|
|
136
|
+
append_native_drop_option(&mut executor_options, amount, &receiver);
|
|
137
|
+
}
|
|
138
|
+
_ => panic_with_error!(env, WorkerOptionsError::InvalidOptionType),
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Ensure all bytes were consumed
|
|
142
|
+
assert_with_error!(env, options.remaining() == 0, WorkerOptionsError::InvalidOptions);
|
|
143
|
+
executor_options.to_bytes()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ========================================================
|
|
147
|
+
// Internal Helper Functions
|
|
148
|
+
// ========================================================
|
|
149
|
+
|
|
150
|
+
/// Efficiently groups DVN options by index.
|
|
151
|
+
///
|
|
152
|
+
/// Searches for existing DVN options with the same index and concatenates them,
|
|
153
|
+
/// or creates a new entry if this is the first option for this DVN index.
|
|
154
|
+
fn append_dvn_option(dvn_options: &mut Map<u32, Bytes>, option_bytes: Bytes) {
|
|
155
|
+
let dvn_idx = option_bytes.get(DVN_IDX_OFFSET).unwrap() as u32;
|
|
156
|
+
if dvn_options.contains_key(dvn_idx) {
|
|
157
|
+
let mut existing = dvn_options.get(dvn_idx).unwrap();
|
|
158
|
+
existing.append(&option_bytes);
|
|
159
|
+
dvn_options.set(dvn_idx, existing);
|
|
160
|
+
} else {
|
|
161
|
+
dvn_options.set(dvn_idx, option_bytes);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/// Appends a LzReceive option to the executor options bytes.
|
|
166
|
+
/// Format: [worker_id][option_size][option_type][execution_gas]
|
|
167
|
+
fn append_lz_receive_option(buf: &mut BufferWriter, execution_gas: u128) {
|
|
168
|
+
buf.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
|
|
169
|
+
.write_u16(17) // option_size: option_type(1) + data(16) = 17 bytes
|
|
170
|
+
.write_u8(EXECUTOR_OPTION_TYPE_LZRECEIVE) // option_type (1 byte)
|
|
171
|
+
.write_u128(execution_gas); // execution gas data (16 bytes)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/// Appends a native drop option to the executor options bytes.
|
|
175
|
+
/// Format: [worker_id][option_size][option_type][amount][receiver]
|
|
176
|
+
fn append_native_drop_option(buf: &mut BufferWriter, amount: u128, receiver: &BytesN<32>) {
|
|
177
|
+
buf.write_u8(EXECUTOR_WORKER_ID) // worker_id (1 byte)
|
|
178
|
+
.write_u16(49) // option_size: option_type(1) + amount(16) + receiver(32) = 49 bytes
|
|
179
|
+
.write_u8(EXECUTOR_OPTION_TYPE_NATIVE_DROP) // option_type (1 byte)
|
|
180
|
+
.write_u128(amount) // drop amount (16 bytes)
|
|
181
|
+
.write_bytes_n(receiver); // receiver address (32 bytes)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/// Converts Bytes to BytesN<32> with left-padding (zeros at the beginning)
|
|
185
|
+
fn left_pad_to_bytes32(env: &Env, bytes: &Bytes) -> BytesN<32> {
|
|
186
|
+
assert_with_error!(env, bytes.len() <= 32, WorkerOptionsError::InvalidBytesLength);
|
|
187
|
+
let mut buf = [0u8; 32];
|
|
188
|
+
bytes.copy_into_slice(&mut buf[32 - bytes.len() as usize..]);
|
|
189
|
+
BytesN::from_array(env, &buf)
|
|
190
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "simple-message-lib"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
license.workspace = true
|
|
6
|
+
publish = false
|
|
7
|
+
|
|
8
|
+
[lib]
|
|
9
|
+
crate-type = ["cdylib", "rlib"]
|
|
10
|
+
doctest = false
|
|
11
|
+
|
|
12
|
+
[features]
|
|
13
|
+
library = []
|
|
14
|
+
testutils = []
|
|
15
|
+
|
|
16
|
+
[dependencies]
|
|
17
|
+
cfg-if = { workspace = true }
|
|
18
|
+
soroban-sdk = { workspace = true }
|
|
19
|
+
# workspace dependencies
|
|
20
|
+
common-macros = { workspace = true }
|
|
21
|
+
utils = { workspace = true }
|
|
22
|
+
endpoint-v2 = { workspace = true, features = ["library"] }
|
|
23
|
+
message-lib-common = { workspace = true }
|
|
24
|
+
|
|
25
|
+
[dev-dependencies]
|
|
26
|
+
soroban-sdk = { workspace = true, features = ["testutils"] }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#![no_std]
|
|
2
|
+
|
|
3
|
+
cfg_if::cfg_if! {
|
|
4
|
+
if #[cfg(any(not(feature = "library"), feature = "testutils"))] {
|
|
5
|
+
mod errors;
|
|
6
|
+
mod simple_message_lib;
|
|
7
|
+
mod storage;
|
|
8
|
+
|
|
9
|
+
pub use simple_message_lib::{SimpleMessageLib, SimpleMessageLibClient};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
#[cfg(test)]
|
|
14
|
+
mod test;
|