@@ -95,6 +95,8 @@ pub struct SystemExecutionStateView<C> {
9595 pub closed : HashedRegisterView < C , bool > ,
9696 /// Permissions for applications on this chain.
9797 pub application_permissions : HashedRegisterView < C , ApplicationPermissions > ,
98+ /// Blobs that have been used or published on this chain.
99+ pub used_blobs : HashedSetView < C , BlobId > ,
98100}
99101
100102/// The configuration for a new chain.
@@ -609,14 +611,14 @@ where
609611 outcome. messages . push ( message) ;
610612 }
611613 PublishBytecode { bytecode_id } => {
612- txn_tracker . replay_oracle_response ( OracleResponse :: Blob ( BlobId :: new (
614+ self . blob_published ( & BlobId :: new (
613615 bytecode_id. contract_blob_hash ,
614616 BlobType :: ContractBytecode ,
615- ) ) ) ?;
616- txn_tracker . replay_oracle_response ( OracleResponse :: Blob ( BlobId :: new (
617+ ) ) ?;
618+ self . blob_published ( & BlobId :: new (
617619 bytecode_id. service_blob_hash ,
618620 BlobType :: ServiceBytecode ,
619- ) ) ) ?;
621+ ) ) ?;
620622 }
621623 CreateApplication {
622624 bytecode_id,
@@ -664,14 +666,11 @@ where
664666 outcome. messages . push ( message) ;
665667 }
666668 PublishDataBlob { blob_hash } => {
667- txn_tracker. replay_oracle_response ( OracleResponse :: Blob ( BlobId :: new (
668- blob_hash,
669- BlobType :: Data ,
670- ) ) ) ?;
669+ self . blob_published ( & BlobId :: new ( blob_hash, BlobType :: Data ) ) ?;
671670 }
672671 ReadBlob { blob_id } => {
673- txn_tracker. replay_oracle_response ( OracleResponse :: Blob ( blob_id) ) ?;
674672 self . read_blob_content ( blob_id) . await ?;
673+ self . blob_used ( Some ( txn_tracker) , blob_id) . await ?;
675674 }
676675 }
677676
@@ -1006,12 +1005,41 @@ where
10061005 Ok ( messages)
10071006 }
10081007
1009- pub async fn read_blob_content ( & mut self , blob_id : BlobId ) -> Result < BlobContent , ViewError > {
1010- self . context ( )
1011- . extra ( )
1012- . get_blob ( blob_id)
1013- . await
1014- . map ( Into :: into)
1008+ /// Records a blob that is used in this block. If this is the first use on this chain, creates
1009+ /// an oracle response for it.
1010+ pub ( crate ) async fn blob_used (
1011+ & mut self ,
1012+ txn_tracker : Option < & mut TransactionTracker > ,
1013+ blob_id : BlobId ,
1014+ ) -> Result < bool , SystemExecutionError > {
1015+ if self . used_blobs . contains ( & blob_id) . await ? {
1016+ return Ok ( false ) ; // Nothing to do.
1017+ }
1018+ self . used_blobs . insert ( & blob_id) ?;
1019+ if let Some ( txn_tracker) = txn_tracker {
1020+ txn_tracker. replay_oracle_response ( OracleResponse :: Blob ( blob_id) ) ?;
1021+ }
1022+ Ok ( true )
1023+ }
1024+
1025+ /// Records a blob that is published in this block. This does not create an oracle entry, and
1026+ /// the blob can be used without using an oracle in the future on this chain.
1027+ fn blob_published ( & mut self , blob_id : & BlobId ) -> Result < ( ) , SystemExecutionError > {
1028+ self . used_blobs . insert ( blob_id) ?;
1029+ Ok ( ( ) )
1030+ }
1031+
1032+ pub async fn read_blob_content (
1033+ & mut self ,
1034+ blob_id : BlobId ,
1035+ ) -> Result < BlobContent , SystemExecutionError > {
1036+ match self . context ( ) . extra ( ) . get_blob ( blob_id) . await {
1037+ Ok ( blob) => Ok ( blob. into ( ) ) ,
1038+ Err ( ViewError :: BlobsNotFound ( _) ) => {
1039+ Err ( SystemExecutionError :: BlobsNotFound ( vec ! [ blob_id] ) )
1040+ }
1041+ Err ( error) => Err ( error. into ( ) ) ,
1042+ }
10151043 }
10161044
10171045 pub async fn assert_blob_exists (
@@ -1054,12 +1082,14 @@ where
10541082 missing_blobs. push ( service_bytecode_blob_id) ;
10551083 }
10561084
1057- if missing_blobs. is_empty ( ) {
1058- txn_tracker. replay_oracle_response ( OracleResponse :: Blob ( contract_bytecode_blob_id) ) ?;
1059- txn_tracker. replay_oracle_response ( OracleResponse :: Blob ( service_bytecode_blob_id) ) ?;
1060- Ok ( ( ) )
1061- } else {
1062- Err ( SystemExecutionError :: BlobsNotFound ( missing_blobs) )
1063- }
1085+ ensure ! (
1086+ missing_blobs. is_empty( ) ,
1087+ SystemExecutionError :: BlobsNotFound ( missing_blobs)
1088+ ) ;
1089+ self . blob_used ( Some ( txn_tracker) , contract_bytecode_blob_id)
1090+ . await ?;
1091+ self . blob_used ( Some ( txn_tracker) , service_bytecode_blob_id)
1092+ . await ?;
1093+ Ok ( ( ) )
10641094 }
10651095}
0 commit comments