Added mechanism create proposal (send_btc_transaction)
This commit is contained in:
parent
f22d61855b
commit
ffc51ba1ea
16 changed files with 210 additions and 69 deletions
|
|
@ -26,7 +26,6 @@ object_id_type bitcoin_transaction_send_evaluator::do_apply( const bitcoin_trans
|
|||
bitcoin_transaction_send_operation& mutable_op = const_cast<bitcoin_transaction_send_operation&>( op );
|
||||
database& d = db();
|
||||
std::vector< info_for_used_vin_id_type > new_vins;
|
||||
sidechain::prev_out new_pw_vout = { "", 0, 0 };
|
||||
sidechain::bytes wit_script;
|
||||
|
||||
finalize_bitcoin_transaction( mutable_op );
|
||||
|
|
@ -53,6 +52,7 @@ object_id_type bitcoin_transaction_send_evaluator::do_apply( const bitcoin_trans
|
|||
obj.confirm = false;
|
||||
});
|
||||
|
||||
sidechain::prev_out new_pw_vout = { "", 0, 0 };
|
||||
if( btc_tx.transaction.vout[0].is_p2wsh() && btc_tx.transaction.vout[0].scriptPubKey == wit_script )
|
||||
new_pw_vout = { btc_tx.transaction.get_txid(), 0, btc_tx.transaction.vout[0].value };
|
||||
|
||||
|
|
|
|||
|
|
@ -409,6 +409,13 @@ signed_block database::_generate_block(
|
|||
_pending_tx_session.reset();
|
||||
_pending_tx_session = _undo_db.start_undo_session();
|
||||
|
||||
if( !is_sidechain_fork_needed() ) {
|
||||
auto op = create_send_btc_tx_proposal( witness_obj );
|
||||
if( op.valid() ) {
|
||||
_pending_tx.insert( _pending_tx.begin(), create_signed_transaction( block_signing_private_key, *op ) );
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t postponed_tx_count = 0;
|
||||
// pop pending state (reset to head block state)
|
||||
for( const processed_transaction& tx : _pending_tx )
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ database::database() :
|
|||
initialize_evaluators();
|
||||
context_sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
|
||||
context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
|
||||
estimated_feerate = 0;
|
||||
}
|
||||
|
||||
database::~database()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/bitcoin_address_object.hpp>
|
||||
#include <graphene/chain/sidechain_proposal_object.hpp>
|
||||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <sidechain/sidechain_condensing_tx.hpp>
|
||||
#include <graphene/chain/protocol/asset.hpp>
|
||||
|
||||
using namespace sidechain;
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
|
|
@ -77,9 +83,11 @@ void database::perform_sidechain_fork()
|
|||
pw.owner = sidechain_account.get_id();
|
||||
pw.count_invalid_pub_key = 1;
|
||||
});
|
||||
|
||||
pw_vout_manager.create_new_vout( {"", 0, 0 } );
|
||||
}
|
||||
|
||||
const sidechain::sidechain_parameters_extension& database::get_sidechain_params() const
|
||||
const sidechain_parameters_extension& database::get_sidechain_params() const
|
||||
{
|
||||
const auto& params = get_global_properties().parameters.extensions.value.sidechain_parameters;
|
||||
FC_ASSERT( params.valid() );
|
||||
|
|
@ -103,5 +111,102 @@ bitcoin_address_object database::get_latest_PW() const
|
|||
return *(--itr);
|
||||
}
|
||||
|
||||
int64_t database::get_estimated_fee( size_t tx_vsize, uint64_t estimated_feerate ) {
|
||||
static const uint64_t default_feerate = 1000;
|
||||
static const uint64_t min_relay_fee = 1000;
|
||||
|
||||
const auto feerate = std::max( default_feerate, estimated_feerate );
|
||||
const auto fee = feerate * int64_t( tx_vsize ) / 1000;
|
||||
|
||||
return std::max( min_relay_fee, fee );
|
||||
}
|
||||
|
||||
void database::processing_sidechain_proposals( const witness_object& current_witness, const fc::ecc::private_key& private_key )
|
||||
{
|
||||
const auto& sidechain_proposal_idx = get_index_type<sidechain_proposal_index>().indices().get< by_id >();
|
||||
const auto& proposal_idx = get_index_type<proposal_index>().indices().get< by_id >();
|
||||
|
||||
for( auto& sidechain_proposal : sidechain_proposal_idx ) {
|
||||
|
||||
const auto& proposal = proposal_idx.find( sidechain_proposal.proposal_id );
|
||||
FC_ASSERT( proposal != proposal_idx.end() );
|
||||
|
||||
switch( sidechain_proposal.proposal_type ) {
|
||||
case sidechain_proposal_type::ISSUE_PBTC :{}
|
||||
case sidechain_proposal_type::SEND_BTC_TRANSACTION :{}
|
||||
case sidechain_proposal_type::WITHDRAW_PBTC :{}
|
||||
case sidechain_proposal_type::RETURN_PBTC_BACK :{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
full_btc_transaction database::create_btc_transaction( const std::vector<info_for_vin>& info_vins,
|
||||
const std::vector<info_for_vout>& info_vouts,
|
||||
const fc::optional<info_for_vin>& info_pw_vin )
|
||||
{
|
||||
sidechain_condensing_tx ctx( info_vins, info_vouts );
|
||||
|
||||
if( info_pw_vin->identifier != SIDECHAIN_NULL_HASH ) {
|
||||
ctx.create_pw_vin( *info_pw_vin );
|
||||
}
|
||||
|
||||
const auto& pw_address = get_latest_PW().address;
|
||||
if( info_vouts.size() > 0 ) {
|
||||
ctx.create_vouts_for_witness_fee( pw_address.witnesses_keys );
|
||||
}
|
||||
|
||||
const uint64_t& change = ctx.get_amount_vins() - ctx.get_amount_transfer_to_bitcoin();
|
||||
if( change > 0 ) {
|
||||
ctx.create_pw_vout( change, pw_address.get_witness_script() );
|
||||
}
|
||||
|
||||
const uint64_t& size_fee = get_estimated_fee( ctx.get_estimate_tx_size( pw_address.witnesses_keys.size() ), estimated_feerate.load() );
|
||||
ctx.subtract_fee( size_fee, SIDECHAIN_DEFAULT_PERCENTAGE_PAYMENT_TO_WIT );
|
||||
|
||||
return std::make_pair( ctx.get_transaction(), size_fee );
|
||||
}
|
||||
|
||||
fc::optional<operation> database::create_send_btc_tx_proposal( const witness_object& current_witness )
|
||||
{
|
||||
const auto& info_vins = i_w_info.get_info_for_vins();
|
||||
const auto& info_vouts = i_w_info.get_info_for_vouts();
|
||||
const auto& info_pw_vin = i_w_info.get_info_for_pw_vin();
|
||||
|
||||
if( info_pw_vin.valid() && ( info_vins.size() || info_vouts.size() ) ) {
|
||||
const auto& btc_tx_and_size_fee = create_btc_transaction( info_vins, info_vouts, info_pw_vin );
|
||||
|
||||
bitcoin_transaction_send_operation btc_send_op;
|
||||
btc_send_op.payer = get_sidechain_account_id();
|
||||
btc_send_op.pw_vin = info_pw_vin->identifier != SIDECHAIN_NULL_HASH ? info_pw_vin->identifier : fc::optional< fc::sha256 >();
|
||||
btc_send_op.vins = info_vins;
|
||||
for( auto& out : info_vouts ) {
|
||||
btc_send_op.vouts.push_back( out.get_id() );
|
||||
}
|
||||
btc_send_op.transaction = btc_tx_and_size_fee.first;
|
||||
btc_send_op.fee_for_size = btc_tx_and_size_fee.second;
|
||||
|
||||
proposal_create_operation proposal_op;
|
||||
proposal_op.fee_paying_account = current_witness.witness_account;
|
||||
proposal_op.proposed_ops.push_back( op_wrapper( btc_send_op ) );
|
||||
uint32_t lifetime = ( get_global_properties().parameters.block_interval * get_global_properties().active_witnesses.size() ) * 3;
|
||||
proposal_op.expiration_time = time_point_sec( head_block_time().sec_since_epoch() + lifetime );
|
||||
return proposal_op;
|
||||
}
|
||||
return fc::optional<operation>();
|
||||
}
|
||||
|
||||
signed_transaction database::create_signed_transaction( const private_key& signing_private_key, const operation& op )
|
||||
{
|
||||
signed_transaction processed_trx;
|
||||
auto dyn_props = get_dynamic_global_properties();
|
||||
processed_trx.set_reference_block( dyn_props.head_block_id );
|
||||
processed_trx.set_expiration( head_block_time() + get_global_properties().parameters.maximum_time_until_expiration );
|
||||
processed_trx.operations.push_back( op );
|
||||
current_fee_schedule().set_fee( processed_trx.operations.back() );
|
||||
|
||||
processed_trx.sign( signing_private_key, get_chain_id() );
|
||||
|
||||
return processed_trx;
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
@ -236,4 +236,6 @@
|
|||
#define SIDECHAIN_DEFAULT_NUMBER_SIG_MULTISIG 5
|
||||
#define SIDECHAIN_DEFAULT_CONDENSING_TX_VINS_NUMBER 5
|
||||
#define SIDECHAIN_DEFAULT_CONDENSING_TX_VOUTS_NUMBER 5
|
||||
#define SIDECHAIN_DEFAULT_PERCENTAGE_PAYMENT_TO_WIT 0.001
|
||||
#define SIDECHAIN_NULL_HASH fc::sha256( "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9" ) // fc::sha256::hash( "" + std::to_string( 0 ) );
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -42,12 +42,15 @@
|
|||
|
||||
#include <sidechain/input_withdrawal_info.hpp>
|
||||
#include <sidechain/primary_wallet_vout_manager.hpp>
|
||||
#include <atomic>
|
||||
|
||||
#include <fc/log/logger.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <secp256k1.h>
|
||||
|
||||
using namespace fc::ecc;
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
using graphene::db::abstract_object;
|
||||
using graphene::db::object;
|
||||
|
|
@ -520,13 +523,24 @@ namespace graphene { namespace chain {
|
|||
const sidechain::sidechain_parameters_extension& get_sidechain_params() const;
|
||||
const account_id_type& get_sidechain_account_id() const;
|
||||
const asset_id_type& get_sidechain_asset_id() const;
|
||||
int64_t get_estimated_fee( size_t tx_vsize, uint64_t estimated_feerate );
|
||||
|
||||
void processing_sidechain_proposals( const witness_object& current_witness, const private_key& signing_private_key );
|
||||
|
||||
sidechain::full_btc_transaction create_btc_transaction( const std::vector<sidechain::info_for_vin>& info_vins,
|
||||
const std::vector<sidechain::info_for_vout>& info_vouts,
|
||||
const fc::optional<sidechain::info_for_vin>& info_pw_vin );
|
||||
fc::optional<operation> create_send_btc_tx_proposal( const witness_object& current_witness );
|
||||
signed_transaction create_signed_transaction( const private_key& signing_private_key, const operation& op );
|
||||
|
||||
|
||||
fc::signal<void( const sidechain::bitcoin_transaction& )> send_btc_tx;
|
||||
|
||||
sidechain::input_withdrawal_info i_w_info;
|
||||
|
||||
sidechain::primary_wallet_vout_manager pw_vout_manager;
|
||||
|
||||
fc::signal<void( const sidechain::bitcoin_transaction& )> send_btc_tx;
|
||||
std::atomic<uint64_t> estimated_feerate;
|
||||
|
||||
secp256k1_context_t* context_sign;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,14 @@ namespace graphene { namespace chain {
|
|||
public:
|
||||
typedef void result_type;
|
||||
database& db;
|
||||
proposal_id_type prop_id;
|
||||
|
||||
sidechain_hardfork_visitor( database& _db ) : db(_db) {}
|
||||
sidechain_hardfork_visitor( database& _db, const proposal_id_type& _prop_id ) : db( _db ), prop_id( _prop_id ) {}
|
||||
|
||||
template<typename T>
|
||||
void operator()( const T &v, const proposal_id_type prop_id ) const {}
|
||||
void operator()( const T &v ) const {}
|
||||
|
||||
void operator()( const bitcoin_transaction_send_operation &v, const proposal_id_type prop_id );
|
||||
void operator()( const bitcoin_transaction_send_operation &v );
|
||||
};
|
||||
|
||||
class proposal_create_evaluator : public evaluator<proposal_create_evaluator>
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ struct proposal_operation_hardfork_visitor
|
|||
}
|
||||
};
|
||||
|
||||
void sidechain_hardfork_visitor::operator()( const bitcoin_transaction_send_operation &v, const proposal_id_type prop_id )
|
||||
void sidechain_hardfork_visitor::operator()( const bitcoin_transaction_send_operation &v )
|
||||
{
|
||||
db.create<sidechain_proposal_object>([&]( sidechain_proposal_object& sch_prop ) {
|
||||
sch_prop.proposal_type = sidechain::sidechain_proposal_type::SEND_BTC_TRANSACTION;
|
||||
|
|
@ -163,7 +163,7 @@ void sidechain_hardfork_visitor::operator()( const bitcoin_transaction_send_oper
|
|||
db.i_w_info.mark_as_used_vout( *itr.second );
|
||||
}
|
||||
|
||||
fc::sha256 hashid = fc::sha256::hash(v.transaction.vin[0].prevout.hash.str() + std::to_string(v.transaction.vin[0].prevout.n));
|
||||
fc::sha256 hashid = v.pw_vin.valid() ? *v.pw_vin : SIDECHAIN_NULL_HASH;
|
||||
db.pw_vout_manager.use_latest_vout( hashid );
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +227,6 @@ void_result proposal_create_evaluator::do_evaluate(const proposal_create_operati
|
|||
object_id_type proposal_create_evaluator::do_apply(const proposal_create_operation& o)
|
||||
{ try {
|
||||
database& d = db();
|
||||
sidechain_hardfork_visitor sidechain_vtor( d );
|
||||
|
||||
const proposal_object& proposal = d.create<proposal_object>([&](proposal_object& proposal) {
|
||||
_proposed_trx.expiration = o.expiration_time;
|
||||
|
|
@ -252,7 +251,9 @@ object_id_type proposal_create_evaluator::do_apply(const proposal_create_operati
|
|||
std::inserter(proposal.required_active_approvals, proposal.required_active_approvals.begin()));
|
||||
});
|
||||
|
||||
sidechain_vtor( o.proposed_ops[0].op, proposal.id );
|
||||
sidechain_hardfork_visitor sidechain_vtor( d , proposal.id );
|
||||
o.proposed_ops[0].op.visit( sidechain_vtor );
|
||||
|
||||
return proposal.id;
|
||||
} FC_CAPTURE_AND_RETHROW( (o) ) }
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ public:
|
|||
input_withdrawal_info( graphene::chain::database& _db ) : db( _db ) {}
|
||||
|
||||
|
||||
fc::optional<info_for_vin> get_info_for_pw_vin();
|
||||
|
||||
|
||||
void insert_info_for_vin( const prev_out& out, const std::string& address, bytes script = bytes() );
|
||||
|
||||
void modify_info_for_vin( const info_for_vin& obj, const std::function<void( info_for_vin& e )>& func );
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
namespace graphene { namespace chain { class database; } }
|
||||
|
||||
using graphene::chain::primary_wallet_vout_object;
|
||||
using graphene::chain::primary_wallet_vout_id_type;
|
||||
|
||||
namespace sidechain {
|
||||
|
||||
class primary_wallet_vout_manager
|
||||
|
|
@ -16,9 +19,9 @@ public:
|
|||
|
||||
bool is_reach_max_unconfirmaed_vout() const;
|
||||
|
||||
fc::optional< graphene::chain::primary_wallet_vout_object > get_latest_unused_vout() const;
|
||||
fc::optional< primary_wallet_vout_object > get_latest_unused_vout() const;
|
||||
|
||||
fc::optional< graphene::chain::primary_wallet_vout_object > get_vout( fc::sha256 hash_id ) const;
|
||||
fc::optional< primary_wallet_vout_object > get_vout( fc::sha256 hash_id ) const;
|
||||
|
||||
void create_new_vout( const sidechain::prev_out& out );
|
||||
|
||||
|
|
@ -30,7 +33,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
fc::optional< graphene::chain::primary_wallet_vout_id_type > get_vout_id( fc::sha256 hash_id ) const;
|
||||
fc::optional< primary_wallet_vout_id_type > get_vout_id( fc::sha256 hash_id ) const;
|
||||
|
||||
graphene::chain::database& db;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,26 +6,6 @@ using namespace sidechain;
|
|||
|
||||
namespace sidechain {
|
||||
|
||||
// void example()
|
||||
// {
|
||||
// std::vector<info_for_vin> vin_infos { ... };
|
||||
// std::vector<info_for_vout> vout_infos { ... };
|
||||
|
||||
// sidechain_condensing_tx sct( vin_infos, vout_infos );
|
||||
|
||||
// if( pw_vin_info ) {
|
||||
// sct.create_pw_vin( pw_vin_info );
|
||||
// }
|
||||
|
||||
// if( vout_infos.size() ) {
|
||||
// sct.create_vouts_for_witness_fee( keys );
|
||||
// }
|
||||
|
||||
// if( ( vin_infos.sum() - vout_infos.sum() ) > 0 ) {
|
||||
// sct.create_pw_vout( vin_infos.sum() - vout_infos.sum(), bytes{ 0x0d, 0x0d, 0x0d } );
|
||||
// }
|
||||
// }
|
||||
|
||||
class sidechain_condensing_tx
|
||||
{
|
||||
|
||||
|
|
@ -33,11 +13,11 @@ public:
|
|||
|
||||
sidechain_condensing_tx( const std::vector<info_for_vin>& vin_info, const std::vector<info_for_vout>& vout_info );
|
||||
|
||||
void create_pw_vin( const info_for_vin& vin_info );
|
||||
void create_pw_vin( const info_for_vin& vin_info, bool front = true );
|
||||
|
||||
void create_pw_vout( const uint64_t amount, const bytes& wit_script_out );
|
||||
void create_pw_vout( const uint64_t amount, const bytes& wit_script_out, bool front = true );
|
||||
|
||||
void create_vouts_for_witness_fee( const accounts_keys& witness_active_keys );
|
||||
void create_vouts_for_witness_fee( const accounts_keys& witness_active_keys, bool front = true );
|
||||
|
||||
uint64_t get_estimate_tx_size( size_t number_witness ) const;
|
||||
|
||||
|
|
@ -69,6 +49,4 @@ private:
|
|||
|
||||
};
|
||||
|
||||
int64_t get_estimated_fee( size_t tx_vsize, uint64_t estimated_feerate ); // move db_sidechain
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,12 @@
|
|||
|
||||
namespace sidechain {
|
||||
|
||||
class bitcoin_transaction;
|
||||
|
||||
using bytes = std::vector<char>;
|
||||
using accounts_keys = std::map< graphene::chain::account_id_type, graphene::chain::public_key_type >;
|
||||
using info_for_vout = graphene::chain::info_for_vout_object;
|
||||
using full_btc_transaction = std::pair<bitcoin_transaction, uint64_t>;
|
||||
|
||||
enum class payment_type
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include <sidechain/input_withdrawal_info.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/primary_wallet_vout_object.hpp>
|
||||
#include <graphene/chain/bitcoin_address_object.hpp>
|
||||
|
||||
namespace sidechain {
|
||||
|
||||
|
|
@ -13,6 +15,24 @@ bool info_for_vin::comparer::operator() ( const info_for_vin& lhs, const info_fo
|
|||
return lhs.id < rhs.id;
|
||||
}
|
||||
|
||||
fc::optional<info_for_vin> input_withdrawal_info::get_info_for_pw_vin()
|
||||
{
|
||||
fc::optional< primary_wallet_vout_object > vout = db.pw_vout_manager.get_latest_unused_vout();
|
||||
if( !vout.valid() ) {
|
||||
return fc::optional<info_for_vin>();
|
||||
}
|
||||
|
||||
const auto& pw_address = db.get_latest_PW().address;
|
||||
|
||||
info_for_vin vin;
|
||||
vin.identifier = vout->hash_id;
|
||||
vin.out = vout->vout;
|
||||
vin.address = pw_address.get_address();
|
||||
vin.script = pw_address.get_witness_script();
|
||||
|
||||
return vin;
|
||||
}
|
||||
|
||||
void input_withdrawal_info::insert_info_for_vin( const prev_out& out, const std::string& address, bytes script )
|
||||
{
|
||||
info_for_vins.insert( info_for_vin( out, address, script ) );
|
||||
|
|
@ -44,6 +64,8 @@ std::vector<info_for_vin> input_withdrawal_info::get_info_for_vins()
|
|||
{
|
||||
std::vector<info_for_vin> result;
|
||||
|
||||
const auto& addr_idx = db.get_index_type<bitcoin_address_index>().indices().get<by_address>();
|
||||
|
||||
info_for_vins.safe_for<by_id_and_not_created>( [&]( info_for_vin_index::index<by_id_and_not_created>::type::iterator itr_b,
|
||||
info_for_vin_index::index<by_id_and_not_created>::type::iterator itr_e )
|
||||
{
|
||||
|
|
@ -55,7 +77,9 @@ std::vector<info_for_vin> input_withdrawal_info::get_info_for_vins()
|
|||
vin.out.n_vout = itr_b->out.n_vout;
|
||||
vin.out.amount = itr_b->out.amount;
|
||||
vin.address = itr_b->address;
|
||||
// vin.script = get account address, from the address get the script
|
||||
const auto& address_itr = addr_idx.find( itr_b->address );
|
||||
FC_ASSERT( address_itr != addr_idx.end() );
|
||||
vin.script = address_itr->address.get_witness_script();
|
||||
|
||||
result.push_back( vin );
|
||||
++itr_b;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <graphene/chain/bitcoin_address_object.hpp>
|
||||
|
||||
namespace sidechain {
|
||||
|
||||
sidechain_net_manager::sidechain_net_manager( graphene::chain::database* _db, std::string _ip,
|
||||
|
|
@ -56,6 +58,8 @@ std::vector<info_for_vin> sidechain_net_manager::extract_info_from_block( const
|
|||
|
||||
std::vector<info_for_vin> result;
|
||||
|
||||
const auto& addr_idx = db->get_index_type<bitcoin_address_index>().indices().get<by_address>();
|
||||
|
||||
for (const auto& tx_child : block.get_child("tx")) {
|
||||
const auto& tx = tx_child.second;
|
||||
|
||||
|
|
@ -67,7 +71,7 @@ std::vector<info_for_vin> sidechain_net_manager::extract_info_from_block( const
|
|||
for (const auto& addr : script.get_child("addresses")) { // in which cases there can be more addresses?
|
||||
const auto address_base58 = addr.second.get_value<std::string>();
|
||||
|
||||
// if( !test.count( address_base58 ) ) continue; // there is such an address in graphene
|
||||
if( !addr_idx.count( address_base58 ) ) continue;
|
||||
|
||||
info_for_vin vin;
|
||||
vin.out.hash_tx = tx.get_child("txid").get_value<std::string>();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ bool primary_wallet_vout_manager::is_reach_max_unconfirmaed_vout() const
|
|||
return !( PW_vout_idx.size() < SIDECHAIN_DEFAULT_NUMBER_UNCONFIRMED_VINS );
|
||||
}
|
||||
|
||||
fc::optional< graphene::chain::primary_wallet_vout_object > primary_wallet_vout_manager::get_latest_unused_vout() const
|
||||
fc::optional< primary_wallet_vout_object > primary_wallet_vout_manager::get_latest_unused_vout() const
|
||||
{
|
||||
const auto& PW_vout_idx = db.get_index_type<graphene::chain::primary_wallet_vout_index>().indices().get< graphene::chain::by_id >();
|
||||
auto itr = PW_vout_idx.end();
|
||||
|
|
@ -20,22 +20,22 @@ fc::optional< graphene::chain::primary_wallet_vout_object > primary_wallet_vout_
|
|||
|
||||
itr--;
|
||||
if( itr->used )
|
||||
return fc::optional< graphene::chain::primary_wallet_vout_object >();
|
||||
return fc::optional< graphene::chain::primary_wallet_vout_object > (*itr);
|
||||
return fc::optional< primary_wallet_vout_object >();
|
||||
return fc::optional< primary_wallet_vout_object > (*itr);
|
||||
}
|
||||
|
||||
fc::optional< graphene::chain::primary_wallet_vout_object > primary_wallet_vout_manager::get_vout( fc::sha256 hash_id ) const
|
||||
fc::optional< primary_wallet_vout_object > primary_wallet_vout_manager::get_vout( fc::sha256 hash_id ) const
|
||||
{
|
||||
const auto& PW_vout_by_hash_id = db.get_index_type<graphene::chain::primary_wallet_vout_index>().indices().get< graphene::chain::by_hash_id >();
|
||||
const auto& itr_hash_id = PW_vout_by_hash_id.find( hash_id );
|
||||
if( itr_hash_id == PW_vout_by_hash_id.end() )
|
||||
return fc::optional< graphene::chain::primary_wallet_vout_object >();
|
||||
return fc::optional< graphene::chain::primary_wallet_vout_object >( *itr_hash_id );
|
||||
return fc::optional< primary_wallet_vout_object >();
|
||||
return fc::optional< primary_wallet_vout_object >( *itr_hash_id );
|
||||
}
|
||||
|
||||
void primary_wallet_vout_manager::create_new_vout( const sidechain::prev_out& out )
|
||||
{
|
||||
db.create<graphene::chain::primary_wallet_vout_object>([&]( graphene::chain::primary_wallet_vout_object& obj ) {
|
||||
db.create<primary_wallet_vout_object>([&]( primary_wallet_vout_object& obj ) {
|
||||
obj.vout = out;
|
||||
obj.hash_id = fc::sha256::hash( out.hash_tx + std::to_string( out.n_vout ) );
|
||||
obj.confirmed = false;
|
||||
|
|
@ -68,7 +68,7 @@ void primary_wallet_vout_manager::confirm_vout( fc::sha256 hash_id )
|
|||
|
||||
auto itr = PW_vout_by_id.find( *vout_id );
|
||||
|
||||
db.modify(*itr, [&]( graphene::chain::primary_wallet_vout_object& PW_vout ) {
|
||||
db.modify(*itr, [&]( primary_wallet_vout_object& PW_vout ) {
|
||||
PW_vout.confirmed = true;
|
||||
});
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ void primary_wallet_vout_manager::use_latest_vout( fc::sha256 hash_id )
|
|||
|
||||
auto itr = PW_vout_by_id.find( *vout_id );
|
||||
|
||||
db.modify(*itr, [&]( graphene::chain::primary_wallet_vout_object& PW_vout ) {
|
||||
db.modify(*itr, [&]( primary_wallet_vout_object& PW_vout ) {
|
||||
PW_vout.used = true;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -8,18 +8,18 @@ sidechain_condensing_tx::sidechain_condensing_tx( const std::vector<info_for_vin
|
|||
create_vouts_for_condensing_tx( vout_info );
|
||||
}
|
||||
|
||||
void sidechain_condensing_tx::create_pw_vin( const info_for_vin& vin_info )
|
||||
void sidechain_condensing_tx::create_pw_vin( const info_for_vin& vin_info, bool front )
|
||||
{
|
||||
bytes witness_script_temp = {0x22};
|
||||
witness_script_temp.insert( witness_script_temp.end(), vin_info.script.begin(), vin_info.script.end() );
|
||||
tb.add_in( payment_type::P2WSH, fc::sha256( vin_info.out.hash_tx ), vin_info.out.n_vout, witness_script_temp, true );
|
||||
tb.add_in( payment_type::P2WSH, fc::sha256( vin_info.out.hash_tx ), vin_info.out.n_vout, witness_script_temp, front );
|
||||
|
||||
amount_vins += vin_info.out.amount;
|
||||
}
|
||||
|
||||
void sidechain_condensing_tx::create_pw_vout( const uint64_t amount, const bytes& wit_script_out )
|
||||
void sidechain_condensing_tx::create_pw_vout( const uint64_t amount, const bytes& wit_script_out, bool front )
|
||||
{
|
||||
tb.add_out( payment_type::P2WSH, amount, bytes(wit_script_out.begin() + 2, wit_script_out.end()), true );
|
||||
tb.add_out( payment_type::P2WSH, amount, bytes(wit_script_out.begin() + 2, wit_script_out.end()), front );
|
||||
}
|
||||
|
||||
void sidechain_condensing_tx::create_vins_for_condensing_tx( const std::vector<info_for_vin>& vin_info )
|
||||
|
|
@ -42,10 +42,10 @@ void sidechain_condensing_tx::create_vouts_for_condensing_tx( const std::vector<
|
|||
}
|
||||
}
|
||||
|
||||
void sidechain_condensing_tx::create_vouts_for_witness_fee( const accounts_keys& witness_active_keys )
|
||||
void sidechain_condensing_tx::create_vouts_for_witness_fee( const accounts_keys& witness_active_keys, bool front )
|
||||
{
|
||||
for( auto& key : witness_active_keys ) {
|
||||
tb.add_out( payment_type::P2PK, 0, key.second, true );
|
||||
tb.add_out( payment_type::P2PK, 0, key.second, front );
|
||||
count_witness_vout++;
|
||||
}
|
||||
}
|
||||
|
|
@ -77,8 +77,13 @@ void sidechain_condensing_tx::subtract_fee( const uint64_t& fee, const double& w
|
|||
fee_size += 1;
|
||||
}
|
||||
|
||||
bool is_pw_vin = tx.vout.size() > ( count_witness_vout + count_transfer_vout );
|
||||
if( is_pw_vin ) {
|
||||
tx.vout[0].value = tx.vout[0].value - fee_size;
|
||||
}
|
||||
|
||||
uint64_t fee_witnesses = 0;
|
||||
size_t offset = tx.vout.size() > ( count_witness_vout + count_transfer_vout ) ? 1 + count_witness_vout : count_witness_vout;
|
||||
size_t offset = is_pw_vin ? 1 + count_witness_vout : count_witness_vout;
|
||||
for( ; offset < tx.vout.size(); offset++ ) {
|
||||
uint64_t amount_without_fee_size = tx.vout[offset].value - fee_size;
|
||||
uint64_t amount_fee_witness = amount_without_fee_size * witness_percentage;
|
||||
|
|
@ -89,10 +94,10 @@ void sidechain_condensing_tx::subtract_fee( const uint64_t& fee, const double& w
|
|||
|
||||
if( count_witness_vout > 0 ) {
|
||||
uint64_t fee_witness = fee_witnesses / count_witness_vout;
|
||||
size_t limit = tx.vout.size() > ( count_witness_vout + count_transfer_vout ) ? 1 + count_witness_vout : count_witness_vout;
|
||||
offset = tx.vout.size() > ( count_witness_vout + count_transfer_vout ) ? 1 : 0;
|
||||
size_t limit = is_pw_vin ? 1 + count_witness_vout : count_witness_vout;
|
||||
size_t offset = is_pw_vin ? 1 : 0;
|
||||
FC_ASSERT( fee_witness > 0 );
|
||||
for( ; offset < limit; offset++ ) {
|
||||
for( offset = 0; offset < limit; offset++ ) {
|
||||
tx.vout[offset].value += fee_witness;
|
||||
}
|
||||
}
|
||||
|
|
@ -100,14 +105,4 @@ void sidechain_condensing_tx::subtract_fee( const uint64_t& fee, const double& w
|
|||
tb = std::move( bitcoin_transaction_builder( tx ) );
|
||||
}
|
||||
|
||||
int64_t get_estimated_fee( size_t tx_vsize, uint64_t estimated_feerate ) {
|
||||
static const uint64_t default_feerate = 1000;
|
||||
static const uint64_t min_relay_fee = 1000;
|
||||
|
||||
const auto feerate = std::max( default_feerate, estimated_feerate );
|
||||
const auto fee = feerate * int64_t( tx_vsize ) / 1000;
|
||||
|
||||
return std::max( min_relay_fee, fee );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue