From ffc51ba1ea403442692905cbfadfaccc7e6192f3 Mon Sep 17 00:00:00 2001 From: Anzhy Cherrnyavski Date: Tue, 29 Jan 2019 15:02:39 +0300 Subject: [PATCH] Added mechanism create proposal (send_btc_transaction) --- .../chain/bitcoin_transaction_evaluator.cpp | 2 +- libraries/chain/db_block.cpp | 7 ++ libraries/chain/db_management.cpp | 1 + libraries/chain/db_sidechain.cpp | 107 +++++++++++++++++- .../chain/include/graphene/chain/config.hpp | 2 + .../chain/include/graphene/chain/database.hpp | 16 ++- .../graphene/chain/proposal_evaluator.hpp | 7 +- libraries/chain/proposal_evaluator.cpp | 9 +- .../sidechain/input_withdrawal_info.hpp | 3 + .../sidechain/primary_wallet_vout_manager.hpp | 9 +- .../sidechain/sidechain_condensing_tx.hpp | 28 +---- .../sidechain/include/sidechain/types.hpp | 3 + libraries/sidechain/input_withdrawal_info.cpp | 26 ++++- .../network/sidechain_net_manager.cpp | 6 +- .../sidechain/primary_wallet_vout_manager.cpp | 18 +-- .../sidechain/sidechain_condensing_tx.cpp | 35 +++--- 16 files changed, 210 insertions(+), 69 deletions(-) diff --git a/libraries/chain/bitcoin_transaction_evaluator.cpp b/libraries/chain/bitcoin_transaction_evaluator.cpp index 55573c88..4c0d54f2 100644 --- a/libraries/chain/bitcoin_transaction_evaluator.cpp +++ b/libraries/chain/bitcoin_transaction_evaluator.cpp @@ -26,7 +26,6 @@ object_id_type bitcoin_transaction_send_evaluator::do_apply( const bitcoin_trans bitcoin_transaction_send_operation& mutable_op = const_cast( 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 }; diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index 4eeeb499..c997eafc 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -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 ) diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp index 95a7125b..9abca707 100644 --- a/libraries/chain/db_management.cpp +++ b/libraries/chain/db_management.cpp @@ -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() diff --git a/libraries/chain/db_sidechain.cpp b/libraries/chain/db_sidechain.cpp index d9ba8d81..cb50791f 100644 --- a/libraries/chain/db_sidechain.cpp +++ b/libraries/chain/db_sidechain.cpp @@ -1,5 +1,11 @@ #include #include +#include +#include +#include +#include + +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().indices().get< by_id >(); + const auto& proposal_idx = get_index_type().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_vins, + const std::vector& info_vouts, + const fc::optional& 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 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(); +} + +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; +} } } \ No newline at end of file diff --git a/libraries/chain/include/graphene/chain/config.hpp b/libraries/chain/include/graphene/chain/config.hpp index 97ea517e..36c29415 100644 --- a/libraries/chain/include/graphene/chain/config.hpp +++ b/libraries/chain/include/graphene/chain/config.hpp @@ -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 ) ); ////////////////////////////////////////////////////////////////////// diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 41225541..fbcb8c5c 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -42,12 +42,15 @@ #include #include +#include #include #include #include +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& info_vins, + const std::vector& info_vouts, + const fc::optional& info_pw_vin ); + fc::optional 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 send_btc_tx; sidechain::input_withdrawal_info i_w_info; sidechain::primary_wallet_vout_manager pw_vout_manager; - fc::signal send_btc_tx; + std::atomic estimated_feerate; secp256k1_context_t* context_sign; diff --git a/libraries/chain/include/graphene/chain/proposal_evaluator.hpp b/libraries/chain/include/graphene/chain/proposal_evaluator.hpp index ca1bed39..b2135ed3 100644 --- a/libraries/chain/include/graphene/chain/proposal_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/proposal_evaluator.hpp @@ -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 - 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 diff --git a/libraries/chain/proposal_evaluator.cpp b/libraries/chain/proposal_evaluator.cpp index d19ee541..2e592f42 100644 --- a/libraries/chain/proposal_evaluator.cpp +++ b/libraries/chain/proposal_evaluator.cpp @@ -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& 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) { _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) ) } diff --git a/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp b/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp index 0126f6f2..b1534e92 100644 --- a/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp +++ b/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp @@ -67,6 +67,9 @@ public: input_withdrawal_info( graphene::chain::database& _db ) : db( _db ) {} + fc::optional 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& func ); diff --git a/libraries/sidechain/include/sidechain/primary_wallet_vout_manager.hpp b/libraries/sidechain/include/sidechain/primary_wallet_vout_manager.hpp index abe8c9c8..96504ed8 100644 --- a/libraries/sidechain/include/sidechain/primary_wallet_vout_manager.hpp +++ b/libraries/sidechain/include/sidechain/primary_wallet_vout_manager.hpp @@ -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; diff --git a/libraries/sidechain/include/sidechain/sidechain_condensing_tx.hpp b/libraries/sidechain/include/sidechain/sidechain_condensing_tx.hpp index b0185d2d..e6d9ba59 100644 --- a/libraries/sidechain/include/sidechain/sidechain_condensing_tx.hpp +++ b/libraries/sidechain/include/sidechain/sidechain_condensing_tx.hpp @@ -6,26 +6,6 @@ using namespace sidechain; namespace sidechain { -// void example() -// { -// std::vector vin_infos { ... }; -// std::vector 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& vin_info, const std::vector& 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 - } diff --git a/libraries/sidechain/include/sidechain/types.hpp b/libraries/sidechain/include/sidechain/types.hpp index 78a28fc6..35ad8004 100644 --- a/libraries/sidechain/include/sidechain/types.hpp +++ b/libraries/sidechain/include/sidechain/types.hpp @@ -9,9 +9,12 @@ namespace sidechain { +class bitcoin_transaction; + using bytes = std::vector; 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; enum class payment_type { diff --git a/libraries/sidechain/input_withdrawal_info.cpp b/libraries/sidechain/input_withdrawal_info.cpp index a5023574..c839ede7 100644 --- a/libraries/sidechain/input_withdrawal_info.cpp +++ b/libraries/sidechain/input_withdrawal_info.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include 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 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(); + } + + 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 input_withdrawal_info::get_info_for_vins() { std::vector result; + const auto& addr_idx = db.get_index_type().indices().get(); + info_for_vins.safe_for( [&]( info_for_vin_index::index::type::iterator itr_b, info_for_vin_index::index::type::iterator itr_e ) { @@ -55,7 +77,9 @@ std::vector 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; diff --git a/libraries/sidechain/network/sidechain_net_manager.cpp b/libraries/sidechain/network/sidechain_net_manager.cpp index 60bf84c2..cae92489 100644 --- a/libraries/sidechain/network/sidechain_net_manager.cpp +++ b/libraries/sidechain/network/sidechain_net_manager.cpp @@ -9,6 +9,8 @@ #include #include +#include + namespace sidechain { sidechain_net_manager::sidechain_net_manager( graphene::chain::database* _db, std::string _ip, @@ -56,6 +58,8 @@ std::vector sidechain_net_manager::extract_info_from_block( const std::vector result; + const auto& addr_idx = db->get_index_type().indices().get(); + for (const auto& tx_child : block.get_child("tx")) { const auto& tx = tx_child.second; @@ -67,7 +71,7 @@ std::vector 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(); - // 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(); diff --git a/libraries/sidechain/primary_wallet_vout_manager.cpp b/libraries/sidechain/primary_wallet_vout_manager.cpp index 9e444cc4..788a92a6 100644 --- a/libraries/sidechain/primary_wallet_vout_manager.cpp +++ b/libraries/sidechain/primary_wallet_vout_manager.cpp @@ -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().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().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& obj ) { + db.create([&]( 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; }); diff --git a/libraries/sidechain/sidechain_condensing_tx.cpp b/libraries/sidechain/sidechain_condensing_tx.cpp index efdbe4b5..58974900 100644 --- a/libraries/sidechain/sidechain_condensing_tx.cpp +++ b/libraries/sidechain/sidechain_condensing_tx.cpp @@ -8,18 +8,18 @@ sidechain_condensing_tx::sidechain_condensing_tx( const std::vector& 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 ); -} - }