oasis_runtime_sdk/
runtime.rs1use std::sync::Arc;
3
4use oasis_core_runtime::{
5 common::{sgx, version},
6 config::Config,
7 consensus::verifier::TrustRoot,
8 dispatcher::{PostInitState, PreInitState},
9 enclave_rpc::session,
10 start_runtime,
11 types::{FeatureScheduleControl, Features},
12};
13
14use crate::{
15 config,
16 context::Context,
17 crypto, dispatcher,
18 keymanager::{KeyManagerClient, TrustedSigners},
19 module::{
20 BlockHandler, FeeProxyHandler, InvariantHandler, MethodHandler, MigrationHandler,
21 ModuleInfoHandler, TransactionHandler,
22 },
23 modules,
24 state::CurrentState,
25 storage::{self},
26};
27
28pub trait Runtime {
30 const VERSION: version::Version;
32 const STATE_VERSION: u32 = 0;
34
35 const PREFETCH_LIMIT: u16 = 0;
37
38 const SCHEDULE_CONTROL: config::ScheduleControl = config::ScheduleControl::default();
40
41 const MAX_CHECK_NONCE_FUTURE_DELTA: u64 = 0;
44
45 type Core: modules::core::API;
47 type Accounts: modules::accounts::API;
49 type FeeProxy: FeeProxyHandler = ();
51
52 type Modules: TransactionHandler
54 + MigrationHandler
55 + MethodHandler
56 + BlockHandler
57 + InvariantHandler
58 + ModuleInfoHandler;
59
60 fn trusted_signers() -> Option<TrustedSigners> {
63 None
64 }
65
66 fn consensus_trust_root() -> Option<TrustRoot> {
69 None
70 }
71
72 fn genesis_state() -> <Self::Modules as MigrationHandler>::Genesis;
74
75 fn migrate_state<C: Context>(_ctx: &C) {
78 }
80
81 fn is_allowed_query(_method: &str) -> bool {
83 true
84 }
85
86 fn is_allowed_private_km_query(_method: &str) -> bool {
91 true
92 }
93
94 fn is_allowed_interactive_call(_method: &str) -> bool {
99 true
100 }
101
102 fn migrate<C: Context>(ctx: &C) {
104 let mut metadata = CurrentState::with_store(|store| {
105 let store = storage::TypedStore::new(storage::PrefixStore::new(
106 store,
107 &modules::core::MODULE_NAME,
108 ));
109 let metadata: modules::core::types::Metadata = store
110 .get(modules::core::state::METADATA)
111 .unwrap_or_default();
112
113 metadata
114 });
115
116 let mut has_changes =
118 Self::Modules::init_or_migrate(ctx, &mut metadata, Self::genesis_state());
119
120 let global_version = metadata
122 .versions
123 .get(modules::core::types::VERSION_GLOBAL_KEY)
124 .copied()
125 .unwrap_or_default();
126 if global_version != Self::STATE_VERSION
127 && !CurrentState::with_env(|env| env.is_check_only())
128 {
129 assert!(
130 global_version == 0 || global_version == Self::STATE_VERSION - 1,
132 "inconsistent existing state version (expected: {} got: {})",
133 Self::STATE_VERSION - 1,
134 global_version
135 );
136
137 Self::migrate_state(ctx);
138
139 metadata.versions.insert(
141 modules::core::types::VERSION_GLOBAL_KEY.to_string(),
142 Self::STATE_VERSION,
143 );
144 has_changes = true;
145 }
146
147 if has_changes {
149 CurrentState::with_store(|store| {
150 let mut store = storage::TypedStore::new(storage::PrefixStore::new(
151 store,
152 &modules::core::MODULE_NAME,
153 ));
154 store.insert(modules::core::state::METADATA, metadata);
155 });
156 }
157 }
158
159 fn start()
161 where
162 Self: Sized + Send + Sync + 'static,
163 {
164 let init = |state: PreInitState<'_>| -> PostInitState {
166 let hi = state.protocol.get_host_info();
168 crypto::signature::context::set_chain_context(
169 hi.runtime_id,
170 &hi.consensus_chain_context,
171 );
172
173 let key_manager = Self::trusted_signers().map(|signers| {
175 Arc::new(KeyManagerClient::new(
176 hi.runtime_id,
177 state.protocol.clone(),
178 state.consensus_verifier.clone(),
179 state.identity.clone(),
180 state.rpc_dispatcher,
181 4096,
182 signers,
183 ))
184 });
185
186 let dispatcher = dispatcher::Dispatcher::<Self>::new(
188 state.protocol.clone(),
189 key_manager,
190 state.consensus_verifier.clone(),
191 );
192 dispatcher.register_enclaverpc(state.rpc_dispatcher);
194 let session_builder = session::Builder::default()
197 .local_identity(state.identity.clone())
198 .quote_policy(Some(Arc::new(sgx::QuotePolicy {
199 ias: Some(sgx::ias::QuotePolicy {
200 disabled: true, ..Default::default()
202 }),
203 pcs: Some(sgx::pcs::QuotePolicy {
204 tdx: Some(sgx::pcs::TdxQuotePolicy {
206 allowed_tdx_modules: vec![],
207 }),
208 ..Default::default()
209 }),
210 })));
211 state.rpc_demux.set_session_builder(session_builder);
212
213 PostInitState {
214 txn_dispatcher: Some(Box::new(dispatcher)),
215 app: None,
216 }
217 };
218
219 let features = Features {
221 schedule_control: Some(FeatureScheduleControl {
222 initial_batch_size: Self::SCHEDULE_CONTROL.initial_batch_size,
223 }),
224 ..Default::default()
225 };
226
227 start_runtime(
229 Box::new(init),
230 Config {
231 version: Self::VERSION,
232 trust_root: Self::consensus_trust_root(),
233 features,
234 persist_check_tx_state: false,
235 ..Default::default()
236 },
237 );
238 }
239}