1
0
Fork 0
forked from lthn/blockchain

added explicit transactions to blocktemplate

This commit is contained in:
cryptozoidberg 2019-11-28 05:28:36 +01:00
parent cdfd321387
commit d7c67b196c
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
8 changed files with 104 additions and 22 deletions

View file

@ -333,6 +333,11 @@ namespace currency
return m_blockchain_storage.create_block_template(b, adr, stakeholder_address, diffic, height, ex_nonce, pos, pe);
}
//-----------------------------------------------------------------------------------------------
bool core::get_block_template(const create_block_template_params& params, create_block_template_response& resp)
{
return m_blockchain_storage.create_block_template(params, resp);
}
//-----------------------------------------------------------------------------------------------
bool core::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const
{
return m_blockchain_storage.find_blockchain_supplement(qblock_ids, resp);

View file

@ -53,7 +53,8 @@ namespace currency
//-------------------- i_miner_handler -----------------------
virtual bool handle_block_found(const block& b, block_verification_context* p_verification_result = nullptr);
virtual bool get_block_template(block& b, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry());
virtual bool get_block_template(const create_block_template_params& params, create_block_template_response& resp);
bool get_block_template(block& b, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry());
miner& get_miner(){ return m_miner; }
static void init_options(boost::program_options::options_description& desc);

View file

@ -109,4 +109,6 @@ namespace currency
blobdata tx_to_blob(const transaction& b);
bool tx_to_blob(const transaction& b, blobdata& b_blob);
bool read_keyimages_from_tx(const transaction& tx, std::list<crypto::key_image>& kil);
}

View file

@ -24,6 +24,7 @@ namespace currency
struct i_miner_handler
{
virtual bool handle_block_found(const block& b, block_verification_context* p_verification_result = nullptr) = 0;
virtual bool get_block_template(const create_block_template_params& params, create_block_template_response& resp) = 0;
virtual bool get_block_template(block& b, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry()) = 0;
protected:
~i_miner_handler(){};

View file

@ -793,28 +793,45 @@ namespace currency
return false;
}
block b = AUTO_VAL_INIT(b);
wide_difficulty_type dt = 0;
currency::pos_entry pe = AUTO_VAL_INIT(pe);
pe.amount = req.pos_amount;
pe.index = req.pos_index;
pe.stake_unlock_time = req.stake_unlock_time;
//pe.keyimage key image will be set in the wallet
//pe.wallet_index is not included in serialization map, TODO: refactoring here
if (!m_core.get_block_template(b, miner_address, stakeholder_address, dt, res.height, req.extra_text, req.pos_block, pe))
create_block_template_params params = AUTO_VAL_INIT(params);
params.miner_address = miner_address;
params.stakeholder_address = stakeholder_address;
params.ex_nonce = req.extra_text;
params.pos = req.pos_block;
params.pe.amount = req.pos_amount;
params.pe.index = req.pos_index;
params.pe.stake_unlock_time = req.stake_unlock_time;
//params.pe.keyimage key image will be set in the wallet
//params.pe.wallet_index is not included in serialization map, TODO: refactoring here
params.pcustom_fill_block_template_func = nullptr;
if (req.explicit_transaction.size())
{
transaction tx = AUTO_VAL_INIT(tx);
if (!parse_and_validate_tx_from_blob(req.explicit_transaction, tx))
{
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
error_resp.message = "Wrong parameters: explicit_transaction is invalid";
LOG_ERROR("Failed to parse explicit_transaction blob");
return false;
}
params.explicit_txs.push_back(tx);
}
create_block_template_response resp = AUTO_VAL_INIT(resp);
if (!m_core.get_block_template(params, resp))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Internal error: failed to create block template";
LOG_ERROR("Failed to create block template");
return false;
}
res.difficulty = dt.convert_to<std::string>();
blobdata block_blob = t_serializable_object_to_blob(b);
res.difficulty = resp.diffic.convert_to<std::string>();
blobdata block_blob = t_serializable_object_to_blob(resp.b);
res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob);
res.prev_hash = string_tools::pod_to_hex(b.prev_id);
res.prev_hash = string_tools::pod_to_hex(resp.b.prev_id);
res.height = resp.height;
//calculate epoch seed
res.seed = currency::ethash_epoch_to_seed(currency::ethash_height_to_epoch(res.height));

View file

