@layerzerolabs/protocol-stellar-v2 0.2.8 → 0.2.9
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 +443 -302
- package/.turbo/turbo-lint.log +118 -96
- package/.turbo/turbo-test.log +853 -731
- package/Cargo.lock +120 -37
- package/Cargo.toml +8 -5
- package/contracts/common-macros/src/contract_impl.rs +44 -0
- package/contracts/common-macros/src/lib.rs +86 -40
- package/contracts/common-macros/src/ownable.rs +24 -32
- package/contracts/common-macros/src/storage.rs +95 -120
- package/contracts/common-macros/src/tests/contract_impl.rs +289 -0
- package/contracts/common-macros/src/tests/mod.rs +9 -0
- package/contracts/common-macros/src/tests/ownable.rs +151 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap +85 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +30 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap +9 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__storage__snapshot_generated_storage_code.snap +1072 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +45 -0
- package/contracts/common-macros/src/tests/storage.rs +485 -0
- package/contracts/common-macros/src/tests/test_helpers.rs +93 -0
- package/contracts/common-macros/src/tests/ttl_configurable.rs +34 -0
- package/contracts/common-macros/src/ttl_configurable.rs +31 -14
- package/contracts/common-macros/src/utils.rs +27 -0
- package/contracts/endpoint-v2/ARCHITECTURE.md +4 -4
- package/contracts/endpoint-v2/src/endpoint_v2.rs +18 -15
- package/contracts/endpoint-v2/src/interfaces/message_lib.rs +2 -3
- package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +5 -3
- package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +2 -2
- package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +2 -2
- package/contracts/endpoint-v2/src/interfaces/send_lib.rs +4 -4
- package/contracts/endpoint-v2/src/lib.rs +6 -5
- package/contracts/endpoint-v2/src/message_lib_manager.rs +14 -6
- package/contracts/endpoint-v2/src/messaging_channel.rs +6 -2
- package/contracts/endpoint-v2/src/messaging_composer.rs +6 -2
- package/contracts/endpoint-v2/src/storage.rs +10 -7
- package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +16 -16
- package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +46 -46
- package/contracts/endpoint-v2/src/tests/mock.rs +2 -2
- package/contracts/endpoint-v2/src/util.rs +8 -2
- package/contracts/message-libs/block-message-lib/Cargo.toml +1 -0
- package/contracts/message-libs/block-message-lib/src/lib.rs +5 -5
- package/contracts/message-libs/message-lib-common/src/errors.rs +8 -8
- package/contracts/message-libs/message-lib-common/src/interfaces/dvn.rs +0 -1
- package/contracts/message-libs/message-lib-common/src/interfaces/mod.rs +3 -3
- package/contracts/message-libs/message-lib-common/src/lib.rs +0 -2
- package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +4 -6
- package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +2 -2
- package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +11 -11
- package/contracts/message-libs/message-lib-common/src/worker_options.rs +10 -16
- package/contracts/message-libs/simple-message-lib/src/errors.rs +0 -4
- package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +49 -34
- package/contracts/message-libs/simple-message-lib/src/storage.rs +3 -7
- package/contracts/message-libs/simple-message-lib/src/test.rs +3 -3
- package/contracts/message-libs/treasury/src/storage.rs +1 -2
- package/contracts/message-libs/treasury/src/tests/setup.rs +3 -2
- package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +0 -13
- package/contracts/message-libs/treasury/src/treasury.rs +18 -21
- package/contracts/message-libs/uln-302/Cargo.toml +1 -0
- package/contracts/message-libs/uln-302/src/interfaces/mod.rs +4 -4
- package/contracts/message-libs/uln-302/src/interfaces/{receive.rs → receive_uln.rs} +3 -3
- package/contracts/message-libs/uln-302/src/interfaces/{send.rs → send_uln.rs} +8 -80
- package/contracts/message-libs/uln-302/src/lib.rs +5 -4
- package/contracts/message-libs/uln-302/src/{receive.rs → receive_uln.rs} +20 -12
- package/contracts/message-libs/uln-302/src/{send.rs → send_uln.rs} +19 -13
- package/contracts/message-libs/uln-302/src/storage.rs +1 -2
- package/contracts/message-libs/uln-302/src/tests/config/uln_config.rs +3 -2
- package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +30 -30
- package/contracts/message-libs/uln-302/src/tests/setup.rs +12 -11
- package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +1 -1
- package/contracts/message-libs/uln-302/src/{config_validation.rs → types.rs} +79 -11
- package/contracts/message-libs/uln-302/src/uln302.rs +15 -10
- package/contracts/oapp-macros/Cargo.toml +2 -8
- package/contracts/oapp-macros/src/lib.rs +57 -311
- package/contracts/oapp-macros/src/oapp_core.rs +23 -32
- package/contracts/oapp-macros/src/oapp_full.rs +8 -2
- package/contracts/oapp-macros/src/oapp_options_type3.rs +21 -36
- package/contracts/oapp-macros/src/oapp_receiver.rs +38 -57
- package/contracts/oapp-macros/src/oapp_sender.rs +12 -14
- package/contracts/oapp-macros/src/util.rs +14 -10
- package/contracts/oapps/counter/Cargo.toml +2 -1
- package/contracts/oapps/counter/integration_tests/utils.rs +4 -4
- package/contracts/oapps/counter/src/codec.rs +8 -9
- package/contracts/oapps/counter/src/counter.rs +156 -147
- package/contracts/oapps/counter/src/storage.rs +1 -2
- package/contracts/oapps/counter/src/tests/test_codec.rs +5 -5
- package/contracts/oapps/counter/src/tests/test_counter.rs +11 -13
- package/contracts/oapps/oapp/Cargo.toml +1 -0
- package/contracts/oapps/oapp/src/errors.rs +1 -1
- package/contracts/oapps/oapp/src/lib.rs +3 -0
- package/contracts/oapps/oapp/src/macro_tests/mod.rs +1 -0
- package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +312 -0
- package/contracts/oapps/oapp/src/oapp_core.rs +52 -53
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +18 -28
- package/contracts/oapps/oapp/src/oapp_receiver.rs +82 -31
- package/contracts/oapps/oapp/src/oapp_sender.rs +55 -13
- package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +16 -3
- package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +33 -8
- package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +6 -9
- package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +28 -15
- package/contracts/oapps/oft/Cargo.toml +27 -0
- package/contracts/oapps/oft/integration-tests/mod.rs +3 -0
- package/contracts/oapps/oft/integration-tests/setup.rs +320 -0
- package/contracts/oapps/oft/integration-tests/test_with_sml.rs +155 -0
- package/contracts/oapps/oft/integration-tests/utils.rs +201 -0
- package/contracts/oapps/oft/src/codec/mod.rs +2 -0
- package/contracts/oapps/oft/src/codec/oft_compose_msg_codec.rs +55 -0
- package/contracts/oapps/oft/src/codec/oft_msg_codec.rs +62 -0
- package/contracts/oapps/oft/src/constants.rs +5 -0
- package/contracts/oapps/oft/src/errors.rs +8 -0
- package/contracts/oapps/oft/src/events.rs +19 -0
- package/contracts/oapps/oft/src/interfaces/mint_burn_token.rs +23 -0
- package/contracts/oapps/oft/src/interfaces/mod.rs +3 -0
- package/contracts/oapps/oft/src/lib.rs +22 -0
- package/contracts/oapps/oft/src/macro_tests/mod.rs +2 -0
- package/contracts/oapps/oft/src/macro_tests/test_all_default.rs +41 -0
- package/contracts/oapps/oft/src/macro_tests/test_override.rs +83 -0
- package/contracts/oapps/oft/src/oft.rs +320 -0
- package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +50 -0
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +50 -0
- package/contracts/oapps/oft/src/oft_types/mod.rs +10 -0
- package/contracts/oapps/oft/src/storage.rs +11 -0
- package/contracts/oapps/oft/src/tests/mod.rs +13 -0
- package/contracts/oapps/oft/src/tests/test_decimals.rs +89 -0
- package/contracts/oapps/oft/src/tests/test_lz_receive.rs +282 -0
- package/contracts/oapps/oft/src/tests/test_oft_compose_msg_codec.rs +68 -0
- package/contracts/oapps/oft/src/tests/test_oft_msg_codec.rs +136 -0
- package/contracts/oapps/oft/src/tests/test_oft_version.rs +13 -0
- package/contracts/oapps/oft/src/tests/test_quote_oft.rs +159 -0
- package/contracts/oapps/oft/src/tests/test_quote_send.rs +195 -0
- package/contracts/oapps/oft/src/tests/test_resolve_address.rs +37 -0
- package/contracts/oapps/oft/src/tests/test_send.rs +915 -0
- package/contracts/oapps/oft/src/tests/test_token.rs +47 -0
- package/contracts/oapps/oft/src/tests/test_utils.rs +789 -0
- package/contracts/oapps/oft/src/types.rs +38 -0
- package/contracts/oapps/oft/src/utils.rs +67 -0
- package/contracts/oapps/oft-mint-burn/Cargo.toml +26 -0
- package/contracts/oapps/oft-mint-burn/src/lib.rs +3 -0
- package/contracts/oapps/oft-mint-burn/src/oft.rs +28 -0
- package/contracts/oapps/oft-mint-burn/src/tests/mod.rs +1 -0
- package/contracts/utils/src/buffer_reader.rs +8 -9
- package/contracts/utils/src/buffer_writer.rs +11 -5
- package/contracts/utils/src/errors.rs +5 -5
- package/contracts/utils/src/ownable.rs +14 -6
- package/contracts/utils/src/testing_utils.rs +11 -1
- package/contracts/utils/src/tests/buffer_reader.rs +491 -730
- package/contracts/utils/src/tests/buffer_writer.rs +336 -148
- package/contracts/utils/src/tests/bytes_ext.rs +125 -40
- package/contracts/utils/src/tests/mod.rs +3 -0
- package/contracts/utils/src/tests/ownable.rs +379 -27
- package/contracts/utils/src/tests/test_helper.rs +47 -0
- package/contracts/utils/src/tests/testing_utils.rs +555 -0
- package/contracts/utils/src/tests/ttl.rs +421 -0
- package/contracts/utils/src/ttl.rs +29 -89
- package/contracts/workers/dvn/Cargo.toml +31 -0
- package/contracts/workers/dvn/src/auth.rs +66 -0
- package/contracts/workers/dvn/src/dvn.rs +143 -0
- package/contracts/workers/dvn/src/errors.rs +21 -0
- package/contracts/workers/dvn/src/events.rs +19 -0
- package/contracts/workers/dvn/src/interfaces/dvn.rs +12 -0
- package/contracts/workers/dvn/src/interfaces/mod.rs +5 -0
- package/contracts/workers/dvn/src/interfaces/multisig.rs +15 -0
- package/contracts/workers/dvn/src/lib.rs +24 -0
- package/contracts/workers/dvn/src/multisig.rs +127 -0
- package/contracts/workers/dvn/src/storage.rs +35 -0
- package/contracts/workers/dvn/src/tests/auth.rs +237 -0
- package/contracts/workers/dvn/src/tests/dvn.rs +349 -0
- package/contracts/workers/dvn/src/tests/key_pair.rs +66 -0
- package/contracts/workers/dvn/src/tests/mod.rs +5 -0
- package/contracts/workers/dvn/src/tests/multisig/mod.rs +3 -0
- package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +133 -0
- package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +108 -0
- package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +109 -0
- package/contracts/workers/dvn/src/tests/setup.rs +109 -0
- package/contracts/workers/dvn/src/types.rs +26 -0
- package/contracts/workers/dvn-fee-lib/Cargo.toml +24 -0
- package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +113 -0
- package/contracts/workers/dvn-fee-lib/src/errors.rs +8 -0
- package/contracts/workers/dvn-fee-lib/src/lib.rs +17 -0
- package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +282 -0
- package/contracts/workers/dvn-fee-lib/src/tests/mod.rs +1 -0
- package/contracts/workers/executor/Cargo.toml +10 -7
- package/contracts/workers/executor/src/errors.rs +8 -0
- package/contracts/workers/executor/src/events.rs +4 -7
- package/contracts/workers/executor/src/interfaces/executor.rs +72 -22
- package/contracts/workers/executor/src/interfaces/mod.rs +0 -2
- package/contracts/workers/executor/src/lib.rs +16 -7
- package/contracts/workers/executor/src/lz_executor.rs +308 -0
- package/contracts/workers/executor/src/storage.rs +24 -16
- package/contracts/workers/executor-fee-lib/Cargo.toml +22 -0
- package/contracts/workers/executor-fee-lib/src/errors.rs +15 -0
- package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +215 -0
- package/contracts/workers/executor-fee-lib/src/executor_option.rs +203 -0
- package/contracts/workers/executor-fee-lib/src/lib.rs +7 -0
- package/contracts/workers/executor-helper/Cargo.toml +29 -0
- package/contracts/workers/executor-helper/src/executor_helper.rs +161 -0
- package/contracts/workers/executor-helper/src/lib.rs +11 -0
- package/contracts/workers/{worker-common → worker}/Cargo.toml +1 -4
- package/contracts/workers/worker/src/errors.rs +24 -0
- package/contracts/workers/worker/src/events.rs +62 -0
- package/contracts/workers/worker/src/interfaces/dvn_fee_lib.rs +75 -0
- package/contracts/workers/worker/src/interfaces/executor_fee_lib.rs +84 -0
- package/contracts/workers/{worker-common → worker}/src/interfaces/mod.rs +2 -2
- package/contracts/workers/worker/src/interfaces/price_feed.rs +85 -0
- package/contracts/workers/worker/src/lib.rs +14 -0
- package/contracts/workers/worker/src/storage.rs +63 -0
- package/contracts/workers/worker/src/worker.rs +459 -0
- package/package.json +3 -3
- package/sdk/dist/generated/bml.d.ts +88 -17
- package/sdk/dist/generated/bml.js +62 -16
- package/sdk/dist/generated/counter.d.ts +281 -102
- package/sdk/dist/generated/counter.js +93 -41
- package/sdk/dist/generated/endpoint.d.ts +128 -105
- package/sdk/dist/generated/endpoint.js +47 -45
- package/sdk/dist/generated/sml.d.ts +212 -69
- package/sdk/dist/generated/sml.js +103 -53
- package/sdk/dist/generated/uln302.d.ts +270 -173
- package/sdk/dist/generated/uln302.js +112 -64
- package/sdk/package.json +11 -11
- package/sdk/test/index.test.ts +147 -42
- package/sdk/test/suites/constants.ts +7 -3
- package/sdk/test/suites/deploy.ts +65 -42
- package/sdk/test/suites/localnet.ts +2 -2
- package/sdk/test/suites/scan.ts +28 -25
- package/sdk/test/utils.ts +199 -0
- package/sdk/tsconfig.json +93 -95
- package/tools/ts-bindings-gen/src/main.rs +2 -0
- package/contracts/common-macros/src/snapshots/common_macros__tests__tests__snapshot_generated_storage_code.snap +0 -310
- package/contracts/common-macros/src/tests.rs +0 -287
- package/contracts/oapp-macros/tests/test_macros.rs +0 -522
- package/contracts/workers/executor/src/executor.rs +0 -347
- package/contracts/workers/executor/src/interfaces/types.rs +0 -51
- package/contracts/workers/worker-common/src/constants.rs +0 -17
- package/contracts/workers/worker-common/src/errors.rs +0 -6
- package/contracts/workers/worker-common/src/events.rs +0 -34
- package/contracts/workers/worker-common/src/interfaces/executor_fee_lib.rs +0 -35
- package/contracts/workers/worker-common/src/interfaces/price_feed.rs +0 -40
- package/contracts/workers/worker-common/src/interfaces/worker.rs +0 -60
- package/contracts/workers/worker-common/src/lib.rs +0 -19
- package/contracts/workers/worker-common/src/storage.rs +0 -32
- package/contracts/workers/worker-common/src/worker_common.rs +0 -166
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
extern crate std;
|
|
2
|
+
|
|
3
|
+
use crate::errors::TtlError;
|
|
4
|
+
use crate::ttl::{
|
|
5
|
+
DefaultTtlConfigurable, TtlConfig, TtlConfigStorage, TtlConfigurable, DEFAULT_INSTANCE_TTL, DEFAULT_PERSISTENT_TTL,
|
|
6
|
+
MAX_TTL,
|
|
7
|
+
};
|
|
8
|
+
use soroban_sdk::{contract, contractimpl, Address, Env};
|
|
9
|
+
|
|
10
|
+
// ============================================
|
|
11
|
+
// Test Contract for TTL functionality
|
|
12
|
+
// ============================================
|
|
13
|
+
|
|
14
|
+
#[contract]
|
|
15
|
+
pub struct TtlTestContract;
|
|
16
|
+
|
|
17
|
+
#[contractimpl]
|
|
18
|
+
impl TtlTestContract {
|
|
19
|
+
// TtlConfigStorage storage tests
|
|
20
|
+
pub fn frozen(env: &Env) -> bool {
|
|
21
|
+
TtlConfigStorage::frozen(env)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
pub fn set_frozen(env: &Env, value: bool) {
|
|
25
|
+
TtlConfigStorage::set_frozen(env, &value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
pub fn instance_ttl(env: &Env) -> TtlConfig {
|
|
29
|
+
TtlConfigStorage::instance(env).unwrap_or(DEFAULT_INSTANCE_TTL)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
pub fn set_instance_ttl(env: &Env, config: TtlConfig) {
|
|
33
|
+
TtlConfigStorage::set_instance(env, &config);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
pub fn has_instance_ttl(env: &Env) -> bool {
|
|
37
|
+
TtlConfigStorage::has_instance(env)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
pub fn remove_instance_ttl(env: &Env) {
|
|
41
|
+
TtlConfigStorage::remove_instance(env);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
pub fn remove_persistent_ttl(env: &Env) {
|
|
45
|
+
TtlConfigStorage::remove_persistent(env);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
pub fn persistent_ttl(env: &Env) -> TtlConfig {
|
|
49
|
+
TtlConfigStorage::persistent(env).unwrap_or(DEFAULT_PERSISTENT_TTL)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
pub fn set_persistent_ttl(env: &Env, config: TtlConfig) {
|
|
53
|
+
TtlConfigStorage::set_persistent(env, &config);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
pub fn has_persistent_ttl(env: &Env) -> bool {
|
|
57
|
+
TtlConfigStorage::has_persistent(env)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// DefaultTtlConfigurable tests
|
|
61
|
+
pub fn configurable_set_ttl_configs(env: &Env, instance: Option<TtlConfig>, persistent: Option<TtlConfig>) {
|
|
62
|
+
DefaultTtlConfigurable::set_ttl_configs(env, &instance, &persistent);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
pub fn configurable_ttl_configs(env: &Env) -> (Option<TtlConfig>, Option<TtlConfig>) {
|
|
66
|
+
DefaultTtlConfigurable::ttl_configs(env)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
pub fn configurable_freeze_ttl_configs(env: &Env) {
|
|
70
|
+
DefaultTtlConfigurable::freeze_ttl_configs(env);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
pub fn is_ttl_configs_frozen(env: &Env) -> bool {
|
|
74
|
+
DefaultTtlConfigurable::is_ttl_configs_frozen(env)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fn setup_contract() -> (Env, Address, TtlTestContractClient<'static>) {
|
|
79
|
+
let env = Env::default();
|
|
80
|
+
let contract_id = env.register(TtlTestContract, ());
|
|
81
|
+
let client = TtlTestContractClient::new(&env, &contract_id);
|
|
82
|
+
(env, contract_id, client)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ============================================
|
|
86
|
+
// TtlConfig Struct Tests
|
|
87
|
+
// ============================================
|
|
88
|
+
|
|
89
|
+
#[test]
|
|
90
|
+
fn test_ttl_config_new() {
|
|
91
|
+
let config = TtlConfig::new(100, 200);
|
|
92
|
+
assert_eq!(config.threshold, 100);
|
|
93
|
+
assert_eq!(config.extend_to, 200);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
#[test]
|
|
97
|
+
fn test_ttl_config_is_valid() {
|
|
98
|
+
// Valid configs
|
|
99
|
+
assert!(TtlConfig::new(100, 200).is_valid(300)); // threshold < extend_to < max
|
|
100
|
+
assert!(TtlConfig::new(100, 100).is_valid(200)); // threshold == extend_to
|
|
101
|
+
assert!(TtlConfig::new(100, 200).is_valid(200)); // extend_to == max
|
|
102
|
+
assert!(TtlConfig::new(100, 100).is_valid(100)); // all equal
|
|
103
|
+
assert!(TtlConfig::new(0, 0).is_valid(0)); // all zeros
|
|
104
|
+
assert!(TtlConfig::new(0, 0).is_valid(100)); // zero config with non-zero max
|
|
105
|
+
assert!(TtlConfig::new(0, 100).is_valid(100)); // threshold at minimum
|
|
106
|
+
assert!(TtlConfig::new(99, 100).is_valid(100)); // threshold just below extend_to
|
|
107
|
+
assert!(TtlConfig::new(MAX_TTL - 1, MAX_TTL).is_valid(MAX_TTL)); // large values
|
|
108
|
+
assert!(TtlConfig::new(MAX_TTL, MAX_TTL).is_valid(MAX_TTL)); // max values
|
|
109
|
+
|
|
110
|
+
// Invalid configs
|
|
111
|
+
assert!(!TtlConfig::new(200, 100).is_valid(300)); // threshold > extend_to
|
|
112
|
+
assert!(!TtlConfig::new(100, 400).is_valid(300)); // extend_to > max
|
|
113
|
+
assert!(!TtlConfig::new(100, 100).is_valid(99)); // extend_to > max
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#[test]
|
|
117
|
+
fn test_default_ttl_configs_are_valid() {
|
|
118
|
+
assert!(DEFAULT_INSTANCE_TTL.is_valid(MAX_TTL));
|
|
119
|
+
assert!(DEFAULT_PERSISTENT_TTL.is_valid(MAX_TTL));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ============================================
|
|
123
|
+
// TtlConfigStorage Storage Tests
|
|
124
|
+
// ============================================
|
|
125
|
+
|
|
126
|
+
#[test]
|
|
127
|
+
fn test_ttl_config_data_defaults() {
|
|
128
|
+
let (_, _, client) = setup_contract();
|
|
129
|
+
|
|
130
|
+
// Default frozen state should be false
|
|
131
|
+
assert!(!client.frozen());
|
|
132
|
+
|
|
133
|
+
// Default TTLs should be returned when not set
|
|
134
|
+
assert_eq!(client.instance_ttl(), DEFAULT_INSTANCE_TTL);
|
|
135
|
+
assert_eq!(client.persistent_ttl(), DEFAULT_PERSISTENT_TTL);
|
|
136
|
+
|
|
137
|
+
// has_* should return false initially
|
|
138
|
+
assert!(!client.has_instance_ttl());
|
|
139
|
+
assert!(!client.has_persistent_ttl());
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
#[test]
|
|
143
|
+
fn test_ttl_config_data_set_get_remove() {
|
|
144
|
+
let (_, _, client) = setup_contract();
|
|
145
|
+
|
|
146
|
+
let instance_cfg = TtlConfig::new(1000, 2000);
|
|
147
|
+
let persistent_cfg = TtlConfig::new(3000, 4000);
|
|
148
|
+
|
|
149
|
+
// Set and verify instance
|
|
150
|
+
client.set_instance_ttl(&instance_cfg);
|
|
151
|
+
assert!(client.has_instance_ttl());
|
|
152
|
+
assert_eq!(client.instance_ttl(), instance_cfg);
|
|
153
|
+
|
|
154
|
+
// Set and verify persistent
|
|
155
|
+
client.set_persistent_ttl(&persistent_cfg);
|
|
156
|
+
assert!(client.has_persistent_ttl());
|
|
157
|
+
assert_eq!(client.persistent_ttl(), persistent_cfg);
|
|
158
|
+
|
|
159
|
+
// Remove and verify defaults return
|
|
160
|
+
client.remove_instance_ttl();
|
|
161
|
+
assert!(!client.has_instance_ttl());
|
|
162
|
+
assert_eq!(client.instance_ttl(), DEFAULT_INSTANCE_TTL);
|
|
163
|
+
|
|
164
|
+
// Remove persistent
|
|
165
|
+
client.remove_persistent_ttl();
|
|
166
|
+
assert!(!client.has_persistent_ttl());
|
|
167
|
+
assert_eq!(client.persistent_ttl(), DEFAULT_PERSISTENT_TTL);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
#[test]
|
|
171
|
+
fn test_ttl_config_data_frozen() {
|
|
172
|
+
let (_, _, client) = setup_contract();
|
|
173
|
+
|
|
174
|
+
assert!(!client.frozen());
|
|
175
|
+
|
|
176
|
+
client.set_frozen(&true);
|
|
177
|
+
assert!(client.frozen());
|
|
178
|
+
|
|
179
|
+
client.set_frozen(&false);
|
|
180
|
+
assert!(!client.frozen());
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
#[test]
|
|
184
|
+
fn test_ttl_config_data_independent_storage() {
|
|
185
|
+
let (_, _, client) = setup_contract();
|
|
186
|
+
|
|
187
|
+
let instance_cfg = TtlConfig::new(100, 200);
|
|
188
|
+
let persistent_cfg = TtlConfig::new(300, 400);
|
|
189
|
+
|
|
190
|
+
// Set each independently and verify others unchanged
|
|
191
|
+
client.set_instance_ttl(&instance_cfg);
|
|
192
|
+
assert_eq!(client.instance_ttl(), instance_cfg);
|
|
193
|
+
assert_eq!(client.persistent_ttl(), DEFAULT_PERSISTENT_TTL);
|
|
194
|
+
|
|
195
|
+
client.set_persistent_ttl(&persistent_cfg);
|
|
196
|
+
assert_eq!(client.instance_ttl(), instance_cfg);
|
|
197
|
+
assert_eq!(client.persistent_ttl(), persistent_cfg);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
#[test]
|
|
201
|
+
fn test_ttl_config_data_remove_all() {
|
|
202
|
+
let (_, _, client) = setup_contract();
|
|
203
|
+
|
|
204
|
+
let instance_cfg = TtlConfig::new(1000, 2000);
|
|
205
|
+
let persistent_cfg = TtlConfig::new(3000, 4000);
|
|
206
|
+
|
|
207
|
+
// Set all configs
|
|
208
|
+
client.set_instance_ttl(&instance_cfg);
|
|
209
|
+
client.set_persistent_ttl(&persistent_cfg);
|
|
210
|
+
|
|
211
|
+
// Verify all are set
|
|
212
|
+
assert!(client.has_instance_ttl());
|
|
213
|
+
assert!(client.has_persistent_ttl());
|
|
214
|
+
|
|
215
|
+
// Remove all
|
|
216
|
+
client.remove_instance_ttl();
|
|
217
|
+
client.remove_persistent_ttl();
|
|
218
|
+
|
|
219
|
+
// Verify all return to defaults
|
|
220
|
+
assert!(!client.has_instance_ttl());
|
|
221
|
+
assert!(!client.has_persistent_ttl());
|
|
222
|
+
assert_eq!(client.instance_ttl(), DEFAULT_INSTANCE_TTL);
|
|
223
|
+
assert_eq!(client.persistent_ttl(), DEFAULT_PERSISTENT_TTL);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
#[test]
|
|
227
|
+
fn test_ttl_config_data_remove_when_not_set() {
|
|
228
|
+
let (_, _, client) = setup_contract();
|
|
229
|
+
|
|
230
|
+
// Removing when not set should not panic
|
|
231
|
+
client.remove_instance_ttl();
|
|
232
|
+
client.remove_persistent_ttl();
|
|
233
|
+
|
|
234
|
+
// Should still return defaults
|
|
235
|
+
assert_eq!(client.instance_ttl(), DEFAULT_INSTANCE_TTL);
|
|
236
|
+
assert_eq!(client.persistent_ttl(), DEFAULT_PERSISTENT_TTL);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// ============================================
|
|
240
|
+
// DefaultTtlConfigurable Tests - Basic Operations
|
|
241
|
+
// ============================================
|
|
242
|
+
|
|
243
|
+
#[test]
|
|
244
|
+
fn test_default_ttl_configurable_initial_state() {
|
|
245
|
+
let (_, _, client) = setup_contract();
|
|
246
|
+
|
|
247
|
+
let (instance, persistent) = client.configurable_ttl_configs();
|
|
248
|
+
assert!(instance.is_none());
|
|
249
|
+
assert!(persistent.is_none());
|
|
250
|
+
|
|
251
|
+
assert!(!client.is_ttl_configs_frozen());
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
#[test]
|
|
255
|
+
fn test_default_ttl_configurable_set_all() {
|
|
256
|
+
let (_, _, client) = setup_contract();
|
|
257
|
+
|
|
258
|
+
let instance_cfg = TtlConfig::new(1000, 2000);
|
|
259
|
+
let persistent_cfg = TtlConfig::new(3000, 4000);
|
|
260
|
+
|
|
261
|
+
client.configurable_set_ttl_configs(&Some(instance_cfg), &Some(persistent_cfg));
|
|
262
|
+
|
|
263
|
+
let (instance, persistent) = client.configurable_ttl_configs();
|
|
264
|
+
assert_eq!(instance, Some(instance_cfg));
|
|
265
|
+
assert_eq!(persistent, Some(persistent_cfg));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
#[test]
|
|
269
|
+
fn test_default_ttl_configurable_set_partial() {
|
|
270
|
+
let (_, _, client) = setup_contract();
|
|
271
|
+
|
|
272
|
+
let instance_cfg = TtlConfig::new(1000, 2000);
|
|
273
|
+
|
|
274
|
+
// Only set instance config
|
|
275
|
+
client.configurable_set_ttl_configs(&Some(instance_cfg), &None);
|
|
276
|
+
|
|
277
|
+
let (instance, persistent) = client.configurable_ttl_configs();
|
|
278
|
+
assert_eq!(instance, Some(instance_cfg));
|
|
279
|
+
assert!(persistent.is_none());
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
#[test]
|
|
283
|
+
fn test_default_ttl_configurable_set_and_remove() {
|
|
284
|
+
let (_, _, client) = setup_contract();
|
|
285
|
+
|
|
286
|
+
let instance_cfg = TtlConfig::new(1000, 2000);
|
|
287
|
+
|
|
288
|
+
// Set config
|
|
289
|
+
client.configurable_set_ttl_configs(&Some(instance_cfg), &None);
|
|
290
|
+
assert_eq!(client.configurable_ttl_configs().0, Some(instance_cfg));
|
|
291
|
+
|
|
292
|
+
// Remove by passing None
|
|
293
|
+
client.configurable_set_ttl_configs(&None, &None);
|
|
294
|
+
assert!(client.configurable_ttl_configs().0.is_none());
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// ============================================
|
|
298
|
+
// DefaultTtlConfigurable Tests - Freeze Operations
|
|
299
|
+
// ============================================
|
|
300
|
+
|
|
301
|
+
#[test]
|
|
302
|
+
fn test_default_ttl_configurable_freeze() {
|
|
303
|
+
let (_, _, client) = setup_contract();
|
|
304
|
+
|
|
305
|
+
assert!(!client.is_ttl_configs_frozen());
|
|
306
|
+
client.configurable_freeze_ttl_configs();
|
|
307
|
+
assert!(client.is_ttl_configs_frozen());
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
#[test]
|
|
311
|
+
#[should_panic(expected = "Error(Contract, #1201)")]
|
|
312
|
+
fn test_default_ttl_configurable_set_when_frozen() {
|
|
313
|
+
let (_, _, client) = setup_contract();
|
|
314
|
+
|
|
315
|
+
client.configurable_freeze_ttl_configs();
|
|
316
|
+
|
|
317
|
+
let instance_cfg = TtlConfig::new(1000, 2000);
|
|
318
|
+
client.configurable_set_ttl_configs(&Some(instance_cfg), &None);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
#[test]
|
|
322
|
+
#[should_panic(expected = "Error(Contract, #1202)")]
|
|
323
|
+
fn test_default_ttl_configurable_freeze_when_already_frozen() {
|
|
324
|
+
let (_, _, client) = setup_contract();
|
|
325
|
+
|
|
326
|
+
client.configurable_freeze_ttl_configs();
|
|
327
|
+
client.configurable_freeze_ttl_configs();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// ============================================
|
|
331
|
+
// DefaultTtlConfigurable Tests - Validation
|
|
332
|
+
// ============================================
|
|
333
|
+
|
|
334
|
+
#[test]
|
|
335
|
+
#[should_panic(expected = "Error(Contract, #1200)")]
|
|
336
|
+
fn test_default_ttl_configurable_invalid_instance_config() {
|
|
337
|
+
let (_, _, client) = setup_contract();
|
|
338
|
+
// threshold > extend_to is invalid
|
|
339
|
+
let invalid_cfg = TtlConfig::new(3000, 2000);
|
|
340
|
+
client.configurable_set_ttl_configs(&Some(invalid_cfg), &None);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
#[test]
|
|
344
|
+
#[should_panic(expected = "Error(Contract, #1200)")]
|
|
345
|
+
fn test_default_ttl_configurable_invalid_persistent_config() {
|
|
346
|
+
let (_, _, client) = setup_contract();
|
|
347
|
+
let invalid_cfg = TtlConfig::new(5000, 4000);
|
|
348
|
+
client.configurable_set_ttl_configs(&None, &Some(invalid_cfg));
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
#[test]
|
|
352
|
+
#[should_panic(expected = "Error(Contract, #1200)")]
|
|
353
|
+
fn test_default_ttl_configurable_exceeds_max_ttl() {
|
|
354
|
+
let (_, _, client) = setup_contract();
|
|
355
|
+
let invalid_cfg = TtlConfig::new(1000, MAX_TTL + 1);
|
|
356
|
+
client.configurable_set_ttl_configs(&Some(invalid_cfg), &None);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
#[test]
|
|
360
|
+
fn test_default_ttl_configurable_invalid_does_not_partially_update() {
|
|
361
|
+
let (_, _, client) = setup_contract();
|
|
362
|
+
|
|
363
|
+
// Seed with an initial valid state.
|
|
364
|
+
let before_instance = TtlConfig::new(1000, 2000);
|
|
365
|
+
let before_persistent = TtlConfig::new(3000, 4000);
|
|
366
|
+
client.configurable_set_ttl_configs(&Some(before_instance), &Some(before_persistent));
|
|
367
|
+
assert_eq!(client.configurable_ttl_configs(), (Some(before_instance), Some(before_persistent)));
|
|
368
|
+
|
|
369
|
+
// Attempt to update with one invalid config and one different valid config.
|
|
370
|
+
// This must fail and must not partially apply any changes.
|
|
371
|
+
let invalid_instance = TtlConfig::new(3000, 2000); // threshold > extend_to
|
|
372
|
+
let next_persistent = TtlConfig::new(3100, 4100);
|
|
373
|
+
assert_eq!(
|
|
374
|
+
client.try_configurable_set_ttl_configs(&Some(invalid_instance), &Some(next_persistent)).unwrap_err().unwrap(),
|
|
375
|
+
TtlError::InvalidTtlConfig.into()
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
// Ensure nothing changed.
|
|
379
|
+
assert_eq!(client.configurable_ttl_configs(), (Some(before_instance), Some(before_persistent)));
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// ============================================
|
|
383
|
+
// DefaultTtlConfigurable Tests - Boundary Values
|
|
384
|
+
// ============================================
|
|
385
|
+
|
|
386
|
+
#[test]
|
|
387
|
+
fn test_default_ttl_configurable_at_max_ttl() {
|
|
388
|
+
let (env, _, client) = setup_contract();
|
|
389
|
+
|
|
390
|
+
// Get the effective max TTL
|
|
391
|
+
let effective_max = u32::min(MAX_TTL, env.storage().max_ttl());
|
|
392
|
+
|
|
393
|
+
// extend_to == effective_max should be valid
|
|
394
|
+
let valid_cfg = TtlConfig::new(1000, effective_max);
|
|
395
|
+
client.configurable_set_ttl_configs(&Some(valid_cfg), &None);
|
|
396
|
+
|
|
397
|
+
let (instance, _) = client.configurable_ttl_configs();
|
|
398
|
+
assert_eq!(instance, Some(valid_cfg));
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
#[test]
|
|
402
|
+
fn test_default_ttl_configurable_boundary_values() {
|
|
403
|
+
let (env, _, client) = setup_contract();
|
|
404
|
+
|
|
405
|
+
let effective_max = u32::min(MAX_TTL, env.storage().max_ttl());
|
|
406
|
+
|
|
407
|
+
// Zero threshold and extend_to
|
|
408
|
+
let cfg = TtlConfig::new(0, 0);
|
|
409
|
+
client.configurable_set_ttl_configs(&Some(cfg), &None);
|
|
410
|
+
assert_eq!(client.configurable_ttl_configs().0, Some(cfg));
|
|
411
|
+
|
|
412
|
+
// Zero threshold, max extend_to
|
|
413
|
+
let cfg = TtlConfig::new(0, effective_max);
|
|
414
|
+
client.configurable_set_ttl_configs(&Some(cfg), &None);
|
|
415
|
+
assert_eq!(client.configurable_ttl_configs().0, Some(cfg));
|
|
416
|
+
|
|
417
|
+
// Equal threshold and extend_to
|
|
418
|
+
let cfg = TtlConfig::new(1000, 1000);
|
|
419
|
+
client.configurable_set_ttl_configs(&Some(cfg), &None);
|
|
420
|
+
assert_eq!(client.configurable_ttl_configs().0, Some(cfg));
|
|
421
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
use crate as utils;
|
|
2
1
|
use crate::errors::TtlError;
|
|
3
|
-
use soroban_sdk::{assert_with_error, contracttype, Env};
|
|
2
|
+
use soroban_sdk::{assert_with_error, contractclient, contracttype, Env};
|
|
4
3
|
|
|
5
4
|
/// Number of ledgers per day (~5 second ledger close time).
|
|
6
5
|
pub const LEDGERS_PER_DAY: u32 = (24 * 3600) / 5;
|
|
@@ -16,8 +15,6 @@ pub const MAX_TTL: u32 = 365 * LEDGERS_PER_DAY;
|
|
|
16
15
|
pub const DEFAULT_INSTANCE_TTL: TtlConfig = TtlConfig::new(29 * LEDGERS_PER_DAY, 30 * LEDGERS_PER_DAY);
|
|
17
16
|
/// Default TTL for persistent storage (30 days, extends at 29 days remaining).
|
|
18
17
|
pub const DEFAULT_PERSISTENT_TTL: TtlConfig = TtlConfig::new(29 * LEDGERS_PER_DAY, 30 * LEDGERS_PER_DAY);
|
|
19
|
-
/// Default TTL for temporary storage (7 days, extends at 6 days remaining).
|
|
20
|
-
pub const DEFAULT_TEMPORARY_TTL: TtlConfig = TtlConfig::new(6 * LEDGERS_PER_DAY, 7 * LEDGERS_PER_DAY);
|
|
21
18
|
|
|
22
19
|
/// A pair of TTL values: threshold (when to trigger extension) and extend_to (target TTL).
|
|
23
20
|
#[contracttype]
|
|
@@ -42,8 +39,12 @@ impl TtlConfig {
|
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
/// Storage keys for TTL configuration.
|
|
42
|
+
///
|
|
43
|
+
/// Note: These instance storage entries do NOT have automatic TTL extension enabled to avoid
|
|
44
|
+
/// infinite recursion--extending TTL config storage would require reading the TTL config,
|
|
45
|
+
/// which would trigger another extension, creating a deep loop.
|
|
45
46
|
#[common_macros::storage]
|
|
46
|
-
pub enum
|
|
47
|
+
pub enum TtlConfigStorage {
|
|
47
48
|
#[instance(bool)]
|
|
48
49
|
#[default(false)]
|
|
49
50
|
Frozen,
|
|
@@ -53,111 +54,50 @@ pub enum TtlConfigData {
|
|
|
53
54
|
|
|
54
55
|
#[instance(TtlConfig)]
|
|
55
56
|
Persistent,
|
|
56
|
-
|
|
57
|
-
#[instance(TtlConfig)]
|
|
58
|
-
Temporary,
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/// Trait for providing TTL configurations.
|
|
62
|
-
pub trait TtlConfigProvider {
|
|
63
|
-
fn persistent(env: &Env) -> TtlConfig;
|
|
64
|
-
fn instance(env: &Env) -> TtlConfig;
|
|
65
|
-
fn temporary(env: &Env) -> TtlConfig;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/// Helper functions used by the `#[storage]` macro to enforce that a user-provided
|
|
69
|
-
/// TTL config provider implements the [`TtlConfigProvider`] trait.
|
|
70
|
-
///
|
|
71
|
-
/// The macro generates code that calls these functions with the provider type as
|
|
72
|
-
/// the generic parameter `T`. If the provider does not implement `TtlConfigProvider`,
|
|
73
|
-
/// the compiler will emit an error at the macro expansion site, ensuring type safety
|
|
74
|
-
/// at compile time.
|
|
75
|
-
pub mod ttl_config {
|
|
76
|
-
use super::{TtlConfig, TtlConfigProvider};
|
|
77
|
-
use soroban_sdk::Env;
|
|
78
|
-
|
|
79
|
-
pub fn instance<T: TtlConfigProvider>(env: &Env) -> TtlConfig {
|
|
80
|
-
T::instance(env)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
pub fn persistent<T: TtlConfigProvider>(env: &Env) -> TtlConfig {
|
|
84
|
-
T::persistent(env)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
pub fn temporary<T: TtlConfigProvider>(env: &Env) -> TtlConfig {
|
|
88
|
-
T::temporary(env)
|
|
89
|
-
}
|
|
90
57
|
}
|
|
91
58
|
|
|
92
|
-
///
|
|
93
|
-
|
|
59
|
+
/// Trait for contracts that allow TTL configuration management.
|
|
60
|
+
#[contractclient(name = "TtlConfigurableClient")]
|
|
61
|
+
pub trait TtlConfigurable {
|
|
62
|
+
/// Sets TTL configs. None values remove the config.
|
|
63
|
+
fn set_ttl_configs(env: &Env, instance: &Option<TtlConfig>, persistent: &Option<TtlConfig>);
|
|
94
64
|
|
|
95
|
-
|
|
96
|
-
fn
|
|
97
|
-
TtlConfigData::instance(env).unwrap_or(DEFAULT_INSTANCE_TTL)
|
|
98
|
-
}
|
|
65
|
+
/// Returns current TTL configs (instance, persistent).
|
|
66
|
+
fn ttl_configs(env: &Env) -> (Option<TtlConfig>, Option<TtlConfig>);
|
|
99
67
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
68
|
+
/// Permanently freezes TTL configs, preventing further changes.
|
|
69
|
+
fn freeze_ttl_configs(env: &Env);
|
|
103
70
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/// Trait for contracts that allow TTL configuration management.
|
|
110
|
-
pub trait TtlConfigurable {
|
|
111
|
-
/// Sets TTL configs. None values remove the config (use defaults).
|
|
112
|
-
fn set_ttl_config(
|
|
113
|
-
env: &Env,
|
|
114
|
-
instance: &Option<TtlConfig>,
|
|
115
|
-
persistent: &Option<TtlConfig>,
|
|
116
|
-
temporary: &Option<TtlConfig>,
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
/// Returns current TTL configs (instance, persistent, temporary).
|
|
120
|
-
fn ttl_config(env: &Env) -> (Option<TtlConfig>, Option<TtlConfig>, Option<TtlConfig>);
|
|
121
|
-
|
|
122
|
-
/// Permanently freezes TTL config, preventing further changes.
|
|
123
|
-
fn freeze_ttl_config(env: &Env);
|
|
124
|
-
|
|
125
|
-
/// Returns whether TTL config is frozen.
|
|
126
|
-
fn is_ttl_config_frozen(env: &Env) -> bool;
|
|
71
|
+
/// Returns whether TTL configs are frozen.
|
|
72
|
+
fn is_ttl_configs_frozen(env: &Env) -> bool;
|
|
127
73
|
}
|
|
128
74
|
|
|
129
75
|
/// Default implementation of TtlConfigurable.
|
|
130
76
|
pub struct DefaultTtlConfigurable;
|
|
131
77
|
|
|
132
78
|
impl TtlConfigurable for DefaultTtlConfigurable {
|
|
133
|
-
fn
|
|
134
|
-
env
|
|
135
|
-
instance: &Option<TtlConfig>,
|
|
136
|
-
persistent: &Option<TtlConfig>,
|
|
137
|
-
temporary: &Option<TtlConfig>,
|
|
138
|
-
) {
|
|
139
|
-
assert_with_error!(env, !Self::is_ttl_config_frozen(env), TtlError::TtlConfigFrozen);
|
|
79
|
+
fn set_ttl_configs(env: &Env, instance: &Option<TtlConfig>, persistent: &Option<TtlConfig>) {
|
|
80
|
+
assert_with_error!(env, !Self::is_ttl_configs_frozen(env), TtlError::TtlConfigFrozen);
|
|
140
81
|
|
|
141
82
|
let max_ttl = u32::min(MAX_TTL, env.storage().max_ttl());
|
|
142
|
-
let all_valid = [instance, persistent
|
|
83
|
+
let all_valid = [instance, persistent].iter().all(|c| c.is_none_or(|cfg| cfg.is_valid(max_ttl)));
|
|
143
84
|
assert_with_error!(env, all_valid, TtlError::InvalidTtlConfig);
|
|
144
85
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
TtlConfigData::set_or_remove_temporary(env, temporary);
|
|
86
|
+
TtlConfigStorage::set_or_remove_instance(env, instance);
|
|
87
|
+
TtlConfigStorage::set_or_remove_persistent(env, persistent);
|
|
148
88
|
}
|
|
149
89
|
|
|
150
|
-
fn
|
|
151
|
-
(
|
|
90
|
+
fn ttl_configs(env: &Env) -> (Option<TtlConfig>, Option<TtlConfig>) {
|
|
91
|
+
(TtlConfigStorage::instance(env), TtlConfigStorage::persistent(env))
|
|
152
92
|
}
|
|
153
93
|
|
|
154
|
-
fn
|
|
155
|
-
assert_with_error!(env, !Self::
|
|
156
|
-
|
|
94
|
+
fn freeze_ttl_configs(env: &Env) {
|
|
95
|
+
assert_with_error!(env, !Self::is_ttl_configs_frozen(env), TtlError::TtlConfigAlreadyFrozen);
|
|
96
|
+
TtlConfigStorage::set_frozen(env, &true);
|
|
157
97
|
}
|
|
158
98
|
|
|
159
|
-
fn
|
|
160
|
-
|
|
99
|
+
fn is_ttl_configs_frozen(env: &Env) -> bool {
|
|
100
|
+
TtlConfigStorage::frozen(env)
|
|
161
101
|
}
|
|
162
102
|
}
|
|
163
103
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "dvn"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
license.workspace = true
|
|
6
|
+
publish = false
|
|
7
|
+
|
|
8
|
+
[features]
|
|
9
|
+
library = []
|
|
10
|
+
testutils = []
|
|
11
|
+
|
|
12
|
+
[lib]
|
|
13
|
+
crate-type = ["cdylib"]
|
|
14
|
+
doctest = false
|
|
15
|
+
|
|
16
|
+
[dependencies]
|
|
17
|
+
cfg-if = "1.0"
|
|
18
|
+
soroban-sdk = { workspace = true, features = ["hazmat-crypto"] }
|
|
19
|
+
worker = { workspace = true }
|
|
20
|
+
message-lib-common = { workspace = true }
|
|
21
|
+
utils = { workspace = true }
|
|
22
|
+
common-macros = { workspace = true }
|
|
23
|
+
endpoint-v2 = { workspace = true }
|
|
24
|
+
|
|
25
|
+
[dev-dependencies]
|
|
26
|
+
soroban-sdk = { workspace = true, features = ["testutils"] }
|
|
27
|
+
insta = { workspace = true }
|
|
28
|
+
k256 = "0.13"
|
|
29
|
+
sha3 = "0.10"
|
|
30
|
+
rand = "0.8"
|
|
31
|
+
ed25519-dalek = "2"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
use crate::TransactionAuthData;
|
|
2
|
+
use soroban_sdk::{
|
|
3
|
+
address_payload::AddressPayload,
|
|
4
|
+
auth::{Context, CustomAccountInterface},
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
#[contractimpl]
|
|
8
|
+
impl CustomAccountInterface for Dvn {
|
|
9
|
+
type Signature = TransactionAuthData;
|
|
10
|
+
type Error = DvnError;
|
|
11
|
+
|
|
12
|
+
#[allow(non_snake_case)]
|
|
13
|
+
fn __check_auth(
|
|
14
|
+
env: Env,
|
|
15
|
+
signature_payload: Hash<32>,
|
|
16
|
+
auth_data: Self::Signature,
|
|
17
|
+
auth_contexts: Vec<Context>,
|
|
18
|
+
) -> Result<(), Self::Error> {
|
|
19
|
+
let TransactionAuthData { vid, expiration, signatures, admin, admin_signature } = auth_data;
|
|
20
|
+
|
|
21
|
+
verify_admin(&env, &admin, &admin_signature, &signature_payload)?;
|
|
22
|
+
|
|
23
|
+
let stored_vid = DvnStorage::vid(&env).unwrap();
|
|
24
|
+
if vid != stored_vid {
|
|
25
|
+
return Err(DvnError::InvalidVid);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if expiration <= env.ledger().timestamp() {
|
|
29
|
+
return Err(DvnError::AuthDataExpired);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let hash = hash_auth_data(&env, vid, expiration, &auth_contexts);
|
|
33
|
+
|
|
34
|
+
if DvnStorage::used_hash(&env, &hash) {
|
|
35
|
+
return Err(DvnError::HashAlreadyUsed);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
Dvn::verify_signatures(&env, &hash, &signatures);
|
|
39
|
+
|
|
40
|
+
DvnStorage::set_used_hash(&env, &hash, &true);
|
|
41
|
+
|
|
42
|
+
Ok(())
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fn verify_admin(
|
|
47
|
+
env: &Env,
|
|
48
|
+
admin: &BytesN<32>,
|
|
49
|
+
admin_signature: &BytesN<64>,
|
|
50
|
+
signature_payload: &Hash<32>,
|
|
51
|
+
) -> Result<(), DvnError> {
|
|
52
|
+
let admin_address = Address::from_payload(env, AddressPayload::AccountIdPublicKeyEd25519(admin.clone()));
|
|
53
|
+
if !Dvn::is_admin(env, &admin_address) {
|
|
54
|
+
return Err(DvnError::OnlyAdmin);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
env.crypto().ed25519_verify(admin, &signature_payload.clone().into(), admin_signature);
|
|
58
|
+
|
|
59
|
+
Ok(())
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fn hash_auth_data(env: &Env, vid: u32, expiration: u64, auth_contexts: &Vec<Context>) -> BytesN<32> {
|
|
63
|
+
let mut writer = BufferWriter::new(env);
|
|
64
|
+
let data = writer.write_u32(vid).write_u64(expiration).write_bytes(&auth_contexts.to_xdr(env)).to_bytes();
|
|
65
|
+
env.crypto().keccak256(&data).into()
|
|
66
|
+
}
|