radix_engine_interface/api/
key_value_store_api.rs

1use radix_common::prelude::{
2    replace_self_package_address, ScryptoCustomTypeKind, ScryptoDescribe, VersionedScryptoSchema,
3};
4use radix_common::types::*;
5use radix_common::{ManifestSbor, ScryptoSbor};
6use radix_engine_interface::api::key_value_entry_api::KeyValueEntryHandle;
7use radix_engine_interface::api::LockFlags;
8use sbor::rust::prelude::*;
9use sbor::LocalTypeId;
10use sbor::{generate_full_schema, TypeAggregator};
11
12pub const KV_STORE_DATA_SCHEMA_VARIANT_LOCAL: u8 = 0;
13pub const KV_STORE_DATA_SCHEMA_VARIANT_REMOTE: u8 = 1;
14
15/// Less flexible than previous revision, as mixed type origin is not allowed, but
16/// better for client-side optimization
17#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor, ManifestSbor)]
18pub enum KeyValueStoreDataSchema {
19    // TODO: ignore this variant in Scrypto for smaller code size
20    Local {
21        additional_schema: VersionedScryptoSchema,
22        key_type: LocalTypeId,
23        value_type: LocalTypeId,
24        allow_ownership: bool,
25    },
26    Remote {
27        key_type: BlueprintTypeIdentifier,
28        value_type: BlueprintTypeIdentifier,
29        allow_ownership: bool,
30    },
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor, ManifestSbor)]
34pub struct LocalKeyValueStoreDataSchema {
35    pub additional_schema: VersionedScryptoSchema,
36    pub key_type: LocalTypeId,
37    pub value_type: LocalTypeId,
38    pub allow_ownership: bool,
39}
40
41#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor, ManifestSbor)]
42pub struct RemoteKeyValueStoreDataSchema {
43    pub key_type: BlueprintTypeIdentifier,
44    pub value_type: BlueprintTypeIdentifier,
45    pub allow_ownership: bool,
46}
47
48impl LocalKeyValueStoreDataSchema {
49    pub fn new_with_self_package_replacement<K: ScryptoDescribe, V: ScryptoDescribe>(
50        package_address: PackageAddress,
51        allow_ownership: bool,
52    ) -> Self {
53        let mut aggregator = TypeAggregator::<ScryptoCustomTypeKind>::new();
54        let key_type_id = aggregator.add_child_type_and_descendents::<K>();
55        let value_type_id = aggregator.add_child_type_and_descendents::<V>();
56        let mut schema = generate_full_schema(aggregator);
57        replace_self_package_address(&mut schema, package_address);
58        Self {
59            additional_schema: schema,
60            key_type: key_type_id,
61            value_type: value_type_id,
62            allow_ownership,
63        }
64    }
65
66    pub fn new_without_self_package_replacement<K: ScryptoDescribe, V: ScryptoDescribe>(
67        allow_ownership: bool,
68    ) -> Self {
69        let mut aggregator = TypeAggregator::<ScryptoCustomTypeKind>::new();
70        let key_type_id = aggregator.add_child_type_and_descendents::<K>();
71        let value_type_id = aggregator.add_child_type_and_descendents::<V>();
72        let schema = generate_full_schema(aggregator);
73        Self {
74            additional_schema: schema,
75            key_type: key_type_id,
76            value_type: value_type_id,
77            allow_ownership,
78        }
79    }
80}
81
82impl RemoteKeyValueStoreDataSchema {
83    pub fn new(
84        key_type: BlueprintTypeIdentifier,
85        value_type: BlueprintTypeIdentifier,
86        allow_ownership: bool,
87    ) -> Self {
88        Self {
89            key_type,
90            value_type,
91            allow_ownership,
92        }
93    }
94}
95
96impl KeyValueStoreDataSchema {
97    pub fn new_local_with_self_package_replacement<K: ScryptoDescribe, V: ScryptoDescribe>(
98        package_address: PackageAddress,
99        allow_ownership: bool,
100    ) -> Self {
101        let schema = LocalKeyValueStoreDataSchema::new_with_self_package_replacement::<K, V>(
102            package_address,
103            allow_ownership,
104        );
105        Self::Local {
106            additional_schema: schema.additional_schema,
107            key_type: schema.key_type,
108            value_type: schema.value_type,
109            allow_ownership: schema.allow_ownership,
110        }
111    }
112
113    pub fn new_local_without_self_package_replacement<K: ScryptoDescribe, V: ScryptoDescribe>(
114        allow_ownership: bool,
115    ) -> Self {
116        let schema = LocalKeyValueStoreDataSchema::new_without_self_package_replacement::<K, V>(
117            allow_ownership,
118        );
119        Self::Local {
120            additional_schema: schema.additional_schema,
121            key_type: schema.key_type,
122            value_type: schema.value_type,
123            allow_ownership: schema.allow_ownership,
124        }
125    }
126
127    pub fn new_remote(
128        key_type: BlueprintTypeIdentifier,
129        value_type: BlueprintTypeIdentifier,
130        allow_ownership: bool,
131    ) -> Self {
132        Self::Remote {
133            key_type,
134            value_type,
135            allow_ownership,
136        }
137    }
138}
139
140pub trait SystemKeyValueStoreApi<E> {
141    /// Creates a new key value store with a given schema
142    fn key_value_store_new(&mut self, data_schema: KeyValueStoreDataSchema) -> Result<NodeId, E>;
143
144    /// Open a key value store entry for reading/writing
145    fn key_value_store_open_entry(
146        &mut self,
147        node_id: &NodeId,
148        key: &Vec<u8>,
149        flags: LockFlags,
150    ) -> Result<KeyValueEntryHandle, E>;
151
152    /// Removes an entry from a key value store
153    fn key_value_store_remove_entry(
154        &mut self,
155        node_id: &NodeId,
156        key: &Vec<u8>,
157    ) -> Result<Vec<u8>, E>;
158}