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 type Core: modules::core::API;
43 type Accounts: modules::accounts::API;
45 type FeeProxy: FeeProxyHandler = ();
47
48 type Modules: TransactionHandler
50 + MigrationHandler
51 + MethodHandler
52 + BlockHandler
53 + InvariantHandler
54 + ModuleInfoHandler;
55
56 fn trusted_signers() -> Option<TrustedSigners> {
59 None
60 }
61
62 fn consensus_trust_root() -> Option<TrustRoot> {
65 None
66 }
67
68 fn genesis_state() -> <Self::Modules as MigrationHandler>::Genesis;
70
71 fn migrate_state<C: Context>(_ctx: &C) {
74 }
76
77 fn is_allowed_query(_method: &str) -> bool {
79 true
80 }
81
82 fn is_allowed_private_km_query(_method: &str) -> bool {
87 true
88 }
89
90 fn is_allowed_interactive_call(_method: &str) -> bool {
95 true
96 }
97
98 fn migrate<C: Context>(ctx: &C) {
100 let mut metadata = CurrentState::with_store(|store| {
101 let store = storage::TypedStore::new(storage::PrefixStore::new(
102 store,
103 &modules::core::MODULE_NAME,
104 ));
105 let metadata: modules::core::types::Metadata = store
106 .get(modules::core::state::METADATA)
107 .unwrap_or_default();
108
109 metadata
110 });
111
112 let mut has_changes =
114 Self::Modules::init_or_migrate(ctx, &mut metadata, Self::genesis_state());
115
116 let global_version = metadata
118 .versions
119 .get(modules::core::types::VERSION_GLOBAL_KEY)
120 .copied()
121 .unwrap_or_default();
122 if global_version != Self::STATE_VERSION
123 && !CurrentState::with_env(|env| env.is_check_only())
124 {
125 assert!(
126 global_version == 0 || global_version == Self::STATE_VERSION - 1,
128 "inconsistent existing state version (expected: {} got: {})",
129 Self::STATE_VERSION - 1,
130 global_version
131 );
132
133 Self::migrate_state(ctx);
134
135 metadata.versions.insert(
137 modules::core::types::VERSION_GLOBAL_KEY.to_string(),
138 Self::STATE_VERSION,
139 );
140 has_changes = true;
141 }
142
143 if has_changes {
145 CurrentState::with_store(|store| {
146 let mut store = storage::TypedStore::new(storage::PrefixStore::new(
147 store,
148 &modules::core::MODULE_NAME,
149 ));
150 store.insert(modules::core::state::METADATA, metadata);
151 });
152 }
153 }
154
155 fn start()
157 where
158 Self: Sized + Send + Sync + 'static,
159 {
160 let init = |state: PreInitState<'_>| -> PostInitState {
162 let hi = state.protocol.get_host_info();
164 crypto::signature::context::set_chain_context(
165 hi.runtime_id,
166 &hi.consensus_chain_context,
167 );
168
169 let key_manager = Self::trusted_signers().map(|signers| {
171 Arc::new(KeyManagerClient::new(
172 hi.runtime_id,
173 state.protocol.clone(),
174 state.consensus_verifier.clone(),
175 state.identity.clone(),
176 state.rpc_dispatcher,
177 4096,
178 signers,
179 ))
180 });
181
182 let dispatcher = dispatcher::Dispatcher::<Self>::new(
184 state.protocol.clone(),
185 key_manager,
186 state.consensus_verifier.clone(),
187 );
188 dispatcher.register_enclaverpc(state.rpc_dispatcher);
190 let session_builder = session::Builder::default()
193 .local_identity(state.identity.clone())
194 .quote_policy(Some(Arc::new(sgx::QuotePolicy {
195 ias: Some(sgx::ias::QuotePolicy {
196 disabled: true, ..Default::default()
198 }),
199 pcs: Some(sgx::pcs::QuotePolicy {
200 tdx: Some(sgx::pcs::TdxQuotePolicy {
202 allowed_tdx_modules: vec![],
203 }),
204 ..Default::default()
205 }),
206 })));
207 state.rpc_demux.set_session_builder(session_builder);
208
209 PostInitState {
210 txn_dispatcher: Some(Box::new(dispatcher)),
211 app: None,
212 }
213 };
214
215 let features = Features {
217 schedule_control: Some(FeatureScheduleControl {
218 initial_batch_size: Self::SCHEDULE_CONTROL.initial_batch_size,
219 }),
220 ..Default::default()
221 };
222
223 start_runtime(
225 Box::new(init),
226 Config {
227 version: Self::VERSION,
228 trust_root: Self::consensus_trust_root(),
229 features,
230 persist_check_tx_state: false,
231 ..Default::default()
232 },
233 );
234 }
235}