forked from lthn/blockchain
Merge branch 'develop' of github.com:hyle-team/zano into develop
This commit is contained in:
commit
cd8f37161a
7 changed files with 265 additions and 70 deletions
|
|
@ -4861,7 +4861,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
CHECK_AND_ASSERT_MES_NO_RET(add_res, "handle_block_to_main_chain: failed to add transaction back to transaction pool");
|
||||
purge_block_data_from_blockchain(bl, tx_processed_count);
|
||||
add_block_as_invalid(bl, id);
|
||||
LOG_PRINT_L0("Block with id " << id << " added as invalid becouse of wrong inputs in transactions");
|
||||
LOG_PRINT_L0("Block with id " << id << " added as invalid because of wrong inputs in transactions");
|
||||
bvc.m_verification_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -5361,7 +5361,7 @@ bool blockchain_storage::build_stake_modifier(stake_modifier_type& sm, const alt
|
|||
else
|
||||
{
|
||||
bool r = string_tools::parse_tpod_from_hex_string(POS_STARTER_KERNEL_HASH, sm.last_pos_kernel_id);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse POS_STARTER_MODFIFIER");
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse POS_STARTER_KERNEL_HASH");
|
||||
}
|
||||
|
||||
sm.last_pow_id = get_block_hash(pbei_last_pow->bl);
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ bool test_generator::add_block_info(const currency::block& b, const std::list<cu
|
|||
sk.stake_modifier.last_pos_kernel_id = chain[pos_idx]->ks_hash;
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(string_tools::parse_tpod_from_hex_string(POS_STARTER_KERNEL_HASH, sk.stake_modifier.last_pos_kernel_id), false, "Failed to parse POS_STARTER_MODFIFIER");
|
||||
CHECK_AND_ASSERT_MES(string_tools::parse_tpod_from_hex_string(POS_STARTER_KERNEL_HASH, sk.stake_modifier.last_pos_kernel_id), false, "Failed to parse POS_STARTER_KERNEL_HASH");
|
||||
}
|
||||
uint64_t pow_idx = get_last_block_of_type(false, chain);
|
||||
sk.stake_modifier.last_pow_id = get_block_hash(chain[pow_idx]->b);
|
||||
|
|
@ -686,7 +686,7 @@ bool test_generator::build_stake_modifier(stake_modifier_type& sm, const test_ge
|
|||
else
|
||||
{
|
||||
bool r = string_tools::parse_tpod_from_hex_string(POS_STARTER_KERNEL_HASH, sm.last_pos_kernel_id);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse POS_STARTER_MODFIFIER");
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse POS_STARTER_KERNEL_HASH");
|
||||
}
|
||||
|
||||
sm.last_pow_id = get_block_hash(blck_chain[last_pow_i]->b);
|
||||
|
|
|
|||
|
|
@ -1024,3 +1024,11 @@ void tx2log(const currency::transaction& tx)
|
|||
currency::transaction ltx = tx;
|
||||
LOG_PRINT("!dbg transaction: " << currency::get_transaction_hash(ltx) << ENDL << currency::obj_to_json_str(ltx), LOG_LEVEL_0);
|
||||
}
|
||||
|
||||
const char* amount2log(const uint64_t amount)
|
||||
{
|
||||
static std::string s;
|
||||
s = currency::print_money_brief(amount);
|
||||
LOG_PRINT("!dbg amount: " << s, LOG_LEVEL_0);
|
||||
return s.c_str();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -312,22 +312,28 @@ bool hard_fork_1_checkpoint_basic_test::generate(std::vector<test_event_entry>&
|
|||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time());
|
||||
generator.set_hardfork_height(m_hardfork_height);
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
DO_CALLBACK_PARAMS(events, "set_checkpoint", params_checkpoint(CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 2));
|
||||
DO_CALLBACK_PARAMS(events, "set_checkpoint", params_checkpoint(2 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 7));
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
DO_CALLBACK(events, "check_being_in_cp_zone"); // make sure CP was has passed
|
||||
|
||||
//
|
||||
// before hardfork 1
|
||||
//
|
||||
|
||||
std::vector<tx_source_entry> sources;
|
||||
CHECK_AND_ASSERT_MES(fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), MK_TEST_COINS(90) + TESTS_DEFAULT_FEE, 0), false, "");
|
||||
|
||||
uint64_t stake_lock_time = 100; // locked till block 100
|
||||
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
CHECK_AND_ASSERT_MES(fill_tx_sources_and_destinations(events, blk_0r, miner_acc, alice_acc, MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations), false, "");
|
||||
destinations.push_back(tx_destination_entry(MK_TEST_COINS(90), alice_acc.get_public_address()));
|
||||
|
||||
// set unlock_time_2, should be rejected before hardfork 1
|
||||
std::vector<extra_v> extra;
|
||||
etc_tx_details_unlock_time2 ut2 = AUTO_VAL_INIT(ut2);
|
||||
ut2.unlock_time_array.resize(destinations.size());
|
||||
ut2.unlock_time_array[0] = 1; // not zero, unlocked from block 1
|
||||
ut2.unlock_time_array[0] = stake_lock_time;
|
||||
extra.push_back(ut2);
|
||||
transaction tx_0 = AUTO_VAL_INIT(tx_0);
|
||||
crypto::secret_key tx_sec_key;
|
||||
|
|
@ -342,13 +348,94 @@ bool hard_fork_1_checkpoint_basic_test::generate(std::vector<test_event_entry>&
|
|||
DO_CALLBACK(events, "clear_tx_pool");
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_1, blk_0r, miner_acc);
|
||||
MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_acc); // <-- checkpoint
|
||||
MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_acc);
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_acc); // <-- hard fork
|
||||
MAKE_NEXT_BLOCK(events, blk_4, blk_3, miner_acc);
|
||||
// make sure hardfork went okay
|
||||
CHECK_AND_ASSERT_MES(blk_3.major_version != CURRENT_BLOCK_MAJOR_VERSION && blk_4.major_version == CURRENT_BLOCK_MAJOR_VERSION, false, "hardfork did not happen as expected");
|
||||
|
||||
//
|
||||
// after hardfork 1
|
||||
//
|
||||
|
||||
// now tx_0 is okay and can be added to the blockchain
|
||||
events.push_back(tx_0);
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4, miner_acc, tx_0);
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_5r, blk_5, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
CREATE_TEST_WALLET(alice_wlt, alice_acc, blk_0);
|
||||
REFRESH_TEST_WALLET_AT_GEN_TIME(events, alice_wlt, blk_5r, 2 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
|
||||
CHECK_TEST_WALLET_BALANCE_AT_GEN_TIME(alice_wlt, MK_TEST_COINS(90));
|
||||
|
||||
// try to mine a PoS block using locked coins
|
||||
block blk_6;
|
||||
{
|
||||
const block& prev_block = blk_5r;
|
||||
const transaction& stake = tx_0;
|
||||
const account_base& stakeholder = alice_acc;
|
||||
|
||||
crypto::hash prev_id = get_block_hash(prev_block);
|
||||
size_t height = get_block_height(prev_block) + 1;
|
||||
currency::wide_difficulty_type diff = generator.get_difficulty_for_next_block(prev_id, false);
|
||||
|
||||
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
|
||||
size_t stake_output_idx = 0;
|
||||
size_t stake_output_gidx = 0;
|
||||
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
|
||||
crypto::key_image stake_output_key_image;
|
||||
keypair kp;
|
||||
generate_key_image_helper(stakeholder.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
|
||||
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
|
||||
|
||||
pos_block_builder pb;
|
||||
pb.step1_init_header(height, prev_id);
|
||||
pb.m_block.major_version = CURRENT_BLOCK_MAJOR_VERSION;
|
||||
pb.step2_set_txs(std::vector<transaction>());
|
||||
pb.step3_build_stake_kernel(stake_output_amount, stake_output_gidx, stake_output_key_image, diff, prev_id, null_hash, prev_block.timestamp);
|
||||
pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), miner_acc.get_public_address(), stakeholder.get_public_address());
|
||||
|
||||
// set etc_tx_details_unlock_time2
|
||||
remove_unlock_v1_entries_from_extra(pb.m_block.miner_tx.extra); // clear already set unlock
|
||||
std::vector<extra_v> extra;
|
||||
etc_tx_details_unlock_time2 ut2 = AUTO_VAL_INIT(ut2);
|
||||
ut2.unlock_time_array.push_back(height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW); // reward lock
|
||||
for(size_t i = 0; i < pb.m_block.miner_tx.vout.size() - 1; ++i)
|
||||
ut2.unlock_time_array.push_back(stake_lock_time); // using the same lock time as stake input
|
||||
extra.push_back(ut2);
|
||||
pb.m_block.miner_tx.extra.push_back(ut2);
|
||||
|
||||
pb.step5_sign(stake_tx_pub_key, stake_output_idx, stake_output_pubkey, stakeholder);
|
||||
blk_6 = pb.m_block;
|
||||
}
|
||||
events.push_back(blk_6);
|
||||
generator.add_block_info(blk_6, std::list<transaction>()); // add modified block info
|
||||
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_7, blk_6, miner_acc); // <-- checkpoint
|
||||
MAKE_NEXT_BLOCK(events, blk_8, blk_7, miner_acc);
|
||||
|
||||
DO_CALLBACK(events, "check_not_being_in_cp_zone"); // make sure CP was has passed
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_8r, blk_8, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
// make sure locked Alice's coins still can't be spent
|
||||
sources.clear();
|
||||
r = fill_tx_sources(sources, events, blk_8r, alice_acc.get_keys(), MK_TEST_COINS(90), 0 /* nmix */, true /* check for spends */, false /* check for unlock time */);
|
||||
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
|
||||
transaction tx_1 = AUTO_VAL_INIT(tx_1);
|
||||
r = construct_tx(alice_acc.get_keys(), sources, std::vector<tx_destination_entry>{ tx_destination_entry(MK_TEST_COINS(90) - TESTS_DEFAULT_FEE, miner_acc.get_public_address()) },
|
||||
empty_attachment, tx_1, stake_lock_time /* try to use stake unlock time -- should not work as it is not a coinbase */);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
|
||||
|
||||
DO_CALLBACK(events, "mark_invalid_tx");
|
||||
events.push_back(tx_1);
|
||||
|
||||
// mine another PoS block using the same stake after a checkpoint
|
||||
std::list<currency::account_base> pos_stakeing_accounts{alice_acc};
|
||||
MAKE_NEXT_POS_BLOCK(events, blk_9, blk_8r, miner_acc, pos_stakeing_accounts);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -614,14 +701,16 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
|
|||
|
||||
// create few locked outputs in the blockchain with unique amount
|
||||
// tx_0 : miner -> Alice, miner -> Bob
|
||||
uint64_t stake_unlock_time = 100; // locked until block 100
|
||||
uint64_t stake_amount = MK_TEST_COINS(10);
|
||||
std::vector<extra_v> extra;
|
||||
etc_tx_details_unlock_time ut = AUTO_VAL_INIT(ut);
|
||||
ut.v = 100; // locked until block 100
|
||||
ut.v = stake_unlock_time;
|
||||
extra.push_back(ut);
|
||||
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.push_back(tx_destination_entry(MK_TEST_COINS(10), alice_acc.get_public_address()));
|
||||
destinations.push_back(tx_destination_entry(MK_TEST_COINS(10), bob_acc.get_public_address()));
|
||||
destinations.push_back(tx_destination_entry(stake_amount, alice_acc.get_public_address()));
|
||||
destinations.push_back(tx_destination_entry(stake_amount, bob_acc.get_public_address()));
|
||||
|
||||
transaction tx_0 = AUTO_VAL_INIT(tx_0);
|
||||
r = construct_tx_to_key(events, tx_0, blk_0r, miner_acc, destinations, TESTS_DEFAULT_FEE, 0, 0, extra);
|
||||
|
|
@ -635,7 +724,7 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
|
|||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1);
|
||||
|
||||
block blk_s;
|
||||
block blk_b1;
|
||||
{
|
||||
const block& prev_block = blk_1r;
|
||||
const transaction& stake = tx_0;
|
||||
|
|
@ -659,7 +748,7 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
|
|||
pb.m_block.major_version = CURRENT_BLOCK_MAJOR_VERSION;
|
||||
pb.step2_set_txs(std::vector<transaction>());
|
||||
pb.step3_build_stake_kernel(stake_output_amount, stake_output_gidx, stake_output_key_image, diff, prev_id, null_hash, prev_block.timestamp);
|
||||
pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), miner_acc.get_public_address());
|
||||
pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), miner_acc.get_public_address(), stakeholder.get_public_address());
|
||||
|
||||
// set etc_tx_details_unlock_time2
|
||||
remove_unlock_v1_entries_from_extra(pb.m_block.miner_tx.extra); // clear already set unlock
|
||||
|
|
@ -672,11 +761,57 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
|
|||
pb.m_block.miner_tx.extra.push_back(ut2);
|
||||
|
||||
pb.step5_sign(stake_tx_pub_key, stake_output_idx, stake_output_pubkey, stakeholder);
|
||||
blk_s = pb.m_block;
|
||||
blk_b1 = pb.m_block;
|
||||
}
|
||||
|
||||
DO_CALLBACK(events, "mark_invalid_block"); // should not pass as using time-locking in outputs
|
||||
events.push_back(blk_s);
|
||||
// should not pass as using time-locking in outputs
|
||||
DO_CALLBACK(events, "mark_invalid_block");
|
||||
events.push_back(blk_b1);
|
||||
|
||||
|
||||
block blk_b2;
|
||||
{
|
||||
const block& prev_block = blk_1r;
|
||||
const transaction& stake = tx_0;
|
||||
const account_base& stakeholder = alice_acc;
|
||||
|
||||
crypto::hash prev_id = get_block_hash(prev_block);
|
||||
size_t height = get_block_height(prev_block) + 1;
|
||||
currency::wide_difficulty_type diff = generator.get_difficulty_for_next_block(prev_id, false);
|
||||
|
||||
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
|
||||
size_t stake_output_idx = 0;
|
||||
size_t stake_output_gidx = 0;
|
||||
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
|
||||
crypto::key_image stake_output_key_image;
|
||||
keypair kp;
|
||||
generate_key_image_helper(stakeholder.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
|
||||
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
|
||||
|
||||
pos_block_builder pb;
|
||||
pb.step1_init_header(height, prev_id);
|
||||
pb.m_block.major_version = CURRENT_BLOCK_MAJOR_VERSION;
|
||||
pb.step2_set_txs(std::vector<transaction>());
|
||||
pb.step3_build_stake_kernel(stake_output_amount, stake_output_gidx, stake_output_key_image, diff, prev_id, null_hash, prev_block.timestamp);
|
||||
pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), miner_acc.get_public_address(), stakeholder.get_public_address());
|
||||
|
||||
// set etc_tx_details_unlock_time2
|
||||
remove_unlock_v1_entries_from_extra(pb.m_block.miner_tx.extra); // clear already set unlock
|
||||
std::vector<extra_v> extra;
|
||||
etc_tx_details_unlock_time2 ut2 = AUTO_VAL_INIT(ut2);
|
||||
ut2.unlock_time_array.push_back(height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW); // reward lock
|
||||
for(size_t i = 0; i < pb.m_block.miner_tx.vout.size() - 1; ++i)
|
||||
ut2.unlock_time_array.push_back(stake_unlock_time - 1); // stake locked by 1 less height that stake_unlock_time, that is incorrect as lock time of this coin is decreased
|
||||
extra.push_back(ut2);
|
||||
pb.m_block.miner_tx.extra.push_back(ut2);
|
||||
|
||||
pb.step5_sign(stake_tx_pub_key, stake_output_idx, stake_output_pubkey, stakeholder);
|
||||
blk_b2 = pb.m_block;
|
||||
}
|
||||
|
||||
// should no pass because stake output has less lock time than stake input
|
||||
DO_CALLBACK(events, "mark_invalid_block");
|
||||
events.push_back(blk_b2);
|
||||
|
||||
block blk_good;
|
||||
{
|
||||
|
|
@ -702,7 +837,7 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
|
|||
pb.m_block.major_version = CURRENT_BLOCK_MAJOR_VERSION;
|
||||
pb.step2_set_txs(std::vector<transaction>());
|
||||
pb.step3_build_stake_kernel(stake_output_amount, stake_output_gidx, stake_output_key_image, diff, prev_id, null_hash, prev_block.timestamp);
|
||||
pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), miner_acc.get_public_address());
|
||||
pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), miner_acc.get_public_address(), stakeholder.get_public_address());
|
||||
|
||||
// set etc_tx_details_unlock_time2
|
||||
remove_unlock_v1_entries_from_extra(pb.m_block.miner_tx.extra); // clear already set unlock
|
||||
|
|
@ -710,7 +845,7 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
|
|||
etc_tx_details_unlock_time2 ut2 = AUTO_VAL_INIT(ut2);
|
||||
ut2.unlock_time_array.push_back(height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW); // reward lock
|
||||
for(size_t i = 0; i < pb.m_block.miner_tx.vout.size() - 1; ++i)
|
||||
ut2.unlock_time_array.push_back(100); // stake locked by height 100
|
||||
ut2.unlock_time_array.push_back(stake_unlock_time); // using the same lock time as stake input
|
||||
extra.push_back(ut2);
|
||||
pb.m_block.miner_tx.extra.push_back(ut2);
|
||||
|
||||
|
|
@ -718,8 +853,22 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
|
|||
blk_good = pb.m_block;
|
||||
}
|
||||
|
||||
// should be okay
|
||||
// should pass okay
|
||||
events.push_back(blk_good);
|
||||
generator.add_block_info(blk_good, std::list<transaction>()); // add modified block info
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_2, blk_good, miner_acc);
|
||||
|
||||
std::vector<tx_source_entry> sources;
|
||||
r = fill_tx_sources(sources, events, blk_2, alice_acc.get_keys(), stake_amount / 2 + TESTS_DEFAULT_FEE, 0 /* nmix */, true /* check for spends */, false /* check for unlock time */);
|
||||
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
|
||||
transaction tx_1 = AUTO_VAL_INIT(tx_1);
|
||||
r = construct_tx(alice_acc.get_keys(), sources, std::vector<tx_destination_entry>{ tx_destination_entry(stake_amount / 2, miner_acc.get_public_address()) },
|
||||
empty_attachment, tx_1, stake_unlock_time /* try to use stake unlock time -- should not work as it is not a coinbase */);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
|
||||
|
||||
DO_CALLBACK(events, "mark_invalid_tx");
|
||||
events.push_back(tx_1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ hard_fork_1_locked_mining_test::hard_fork_1_locked_mining_test()
|
|||
|
||||
bool hard_fork_1_locked_mining_test::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
random_state_test_restorer::reset_random();
|
||||
// Test idea: make sure PoS mining on locked coins is possible
|
||||
|
||||
GENERATE_ACCOUNT(preminer_acc);
|
||||
GENERATE_ACCOUNT(miner_acc);
|
||||
|
|
@ -36,20 +36,30 @@ bool hard_fork_1_locked_mining_test::generate(std::vector<test_event_entry>& eve
|
|||
DO_CALLBACK(events, "configure_core");
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3);
|
||||
|
||||
//construc tx that locks transaction for some period of time
|
||||
// make a couple of huge txs
|
||||
//construct tx that locks coins for some period of time
|
||||
//make a couple of huge txs
|
||||
bool r = false;
|
||||
std::vector<extra_v> extra;
|
||||
|
||||
std::vector<tx_source_entry> sources_1;
|
||||
r = fill_tx_sources(sources_1, events, blk_0r, miner_acc.get_keys(), 2000000000000+TESTS_DEFAULT_FEE, 0);
|
||||
r = fill_tx_sources(sources_1, events, blk_0r, miner_acc.get_keys(), CURRENCY_BLOCK_REWARD + TESTS_DEFAULT_FEE, 0);
|
||||
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
|
||||
std::vector<tx_destination_entry> destinations({ tx_destination_entry(2010000000000, pos_miner_acc.get_public_address()) });
|
||||
std::vector<tx_destination_entry> destinations({ tx_destination_entry(CURRENCY_BLOCK_REWARD, pos_miner_acc.get_public_address()) });
|
||||
crypto::secret_key stub;
|
||||
transaction tx_1 = AUTO_VAL_INIT(tx_1);
|
||||
r = construct_tx(miner_acc.get_keys(), sources_1, destinations, extra, empty_attachment, tx_1, stub, get_block_height(blk_0r)+2000);
|
||||
uint64_t unlock_time = get_block_height(blk_0r) + 2000;
|
||||
r = construct_tx(miner_acc.get_keys(), sources_1, destinations, extra, empty_attachment, tx_1, stub, unlock_time);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
|
||||
events.push_back(tx_1); // push it to the pool
|
||||
|
||||
uint64_t ut1 = get_tx_x_detail<etc_tx_details_unlock_time>(tx_1);
|
||||
etc_tx_details_unlock_time2 ut2 = AUTO_VAL_INIT(ut2);
|
||||
get_type_in_variant_container(tx_1.extra, ut2);
|
||||
std::stringstream ss;
|
||||
for (auto v : ut2.unlock_time_array)
|
||||
ss << v << " ";
|
||||
LOG_PRINT_YELLOW("tx1: ut1: " << ut1 << ", ut2: " << ss.str(), LOG_LEVEL_0);
|
||||
|
||||
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_0r_tx, blk_0r, miner_acc, tx_1);
|
||||
|
||||
|
|
@ -61,13 +71,30 @@ bool hard_fork_1_locked_mining_test::generate(std::vector<test_event_entry>& eve
|
|||
events.push_back(event_core_time(next_blk_pow.timestamp - 10));
|
||||
last_block = next_blk_pow;
|
||||
}
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_1, last_block, miner_acc);
|
||||
MAKE_NEXT_POS_BLOCK(events, blk_2, blk_1, miner_acc, miner_acc_lst);
|
||||
MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_acc);
|
||||
|
||||
std::list<currency::account_base> accounts_2;
|
||||
accounts_2.push_back(pos_miner_acc);
|
||||
//let's try to mint PoS block from locked account
|
||||
//mint PoS block from locked account into an altchain
|
||||
MAKE_NEXT_POS_BLOCK(events, next_blk_pos, last_block, pos_miner_acc, accounts_2);
|
||||
|
||||
DO_CALLBACK(events, "c1");
|
||||
// switch chains
|
||||
MAKE_NEXT_BLOCK(events, blk_2a, next_blk_pos, miner_acc);
|
||||
MAKE_NEXT_BLOCK(events, blk_3a, blk_2a, miner_acc);
|
||||
MAKE_NEXT_BLOCK(events, blk_4a, blk_3a, miner_acc);
|
||||
|
||||
// make sure switch happened
|
||||
DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(blk_4a));
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_4ar, blk_4a, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
// mint another PoS block from locked account
|
||||
MAKE_NEXT_POS_BLOCK(events, blk_5a, blk_4ar, pos_miner_acc, accounts_2);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void pos_block_builder::step3_build_stake_kernel(
|
|||
if (last_pos_block_kernel_hash == null_hash)
|
||||
{
|
||||
bool r = string_tools::parse_tpod_from_hex_string(POS_STARTER_KERNEL_HASH, m_stake_kernel.stake_modifier.last_pos_kernel_id);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to parse POS_STARTER_MODFIFIER");
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to parse POS_STARTER_KERNEL_HASH");
|
||||
}
|
||||
|
||||
wide_difficulty_type stake_difficulty = difficulty / stake_output_amount;
|
||||
|
|
@ -105,9 +105,21 @@ void pos_block_builder::step3_build_stake_kernel(
|
|||
m_step = 3;
|
||||
}
|
||||
|
||||
void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
||||
const boost::multiprecision::uint128_t& already_generated_coins,
|
||||
const account_public_address &reward_and_stake_receiver_address,
|
||||
const blobdata& extra_nonce,
|
||||
size_t max_outs,
|
||||
const extra_alias_entry& alias,
|
||||
keypair tx_one_time_key)
|
||||
{
|
||||
step4_generate_coinbase_tx(median_size, already_generated_coins, reward_and_stake_receiver_address, reward_and_stake_receiver_address, extra_nonce, max_outs, alias, tx_one_time_key);
|
||||
}
|
||||
|
||||
void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
||||
const boost::multiprecision::uint128_t& already_generated_coins,
|
||||
const account_public_address &reward_receiver_address,
|
||||
const account_public_address &stakeholder_address,
|
||||
const blobdata& extra_nonce,
|
||||
size_t max_outs,
|
||||
const extra_alias_entry& alias,
|
||||
|
|
@ -118,7 +130,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
|||
// generate miner tx using incorrect current_block_size only for size estimation
|
||||
size_t estimated_block_size = m_txs_total_size;
|
||||
bool r = construct_homemade_pos_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, m_pos_stake_amount, m_stake_kernel.kimage,
|
||||
m_pos_stake_output_gindex, reward_receiver_address, m_block.miner_tx, extra_nonce, max_outs, alias, tx_one_time_key);
|
||||
m_pos_stake_output_gindex, reward_receiver_address, stakeholder_address, m_block.miner_tx, extra_nonce, max_outs, tx_one_time_key);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "construct_homemade_pos_miner_tx failed");
|
||||
|
||||
estimated_block_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx);
|
||||
|
|
@ -126,7 +138,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
|||
for (size_t try_count = 0; try_count != 10; ++try_count)
|
||||
{
|
||||
r = construct_homemade_pos_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, m_pos_stake_amount, m_stake_kernel.kimage,
|
||||
m_pos_stake_output_gindex, reward_receiver_address, m_block.miner_tx, extra_nonce, max_outs, alias, tx_one_time_key);
|
||||
m_pos_stake_output_gindex, reward_receiver_address, stakeholder_address, m_block.miner_tx, extra_nonce, max_outs, tx_one_time_key);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "construct_homemade_pos_miner_tx failed");
|
||||
|
||||
cumulative_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx);
|
||||
|
|
@ -171,11 +183,11 @@ bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const bo
|
|||
uint64_t pos_stake_amount,
|
||||
crypto::key_image pos_stake_keyimage,
|
||||
size_t pos_stake_gindex,
|
||||
const account_public_address &miner_address,
|
||||
const account_public_address &reward_receiving_address,
|
||||
const account_public_address &stakeholder_address,
|
||||
transaction& tx,
|
||||
const blobdata& extra_nonce /*= blobdata()*/,
|
||||
size_t max_outs /*= CURRENCY_MINER_TX_MAX_OUTS*/,
|
||||
const extra_alias_entry& alias /*= alias_info()*/,
|
||||
keypair tx_one_time_key /*= keypair::generate()*/)
|
||||
{
|
||||
boost::value_initialized<transaction> new_tx;
|
||||
|
|
@ -189,12 +201,6 @@ bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const bo
|
|||
bool r = get_block_reward(true, median_size, current_block_size, already_generated_coins, block_reward, height);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Block is too big");
|
||||
block_reward += fee;
|
||||
block_reward += pos_stake_amount;
|
||||
|
||||
uint64_t alias_reward = 0;
|
||||
if (!alias.m_alias.empty())
|
||||
alias_reward = currency::get_alias_coast_from_fee(alias.m_alias, TESTS_DEFAULT_FEE);
|
||||
block_reward -= alias_reward;
|
||||
|
||||
// decompose reward into outputs and populate tx.vout
|
||||
std::vector<size_t> out_amounts;
|
||||
|
|
@ -202,14 +208,15 @@ bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const bo
|
|||
[&out_amounts](uint64_t a_chunk) { out_amounts.push_back(a_chunk); },
|
||||
[&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); });
|
||||
|
||||
CHECK_AND_ASSERT_MES(1 <= max_outs, false, "max_out must be non-zero");
|
||||
while (max_outs < out_amounts.size())
|
||||
CHECK_AND_ASSERT_MES(2 <= max_outs, false, "max_out must be greather than 1");
|
||||
while (out_amounts.size() + 1 > max_outs)
|
||||
{
|
||||
out_amounts[out_amounts.size() - 2] += out_amounts.back();
|
||||
out_amounts.resize(out_amounts.size() - 1);
|
||||
}
|
||||
|
||||
bool burn_money = miner_address.m_spend_public_key == null_pkey && miner_address.m_view_public_key == null_pkey; // if true, burn money, so no one on Earth can spend them
|
||||
// reward
|
||||
bool burn_money = reward_receiving_address.m_spend_public_key == null_pkey && reward_receiving_address.m_view_public_key == null_pkey; // if true, burn reward, so no one on Earth can spend them
|
||||
for (size_t output_index = 0; output_index < out_amounts.size(); ++output_index)
|
||||
{
|
||||
txout_to_key tk;
|
||||
|
|
@ -218,7 +225,7 @@ bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const bo
|
|||
|
||||
if (!burn_money)
|
||||
{
|
||||
r = currency::derive_public_key_from_target_address(miner_address, tx_one_time_key.sec, output_index, tk.key); // derivation(view_pub; tx_sec).derive(output_index, spend_pub) => output pub key
|
||||
r = currency::derive_public_key_from_target_address(reward_receiving_address, tx_one_time_key.sec, output_index, tk.key); // derivation(view_pub; tx_sec).derive(output_index, spend_pub) => output pub key
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to derive_public_key_from_target_address");
|
||||
}
|
||||
|
||||
|
|
@ -228,36 +235,31 @@ bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const bo
|
|||
tx.vout.push_back(out);
|
||||
}
|
||||
|
||||
// stake
|
||||
burn_money = stakeholder_address.m_spend_public_key == null_pkey && stakeholder_address.m_view_public_key == null_pkey; // if true, burn stake
|
||||
{
|
||||
txout_to_key tk;
|
||||
tk.key = null_pkey; // null means burn money
|
||||
tk.mix_attr = 0;
|
||||
|
||||
if (!burn_money)
|
||||
{
|
||||
r = currency::derive_public_key_from_target_address(stakeholder_address, tx_one_time_key.sec, tx.vout.size(), tk.key);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to derive_public_key_from_target_address");
|
||||
}
|
||||
|
||||
tx_out out;
|
||||
out.amount = pos_stake_amount;
|
||||
out.target = tk;
|
||||
tx.vout.push_back(out);
|
||||
}
|
||||
|
||||
// take care about extra
|
||||
add_tx_pub_key_to_extra(tx, tx_one_time_key.pub);
|
||||
if (extra_nonce.size())
|
||||
if (!add_tx_extra_userdata(tx, extra_nonce))
|
||||
return false;
|
||||
if (alias.m_alias.size())
|
||||
{
|
||||
if (!add_tx_extra_alias(tx, alias))
|
||||
return false;
|
||||
|
||||
// decompose alias reward into digits and create additional outputs
|
||||
out_amounts.clear();
|
||||
decompose_amount_into_digits(alias_reward, DEFAULT_DUST_THRESHOLD, [&out_amounts](uint64_t a_chunk) { out_amounts.push_back(a_chunk); }, [&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); });
|
||||
while (out_amounts.size() > max_outs)
|
||||
{
|
||||
out_amounts[out_amounts.size() - 2] += out_amounts.back();
|
||||
out_amounts.resize(out_amounts.size() - 1);
|
||||
}
|
||||
for (size_t output_index = 0; output_index < out_amounts.size(); ++output_index)
|
||||
{
|
||||
txout_to_key tk;
|
||||
tk.key = null_pkey; // burn money for the sake of alias!
|
||||
tk.mix_attr = 0;
|
||||
tx_out out;
|
||||
out.amount = out_amounts[output_index];
|
||||
out.target = tk;
|
||||
tx.vout.push_back(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// populate ins with 1) money-generating and 2) PoS
|
||||
txin_gen in;
|
||||
in.height = height;
|
||||
|
|
|
|||
|
|
@ -27,11 +27,20 @@ struct pos_block_builder
|
|||
void step4_generate_coinbase_tx(size_t median_size,
|
||||
const boost::multiprecision::uint128_t& already_generated_coins,
|
||||
const currency::account_public_address &reward_receiver_address,
|
||||
const currency::account_public_address &stakeholder_address,
|
||||
const currency::blobdata& extra_nonce = currency::blobdata(),
|
||||
size_t max_outs = CURRENCY_MINER_TX_MAX_OUTS,
|
||||
const currency::extra_alias_entry& alias = currency::extra_alias_entry(),
|
||||
currency::keypair tx_one_time_key = currency::keypair::generate());
|
||||
|
||||
|
||||
void step4_generate_coinbase_tx(size_t median_size,
|
||||
const boost::multiprecision::uint128_t& already_generated_coins,
|
||||
const currency::account_public_address &reward_and_stake_receiver_address,
|
||||
const currency::blobdata& extra_nonce = currency::blobdata(),
|
||||
size_t max_outs = CURRENCY_MINER_TX_MAX_OUTS,
|
||||
const currency::extra_alias_entry& alias = currency::extra_alias_entry(),
|
||||
currency::keypair tx_one_time_key = currency::keypair::generate());
|
||||
|
||||
void step5_sign(const crypto::public_key& stake_tx_pub_key, size_t stake_tx_out_index, const crypto::public_key& stake_tx_out_pub_key, const currency::account_base& stakeholder_account);
|
||||
|
||||
currency::block m_block;
|
||||
|
|
@ -50,11 +59,11 @@ bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const bo
|
|||
uint64_t pos_stake_amount,
|
||||
crypto::key_image pos_stake_keyimage,
|
||||
size_t pos_stake_gindex,
|
||||
const currency::account_public_address &miner_address,
|
||||
const currency::account_public_address &reward_receiving_address,
|
||||
const currency::account_public_address &stakeholder_address,
|
||||
currency::transaction& tx,
|
||||
const currency::blobdata& extra_nonce = currency::blobdata(),
|
||||
size_t max_outs = CURRENCY_MINER_TX_MAX_OUTS,
|
||||
const currency::extra_alias_entry& alias = currency::extra_alias_entry(),
|
||||
currency::keypair tx_one_time_key = currency::keypair::generate());
|
||||
|
||||
bool mine_next_pos_block_in_playtime_sign_cb(currency::core& c, const currency::block& prev_block, const currency::block& coinstake_scr_block, const currency::account_base& acc,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue