Skip to content

Commit 10a2b43

Browse files
committed
Test case to reproduce bitshares#125 block producing issue
When signing key is updated in the same block, producing will fail.
1 parent bde91ab commit 10a2b43

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

tests/tests/block_tests.cpp

+108
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,114 @@ BOOST_AUTO_TEST_CASE( undo_block )
235235
}
236236
}
237237

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+
238346
BOOST_AUTO_TEST_CASE( fork_blocks )
239347
{
240348
try {

0 commit comments

Comments
 (0)