@ -770,7 +770,7 @@ namespace currency
{
struct request
{
//uint64_t reserve_size; //max 255 bytes
blobdata explicit_transaction;
std::string extra_text;
std::string wallet_address;
std::string stakeholder_address;
@ -780,6 +780,7 @@ namespace currency
uint64_t stake_unlock_time;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_BLOB_AS_HEX_STRING(explicit_transaction)
KV_SERIALIZE(extra_text)
KV_SERIALIZE(wallet_address)
KV_SERIALIZE(stakeholder_address);

View file

@ -2291,15 +2291,32 @@ void wallet2::get_transfers(wallet2::transfer_container& incoming_transfers) con
incoming_transfers = m_transfers;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::generate_packing_transaction_if_needed(transaction& tx)
bool wallet2::generate_packing_transaction_if_needed(transaction& tx, uint64_t fake_outputs_number)
{
prepare_free_transfers_cache(0);
auto it = m_found_free_amounts.find(CURRENCY_BLOCK_REWARD);
if (it == m_found_free_amounts.end() || it->second.size() < WALLET_POS_MINT_PACKING_SIZE)
return false;
//let's check if we have at least WALLET_POS_MINT_PACKING_SIZE transactions which is ready to go
size_t count = 0;
for (auto it_ind = it->second.begin(); it_ind != it->second.end() && count < WALLET_POS_MINT_PACKING_SIZE; it_ind++)
{
if (is_transfer_ready_to_go(m_transfers[*it_ind], fake_outputs_number))
++count;
}
if (count < WALLET_POS_MINT_PACKING_SIZE)
return false;
construct_tx_param ctp = get_default_construct_tx_param();
currency::tx_destination_entry de = AUTO_VAL_INIT(de);
de.addr.push_back(m_account.get_public_address());
de.amount = WALLET_POS_MINT_PACKING_SIZE;
ctp.dsts.push_back(de);
ctp.perform_packing = true;
transfer(ctp, tx, false, nullptr);
return true;
}
//----------------------------------------------------------------------------------------------------
std::string wallet2::get_transfers_str(bool include_spent /*= true*/, bool include_unspent /*= true*/) const
@ -2769,6 +2786,12 @@ bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request&
tmpl_req.pos_index = req.pos_entries[rsp.index].index;
tmpl_req.extra_text = m_miner_text_info;
tmpl_req.stake_unlock_time = req.pos_entries[rsp.index].stake_unlock_time;
//generate packing tx
transaction pack_tx = AUTO_VAL_INIT(pack_tx);
if (generate_packing_transaction_if_needed(pack_tx, 0))
{
tx_to_blob(pack_tx, tmpl_req.explicit_transaction);
}
m_core_proxy->call_COMMAND_RPC_GETBLOCKTEMPLATE(tmpl_req, tmpl_rsp);
WLT_CHECK_AND_ASSERT_MES(tmpl_rsp.status == CORE_RPC_STATUS_OK, false, "Failed to create block template after kernel hash found!");
@ -3453,12 +3476,10 @@ bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake
}
it->second.erase(it->second.begin());
if (!it->second.size())
found_free_amounts.erase(it);
m_found_free_amounts.erase(it);
}
return prepare_tx_sources(fake_outputs_count, sources, selected_indicies, found_money);
}
//----------------------------------------------------------------------------------------------------
bool wallet2::prepare_tx_sources(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust_threshold, std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies, uint64_t& found_money)
@ -4110,6 +4131,8 @@ void wallet2::prepare_transaction(const construct_tx_param& ctp, finalize_tx_par
TIME_MEASURE_START_MS(prepare_tx_sources_time);
if (ctp.multisig_id == currency::null_hash)
prepare_tx_sources(needed_money, ctp.fake_outputs_count, ctp.dust_policy.dust_threshold, ftp.sources, ftp.selected_transfers, found_money);
else if (ctp.perform_packing)
prepare_tx_sources_for_packing(WALLET_POS_MINT_PACKING_SIZE, 0, ftp.sources, ftp.selected_transfers, found_money);
else
prepare_tx_sources(ctp.multisig_id, ftp.sources, found_money);
TIME_MEASURE_FINISH_MS(prepare_tx_sources_time);
@ -4239,7 +4262,32 @@ void wallet2::transfer(const std::vector<currency::tx_destination_entry>& dsts,
ctp.tx_outs_attr = tx_outs_attr;
ctp.unlock_time = unlock_time;
TIME_MEASURE_FINISH(precalculation_time);
transfer(ctp, tx, send_to_network, p_signed_tx_blob_str);
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
construct_tx_param wallet2::get_default_construct_tx_param_inital()
{
construct_tx_param ctp = AUTO_VAL_INIT(ctp);
ctp.fee = m_core_runtime_config.tx_default_fee;
ctp.dust_policy = tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD);
ctp.split_strategy_id = tools::detail::ssi_digit;
ctp.tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED;
ctp.shuffle = 0;
return ctp;
}
const construct_tx_param& wallet2::get_default_construct_tx_param()
{
static construct_tx_param ctp = get_default_construct_tx_param_inital();
return ctp;
}
//----------------------------------------------------------------------------------------------------
void wallet2::transfer(const construct_tx_param& ctp,
currency::transaction &tx,
bool send_to_network,
std::string* p_signed_tx_blob_str)
{
TIME_MEASURE_START(prepare_transaction_time);
finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
prepare_transaction(ctp, ftp);

View file

@ -541,6 +541,11 @@ namespace tools
const std::vector<currency::attachment_v>& attachments,
currency::transaction& tx);
void transfer(const construct_tx_param& ctp,
currency::transaction &tx,
bool send_to_network,
std::string* p_signed_tx_blob_str);
template<typename destination_split_strategy_t>
void transfer_from_contract(
const std::list<currency::account_keys>& owner_keys,
@ -805,7 +810,9 @@ private:
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const wallet_public::wallet_transfer_info& wti) const;
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const std::string& reason = "internal intention") const;
construct_tx_param get_default_construct_tx_param_inital();
const construct_tx_param& get_default_construct_tx_param();
uint64_t get_tx_expiration_median() const;
@ -847,7 +854,7 @@ private:
void exception_handler() const;
uint64_t get_minimum_allowed_fee_for_contract(const crypto::hash& ms_id);
void check_for_free_space_and_throw_if_it_lacks(const std::wstring& path, uint64_t exact_size_needed_if_known = UINT64_MAX);
bool generate_packing_transaction_if_needed(transaction& tx);
bool generate_packing_transaction_if_needed(transaction& tx, uint64_t fake_outputs_number);
currency::account_base m_account;