@@ -235,6 +235,114 @@ BOOST_AUTO_TEST_CASE( undo_block )
235
235
}
236
236
}
237
237
238
+ BOOST_AUTO_TEST_CASE ( change_signing_key )
239
+ {
240
+ try {
241
+ fc::temp_directory data_dir ( graphene::utilities::temp_directory_path () );
242
+ {
243
+ database db;
244
+ auto init_account_priv_key = fc::ecc::private_key::regenerate (fc::sha256::hash (string (" null_key" )) );
245
+ auto init_pub_key = init_account_priv_key.get_public_key ();
246
+ auto new_key = fc::ecc::private_key::regenerate (fc::sha256::hash (string (" new_key" )) );
247
+ auto new_pub_key = new_key.get_public_key ();
248
+
249
+ std::map< public_key_type, fc::ecc::private_key > key_map;
250
+ key_map[init_pub_key] = init_account_priv_key;
251
+ key_map[new_pub_key] = new_key;
252
+
253
+ auto change_signing_key = [&db,&init_account_priv_key]( witness_id_type wit, public_key_type new_signing_key ) {
254
+ witness_update_operation wuop;
255
+ wuop.witness_account = wit (db).witness_account ;
256
+ wuop.witness = wit;
257
+ wuop.new_signing_key = new_signing_key;
258
+ signed_transaction wu_trx;
259
+ wu_trx.operations .push_back ( wuop );
260
+ wu_trx.set_reference_block ( db.head_block_id () );
261
+ wu_trx.set_expiration ( db.head_block_time ()
262
+ + fc::seconds ( 0x1000 * db.get_global_properties ().parameters .block_interval ) );
263
+ wu_trx.sign ( init_account_priv_key, db.get_chain_id () );
264
+ PUSH_TX ( db, wu_trx, 0 );
265
+ };
266
+
267
+ // open database
268
+ db.open (data_dir.path (), make_genesis, " TEST" );
269
+
270
+ // generate some empty blocks with init keys
271
+ for ( uint32_t i = 0 ; i < 30 ; ++i )
272
+ {
273
+ auto now = db.get_slot_time (1 );
274
+ auto next_witness = db.get_scheduled_witness ( 1 );
275
+ db.generate_block ( now, next_witness, init_account_priv_key, database::skip_nothing );
276
+ }
277
+
278
+ // generate some blocks and change keys in same block
279
+ for ( uint32_t i = 0 ; i < 9 ; ++i )
280
+ {
281
+ auto now = db.get_slot_time (1 );
282
+ auto next_witness = db.get_scheduled_witness ( 1 );
283
+ public_key_type current_key = next_witness (db).signing_key ;
284
+ change_signing_key ( next_witness, new_key.get_public_key () );
285
+ idump ( (i)(now)(next_witness) );
286
+ auto b = db.generate_block ( now, next_witness, key_map[current_key], database::skip_nothing );
287
+ idump ( (b) );
288
+ }
289
+
290
+ // pop a few blocks and clear pending, some signing keys should be changed back
291
+ for ( uint32_t i = 0 ; i < 4 ; ++i )
292
+ {
293
+ db.pop_block ();
294
+ }
295
+ db._popped_tx .clear ();
296
+ db.clear_pending ();
297
+
298
+ // generate a few blocks and change keys in same block
299
+ for ( uint32_t i = 0 ; i < 2 ; ++i )
300
+ {
301
+ auto now = db.get_slot_time (1 );
302
+ auto next_witness = db.get_scheduled_witness ( 1 );
303
+ public_key_type current_key = next_witness (db).signing_key ;
304
+ change_signing_key ( next_witness, new_key.get_public_key () );
305
+ idump ( (i)(now)(next_witness) );
306
+ auto b = db.generate_block ( now, next_witness, key_map[current_key], database::skip_nothing );
307
+ idump ( (b) );
308
+ }
309
+
310
+ // generate some blocks but don't change a key
311
+ for ( uint32_t i = 0 ; i < 25 ; ++i )
312
+ {
313
+ auto now = db.get_slot_time (1 );
314
+ auto next_witness = db.get_scheduled_witness ( 1 );
315
+ public_key_type current_key = next_witness (db).signing_key ;
316
+ idump ( (i)(now)(next_witness) );
317
+ auto b = db.generate_block ( now, next_witness, key_map[current_key], database::skip_nothing );
318
+ idump ( (b) );
319
+ }
320
+
321
+ // close the database, flush all data to disk
322
+ db.close ();
323
+
324
+ // reopen database, all data should be unchanged
325
+ db.open (data_dir.path (), make_genesis, " TEST" );
326
+
327
+ // generate more blocks and change keys in same block
328
+ for ( uint32_t i = 0 ; i < 25 ; ++i )
329
+ {
330
+ auto now = db.get_slot_time (1 );
331
+ auto next_witness = db.get_scheduled_witness ( 1 );
332
+ public_key_type current_key = next_witness (db).signing_key ;
333
+ change_signing_key ( next_witness, new_key.get_public_key () );
334
+ idump ( (i)(now)(next_witness) );
335
+ auto b = db.generate_block ( now, next_witness, key_map[current_key], database::skip_nothing );
336
+ idump ( (b) );
337
+ }
338
+
339
+ }
340
+ } catch (fc::exception & e) {
341
+ edump ((e.to_detail_string ()));
342
+ throw ;
343
+ }
344
+ }
345
+
238
346
BOOST_AUTO_TEST_CASE ( fork_blocks )
239
347
{
240
348
try {
0 commit comments