@@ -343,6 +343,13 @@ impl UserData {
343343 }
344344}
345345
346+ #[ derive( Clone , Debug ) ]
347+ pub struct CreateApplicationResult {
348+ pub app_id : UserApplicationId ,
349+ pub message : RawOutgoingMessage < SystemMessage , Amount > ,
350+ pub blobs_to_register : Vec < BlobId > ,
351+ }
352+
346353#[ derive( Error , Debug ) ]
347354pub enum SystemExecutionError {
348355 #[ error( transparent) ]
@@ -634,31 +641,23 @@ where
634641 instantiation_argument,
635642 required_application_ids,
636643 } => {
637- let id = UserApplicationId {
638- bytecode_id,
639- creation : context. next_message_id ( txn_tracker. next_message_index ( ) ) ,
640- } ;
641- for application in required_application_ids. iter ( ) . chain ( iter:: once ( & id) ) {
642- self . check_and_record_bytecode_blobs ( & application. bytecode_id , txn_tracker)
643- . await ?;
644- }
645- self . registry
646- . register_new_application (
647- id,
648- parameters. clone ( ) ,
649- required_application_ids. clone ( ) ,
644+ let next_message_id = context. next_message_id ( txn_tracker. next_message_index ( ) ) ;
645+ let CreateApplicationResult {
646+ app_id,
647+ message,
648+ blobs_to_register,
649+ } = self
650+ . create_application (
651+ next_message_id,
652+ bytecode_id,
653+ parameters,
654+ required_application_ids,
650655 )
651656 . await ?;
652- // Send a message to ourself to increment the message ID.
653- let message = RawOutgoingMessage {
654- destination : Destination :: Recipient ( context. chain_id ) ,
655- authenticated : false ,
656- grant : Amount :: ZERO ,
657- kind : MessageKind :: Protected ,
658- message : SystemMessage :: ApplicationCreated ,
659- } ;
657+ self . record_bytecode_blobs ( blobs_to_register, txn_tracker)
658+ . await ?;
660659 outcome. messages . push ( message) ;
661- new_application = Some ( ( id , instantiation_argument. clone ( ) ) ) ;
660+ new_application = Some ( ( app_id , instantiation_argument. clone ( ) ) ) ;
662661 }
663662 RequestApplication {
664663 chain_id,
@@ -1024,6 +1023,49 @@ where
10241023 Ok ( messages)
10251024 }
10261025
1026+ pub async fn create_application (
1027+ & mut self ,
1028+ next_message_id : MessageId ,
1029+ bytecode_id : BytecodeId ,
1030+ parameters : Vec < u8 > ,
1031+ required_application_ids : Vec < UserApplicationId > ,
1032+ ) -> Result < CreateApplicationResult , SystemExecutionError > {
1033+ let id = UserApplicationId {
1034+ bytecode_id,
1035+ creation : next_message_id,
1036+ } ;
1037+ let mut blobs_to_register = vec ! [ ] ;
1038+ for application in required_application_ids. iter ( ) . chain ( iter:: once ( & id) ) {
1039+ let ( contract_bytecode_blob_id, service_bytecode_blob_id) =
1040+ self . check_bytecode_blobs ( & application. bytecode_id ) . await ?;
1041+ // We only remember to register the blobs that aren't recorded in `used_blobs`
1042+ // already.
1043+ if !self . used_blobs . contains ( & contract_bytecode_blob_id) . await ? {
1044+ blobs_to_register. push ( contract_bytecode_blob_id) ;
1045+ }
1046+ if !self . used_blobs . contains ( & service_bytecode_blob_id) . await ? {
1047+ blobs_to_register. push ( service_bytecode_blob_id) ;
1048+ }
1049+ }
1050+ self . registry
1051+ . register_new_application ( id, parameters. clone ( ) , required_application_ids. clone ( ) )
1052+ . await ?;
1053+ // Send a message to ourself to increment the message ID.
1054+ let message = RawOutgoingMessage {
1055+ destination : Destination :: Recipient ( next_message_id. chain_id ) ,
1056+ authenticated : false ,
1057+ grant : Amount :: ZERO ,
1058+ kind : MessageKind :: Protected ,
1059+ message : SystemMessage :: ApplicationCreated ,
1060+ } ;
1061+
1062+ Ok ( CreateApplicationResult {
1063+ app_id : id,
1064+ message,
1065+ blobs_to_register,
1066+ } )
1067+ }
1068+
10271069 /// Records a blob that is used in this block. If this is the first use on this chain, creates
10281070 /// an oracle response for it.
10291071 pub ( crate ) async fn blob_used (
@@ -1072,11 +1114,10 @@ where
10721114 }
10731115 }
10741116
1075- async fn check_and_record_bytecode_blobs (
1117+ async fn check_bytecode_blobs (
10761118 & mut self ,
10771119 bytecode_id : & BytecodeId ,
1078- txn_tracker : & mut TransactionTracker ,
1079- ) -> Result < ( ) , SystemExecutionError > {
1120+ ) -> Result < ( BlobId , BlobId ) , SystemExecutionError > {
10801121 let contract_bytecode_blob_id =
10811122 BlobId :: new ( bytecode_id. contract_blob_hash , BlobType :: ContractBytecode ) ;
10821123
@@ -1105,10 +1146,32 @@ where
11051146 missing_blobs. is_empty( ) ,
11061147 SystemExecutionError :: BlobsNotFound ( missing_blobs)
11071148 ) ;
1108- self . blob_used ( Some ( txn_tracker) , contract_bytecode_blob_id)
1109- . await ?;
1110- self . blob_used ( Some ( txn_tracker) , service_bytecode_blob_id)
1111- . await ?;
1149+
1150+ Ok ( ( contract_bytecode_blob_id, service_bytecode_blob_id) )
1151+ }
1152+
1153+ async fn record_bytecode_blobs (
1154+ & mut self ,
1155+ blob_ids : Vec < BlobId > ,
1156+ txn_tracker : & mut TransactionTracker ,
1157+ ) -> Result < ( ) , SystemExecutionError > {
1158+ for blob_id in blob_ids {
1159+ self . blob_used ( Some ( txn_tracker) , blob_id) . await ?;
1160+ }
11121161 Ok ( ( ) )
11131162 }
1163+
1164+ async fn check_and_record_bytecode_blobs (
1165+ & mut self ,
1166+ bytecode_id : & BytecodeId ,
1167+ txn_tracker : & mut TransactionTracker ,
1168+ ) -> Result < ( ) , SystemExecutionError > {
1169+ let ( contract_bytecode_blob_id, service_bytecode_blob_id) =
1170+ self . check_bytecode_blobs ( bytecode_id) . await ?;
1171+ self . record_bytecode_blobs (
1172+ vec ! [ contract_bytecode_blob_id, service_bytecode_blob_id] ,
1173+ txn_tracker,
1174+ )
1175+ . await
1176+ }
11141177}
0 commit comments