@@ -1241,35 +1241,62 @@ mod tests {
12411241 }
12421242
12431243 #[ test]
1244- fn ocw_clears_cache_after_election ( ) {
1245- let ( mut ext, _pool ) = ExtBuilder :: default ( ) . build_offchainify ( 0 ) ;
1244+ fn ocw_clears_cache_on_unsigned_phase_open ( ) {
1245+ let ( mut ext, pool ) = ExtBuilder :: default ( ) . build_offchainify ( 0 ) ;
12461246 ext. execute_with ( || {
1247- roll_to ( 25 ) ;
1248- assert_eq ! ( MultiPhase :: current_phase( ) , Phase :: Unsigned ( ( true , 25 ) ) ) ;
1247+ const BLOCK : u64 = 25 ;
1248+ let block_plus = |delta : u64 | BLOCK + delta;
1249+ let offchain_repeat = <Runtime as Config >:: OffchainRepeat :: get ( ) ;
12491250
1250- // we must clear the offchain storage to ensure the offchain execution check doesn't get
1251- // in the way.
1252- let mut storage = StorageValueRef :: persistent ( & OFFCHAIN_LAST_BLOCK ) ;
1253- storage. clear ( ) ;
1251+ roll_to ( BLOCK ) ;
1252+ // we are on the first block of the unsigned phase
1253+ assert_eq ! ( MultiPhase :: current_phase( ) , Phase :: Unsigned ( ( true , BLOCK ) ) ) ;
12541254
12551255 assert ! (
12561256 !ocw_solution_exists:: <Runtime >( ) ,
12571257 "no solution should be present before we mine one" ,
12581258 ) ;
12591259
1260- // creates and cache a solution
1261- MultiPhase :: offchain_worker ( 25 ) ;
1260+ // create and cache a solution on the first block of the unsigned phase
1261+ MultiPhase :: offchain_worker ( BLOCK ) ;
12621262 assert ! (
12631263 ocw_solution_exists:: <Runtime >( ) ,
12641264 "a solution must be cached after running the worker" ,
12651265 ) ;
12661266
1267- // after an election, the solution must be cleared
1267+ // record the submitted tx,
1268+ let tx_cache_1 = pool. read ( ) . transactions [ 0 ] . clone ( ) ;
1269+ // and assume it has been processed.
1270+ pool. try_write ( ) . unwrap ( ) . transactions . clear ( ) ;
1271+
1272+ // after an election, the solution is not cleared
12681273 // we don't actually care about the result of the election
1269- roll_to ( 26 ) ;
12701274 let _ = MultiPhase :: do_elect ( ) ;
1271- MultiPhase :: offchain_worker ( 26 ) ;
1272- assert ! ( !ocw_solution_exists:: <Runtime >( ) , "elections must clear the ocw cache" ) ;
1275+ MultiPhase :: offchain_worker ( block_plus ( 1 ) ) ;
1276+ assert ! ( ocw_solution_exists:: <Runtime >( ) , "elections does not clear the ocw cache" ) ;
1277+
1278+ // submit a solution with the offchain worker after the repeat interval
1279+ MultiPhase :: offchain_worker ( block_plus ( offchain_repeat + 1 ) ) ;
1280+
1281+ // record the submitted tx,
1282+ let tx_cache_2 = pool. read ( ) . transactions [ 0 ] . clone ( ) ;
1283+ // and assume it has been processed.
1284+ pool. try_write ( ) . unwrap ( ) . transactions . clear ( ) ;
1285+
1286+ // the OCW submitted the same solution twice since the cache was not cleared.
1287+ assert_eq ! ( tx_cache_1, tx_cache_2) ;
1288+
1289+ let current_block = block_plus ( offchain_repeat * 2 + 2 ) ;
1290+ // force the unsigned phase to start on the current block.
1291+ CurrentPhase :: < Runtime > :: set ( Phase :: Unsigned ( ( true , current_block) ) ) ;
1292+
1293+ // clear the cache and create a solution since we are on the first block of the unsigned
1294+ // phase.
1295+ MultiPhase :: offchain_worker ( current_block) ;
1296+ let tx_cache_3 = pool. read ( ) . transactions [ 0 ] . clone ( ) ;
1297+
1298+ // the submitted solution changes because the cache was cleared.
1299+ assert_eq ! ( tx_cache_1, tx_cache_3) ;
12731300 } )
12741301 }
12751302
0 commit comments