@@ -43,6 +43,7 @@ impl Handler<CreateContextRequest> for ContextManager {
43
43
& self . context_client ,
44
44
& self . external_config ,
45
45
& mut self . contexts ,
46
+ & mut self . applications ,
46
47
protocol,
47
48
seed,
48
49
& application_id,
@@ -52,33 +53,48 @@ impl Handler<CreateContextRequest> for ContextManager {
52
53
Err ( err) => return ActorResponse :: reply ( Err ( err) ) ,
53
54
} ;
54
55
55
- let guard = prepared
56
- . context
56
+ let Prepared {
57
+ external_config,
58
+ application,
59
+ context,
60
+ context_secret,
61
+ identity,
62
+ identity_secret,
63
+ sender_key,
64
+ } = prepared;
65
+
66
+ let guard = context
57
67
. lock
58
68
. clone ( )
59
69
. try_lock_owned ( )
60
70
. expect ( "logically exclusive" ) ;
61
71
62
- let task = create_context (
63
- self . datastore . clone ( ) ,
64
- self . node_client . clone ( ) ,
65
- self . context_client . clone ( ) ,
66
- self . runtime_engine . clone ( ) ,
67
- prepared. external_config ,
68
- prepared. context . meta ,
69
- prepared. context_secret ,
70
- prepared. application ,
71
- prepared. identity ,
72
- prepared. identity_secret ,
73
- prepared. sender_key ,
74
- init_params,
75
- guard,
76
- ) ;
72
+ let context = context. meta ;
73
+
74
+ let module_task = self . get_module ( application_id) ;
77
75
78
76
ActorResponse :: r#async (
79
- task. into_actor ( self )
77
+ module_task
78
+ . and_then ( move |module, act, _ctx| {
79
+ create_context (
80
+ act. datastore . clone ( ) ,
81
+ act. node_client . clone ( ) ,
82
+ act. context_client . clone ( ) ,
83
+ module,
84
+ external_config,
85
+ context,
86
+ context_secret,
87
+ application,
88
+ identity,
89
+ identity_secret,
90
+ sender_key,
91
+ init_params,
92
+ guard,
93
+ )
94
+ . into_actor ( act)
95
+ } )
80
96
. map_ok ( move |root_hash, act, _ctx| {
81
- if let Some ( meta) = act. contexts . get_mut ( & prepared . context . meta . id ) {
97
+ if let Some ( meta) = act. contexts . get_mut ( & context. id ) {
82
98
// this should almost always exist, but with an LruCache, it
83
99
// may not. And if it's been evicted, the next execution will
84
100
// re-create it with data from the store, so it's not a problem
@@ -87,12 +103,12 @@ impl Handler<CreateContextRequest> for ContextManager {
87
103
}
88
104
89
105
CreateContextResponse {
90
- context_id : prepared . context . meta . id ,
91
- identity : prepared . identity ,
106
+ context_id : context. id ,
107
+ identity,
92
108
}
93
109
} )
94
110
. map_err ( move |err, act, _ctx| {
95
- let _ignored = act. contexts . remove ( & prepared . context . meta . id ) ;
111
+ let _ignored = act. contexts . remove ( & context. id ) ;
96
112
97
113
err
98
114
} ) ,
@@ -116,6 +132,7 @@ impl Prepared<'_> {
116
132
context_client : & ContextClient ,
117
133
external_config : & ExternalClientConfig ,
118
134
contexts : & mut BTreeMap < ContextId , ContextMeta > ,
135
+ applications : & mut BTreeMap < ApplicationId , Application > ,
119
136
protocol : String ,
120
137
seed : Option < [ u8 ; 32 ] > ,
121
138
application_id : & ApplicationId ,
@@ -185,24 +202,28 @@ impl Prepared<'_> {
185
202
. flatten ( )
186
203
. ok_or_eyre ( "failed to derive a context id after 5 tries" ) ?;
187
204
188
- let Some ( application) = node_client. get_application ( application_id) ? else {
189
- bail ! ( "application not found" ) ;
190
- } ;
205
+ let application = match applications. entry ( * application_id) {
206
+ btree_map:: Entry :: Vacant ( vacant) => {
207
+ let application = node_client
208
+ . get_application ( application_id) ?
209
+ . ok_or_eyre ( "application not found" ) ?;
191
210
192
- if !node_client. has_blob ( & application. blob ) ? {
193
- bail ! ( "application points to dangling blob" ) ;
194
- }
211
+ vacant. insert ( application)
212
+ }
213
+ btree_map:: Entry :: Occupied ( occupied) => occupied. into_mut ( ) ,
214
+ } ;
195
215
196
216
let identity = identity_secret. public_key ( ) ;
197
217
198
- let meta = Context :: new ( context_id, application . id , Hash :: default ( ) ) ;
218
+ let meta = Context :: new ( context_id, * application_id , Hash :: default ( ) ) ;
199
219
200
220
let context = entry. insert ( ContextMeta {
201
221
meta,
202
- blob : application. blob ,
203
222
lock : Arc :: new ( Mutex :: new ( context_id) ) ,
204
223
} ) ;
205
224
225
+ let application = application. clone ( ) ;
226
+
206
227
Ok ( Self {
207
228
external_config,
208
229
application,
@@ -219,7 +240,7 @@ async fn create_context(
219
240
datastore : Store ,
220
241
node_client : NodeClient ,
221
242
context_client : ContextClient ,
222
- engine : calimero_runtime:: Engine ,
243
+ module : calimero_runtime:: Module ,
223
244
external_config : ContextConfigParams < ' _ > ,
224
245
mut context : Context ,
225
246
context_secret : PrivateKey ,
@@ -230,22 +251,12 @@ async fn create_context(
230
251
init_params : Vec < u8 > ,
231
252
guard : OwnedMutexGuard < ContextId > ,
232
253
) -> eyre:: Result < Hash > {
233
- let Some ( blob) = node_client. get_blob_bytes ( & application. blob ) . await ? else {
234
- bail ! (
235
- "missing blob `{}` for application `{}`" ,
236
- application. blob,
237
- application. id
238
- ) ;
239
- } ;
240
-
241
254
let storage = ContextStorage :: from ( datastore, context. id ) ;
242
255
243
- let module = engine. compile ( & blob) ?;
244
-
245
256
let ( outcome, storage) = execute (
246
257
& guard,
247
- identity,
248
258
module,
259
+ identity,
249
260
"init" . into ( ) ,
250
261
init_params. into ( ) ,
251
262
storage,
0 commit comments