@@ -29,12 +29,18 @@ use sp_core::{
2929 offchain:: { self , OffchainDbExt , OffchainWorkerExt , TransactionPoolExt } ,
3030 ExecutionContext ,
3131} ;
32- use sp_externalities:: Extensions ;
32+ use sp_externalities:: { Extension , Extensions } ;
3333use sp_keystore:: { KeystoreExt , SyncCryptoStorePtr } ;
34- use sp_runtime:: { generic:: BlockId , traits} ;
34+ use sp_runtime:: {
35+ generic:: BlockId ,
36+ traits:: { Block as BlockT , NumberFor } ,
37+ } ;
3538pub use sp_state_machine:: ExecutionStrategy ;
3639use sp_state_machine:: { DefaultHandler , ExecutionManager } ;
37- use std:: sync:: { Arc , Weak } ;
40+ use std:: {
41+ marker:: PhantomData ,
42+ sync:: { Arc , Weak } ,
43+ } ;
3844
3945/// Execution strategies settings.
4046#[ derive( Debug , Clone ) ]
@@ -63,18 +69,81 @@ impl Default for ExecutionStrategies {
6369 }
6470}
6571
66- /// Generate the starting set of ExternalitiesExtensions based upon the given capabilities
67- pub trait ExtensionsFactory : Send + Sync {
68- /// Make `Extensions` for given `Capabilities`.
69- fn extensions_for ( & self , capabilities : offchain:: Capabilities ) -> Extensions ;
72+ /// Generate the starting set of [`Extensions`].
73+ ///
74+ /// These [`Extensions`] are passed to the environment a runtime is executed in.
75+ pub trait ExtensionsFactory < Block : BlockT > : Send + Sync {
76+ /// Create [`Extensions`] for the given input.
77+ ///
78+ /// - `block_hash`: The hash of the block in the context that extensions will be used.
79+ /// - `block_number`: The number of the block in the context that extensions will be used.
80+ /// - `capabilities`: The capabilities
81+ fn extensions_for (
82+ & self ,
83+ block_hash : Block :: Hash ,
84+ block_number : NumberFor < Block > ,
85+ capabilities : offchain:: Capabilities ,
86+ ) -> Extensions ;
7087}
7188
72- impl ExtensionsFactory for ( ) {
73- fn extensions_for ( & self , _capabilities : offchain:: Capabilities ) -> Extensions {
89+ impl < Block : BlockT > ExtensionsFactory < Block > for ( ) {
90+ fn extensions_for (
91+ & self ,
92+ _: Block :: Hash ,
93+ _: NumberFor < Block > ,
94+ _capabilities : offchain:: Capabilities ,
95+ ) -> Extensions {
7496 Extensions :: new ( )
7597 }
7698}
7799
100+ impl < Block : BlockT , T : ExtensionsFactory < Block > > ExtensionsFactory < Block > for Vec < T > {
101+ fn extensions_for (
102+ & self ,
103+ block_hash : Block :: Hash ,
104+ block_number : NumberFor < Block > ,
105+ capabilities : offchain:: Capabilities ,
106+ ) -> Extensions {
107+ let mut exts = Extensions :: new ( ) ;
108+ exts. extend ( self . iter ( ) . map ( |e| e. extensions_for ( block_hash, block_number, capabilities) ) ) ;
109+ exts
110+ }
111+ }
112+
113+ /// An [`ExtensionsFactory`] that registers an [`Extension`] before a certain block.
114+ pub struct ExtensionBeforeBlock < Block : BlockT , Ext > {
115+ before : NumberFor < Block > ,
116+ _marker : PhantomData < fn ( Ext ) -> Ext > ,
117+ }
118+
119+ impl < Block : BlockT , Ext > ExtensionBeforeBlock < Block , Ext > {
120+ /// Create the extension factory.
121+ ///
122+ /// - `before`: The block number until the extension should be registered.
123+ pub fn new ( before : NumberFor < Block > ) -> Self {
124+ Self { before, _marker : PhantomData }
125+ }
126+ }
127+
128+ impl < Block : BlockT , Ext : Default + Extension > ExtensionsFactory < Block >
129+ for ExtensionBeforeBlock < Block , Ext >
130+ {
131+ fn extensions_for (
132+ & self ,
133+ _: Block :: Hash ,
134+ block_number : NumberFor < Block > ,
135+ _: offchain:: Capabilities ,
136+ ) -> Extensions {
137+ let mut exts = Extensions :: new ( ) ;
138+
139+ if block_number < self . before {
140+ exts. register ( Ext :: default ( ) ) ;
141+ }
142+
143+ exts
144+ }
145+ }
146+
78147/// Create a Offchain DB accessor object.
79148pub trait DbExternalitiesFactory : Send + Sync {
80149 /// Create [`offchain::DbExternalities`] instance.
@@ -92,7 +161,7 @@ impl<T: offchain::DbExternalities + Clone + Sync + Send + 'static> DbExternaliti
92161/// This crate aggregates extensions available for the offchain calls
93162/// and is responsible for producing a correct `Extensions` object.
94163/// for each call, based on required `Capabilities`.
95- pub struct ExecutionExtensions < Block : traits :: Block > {
164+ pub struct ExecutionExtensions < Block : BlockT > {
96165 strategies : ExecutionStrategies ,
97166 keystore : Option < SyncCryptoStorePtr > ,
98167 offchain_db : Option < Box < dyn DbExternalitiesFactory > > ,
@@ -103,10 +172,10 @@ pub struct ExecutionExtensions<Block: traits::Block> {
103172 // That's also the reason why it's being registered lazily instead of
104173 // during initialization.
105174 transaction_pool : RwLock < Option < Weak < dyn OffchainSubmitTransaction < Block > > > > ,
106- extensions_factory : RwLock < Box < dyn ExtensionsFactory > > ,
175+ extensions_factory : RwLock < Box < dyn ExtensionsFactory < Block > > > ,
107176}
108177
109- impl < Block : traits :: Block > Default for ExecutionExtensions < Block > {
178+ impl < Block : BlockT > Default for ExecutionExtensions < Block > {
110179 fn default ( ) -> Self {
111180 Self {
112181 strategies : Default :: default ( ) ,
@@ -118,7 +187,7 @@ impl<Block: traits::Block> Default for ExecutionExtensions<Block> {
118187 }
119188}
120189
121- impl < Block : traits :: Block > ExecutionExtensions < Block > {
190+ impl < Block : BlockT > ExecutionExtensions < Block > {
122191 /// Create new `ExecutionExtensions` given a `keystore` and `ExecutionStrategies`.
123192 pub fn new (
124193 strategies : ExecutionStrategies ,
@@ -142,8 +211,8 @@ impl<Block: traits::Block> ExecutionExtensions<Block> {
142211 }
143212
144213 /// Set the new extensions_factory
145- pub fn set_extensions_factory ( & self , maker : Box < dyn ExtensionsFactory > ) {
146- * self . extensions_factory . write ( ) = maker;
214+ pub fn set_extensions_factory ( & self , maker : impl ExtensionsFactory < Block > + ' static ) {
215+ * self . extensions_factory . write ( ) = Box :: new ( maker) ;
147216 }
148217
149218 /// Register transaction pool extension.
@@ -156,10 +225,18 @@ impl<Block: traits::Block> ExecutionExtensions<Block> {
156225
157226 /// Based on the execution context and capabilities it produces
158227 /// the extensions object to support desired set of APIs.
159- pub fn extensions ( & self , at : & BlockId < Block > , context : ExecutionContext ) -> Extensions {
228+ pub fn extensions (
229+ & self ,
230+ block_hash : Block :: Hash ,
231+ block_number : NumberFor < Block > ,
232+ context : ExecutionContext ,
233+ ) -> Extensions {
160234 let capabilities = context. capabilities ( ) ;
161235
162- let mut extensions = self . extensions_factory . read ( ) . extensions_for ( capabilities) ;
236+ let mut extensions =
237+ self . extensions_factory
238+ . read ( )
239+ . extensions_for ( block_hash, block_number, capabilities) ;
163240
164241 if capabilities. contains ( offchain:: Capabilities :: KEYSTORE ) {
165242 if let Some ( ref keystore) = self . keystore {
@@ -169,10 +246,10 @@ impl<Block: traits::Block> ExecutionExtensions<Block> {
169246
170247 if capabilities. contains ( offchain:: Capabilities :: TRANSACTION_POOL ) {
171248 if let Some ( pool) = self . transaction_pool . read ( ) . as_ref ( ) . and_then ( |x| x. upgrade ( ) ) {
172- extensions
173- . register ( TransactionPoolExt (
174- Box :: new ( TransactionPoolAdapter { at : * at , pool } ) as _ ,
175- ) ) ;
249+ extensions. register ( TransactionPoolExt ( Box :: new ( TransactionPoolAdapter {
250+ at : BlockId :: Hash ( block_hash ) ,
251+ pool,
252+ } ) as _ ) ) ;
176253 }
177254 }
178255
@@ -203,7 +280,8 @@ impl<Block: traits::Block> ExecutionExtensions<Block> {
203280 /// the right manager and extensions object to support desired set of APIs.
204281 pub fn manager_and_extensions < E : std:: fmt:: Debug > (
205282 & self ,
206- at : & BlockId < Block > ,
283+ block_hash : Block :: Hash ,
284+ block_number : NumberFor < Block > ,
207285 context : ExecutionContext ,
208286 ) -> ( ExecutionManager < DefaultHandler < E > > , Extensions ) {
209287 let manager = match context {
@@ -215,17 +293,17 @@ impl<Block: traits::Block> ExecutionExtensions<Block> {
215293 ExecutionContext :: OffchainCall ( _) => self . strategies . other . get_manager ( ) ,
216294 } ;
217295
218- ( manager, self . extensions ( at , context) )
296+ ( manager, self . extensions ( block_hash , block_number , context) )
219297 }
220298}
221299
222300/// A wrapper type to pass `BlockId` to the actual transaction pool.
223- struct TransactionPoolAdapter < Block : traits :: Block > {
301+ struct TransactionPoolAdapter < Block : BlockT > {
224302 at : BlockId < Block > ,
225303 pool : Arc < dyn OffchainSubmitTransaction < Block > > ,
226304}
227305
228- impl < Block : traits :: Block > offchain:: TransactionPool for TransactionPoolAdapter < Block > {
306+ impl < Block : BlockT > offchain:: TransactionPool for TransactionPoolAdapter < Block > {
229307 fn submit_transaction ( & mut self , data : Vec < u8 > ) -> Result < ( ) , ( ) > {
230308 let xt = match Block :: Extrinsic :: decode ( & mut & * data) {
231309 Ok ( xt) => xt,
0 commit comments